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(
|
auto cmsisHidInterface = Usb::HidInterface(
|
||||||
this->cmsisHidInterfaceNumber,
|
this->cmsisHidInterfaceNumber,
|
||||||
this->getCmsisHidReportSize(),
|
this->getEndpointMaxPacketSize(
|
||||||
|
this->getFirstEndpointAddress(this->cmsisHidInterfaceNumber, LIBUSB_ENDPOINT_IN)
|
||||||
|
),
|
||||||
this->vendorId,
|
this->vendorId,
|
||||||
this->productId
|
this->productId
|
||||||
);
|
);
|
||||||
@@ -157,33 +159,4 @@ namespace DebugToolDrivers::Microchip
|
|||||||
|
|
||||||
this->sessionStarted = false;
|
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;
|
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() {
|
virtual void configureAvr8Interface() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "src/Logger/Logger.hpp"
|
#include "src/Logger/Logger.hpp"
|
||||||
|
#include "src/Services/StringService.hpp"
|
||||||
|
|
||||||
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
|
#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp"
|
||||||
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
|
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
|
||||||
#include "src/TargetController/Exceptions/DeviceNotFound.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) {
|
std::vector<LibusbDevice> UsbDevice::findMatchingDevices(std::uint16_t vendorId, std::uint16_t productId) {
|
||||||
::libusb_device** devices = nullptr;
|
::libusb_device** devices = nullptr;
|
||||||
::libusb_device* device;
|
::libusb_device* device;
|
||||||
|
|||||||
@@ -38,6 +38,22 @@ namespace Usb
|
|||||||
*/
|
*/
|
||||||
std::string getSerialNumber() const;
|
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.
|
* 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;
|
using Targets::RiscV::DebugModule::DmiOperation;
|
||||||
|
|
||||||
WchLinkInterface::WchLinkInterface(Usb::UsbInterface& usbInterface)
|
WchLinkInterface::WchLinkInterface(Usb::UsbInterface& usbInterface, Usb::UsbDevice& usbDevice)
|
||||||
: usbInterface(usbInterface)
|
: usbInterface(usbInterface)
|
||||||
|
, commandEndpointMaxPacketSize(usbDevice.getEndpointMaxPacketSize(WchLinkInterface::USB_COMMAND_ENDPOINT_OUT))
|
||||||
|
, dataEndpointMaxPacketSize(usbDevice.getEndpointMaxPacketSize(WchLinkInterface::USB_DATA_ENDPOINT_OUT))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
DeviceInfo WchLinkInterface::getDeviceInfo() {
|
DeviceInfo WchLinkInterface::getDeviceInfo() {
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp"
|
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp"
|
||||||
#include "src/DebugToolDrivers/USB/UsbInterface.hpp"
|
#include "src/DebugToolDrivers/USB/UsbInterface.hpp"
|
||||||
|
#include "src/DebugToolDrivers/USB/UsbDevice.hpp"
|
||||||
|
|
||||||
#include "src/DebugToolDrivers/WCH/WchGeneric.hpp"
|
#include "src/DebugToolDrivers/WCH/WchGeneric.hpp"
|
||||||
#include "Commands/Command.hpp"
|
#include "Commands/Command.hpp"
|
||||||
@@ -23,7 +25,7 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
|||||||
class WchLinkInterface: public TargetInterfaces::RiscV::RiscVDebugInterface
|
class WchLinkInterface: public TargetInterfaces::RiscV::RiscVDebugInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit WchLinkInterface(Usb::UsbInterface& usbInterface);
|
WchLinkInterface(Usb::UsbInterface& usbInterface, Usb::UsbDevice& usbDevice);
|
||||||
|
|
||||||
DeviceInfo getDeviceInfo();
|
DeviceInfo getDeviceInfo();
|
||||||
|
|
||||||
@@ -43,11 +45,16 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
|||||||
) override;
|
) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr std::uint8_t USB_ENDPOINT_IN = 0x81;
|
static constexpr std::uint8_t USB_COMMAND_ENDPOINT_IN = 0x81;
|
||||||
static constexpr std::uint8_t USB_ENDPOINT_OUT = 0x01;
|
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;
|
Usb::UsbInterface& usbInterface;
|
||||||
|
|
||||||
|
std::uint16_t commandEndpointMaxPacketSize = 0;
|
||||||
|
std::uint16_t dataEndpointMaxPacketSize = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 'target activation' command returns a payload of 5 bytes.
|
* The 'target activation' command returns a payload of 5 bytes.
|
||||||
*
|
*
|
||||||
@@ -67,9 +74,17 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
|||||||
|
|
||||||
template <class CommandType>
|
template <class CommandType>
|
||||||
auto sendCommandAndWaitForResponse(const CommandType& command) {
|
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) {
|
if (rawResponse.size() < 3) {
|
||||||
throw Exceptions::DeviceCommunicationFailure("Invalid response size from device");
|
throw Exceptions::DeviceCommunicationFailure("Invalid response size from device");
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ namespace DebugToolDrivers::Wch
|
|||||||
this->wchLinkUsbInterface->init();
|
this->wchLinkUsbInterface->init();
|
||||||
|
|
||||||
this->wchLinkInterface = std::make_unique<Protocols::WchLink::WchLinkInterface>(
|
this->wchLinkInterface = std::make_unique<Protocols::WchLink::WchLinkInterface>(
|
||||||
*(this->wchLinkUsbInterface.get())
|
*(this->wchLinkUsbInterface.get()),
|
||||||
|
*this
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this->getDeviceInfo().variant != this->variant) {
|
if (this->getDeviceInfo().variant != this->variant) {
|
||||||
|
|||||||
Reference in New Issue
Block a user