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

#include "lmcal_cfg.h"
#include "lmcal_exmc.h"
#include "lmcal_exmc_port.h"

//******************************************* Локальные константы *******************************************

#define EXMC_CH_CONFIG_FILL(nChNum)              \
{                                                \
    .enable   = LMCAL_EXMC_CH##nChNum##_ENABLE,  \
    .addr     = LMCAL_EXMC_CH##nChNum##_ADDR,    \
    .size     = LMCAL_EXMC_CH##nChNum##_SIZE     \
}

//******************************************* Проверка параметров *******************************************


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

// Конфигурация канала
typedef struct
{
    bool enable;
    u32  addr;
    u32  size;
} exmc_ch_config_t;


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

#if (LMCAL_EXMC_CH0_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch0_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH0_ADDR);
#endif

#if (LMCAL_EXMC_CH1_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch1_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH1_ADDR);
#endif

#if (LMCAL_EXMC_CH2_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch2_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH2_ADDR);
#endif

#if (LMCAL_EXMC_CH3_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch3_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH3_ADDR);
#endif

#if (LMCAL_EXMC_CH4_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch4_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH4_ADDR);
#endif

#if (LMCAL_EXMC_CH5_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch5_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH5_ADDR);
#endif

#if (LMCAL_EXMC_CH6_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch6_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH6_ADDR);
#endif

#if (LMCAL_EXMC_CH7_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch7_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH7_ADDR);
#endif

#if (LMCAL_EXMC_CH8_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch8_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH8_ADDR);
#endif

#if (LMCAL_EXMC_CH9_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch9_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH9_ADDR);
#endif

#if (LMCAL_EXMC_CH10_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch10_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH10_ADDR);
#endif

#if (LMCAL_EXMC_CH11_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch11_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH11_ADDR);
#endif

#if (LMCAL_EXMC_CH12_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch12_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH12_ADDR);
#endif

#if (LMCAL_EXMC_CH13_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch13_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH13_ADDR);
#endif

#if (LMCAL_EXMC_CH14_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch14_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH14_ADDR);
#endif

#if (LMCAL_EXMC_CH15_ENABLE == 1)
lmcal_exmc_t* const lmcal_exmc_ch15_buf = (lmcal_exmc_t*)(LMCAL_EXMC_CH15_ADDR);
#endif


lmcal_exmc_t* const lmcal_exmc_buf[] = 
{
    #if (LMCAL_EXMC_CH0_ENABLE == 1)
    lmcal_exmc_ch0_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH1_ENABLE == 1)
    lmcal_exmc_ch1_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH2_ENABLE == 1)
    lmcal_exmc_ch2_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH3_ENABLE == 1)
    lmcal_exmc_ch3_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH4_ENABLE == 1)
    lmcal_exmc_ch4_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH5_ENABLE == 1)
    lmcal_exmc_ch5_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH6_ENABLE == 1)
    lmcal_exmc_ch6_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH7_ENABLE == 1)
    lmcal_exmc_ch7_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH8_ENABLE == 1)
    lmcal_exmc_ch8_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH9_ENABLE == 1)
    lmcal_exmc_ch9_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH10_ENABLE == 1)
    lmcal_exmc_ch10_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH11_ENABLE == 1)
    lmcal_exmc_ch11_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH12_ENABLE == 1)
    lmcal_exmc_ch12_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH13_ENABLE == 1)
    lmcal_exmc_ch13_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH14_ENABLE == 1)
    lmcal_exmc_ch14_buf,
    #else
    NULL,
    #endif

    #if (LMCAL_EXMC_CH15_ENABLE == 1)
    lmcal_exmc_ch15_buf,
    #else
    NULL,
    #endif
};

//************************************* Локальные (приватные) переменные ************************************

#if (LMCAL_DEBUG == 1)
static bool b_init_done = false;
#endif

static const exmc_ch_config_t exmc_st_ch_config[LMCAL_EXMC_CHANNEL_QTY] =
{ 
    EXMC_CH_CONFIG_FILL(0),
    EXMC_CH_CONFIG_FILL(1),
    EXMC_CH_CONFIG_FILL(2),
    EXMC_CH_CONFIG_FILL(3),
    EXMC_CH_CONFIG_FILL(4),
    EXMC_CH_CONFIG_FILL(5),
    EXMC_CH_CONFIG_FILL(6),
    EXMC_CH_CONFIG_FILL(7),
    EXMC_CH_CONFIG_FILL(8),
    EXMC_CH_CONFIG_FILL(9),
    EXMC_CH_CONFIG_FILL(10),
    EXMC_CH_CONFIG_FILL(11),
    EXMC_CH_CONFIG_FILL(12),
    EXMC_CH_CONFIG_FILL(13),
    EXMC_CH_CONFIG_FILL(14),
    EXMC_CH_CONFIG_FILL(15),
};



//***********************************************************************************************************
//******************************** Определения локальных (приватных) функций ********************************
//***********************************************************************************************************



//***********************************************************************************************************
//******************************** Определения процедур обработки прерываний ********************************
//***********************************************************************************************************



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

fun_res_t lmcal_exmc_init(void)
{
    fun_res_t err = ERR_OK;

    #if (LMCAL_DEBUG == 1)
        err = L_ASSERT(false == b_init_done);
        L_CHECK_ERR(err);
    #endif
    
    err = lmcal_exmc_port_init();
    L_CHECK_ERR(err);
    
    #if (LMCAL_DEBUG == 1)
    b_init_done = true;
    #endif

    L_EXIT;
    return err;
}



fun_res_t lmcal_exmc_deinit(void)
{
    fun_res_t err = ERR_OK;

    #if (LMCAL_DEBUG == 1)
        err = L_ASSERT(true == b_init_done);
        L_CHECK_ERR(err);
    #endif
    
    err = lmcal_exmc_port_deinit();
    L_CHECK_ERR(err);
        
    #if (LMCAL_DEBUG == 1)
    b_init_done = false;
    #endif

    L_EXIT;
    return err;
}


fun_res_t lmcal_exmc_erase_all(lmcal_exmc_t symbol)
{
    fun_res_t err = ERR_OK;

    #if (LMCAL_DEBUG == 1)
        err = L_ASSERT(true == b_init_done);
        L_CHECK_ERR(err);
    #endif
    
    for (u8 i = 0; i < LMCAL_EXMC_CHANNEL_QTY; i++)
    {
        if (exmc_st_ch_config[i].enable == true)
        {
            lmcal_exmc_t* buf_addr = lmcal_exmc_buf[i];
            u32 end_tmp = exmc_st_ch_config[i].size; // * LMCAL_EXMC_WTYPE;
            for (u32 tmp = 0; tmp < end_tmp; tmp++)
            {
                *(buf_addr++) = symbol;
            }
        }
    }

    #if (LMCAL_DEBUG == 1)
    L_EXIT;
    #endif
    return err;
}

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