#ifndef SETTINGS_API_H
#define SETTINGS_API_H

#include "at32f403a_407.h"
#include "model_cfg.h"
#include "usart.h"
#include "sys_api.h"
#include "io.h"
#include "mb.h"
#include "mbport.h"
#include "log.h"
#include "analog_input.h"
#include "analog_output.h"
#include "preset_ai.h"
#include <stdbool.h>


// Изменить версию если поменялась структура настроек
#define SETTINGS_VERSION    0x01


// ------------------------------------------------------------------- //
//					 	Граничные значения
// ------------------------------------------------------------------- //

#define MAX_ARCHIVE_PERIOD  43200

// ------------------------------------------------------------------- //
//					 	Настройки лога и архива
// ------------------------------------------------------------------- //

#define ARCH_DIO_CH_NUMBER              8

#define ARCH_AI_CH_NUMBER               12 //12  


// ------------------------------------------------------------------- //
//					 		Draft
// ------------------------------------------------------------------- //

/*
1. Uptime (uint32_t)                    // +
2. Realtime (unix timestamp, uint32_t)  // +
3. Версия прошивки                      // +
4. Модель (char 16 байт)                // +

*/



// ------------------------------------------------------------------- //
//					 		Modbus
// ------------------------------------------------------------------- //

#define MB_STOP_BIT_MASK    0x03
#define MB_STOP_BIT_1       0x00
#define MB_STOP_BIT_2       0x02

#define MB_PARITY_MASK      (0x03 << 3)
#define MB_NO_PAR           (0x00 << 3)
#define MB_EVEN_PAR         (0x02 << 3)
#define MB_ODD_PAR          (0x03 << 3)

#define MB_BRD_MASK         (0x07 << 5)
#define MB_BRD_2400         (0x00 << 5)
#define MB_BRD_4800         (0x01 << 5)
#define MB_BRD_9600         (0x02 << 5)
#define MB_BRD_19200        (0x03 << 5)
#define MB_BRD_38400        (0x04 << 5)
#define MB_BRD_57600        (0x05 << 5)
#define MB_BRD_115200       (0x06 << 5)



// Modbus 
typedef struct
{
	rate_t     baud;		// Скорость порта 
	parity_t   parity;		// Четность 
	databits_t databits;	// Число бит данных
	stopbits_t stopbits;	// Число стоп-бит  
    
} modbus_t;


// Общая структура настроек для IAP и FW
typedef struct
{
    uint16_t    mb_port;    // Настройки порта для modbus
    //char model[MODEL_LEN];  // Модель
} com_settings_t;


#if 0
// Дискретные входы
typedef struct
{
    uint16_t debounce_time; // период антидребезга в мс (0 - 10 сек)
} dinput_t;
#endif


