Moved wMaxPacketSize retrieval to Usb::UsbDevice class.
And some other bits of tidying
This commit is contained in:
@@ -40,7 +40,9 @@ namespace DebugToolDrivers::Microchip
|
||||
|
||||
auto cmsisHidInterface = Usb::HidInterface(
|
||||
this->cmsisHidInterfaceNumber,
|
||||
this->getCmsisHidReportSize(),
|
||||
this->getEndpointMaxPacketSize(
|
||||
this->getFirstEndpointAddress(this->cmsisHidInterfaceNumber, LIBUSB_ENDPOINT_IN)
|
||||
),
|
||||
this->vendorId,
|
||||
this->productId
|
||||
);
|
||||
@@ -157,33 +159,4 @@ namespace DebugToolDrivers::Microchip
|
||||
|
||||
this->sessionStarted = false;
|
||||
}
|
||||
|
||||
std::uint16_t EdbgDevice::getCmsisHidReportSize() {
|
||||
const auto activeConfigDescriptor = this->getConfigDescriptor();
|
||||
|
||||
for (auto interfaceIndex = 0; interfaceIndex < activeConfigDescriptor->bNumInterfaces; ++interfaceIndex) {
|
||||
const auto* interfaceDescriptor = (activeConfigDescriptor->interface + interfaceIndex)->altsetting;
|
||||
|
||||
if (interfaceDescriptor->bInterfaceNumber != this->cmsisHidInterfaceNumber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto endpointIndex = 0; endpointIndex < activeConfigDescriptor->bNumInterfaces; ++endpointIndex) {
|
||||
const auto* endpointDescriptor = (interfaceDescriptor->endpoint + endpointIndex);
|
||||
|
||||
if ((endpointDescriptor->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) != LIBUSB_ENDPOINT_IN) {
|
||||
// Not an IN endpoint
|
||||
continue;
|
||||
}
|
||||
|
||||
return endpointDescriptor->wMaxPacketSize;
|
||||
}
|
||||
}
|
||||
|
||||
throw DeviceInitializationFailure(
|
||||
"Failed to obtain CMSIS-DAP HID report size via endpoint descriptor - could not find IN endpoint for "
|
||||
"selected configuration value (" + std::to_string(activeConfigDescriptor->bConfigurationValue)
|
||||
+ ") and interface number (" + std::to_string(this->cmsisHidInterfaceNumber) + ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,17 +155,6 @@ namespace DebugToolDrivers::Microchip
|
||||
|
||||
bool sessionStarted = false;
|
||||
|
||||
/**
|
||||
* Because EDBG devices require fixed-length reports to be transmitted to/from their HID interface, we must
|
||||
* know the HID report size (as it differs across EDBG devices).
|
||||
*
|
||||
* This member function will obtain the report size from the endpoint descriptor of the IN endpoint, from the
|
||||
* HID interface.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
std::uint16_t getCmsisHidReportSize();
|
||||
|
||||
virtual void configureAvr8Interface() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <array>
|
||||
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Services/StringService.hpp"
|
||||
|
||||
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
|
||||
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
|
||||
#include "src/TargetController/Exceptions/DeviceNotFound.hpp"
|
||||
@@ -100,6 +102,53 @@ namespace Usb
|
||||
}
|
||||
}
|
||||
|
||||
std::uint8_t UsbDevice::getFirstEndpointAddress(
|
||||
std::uint8_t interfaceNumber,
|
||||
::libusb_endpoint_direction direction
|
||||
) {
|
||||
const auto activeConfigDescriptor = this->getConfigDescriptor();
|
||||
|
||||
for (auto interfaceIndex = 0; interfaceIndex < activeConfigDescriptor->bNumInterfaces; ++interfaceIndex) {
|
||||
const auto* interfaceDescriptor = (activeConfigDescriptor->interface + interfaceIndex)->altsetting;
|
||||
|
||||
if (interfaceDescriptor->bInterfaceNumber != interfaceNumber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto endpointIndex = 0; endpointIndex < interfaceDescriptor->bNumEndpoints; ++endpointIndex) {
|
||||
const auto* endpointDescriptor = (interfaceDescriptor->endpoint + endpointIndex);
|
||||
|
||||
if ((endpointDescriptor->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) != direction) {
|
||||
return endpointDescriptor->bEndpointAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw DeviceInitializationFailure("Failed to obtain address of USB endpoint");
|
||||
}
|
||||
|
||||
std::uint16_t UsbDevice::getEndpointMaxPacketSize(std::uint8_t endpointAddress) {
|
||||
const auto activeConfigDescriptor = this->getConfigDescriptor();
|
||||
|
||||
for (auto interfaceIndex = 0; interfaceIndex < activeConfigDescriptor->bNumInterfaces; ++interfaceIndex) {
|
||||
const auto* interfaceDescriptor = (activeConfigDescriptor->interface + interfaceIndex)->altsetting;
|
||||
|
||||
for (auto endpointIndex = 0; endpointIndex < interfaceDescriptor->bNumEndpoints; ++endpointIndex) {
|
||||
const auto* endpointDescriptor = (interfaceDescriptor->endpoint + endpointIndex);
|
||||
|
||||
if (endpointDescriptor->bEndpointAddress == endpointAddress) {
|
||||
return endpointDescriptor->wMaxPacketSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw DeviceInitializationFailure(
|
||||
"Failed to obtain maximum packet size of USB endpoint (address: 0x"
|
||||
+ Services::StringService::toHex(endpointAddress) + "). Endpoint not found. Selected configuration "
|
||||
"value (" + std::to_string(activeConfigDescriptor->bConfigurationValue) + ")"
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<LibusbDevice> UsbDevice::findMatchingDevices(std::uint16_t vendorId, std::uint16_t productId) {
|
||||
::libusb_device** devices = nullptr;
|
||||
::libusb_device* device;
|
||||
|
||||
@@ -38,6 +38,22 @@ namespace Usb
|
||||
*/
|
||||
std::string getSerialNumber() const;
|
||||
|
||||
/**
|
||||
* Obtains the address of the first endpoint within a given interface and of a particular direction.
|
||||
*
|
||||
* @param endpointAddress
|
||||
* @return
|
||||
*/
|
||||
std::uint8_t getFirstEndpointAddress(std::uint8_t interfaceNumber, ::libusb_endpoint_direction direction);
|
||||
|
||||
/**
|
||||
* Obtains the maximum packet size of an endpoint.
|
||||
*
|
||||
* @param endpointAddress
|
||||
* @return
|
||||
*/
|
||||
std::uint16_t getEndpointMaxPacketSize(std::uint8_t endpointAddress);
|
||||
|
||||
/**
|
||||
* Selects a specific configuration on the device, using the configuration index.
|
||||
*
|
||||
|
||||
@@ -21,8 +21,10 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
|
||||
using Targets::RiscV::DebugModule::DmiOperation;
|
||||
|
||||
WchLinkInterface::WchLinkInterface(Usb::UsbInterface& usbInterface)
|
||||
WchLinkInterface::WchLinkInterface(Usb::UsbInterface& usbInterface, Usb::UsbDevice& usbDevice)
|
||||
: usbInterface(usbInterface)
|
||||
, commandEndpointMaxPacketSize(usbDevice.getEndpointMaxPacketSize(WchLinkInterface::USB_COMMAND_ENDPOINT_OUT))
|
||||
, dataEndpointMaxPacketSize(usbDevice.getEndpointMaxPacketSize(WchLinkInterface::USB_DATA_ENDPOINT_OUT))
|
||||
{}
|
||||
|
||||
DeviceInfo WchLinkInterface::getDeviceInfo() {
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp"
|
||||
#include "src/DebugToolDrivers/USB/UsbInterface.hpp"
|
||||
#include "src/DebugToolDrivers/USB/UsbDevice.hpp"
|
||||
|
||||
#include "src/DebugToolDrivers/WCH/WchGeneric.hpp"
|
||||
#include "Commands/Command.hpp"
|
||||
@@ -23,7 +25,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
class WchLinkInterface: public TargetInterfaces::RiscV::RiscVDebugInterface
|
||||
{
|
||||
public:
|
||||
explicit WchLinkInterface(Usb::UsbInterface& usbInterface);
|
||||
WchLinkInterface(Usb::UsbInterface& usbInterface, Usb::UsbDevice& usbDevice);
|
||||
|
||||
DeviceInfo getDeviceInfo();
|
||||
|
||||
@@ -43,11 +45,16 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
) override;
|
||||
|
||||
private:
|
||||
static constexpr std::uint8_t USB_ENDPOINT_IN = 0x81;
|
||||
static constexpr std::uint8_t USB_ENDPOINT_OUT = 0x01;
|
||||
static constexpr std::uint8_t USB_COMMAND_ENDPOINT_IN = 0x81;
|
||||
static constexpr std::uint8_t USB_COMMAND_ENDPOINT_OUT = 0x01;
|
||||
static constexpr std::uint8_t USB_DATA_ENDPOINT_IN = 0x82;
|
||||
static constexpr std::uint8_t USB_DATA_ENDPOINT_OUT = 0x02;
|
||||
|
||||
Usb::UsbInterface& usbInterface;
|
||||
|
||||
std::uint16_t commandEndpointMaxPacketSize = 0;
|
||||
std::uint16_t dataEndpointMaxPacketSize = 0;
|
||||
|
||||
/**
|
||||
* The 'target activation' command returns a payload of 5 bytes.
|
||||
*
|
||||
@@ -67,9 +74,17 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
|
||||
template <class CommandType>
|
||||
auto sendCommandAndWaitForResponse(const CommandType& command) {
|
||||
this->usbInterface.writeBulk(WchLinkInterface::USB_ENDPOINT_OUT, command.getRawCommand());
|
||||
auto rawCommand = command.getRawCommand();
|
||||
|
||||
const auto rawResponse = this->usbInterface.readBulk(WchLinkInterface::USB_ENDPOINT_IN);
|
||||
if (rawCommand.size() > this->commandEndpointMaxPacketSize) {
|
||||
throw Exceptions::DeviceCommunicationFailure(
|
||||
"Raw command size exceeds maximum packet size for command endpoint"
|
||||
);
|
||||
}
|
||||
|
||||
this->usbInterface.writeBulk(WchLinkInterface::USB_COMMAND_ENDPOINT_OUT, std::move(rawCommand));
|
||||
|
||||
const auto rawResponse = this->usbInterface.readBulk(WchLinkInterface::USB_COMMAND_ENDPOINT_IN);
|
||||
|
||||
if (rawResponse.size() < 3) {
|
||||
throw Exceptions::DeviceCommunicationFailure("Invalid response size from device");
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace DebugToolDrivers::Wch
|
||||
this->wchLinkUsbInterface->init();
|
||||
|
||||
this->wchLinkInterface = std::make_unique<Protocols::WchLink::WchLinkInterface>(
|
||||
*(this->wchLinkUsbInterface.get())
|
||||
*(this->wchLinkUsbInterface.get()),
|
||||
*this
|
||||
);
|
||||
|
||||
if (this->getDeviceInfo().variant != this->variant) {
|
||||
|
||||
Reference in New Issue
Block a user