Добавил сырую EEPROM
This commit is contained in:
1 parent
a0c4b0ff0e
commit
4710f730b3
16 files changed
+1227
No files matched your search
@@ -0,0 +1,145 @@
|
||||
#include "EEPROM.h"
|
||||
#include "mik32_hal_eeprom.h"
|
||||
|
||||
#define EEPROM_OP_TIMEOUT 100000
|
||||
#define EEPROM_PAGE_WORDS 32
|
||||
#define EEPROM_PAGE_COUNT 8 // КОличество страниц пользовательской EEPROM
|
||||
#define EEPROM_START_ADDR 0x1C00 // Адрес начала пользовательской EEPROM
|
||||
#define EEPROM_WORD_SIZE 4 // Слово занимает 4 байта
|
||||
#define EEPROM_PAGE_SIZE ( EEPROM_PAGE_WORDS * EEPROM_PAGE_WORDS ) // Страница занимает 32*4 = 128 байт
|
||||
#define EEPROM_END 0x1FFF
|
||||
#define EEPROM_LENGHT (EEPROM_PAGE_SIZE * EEPROM_PAGE_COUNT)
|
||||
|
||||
HAL_EEPROM_HandleTypeDef heeprom;
|
||||
|
||||
|
||||
EEPtr 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);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
uint8_t EEPROMClass:: read( int idx )
|
||||
{
|
||||
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
|
||||
return 0x00;
|
||||
|
||||
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, 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 EEPROMClass:: write( int idx, uint8_t val )
|
||||
{
|
||||
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
|
||||
return;
|
||||
|
||||
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, 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_Write(&heeprom, EEPROM_START_ADDR, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
|
||||
}
|
||||
|
||||
// Делает то же, что и write, но записывает только если новый байт отличается от уже записанного
|
||||
void EEPROMClass:: update( int idx, uint8_t val )
|
||||
{
|
||||
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
|
||||
return;
|
||||
|
||||
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, 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);
|
||||
// Проверка того, что записанный байт отличается от нового
|
||||
if((write_data_buf[word_idx] & ((uint32_t)(0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1)) * 8)) != 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, EEPROM_START_ADDR, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t EEPROMClass:: length( void )
|
||||
{
|
||||
return EEPROM_LENGHT;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
const T& EEPROMClass:: put(int idx, const T &t) {
|
||||
// Создание объекта EEPtr, который указывает на начальный адрес в EEPROM.
|
||||
EEPtr e = idx;
|
||||
|
||||
// Указатель на данные, которые нужно записать в EEPROM.
|
||||
const uint8_t *ptr = (const uint8_t*) &t;
|
||||
|
||||
// Количество байт данных для записи.
|
||||
int count = sizeof(T);
|
||||
|
||||
// Цикл для записи данных побайтно в EEPROM.
|
||||
for(; count ; --count, ++e) {
|
||||
// Запись текущего байта данных в EEPROM.
|
||||
(*e).update( *ptr++ );
|
||||
}
|
||||
|
||||
// Возврат ссылки на записанный объект.
|
||||
return t;
|
||||
}
|
||||
|
||||
T& EEPROMClass:: get(int idx, T &t) {
|
||||
EEPtr e = idx; // Указатель на адрес в EEPROM
|
||||
uint8_t *ptr = (uint8_t*) &t; // Преобразуем ссылку на объект данных в указатель на байт
|
||||
for (int count = sizeof(T); count; --count, ++e) {
|
||||
*ptr++ = *e; // Читаем данные из EEPROM и записываем в объект
|
||||
}
|
||||
return t; // Возвращаем ссылку на переданный объект с прочитанными данными
|
||||
}
|
||||
|
||||
|
||||
|
||||
// uint32_t* EEPROM_Read(uint16_t index)
|
||||
// {
|
||||
// uint32_t read_data_buf[];
|
||||
// HAL_EEPROM_Read(&heeprom, 0x1C00 + index, read_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
|
||||
// return read_data_buf;
|
||||
// }
|
||||
Reference in new issue
Block a user