1063 lines
28 KiB
C
Raw Permalink Normal View History

2025-04-26 16:03:23 +08:00
/** ##########################################################################
** Filename :
** Project :
** Module :
** Processor :
** Version : 1.0
** Compiler :
** Date/Time :
** Abstract :
** Contents :
** Note :
**
** (c) Copyright dmdz Co.,Ltd
** --------------------------------------------------------------------------
** R E V I S I O N H I S T O R Y
** --------------------------------------------------------------------------
** Date Ver Author Description
** -20230602- --V1.0-- --mingyea--- ----
** #########################################################################*/
/*---------------------------------------------------------------------------
- I N C L U D E F I L E S
----------------------------------------------------------------------------*/
#include "common_types.h"
#include "common_memory.h"
#include "queue_entity.h"
#include "can.h"
#include "nvic.h"
#ifdef CAN_LS_NM
#include "Ls_Nm.h"
#endif
#ifdef CAN_AUTOSAR_EN
#include "can_drive.h"
#include "CanIf.h"
#endif
#include "bl_can.h"
static void can_tx_task(void);
/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- T Y P E D E F I N I T I O N S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- S T A T I C V A R I A B L E S
----------------------------------------------------------------------------*/
#ifdef CAN_DRIVE_QUEUE_ENABLE
static sequential_queue_s can_tx_queue;
static can_queue_elem_s can_tx_qbuf[CAN_ID_0_TX_QUEUE_DEPTH]; /* 隊列 */
static sequential_queue_s can_rx_queue;
static can_queue_elem_s can_rx_qbuf[CAN_ID_0_RX_QUEUE_DEPTH]; /* 隊列 */
#else
#endif
static can_s g_can[CAN_ID_TOTAL] = {0};
//#define CAN_TXMASK(hth) ((bl_u8_t)(0x01<<(hth)))
#define CAN_TXMASK(hth) ((bl_u8_t)(0x02))
/*---------------------------------------------------------------------------
* G L O B A L V A R I A B L E S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- F U N C T I O N P R O T O T Y P E
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : BaudRate CAN总线波特率bps
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
uint32_t CAN_GetBaudRateNum(uint32_t BaudRate)
{
switch (BaudRate)
{
case 1000000 :
return 0;
case 900000 :
return 1;
case 800000 :
return 2;
case 666000 :
return 3;
case 600000 :
return 4;
case 500000 :
return 5;
case 400000 :
return 6;
case 300000 :
return 7;
case 250000 :
return 8;
case 225000:
return 9;
case 200000 :
return 10;
case 160000:
return 11;
case 150000 :
return 12;
case 144000:
return 13;
case 125000 :
return 14;
case 120000:
return 15;
case 100000 :
return 16;
case 90000 :
return 17;
case 80000 :
return 18;
case 75000:
return 19;
case 60000 :
return 20;
case 50000 :
return 21;
case 40000 :
return 22;
case 30000 :
return 23;
case 20000 :
return 24;
default:
return 0;
}
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : CAN中断服务函数
----------------------------------------------------------------------------*/
void CAN_IRQHandler(void)
{
u8 l_buf_index = 0xffu;
u8 buffIdx =0u;
static uint8_t last_ESTAT = 5;
CanRxMsg tempCanRxMsg = {0u};
can_queue_elem_s l_rx;
uint32_t data1, data2;
#if 0
if ((FL_ENABLE == FL_CAN_IsEnabledIT_RXOK(CAN))
&& (FL_SET == FL_CAN_IsActiveFlag_RXOK(CAN)))
#else //改成 判断非空,更合理
if((FL_ENABLE == FL_CAN_IsEnabledIT_RXNotEmpty(CAN))
&& (FL_SET == FL_CAN_IsActiveFlag_RXNotEmpty(CAN)))
#endif
{
while(FL_CAN_IsActiveFlag_RXNotEmpty(CAN) == FL_SET)
{
tempCanRxMsg.ID = FL_CAN_ReadRXMessageID(CAN);
tempCanRxMsg.DLC = FL_CAN_ReadRXMessageLength(CAN);
data1 = FL_CAN_ReadRXMessageWord1(CAN);
data2 = FL_CAN_ReadRXMessageWord2(CAN);
tempCanRxMsg.Data[0] = (uint8_t)data1 & 0xff;
tempCanRxMsg.Data[1] = (uint8_t)(data1 >> 8) & 0xff;
tempCanRxMsg.Data[2] = (uint8_t)(data1 >> 16) & 0xff;
tempCanRxMsg.Data[3] = (uint8_t)(data1 >> 24) & 0xff;
tempCanRxMsg.Data[4] = (uint8_t)data2 & 0xff;
tempCanRxMsg.Data[5] = (uint8_t)(data2 >> 8) & 0xff;
tempCanRxMsg.Data[6] = (uint8_t)(data2 >> 16) & 0xff;
tempCanRxMsg.Data[7] = (uint8_t)(data2 >> 24) & 0xff;
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].canid = tempCanRxMsg.ID;
if( (tempCanRxMsg.ID != CANIF_PHY_RX_CANID) && (tempCanRxMsg.ID != CANIF_FUN_RX_CANID) )
{
g_can[CAN_ID_0].test[4]++;
}
else
{
g_can[CAN_ID_0].test[5]++;
}
#endif
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[0]++;
#endif
/* 拆分ID */
if (tempCanRxMsg.ID & (1 << 12))
{
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[1]++;
#endif
/* 扩展ID */
tempCanRxMsg.IDE = CAN_ID_EXT;
tempCanRxMsg.ID = ((tempCanRxMsg.ID & 0x7FF) << 18) + ((tempCanRxMsg.ID >> 13) & 0x3FFFF);
if (tempCanRxMsg.ID & 0x80000000)
{
/* 扩展远程帧 */
tempCanRxMsg.RTR = CAN_RTR_REMOTE;
}
else
{
/* 扩展数据帧 */
tempCanRxMsg.RTR = CAN_RTR_Data;
}
}
else
{
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[2]++;
#endif
/* 标准ID */
tempCanRxMsg.IDE = CAN_ID_STD;
if (tempCanRxMsg.ID & (1 << 11))
{
/* 标准远程帧 */
tempCanRxMsg.RTR = CAN_RTR_REMOTE;
}
else
{
/* 标准数据帧 */
tempCanRxMsg.RTR = CAN_RTR_Data;
}
tempCanRxMsg.ID = tempCanRxMsg.ID & 0x7FF;
}
/* 默认只有一个FIFO */
tempCanRxMsg.FMI = 0;
//加入队列
common_memory_copys((u8*)&l_rx.msg,(u8*)&tempCanRxMsg,sizeof(CAN_MsgInfoType));
common_memory_copys((u8*)&l_rx.buf[0],(u8*)&tempCanRxMsg.Data[0],CAN_FRAME_MAX_DLC);
//转成协议栈
if(l_rx.msg.IDE == CAN_ID_EXT)
{
l_rx.msg.IDE = EXTENDED_CAN;
}
l_rx.phy_id =INST_CANCOM0;
l_rx.mailbox_id =0u;
l_rx.msg.DLC = tempCanRxMsg.DLC;//can_sw_dlc_to_len(l_rx.msg.DLC);
#ifdef CAN_DRIVE_QUEUE_ENABLE
(void)queue_add_element(&can_rx_queue,(const sequential_queue_elem*)&l_rx);//NOLINT
#endif
l_rx.msg_id = l_rx.msg.ID;
l_rx.len = l_rx.msg.DLC;
l_rx.type = l_rx.msg.IDE;
//#ifdef CAN_AUTOSAR_EN
can_id_phy_rx_irq_task(CAN_ID_0,&l_rx);
//#endif
#if 0 //def CAN_LS_NM
if(CanNm_is_busoff() == TRUE)
{
#ifdef CAN_LS_NM
//Can_SetTxStatus_finish(CAN_ID_0);
CanNm_TxConfirmation_com(0,CAN_ID_0);
#endif
}
#endif
FL_CAN_ClearFlag_RXNotEmpty(CAN);
}
//FL_CAN_ClearFlag_RXOK(CAN);
//FL_CAN_ClearFlag_RXNotEmpty(CAN);
}
#if 1 //把溢出判断也监控
if((FL_CAN_IsActiveFlag_RXOverflow(CAN)==FL_SET)&&(FL_CAN_IsEnabledIT_RXOverflow(CAN)==FL_ENABLE))
{
FL_CAN_ClearFlag_RXOverflow(CAN);
//g_can_test[1]++;
}
#endif
if( (FL_ENABLE == FL_CAN_IsEnabledIT_TXOK(CAN) ) && (FL_SET == FL_CAN_IsActiveFlag_TXOK(CAN) ) )
{
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[3]++;
#endif
#ifdef CAN_AUTOSAR_EN
l_buf_index= g_can[CAN_ID_0].mailbox_id;
buffIdx =0u;
can_id_phy_tx_irq_task(CAN_ID_0,l_buf_index,buffIdx);
#else
#ifdef CAN_LS_NM
if(0 != (CAN->ISR & CAN_TXMASK(phyhth)))
{
#ifdef CAN_ENABLE_HIGH_TX
if(buf_index==2u)
{
FL_CAN_DisableIT_TXHighPriorBuffFull(CAN);
}
else
#endif
{
FL_CAN_DisableIT_TXOK(CAN);
}
}
Can_SetTxStatus_finish(CAN_ID_0);
CanNm_TxConfirmation_com(0,CAN_ID_0);
#endif
#endif
FL_CAN_ClearFlag_TXOK(CAN);
}
#ifdef CAN_ENABLE_HIGH_TX
if( (FL_ENABLE == FL_CAN_IsEnabledIT_TXHighPriorBuffFull(CAN)) && (FL_SET == FL_CAN_IsActiveFlag_TXOK(CAN) ) )
{
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[4]++;
#endif
#ifdef CAN_AUTOSAR_EN
l_buf_index= g_can[CAN_ID_0].mailbox_id;
buffIdx =0u;
can_id_phy_tx_irq_task(CAN_ID_0,l_buf_index,buffIdx);
#else
#ifdef CAN_LS_NM
Can_SetTxStatus_finish(CAN_ID_0);
CanNm_TxConfirmation_com(0,CAN_ID_0);
#endif
#endif
FL_CAN_ClearFlag_TXOK(CAN);
FL_CAN_ClearFlag_TXHighPriorBuffFull(CAN);
}
else
{
if( (FL_ENABLE == FL_CAN_IsEnabledIT_TXHighPriorBuffFull(CAN)) && (FL_CAN_IsActiveFlag_TXHighPriorBuffFull(CAN)) )
{
FL_CAN_ClearFlag_TXHighPriorBuffFull(CAN);
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[5]++;
#endif
}
}
#endif
#if 0
if(FL_CAN_IsActiveFlag_TXBuffFull(CAN) != FL_RESET)
{
FL_CAN_ClearFlag_TXBuffFull(CAN);
}
#endif
if (CAN->ISR & CAN_ISR_ERROR_Msk)
{
#if 0
/* 错误中断 */
/* 主动错误转换为被动错误时刻检测 */
if (last_ESTAT == 1)
{
if (((CAN->SR & (3 << 7)) >> 7) == 3)
{
;
}
}
last_ESTAT = ((CAN->SR & (3 << 7)) >> 7);
#endif
#ifdef CAN_LS_NM
//CanNm_PhysErrorInd(CAN_ID_0,NM_DLL_BUS_OFF_PRE);
#endif
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[6]++;
#endif
FL_CAN_ClearFlag_Error(CAN);
}
//if (CAN->ISR & CAN_ISR_BSOFF_Msk)
if( (FL_CAN_IsActiveFlag_BusOff(CAN)==TRUE) && (FL_CAN_IsEnabledIT_BusOff(CAN)==TRUE) )
{
/* busoff中断 */
/* CEN禁止后再使能即可清除can busoff的状态在CAN模块稳定后可以立即发送数据 */
//CAN->CR = 0;
//CAN->CR = 1;
FL_CAN_SetSoftwareReset(CAN,FL_CAN_SOFTWARE_RESET);
//CAN->ICR = CAN_ICR_CBSOFF_Msk;
#if 1
#ifdef CAN_LS_NM
CanNm_PhysErrorInd(CAN_ID_0,NM_DLL_BUS_OFF);
#endif
#endif
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[7]++;
#endif
FL_CAN_ClearFlag_BusOff(CAN);
}
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[8]++;
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : CAN接收中断配置
----------------------------------------------------------------------------*/
void CAN_NVIC_Configuration(void)
{
FL_CAN_ClearFlag_RXOK(CAN);
// FL_CAN_EnableIT_RXOK(CAN);
/* NVIC中断配置 */
NVIC_ClearPendingIRQ(CAN_IRQn);
NVIC_DisableIRQ(CAN_IRQn);
NVIC_SetPriority(CAN_IRQn, NVIC_PRIORITY_CAN);
NVIC_EnableIRQ(CAN_IRQn);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : FilterNumber ReceiveMsgId ID ReceiveMsgIdType ID类型0-1-
|Output parameters :
|Return value :
|Description : CAN接收滤波器
----------------------------------------------------------------------------*/
void CAN_ConfigFilter(uint8_t FilterNumber, uint32_t ReceiveMsgId, uint8_t ReceiveMsgIdType)
{
FL_CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
if (FilterNumber > FL_CAN_FILTER4)
{
return;
}
if (ReceiveMsgIdType == CAN_Id_Standard)
{
/* 标准帧 */
CAN_FilterInitStructure.filterIdStandard = ReceiveMsgId; /* 标准ID */
CAN_FilterInitStructure.filterIdSRR = 0;
CAN_FilterInitStructure.filterIdIDE = 0;
CAN_FilterInitStructure.filterIdRTR = 0;
CAN_FilterInitStructure.filterMaskIdHigh = 0X7FF;
CAN_FilterInitStructure.filterMaskIdSRR = 0x01;
CAN_FilterInitStructure.filterMaskIdIDE = 0x01; /* 滤波器掩码1该位参与滤波器比较0不参与 */
CAN_FilterInitStructure.filterMaskIdRTR = 0x01;
CAN_FilterInitStructure.filterEn = FL_ENABLE;
FL_CAN_FilterInit(CAN, &CAN_FilterInitStructure, FilterNumber);
}
else
{
CAN_FilterInitStructure.filterIdExtend = ReceiveMsgId; /* 扩展ID */
CAN_FilterInitStructure.filterIdSRR = 0X01;
CAN_FilterInitStructure.filterIdIDE = 0X01;
CAN_FilterInitStructure.filterIdRTR = 0X00;
CAN_FilterInitStructure.filterMaskIdHigh = 0X7FF;
CAN_FilterInitStructure.filterMaskIdLow = 0X3FFFF;
CAN_FilterInitStructure.filterMaskIdSRR = 0X01;
CAN_FilterInitStructure.filterMaskIdIDE = 0X01; /* 滤波器掩码1该位参与滤波器比较0不参与 */
CAN_FilterInitStructure.filterMaskIdRTR = 0x01;
CAN_FilterInitStructure.filterEn = FL_ENABLE;
FL_CAN_FilterInit(CAN, &CAN_FilterInitStructure, FilterNumber);
}
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : ---使autosar時調
----------------------------------------------------------------------------*/
void can_init(void)
{
#ifdef CAN_ID_0_EN
can0_init();
#endif
#ifdef CAN_ID_1_EN
can1_init();
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can_de_init(void)
{
#ifdef CAN_ID_0_EN
can0_de_init();
#endif
#ifdef CAN_ID_1_EN
can1_de_init();
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can_task(void)
{
can_tx_task();
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can_phy_drive_init(can_id_e phy_id)
{
switch(phy_id)
{
case CAN_ID_0:
#ifdef CAN_ID_0_EN
can0_init();
#endif
break;
case CAN_ID_1:
#ifdef CAN_ID_1_EN
can1_init();
#endif
break;
default:
break;
}
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : BaudRate CAN总线波特率
|Output parameters :
|Return value :
|Description : CAN
----------------------------------------------------------------------------*/
void CAN_Configuration(uint32_t BaudRate)
{
FL_CAN_InitTypeDef CAN_InitStructure = {0};
/* CAN register init */
//CAN_NVIC_Configuration();
//CAN_GPIO_Configuration();
/* CAN cell init */
#if 0
CAN_InitStructure.TS1 = CAN_BaudRateInitTab[CAN_GetBaudRateNum(BaudRate)].BS1;
CAN_InitStructure.TS2 = CAN_BaudRateInitTab[CAN_GetBaudRateNum(BaudRate)].BS2; /* 位时序设置 */
CAN_InitStructure.SJW = CAN_BaudRateInitTab[CAN_GetBaudRateNum(BaudRate)].SJW;
CAN_InitStructure.BRP = CAN_BaudRateInitTab[CAN_GetBaudRateNum(BaudRate)].PreScale; /* 波特率预分频 */
#else
#if 1 //75 %
CAN_InitStructure.TS1 = CAN_BS1_11tq;
CAN_InitStructure.TS2 = CAN_BS2_4tq; /* 位时序设置 */
CAN_InitStructure.SJW = CAN_SJW_3tq;
CAN_InitStructure.BRP = 0u; /* 波特率预分频 */
#else //81
CAN_InitStructure.TS1 = CAN_BS1_12tq;
CAN_InitStructure.TS2 = CAN_BS2_3tq; /* 位时序设置 */
CAN_InitStructure.SJW = CAN_SJW_2tq;
CAN_InitStructure.BRP = 0u; /* 波特率预分频 */
#endif
#endif
CAN_InitStructure.mode = FL_CAN_MODE_NORMAL; /* 工作模式设置 */
CAN_InitStructure.clockSource = FL_CMU_CAN_CLK_SOURCE_XTHF; /* 时钟源设置 */
FL_CAN_Init(CAN, &CAN_InitStructure);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can0_de_init(void)
{
#if 1
//CanTrcv_Disable();
//FL_CAN_Disable(CAN);
//FL_CMU_DisableGroup1BusClock(FL_CMU_GROUP1_BUSCLK_PAD);
//FL_CMU_DisableGroup4BusClock(FL_CMU_GROUP4_BUSCLK_ATIM);
//FL_CMU_DisableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_ATIM);
//FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_CAN);
//FL_CMU_DisableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_CAN);
FL_CAN_ClearFlag_RXOverflow(CAN);
FL_CAN_ClearFlag_TXOK(CAN);
FL_CAN_ClearFlag_TXHighPriorBuffFull(CAN);
FL_CAN_ClearFlag_Error(CAN);
FL_CAN_DisableIT_TXOK(CAN);
FL_CAN_Disable(CAN);
NVIC_ClearPendingIRQ(CAN_IRQn);
NVIC_DisableIRQ(CAN_IRQn);
#else
/* NVIC DeInit */
NVIC_DisableIRQ(CAN_IRQn);
NVIC_ClearPendingIRQ(CAN_IRQn);
/* Enable Peripheral Reset */
FL_RMU_EnablePeripheralReset(RMU);
FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_CAN);
FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_CAN);
FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_CAN);
FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_CAN);
FL_RMU_DisablePeripheralReset(RMU);
/* Close CANBUS Clock */
FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_CAN);
FL_CMU_DisableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_CAN);
/* GPIO DeInit */
//FL_GPIO_DeInit(GPIOA,FL_GPIO_PIN_6 | FL_GPIO_PIN_7);
//FL_GPIO_DeInit(GPIOC,FL_GPIO_PIN_6);
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can0_init(void)
{
#ifdef CAN_DRIVE_QUEUE_ENABLE
queue_init(&can_tx_queue,(sequential_queue_elem*)&can_tx_qbuf,CAN_ID_0_TX_QUEUE_DEPTH,sizeof(can_queue_elem_s));
queue_init(&can_rx_queue,(sequential_queue_elem*)&can_rx_qbuf,CAN_ID_0_RX_QUEUE_DEPTH,sizeof(can_queue_elem_s));
#endif
//CAN->CR = 0u; //为了重新初始化,相当于反初始化
CAN_Configuration(g_can0_baudrate);
/* 设置CAN接收滤波器 */
CAN_ConfigFilter(0, CANIF_PHY_RX_CANID, MSG_ID_TYPE);
CAN_ConfigFilter(1, CANIF_FUN_RX_CANID, MSG_ID_TYPE);
#if 1 //改成判断非空更合理
FL_CAN_ClearFlag_RXNotEmpty(CAN);
FL_CAN_EnableIT_RXNotEmpty(CAN); /* 接收中断使能 */
#else
/* 使能接收中断 */
FL_CAN_ClearFlag_RXOK(CAN);
FL_CAN_EnableIT_RXOK(CAN); //接收中断使能
#endif
//FL_CAN_ClearFlag_Error(CAN);
//FL_CAN_EnableIT_Error(CAN); //错误中断使能
FL_CAN_ClearFlag_RXOverflow(CAN);//接收溢出中断标志位清除
FL_CAN_EnableIT_RXOverflow(CAN);//接收溢出中断使能
FL_CAN_ClearFlag_BusOff(CAN); //BusOff中断使能
FL_CAN_EnableIT_BusOff(CAN);
//FL_CAN_ClearFlag_TXOK(CAN);
//FL_CAN_EnableIT_TXOK(CAN); //发送完成中断使能
g_can[CAN_ID_0].state_tx = CAN_TX_STATE_IDLE;
CAN_NVIC_Configuration(); //调用顺序会引起busoff不能恢复
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : TX FIFO发送数据
----------------------------------------------------------------------------*/
void FL_CAN_FIFO_Write(u8 mailbox_id,uint32_t id, uint32_t len, uint32_t data1, uint32_t data2)
{
#if 0
uint32_t i = 5;
while ((FL_CAN_IsActiveFlag_TXBuffFull(CAN) != FL_RESET)&i)
{
i--;
FL_DelayMs(1);
}
#endif
if(FL_CAN_IsActiveFlag_TXBuffFullSignal(CAN)==FL_RESET)
{
g_can[CAN_ID_0].mailbox_id = mailbox_id;
#ifdef CAN_ENABLE_HIGH_TX
if(mailbox_id == 2u)
{
FL_CAN_ClearFlag_TXHighPriorBuffFull(CAN);
FL_CAN_WriteHighPriorTXMessageID(CAN, id);
FL_CAN_WriteHighPriorMessageLength(CAN, len);
FL_CAN_WriteHighPriorMessageWord1(CAN, data1);
FL_CAN_WriteHighPriorMessageWord2(CAN, data2);
FL_CAN_EnableIT_TXHighPriorBuffFull(CAN);
}
else
#endif
{
FL_CAN_ClearFlag_TXOK(CAN);
FL_CAN_ClearFlag_TXBuffFull(CAN);
FL_CAN_WriteTXMessageID(CAN, id);
FL_CAN_WriteTXMessageLength(CAN, len);
FL_CAN_WriteTXMessageWord1(CAN, data1);
FL_CAN_WriteTXMessageWord2(CAN, data2);
FL_CAN_EnableIT_TXOK(CAN);
}
}
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : CANx CAN通道号 TxMessage CAN消息指针
|Output parameters :
|Return value :
|Description : CAN数据
----------------------------------------------------------------------------*/
uint8_t CAN_WriteData(u8 mailbox_id,CanTxMsg *TxMessage)
{
uint32_t id = 0;
uint32_t len = 0;
uint32_t data1 = 0;
uint32_t data2 = 0;
if (TxMessage->IDE)
{
/* 扩展 */
if (TxMessage->RTR)
{
/* 远程帧 */
id = ((TxMessage->ID & 0x3ffff) << 13) | ((uint32_t)1 << 12) | ((uint32_t)1 << 31) | ((TxMessage->ID & 0x1ffc0000) >> 18);
}
else
{
/* 数据帧 */
id = ((TxMessage->ID & 0x3ffff) << 13) | ((uint32_t)1 << 12) | ((uint32_t)1 << 11) | ((TxMessage->ID & 0x1ffc0000) >> 18);
}
}
else
{
/* 标准 */
if (TxMessage->RTR)
{
/* 远程帧 */
id = (TxMessage->ID & 0x7ff) | (1 << 11);
}
else
{
/* 数据帧 */
id = TxMessage->ID & 0x7ff;
}
}
len = TxMessage->DLC;
data1 = (((uint32_t)TxMessage->Data[3] << 24) |
((uint32_t)TxMessage->Data[2] << 16) |
((uint32_t)TxMessage->Data[1] << 8) |
((uint32_t)TxMessage->Data[0]));
data2 = (((uint32_t)TxMessage->Data[7] << 24) |
((uint32_t)TxMessage->Data[6] << 16) |
((uint32_t)TxMessage->Data[5] << 8) |
((uint32_t)TxMessage->Data[4]));
FL_CAN_FIFO_Write(mailbox_id,id, len, data1, data2);
return 0;
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
static void can_tx_task(void)
{
//考虙這里加隊列發送;
#ifdef CAN_DRIVE_QUEUE_ENABLE
//u8 l_buf_index;
can_queue_elem_s l_rx;
can_queue_elem_s l_tx;
//CAN_Type *p_can;
//u8 i;
/*PCLINT_ERROS*/ /*lint --e(928) */ /* 928 11.4(建議): 不應在某類型對像指針和其他不同類型對像指針之間進行強制轉換。*/
if( queue_get_head(&can_tx_queue,(sequential_queue_elem*)&l_tx) == QUEUE_OK)
{
/*PCLINT_ERROS*/ /*lint --e(926) */ /* */
/*PCLINT_ERROS*/ /*lint --e(641) --e(960) --e(923) */
queue_del_element(&can_tx_queue,(sequential_queue_elem*)&l_tx);
if(l_tx.phy_id == INST_CANCOM0)
{
//p_can = CAN0;
//common_memory_copys((u8*)&g_can[INST_CANCOM0].tx,(u8*)&l_tx.msg,sizeof(CAN_MsgInfoType)); //
//common_memory_copys((u8*)&g_can[INST_CANCOM0].tx_buf[0],(u8*)&l_tx.buf[0],CAN_FRAME_MAX_DLC);
//g_can[INST_CANCOM0].tx.DATA = &g_can[INST_CANCOM0].tx_buf[0];
//把dlc转换成寄存器能识别的长度
//g_can[INST_CANCOM0].tx.DLC = can_sw_len_to_dlc(g_can[INST_CANCOM0].tx.DLC);
CAN_WriteData(l_tx.mailbox_id,&l_tx.msg);//发送数据
}
}
/*PCLINT_ERROS*/ /*lint --e(928) */ /* 928 11.4(建議): 不應在某類型對像指針和其他不同類型對像指針之間進行強制轉換。*/
if( queue_get_head(&can_rx_queue,(sequential_queue_elem*)&l_rx) == QUEUE_OK)
{
/*PCLINT_ERROS*/ /*lint --e(926) */ /* */
/*PCLINT_ERROS*/ /*lint --e(641) --e(960) --e(923) */
queue_del_element(&can_rx_queue,(sequential_queue_elem*)&l_rx);
//
#ifdef CAN_LOGIC_DEBUG
g_can[CAN_ID_0].test[9]++;
#endif
}
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can_op_tx_task(void)
{
#if 1
static u8 g_cc=0;
#ifdef CAN_DRIVE_QUEUE_ENABLE
can_queue_elem_s l_tx;
u8 i;
g_can[CAN_ID_0].count++;
l_tx.phy_id = INST_CANCOM0;
//l_tx.mailbox_id = g_can_id_0_cfg_tx_table[0].mb_fifo_id;
l_tx.msg.ID = 0x228; //
l_tx.msg.IDE = CAN_MSG_ID_STD; //
l_tx.msg.DLC = CAN_FRAME_DLC;
#ifdef CAN_ID_0_FD_EN
l_tx.msg.FDF = CAN_MSG_TYPE_FD;
l_tx.msg.BRS = CAN_MSG_BRS_FAST;
#else
l_tx.msg.FDF = CAN_MSG_TYPE_NORMAL;
l_tx.msg.BRS = CAN_MSG_BRS_NORMAL_LOW;
#endif
l_tx.msg.RTR = CAN_MSG_RTR_DATA;
//l_tx.msg_id = g_can_id_0_cfg_tx_table[0].can_id;
g_cc++;
for(i=0;i<CAN_FRAME_DLC;i++)
{
l_tx.buf[i] = 0x11u+i+g_cc;
}
common_memory_copys((u8*)&l_tx.msg.Data[0],(u8*)&l_tx.buf[0],CAN_FRAME_MAX_DLC); //
//if(g_can[CAN_ID_0].count & 0x01)
{
(void)queue_add_element(&can_tx_queue,(const sequential_queue_elem*)&l_tx);//NOLINT
}
l_tx.phy_id = INST_CANCOM0;
//l_tx.mailbox_id = g_can_id_0_cfg_tx_table[0].mb_fifo_id;
l_tx.msg.ID = 0x7654229; //
l_tx.msg.IDE = CAN_MSG_ID_EXT; //
l_tx.msg.DLC = CAN_FRAME_DLC;
#ifdef CAN_ID_0_FD_EN
l_tx.msg.FDF = CAN_MSG_TYPE_FD;
l_tx.msg.BRS = CAN_MSG_BRS_FAST;
#else
l_tx.msg.FDF = CAN_MSG_TYPE_NORMAL;
l_tx.msg.BRS = CAN_MSG_BRS_NORMAL_LOW;
#endif
l_tx.msg.RTR = CAN_MSG_RTR_DATA;
//l_tx.msg_id = g_can_id_0_cfg_tx_table[0].can_id;
for(i=0;i<CAN_FRAME_DLC;i++)
{
l_tx.buf[i] = 0x22u+i+g_cc;
}
common_memory_copys((u8*)&l_tx.msg.Data[0],(u8*)&l_tx.buf[0],CAN_FRAME_MAX_DLC); //
//if(g_can[CAN_ID_0].count & 0x01)
{
(void)queue_add_element(&can_tx_queue,(const sequential_queue_elem*)&l_tx);//NOLINT
}
#else
#endif
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void can_tx_start(const can_queue_elem_s *p_tx)
{
u8 i;
can_queue_elem_s l_tx;
//CAN_Type* p_can;
/*
l_tx.phy_id = INST_CANCOM0;
//l_tx.mailbox_id = g_can_id_0_cfg_tx_table[0].mb_fifo_id;
l_tx.msg.ID = 0x228; //
l_tx.msg.IDE = CAN_MSG_ID_EXT; //
l_tx.msg.DLC = CAN_FRAME_DLC;
#ifdef CAN_ID_0_FD_EN
l_tx.msg.FDF = CAN_MSG_TYPE_FD;
l_tx.msg.BRS = CAN_MSG_BRS_FAST;
#else
l_tx.msg.FDF = CAN_MSG_TYPE_NORMAL;
l_tx.msg.BRS = CAN_MSG_BRS_NORMAL_LOW;
#endif
l_tx.msg.RTR = CAN_MSG_RTR_DATA;
//l_tx.msg_id = g_can_id_0_cfg_tx_table[0].can_id;
l_tx.msg.DATA = &l_tx.buf[0];
g_cc++;
for(i=0;i<CAN_FRAME_DLC;i++)
{
l_tx.buf[i] = 0x11u+i+g_cc;
}
*/
//p_can = CAN0;
if(p_tx->type == CAN_MSG_ID_STD)
{
l_tx.msg.IDE = CAN_ID_STD; //
}
else
{
l_tx.msg.IDE = CAN_ID_EXT; //
}
//p_tx->phy_id
//mailbox_id
l_tx.msg.ID = p_tx->msg_id;
l_tx.msg.DLC = p_tx->len;
#ifdef CAN_ID_0_FD_EN
#if 0
if(p_tx->fd_enable == 0u)
{
l_tx.msg.FDF = CAN_MSG_TYPE_NORMAL; //
l_tx.msg.BRS = CAN_MSG_BRS_NORMAL_LOW;
}
else
{
l_tx.msg.FDF = CAN_MSG_TYPE_FD; //
l_tx.msg.BRS = CAN_MSG_BRS_FAST;
}
#else
l_tx.msg.FDF = p_tx->fd_enable; //
l_tx.msg.BRS = p_tx->enable_brs;
#endif
#else
l_tx.msg.FDF = CAN_MSG_TYPE_NORMAL; //
l_tx.msg.BRS = CAN_MSG_BRS_NORMAL_LOW;
#endif
l_tx.msg.RTR = CAN_MSG_RTR_DATA;
l_tx.msg.ESI = 1u;
l_tx.msg.RTS = 1u;
l_tx.mailbox_id = p_tx->mailbox_id;
#if 1
//l_tx.msg.DATA = &l_tx.buf[0];
for(i=0;i<CAN_FRAME_DLC;i++)
{
l_tx.buf[i] = p_tx->buf[i];
l_tx.msg.Data[i] = p_tx->buf[i];
}
#endif
#if 0
common_memory_copys((u8*)&g_can[INST_CANCOM0].tx,(u8*)&l_tx.msg,sizeof(CAN_MsgInfoType)); //
common_memory_copys((u8*)&g_can[INST_CANCOM0].tx_buf[0],(u8*)&p_tx->buf[0],CAN_FRAME_MAX_DLC);
g_can[INST_CANCOM0].tx.DATA = &g_can[INST_CANCOM0].tx_buf[0];
//把dlc转换成寄存器能识别的长度
g_can[INST_CANCOM0].tx.DLC = can_sw_len_to_dlc(g_can[INST_CANCOM0].tx.DLC);
#if 1
if(l_tx.mailbox_id==2)
{
CAN_TransmitMessage(p_can, &g_can[INST_CANCOM0].tx, CAN_TRANSMIT_PRIMARY);//发送数据
}
else
{
CAN_TransmitMessage(p_can, &g_can[INST_CANCOM0].tx, CAN_TRANSMIT_SECONDARY);//发送数据
}
#else
CAN_TransmitMessage(p_can, &g_can[INST_CANCOM0].tx, CAN_TRANSMIT_SECONDARY);//发送数据
#endif
#else
CAN_WriteData(l_tx.mailbox_id,&l_tx.msg);//发送数据
#endif
}