- обновлен elbear_fw_bootloader - добавлена проверка контрольной суммы каждой строки hex файла. - в модуль работы с АЦП добавлена функция analogReadResolution(). Функция analogRead() теперь возвращает усредненное по 10 измерениям значение. - общая функция обработки прерываний перенесена в память RAM. Обработчики прерываний модулей External Interrupts и Advanced I/O (функция tone()) так же перенесены в память RAM для увеличения скорости выполнения кода. - в пакет добавлены библиотеки EEPROM, Servo, SoftSerial, NeoPixel, MFRC522 адаптированные для работы с платой Elbear Ace-Uno. - добавлено описание особенностей работы с пакетом
119 lines
4.6 KiB
C++
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);
|
|
} |