1.5wuling_zhuanjietou/HARDWARE/CAN/can_app.c

512 lines
12 KiB
C
Raw Normal View History

2024-10-17 01:06:51 +00:00
/******************** (C) COPYRIGHT 2011 Ƕ<><C7B6>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ********************
* <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>can_app.c
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
*
* <EFBFBD> <EFBFBD><EFBFBD>V1.0
**********************************************************************************/
#include "Sys.h"
#include "adc.h"
#include "can.h"
#include "CanBusDrv.h"
#include "candrvctrl.h"
static st_cl candrv_if[2];
/*****************************************************************************
* <EFBFBD><EFBFBD>¼ÿһ<EFBFBD><EFBFBD>CAN ID<EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
****************************************************************************/
static struct
{
unsigned int frame_id; /* ID */
unsigned int period; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
unsigned int send_tick; /* <20><><EFBFBD><EFBFBD>TICK */
unsigned int sent_tick; /* <20><><EFBFBD>ͳɹ<CDB3>TICK */
} CAN_ID_SENT_TICK_MAP[] =
{
{CANBMS65CINFOID_WULING, 1000, 0, 0},
{CANBMS38AINFOID_WULING, 100, 0, 0},
{CANBMS38BINFOID_WULING, 100, 0, 0},
{CANBMS38CINFOID_WULING, 100, 0, 0},
{CANBMS38DINFOID_WULING, 100, 0, 0},
{CANBMS38EINFOID_WULING, 100, 0, 0},
{CANBMS598INFOID_WULING, 1000, 0, 0},
{CANBMS599INFOID_WULING, 1000, 0, 0},
{CANBMS59AINFOID_WULING, 1000, 0, 0},
};
void can2_bus_error_cb(e_link_sts err);
/****************************************************************************
* @brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>can ID<EFBFBD><EFBFBD>ʵ<EFBFBD>ʷ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>Ƿ񳬹<EFBFBD>ָ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
*
* @param frame_id: Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN ID,
* @param outtime: <EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD><EFBFBD>λms
*
* @return: bool
* true: <EFBFBD><EFBFBD><EFBFBD>ڳ<EFBFBD>ʱ
* false: δ<EFBFBD><EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD>
*/
bool can_sent_cycle_timeout(unsigned int frame_id)
{
unsigned short i;
for (i=0; i < (sizeof(CAN_ID_SENT_TICK_MAP)/sizeof(CAN_ID_SENT_TICK_MAP[0])); i++)
{
if (CAN_ID_SENT_TICK_MAP[i].frame_id == frame_id)
{
if ( CAN_ID_SENT_TICK_MAP[i].sent_tick == 0)
{
return true;
}
// if (CAN_ID_SENT_TICK_MAP[i].send_tick == 0 || CAN_ID_SENT_TICK_MAP[i].sent_tick == 0)
// {
// return true;
// }
#if 0
else if (abs(CAN_ID_SENT_TICK_MAP[i].sent_tick - CAN_ID_SENT_TICK_MAP[i].send_tick) < 5)
{
/* <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ͷ<EFBFBD><CDB7>ͳɹ<CDB3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>϶<EFBFBD><CFB6><EFBFBD>һ<EFBFBD>η<EFBFBD><CEB7>ͳɹ<CDB3><C9B9>ˣ<EFBFBD><CBA3>÷<EFBFBD><C3B7><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>жԱ<D0B6> */
if (TickOut(&CAN_ID_SENT_TICK_MAP[i].send_tick, CAN_ID_SENT_TICK_MAP[i].period))
{
return true;
}
else
{
return false;
}
}
#endif
else if (TickOut(&CAN_ID_SENT_TICK_MAP[i].sent_tick, CAN_ID_SENT_TICK_MAP[i].period - 3))
{
/* <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ͷ<EFBFBD><CDB7>ͳɹ<CDB3>ʱ<EFBFBD><EFBFBD><E4B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>϶<EFBFBD><CFB6><EFBFBD>һ<EFBFBD>η<EFBFBD><CEB7><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>η<EFBFBD><CEB7>ͳɹ<CDB3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>жԱ<D0B6> */
return true;
}
else
{
return false;
}
}
}
return true;
}
/****************************************************************************
* @brief: <EFBFBD><EFBFBD>¼ÿһ<EFBFBD><EFBFBD>CANid<EFBFBD>ķ<EFBFBD><EFBFBD>ͳɹ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
*
* @param frame_id: <EFBFBD><EFBFBD><EFBFBD>ͳɹ<EFBFBD>CAN ID
*
* @return: void
*/
static __inline void can_sent_tick_update(unsigned int frame_id)
{
unsigned short i;
for (i=0; i < (sizeof(CAN_ID_SENT_TICK_MAP)/sizeof(CAN_ID_SENT_TICK_MAP[0])); i++)
{
if (CAN_ID_SENT_TICK_MAP[i].frame_id == frame_id)
{
TickOut(&CAN_ID_SENT_TICK_MAP[i].sent_tick, 0);
}
}
}
/****************************************************************************
* @brief: <EFBFBD><EFBFBD>¼ÿһ<EFBFBD><EFBFBD>CANid<EFBFBD>ķ<EFBFBD><EFBFBD>͵<EFBFBD>ʱ<EFBFBD><EFBFBD>
*
* @param frame_id: <EFBFBD><EFBFBD><EFBFBD>ͳɹ<EFBFBD>CAN ID
*
* @return: void
*/
static __inline void can_send_tick_update(unsigned int frame_id)
{
unsigned short i;
for (i=0; i < (sizeof(CAN_ID_SENT_TICK_MAP)/sizeof(CAN_ID_SENT_TICK_MAP[0])); i++)
{
if (CAN_ID_SENT_TICK_MAP[i].frame_id == frame_id)
{
TickOut(&CAN_ID_SENT_TICK_MAP[i].send_tick, 0);
}
}
}
/*can <20><> <20><><EFBFBD><EFBFBD>*/
int8_t can_write( CanTxMsg *TxMessage)
{
u16 time_up = 0;
if (candrv_if[0].SEND != NULL)
{
return candrv_if[0].SEND(0, (TxMessage->IDE == CAN_ID_EXT)?TxMessage->ExtId:TxMessage->StdId, \
TxMessage->Data, (TxMessage->RTR == CAN_RTR_DATA)?TxMessage->DLC:0, \
(TxMessage->IDE == CAN_ID_EXT)?TxMessage->ExtId:TxMessage->StdId,NULL);
}
return 0;
}
int8_t can_write2( CanTxMsg *TxMessage)
{
u16 time_up = 0;
uint8_t TransmitMailbox;
static u16 sendpoweronflag = 0;
static u8 sendlowvoltflag = 0;
static u8 sendhighvoltflag = 0;
#if 1
if(sendpoweronflag++ < 12) //<2F><><EFBFBD>ϵ粻<CFB5>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ
{
}
else
{
if(sendpoweronflag > 100)sendpoweronflag =100;
if(sendlowvoltflag == 0)
{
if (Sample_DataS.VIN_Input_Voltage < 5.90) {
sendlowvoltflag = 1;
return 1;
}
}
else
{
if (Sample_DataS.VIN_Input_Voltage < 6.40) {
return 1;
}
else
{
sendlowvoltflag = 0;
}
}
if(sendhighvoltflag == 0)
{
if (Sample_DataS.VIN_Input_Voltage > 18.1) {
sendhighvoltflag = 1;
return 1;
}
}
else
{
if (Sample_DataS.VIN_Input_Voltage > 17.6) {
return 1;
}
else
{
sendhighvoltflag = 0;
}
}
}
#endif
//UDS<44><53>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>
if (!UdsApi_Is_UdsEnableNCMTx()) {
return 1;
}
if (candrv_if[1].SEND != NULL)
{
if (candrv_if[1].SEND(1, (TxMessage->IDE == CAN_ID_EXT)?TxMessage->ExtId:TxMessage->StdId, \
TxMessage->Data, (TxMessage->RTR == CAN_RTR_DATA)?TxMessage->DLC:0, \
(TxMessage->IDE == CAN_ID_EXT)?TxMessage->ExtId:TxMessage->StdId, NULL))
{
/* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD> */
//can_send_tick_update((TxMessage->IDE == CAN_ID_EXT)?TxMessage->ExtId:TxMessage->StdId);
return 0;
}
}
return 0;
}
/************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BUSSOFF<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>
***********************************************************************************************************/
typedef enum
{
E_BUS_NORMAL = 0,
E_BUS_BUSOFF,
E_BUS_RECOVERY_ACK,
} bus_recovery_step_e;
typedef struct
{
unsigned char step; /* 0 - <20><><EFBFBD><EFBFBD> 1 - bus off <20><>ʱ 2-bus off recovery ȷ<><C8B7> */
unsigned int bus_off_tick; /* <20><><EFBFBD><EFBFBD>bus off<66><66>ʱ<EFBFBD><CAB1> */
unsigned int recovery_tick; /* recovery<72><79>ʱ<EFBFBD><CAB1> */
unsigned short recovery_times; /* <20><><EFBFBD><EFBFBD>recovey<65><79><EFBFBD><EFBFBD> */
unsigned char first_frm;
} bus_off_recovery_t;
static const unsigned short BUS_OFF_TIME_MS[] = {30, 198, 198, 198, 198, 198};
static bus_off_recovery_t canbus[BSP_CAN_CHANNEL_NUM];
/**
* @brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>bus off<EFBFBD><EFBFBD>recovery<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param : void
*
* @return: void
*
* @remark: <EFBFBD>Զ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD>ɷ<EFBFBD><EFBFBD>ڶ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD>ִ<EFBFBD>еļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>10ms<EFBFBD><EFBFBD>
*/
#include "led.h"
extern void WULING_DCDCSendBms2_force(void);
extern u8 EntSlpFlag ;
void can_bus_off_recovery(void)
{
unsigned char i;
unsigned int timeout;
unsigned char buffer[8]={0};
for (i = 0; i < BSP_CAN_CHANNEL_NUM; i++)
{
// if ((canbus[i].step == E_BUS_BUSOFF) && (EntSlpFlag==0)/* && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/)
if ((canbus[i].step == E_BUS_BUSOFF)/* && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/)
{
if (canbus[i].recovery_times < (sizeof(BUS_OFF_TIME_MS)/sizeof(BUS_OFF_TIME_MS[0])))
{
timeout = BUS_OFF_TIME_MS[canbus[i].recovery_times];
}
else
{
/* reopen <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
timeout = BUS_OFF_TIME_MS[(sizeof(BUS_OFF_TIME_MS)/sizeof(BUS_OFF_TIME_MS[0]))-1];
}
if (TickOut(&canbus[i].bus_off_tick, timeout))
{
SYS_ENTER_CRITICAL();
canbus[i].recovery_times++;
if (candrv_if[i].ConfigBus != NULL) candrv_if[i].ConfigBus(i, 0,0,0);
canbus[i].step = E_BUS_RECOVERY_ACK;
// /* ģ<><EFBFBD><E2B7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD> */
// if(ChkPwrManageAccoff()!=0 )
// {
buffer[0]=1;
// }
if (candrv_if[i].SEND!= NULL) candrv_if[i].SEND(i, CANBMS65CINFOID_WULING, buffer, 8, CANBMS65CINFOID_WULING, NULL);
SYS_EXIT_CRITICAL();
TickOut(&canbus[i].recovery_tick, 0);
canbus[i].first_frm = 1;
}
}
else if (canbus[i].step == E_BUS_RECOVERY_ACK)
{
if (TickOut(&canbus[i].recovery_tick, 103))
{
WULING_DCDCSendBms2_force();
canbus[i].recovery_times = 0;
canbus[i].step = E_BUS_NORMAL;
}
}
}
}
/**
* @brief: <EFBFBD><EFBFBD>ӡ can <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
*/
void can_bus_off_status_printf(void)
{
printf("can 1: step(%d), recorvery(%d), last bus off tick(%d), last recovery tick(%d)!\n", \
canbus[0].step, canbus[0].recovery_times, canbus[0].bus_off_tick, canbus[0].recovery_tick);
printf("can 2: step(%d), recorvery(%d), last bus off tick(%d) last recovery tick(%d)!\n", \
canbus[1].step, canbus[1].recovery_times, canbus[1].bus_off_tick, canbus[1].recovery_tick);
}
/***********************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵײ<EFBFBD><EFBFBD>Ľӿ<EFBFBD>
**********************************************************************************************/
void can2_bus_error_cb(e_link_sts err)
{
if (err != e_err_bussoff)
{
/* <20><><EFBFBD><EFBFBD>BUSS OFF<46><46>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
return;
}
if (canbus[1].step != E_BUS_BUSOFF)
{
if (candrv_if[1].CloseLink != NULL) candrv_if[1].CloseLink(1);
canbus[1].step = E_BUS_BUSOFF;
TickOut(&canbus[1].bus_off_tick, 0);
}
}
static void can2_comm_sent_cb(unsigned int canid, unsigned int result)
{
/* <20><><EFBFBD>ͻص<CDBB> */
if (result == _SUCCESS)
{
/* <20><><EFBFBD>ͳɹ<CDB3> */
can_sent_tick_update(canid);
if (canbus[1].first_frm > 0 && canbus[1].step == E_BUS_RECOVERY_ACK)
{
canbus[1].first_frm = 0;
TickOut(&canbus[1].recovery_tick, 0);
}
}
else if (result == _ABANDON)
{
/* <20><>Ϊ<EFBFBD><EFBFBD>ָ<EFBFBD> */
}
else
{
/* <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7> */
}
}
static st_pl can2_protocol =
{
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>",
0,
3,
10,
NULL,
can2_bus_error_cb,
can2_comm_sent_cb
};
#if 0
static void can1_bus_error_cb(e_link_sts err)
{
}
static void can1_comm_sent_cb(unsigned int canid, unsigned int result)
{
/* <20><><EFBFBD>ͻص<CDBB> */
}
#endif
static st_pl can1_protocol =
{
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>",
0,
3,
10,
NULL,
NULL,
NULL
};
void InitCanDrvCtrlMode(void);
void InitCanifToCanDrvCtrl(void);
bool InstallProtocalToIF(unsigned char chan, st_pl* ppl, st_cl * pcl);
/**
* @brief: <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>can Э<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void can_porting_init(void);
/**
* @brief: <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>can Э<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵĵ<EFBFBD><EFBFBD><EFBFBD>
*/
void can_porting_schedule(void);
void app_can_handle(void)
{
static uint8_t bms_rev_busy_flag = 0;
static CanRxMsg MutliBMSCAN1Msg;
CanRxMsg rec_message;
unsigned int id;
unsigned char data[8], len;
can_porting_schedule();
while (candrv_if[0].REC != NULL && candrv_if[0].REC(0,&id, data, &len) == true)
{
/* <20><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD> */
CAN_FRAME_INIT((CanTxMsg *)(&rec_message), id, data, len);
rec_message.FMI = 0;
bms_rev_busy_flag = 1;
if(bms_RcvCanSingleDataProc(rec_message) == 1)
{
MutliBMSCAN1Msg = rec_message;
bms_RcvCanMutliData(MutliBMSCAN1Msg,0,&bms_rev_busy_flag);
}
IWDG_Feed();
}
while (candrv_if[1].REC != NULL && candrv_if[1].REC(1,&id, data, &len) == true)
{
/* <20><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD> */
CAN_FRAME_INIT((CanTxMsg *)(&rec_message), id, data, len);
rec_message.FMI = 0;
//UDS<44><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (UdsApi_Is_UdsEnableNCMRx()) {
bms_RcvCan2DataProc(rec_message);
}
UdsApi_MsgQueueIn(rec_message);
memset(&rec_message,0,sizeof(rec_message));
// bms_RcvCan2DataProc(rec_message);
IWDG_Feed();
}
can_bus_off_recovery();
}
void app_can_init(void)
{
memset(&canbus[0], 0x00, sizeof(canbus));
memset(&candrv_if[0], 0x00, sizeof(candrv_if));
can_porting_init();
InitCanDrvCtrlMode();
InitCanifToCanDrvCtrl();
if(InstallProtocalToIF(0,&can1_protocol,&candrv_if[0]) == true)
{
printf("can1 Э<><D0AD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>\r\n");
}
if(InstallProtocalToIF(1,&can2_protocol,&candrv_if[1]) == true)
{
printf("can2 Э<><D0AD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>\r\n");
}
if (candrv_if[0].ConfigBus != NULL)
{
candrv_if[0].ConfigBus(0, 0, 0, 0);
}
if (candrv_if[1].ConfigBus != NULL)
{
candrv_if[1].ConfigBus(1, 0, 0, 0);
}
}