#include "at32f403a_407.h"
#include "modbus_ai_params.h"
#include "settings_api.h"
#include "modbus_params.h"
#include "analog_input.h"
#include "preset_ai.h"


extern mb_param_t mb_param[];

#if defined (MAI_12)

//
uint16_t mb_init_ai_params(uint16_t i)
{
    uint16_t index = i;
    uint16_t addr = 0;  
  
    // Статус входов (вкл./выкл.)
    mb_param[index].reg = 0x0300;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.ai_state_bits;
	mb_param[index].set = mb_set_ai_state;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;

    // Режим работы входов
    mb_param[index].reg = 0x0301;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.ai_mode_bits;
	mb_param[index].set = mb_set_ai_mode;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;

    // Диапазон измерения напряжения
    mb_param[index].reg = 0x0302;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.ai_voltage_mode_bits;
	mb_param[index].set = mb_set_ai_voltage_mode;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;
    
    // Диапазон измерения тока
    mb_param[index].reg = 0x0303;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.ai_current_mode_bits;
	mb_param[index].set = mb_set_ai_current_mode;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;
        
    // Флаги аварий аналоговых входов. Определяется аппаратно.
    mb_param[index].reg = 0x0304;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&ai_alarm;
	mb_param[index].set = NULL;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;
    
    // 
    mb_param[index].reg = 0x0305;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.ext_sens_power;
	mb_param[index].set = mb_set_ext_sens_power;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;
    
    // Коэффициенты усиления. Регистры 0x0310 - 0x031В.
    addr = 0x0310;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 1;
        mb_param[index].param = (uint8_t*)&ai_gain[i];
        mb_param[index].set = mb_set_ai_gain;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 1;
        index++;
    }
    
    // ---------------------------------------------------------------------- //
    // Коэффициенты K
    addr = 0x0320;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.ai[i].k_factor;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
    
    // ---------------------------------------------------------------------- //
    // Коэффициенты B
    addr = 0x0340;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.ai[i].b_factor;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
        
    // ---------------------------------------------------------------------- //
    // Сырые данные каналов ADC
    addr = 0x0360;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr + i;
        mb_param[index].size = 1;
        mb_param[index].param = (uint8_t*)&adc_com_raw_data[i];
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        index++;
    }
    
    addr = 0x036C;
    //CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R
    for (int i = 0; i < AI_ADD_NUMBER; i++)
    {
        mb_param[index].reg = addr + i;
        mb_param[index].size = 1;
        mb_param[index].param = (uint8_t*)&adc_add_raw_data[i];
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        index++;
    }

    // ---------------------------------------------------------------------- //
    // Фильтрованные данные с учетом коэф-ов К, B
    addr = 0x0380;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&adc_com_data[i];
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
    
    // ---------------------------------------------------------------------- //
    // Фильтрованные значения 12-и основных каналов. Вывод для отладки.
    addr = 0x03A0;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr + i;
        mb_param[index].size = 1;
        mb_param[index].param = (uint8_t*)&adc_com_fil_data[i];
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        index++;
    }
    
    // ---------------------------------------------------------------------- //
    
    // Статус уставок (вкл./выкл.)
    mb_param[index].reg = 0x03B0;
	mb_param[index].size = 1;
	mb_param[index].param = (uint8_t*)&settings.preset_state_bits;
	mb_param[index].set = mb_set_preset_state;
    mb_param[index].get = NULL;
    mb_param[index].check_handler = mb_check_dummy;
    
    index++;
    
    // Нижнее значение уставки
    addr = 0x03BA;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.preset[i].min;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
    
    // Верхнее значение уставки
    addr = 0x03D2;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.preset[i].max;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
    
    // Значение гистерезиса
    addr = 0x03EA;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.preset[i].hyst;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
    
    // Набор калибровочных коэффициентов "K"
/*    
    addr = 0x0410;
    for (int i = 0; i < AI_COMMON_NUMBER; i++)
    {
        mb_param[index].reg = addr;
        mb_param[index].size = 2;
        mb_param[index].param = (uint8_t*)&settings.preset[i].hyst;
        mb_param[index].set = NULL;
        mb_param[index].get = NULL;
        mb_param[index].check_handler = mb_check_dummy;
        
        addr += 2;
        index++;
    }
*/    
    return index;
}


// -------------------------------------------------------------------------- //
//                          Установка параметров
// -------------------------------------------------------------------------- //

//
mb_delay_action_t mb_set_ai_state(void)
{
    ai_set();
    return MB_SAVE_SETTINGS;;
}


// При изменении режима измерения нужно проверить флаг аварий.
// Если флаг установлен, то канал нельзя перевести в режим измерения тока.
mb_delay_action_t mb_set_ai_mode(void)
{
    for (uint8_t i = 0; i < AI_COMMON_NUMBER; i++) 
    {
        if (!ai_alarm_f[i].alarm_flag)
            settings.ai[i].mode = (uint8_t)((settings.ai_mode_bits >> i) & 1);
        else if (((uint8_t)(settings.ai_mode_bits >> i) & 1) == 0)
            settings.ai[i].mode = (uint8_t)((settings.ai_mode_bits >> i) & 1);
    }  
    ai_set_meas_mode();  
    return MB_SAVE_SETTINGS;
}


// Диапазон измерения напряжения.
mb_delay_action_t mb_set_ai_voltage_mode(void)
{
    for (uint8_t i = 0; i < AI_COMMON_NUMBER; i++)
    {
        settings.ai[i].voltage_mode = (uint8_t)((settings.ai_voltage_mode_bits >> i) & 1);
    }
    
    return MB_SAVE_SETTINGS;
}


// Диапазон зимерения тока.
mb_delay_action_t mb_set_ai_current_mode(void)
{
    for (uint8_t i = 0; i < AI_COMMON_NUMBER; i++)
    {
        settings.ai[i].current_mode = (uint8_t)((settings.ai_current_mode_bits >> i) & 1);
    }
    
    return MB_SAVE_SETTINGS;
}


//
mb_delay_action_t mb_set_ai_gain(void)
{
    for (uint8_t i = 0; i < AI_COMMON_NUMBER; i++)
    {
        settings.ai[i].gain_factor = ai_gain[i];
    }  
    return MB_NO_ACTION;
}


//
mb_delay_action_t mb_set_ext_sens_power(void)
{
    if (!ai_cur_lim.alarm_flag)
        ai_ext_sens_power(settings.ext_sens_power);
      
    return MB_SAVE_SETTINGS;
}


// Статус уставок (вкл./выкл.)
mb_delay_action_t mb_set_preset_state(void)
{
    preset_set_state();
    return MB_SAVE_SETTINGS;
}



#endif