From f33566cb41868ac5d4da3c16d6eee3a7ab0008f7 Mon Sep 17 00:00:00 2001 From: EgorShin <98223248+EgorShin@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:21:55 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE?= =?UTF-8?q?=D0=B1=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=D1=85,=20=D1=84?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20write=20=D1=82=D0=B5?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D1=8F=D0=B5=D1=82=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20update,=20put=20=D0=B8=20get=20=D1=82=D0=B5=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D1=8C=20=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E?= =?UTF-8?q?=D1=82=20=D0=BD=D0=B5=20=D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8,=20=D0=B0=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eeprom_iteration/eeprom_iteration.ino | 3 -- .../EEPROM/examples/eeprom_put/eeprom_put.ino | 3 -- .../examples/eeprom_read/eeprom_read.ino | 21 +------- .../examples/eeprom_update/eeprom_update.ino | 23 +------- .../examples/eeprom_write/eeprom_write.ino | 23 +------- libraries/EEPROM/src/EEPROM.cpp | 53 +++++++++---------- libraries/EEPROM/src/EEPROM.h | 46 ++++++++++------ 7 files changed, 60 insertions(+), 112 deletions(-) diff --git a/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino b/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino index d4c3427..c01d241 100644 --- a/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino +++ b/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino @@ -6,9 +6,6 @@ Running this sketch is not necessary, this is simply highlighting certain programming methods. - - Written by Christopher Andrews 2015 - Released under MIT licence. ***/ #include diff --git a/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino b/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino index 29e1cca..9c452f9 100644 --- a/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino +++ b/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino @@ -9,9 +9,6 @@ the put method will use update semantics. As in a byte will only be written to the EEPROM if the data is actually different. - - Written by Christopher Andrews 2015 - Released under MIT licence. ***/ #include diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino index a2980b7..ec6e0cf 100644 --- a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino +++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino @@ -3,7 +3,6 @@ * * Reads the value of each byte of the EEPROM and prints it * to the computer. - * This example code is in the public domain. */ #include @@ -29,29 +28,11 @@ void loop() { Serial.print("\t"); Serial.print(value, DEC); Serial.println(); - - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduino Duemilanove: 512 B EEPROM storage. - - Arduino Uno: 1 kB EEPROM storage. - - Arduino Mega: 4 kB EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ + address = address + 1; if (address == EEPROM.length()) { address = 0; } - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++address &= EEPROM.length() - 1; - ***/ - delay(500); } diff --git a/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino b/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino index b80051e..93ea2b4 100644 --- a/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino +++ b/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino @@ -7,8 +7,6 @@ If a value has not changed in the EEPROM, it is not overwritten which would reduce the life span of the EEPROM unnecessarily. - - Released using MIT licence. ***/ #include @@ -26,7 +24,7 @@ void loop() { 0 to 1023 and each byte of the EEPROM can only hold a value from 0 to 255. ***/ - int val = analogRead(0) / 4; + int val = analogRead(0) / 16; /*** Update the particular EEPROM cell. @@ -43,29 +41,10 @@ void loop() { } ***/ - - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduino Duemilanove: 512 B EEPROM storage. - - Arduino Uno: 1 kB EEPROM storage. - - Arduino Mega: 4 kB EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ address = address + 1; if (address == EEPROM.length()) { address = 0; } - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++address &= EEPROM.length() - 1; - ***/ - delay(100); } diff --git a/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino index b83fe59..2b23347 100644 --- a/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino +++ b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino @@ -22,7 +22,7 @@ void loop() { value from 0 to 255. ***/ - int val = analogRead(0) / 4; + int val = analogRead(0) / 16; /*** Write the value to the appropriate byte of the EEPROM. @@ -32,29 +32,10 @@ void loop() { EEPROM.write(addr, val); - /*** - Advance to the next address, when at the end restart at the beginning. - - Larger AVR processors have larger EEPROM sizes, E.g: - - Arduino Duemilanove: 512 B EEPROM storage. - - Arduino Uno: 1 kB EEPROM storage. - - Arduino Mega: 4 kB EEPROM storage. - - Rather than hard-coding the length, you should use the pre-provided length function. - This will make your code portable to all AVR processors. - ***/ addr = addr + 1; if (addr == EEPROM.length()) { addr = 0; } - - /*** - As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an - EEPROM address is also doable by a bitwise and of the length - 1. - - ++addr &= EEPROM.length() - 1; - ***/ - - + delay(100); } diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp index 12dc0a0..2c37209 100644 --- a/libraries/EEPROM/src/EEPROM.cpp +++ b/libraries/EEPROM/src/EEPROM.cpp @@ -16,13 +16,19 @@ void EEPROMClass:: begin() HAL_EEPROM_CalculateTimings(&heeprom, OSC_SYSTEM_VALUE); } -uint8_t read( int idx ) +uint8_t read_byte( int idx ) { // Проверка адекватности адреса idx if (idx < 0) + { idx = -idx; + ErrorMsgHandler("EEPROM.read(): The eeprom cell address must be non-negative"); + } if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) - idx = (int)((uint32_t)idx % EEPROM_LENGHT); + { + idx = (int)((uint32_t)idx % EEPROM_LENGHT); + ErrorMsgHandler("EEPROM.read(): The address of the eeprom cell goes beyond the eeprom"); + } uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {}; @@ -40,45 +46,36 @@ uint8_t read( int idx ) return (uint8_t)(( read_data_buf[word_idx] & (((uint32_t)0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)) ) >> ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)); } -void write( int idx, uint8_t val ) +void write_byte( int idx, uint8_t val ) { // Проверка адекватности адреса idx if (idx < 0) + { idx = -idx; + ErrorMsgHandler("EEPROM.write(): The eeprom cell address must be non-negative"); + } if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) - idx = (int)((uint32_t)idx % EEPROM_LENGHT); - - uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {}; - - // Вычисление адреса начала нужной страницы - uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE; - // Читаем нужную страницу - HAL_EEPROM_Read(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT); - // Адрес искомого слова в eeprom: EEPROM_START_ADDR + (uint32_t)idx - uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE; - // Индекс искомого слова в массиве write_data_buf: адрес слова в eeprom за вычетом адреса начала страницы - uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE; - // Номер байта в составе слова - uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE; - // Извлечение нужного байта - uint32_t byte = (((uint32_t)val) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)); - // Вычленение и замена нужного байта из страницы - write_data_buf[word_idx] = (write_data_buf[word_idx] & (~(((uint32_t)0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)))) | byte; - - // Очистка нужной страницы - HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT); - - HAL_EEPROM_Write(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT); + { + idx = (int)((uint32_t)idx % EEPROM_LENGHT); + ErrorMsgHandler("EEPROM.write(): The address of the eeprom cell goes beyond the eeprom"); + } + update_byte(idx, val); } // Делает то же, что и write, но записывает только если новый байт отличается от уже записанного -void update( int idx, uint8_t val ) +void update_byte( int idx, uint8_t val ) { // Проверка адекватности адреса idx if (idx < 0) + { idx = -idx; + ErrorMsgHandler("EEPROM.update(): The eeprom cell address must be non-negative"); + } if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) - idx = (int)((uint32_t)idx % EEPROM_LENGHT); + { + idx = (int)((uint32_t)idx % EEPROM_LENGHT); + ErrorMsgHandler("EEPROM.update(): The address of the eeprom cell goes beyond the eeprom"); + } uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {}; diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h index 1eeb4bb..fe79006 100644 --- a/libraries/EEPROM/src/EEPROM.h +++ b/libraries/EEPROM/src/EEPROM.h @@ -16,20 +16,22 @@ void HAL_read(uint16_t addr, uint32_t * data); void HAL_write(uint16_t addr, uint32_t * data); void HAL_erase(uint16_t addr); -uint8_t read( int idx ); -void write( int idx, uint8_t val ); -void update( int idx, uint8_t val ); +uint8_t read_byte( int idx ); +void write_byte( int idx, uint8_t val ); +void update_byte( int idx, uint8_t val ); + +extern void ErrorMsgHandler(const char * msg); struct EERef{ EERef( const int index ) : index( index ) {} - uint8_t operator*() const { return read( index ); } + uint8_t operator*() const { return read_byte( index ); } operator uint8_t() const { return **this; } EERef &operator=( const EERef &ref ) { return *this = *ref; } - EERef &operator=( uint8_t in ) { return write( index, in ), *this; } + EERef &operator=( uint8_t in ) { return write_byte( index, in ), *this; } EERef &operator +=( uint8_t in ) { return *this = **this + in; } EERef &operator -=( uint8_t in ) { return *this = **this - in; } EERef &operator *=( uint8_t in ) { return *this = **this * in; } @@ -86,24 +88,31 @@ struct EEPROMClass{ EERef operator[]( const int idx ) { return idx; } uint8_t read( int idx ) { return EERef( idx ); } void write( int idx, uint8_t val ) { (EERef( idx )) = val; } - void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } + void update( int idx, uint8_t val ) { update_byte(idx, val); } void begin(); - EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. + EEPtr end() { return length(); } // Standards requires this to be the item after the last valid entry. The returned pointer is invalid. uint16_t length() { return (uint16_t)EEPROM_LENGHT; } template< typename T > - T& put(int idx, T& dataPointer) + T &put(int idx, T &data) { + void* dataPointer = (void*)&data; // Проверка адекватности адреса idx if (idx < 0) + { idx = -idx; + ErrorMsgHandler("EEPROM.put(): The eeprom cell address must be non-negative"); + } if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) - idx = (int)((uint32_t)idx % EEPROM_LENGHT); + { + idx = (int)((uint32_t)idx % EEPROM_LENGHT); + ErrorMsgHandler("EEPROM.put(): The address of the eeprom cell goes beyond the eeprom"); + } uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {}; // Размер данных под запись - uint32_t dataSize = sizeof(dataPointer); + uint32_t dataSize = sizeof(data); // Сдвиг начала записи данных uint32_t dataShift = 0; uint32_t writeSize = dataSize; @@ -162,21 +171,28 @@ struct EEPROMClass{ HAL_write((uint16_t)addr, write_data_buf); dataSize -= writeSize; } - return dataPointer; + return data; } template< typename T > - T& get(int idx, T& dataPointer) + T &get(int idx, T &data) { + void* dataPointer = (void*)&data; // Проверка адекватности адреса idx if (idx < 0) + { idx = -idx; + ErrorMsgHandler("EEPROM.get(): The eeprom cell address must be non-negative"); + } if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT) - idx = (int)((uint32_t)idx % EEPROM_LENGHT); + { + idx = (int)((uint32_t)idx % EEPROM_LENGHT); + ErrorMsgHandler("EEPROM.get(): The address of the eeprom cell goes beyond the eeprom"); + } uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {}; // Размер данных - uint32_t dataSize = sizeof(dataPointer); + uint32_t dataSize = sizeof(data); // Сдвиг начала чтения данных uint32_t dataShift = 0; uint32_t readSize = dataSize; @@ -230,7 +246,7 @@ struct EEPROMClass{ memcpy((void *)((uint8_t *)dataPointer + dataShift), (void*)(read_data_buf), readSize); dataSize -= readSize; } - return dataPointer; // Возвращаем ссылку на переданный объект с прочитанными данными + return data; // Возвращаем ссылку на переданный объект с прочитанными данными } };