Add empty EEPROM HAL implementation

pull/21/head
D.R.racer 2021-06-10 11:56:34 +02:00 committed by DRracer
parent dfb57bcae5
commit 9e4bd97968
4 changed files with 337 additions and 324 deletions

View File

@ -188,6 +188,7 @@ target_sources(
src/hal/avr/cpu.cpp src/hal/avr/cpu.cpp
src/hal/avr/usart.cpp src/hal/avr/usart.cpp
src/hal/avr/shr16.cpp src/hal/avr/shr16.cpp
src/hal/avr/eeprom.cpp
src/hal/adc.cpp src/hal/adc.cpp
src/modules/protocol.cpp src/modules/protocol.cpp
src/modules/buttons.cpp src/modules/buttons.cpp
@ -197,6 +198,7 @@ target_sources(
src/modules/idler.cpp src/modules/idler.cpp
src/modules/leds.cpp src/modules/leds.cpp
src/modules/motion.cpp src/modules/motion.cpp
src/modules/permanent_storage.cpp
src/modules/selector.cpp src/modules/selector.cpp
src/logic/command_base.cpp src/logic/command_base.cpp
src/logic/cut_filament.cpp src/logic/cut_filament.cpp

11
src/hal/avr/eeprom.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "../eeprom.h"
namespace hal {
namespace eeprom {
uint8_t ReadByte(const uint8_t *addr) {
return 0;
}
} // namespace eeprom
} // namespace hal

View File

@ -2,19 +2,19 @@
#include <stdint.h> #include <stdint.h>
namespace hal { namespace hal {
namespace EEPROM { namespace eeprom {
/// EEPROM interface /// EEPROM interface
void WriteByte(const uint8_t *addr, uint8_t value); extern void WriteByte(const uint8_t *addr, uint8_t value);
void UpdateByte(const uint8_t *addr, uint8_t value); extern void UpdateByte(const uint8_t *addr, uint8_t value);
uint8_t ReadByte(const uint8_t *addr); extern uint8_t ReadByte(const uint8_t *addr);
void WriteWord(const uint8_t *addr, uint16_t value); extern void WriteWord(const uint8_t *addr, uint16_t value);
void UpdateWord(const uint8_t *addr, uint16_t value); extern void UpdateWord(const uint8_t *addr, uint16_t value);
uint16_t ReadWord(const uint8_t *addr); extern uint16_t ReadWord(const uint8_t *addr);
/// @returns physical end address of EEPROM memory end /// @returns physical end address of EEPROM memory end
constexpr const uint16_t End(); extern constexpr const uint16_t End();
} // namespace EEPROM } // namespace EEPROM
} // namespace hal } // namespace hal

View File

@ -7,86 +7,86 @@ namespace permanent_storage {
#define ARR_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) #define ARR_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
/// @brief EEPROM data layout /// @brief EEPROM data layout
/// ///
/// Do not remove, reorder or change size of existing fields. /// Do not remove, reorder or change size of existing fields.
/// Otherwise values stored with previous version of firmware would be broken. /// Otherwise values stored with previous version of firmware would be broken.
/// It is possible to add fields in the end of this struct, ensuring that erased EEPROM is handled well. /// It is possible to add fields in the end of this struct, ensuring that erased EEPROM is handled well.
/// Last byte in EEPROM is reserved for layoutVersion. If some field is repurposed, layoutVersion /// Last byte in EEPROM is reserved for layoutVersion. If some field is repurposed, layoutVersion
/// needs to be changed to force an EEPROM erase. /// needs to be changed to force an EEPROM erase.
struct eeprom_t { struct eeprom_t {
uint8_t eepromLengthCorrection; ///< Legacy bowden length correction uint8_t eepromLengthCorrection; ///< Legacy bowden length correction
uint16_t eepromBowdenLen[5]; ///< Bowden length for each filament uint16_t eepromBowdenLen[5]; ///< Bowden length for each filament
uint8_t eepromFilamentStatus[3]; ///< Majority vote status of eepromFilament wear leveling uint8_t eepromFilamentStatus[3]; ///< Majority vote status of eepromFilament wear leveling
uint8_t eepromFilament[800]; ///< Top nibble status, bottom nibble last filament loaded uint8_t eepromFilament[800]; ///< Top nibble status, bottom nibble last filament loaded
uint8_t eepromDriveErrorCountH; uint8_t eepromDriveErrorCountH;
uint8_t eepromDriveErrorCountL[2]; uint8_t eepromDriveErrorCountL[2];
} __attribute__((packed)); } __attribute__((packed));
// @@TODO static_assert(sizeof(eeprom_t) - 2 <= hal::EEPROM::End(), "eeprom_t doesn't fit into EEPROM available."); // @@TODO static_assert(sizeof(eeprom_t) - 2 <= hal::EEPROM::End(), "eeprom_t doesn't fit into EEPROM available.");
/// @brief EEPROM layout version /// @brief EEPROM layout version
static const uint8_t layoutVersion = 0xff; static const uint8_t layoutVersion = 0xff;
//d = 6.3 mm pulley diameter //d = 6.3 mm pulley diameter
//c = pi * d pulley circumference //c = pi * d pulley circumference
//FSPR = 200 full steps per revolution (stepper motor constant) (1.8 deg/step) //FSPR = 200 full steps per revolution (stepper motor constant) (1.8 deg/step)
//mres = 2 pulley microstep resolution (uint8_t __res(AX_PUL)) //mres = 2 pulley microstep resolution (uint8_t __res(AX_PUL))
//mres = 2 selector microstep resolution (uint8_t __res(AX_SEL)) //mres = 2 selector microstep resolution (uint8_t __res(AX_SEL))
//mres = 16 idler microstep resolution (uint8_t __res(AX_IDL)) //mres = 16 idler microstep resolution (uint8_t __res(AX_IDL))
//1 pulley ustep = (d*pi)/(mres*FSPR) = 49.48 um //1 pulley ustep = (d*pi)/(mres*FSPR) = 49.48 um
static eeprom_t *const eepromBase = reinterpret_cast<eeprom_t *>(0); ///< First EEPROM address static eeprom_t *const eepromBase = reinterpret_cast<eeprom_t *>(0); ///< First EEPROM address
static const uint16_t eepromEmpty = 0xffff; ///< EEPROM content when erased static const uint16_t eepromEmpty = 0xffff; ///< EEPROM content when erased
static const uint16_t eepromLengthCorrectionBase = 7900u; ///< legacy bowden length correction base (~391mm) static const uint16_t eepromLengthCorrectionBase = 7900u; ///< legacy bowden length correction base (~391mm)
static const uint16_t eepromBowdenLenDefault = 8900u; ///< Default bowden length (~427 mm) static const uint16_t eepromBowdenLenDefault = 8900u; ///< Default bowden length (~427 mm)
static const uint16_t eepromBowdenLenMinimum = 6900u; ///< Minimum bowden length (~341 mm) static const uint16_t eepromBowdenLenMinimum = 6900u; ///< Minimum bowden length (~341 mm)
static const uint16_t eepromBowdenLenMaximum = 16000u; ///< Maximum bowden length (~792 mm) static const uint16_t eepromBowdenLenMaximum = 16000u; ///< Maximum bowden length (~792 mm)
void Init() { void Init() {
if (hal::EEPROM::ReadByte((const uint8_t *)hal::EEPROM::End()) != layoutVersion) { if (hal::eeprom::ReadByte((const uint8_t *)hal::eeprom::End()) != layoutVersion) {
EraseAll(); EraseAll();
} }
} }
/// @brief Erase the whole EEPROM /// @brief Erase the whole EEPROM
void EraseAll() { void EraseAll() {
for (uint16_t i = 0; i < hal::EEPROM::End(); i++) { for (uint16_t i = 0; i < hal::eeprom::End(); i++) {
hal::EEPROM::UpdateByte((uint8_t *)i, static_cast<uint8_t>(eepromEmpty)); hal::eeprom::UpdateByte((uint8_t *)i, static_cast<uint8_t>(eepromEmpty));
}
hal::EEPROM::UpdateByte((const uint8_t *)hal::EEPROM::End(), layoutVersion);
} }
hal::eeprom::UpdateByte((const uint8_t *)hal::eeprom::End(), layoutVersion);
}
/// @brief Is filament number valid? /// @brief Is filament number valid?
/// @retval true valid /// @retval true valid
/// @retval false invalid /// @retval false invalid
static bool validFilament(uint8_t filament) { static bool validFilament(uint8_t filament) {
return filament < ARR_SIZE(eeprom_t::eepromBowdenLen); return filament < ARR_SIZE(eeprom_t::eepromBowdenLen);
} }
/// @brief Is bowden length in valid range? /// @brief Is bowden length in valid range?
/// @param BowdenLength bowden length /// @param BowdenLength bowden length
/// @retval true valid /// @retval true valid
/// @retval false invalid /// @retval false invalid
static bool validBowdenLen(const uint16_t BowdenLength) { static bool validBowdenLen(const uint16_t BowdenLength) {
if ((BowdenLength >= eepromBowdenLenMinimum) if ((BowdenLength >= eepromBowdenLenMinimum)
&& BowdenLength <= eepromBowdenLenMaximum) { && BowdenLength <= eepromBowdenLenMaximum) {
return true; return true;
} }
return false; return false;
} }
/// @brief Get bowden length for active filament /// @brief Get bowden length for active filament
/// ///
/// Returns stored value, doesn't return actual value when it is edited by increase() / decrease() unless it is stored. /// Returns stored value, doesn't return actual value when it is edited by increase() / decrease() unless it is stored.
/// @return stored bowden length /// @return stored bowden length
uint16_t BowdenLength::get() { uint16_t BowdenLength::get() {
uint8_t filament = 0 /*active_extruder*/; //@@TODO uint8_t filament = 0 /*active_extruder*/; //@@TODO
if (validFilament(filament)) { if (validFilament(filament)) {
uint16_t bowdenLength = hal::EEPROM::ReadByte((const uint8_t *)&(eepromBase->eepromBowdenLen[filament])); uint16_t bowdenLength = hal::eeprom::ReadByte((const uint8_t *)&(eepromBase->eepromBowdenLen[filament]));
if (eepromEmpty == bowdenLength) { if (eepromEmpty == bowdenLength) {
const uint8_t LengthCorrectionLegacy = hal::EEPROM::ReadByte(&(eepromBase->eepromLengthCorrection)); const uint8_t LengthCorrectionLegacy = hal::eeprom::ReadByte(&(eepromBase->eepromLengthCorrection));
if (LengthCorrectionLegacy <= 200) { if (LengthCorrectionLegacy <= 200) {
bowdenLength = eepromLengthCorrectionBase + LengthCorrectionLegacy * 10; bowdenLength = eepromLengthCorrectionBase + LengthCorrectionLegacy * 10;
} }
@ -96,90 +96,90 @@ namespace permanent_storage {
} }
return eepromBowdenLenDefault; return eepromBowdenLenDefault;
} }
/// @brief Construct BowdenLength object which allows bowden length manipulation /// @brief Construct BowdenLength object which allows bowden length manipulation
/// ///
/// To be created on stack, new value is permanently stored when object goes out of scope. /// To be created on stack, new value is permanently stored when object goes out of scope.
/// Active filament and associated bowden length is stored in member variables. /// Active filament and associated bowden length is stored in member variables.
BowdenLength::BowdenLength() BowdenLength::BowdenLength()
: filament(/*active_extruder*/ 0) : filament(/*active_extruder*/ 0)
, length(BowdenLength::get()) // @@TODO , length(BowdenLength::get()) // @@TODO
{ {
} }
/// @brief Increase bowden length /// @brief Increase bowden length
/// ///
/// New value is not stored immediately. See ~BowdenLength() for storing permanently. /// New value is not stored immediately. See ~BowdenLength() for storing permanently.
/// @retval true passed /// @retval true passed
/// @retval false failed, it is not possible to increase, new bowden length would be out of range /// @retval false failed, it is not possible to increase, new bowden length would be out of range
bool BowdenLength::increase() { bool BowdenLength::increase() {
if (validBowdenLen(length + stepSize)) { if (validBowdenLen(length + stepSize)) {
length += stepSize; length += stepSize;
return true; return true;
} }
return false; return false;
} }
/// @brief Decrease bowden length /// @brief Decrease bowden length
/// ///
/// New value is not stored immediately. See ~BowdenLength() for storing permanently. /// New value is not stored immediately. See ~BowdenLength() for storing permanently.
/// @retval true passed /// @retval true passed
/// @retval false failed, it is not possible to decrease, new bowden length would be out of range /// @retval false failed, it is not possible to decrease, new bowden length would be out of range
bool BowdenLength::decrease() { bool BowdenLength::decrease() {
if (validBowdenLen(length - stepSize)) { if (validBowdenLen(length - stepSize)) {
length -= stepSize; length -= stepSize;
return true; return true;
} }
return false; return false;
} }
/// @brief Store bowden length permanently. /// @brief Store bowden length permanently.
BowdenLength::~BowdenLength() { BowdenLength::~BowdenLength() {
if (validFilament(filament)) if (validFilament(filament))
hal::EEPROM::UpdateWord((const uint8_t *)&(eepromBase->eepromBowdenLen[filament]), length); hal::eeprom::UpdateWord((const uint8_t *)&(eepromBase->eepromBowdenLen[filament]), length);
} }
/// @brief Get filament storage status /// @brief Get filament storage status
/// ///
/// Uses 2 out of 3 majority vote. /// Uses 2 out of 3 majority vote.
/// ///
/// @return status /// @return status
/// @retval 0xff Uninitialized EEPROM or no 2 values agrees /// @retval 0xff Uninitialized EEPROM or no 2 values agrees
uint8_t FilamentLoaded::getStatus() { uint8_t FilamentLoaded::getStatus() {
if (hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[0])) == hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[1]))) if (hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[0])) == hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[1])))
return hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[0])); return hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[0]));
if (hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[0])) == hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[2]))) if (hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[0])) == hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[2])))
return hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[0])); return hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[0]));
if (hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[1])) == hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[2]))) if (hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[1])) == hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[2])))
return hal::EEPROM::ReadByte(&(eepromBase->eepromFilamentStatus[1])); return hal::eeprom::ReadByte(&(eepromBase->eepromFilamentStatus[1]));
return 0xff; return 0xff;
} }
/// @brief Set filament storage status /// @brief Set filament storage status
/// ///
/// @retval true Succeed /// @retval true Succeed
/// @retval false Failed /// @retval false Failed
bool FilamentLoaded::setStatus(uint8_t status) { bool FilamentLoaded::setStatus(uint8_t status) {
for (uint8_t i = 0; i < ARR_SIZE(eeprom_t::eepromFilamentStatus); ++i) { for (uint8_t i = 0; i < ARR_SIZE(eeprom_t::eepromFilamentStatus); ++i) {
hal::EEPROM::UpdateByte(&(eepromBase->eepromFilamentStatus[i]), status); hal::eeprom::UpdateByte(&(eepromBase->eepromFilamentStatus[i]), status);
} }
if (getStatus() == status) if (getStatus() == status)
return true; return true;
return false; return false;
} }
/// @brief Get index of last valid filament /// @brief Get index of last valid filament
/// ///
/// Depending on status, it searches from the beginning or from the end of eepromFilament[] /// Depending on status, it searches from the beginning or from the end of eepromFilament[]
/// for the first non-matching status. Previous index (of matching status, or out of array bounds) /// for the first non-matching status. Previous index (of matching status, or out of array bounds)
/// is returned. /// is returned.
/// ///
/// @return index to eepromFilament[] of last valid value /// @return index to eepromFilament[] of last valid value
/// it can be out of array range, if first item status doesn't match expected status /// it can be out of array range, if first item status doesn't match expected status
/// getNext(index, status) turns it to first valid index. /// getNext(index, status) turns it to first valid index.
int16_t FilamentLoaded::getIndex() { int16_t FilamentLoaded::getIndex() {
const uint8_t status = getStatus(); const uint8_t status = getStatus();
int16_t index = -1; int16_t index = -1;
switch (status) { switch (status) {
@ -187,7 +187,7 @@ namespace permanent_storage {
case KeyFront2: case KeyFront2:
index = ARR_SIZE(eeprom_t::eepromFilament) - 1; // It is the last one, if no dirty index found index = ARR_SIZE(eeprom_t::eepromFilament) - 1; // It is the last one, if no dirty index found
for (uint16_t i = 0; i < ARR_SIZE(eeprom_t::eepromFilament); ++i) { for (uint16_t i = 0; i < ARR_SIZE(eeprom_t::eepromFilament); ++i) {
if (status != (hal::EEPROM::ReadByte(&(eepromBase->eepromFilament[i])) >> 4)) { if (status != (hal::eeprom::ReadByte(&(eepromBase->eepromFilament[i])) >> 4)) {
index = i - 1; index = i - 1;
break; break;
} }
@ -197,7 +197,7 @@ namespace permanent_storage {
case KeyReverse2: case KeyReverse2:
index = 0; // It is the last one, if no dirty index found index = 0; // It is the last one, if no dirty index found
for (int16_t i = (ARR_SIZE(eeprom_t::eepromFilament) - 1); i >= 0; --i) { for (int16_t i = (ARR_SIZE(eeprom_t::eepromFilament) - 1); i >= 0; --i) {
if (status != (hal::EEPROM::ReadByte(&(eepromBase->eepromFilament[i])) >> 4)) { if (status != (hal::eeprom::ReadByte(&(eepromBase->eepromFilament[i])) >> 4)) {
index = i + 1; index = i + 1;
break; break;
} }
@ -207,17 +207,17 @@ namespace permanent_storage {
break; break;
} }
return index; return index;
} }
/// @brief Get last filament loaded /// @brief Get last filament loaded
/// @param [in,out] filament filament number 0 to 4 /// @param [in,out] filament filament number 0 to 4
/// @retval true success /// @retval true success
/// @retval false failed /// @retval false failed
bool FilamentLoaded::get(uint8_t &filament) { bool FilamentLoaded::get(uint8_t &filament) {
int16_t index = getIndex(); int16_t index = getIndex();
if ((index < 0) || (static_cast<uint16_t>(index) >= ARR_SIZE(eeprom_t::eepromFilament))) if ((index < 0) || (static_cast<uint16_t>(index) >= ARR_SIZE(eeprom_t::eepromFilament)))
return false; return false;
const uint8_t rawFilament = hal::EEPROM::ReadByte(&(eepromBase->eepromFilament[index])); const uint8_t rawFilament = hal::eeprom::ReadByte(&(eepromBase->eepromFilament[index]));
filament = 0x0f & rawFilament; filament = 0x0f & rawFilament;
if (filament > 4) if (filament > 4)
return false; return false;
@ -230,19 +230,19 @@ namespace permanent_storage {
if ((rawFilament >> 4) != status) if ((rawFilament >> 4) != status)
return false; return false;
return true; return true;
} }
/// @brief Set filament being loaded /// @brief Set filament being loaded
/// ///
/// Always fails, if it is not possible to store status. /// Always fails, if it is not possible to store status.
/// If it is not possible store filament, it tries all other /// If it is not possible store filament, it tries all other
/// keys. Fails if storing with all other keys failed. /// keys. Fails if storing with all other keys failed.
/// ///
/// @param filament bottom 4 bits are stored /// @param filament bottom 4 bits are stored
/// but only value 0 to 4 passes validation in FilamentLoaded::get() /// but only value 0 to 4 passes validation in FilamentLoaded::get()
/// @retval true success /// @retval true success
/// @retval false failed /// @retval false failed
bool FilamentLoaded::set(uint8_t filament) { bool FilamentLoaded::set(uint8_t filament) {
for (uint8_t i = 0; i < BehindLastKey - 1; ++i) { for (uint8_t i = 0; i < BehindLastKey - 1; ++i) {
uint8_t status = getStatus(); uint8_t status = getStatus();
int16_t index = getIndex(); int16_t index = getIndex();
@ -250,23 +250,23 @@ namespace permanent_storage {
if (!setStatus(status)) if (!setStatus(status))
return false; return false;
uint8_t filamentRaw = ((status << 4) & 0xf0) + (filament & 0x0f); uint8_t filamentRaw = ((status << 4) & 0xf0) + (filament & 0x0f);
hal::EEPROM::UpdateByte(&(eepromBase->eepromFilament[index]), filamentRaw); hal::eeprom::UpdateByte(&(eepromBase->eepromFilament[index]), filamentRaw);
if (filamentRaw == hal::EEPROM::ReadByte(&(eepromBase->eepromFilament[index]))) if (filamentRaw == hal::eeprom::ReadByte(&(eepromBase->eepromFilament[index])))
return true; return true;
getNext(status); getNext(status);
if (!setStatus(status)) if (!setStatus(status))
return false; return false;
} }
return false; return false;
} }
/// @brief Get next status and index /// @brief Get next status and index
/// ///
/// Get next available index following index input parameter to store filament in eepromFilament[]. /// Get next available index following index input parameter to store filament in eepromFilament[].
/// If index would reach behind indexable space, status is updated to next and first index matching status indexing mode is returned. /// If index would reach behind indexable space, status is updated to next and first index matching status indexing mode is returned.
/// @param [in,out] status /// @param [in,out] status
/// @param [in,out] index /// @param [in,out] index
void FilamentLoaded::getNext(uint8_t &status, int16_t &index) { void FilamentLoaded::getNext(uint8_t &status, int16_t &index) {
switch (status) { switch (status) {
case KeyFront1: case KeyFront1:
case KeyFront2: case KeyFront2:
@ -289,14 +289,14 @@ namespace permanent_storage {
index = 0; index = 0;
break; break;
} }
} }
/// @brief Get next status /// @brief Get next status
/// ///
/// Sets status to next indexing mode. /// Sets status to next indexing mode.
/// ///
/// @param [in,out] status /// @param [in,out] status
void FilamentLoaded::getNext(uint8_t &status) { void FilamentLoaded::getNext(uint8_t &status) {
switch (status) { switch (status) {
case KeyFront1: case KeyFront1:
status = KeyReverse1; status = KeyReverse1;
@ -314,41 +314,41 @@ namespace permanent_storage {
status = KeyFront1; status = KeyFront1;
break; break;
} }
} }
uint16_t DriveError::get() { uint16_t DriveError::get() {
return ((static_cast<uint16_t>(getH()) << 8) + getL()); return ((static_cast<uint16_t>(getH()) << 8) + getL());
} }
void DriveError::increment() { void DriveError::increment() {
uint16_t errors = get(); uint16_t errors = get();
if (errors < 0xffff) { if (errors < 0xffff) {
++errors; ++errors;
setL(errors); setL(errors);
setH(errors >> 8); setH(errors >> 8);
} }
} }
uint8_t DriveError::getL() { uint8_t DriveError::getL() {
uint8_t first = hal::EEPROM::ReadByte(&(eepromBase->eepromDriveErrorCountL[0])); uint8_t first = hal::eeprom::ReadByte(&(eepromBase->eepromDriveErrorCountL[0]));
uint8_t second = hal::EEPROM::ReadByte(&(eepromBase->eepromDriveErrorCountL[1])); uint8_t second = hal::eeprom::ReadByte(&(eepromBase->eepromDriveErrorCountL[1]));
if (0xff == first && 0 == second) if (0xff == first && 0 == second)
return 1; return 1;
return (first > second) ? ++first : ++second; return (first > second) ? ++first : ++second;
} }
void DriveError::setL(uint8_t lowByte) { void DriveError::setL(uint8_t lowByte) {
hal::EEPROM::UpdateByte(&(eepromBase->eepromDriveErrorCountL[lowByte % 2]), lowByte - 1); hal::eeprom::UpdateByte(&(eepromBase->eepromDriveErrorCountL[lowByte % 2]), lowByte - 1);
} }
uint8_t DriveError::getH() { uint8_t DriveError::getH() {
return (hal::EEPROM::ReadByte(&(eepromBase->eepromDriveErrorCountH)) + 1); return (hal::eeprom::ReadByte(&(eepromBase->eepromDriveErrorCountH)) + 1);
} }
void DriveError::setH(uint8_t highByte) { void DriveError::setH(uint8_t highByte) {
hal::EEPROM::UpdateByte(&(eepromBase->eepromDriveErrorCountH), highByte - 1); hal::eeprom::UpdateByte(&(eepromBase->eepromDriveErrorCountH), highByte - 1);
} }
} // namespace permanent_storage } // namespace permanent_storage
} // namespace modules } // namespace modules