elbear_arduino_bsp/libraries/EEPROM/src/EEPROM.cpp
klassents 766b7b32ea Обновление до версии 0.3.0
- обновлен elbear_fw_bootloader - добавлена проверка контрольной суммы каждой строки hex файла.
- в модуль работы с АЦП добавлена функция analogReadResolution(). Функция analogRead() теперь возвращает усредненное по 10 измерениям значение.
- общая функция обработки прерываний перенесена в память RAM. Обработчики прерываний модулей External Interrupts и Advanced I/O (функция tone()) так же перенесены в память RAM для увеличения скорости выполнения кода.
- в пакет добавлены библиотеки EEPROM, Servo, SoftSerial, NeoPixel, MFRC522 адаптированные для работы с платой Elbear Ace-Uno.
- добавлено описание особенностей работы с пакетом
2024-10-17 08:27:39 +03:00

119 lines
4.6 KiB
C++

#include "EEPROM.h"
#include "mik32_hal_eeprom.h"
#include "mik32_hal.h"
HAL_EEPROM_HandleTypeDef heeprom;
void EEPROMClass:: begin()
{
heeprom.Instance = EEPROM_REGS;
heeprom.Mode = HAL_EEPROM_MODE_TWO_STAGE;
heeprom.ErrorCorrection = HAL_EEPROM_ECC_ENABLE;
heeprom.EnableInterrupt = HAL_EEPROM_SERR_DISABLE;
HAL_EEPROM_Init(&heeprom);
HAL_EEPROM_CalculateTimings(&heeprom, OSC_SYSTEM_VALUE);
}
uint8_t read_byte( int idx )
{
// check if idx is valid
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);
ErrorMsgHandler("EEPROM.read(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {};
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// read desired page
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, read_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the read_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// get desired byte from page data
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_byte( int idx, uint8_t val )
{
// check if idx is valid
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);
ErrorMsgHandler("EEPROM.write(): The address of the eeprom cell goes beyond the eeprom");
}
update_byte(idx, val);
}
void update_byte( int idx, uint8_t val )
{
// check if idx is valid
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);
ErrorMsgHandler("EEPROM.update(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {};
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// read desired page
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the write_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// get desired byte
uint32_t byte = ((uint32_t)val) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8);
uint8_t oldVal = (uint8_t)(*((uint8_t*)write_data_buf + word_idx * EEPROM_WORD_SIZE + (EEPROM_WORD_SIZE - byte_idx - 1)));
// checking if written byte is different from the new one
if(oldVal != val)
{
// clear page
HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
// get and replace the desired byte
write_data_buf[word_idx] = (write_data_buf[word_idx] & (~((uint32_t)(0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)))) | byte;
HAL_EEPROM_Write(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}
}
void HAL_read(uint16_t addr, uint32_t * data)
{
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, data, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
}
void HAL_write(uint16_t addr, uint32_t * data)
{
HAL_EEPROM_Write(&heeprom, (uint16_t)addr, data, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}
void HAL_erase(uint16_t addr)
{
HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}