Большой апгрейд:
- исправлены баги библиотеки memspi - добавлены модули для сохранения настреок в eeprom и flash (с равномерным износом) - надо тестить, проверять и рефакторить
This commit is contained in:
18
Inc/memspi.h
18
Inc/memspi.h
@@ -39,31 +39,35 @@
|
||||
#define __SPI_MEMORY_H_
|
||||
|
||||
#include "memspi_core.h"
|
||||
|
||||
extern MEMSPI_HandleTypeDef memory_spi;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////---FUNCTIONS FOR USER---//////////////////////
|
||||
/* Initialize SPI and GPIO for MEMSPI FLASH */
|
||||
void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi, SPI_HandleTypeDef *hspi);
|
||||
/* Read external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout);
|
||||
HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint32_t Size, uint32_t Timeout);
|
||||
/* Write external EEPROM */
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
/* Write external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_WriteInitTypeDef *WriteInit, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
/* Program external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
/* Erase external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
/* @brief Set protection for FLASH sectors */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Protection(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Size, uint32_t ProtectState, uint32_t Timeout);
|
||||
///////////////////////---FUNCTIONS FOR USER---//////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////////---SERVICE FUNCTIONS---//////////////////////
|
||||
/* Write page in external EEPROM */
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
/* Erase external FLASH Sector */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
/* Program page in external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
/* Program data in external FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Bytes(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
/* Setting WEL bit until it setted or until timeout */
|
||||
HAL_StatusTypeDef MEMSPI_WriteEnablingUntilTimeout(MEMSPI_HandleTypeDef *hmemspi, uint32_t *Timeout, uint32_t *tickstart);
|
||||
/* Wait for flag until timeout */
|
||||
|
||||
@@ -26,30 +26,61 @@
|
||||
|
||||
#include "memspi_config.h"
|
||||
|
||||
#ifndef local_time
|
||||
#define local_time() HAL_GetTick() ///< Локальное время
|
||||
#endif
|
||||
|
||||
/** @defgroup MEMSPI_Commands Memory SPI Commands
|
||||
* @brief Определения команд SPI-памяти
|
||||
* @{
|
||||
*/
|
||||
#define MEMSPI_READ_JEDEC_ID 0x9F ///< Команда чтения JEDEC ID
|
||||
#define MEMSPI_READ_UNIQUE_ID 0x4B ///< Команда чтения уникального идентификатора
|
||||
|
||||
#ifdef RUFLASH
|
||||
|
||||
#define MEMSPI_READ_DATA (0x03)
|
||||
|
||||
#define MEMSPI_ERASE_SECTOR (0xD8)
|
||||
#define MEMSPI_ERASE_CHIP (0x60)
|
||||
|
||||
#define MEMSPI_WRITE_ENABLE (0x06)
|
||||
#define MEMSPI_WRITE_DISABLE (0x04)
|
||||
|
||||
#define MEMSPI_PAGE_PROGRAM (0x02)
|
||||
#define MEMSPI_BYTE_PROGRAM (0x02)
|
||||
#define MEMSPI_WRITE_EEPROM (MEMSPI_PAGE_PROGRAM)
|
||||
|
||||
#define MEMSPI_PROTECT_SECTOR (0x36)
|
||||
#define MEMSPI_UNPROTECT_SECTOR (0x39)
|
||||
#define MEMSPI_READ_PROTECT_REG (0x3C)
|
||||
|
||||
|
||||
#define MEMSPI_READ_STATUS_REG (0x05)
|
||||
#if defined(SEPARATED_STATUS_REGISTER)
|
||||
#define MEMSPI_READ_STATUS_REG_2 (0x35)
|
||||
#endif
|
||||
#define MEMSPI_WRITE_STATUS_REG (0x01)
|
||||
|
||||
|
||||
#define MEMSPI_READ_JEDEC_ID (0x9F)
|
||||
#define MEMSPI_READ_UNIQUE_ID (0x4B)
|
||||
|
||||
#else
|
||||
#define MEMSPI_READ_DATA 0x03 ///< Чтение данных из памяти
|
||||
|
||||
#define MEMSPI_ERASE_SECTOR 0x20 ///< Стирание одного сектора
|
||||
|
||||
#define MEMSPI_WRITE_ENABLE 0x06 ///< Разрешение записи
|
||||
#define MEMSPI_WRITE_DISABLE 0x04 ///< Запрещение записи
|
||||
#define MEMSPI_WRITE_STATUS_REG 0x01 ///< Запись в регистр состояния
|
||||
#define MEMSPI_ERASE_SECTOR 0x20 ///< Стирание одного сектора
|
||||
|
||||
#define MEMSPI_PAGE_PROGRAM 0x02 ///< Программирование одной страницы
|
||||
#define MEMSPI_WRITE_EEPROM MEMSPI_PAGE_PROGRAM ///< Псевдоним для программирования EEPROM
|
||||
#define MEMSPI_READ_STATUS_REG 0x05 ///< Чтение регистра состояния
|
||||
|
||||
#define MEMSPI_READ_STATUS_REG 0x05 ///< Чтение регистра состояния
|
||||
#if defined(MEMSPI_SEPARATED_STATUS_REGISTER)
|
||||
#define MEMSPI_READ_STATUS_REG_2 0x35 ///< Чтение второго регистра состояния (если поддерживается)
|
||||
#endif
|
||||
#define MEMSPI_WRITE_STATUS_REG 0x01 ///< Запись в регистр состояния
|
||||
|
||||
#define MEMSPI_READ_DATA 0x03 ///< Чтение данных из памяти
|
||||
|
||||
#define MEMSPI_READ_JEDEC_ID 0x9F ///< Команда чтения JEDEC ID
|
||||
#define MEMSPI_READ_UNIQUE_ID 0x4B ///< Команда чтения уникального идентификатора
|
||||
#endif
|
||||
/** //MEMSPI_Commands
|
||||
* @}
|
||||
*/
|
||||
@@ -82,6 +113,8 @@
|
||||
#define MEMSPI_SR_SRWD MEMSPI_SR_SRP0 ///< Status Register Write Disable (аналог SRP0)
|
||||
#define MEMSPI_SR_WIP MEMSPI_SR_WEL ///< Write-In-Progress (используется в некоторых EEPROM)
|
||||
|
||||
// Exclusive (by name) RUFLASH SR bits
|
||||
#define MEMSPI_SR_EPE (1<<5) ///< Ошибка/стирания записи
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -144,8 +177,16 @@ HAL_StatusTypeDef MEMSPI_CMD_Read_Data(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
|
||||
HAL_StatusTypeDef MEMSPI_CMD_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
/* Send command to page program in FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Page_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
/* Send command to byte program in FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Byte_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t Byte, uint32_t Timeout);
|
||||
/* Send command to erase sector of FLASH */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Timeout);
|
||||
/* Send command to Unprotect Sector */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_Unprotect_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Timeout);
|
||||
/* Send command to Protect sector */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_Protect_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Timeout);
|
||||
/* Send command to read Sector Protection Register */
|
||||
HAL_StatusTypeDef MEMSPI_CMD_Read_Sector_Protection(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pStatus, uint32_t Timeout);
|
||||
/* Send command to read JEDEC ID */
|
||||
uint32_t MEMSPI_CMD_Read_JEDEC_ID(MEMSPI_HandleTypeDef *hmemspi, uint32_t Timeout);
|
||||
/* Send command to read JEDEC ID */
|
||||
@@ -158,6 +199,17 @@ HAL_StatusTypeDef MEMSPI_CMD_Fast_Read(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef local_time
|
||||
#define local_time() HAL_GetTick() ///< Локальное время
|
||||
#endif
|
||||
|
||||
#ifndef printf_memspi
|
||||
#define printf_memspi(...)
|
||||
#endif
|
||||
#ifndef printf_memspi_err
|
||||
#define printf_memspi_err(...)
|
||||
#endif
|
||||
|
||||
#endif // __SPI_MEMORY_CORE_H_
|
||||
|
||||
/** //MEMSPI_CORE
|
||||
|
||||
275
Inc/params_flash.h
Normal file
275
Inc/params_flash.h
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file params_flash.h
|
||||
* @brief Заголовочный файл модуля записи параметров в Flash
|
||||
**************************************************************************
|
||||
* @details
|
||||
Модуль позволяет сохранять данные в Flash и читать их обратно по номерам блоков.
|
||||
|
||||
@par Параметры
|
||||
- @ref PARAMS_FLASH_MAX_BUFFER_SIZE - Максимальный размер блока данных
|
||||
- @ref PARAMS_FLASH_ASYNCH_BUFFER_SIZE - Размер блока для записи в асинхронном режиме.
|
||||
Заданное количество слов будет записыватся при каждом вызове @ref ParamsFlash_AsynchHandle
|
||||
пока весь блок не будет записан
|
||||
- @ref PARAMS_FLASH_ADDR_START - Начало области Flash для хранения параметров
|
||||
- @ref PARAMS_FLASH_ADDR_END - Конец области Flash для хранения параметров
|
||||
|
||||
@par Пример использования
|
||||
@code
|
||||
#include "params_flash.h"
|
||||
ParamsFlash_HandleInit(&flash_handle, 9, 10, 16); // Инициализация 9 и 10 секторов для записи, размер блока 16 слов
|
||||
read_block_numb = ParamsFlash_ReadBlock(&flash_handle, PARAMS_LAST_BLOCK, read_data, size, read_size); // читаем последний блок
|
||||
// ...
|
||||
if(flag_to_write)
|
||||
{
|
||||
if(ParamsFlash_IsFlashFree(&flash_handle)) // првеоряем свободность флеш
|
||||
{
|
||||
ParamsFlash_WriteBlock(&flash_handle, PARAMS_LAST_BLOCK, data, size); // записываем новый блок
|
||||
if(flash_handle.status == FLASH_BLOCK_FLASH_FULL) // если по какой-то причине не получилось
|
||||
{
|
||||
if(ParamsFlash_Pack(&flash_handle, 0)) // пробуем упаковку
|
||||
{
|
||||
// ошибка при ините упаковке, мб не удалось найти валидный блок
|
||||
ParamsFlash_Pack(&flash_handle, 1); // erase без копирования блока
|
||||
}
|
||||
}
|
||||
else // получилось
|
||||
{
|
||||
flag_to_write = 0; // успешно записали, сбрасываем флаг
|
||||
}
|
||||
}
|
||||
}
|
||||
// уходим и возврашаемся к этому коду позже...
|
||||
@endcode
|
||||
|
||||
@par Возможности
|
||||
|
||||
- Каждый блок имеет уникальный номер (numb) и хранится в фиксированной
|
||||
структуре @ref ParamsFlash_t
|
||||
@code
|
||||
[numb][size][data_start.......data_end][crc]
|
||||
@endcode
|
||||
|
||||
- Блоки располагаются последовательно в выделенной области Flash.
|
||||
В процессе работы хранится адрес куда будет записан следующий блок.
|
||||
@code
|
||||
[ParamsFlash_t #1][ParamsFlash_t #2][ParamsFlash_t #3]...
|
||||
^
|
||||
|
|
||||
next_block_adr
|
||||
@endcode
|
||||
|
||||
От next_block_adr вправо идет поиск свободного места. А влево идет поиск уже записанных блоков
|
||||
@ref __ParamsFlash_FindBlock и @ref __ParamsFlash_FindFreeSpace для подробностей
|
||||
|
||||
- Можно создать несколько хендлов @ref ParamsFlashHandle_t, каждый из которых
|
||||
будет работать с своими параметрами и своей областью Flash памяти.
|
||||
Для работы с несколькими handle необходимо использовать разные сектора Flash памяти
|
||||
@code
|
||||
ParamsFlash_HandleInit(&flash_handle1, 9, 10, 16); // 9,10 сектора
|
||||
ParamsFlash_HandleInit(&flash_handle2, 11, 12, 32); // 11,12 сектора
|
||||
@endcode
|
||||
|
||||
- Запись и стирание происходит асихнронно @ref __ParamsFlash_WriteHandle и @ref __ParamsFlash_EraseHandle.
|
||||
Поэтому надо удостоверится что функции @ref ParamsFlash_WriteBlock и @ref ParamsFlash_Pack вызываются корректно
|
||||
и не накладываются друг на друга. Иначе может произойти игнорирование команд для записи/стирания. **См. Пример использования**
|
||||
|
||||
- При записи c @ref PARAMS_LAST_BLOCK номер нового блока вычисляется
|
||||
автоматически (последний_номер + 1)
|
||||
|
||||
При записи конкретного блока он запишется только в том случае, если его номер не равен последнему номер
|
||||
@code
|
||||
writen_block_numb = ParamsFlash_WriteBlock(&flash_handle, PARAMS_LAST_BLOCK, data, size); // пишем с инкрементом
|
||||
// ждем пока асихнронно запишется...
|
||||
writen_block_numb = ParamsFlash_WriteBlock(&flash_handle, writen_block_numb, data, size); // ошибка
|
||||
// ждем пока асихнронно запишется...
|
||||
writen_block_numb = ParamsFlash_WriteBlock(&flash_handle, 1, data, size); // норм
|
||||
@endcode
|
||||
|
||||
- При чтении c @ref PARAMS_LAST_BLOCK читается последний инициализированный блок
|
||||
@code
|
||||
read_block_numb = ParamsFlash_ReadBlock(&flash_handle, PARAMS_LAST_BLOCK, read_data, size, NULL);
|
||||
@endcode
|
||||
|
||||
При чтении конкретного блока он считается только в том случае, если он валидный (CRC correct)
|
||||
|
||||
- При переполнении сектора Flash будет выполнено стирание текщуего сектора и переход на другой
|
||||
Erase будет пытаться выполнится до тех пор пока не будет успеха.
|
||||
Если вдруг будет ошибка FLASH_BLOCK_FLASH_FULL (нет места в flash, оба сектора заполнены и не стерты по какой-то причине).
|
||||
Можно попытаться сделать упаковку. **См. Пример использования**.
|
||||
|
||||
- Поддерживается проверка целостности и корректности блоков
|
||||
@code
|
||||
if(ParamsFlash_VerifyBlock(&flash_handle, PARAMS_LAST_BLOCK, &last_valid_block_numb))
|
||||
{
|
||||
// crc неправильный или еще что-то
|
||||
}
|
||||
|
||||
if(ParamsFlash_Compare(&flash_handle, block_numb, data, size))
|
||||
{
|
||||
// данные НЕ совпадают
|
||||
}
|
||||
@endcode
|
||||
|
||||
- При вызове каждой функции в структуре заполняется status по которому можно
|
||||
отследить разные ошибки @ref FlashBlockStatus_t
|
||||
*************************************************************************/
|
||||
#ifndef PARAMS_FLASH_H
|
||||
#define PARAMS_FLASH_H
|
||||
|
||||
#include "mylibs_include.h"
|
||||
#include "memspi.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//#define TRACE_WRITE_READ //led1 трейс ParamsFlash_WriteBlock и ParamsFlash_ReadBlock
|
||||
//#define TRACE_FIND_BLOCK //led1 трейс внутренниъх функцйи по поиску блоков/свобождных мест
|
||||
//#define TRACE_FLASH_BUSY //led2 трейс заняносит флеш FLASH_WORKING_ENTER и FLASH_WORKING_EXIT
|
||||
//#define TRACE_ASYNCH //led1 трейс работы asynch
|
||||
|
||||
//#define FLASH_WORKING_NONBLOCKING ///< Режим неблокирующей работы с Flash
|
||||
|
||||
|
||||
#if !defined(PARAMS_FLASH_MAX_BUFFER_SIZE)
|
||||
#define PARAMS_FLASH_MAX_BUFFER_SIZE 1096 ///< Максимальный размер блока данных
|
||||
#endif
|
||||
#if !defined(PARAMS_FLASH_ASYNCH_BUFFER_SIZE)
|
||||
#define PARAMS_FLASH_ASYNCH_BUFFER_SIZE 100 ///< Размер блока для записи в асинхронном режиме. Заданное количество слов будет записыватся при каждом вызове @ref ParamsFlash_AsynchHandle
|
||||
#endif
|
||||
#if !defined(PARAMS_FLASH_ADDR_START)
|
||||
#define PARAMS_FLASH_ADDR_START 0x0 ///< Начало допустимой адресации Flash
|
||||
#endif
|
||||
#if !defined(PARAMS_FLASH_ADDR_END)
|
||||
#define PARAMS_FLASH_ADDR_END 0x1FFFF+1 ///< Конец допустимой адресации Flash
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define PARAMS_LAST_BLOCK 0xFFFF ///< Команда считать последний блок
|
||||
|
||||
#define FLASH_WORKING_CHECK(_h_) (flash_working == 1) ///< Проверка занятности Flash
|
||||
#define FLASH_WORKING_ENTER(_h_) do{flash_working = 1; LED2_TRACE_ENTER(); /*DINT;flash_reset();*/ }while(0) ///< Начало работы с Flash
|
||||
#define FLASH_WORKING_EXIT(_h_) do{flash_working = 0; LED2_TRACE_EXIT(); /*EnableInterrupts();*/ }while(0) ///< Конец работы с Flash
|
||||
|
||||
|
||||
#ifndef SETTINGS_USE_MEMORY_EEPROM
|
||||
#define EMPTY_MEMORY 0xFFFF
|
||||
#else
|
||||
#define EMPTY_MEMORY 0x0000
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define __SET_CURR_BLOCK(pcur, adr) do{ pcur = &__buff; MEMSPI_Read_Memory(&memory_spi, adr, (uint8_t *)pcur, sizeof(ParamsFlash_t), 1000); }while(0);
|
||||
#define __WRITE_CURR_BLOCK(pcur, adr, size) MEMSPI_FLASH_Program(&memory_spi, adr, (uint8_t *)pcur, size, 1000, 1)
|
||||
#define __READ_BYTE(adr, data, size) MEMSPI_Read_Memory(&memory_spi, adr, (uint8_t *)data, size, 1000)
|
||||
//#define __SET_CURR_BLOCK(pcur) do{ cur = (volatile ParamsFlash_t*)addr }while(0);
|
||||
|
||||
/**
|
||||
* @brief Варианты ошибок блока
|
||||
*/
|
||||
typedef enum {
|
||||
FLASH_BLOCK_OK = 0, ///< Блок корректен
|
||||
FLASH_BLOCK_EMPTY , ///< Блок не инициализирован
|
||||
FLASH_BLOCK_CRC_ERROR , ///< CRC блока не совпадает
|
||||
FLASH_BLOCK_ALREADY_EXIST , ///< Блок уже существует
|
||||
FLASH_BLOCK_NOT_FOUND , ///< Блок не найден
|
||||
FLASH_BLOCK_FLASH_FULL , ///< Нет места в Flash для блока
|
||||
FLASH_BLOCK_INIT_ERR , ///< Ошибка инициализации блока (неадекватные параметры)
|
||||
FLASH_BLOCK_WRITE_ERR , ///< Ошибка записи
|
||||
FLASH_BLOCK_BUSY , ///< Работа с флеш уже идет
|
||||
FLASH_BLOCK_UNKNOWN_ERR ///< Неизвестная ошибка
|
||||
} FlashBlockStatus_t;
|
||||
|
||||
/**
|
||||
* @brief Структура данных, которая будет положена в Flash
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t numb; ///< Номер блока
|
||||
uint16_t size; ///< Размер данных
|
||||
uint16_t data[PARAMS_FLASH_MAX_BUFFER_SIZE]; ///< Буфер данных
|
||||
uint16_t crc16; ///< CRC блока
|
||||
} ParamsFlash_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle конкретного сектора
|
||||
*/
|
||||
typedef struct {
|
||||
// общая инфа о секторе
|
||||
uint16_t sector_num; ///< Номер сектора
|
||||
uint32_t addr_start; ///< Абсолютный адрес начала сектора
|
||||
uint32_t addr_end; ///< Абсолютный адрес конца сектора
|
||||
uint16_t size; ///< Размер сектора словах
|
||||
uint16_t capacity; ///< Вместимость - сколько блоков можно положить
|
||||
|
||||
// всякие служебные штуки
|
||||
uint32_t next_block_adr; ///< Адрес следующего блока в секторе
|
||||
uint16_t erase_pending; ///< Флаг, что нужен erase сектора
|
||||
} FlashSector_t;
|
||||
|
||||
/**
|
||||
* @brief Handle для работы с конкретной областью Flash
|
||||
*/
|
||||
typedef struct {
|
||||
int initialized; ///< Флаг что модуль успешно инициализирован
|
||||
FlashSector_t sector[2]; ///< Два сектора для записи
|
||||
int sect_curr_ind; ///< Номер текущего сектора (0 или 1)
|
||||
uint16_t buffer_size; ///< Размер буфера в словах (1 слово = 16 бит)
|
||||
|
||||
ParamsFlash_t blk_tmp; ///< Временная структура для операций
|
||||
|
||||
uint32_t addr_start; ///< Начало текущей области Flash
|
||||
uint32_t addr_end; ///< Конец текущей области Flash
|
||||
uint32_t next_block_adr; ///< Адрес следующего блока
|
||||
uint16_t write_pending; ///< Флаг для записи @ref blk_tmp в Flash
|
||||
uint16_t write_word_cnt; ///< Количество записанных байт
|
||||
|
||||
FlashBlockStatus_t status; ///< Статус хендла
|
||||
} ParamsFlashHandle_t;
|
||||
|
||||
/* ======= Инициализация модуля ======================================= */
|
||||
/* Инициализация handle */
|
||||
int ParamsFlash_HandleInit(ParamsFlashHandle_t *h, int sector_1, int sector_2, int buf_size);
|
||||
/* Обработчик неблокирующей работы модуля */
|
||||
int ParamsFlash_AsynchHandle(ParamsFlashHandle_t *h);
|
||||
|
||||
/* ======= Функции управления ======================================= */
|
||||
/* Проверка свободности флеш */
|
||||
int ParamsFlash_IsFlashFree(ParamsFlashHandle_t *h);
|
||||
/* Запись блока во Flash */
|
||||
int ParamsFlash_WriteBlock(ParamsFlashHandle_t *h, int block_num, const uint16_t *Buffer, int size);
|
||||
/* Чтение блока из Flash */
|
||||
int ParamsFlash_ReadBlock(ParamsFlashHandle_t *h, int block_num, uint16_t *Buffer, int size, int *read_size);
|
||||
/* Упаковка Flash: стирание всей области и запись последнего блока в начало */
|
||||
int ParamsFlash_Pack(ParamsFlashHandle_t *h, int force);
|
||||
/* Полная инициализация Flash (стирание всей области) */
|
||||
int ParamsFlash_Init(ParamsFlashHandle_t *h);
|
||||
/* Проверка блока на корректность */
|
||||
FlashBlockStatus_t ParamsFlash_VerifyBlock(ParamsFlashHandle_t *h, int block_num, int *last_valid_num);
|
||||
/* Сравнение данных с блоком из Flash */
|
||||
int ParamsFlash_Compare(ParamsFlashHandle_t *h, int block_num, const uint16_t *data, int size);
|
||||
/* Получение статистики по блокам */
|
||||
int ParamsFlash_GetInfo(ParamsFlashHandle_t *h, int *totalBlocks, int *validBlocks, int *invalidBlocks);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(TRACE_FLASH_BUSY)
|
||||
#define LED2_TRACE_ENTER() i_led2_on_off(1);
|
||||
#define LED2_TRACE_EXIT() i_led2_on_off(0);
|
||||
#else
|
||||
#define LED2_TRACE_ENTER()
|
||||
#define LED2_TRACE_EXIT()
|
||||
#endif
|
||||
|
||||
#define LED1_TRACE_ENTER() i_led1_on_off(1);
|
||||
#define LED1_TRACE_EXIT() i_led1_on_off(0);
|
||||
|
||||
|
||||
|
||||
#endif //PARAMS_FLASH_H
|
||||
136
Inc/set_to_mem.h
Normal file
136
Inc/set_to_mem.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file set_to_mem.h
|
||||
* @brief Заголовочный файл для записи в память настроек.
|
||||
**************************************************************************
|
||||
* @defgroup SETMEM_TOOLS Settings to Memory Tools
|
||||
* @brief Модуль для записи/считывания настроек в память
|
||||
**************************************************************************
|
||||
@details Есть следующие настройки:
|
||||
|
||||
- @ref SETTINGS_USE_SETTINGS_FROM_BUFFER : выкидывать в память данные по указателю на разные настройки
|
||||
- Для работы надо объявить в структуре данные которые будут записываться (@ref SettingsInMemTypeDef)
|
||||
и указатели на эти данные (@ref SettingsSourceTypeDef)
|
||||
- Добавить @ref CompareSettings на каждый массив настроек, для отслеживания изменений.
|
||||
При отличии - выставляется флаг для записи настроек в память
|
||||
- Добавить @ref WriteSettingToBuffer и @ref ReadSettingFromBuffer для синхронизации
|
||||
каждого элемента структуры буфера и реальных настроек.
|
||||
|
||||
(_CompareSettings`, WriteSettingToBuffer` и ReadSettingFromBuffer` это дефайны которые принимают название элемента структуры и уже вызывают нужные функции_)
|
||||
|
||||
|
||||
- @ref SETTINGS_USE_SETTINGS_FROM_POINTER : заполнять необходимыми настройками буфер и полностью выкидывать его в память
|
||||
- Для работы надо объявить в структуре данные которые будут записываться (@ref SettingsInMemTypeDef)
|
||||
- Инициализировать каждый элемент структуры функцией @ref InitSettingsToMem
|
||||
- Добавить @ref WriteSettingsArrayToMem и @ref ReadSettingsArrayFromMem для записи/считывания
|
||||
каждого элемента структуры в память
|
||||
- Выставлять флаг @ref update_settings_flag для записи настроек в память,
|
||||
когда необходимо это сделать (само по себе оно не может определить когда надо записать,
|
||||
т.к. нет буфера для отслеживания изменений)
|
||||
|
||||
- @ref SETTINGS_MEMORY_PROTECT_ENABLE : включение защиты на память.
|
||||
Перед записью защита снимается, и после записи ставится обратно.
|
||||
* @{
|
||||
*************************************************************************/
|
||||
#ifndef _SET_TO_MEM_H_
|
||||
#define _SET_TO_MEM_H_
|
||||
|
||||
#include "mylibs_include.h"
|
||||
#include "params_flash.h"
|
||||
#include "memspi.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Структура для записи одного массива настроек по указателю.
|
||||
* @details Используется при @ref SETTINGS_USE_SETTINGS_FROM_POINTER
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t adr; ///< Адрес в памяти
|
||||
uint32_t length; ///< Размер блока
|
||||
|
||||
uint8_t *real_ptr; ///< Указатель на реальные рабочие данные
|
||||
uint8_t *mem_ptr; ///< Указатель на данные, которые пишутся в память
|
||||
}SettingArrayTypeDef;
|
||||
|
||||
|
||||
#define MEMORY_ERROR_EMPTY ((uint32_t)(1<<0)) ///< Бит ошибки - память пустая
|
||||
#define MEMORY_ERROR_WRITE ((uint32_t)(1<<1)) ///< Бит ошибки - запись
|
||||
#define MEMORY_ERROR_READ ((uint32_t)(1<<2)) ///< Бит ошибки - чтение
|
||||
|
||||
/**
|
||||
* @brief Структура для хранения настроек устройства.
|
||||
* @details Содержит указатели на настройки и другие параметры для их обработки.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MEMSPI_HandleTypeDef *hmemspi; ///< Указатель на хендл для работы с памятью
|
||||
|
||||
#ifdef SETTINGS_USE_WEAR_LEVELING_FLASH
|
||||
ParamsFlashHandle_t flash_handle; ///< Хендл для равномерного использования флеш памяти
|
||||
#endif
|
||||
|
||||
#ifdef SETTINGS_USE_SETTINGS_FROM_BUFFER
|
||||
uint8_t *buffer;
|
||||
#endif
|
||||
|
||||
SettingArrayTypeDef setarr[32]; ///< Структура настроек для хранения в памяти
|
||||
uint8_t setarr_count;
|
||||
|
||||
uint32_t start_adr; ///< Начальный адрес в памяти для записи настроек
|
||||
uint32_t settings_size; ///< Размер всего массива настроек
|
||||
|
||||
uint8_t update_settings_flag; ///< Флаг для обновления настроек в памяти
|
||||
uint32_t settings_error; ///< Флаг ошибки настроек
|
||||
}SettingsTypeDef;
|
||||
extern SettingsTypeDef Settings;
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup SETMEM_GENERAL_FUNC General functions for writing/reading settings
|
||||
* @ingroup SETMEM_TOOLS
|
||||
* @brief Общие функции для работы с настройками в памяти.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Инициализаия обзего хендла для работы с настройками */
|
||||
HAL_StatusTypeDef Settings_Init(SettingsTypeDef *settings, SPI_HandleTypeDef *hspi, uint32_t adr);
|
||||
/* Добавление массива настроек для хранения в памяти */
|
||||
HAL_StatusTypeDef Settings_AddArray(SettingsTypeDef *settings, uint8_t *pRealArray, uint32_t *startadr, uint32_t sizeofarray);
|
||||
/* Запись настроек в память */
|
||||
void Settings_WriteSettings(SettingsTypeDef *settings);
|
||||
/* Чтение настроек из памяти */
|
||||
void Settings_ReadSettings(SettingsTypeDef *settings);
|
||||
/* Проверить настройки на валидность. */
|
||||
void Settings_CheckSettings(SettingsTypeDef *settings);
|
||||
|
||||
/** SETMEM_GENERAL_FUNC
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup SETMEM_SUPPORT_FUNC Support functions for writing/reading
|
||||
* @ingroup SETMEM_TOOLS
|
||||
* @brief Служебные функции для работы с настройками в памяти
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Запись настроек в память в зависимости от конфигурации */
|
||||
void WriteSettingsToMem(SettingsTypeDef *settings);
|
||||
/* Чтение настроек из памяти в зависимости от конфигурации */
|
||||
void ReadSettingsFromMem(SettingsTypeDef *settings);
|
||||
|
||||
/* Записывает массив настроек через указатель в память */
|
||||
void WriteSettingsArrayToMem(SettingsTypeDef *settings, SettingArrayTypeDef *settingarr);
|
||||
/* итает массив настроек через указатель в память */
|
||||
void ReadSettingsArrayFromMem(SettingsTypeDef *settings, SettingArrayTypeDef *settingarr);
|
||||
|
||||
/** SETMEM_SUPPORT_FUNC
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** SETMEM_TOOLS
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif //_SET_TO_MEM_H_
|
||||
Reference in New Issue
Block a user