Retry DMI operations when BUSY status returned in WCH-Link driver
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "WchLinkInterface.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <thread>
|
||||
|
||||
#include "Commands/Control/GetDeviceInfo.hpp"
|
||||
#include "Commands/Control/AttachTarget.hpp"
|
||||
@@ -79,15 +80,29 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
DebugModule::RegisterValue WchLinkInterface::readDebugModuleRegister(DebugModule::RegisterAddress address) {
|
||||
using DebugModule::DmiOperationStatus;
|
||||
|
||||
auto attempt = std::uint8_t{0};
|
||||
while (attempt < WchLinkInterface::DMI_OP_MAX_RETRY) {
|
||||
if (attempt > 0) {
|
||||
std::this_thread::sleep_for(this->dmiOpRetryDelay);
|
||||
}
|
||||
|
||||
const auto response = this->sendCommandAndWaitForResponse(
|
||||
Commands::DebugModuleInterfaceOperation{DmiOperation::READ, address}
|
||||
);
|
||||
|
||||
if (response.operationStatus != DmiOperationStatus::SUCCESS) {
|
||||
if (response.operationStatus == DmiOperationStatus::SUCCESS) {
|
||||
return response.value;
|
||||
}
|
||||
|
||||
if (response.operationStatus == DmiOperationStatus::FAILED) {
|
||||
throw Exceptions::DeviceCommunicationFailure{"DMI operation failed"};
|
||||
}
|
||||
|
||||
return response.value;
|
||||
// Busy response...
|
||||
++attempt;
|
||||
}
|
||||
|
||||
throw Exceptions::DeviceCommunicationFailure{"DMI operation timed out"};
|
||||
}
|
||||
|
||||
void WchLinkInterface::writeDebugModuleRegister(
|
||||
@@ -96,13 +111,29 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
) {
|
||||
using DebugModule::DmiOperationStatus;
|
||||
|
||||
auto attempt = std::uint8_t{0};
|
||||
while (attempt < WchLinkInterface::DMI_OP_MAX_RETRY) {
|
||||
if (attempt > 0) {
|
||||
std::this_thread::sleep_for(this->dmiOpRetryDelay);
|
||||
}
|
||||
|
||||
const auto response = this->sendCommandAndWaitForResponse(
|
||||
Commands::DebugModuleInterfaceOperation{DmiOperation::WRITE, address, value}
|
||||
);
|
||||
|
||||
if (response.operationStatus != DmiOperationStatus::SUCCESS) {
|
||||
if (response.operationStatus == DmiOperationStatus::SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.operationStatus == DmiOperationStatus::FAILED) {
|
||||
throw Exceptions::DeviceCommunicationFailure{"DMI operation failed"};
|
||||
}
|
||||
|
||||
// Busy response...
|
||||
++attempt;
|
||||
}
|
||||
|
||||
throw Exceptions::DeviceCommunicationFailure{"DMI operation timed out"};
|
||||
}
|
||||
|
||||
void WchLinkInterface::writeFlashMemory(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
@@ -61,11 +62,14 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|
||||
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;
|
||||
static constexpr std::uint8_t DMI_OP_MAX_RETRY = 10;
|
||||
|
||||
Usb::UsbInterface& usbInterface;
|
||||
|
||||
std::uint16_t commandEndpointMaxPacketSize = 0;
|
||||
std::uint16_t dataEndpointMaxPacketSize = 0;
|
||||
// TODO: Move this into a config param
|
||||
std::chrono::microseconds dmiOpRetryDelay = std::chrono::microseconds{10};
|
||||
|
||||
/**
|
||||
* The 'target activation' command returns a payload of 5 bytes.
|
||||
|
||||
Reference in New Issue
Block a user