forked from gary/BCU
2
0
Fork 0
BCU/app/stm32fxxx_app/app/dido_manager.c

397 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
//@wagnk2-17这里原本的status加了2取消了
do_item.ctrl_status[idx] = (DoStatus)(status);
}
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);
}
}