From a0bff0ef3a429ff65ee3b3c8b0793a27d93bfd06 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 13 Jun 2022 09:50:16 +0200 Subject: [PATCH] Introduce register map + use Read/Write register --- src/CMakeLists.txt | 2 +- src/application.cpp | 74 +++++++++++++++++++++++--------------- src/application.h | 2 ++ src/registers.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++ src/registers.h | 6 ++++ src/version.c | 4 ++- src/version.h | 9 ++++- 7 files changed, 151 insertions(+), 32 deletions(-) create mode 100644 src/registers.cpp create mode 100644 src/registers.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f60e12c..932e07e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -target_sources(firmware PRIVATE application.cpp debug.cpp main.cpp) +target_sources(firmware PRIVATE application.cpp debug.cpp main.cpp registers.cpp version.c) target_link_libraries(firmware LUFA) diff --git a/src/application.cpp b/src/application.cpp index 3a40ff2..29464b5 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -1,5 +1,6 @@ /// @file #include "application.h" +#include "registers.h" #include "modules/leds.h" #include "modules/globals.h" @@ -157,33 +158,33 @@ void Application::ReportFINDA(const mp::RequestMsg &rq) { modules::serial::WriteToUSART(rsp, len); } -void Application::ReportVersion(const mp::RequestMsg &rq) { - uint8_t v = 0; +//void Application::ReportVersion(const mp::RequestMsg &rq) { +// uint8_t v = 0; - switch (rq.value) { - case 0: - v = project_version_major; - break; - case 1: - v = project_version_minor; - break; - case 2: - v = project_version_revision; - break; - case 3: - // @@TODO may be allow reporting uint16_t number of errors, - // but anything beyond 255 errors means there is something seriously wrong with the MMU - v = mg::globals.DriveErrors(); - break; - default: - v = 0; - break; - } +// switch (rq.value) { +// case 0: +// v = project_version_major; +// break; +// case 1: +// v = project_version_minor; +// break; +// case 2: +// v = project_version_revision; +// break; +// case 3: +// // @@TODO may be allow reporting uint16_t number of errors, +// // but anything beyond 255 errors means there is something seriously wrong with the MMU +// v = mg::globals.DriveErrors(); +// break; +// default: +// v = 0; +// break; +// } - uint8_t rsp[10]; - uint8_t len = protocol.EncodeResponseVersion(rq, v, rsp); - modules::serial::WriteToUSART(rsp, len); -} +// uint8_t rsp[10]; +// uint8_t len = protocol.EncodeResponseVersion(rq, v, rsp); +// modules::serial::WriteToUSART(rsp, len); +//} void Application::ReportRunningCommand() { uint8_t rsp[maxMsgLen]; @@ -191,6 +192,21 @@ void Application::ReportRunningCommand() { modules::serial::WriteToUSART(rsp, len); } +void Application::ReportReadRegister(const mp::RequestMsg &rq) { + uint8_t rsp[maxMsgLen]; + uint16_t value2; + bool accepted = ReadRegister(rq.value, value2); + uint8_t len = protocol.EncodeResponseRead(rq, accepted, value2, rsp); + modules::serial::WriteToUSART(rsp, len); +} + +void Application::ReportWriteRegister(const mp::RequestMsg &rq) { + uint8_t rsp[maxMsgLen]; + mp::ResponseMsgParamCodes ar = WriteRegister(rq.value, rq.value2) ? mp::ResponseMsgParamCodes::Accepted : mp::ResponseMsgParamCodes::Rejected; + uint8_t len = protocol.EncodeResponseCmdAR(rq, ar, rsp); + modules::serial::WriteToUSART(rsp, len); +} + void Application::ProcessRequestMsg(const mp::RequestMsg &rq) { switch (rq.code) { case mp::RequestMsgCodes::Button: @@ -211,12 +227,12 @@ void Application::ProcessRequestMsg(const mp::RequestMsg &rq) { hal::cpu::Reset(); break; case mp::RequestMsgCodes::Version: - ReportVersion(rq); - break; case mp::RequestMsgCodes::Read: - break; // @@TODO - not used anywhere yet + ReportReadRegister(rq); + break; case mp::RequestMsgCodes::Write: - break; // @@TODO - not used anywhere yet + ReportWriteRegister(rq); + break; case mp::RequestMsgCodes::Cut: case mp::RequestMsgCodes::Eject: case mp::RequestMsgCodes::Home: diff --git a/src/application.h b/src/application.h index fe69cf0..97ade21 100644 --- a/src/application.h +++ b/src/application.h @@ -39,6 +39,8 @@ private: void ReportFINDA(const mp::RequestMsg &rq); void ReportVersion(const mp::RequestMsg &rq); void ReportRunningCommand(); + void ReportReadRegister(const mp::RequestMsg &rq); + void ReportWriteRegister(const mp::RequestMsg &rq); void ProcessRequestMsg(const mp::RequestMsg &rq); uint16_t lastCommandProcessedMs; diff --git a/src/registers.cpp b/src/registers.cpp new file mode 100644 index 0000000..cdb708f --- /dev/null +++ b/src/registers.cpp @@ -0,0 +1,86 @@ +#include "registers.h" +#include "version.h" + +struct RegisterFlags { + uint8_t writable : 1; + uint8_t eeprom : 1; // 1: register is located in eeprom + uint8_t size : 2; // 0: 1 bit, 1: 1 byte, 2: 2 bytes + constexpr RegisterFlags(bool writable, uint8_t size) + : writable(writable) + , eeprom(0) + , size(size) {} + constexpr RegisterFlags(bool writable, bool eeprom, uint8_t size) + : writable(writable) + , eeprom(eeprom) + , size(size) {} +}; + +struct RegisterRec { + RegisterFlags flags; + void *address; + template + constexpr RegisterRec(bool writable, T *address) + : flags(RegisterFlags(writable, sizeof(T))) + , address((void *)address) {} + constexpr RegisterRec(bool writable, bool eeprom, void *eepromAddress, uint8_t bytes) + : flags(RegisterFlags(writable, eeprom, bytes)) + , address(eepromAddress) {} +}; + +static const RegisterRec registers[] = { + RegisterRec(false, &project_major), + RegisterRec(false, &project_minor), + RegisterRec(false, &project_build_number), + RegisterRec(false, true, (void *)0, 2), // @@TODO needs improvement + +}; + +static constexpr uint8_t registersSize = sizeof(registers) / sizeof(RegisterRec); + +bool ReadRegister(uint8_t address, uint16_t &value) { + if (address >= registersSize) { + return false; + } + value = 0; + if (!registers[address].flags.eeprom) { + switch (registers[address].flags.size) { + case 0: + case 1: + value = *(uint8_t *)registers[address].address; + break; + case 2: + value = *(uint16_t *)registers[address].address; + break; + default: + return false; + } + return true; + } else { + return false; // @@TODO + } +} + +bool WriteRegister(uint8_t address, uint16_t value) { + if (address >= registersSize) { + return false; + } + if (!registers[address].flags.writable) { + return false; + } + if (!registers[address].flags.eeprom) { + switch (registers[address].flags.size) { + case 0: + case 1: + *(uint8_t *)registers[address].address = value; + break; + case 2: + *(uint16_t *)registers[address].address = value; + break; + default: + return false; + } + return true; + } else { + return false; // @@TODO + } +} diff --git a/src/registers.h b/src/registers.h new file mode 100644 index 0000000..a931382 --- /dev/null +++ b/src/registers.h @@ -0,0 +1,6 @@ +/// @file +#pragma once +#include + +bool ReadRegister(uint8_t address, uint16_t &value); +bool WriteRegister(uint8_t address, uint16_t value); diff --git a/src/version.c b/src/version.c index 76955ef..5c44d65 100644 --- a/src/version.c +++ b/src/version.c @@ -12,4 +12,6 @@ const char project_version_suffix[] = STR(FW_VERSION_SUFFIX); const char project_version_suffix_short[] = STR(FW_VERSION_SUFFIX_SHORT); -const int project_build_number = FW_BUILD_NUMBER; +const uint8_t project_major = project_version_major; +const uint8_t project_minor = project_version_minor; +const uint16_t project_build_number = FW_BUILD_NUMBER; diff --git a/src/version.h b/src/version.h index 6127dfd..1ab2e80 100644 --- a/src/version.h +++ b/src/version.h @@ -1,5 +1,6 @@ /// @file version.h #pragma once +#include #ifdef __cplusplus extern "C" { @@ -21,8 +22,14 @@ extern const char project_version_suffix[]; /// Project's short version suffix (+1035) extern const char project_version_suffix_short[]; +/// Project's major version +extern const uint8_t project_major; + +/// Project's minor version +extern const uint8_t project_minor; + /// Project's build number (number of commits in a branch) -extern const int project_build_number; +extern const uint16_t project_build_number; /// Firmware name extern const char project_firmware_name[];