2025-04-26 16:03:23 +08:00

1063 lines
28 KiB
C
Raw Permalink 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.

/** ##########################################################################
** 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
}