BCU/app/stm32fxxx_app/app/dido_manager.c

396 lines
10 KiB
C

#include "drv_gpio.h"
#include "gpio_manager.h"
#include "dido_manager.h"
#include "flash_manager.h"
#include "signal_manager.h"
#include "eeprom_manager.h"
#include "kit_debug.h"
typedef struct
{
uint8_t map[kDiType_End];
uint32_t dly[MAX_DI_NUM];
uint16_t tick[MAX_DI_NUM];
DiType type[MAX_DI_NUM];
DiStatus status[MAX_DI_NUM];
DiPolarity polarity[MAX_DI_NUM];
DiFun fun[MAX_DI_NUM];
}DiItem;
DiItem di_item __attribute__((section (".CCM_RAM")));
typedef struct
{
uint8_t relay_start_io;
uint8_t map[kDoType_End];
uint16_t tick[APP_CFG_RELAY_NUM];
DoCtrlStrategy main_ctrl;
DoType type[APP_CFG_RELAY_NUM];
DoStatus ctrl_status[APP_CFG_RELAY_NUM];
DoStatus actual_status[APP_CFG_RELAY_NUM];
DoErrSrc err_src[APP_CFG_RELAY_NUM]; //DO故障检测源
DoLogic bmsCircuitCtrl;
DoLogic doLogicArray[APP_CFG_RELAY_NUM];
uint32_t off_tick[APP_CFG_RELAY_NUM];
}DoItem;
DoItem do_item __attribute__((section (".UNINIT_RAM"), zero_init));
DiStatus bms_get_di_status(DiType type)
{
uint8_t idx;
DiStatus st = kDiStatus_None;
if(type < kDiType_End)
{
idx = di_item.map[type];
if(idx < MAX_DI_NUM)
{
st = di_item.status[idx];
}
}
return st;
}
DiType bms_get_di_type(uint8_t idx)
{
DiType st = kDiType_Unused;
if(idx < MAX_DI_NUM)
{
st = di_item.type[idx];
}
return st;
}
DiPolarity bms_get_di_polarity(uint8_t idx)
{
DiPolarity st = kDiPolarity_Start;
if(idx < MAX_DI_NUM)
{
st = di_item.polarity[idx];
}
return st;
}
DoCtrlStrategy bms_get_main_ctrl_strategy(void)
{
return do_item.main_ctrl;
}
DoStatus bms_get_do_status_by_idx(uint8_t idx)
{
DoStatus res = kDoStatus_Off;
KIT_ASSERT_PARAM((idx < APP_CFG_RELAY_NUM) || (idx == 0xFF));
if (idx < APP_CFG_RELAY_NUM)
{
res = do_item.actual_status[idx];
}
return res;
}
DoStatus bms_get_do_status_by_type(DoType type)
{
DoStatus res = kDoStatus_Off;
KIT_ASSERT_PARAM(type < kDoType_End);
if(type < kDoType_End)
{
res = bms_get_do_status_by_idx(do_item.map[type]);
}
return res;
}
DoType bms_get_do_type(uint8_t idx)
{
DoType res = kDoType_Unused;
KIT_ASSERT_PARAM(idx < APP_CFG_RELAY_NUM);
if (idx < APP_CFG_RELAY_NUM)
{
res = do_item.type[idx];
}
return res;
}
bool bms_is_do_config(DoType type)
{
bool res = false;
if(type < kDoType_End)
{
res = (do_item.map[type] != 0xFF);
}
return res;
}
DoErrSrc bms_get_do_err_src(DoType type)
{
DoErrSrc res = kDoErrSrc_None;
KIT_ASSERT_PARAM(type < kDoType_End);
if((type < kDoType_End) && (do_item.map[type] < APP_CFG_RELAY_NUM))
{
res = do_item.err_src[do_item.map[type]];
}
return res;
}
void bms_set_do_fault(DoType type, DoStatus status)
{
uint8_t relay_idx = 0;
KIT_ASSERT_PARAM((type < kDoType_End) && ((status == kDoStatus_Adhesion) || (status == kDoStatus_Open)));
if((type < kDoType_End) && ((status == kDoStatus_Adhesion) || (status == kDoStatus_Open)))
{
relay_idx = do_item.map[type];
if(relay_idx < APP_CFG_RELAY_NUM)
{
do_item.tick[relay_idx] = 0;
do_item.actual_status[relay_idx] = status;
}
}
}
void bms_crtl_do_status(DoType type, DoCtrlStatus status, uint16_t dly)
{
uint8_t relay_idx = 0;
KIT_ASSERT_PARAM((type < kDoType_End) && ((status == kDoStatus_Off) || (status == kDoStatus_On)));
if((type < kDoType_End) && (status < kDoCtrlStatus_None))
{
relay_idx = do_item.map[type];
if((relay_idx < APP_CFG_RELAY_NUM)
&& (do_item.ctrl_status[relay_idx] < kDoStatus_ForceOff))
{
do_item.tick[relay_idx] = dly;
do_item.ctrl_status[relay_idx] = (DoStatus)status;
}
}
}
void bms_crtl_do_status_by_idx(uint8_t idx, DoCtrlStatus status, uint16_t dly)
{
KIT_ASSERT_PARAM((idx < APP_CFG_RELAY_NUM) && ((status == kDoStatus_Off) || (status == kDoStatus_On)));
if((idx < APP_CFG_RELAY_NUM)
&& (do_item.ctrl_status[idx] < kDoStatus_ForceOff))
{
do_item.tick[idx] = dly;
do_item.ctrl_status[idx] = (DoStatus)status;
}
}
void bms_force_crtl_do_status(uint8_t idx, DoCtrlStatus status)
{
KIT_ASSERT_PARAM((idx < APP_CFG_RELAY_NUM) && (status < kDoCtrlStatus_End));
if((idx < APP_CFG_RELAY_NUM) && (status < kDoCtrlStatus_End))
{
if(status < kDoCtrlStatus_None)
{
do_item.tick[idx] = RELAY_CTRL_NO_DLY;
do_item.ctrl_status[idx] = (DoStatus)(status + 2);
}
else
{
//取消强控时判断之前是强控状态,是则复位
if(do_item.actual_status[idx] > kDoStatus_On)
{
do_item.tick[idx] = RELAY_CTRL_NO_DLY;
do_item.ctrl_status[idx] = kDoStatus_Off;
}
}
}
}
void bms_cut_all_relay(void)
{
uint32_t i;
for(i = 0; i < APP_CFG_RELAY_NUM; i++)
{
do_item.tick[i] = 0;
do_item.ctrl_status[i] = kDoStatus_ForceOff;
do_item.actual_status[i] = kDoStatus_ForceOff;
drv_gpio_set_pin_status(do_item.relay_start_io + i, kGpioStatus_Low);
}
}
const GpioStatus relay_status_to_ctrl[kDoStatus_End] ={kGpioStatus_Low, kGpioStatus_High, kGpioStatus_Low, kGpioStatus_High, kGpioStatus_Low, kGpioStatus_Low};
void bms_poll_di_do(uint32_t base_time)
{
uint32_t i;
DoStatus rly_st;
if(do_item.bmsCircuitCtrl != NULL)
{
do_item.bmsCircuitCtrl(base_time, 0);
}
//DO
for(i = 0; i < APP_CFG_RELAY_NUM; i++)
{
if(do_item.doLogicArray[i] != NULL)
{
do_item.doLogicArray[i](base_time, i);
}
if(do_item.tick[i] > 0)
{
if(do_item.tick[i] <= base_time)
{
do_item.tick[i] = 0;
rly_st = do_item.ctrl_status[i];
do_item.actual_status[i] = rly_st;
drv_gpio_set_pin_status(do_item.relay_start_io + i, relay_status_to_ctrl[rly_st]);
}
else
{
do_item.tick[i] -= base_time;
}
}
}
for (i = 0; i < MAX_DI_NUM; i++)
{
if(bms_get_signal((SignalIdx)(kSignalIdx_Di1 + i)) != di_item.polarity[i])
{
di_item.tick[i] += base_time;
if(di_item.tick[i] >= di_item.dly[i])
{
di_item.tick[i] = 0;
di_item.status[i] = kDiStatus_Trigger;
}
}
else
{
di_item.tick[i] = 0;
di_item.status[i] = kDiStatus_None;
}
if(di_item.fun[i] != NULL)
{
di_item.fun[i](base_time, di_item.status[i], di_item.type[i]);
}
}
}
/*****************************************************************************
*函数名称:relay_init
*函数功能:继电器初始化
*参 数:无
*返 回 值:无
*修订信息:
******************************************************************************/
extern const DiFun di_func[kDiType_End];
void bms_init_di_do(const DoLogic *do_main_poll_array, uint8_t do_main_poll_len, const DoLogic *do_poll_array)
{
uint32_t idx;
DiType di_type;
DoType do_type;
EepromDataType data_type;
DoErrSrc do_err_src_type;
// //上电前先断开所有继电器
//#if defined(BIUxxB) || defined(BSE1B) || defined(BSE2B)
// drv_gpio_set_pin_status(kGpioType_RlyEn, kGpioStatus_High);
// drv_gpio_set_pin_status(kGpioType_RlyEn, kGpioStatus_Low);
//#endif
bsp_eeprom_set_data(kRelay2_1ForceCtrlStatus, 0x0202, kEepromDataType_Full);
bsp_eeprom_set_data(kRelay4_3ForceCtrlStatus, 0x0202, kEepromDataType_Full);
bsp_eeprom_set_data(kRelay6_5ForceCtrlStatus, 0x0202, kEepromDataType_Full);
bsp_eeprom_set_data(kRelay8_7ForceCtrlStatus, 0x0202, kEepromDataType_Full);
bsp_eeprom_set_data(kRelay10_9ForceCtrlStatus, 0x0202, kEepromDataType_Full);
for(idx = kDoType_Start; idx < kDoType_End; idx++)
{
do_item.map[idx] = 0xFF;
}
for (idx = 0; idx < APP_CFG_RELAY_NUM; idx++)
{
do_item.tick[idx] = 0;
do_item.off_tick[idx] = 0;
do_item.relay_start_io = kGpioType_DO1;
if(get_eeprom_data(kEep_IsSoftReset, kEepromDataType_Low) == 0)
{
do_item.ctrl_status[idx] = kDoStatus_Off;
do_item.actual_status[idx] = kDoStatus_Off;
}
else
{
if(do_item.ctrl_status[idx] < kDoStatus_End)
{
drv_gpio_set_pin_status(do_item.relay_start_io + idx, relay_status_to_ctrl[do_item.ctrl_status[idx]]);
}
else
{
do_item.ctrl_status[idx] = kDoStatus_Off;
}
}
//sfj 7.23新加 DO9 DO10
if(idx == 8 || idx == 9)
{
do_type = (DoType)(get_eeprom_data(kEep_Relay10_9Type, (EepromDataType)(idx % 2)));
if (do_type < kDoType_End)
{
do_item.map[do_type] = idx;
do_item.type[idx] = do_type;
do_item.doLogicArray[idx] = do_poll_array[do_type];
}
do_err_src_type = (DoErrSrc)get_eeprom_data(kEep_DO10_DO9_ErrSrc, (EepromDataType)(idx % 2));
if(do_err_src_type < kDoErrSrc_End)
{
do_item.err_src[idx] = do_err_src_type;
}
}
else//do1-do8
{
do_type = (DoType)(get_eeprom_data(kEep_Relay2_1Type + (idx >> 1), (EepromDataType)(idx % 2)));
if (do_type < kDoType_End)
{
do_item.map[do_type] = idx;
do_item.type[idx] = do_type;
do_item.doLogicArray[idx] = do_poll_array[do_type];
}
do_err_src_type = (DoErrSrc)get_eeprom_data(kEep_DO2_DO1_ErrSrc + (idx >> 1), (EepromDataType)(idx % 2));
if(do_err_src_type < kDoErrSrc_End)
{
do_item.err_src[idx] = do_err_src_type;
}
}
}
//初始化订单继电器策略=本地和远方
idx = get_eeprom_data(kEep_ChgDisMode_HighVoltStrategy, kEepromDataType_Low);
if(idx < do_main_poll_len)
{
do_item.main_ctrl = (DoCtrlStrategy)idx;
do_item.bmsCircuitCtrl = do_main_poll_array[idx];
}
for(idx = kDiType_Start; idx < kDiType_End; idx++)
{
di_item.map[idx] = 0xFF;
}
for (idx = 0; idx < MAX_DI_NUM; idx++)
{
data_type = (EepromDataType)(idx % 2);
di_item.dly[idx] = get_eeprom_data(kEep_Di2_1Delay + (idx >> 1), data_type) * 100;
di_type = (DiType)get_eeprom_data(kEep_Di2_1Type + (idx >> 1), data_type);
if (di_type < kDiType_End)
{
di_item.map[di_type] = idx;
di_item.type[idx] = di_type;
di_item.fun[idx] = di_func[di_type];
}
di_item.polarity[idx] = (DiPolarity)get_eeprom_data(kEep_Di2_1Polarity + (idx >> 1), data_type);
}
}