//***********************************************************************************************************
//! @file        flash_mem.h
//! @brief       Обращение к встроенной flash памяти
//! @par         Поддерживаемые платформы: LTA
//! @version     v1.0.0
//! @date        29.06.2025
//! @details     Выполняет чтение, запись заводской и пользовательской информации из встроенной flash памяти.
//!
//!              Ограничения:
//!              - 
//!
//!              Особенности:
//!              - В случае, если память пуста или повреждена, глоб.указатели будут равны NULL.
//!              - Для инициализации нужно выполнить функцию fm_read()
//!
//***********************************************************************************************************

#ifndef _FLASH_MEM_H
#define _FLASH_MEM_H

//******************************************** Включаемые файлы *********************************************

#include "l_macro_types.h"
#include "flash_mem_cfg.h"
#include "lta_private.h"


//************************************ Глобальные (публичные) константы *************************************

// Размер пароля для записи настроек
#define FM_PASSWD_SIZE          (32)

// Размер поля резервной области памяти в байтах
#define FM_RES_DATA_SIZE        (256)


//******************************************* Определения типов *********************************************

typedef enum 
{
    FM_US_FLAGS_EMPTY                   = 0x0000,
    FM_US_FLAGS_AUTO_IP                 = 0x0001,  // разрешение автоматического получения IP-адреса (через DHCP или link-local)
    FM_US_FLAGS_USER_MAC                = 0x0002,  // использовать пользовательский, а не заводской MAC-адрес
    // FM_US_FLAGS_USER_IP                 = 0x0004,  // использовать пользовательский, а не заводской IP-адрес
    // FM_US_FLAGS_USER_PORTS              = 0x0008,  // использовать пользовательские, а не заводские порты
} fm_user_settings_flags_t;


typedef enum 
{
    FM_US_FORMAT_WRITE_ALL          = 0,    // Запись настроек
    FM_US_FORMAT_WRITE_ONLY_FLAGS,          // Запись только флагов
    FM_US_FORMAT_ERASE                      // Очистка
} fm_us_format_t;


typedef struct 
{
    uint32_t flags;                        // Флаги настроек (user_settings_flags_t)
    uint8_t mac[LTA_MAC_ADDR_SIZE];        // пользовательский MAC-адрес
    uint8_t ipv4_addr[LTA_IPV4_ADDR_SIZE]; // настройки статических параметров IPv4
    uint8_t ipv4_mask[LTA_IPV4_ADDR_SIZE];
    uint8_t ipv4_gate[LTA_IPV4_ADDR_SIZE];
    uint16_t tcp_cmd_port;                 // TCP-порт для обмена командами
    uint16_t tcp_data_port;                // TCP-порт для передачи данных
    uint32_t ctrl;                         // Режим работы (резерв)
    uint8_t  res[FM_RES_DATA_SIZE];        // Резерв
} fm_user_settings_data_t;


typedef struct 
{
    char     name[LTA_DEVNAME_SIZE];        // Название устройства
    char     serial[LTA_SERIAL_SIZE];       // Серийный номер устройства (ASCII строка, оканчивающаяся нулем)
    char     brd_rev[LTA_REVISION_SIZE];    // Ревизия платы   
    uint8_t  mac[LTA_MAC_ADDR_SIZE];        // Заводской MAC-адрес устройства
    uint8_t  res[FM_RES_DATA_SIZE];         // Резерв
} fm_factory_mem_data_t; 



//************************************ Глобальные (публичные) переменные ************************************

// Указатель на пользовательские настройки
extern fm_user_settings_data_t* fm_user_settings_data;

// Указатель на заводскую информацию
extern fm_factory_mem_data_t* fm_factory_mem_data;

// Указатель на калибровки
extern uint8_t* fm_cbr_data;

// Указатель на общие данные (пользовательскую память)
extern uint8_t* fm_cmn_data;



//******************************** Объявления глобальных (публичных) функций ********************************

//-----------------------------------------------------------------------------------------------------------
//! @brief       Обновление указателей на структуры данных.
//! @param       -
//! @retval      -
//-----------------------------------------------------------------------------------------------------------
extern void fm_read(void);



//-----------------------------------------------------------------------------------------------------------
//! @brief       Запись пользовательских настроек в память.
//!
//! param[in]    src          - указатель на структуру
//! param[in]    format       - формат выполнения команды
//! param[in]    cur_password - указатель на текущий пароль
//! param[in]    new_password - указатель на новый пароль (=0, если нет смены пароля)
//!
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_write_user_data(fm_user_settings_data_t* src, 
                                    fm_us_format_t format,
                                    const char* cur_password,
                                    const char* new_password);


//-----------------------------------------------------------------------------------------------------------
//! @brief       Очистка сектора пользовательских настроек.
//! param[in]    cur_password - указатель на текущий пароль
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_erase_user_data(const char* cur_password);



//-----------------------------------------------------------------------------------------------------------
//! @brief       Запись заводских настроек в память.
//!
//! param[in]    src          - указатель на структуру
//! param[in]    cur_password - указатель на текущий пароль
//! param[in]    new_password - указатель на новый пароль (=0, если нет смены пароля)
//!
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_write_factory_data(fm_factory_mem_data_t* src, 
                                       const char* cur_password,
                                       const char* new_password);



//-----------------------------------------------------------------------------------------------------------
//! @brief       Очистка сектора заводских настроек.
//! param[in]    cur_password - указатель на текущий пароль
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_erase_factory_data(const char* cur_password);



//-----------------------------------------------------------------------------------------------------------
//! @brief       Запись калибровок в память.
//!
//! param[in]    src  - указатель на данные
//! param[in]    addr - смещение адреса относительно сектора (в байтах)
//! param[in]    size - размер данных (в байтах)
//!
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_write_cbr_data(uint8_t* src,
                                   uint16_t addr,
                                   uint16_t size);


//-----------------------------------------------------------------------------------------------------------
//! @brief       Очистка сектора калибровок.
//! 
//! param[in]    addr - смещение адреса относительно сектора (в байтах)
//! param[in]    size - размер данных (в байтах)
//! 
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_erase_cbr_data(uint16_t addr,
                                   uint16_t size);




//-----------------------------------------------------------------------------------------------------------
//! @brief       Запись общедоступных данных в память.
//!
//! param[in]    src  - указатель на данные
//! param[in]    addr - смещение адреса относительно сектора (в байтах)
//! param[in]    size - размер данных (в байтах)
//!
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_write_cmn_data(uint8_t* src,
                                   uint16_t addr,
                                   uint16_t size);



//-----------------------------------------------------------------------------------------------------------
//! @brief       Очистка сектора общих данных.
//! 
//! param[in]    addr - смещение адреса относительно сектора (в байтах)
//! param[in]    size - размер данных (в байтах)
//! 
//! @retval      см. fun_res_t
//-----------------------------------------------------------------------------------------------------------
extern fun_res_t fm_erase_cmn_data(uint16_t addr,
                                   uint16_t size);



#endif

//*********************************************** КОНЕЦ ФАЙЛА ***********************************************
