GPIO pad state access and manipulation for WCH RISC-V targets
This commit is contained in:
@@ -287,14 +287,6 @@ namespace Targets::RiscV
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetGpioPadDescriptorAndStatePairs RiscV::getGpioPadStates(const TargetPadDescriptors& padDescriptors) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void RiscV::setGpioPadState(const TargetPadDescriptor& padDescriptor, const TargetGpioPadState& state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void RiscV::enableProgrammingMode() {
|
void RiscV::enableProgrammingMode() {
|
||||||
this->riscVDebugInterface->enableProgrammingMode();
|
this->riscVDebugInterface->enableProgrammingMode();
|
||||||
this->programmingMode = true;
|
this->programmingMode = true;
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ namespace Targets::RiscV
|
|||||||
TargetStackPointer getStackPointer() override;
|
TargetStackPointer getStackPointer() override;
|
||||||
void setStackPointer(TargetStackPointer stackPointer) override;
|
void setStackPointer(TargetStackPointer stackPointer) override;
|
||||||
|
|
||||||
TargetGpioPadDescriptorAndStatePairs getGpioPadStates(const TargetPadDescriptors& padDescriptors) override;
|
|
||||||
void setGpioPadState(const TargetPadDescriptor& padDescriptor, const TargetGpioPadState& state) override;
|
|
||||||
|
|
||||||
void enableProgrammingMode() override;
|
void enableProgrammingMode() override;
|
||||||
void disableProgrammingMode() override;
|
void disableProgrammingMode() override;
|
||||||
bool programmingModeEnabled() override;
|
bool programmingModeEnabled() override;
|
||||||
|
|||||||
41
src/Targets/RiscV/Wch/GpioPadDescriptor.hpp
Normal file
41
src/Targets/RiscV/Wch/GpioPadDescriptor.hpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "src/Targets/TargetPadDescriptor.hpp"
|
||||||
|
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
||||||
|
#include "src/Targets/TargetBitFieldDescriptor.hpp"
|
||||||
|
|
||||||
|
namespace Targets::RiscV::Wch
|
||||||
|
{
|
||||||
|
enum class GpioPadDirection: std::uint8_t
|
||||||
|
{
|
||||||
|
INPUT = 0x00,
|
||||||
|
OUTPUT = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GpioPadInputMode: std::uint8_t
|
||||||
|
{
|
||||||
|
ANALOG = 0x00,
|
||||||
|
FLOATING = 0x01,
|
||||||
|
PULLED = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GpioPadOutputMode: std::uint8_t
|
||||||
|
{
|
||||||
|
GENERAL_PURPOSE = 0x00,
|
||||||
|
ALTERNATE_FUNCTION = 0x01,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GpioPadDescriptor
|
||||||
|
{
|
||||||
|
const TargetBitFieldDescriptor& peripheralClockEnableBitFieldDescriptor;
|
||||||
|
const TargetRegisterDescriptor& configRegisterDescriptor;
|
||||||
|
const TargetBitFieldDescriptor& configBitFieldDescriptor;
|
||||||
|
const TargetBitFieldDescriptor& modeBitFieldDescriptor;
|
||||||
|
const TargetRegisterDescriptor& inputDataRegisterDescriptor;
|
||||||
|
const TargetBitFieldDescriptor& inputDataBitFieldDescriptor;
|
||||||
|
const TargetRegisterDescriptor& outputDataRegisterDescriptor;
|
||||||
|
const TargetBitFieldDescriptor& outputDataBitFieldDescriptor;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -38,6 +38,19 @@ namespace Targets::RiscV::Wch
|
|||||||
, flashStatusRegisterDescriptor(this->flashPeripheralDescriptor.getRegisterDescriptor("flash", "statr"))
|
, flashStatusRegisterDescriptor(this->flashPeripheralDescriptor.getRegisterDescriptor("flash", "statr"))
|
||||||
, flashStatusBootLockFieldDescriptor(this->flashStatusRegisterDescriptor.getBitFieldDescriptor("boot_lock"))
|
, flashStatusBootLockFieldDescriptor(this->flashStatusRegisterDescriptor.getBitFieldDescriptor("boot_lock"))
|
||||||
, flashStatusBootModeFieldDescriptor(this->flashStatusRegisterDescriptor.getBitFieldDescriptor("boot_mode"))
|
, flashStatusBootModeFieldDescriptor(this->flashStatusRegisterDescriptor.getBitFieldDescriptor("boot_mode"))
|
||||||
|
, rccPeripheralDescriptor(this->targetDescriptionFile.getTargetPeripheralDescriptor("rcc"))
|
||||||
|
, portPeripheralClockEnableRegisterDescriptor(
|
||||||
|
this->rccPeripheralDescriptor.getRegisterDescriptor("rcc", "apb2pcenr")
|
||||||
|
)
|
||||||
|
, padDescriptors(this->targetDescriptionFile.targetPadDescriptors())
|
||||||
|
, gpioPortPeripheralDescriptors(this->targetDescriptionFile.gpioPortPeripheralDescriptors())
|
||||||
|
, gpioPadDescriptorsByPadId(
|
||||||
|
WchRiscV::generateGpioPadDescriptorMapping(
|
||||||
|
this->portPeripheralClockEnableRegisterDescriptor,
|
||||||
|
this->gpioPortPeripheralDescriptors,
|
||||||
|
this->padDescriptors
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
this->targetConfig.programSegmentKey.has_value()
|
this->targetConfig.programSegmentKey.has_value()
|
||||||
@@ -363,6 +376,112 @@ namespace Targets::RiscV::Wch
|
|||||||
return programCounter;
|
return programCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TargetGpioPadDescriptorAndStatePairs WchRiscV::getGpioPadStates(const TargetPadDescriptors& padDescriptors) {
|
||||||
|
auto cachedRegsById = std::unordered_map<TargetRegisterId, DynamicRegisterValue>{};
|
||||||
|
const auto readGpioReg = [this, &cachedRegsById] (const TargetRegisterDescriptor& descriptor)
|
||||||
|
-> DynamicRegisterValue& {
|
||||||
|
auto cachedRegIt = cachedRegsById.find(descriptor.id);
|
||||||
|
if (cachedRegIt == cachedRegsById.end()) {
|
||||||
|
cachedRegIt = cachedRegsById.emplace(
|
||||||
|
descriptor.id,
|
||||||
|
this->readRegisterDynamicValue(descriptor)
|
||||||
|
).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedRegIt->second;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto output = TargetGpioPadDescriptorAndStatePairs{};
|
||||||
|
|
||||||
|
for (const auto* padDescriptor : padDescriptors) {
|
||||||
|
const auto gpioPadDescriptorIt = this->gpioPadDescriptorsByPadId.find(padDescriptor->id);
|
||||||
|
if (gpioPadDescriptorIt == this->gpioPadDescriptorsByPadId.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& gpioPadDescriptor = gpioPadDescriptorIt->second;
|
||||||
|
|
||||||
|
const auto& portClockEnableRegisterValue = readGpioReg(this->portPeripheralClockEnableRegisterDescriptor);
|
||||||
|
if (!portClockEnableRegisterValue.bitFieldAs<bool>(gpioPadDescriptor.peripheralClockEnableBitFieldDescriptor)) {
|
||||||
|
// The port peripheral is currently disabled. We cannot obtain any meaningful state for this pad
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& configRegisterValue = readGpioReg(gpioPadDescriptor.configRegisterDescriptor);
|
||||||
|
const auto padMode = configRegisterValue.bitField(gpioPadDescriptor.modeBitFieldDescriptor);
|
||||||
|
|
||||||
|
if (padMode == static_cast<std::uint8_t>(GpioPadDirection::INPUT)) {
|
||||||
|
output.emplace_back(
|
||||||
|
TargetGpioPadDescriptorAndStatePair{
|
||||||
|
*padDescriptor,
|
||||||
|
TargetGpioPadState{
|
||||||
|
readGpioReg(gpioPadDescriptor.inputDataRegisterDescriptor).bitFieldAs<bool>(
|
||||||
|
gpioPadDescriptor.inputDataBitFieldDescriptor
|
||||||
|
) ? TargetGpioPadState::State::HIGH : TargetGpioPadState::State::LOW,
|
||||||
|
TargetGpioPadState::DataDirection::INPUT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.emplace_back(
|
||||||
|
TargetGpioPadDescriptorAndStatePair{
|
||||||
|
*padDescriptor,
|
||||||
|
TargetGpioPadState{
|
||||||
|
readGpioReg(gpioPadDescriptor.outputDataRegisterDescriptor).bitFieldAs<bool>(
|
||||||
|
gpioPadDescriptor.outputDataBitFieldDescriptor
|
||||||
|
) ? TargetGpioPadState::State::HIGH : TargetGpioPadState::State::LOW,
|
||||||
|
TargetGpioPadState::DataDirection::OUTPUT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WchRiscV::setGpioPadState(const TargetPadDescriptor& padDescriptor, const TargetGpioPadState& state) {
|
||||||
|
const auto gpioPadDescriptorIt = this->gpioPadDescriptorsByPadId.find(padDescriptor.id);
|
||||||
|
if (gpioPadDescriptorIt == this->gpioPadDescriptorsByPadId.end()) {
|
||||||
|
throw Exceptions::Exception{"Unknown pad"};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& gpioPadDescriptor = gpioPadDescriptorIt->second;
|
||||||
|
|
||||||
|
auto configRegisterValue = this->readRegisterDynamicValue(gpioPadDescriptor.configRegisterDescriptor);
|
||||||
|
const auto currentDir = configRegisterValue.bitField(
|
||||||
|
gpioPadDescriptor.modeBitFieldDescriptor
|
||||||
|
) == static_cast<std::uint8_t>(GpioPadDirection::INPUT)
|
||||||
|
? TargetGpioPadState::DataDirection::INPUT
|
||||||
|
: TargetGpioPadState::DataDirection::OUTPUT;
|
||||||
|
|
||||||
|
if (currentDir != state.direction) {
|
||||||
|
configRegisterValue.setBitField(
|
||||||
|
gpioPadDescriptor.modeBitFieldDescriptor,
|
||||||
|
static_cast<std::uint8_t>(
|
||||||
|
state.direction == TargetGpioPadState::DataDirection::INPUT
|
||||||
|
? GpioPadDirection::INPUT
|
||||||
|
: GpioPadDirection::OUTPUT
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this->writeRegister(gpioPadDescriptor.configRegisterDescriptor, configRegisterValue.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.direction == TargetGpioPadState::DataDirection::OUTPUT) {
|
||||||
|
auto outDataRegisterValue = this->readRegisterDynamicValue(gpioPadDescriptor.outputDataRegisterDescriptor);
|
||||||
|
outDataRegisterValue.setBitField(
|
||||||
|
gpioPadDescriptor.outputDataBitFieldDescriptor,
|
||||||
|
state.value == TargetGpioPadState::State::HIGH
|
||||||
|
? 0x01
|
||||||
|
: 0x00
|
||||||
|
);
|
||||||
|
this->writeRegister(gpioPadDescriptor.outputDataRegisterDescriptor, outDataRegisterValue.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string WchRiscV::passthroughCommandHelpText() {
|
std::string WchRiscV::passthroughCommandHelpText() {
|
||||||
using Services::StringService;
|
using Services::StringService;
|
||||||
|
|
||||||
@@ -574,4 +693,170 @@ namespace Targets::RiscV::Wch
|
|||||||
|
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<TargetPadId, GpioPadDescriptor> WchRiscV::generateGpioPadDescriptorMapping(
|
||||||
|
const TargetRegisterDescriptor& portPeripheralClockEnableRegisterDescriptor,
|
||||||
|
const std::vector<TargetPeripheralDescriptor>& portPeripheralDescriptors,
|
||||||
|
const std::vector<TargetPadDescriptor>& padDescriptors
|
||||||
|
) {
|
||||||
|
static const auto findConfigBitField = [] (
|
||||||
|
const TargetPadDescriptor& padDescriptor,
|
||||||
|
const TargetRegisterDescriptor& configRegisterDescriptor
|
||||||
|
) -> std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>> {
|
||||||
|
return padDescriptor.key.size() >= 3
|
||||||
|
? configRegisterDescriptor.tryGetBitFieldDescriptor("cnf" + padDescriptor.key.substr(2))
|
||||||
|
: std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const auto findModeBitField = [] (
|
||||||
|
const TargetPadDescriptor& padDescriptor,
|
||||||
|
const TargetRegisterDescriptor& configRegisterDescriptor
|
||||||
|
) -> std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>> {
|
||||||
|
return padDescriptor.key.size() >= 3
|
||||||
|
? configRegisterDescriptor.tryGetBitFieldDescriptor("mode" + padDescriptor.key.substr(2))
|
||||||
|
: std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const auto findInputDataBitField = [] (
|
||||||
|
const TargetPadDescriptor& padDescriptor,
|
||||||
|
const TargetRegisterDescriptor& inputDataRegisterDescriptor
|
||||||
|
) -> std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>> {
|
||||||
|
return padDescriptor.key.size() >= 3
|
||||||
|
? inputDataRegisterDescriptor.tryGetBitFieldDescriptor("indr" + padDescriptor.key.substr(2))
|
||||||
|
: std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const auto findOutputDataBitField = [] (
|
||||||
|
const TargetPadDescriptor& padDescriptor,
|
||||||
|
const TargetRegisterDescriptor& outputDataRegisterDescriptor
|
||||||
|
) -> std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>> {
|
||||||
|
return padDescriptor.key.size() >= 3
|
||||||
|
? outputDataRegisterDescriptor.tryGetBitFieldDescriptor("odr" + padDescriptor.key.substr(2))
|
||||||
|
: std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto output = std::map<TargetPadId, GpioPadDescriptor>{};
|
||||||
|
|
||||||
|
for (const auto& padDesc : padDescriptors) {
|
||||||
|
if (padDesc.type != TargetPadType::GPIO) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& peripheralDesc : portPeripheralDescriptors) {
|
||||||
|
if (
|
||||||
|
!peripheralDesc.tryGetFirstSignalDescriptor(padDesc.key).has_value()
|
||||||
|
|| peripheralDesc.key.size() < 5
|
||||||
|
|| peripheralDesc.key.find("port") != 0
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto portLetter = peripheralDesc.key.substr(4, 1);
|
||||||
|
const auto peripheralClockEnableBitFieldDescOpt = portPeripheralClockEnableRegisterDescriptor.tryGetBitFieldDescriptor(
|
||||||
|
"iop" + portLetter + "en"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!peripheralClockEnableBitFieldDescOpt.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto configRegisterDescOpt = std::optional<std::reference_wrapper<const TargetRegisterDescriptor>>{};
|
||||||
|
auto configBitFieldDescOpt = std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>>{};
|
||||||
|
auto modeBitFieldDescOpt = std::optional<std::reference_wrapper<const TargetBitFieldDescriptor>>{};
|
||||||
|
|
||||||
|
const auto portGroupDescOpt = peripheralDesc.tryGetRegisterGroupDescriptor("port");
|
||||||
|
if (!portGroupDescOpt.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& portGroupDescriptor = portGroupDescOpt->get();
|
||||||
|
|
||||||
|
const auto configLowRegisterDescOpt = portGroupDescriptor.tryGetRegisterDescriptor("cfglr");
|
||||||
|
const auto configHighRegisterDescOpt = portGroupDescriptor.tryGetRegisterDescriptor("cfghr");
|
||||||
|
const auto configExtendedRegisterDescOpt = portGroupDescriptor.tryGetRegisterDescriptor("cfgxr");
|
||||||
|
|
||||||
|
if (configLowRegisterDescOpt.has_value()) {
|
||||||
|
const auto& configLowRegisterDescriptor = configLowRegisterDescOpt->get();
|
||||||
|
|
||||||
|
configBitFieldDescOpt = findConfigBitField(padDesc, configLowRegisterDescriptor);
|
||||||
|
modeBitFieldDescOpt = findModeBitField(padDesc, configLowRegisterDescriptor);
|
||||||
|
|
||||||
|
if (configBitFieldDescOpt.has_value()) {
|
||||||
|
configRegisterDescOpt = configLowRegisterDescOpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!configBitFieldDescOpt.has_value() || !modeBitFieldDescOpt.has_value())
|
||||||
|
&& configHighRegisterDescOpt.has_value()
|
||||||
|
) {
|
||||||
|
const auto& configHighRegisterDescriptor = configHighRegisterDescOpt->get();
|
||||||
|
|
||||||
|
configBitFieldDescOpt = findConfigBitField(padDesc, configHighRegisterDescriptor);
|
||||||
|
modeBitFieldDescOpt = findModeBitField(padDesc, configHighRegisterDescriptor);
|
||||||
|
|
||||||
|
if (configBitFieldDescOpt.has_value()) {
|
||||||
|
configRegisterDescOpt = configHighRegisterDescOpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!configBitFieldDescOpt.has_value() || !modeBitFieldDescOpt.has_value())
|
||||||
|
&& configExtendedRegisterDescOpt.has_value()
|
||||||
|
) {
|
||||||
|
const auto& configExtendedRegisterDescriptor = configExtendedRegisterDescOpt->get();
|
||||||
|
|
||||||
|
configBitFieldDescOpt = findConfigBitField(padDesc, configExtendedRegisterDescriptor);
|
||||||
|
modeBitFieldDescOpt = findModeBitField(padDesc, configExtendedRegisterDescriptor);
|
||||||
|
|
||||||
|
if (configBitFieldDescOpt.has_value()) {
|
||||||
|
configRegisterDescOpt = configExtendedRegisterDescOpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!configRegisterDescOpt.has_value()
|
||||||
|
|| !configBitFieldDescOpt.has_value()
|
||||||
|
|| !modeBitFieldDescOpt.has_value()
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto inputDataRegisterDescOpt = portGroupDescriptor.tryGetRegisterDescriptor("indr");
|
||||||
|
const auto outputDataRegisterDescOpt = portGroupDescriptor.tryGetRegisterDescriptor("outdr");
|
||||||
|
|
||||||
|
if (!inputDataRegisterDescOpt.has_value() || !outputDataRegisterDescOpt.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& inputDataRegisterDescriptor = inputDataRegisterDescOpt->get();
|
||||||
|
const auto& outputDataRegisterDescriptor = outputDataRegisterDescOpt->get();
|
||||||
|
|
||||||
|
const auto inputBitFieldDescOpt = findInputDataBitField(padDesc, inputDataRegisterDescriptor);
|
||||||
|
const auto outputBitFieldDescOpt = findOutputDataBitField(padDesc, outputDataRegisterDescriptor);
|
||||||
|
|
||||||
|
if (!inputBitFieldDescOpt.has_value() || !outputBitFieldDescOpt.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.emplace(
|
||||||
|
padDesc.id,
|
||||||
|
GpioPadDescriptor{
|
||||||
|
.peripheralClockEnableBitFieldDescriptor = peripheralClockEnableBitFieldDescOpt->get(),
|
||||||
|
.configRegisterDescriptor = configRegisterDescOpt->get(),
|
||||||
|
.configBitFieldDescriptor = configBitFieldDescOpt->get(),
|
||||||
|
.modeBitFieldDescriptor = modeBitFieldDescOpt->get(),
|
||||||
|
.inputDataRegisterDescriptor = inputDataRegisterDescriptor,
|
||||||
|
.inputDataBitFieldDescriptor = inputBitFieldDescOpt->get(),
|
||||||
|
.outputDataRegisterDescriptor = outputDataRegisterDescriptor,
|
||||||
|
.outputDataBitFieldDescriptor = outputBitFieldDescOpt->get(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,16 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "src/Targets/RiscV/RiscV.hpp"
|
#include "src/Targets/RiscV/RiscV.hpp"
|
||||||
|
#include "src/Targets/TargetPeripheralDescriptor.hpp"
|
||||||
|
#include "src/Targets/TargetPadDescriptor.hpp"
|
||||||
|
|
||||||
#include "WchRiscVTargetConfig.hpp"
|
#include "WchRiscVTargetConfig.hpp"
|
||||||
#include "TargetDescriptionFile.hpp"
|
#include "TargetDescriptionFile.hpp"
|
||||||
|
#include "GpioPadDescriptor.hpp"
|
||||||
|
|
||||||
namespace Targets::RiscV::Wch
|
namespace Targets::RiscV::Wch
|
||||||
{
|
{
|
||||||
@@ -43,6 +48,9 @@ namespace Targets::RiscV::Wch
|
|||||||
|
|
||||||
TargetMemoryAddress getProgramCounter() override;
|
TargetMemoryAddress getProgramCounter() override;
|
||||||
|
|
||||||
|
TargetGpioPadDescriptorAndStatePairs getGpioPadStates(const TargetPadDescriptors& padDescriptors) override;
|
||||||
|
void setGpioPadState(const TargetPadDescriptor& padDescriptor, const TargetGpioPadState& state) override;
|
||||||
|
|
||||||
std::string passthroughCommandHelpText() override;
|
std::string passthroughCommandHelpText() override;
|
||||||
std::optional<PassthroughResponse> invokePassthroughCommand(const PassthroughCommand& command) override;
|
std::optional<PassthroughResponse> invokePassthroughCommand(const PassthroughCommand& command) override;
|
||||||
|
|
||||||
@@ -84,6 +92,13 @@ namespace Targets::RiscV::Wch
|
|||||||
const TargetBitFieldDescriptor& flashStatusBootLockFieldDescriptor;
|
const TargetBitFieldDescriptor& flashStatusBootLockFieldDescriptor;
|
||||||
const TargetBitFieldDescriptor& flashStatusBootModeFieldDescriptor;
|
const TargetBitFieldDescriptor& flashStatusBootModeFieldDescriptor;
|
||||||
|
|
||||||
|
const TargetPeripheralDescriptor rccPeripheralDescriptor;
|
||||||
|
const TargetRegisterDescriptor& portPeripheralClockEnableRegisterDescriptor;
|
||||||
|
|
||||||
|
std::vector<TargetPadDescriptor> padDescriptors;
|
||||||
|
std::vector<TargetPeripheralDescriptor> gpioPortPeripheralDescriptors;
|
||||||
|
std::map<TargetPadId, GpioPadDescriptor> gpioPadDescriptorsByPadId;
|
||||||
|
|
||||||
const TargetMemorySegmentDescriptor& resolveAliasedMemorySegment();
|
const TargetMemorySegmentDescriptor& resolveAliasedMemorySegment();
|
||||||
TargetMemoryAddress transformMappedAddress(
|
TargetMemoryAddress transformMappedAddress(
|
||||||
TargetMemoryAddress address,
|
TargetMemoryAddress address,
|
||||||
@@ -94,5 +109,11 @@ namespace Targets::RiscV::Wch
|
|||||||
void unlockBootModeBitField();
|
void unlockBootModeBitField();
|
||||||
void enableBootMode();
|
void enableBootMode();
|
||||||
void enableUserMode();
|
void enableUserMode();
|
||||||
|
|
||||||
|
static std::map<TargetPadId, GpioPadDescriptor> generateGpioPadDescriptorMapping(
|
||||||
|
const TargetRegisterDescriptor& portPeripheralClockEnableRegisterDescriptor,
|
||||||
|
const std::vector<TargetPeripheralDescriptor>& portPeripheralDescriptors,
|
||||||
|
const std::vector<TargetPadDescriptor>& padDescriptors
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,11 +325,11 @@ namespace Targets::TargetDescription
|
|||||||
std::map<std::string, TargetPadDescriptor> TargetDescriptionFile::targetPadDescriptorsByKey() const {
|
std::map<std::string, TargetPadDescriptor> TargetDescriptionFile::targetPadDescriptorsByKey() const {
|
||||||
auto output = std::map<std::string, TargetPadDescriptor>{};
|
auto output = std::map<std::string, TargetPadDescriptor>{};
|
||||||
|
|
||||||
const auto gpioPadKeys = this->getGpioPadKeys();
|
const auto gpioPeripheralSignalPadKeys = this->getGpioPeripheralSignalPadKeys();
|
||||||
for (const auto& [key, pad] : this->padsByKey) {
|
for (const auto& [key, pad] : this->padsByKey) {
|
||||||
output.emplace(
|
output.emplace(
|
||||||
key,
|
key,
|
||||||
TargetDescriptionFile::targetPadDescriptorFromPad(pad, gpioPadKeys)
|
TargetDescriptionFile::targetPadDescriptorFromPad(pad, gpioPeripheralSignalPadKeys)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,6 +362,17 @@ namespace Targets::TargetDescription
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<TargetPadDescriptor> TargetDescriptionFile::targetPadDescriptors() const {
|
||||||
|
auto output = std::vector<TargetPadDescriptor>{};
|
||||||
|
|
||||||
|
const auto gpioPeripheralSignalPadKeys = this->getGpioPeripheralSignalPadKeys();
|
||||||
|
for (const auto& [key, pad] : this->padsByKey) {
|
||||||
|
output.emplace_back(TargetDescriptionFile::targetPadDescriptorFromPad(pad, gpioPeripheralSignalPadKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<TargetPeripheralDescriptor> TargetDescriptionFile::gpioPortPeripheralDescriptors() const {
|
std::vector<TargetPeripheralDescriptor> TargetDescriptionFile::gpioPortPeripheralDescriptors() const {
|
||||||
auto output = std::vector<TargetPeripheralDescriptor>{};
|
auto output = std::vector<TargetPeripheralDescriptor>{};
|
||||||
|
|
||||||
@@ -505,7 +516,7 @@ namespace Targets::TargetDescription
|
|||||||
return attribute->get();
|
return attribute->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> TargetDescriptionFile::getGpioPadKeys() const {
|
std::set<std::string> TargetDescriptionFile::getGpioPeripheralSignalPadKeys() const {
|
||||||
auto output = std::set<std::string>{};
|
auto output = std::set<std::string>{};
|
||||||
for (const auto* peripheral : this->getGpioPeripherals()) {
|
for (const auto* peripheral : this->getGpioPeripherals()) {
|
||||||
for (const auto& signal : peripheral->sigs) {
|
for (const auto& signal : peripheral->sigs) {
|
||||||
@@ -984,6 +995,7 @@ namespace Targets::TargetDescription
|
|||||||
memorySegment.executable,
|
memorySegment.executable,
|
||||||
memorySegment.access,
|
memorySegment.access,
|
||||||
memorySegment.access,
|
memorySegment.access,
|
||||||
|
false,
|
||||||
memorySegment.pageSize
|
memorySegment.pageSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1153,10 +1165,10 @@ namespace Targets::TargetDescription
|
|||||||
|
|
||||||
TargetPadDescriptor TargetDescriptionFile::targetPadDescriptorFromPad(
|
TargetPadDescriptor TargetDescriptionFile::targetPadDescriptorFromPad(
|
||||||
const Pad& pad,
|
const Pad& pad,
|
||||||
const std::set<std::string>& gpioPadKeys
|
const std::set<std::string>& gpioPeripheralSignalPadKeys
|
||||||
) {
|
) {
|
||||||
static const auto resolvePadType = [&gpioPadKeys] (const Pad& pad) -> TargetPadType {
|
const auto resolvePadType = [&gpioPeripheralSignalPadKeys] (const Pad& pad) -> TargetPadType {
|
||||||
if (gpioPadKeys.contains(pad.key)) {
|
if (gpioPeripheralSignalPadKeys.contains(pad.key)) {
|
||||||
return TargetPadType::GPIO;
|
return TargetPadType::GPIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,6 @@ namespace Targets::TargetDescription
|
|||||||
[[nodiscard]] std::set<const Peripheral*> getModulePeripherals(const std::string& moduleKey) const;
|
[[nodiscard]] std::set<const Peripheral*> getModulePeripherals(const std::string& moduleKey) const;
|
||||||
[[nodiscard]] std::set<const Peripheral*> getGpioPeripherals() const;
|
[[nodiscard]] std::set<const Peripheral*> getGpioPeripherals() const;
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] std::optional<TargetMemorySegmentDescriptor> tryGetTargetMemorySegmentDescriptor(
|
[[nodiscard]] std::optional<TargetMemorySegmentDescriptor> tryGetTargetMemorySegmentDescriptor(
|
||||||
std::string_view addressSpaceKey,
|
std::string_view addressSpaceKey,
|
||||||
std::string_view segmentKey
|
std::string_view segmentKey
|
||||||
@@ -150,6 +149,7 @@ namespace Targets::TargetDescription
|
|||||||
[[nodiscard]] std::map<std::string, TargetPadDescriptor> targetPadDescriptorsByKey() const;
|
[[nodiscard]] std::map<std::string, TargetPadDescriptor> targetPadDescriptorsByKey() const;
|
||||||
[[nodiscard]] std::map<std::string, TargetPinoutDescriptor> targetPinoutDescriptorsByKey() const;
|
[[nodiscard]] std::map<std::string, TargetPinoutDescriptor> targetPinoutDescriptorsByKey() const;
|
||||||
[[nodiscard]] std::map<std::string, TargetVariantDescriptor> targetVariantDescriptorsByKey() const;
|
[[nodiscard]] std::map<std::string, TargetVariantDescriptor> targetVariantDescriptorsByKey() const;
|
||||||
|
[[nodiscard]] std::vector<TargetPadDescriptor> targetPadDescriptors() const;
|
||||||
[[nodiscard]] std::vector<TargetPeripheralDescriptor> gpioPortPeripheralDescriptors() const;
|
[[nodiscard]] std::vector<TargetPeripheralDescriptor> gpioPortPeripheralDescriptors() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -180,7 +180,7 @@ namespace Targets::TargetDescription
|
|||||||
) const;
|
) const;
|
||||||
[[nodiscard]] const std::string& getDeviceAttribute(const std::string& attributeName) const;
|
[[nodiscard]] const std::string& getDeviceAttribute(const std::string& attributeName) const;
|
||||||
|
|
||||||
[[nodiscard]] std::set<std::string> getGpioPadKeys() const;
|
[[nodiscard]] std::set<std::string> getGpioPeripheralSignalPadKeys() const;
|
||||||
|
|
||||||
static std::optional<std::string> tryGetAttribute(const QDomElement& element, const QString& attributeName);
|
static std::optional<std::string> tryGetAttribute(const QDomElement& element, const QString& attributeName);
|
||||||
static std::string getAttribute(const QDomElement& element, const QString& attributeName);
|
static std::string getAttribute(const QDomElement& element, const QString& attributeName);
|
||||||
@@ -244,7 +244,7 @@ namespace Targets::TargetDescription
|
|||||||
|
|
||||||
static TargetPadDescriptor targetPadDescriptorFromPad(
|
static TargetPadDescriptor targetPadDescriptorFromPad(
|
||||||
const Pad& pad,
|
const Pad& pad,
|
||||||
const std::set<std::string>& gpioPadKeys
|
const std::set<std::string>& gpioPeripheralSignalPadKeys
|
||||||
);
|
);
|
||||||
|
|
||||||
static TargetPinoutDescriptor targetPinoutDescriptorFromPinout(const Pinout& pinout);
|
static TargetPinoutDescriptor targetPinoutDescriptorFromPinout(const Pinout& pinout);
|
||||||
|
|||||||
@@ -66,6 +66,18 @@ namespace Targets
|
|||||||
return this->getRegisterGroupDescriptor(groupKey).getRegisterDescriptor(registerKey);
|
return this->getRegisterGroupDescriptor(groupKey).getRegisterDescriptor(registerKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<
|
||||||
|
std::reference_wrapper<const TargetPeripheralSignalDescriptor>
|
||||||
|
> TargetPeripheralDescriptor::tryGetFirstSignalDescriptor(std::string_view padKey) const {
|
||||||
|
for (const auto& signalDescriptor : this->signalDescriptors) {
|
||||||
|
if (signalDescriptor.padKey == padKey) {
|
||||||
|
return std::cref(signalDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
TargetPeripheralDescriptor TargetPeripheralDescriptor::clone() const {
|
TargetPeripheralDescriptor TargetPeripheralDescriptor::clone() const {
|
||||||
auto output = TargetPeripheralDescriptor{
|
auto output = TargetPeripheralDescriptor{
|
||||||
this->key,
|
this->key,
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ namespace Targets
|
|||||||
const std::string& registerKey
|
const std::string& registerKey
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<
|
||||||
|
std::reference_wrapper<const TargetPeripheralSignalDescriptor>
|
||||||
|
> tryGetFirstSignalDescriptor(std::string_view padKey) const;
|
||||||
|
|
||||||
[[nodiscard]] TargetPeripheralDescriptor clone() const;
|
[[nodiscard]] TargetPeripheralDescriptor clone() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user