// Полная структура настроек
typedef struct
{
    com_settings_t  com_settings;
    uint32_t    critical_section_crc;
/* WARNING! До поля CritSecCRC включительно структура настроек должна быть
* идентичной между бутлоадером и основным ПО и не должна изменяться при обновлении ПО.
* Контроль целостности настроек внутри IAP выполняется только для критической секции,
* т.к. контроль целостности всей структуры не имеет смысла
* (структура настроек всегда будет отличаться внутри основного ПО).
* В случае повреждения критического сектора, загружаются параметры по умолчанию. */    
    
    uint16_t    settings_version;   // Версия структуры настроек 
    uint32_t    control_word;       // Слово для контроля целостности структуры настроек
    
#if defined (MDIO_88)          
    
    di_t        di[DI_NUMBER];      //
    uint16_t    di_state_bits;      //
    
    uint16_t    di_mode_bits;           // режим работы, 0 - вход, 1 - счетчик импульсов
    uint16_t    di_norm_state_bits;     // нормальное состояние (0 - разомкнут, 1 - замкнут)        
    uint16_t    di_debounce[DI_NUMBER]; // дискретные входы
    
    do_t        dout[DO_NUMBER];        // параметры выходов в обычном режиме
    do_t        dout_save[DO_NUMBER];   // параметры выходов в безопасном режиме
    
    uint16_t    period_archive[ARCH_DIO_CH_NUMBER]; // период архивирования
#endif

#if defined (MAI_12)
    
    ai_t        ai[AI_COMMON_NUMBER];   // 
    ai_t        ai_add[AI_ADD_NUMBER];  //
     
    uint16_t    ai_state_bits;      // статус входа (для 12 основных), 0 - выкл, 1 - вкл
    uint16_t    ai_mode_bits;       // режим работы входов (для 12 основных), 0 - измерение напряжения, 1 - тока
    
    uint16_t    ai_voltage_mode_bits;   // режим измерения напряжения (0 - 0-10В, 1 - 0-1В)
    uint16_t    ai_current_mode_bits;   // режим измерения тока (0 - 4-20 мА, 1 - 0-20 mA)
    
    uint16_t    ext_sens_power;     // питание внешних датчиков, 0 - выкл, 1 - вкл
    
    uint16_t    period_archive[ARCH_AI_CH_NUMBER];  // период архивирования
    
    preset_ai_t preset[AI_COMMON_NUMBER];           // уставки
    uint16_t    preset_state_bits;  // статус уставки (0 - выкл, 1 - вкл)
      
#endif    

#if defined (MAO_4)    
    
    ao_t        ao[AO_NUMBER];      // параметры выходов 
    ao_t        ao_save[AO_NUMBER]; // параметры выходов в безопасном режиме
    
    uint16_t    ao_state_bits;      // статус выхода, 0 - выкл, 1 - вкл
    uint16_t    ao_state_save_bits; // статус выхода в безопасном режиме, 0 - выкл, 1 - вкл
    uint16_t    ao_mode_bits;       // режим работы выходов, 0 - напряжения, 1 - ток
    uint16_t    ao_mode_save_bits;  // режим работы выходов в безопасном режиме, 0 - напряжения, 1 - ток
    
#endif    
    
    uint16_t    save_mode;          // безопасный режим, 0 - выкл, 1 - вкл
    uint16_t    save_delay;         // время ожидания опроса (сек.)
      
    uint8_t     info[32];           // Пользовательская информация. Текстовая строка.
    
    
} settings_t;



// Загрузка структуры настроек из flesh
void settings_load(settings_t *settings);

//
void init_settings(void);

//
void settings_read_from_flash(uint8_t *data, uint32_t size);

//
uint32_t settings_get_crc(settings_t *settings);

//
uint32_t settings_get_crit_sec_crc(settings_t *settings);

// Сброс всех настроек в значения по умолчанию
void settings_set_all_default(void);


// -------------------------------------------------------------------------- //
// Настройки по умолчанию

//
void settings_set_modbus_def(uint16_t *mb_port);

//
void settings_conv_modbus_def(modbus_t *mb_settings, uint16_t *mb_port);

// Установка параметров Modbus
void settings_set_modbus_params(uint16_t mb_port);

//
uint32_t settings_get_mb_baud(modbus_t *mb_settings);

//
eMBParity settings_get_mb_par(modbus_t *mb_settings);

//
void settings_init_mb_port(uint8_t mb_addr);

// -------------------------------------------------------------------------- //

// Запись структуры настроек во flash
bool settings_save(settings_t *settings);

//
bool settings_save_with_log(void);

//
bool settings_write_to_flash(uint8_t *data, uint32_t size);

// Очистка сектора настроек
void settings_erase_flash_sector(void);

//
bool settings_is_changed(settings_t *new_settings);

//
void settings_print(void);


// Системные настройки
extern sys_settings_t sys_settings;

// Копия системных настроек
extern sys_settings_t temp_sys_settings;

// Общая структура настроек
extern settings_t settings;

//
extern SemaphoreHandle_t flash_mutex;

#endif /* #ifndef SETTINGS_API_H */

