#ifndef BSP_GATE_H_
#define BSP_GATE_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "kit_macro.h"

#define   MODBUS_INSTANCE_NUM   (5u)

typedef struct
{
    uint16_t read_buf_idx;
    uint16_t write_buf_idx;
    uint16_t read_buf_size;
    uint16_t write_buf_size;
    uint16_t *read_buf;
    uint16_t *write_buf;

    bool     is_write_check;
    bool     is_user_write_fun; //false 使用默认modbus写，无需自己实现，true需用自定义写配置函数
    
    uint16_t  write_data_addr_list[MODBUS_INSTANCE_NUM];
    struct _ModbusItem * write_data_mb_list[MODBUS_INSTANCE_NUM];
}GateItem;


#define GATE_STATIC_INIT(_name, _read_buf_size, _write_buf_size) \
    uint16_t _name##_read_buf[_read_buf_size];   \
    uint16_t _name##_write_buf[_write_buf_size];  \
    GateItem _name =  \
    {   \
        (0), \
        (0), \
        (_read_buf_size), \
        (_write_buf_size), \
        (_name##_read_buf), \
        (_name##_write_buf), \
    }
    
#define GATE_STATIC_INIT_CCM(_name, _read_buf_size, _write_buf_size) \
    uint16_t _name##_read_buf[_read_buf_size]  __attribute__((section (".CCM_RAM")));  \
    uint16_t _name##_write_buf[_write_buf_size]  __attribute__((section (".CCM_RAM")));  \
    GateItem _name =  \
    {   \
        (0), \
        (0), \
        (_read_buf_size), \
        (_write_buf_size), \
        (_name##_read_buf), \
        (_name##_write_buf), \
    }    

#define GATE_STATIC_INIT2(_name, _read_buf_size, _write_buf_size) \
    uint16_t _name##_read_buf[_read_buf_size];   \
    GateItem _name =  \
    {   \
        (0), \
        (0), \
        (_read_buf_size), \
        (_write_buf_size), \
        (_name##_read_buf), \
        (NULL), \
    }

#define GATE_STATIC_INIT2_CCM(_name, _read_buf_size, _write_buf_size) \
    uint16_t _name##_read_buf[_read_buf_size]  __attribute__((section (".CCM_RAM")));   \
    GateItem _name  __attribute__((section (".CCM_RAM"))) =  \
    {   \
        (0), \
        (0), \
        (_read_buf_size), \
        (_write_buf_size), \
        (_name##_read_buf), \
        (NULL), \
    }   
    
int16_t  bsp_gate_get_read_buf_addr(GateItem *item, uint8_t len);
int16_t  bsp_gate_get_write_buf_addr(GateItem *item, uint8_t len);
    
uint16_t bsp_gate_get_read_data(GateItem *item, uint16_t addr);  
uint16_t bsp_gate_get_write_data(GateItem *item, uint16_t addr);
bool     bsp_gate_set_data(GateItem *item, uint16_t addr, uint16_t data);
    
void     bsp_gate_push_read_data(GateItem *item, uint16_t addr, uint8_t *buf, uint8_t len);
void     bsp_gate_push_write_data(GateItem *item, uint16_t addr, uint8_t *buf, uint8_t len);    
uint16_t bsp_gate_copy_from_write_data(GateItem *item, uint8_t *buf);

bool bsp_gate_has_data_change(GateItem *item, uint16_t addr);    
    
#ifdef __cplusplus
}
#endif

#endif
