#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 ) { // Проверка адекватности адреса 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); ErrorMsgHandler("EEPROM.read(): The address of the eeprom cell goes beyond the eeprom"); } uint32_t read_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, read_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; // Индекс искомого слова в массиве read_data_buf: адрес слова в eeprom за вычетом адреса начала страницы uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE; // Номер байта в составе слова uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE; // Вычленение нужного байта из страницы 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 ) { // Проверка адекватности адреса 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); ErrorMsgHandler("EEPROM.write(): The address of the eeprom cell goes beyond the eeprom"); } update_byte(idx, val); } // Делает то же, что и write, но записывает только если новый байт отличается от уже записанного 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); ErrorMsgHandler("EEPROM.update(): The address of the eeprom cell goes beyond the eeprom"); } 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); uint8_t oldVal = (uint8_t)(*((uint8_t*)write_data_buf + word_idx * EEPROM_WORD_SIZE + (EEPROM_WORD_SIZE - byte_idx - 1))); // Проверка того, что записанный байт отличается от нового if(oldVal != val) { // Очистка нужной страницы HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT); // Вычленение и замена нужного байта из страницы 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); } } // uint16_t EEPROMClass:: length( void ) // { // return (uint16_t)EEPROM_LENGHT; // } 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); }