Massive refactor to accommodate RISC-V targets

- Refactored entire codebase (excluding the Insight component) to accommodate multiple target architectures (no longer specific to AVR)
- Deleted 'generate SVD' GDB monitor command - I will eventually move this functionality to the Bloom website
- Added unit size property to address spaces
- Many other changes which I couldn't be bothered to describe here
This commit is contained in:
Nav
2024-07-23 21:14:22 +01:00
parent 2986934485
commit 6cdbfbe950
331 changed files with 8815 additions and 8565 deletions

View File

@@ -18,9 +18,10 @@
namespace DebugToolDrivers::Wch::Protocols::WchLink
{
using namespace ::DebugToolDrivers::Protocols::RiscVDebugSpec;
using namespace Exceptions;
using Targets::RiscV::DebugModule::DmiOperation;
using DebugModule::DmiOperation;
WchLinkInterface::WchLinkInterface(Usb::UsbInterface& usbInterface, Usb::UsbDevice& usbDevice)
: usbInterface(usbInterface)
@@ -29,34 +30,32 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
{}
DeviceInfo WchLinkInterface::getDeviceInfo() {
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::GetDeviceInfo());
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::GetDeviceInfo{});
if (response.payload.size() < 3) {
throw Exceptions::DeviceCommunicationFailure("Cannot construct DeviceInfo response - invalid payload");
throw Exceptions::DeviceCommunicationFailure{"Cannot construct DeviceInfo response - invalid payload"};
}
static const auto variantsById = BiMap<std::uint8_t, WchLinkVariant>({
static const auto variantsById = BiMap<std::uint8_t, WchLinkVariant>{
{0x01, WchLinkVariant::LINK_CH549},
{0x02, WchLinkVariant::LINK_E_CH32V307},
{0x12, WchLinkVariant::LINK_E_CH32V307},
{0x03, WchLinkVariant::LINK_S_CH32V203},
});
};
return DeviceInfo(
WchFirmwareVersion(response.payload[0], response.payload[1]),
WchFirmwareVersion{response.payload[0], response.payload[1]},
response.payload.size() >= 4
? std::optional(variantsById.valueAt(response.payload[2]).value_or(WchLinkVariant::UNKNOWN))
? std::optional{variantsById.valueAt(response.payload[2]).value_or(WchLinkVariant::UNKNOWN)}
: std::nullopt
);
}
void WchLinkInterface::activate(const Targets::RiscV::TargetParameters& targetParameters) {
void WchLinkInterface::activate() {
this->setClockSpeed(WchLinkTargetClockSpeed::CLK_6000_KHZ);
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::AttachTarget());
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::AttachTarget{});
if (response.payload.size() != 5) {
throw Exceptions::DeviceCommunicationFailure("Unexpected response payload size for AttachTarget command");
throw Exceptions::DeviceCommunicationFailure{"Unexpected response payload size for AttachTarget command"};
}
this->cachedTargetId = static_cast<WchTargetId>(
@@ -67,10 +66,9 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
}
void WchLinkInterface::deactivate() {
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::DetachTarget());
const auto response = this->sendCommandAndWaitForResponse(Commands::Control::DetachTarget{});
if (response.payload.size() != 1) {
throw Exceptions::DeviceCommunicationFailure("Unexpected response payload size for DetachTarget command");
throw Exceptions::DeviceCommunicationFailure{"Unexpected response payload size for DetachTarget command"};
}
}
@@ -78,34 +76,32 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
return "0x" + Services::StringService::toHex(this->cachedTargetId.value());
}
Targets::RiscV::DebugModule::RegisterValue WchLinkInterface::readDebugModuleRegister(
Targets::RiscV::DebugModule::RegisterAddress address
) {
using Targets::RiscV::DebugModule::DmiOperationStatus ;
DebugModule::RegisterValue WchLinkInterface::readDebugModuleRegister(DebugModule::RegisterAddress address) {
using DebugModule::DmiOperationStatus;
const auto response = this->sendCommandAndWaitForResponse(
Commands::DebugModuleInterfaceOperation(DmiOperation::READ, address)
Commands::DebugModuleInterfaceOperation{DmiOperation::READ, address}
);
if (response.operationStatus != DmiOperationStatus::SUCCESS) {
throw Exceptions::DeviceCommunicationFailure("DMI operation failed");
throw Exceptions::DeviceCommunicationFailure{"DMI operation failed"};
}
return response.value;
}
void WchLinkInterface::writeDebugModuleRegister(
Targets::RiscV::DebugModule::RegisterAddress address,
Targets::RiscV::DebugModule::RegisterValue value
DebugModule::RegisterAddress address,
DebugModule::RegisterValue value
) {
using Targets::RiscV::DebugModule::DmiOperationStatus ;
using DebugModule::DmiOperationStatus;
const auto response = this->sendCommandAndWaitForResponse(
Commands::DebugModuleInterfaceOperation(DmiOperation::WRITE, address, value)
Commands::DebugModuleInterfaceOperation{DmiOperation::WRITE, address, value}
);
if (response.operationStatus != DmiOperationStatus::SUCCESS) {
throw Exceptions::DeviceCommunicationFailure("DMI operation failed");
throw Exceptions::DeviceCommunicationFailure{"DMI operation failed"};
}
}
@@ -119,36 +115,35 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
std::ceil(static_cast<float>(bufferSize) / static_cast<float>(packetSize))
);
for (std::uint32_t i = 0; i < packetsRequired; ++i) {
for (auto i = std::uint32_t{0}; i < packetsRequired; ++i) {
const auto segmentSize = static_cast<std::uint8_t>(std::min(bufferSize - (i * packetSize), packetSize));
const auto response = this->sendCommandAndWaitForResponse(
Commands::PreparePartialFlashPageWrite(startAddress + (packetSize * i), segmentSize)
Commands::PreparePartialFlashPageWrite{startAddress + (packetSize * i), segmentSize}
);
if (response.payload.size() != 1) {
throw Exceptions::DeviceCommunicationFailure(
throw Exceptions::DeviceCommunicationFailure{
"Unexpected response payload size for PreparePartialFlashPageWrite command"
);
};
}
this->usbInterface.writeBulk(
WchLinkInterface::USB_DATA_ENDPOINT_OUT,
std::vector<unsigned char>(
std::vector<unsigned char>{
buffer.begin() + (packetSize * i),
buffer.begin() + (packetSize * i) + segmentSize
)
}
);
const auto rawResponse = this->usbInterface.readBulk(WchLinkInterface::USB_DATA_ENDPOINT_IN);
if (rawResponse.size() != 4) {
throw Exceptions::DeviceCommunicationFailure("Unexpected response size for partial flash page write");
throw Exceptions::DeviceCommunicationFailure{"Unexpected response size for partial flash page write"};
}
/*
* I have no idea what any of these bytes mean. There's no documentation available for this.
*
* All I know is that these values indicate a successful write.
* I have no idea what any of these bytes mean. I've not been a le to find any documentation for
* this. All I know is that these values indicate a successful write.
*/
if (
rawResponse[0] != 0x41
@@ -156,28 +151,28 @@ namespace DebugToolDrivers::Wch::Protocols::WchLink
|| rawResponse[2] != 0x01
|| rawResponse[3] != 0x02
) {
throw Exceptions::DeviceCommunicationFailure("Partial flash page write failed");
throw Exceptions::DeviceCommunicationFailure{"Partial flash page write failed"};
}
}
}
void WchLinkInterface::setClockSpeed(WchLinkTargetClockSpeed speed) {
const auto speedIdsBySpeed = BiMap<WchLinkTargetClockSpeed, std::uint8_t>({
const auto speedIdsBySpeed = BiMap<WchLinkTargetClockSpeed, std::uint8_t>{
{WchLinkTargetClockSpeed::CLK_6000_KHZ, 0x01},
{WchLinkTargetClockSpeed::CLK_4000_KHZ, 0x02},
{WchLinkTargetClockSpeed::CLK_400_KHZ, 0x03},
});
};
const auto response = this->sendCommandAndWaitForResponse(
Commands::SetClockSpeed(this->cachedTargetGroupId.value_or(0x01), speedIdsBySpeed.at(speed))
Commands::SetClockSpeed{this->cachedTargetGroupId.value_or(0x01), speedIdsBySpeed.at(speed)}
);
if (response.payload.size() != 1) {
throw Exceptions::DeviceCommunicationFailure("Unexpected response payload size for SetClockSpeed command");
throw Exceptions::DeviceCommunicationFailure{"Unexpected response payload size for SetClockSpeed command"};
}
if (response.payload[0] != 0x01) {
throw Exceptions::DeviceCommunicationFailure("Unexpected response for SetClockSpeed command");
throw Exceptions::DeviceCommunicationFailure{"Unexpected response for SetClockSpeed command"};
}
}
}