#include <stdint.h>
#include "gpio.h"
#include "isr.h"
#include "rte_can.h"
CANMSG_Type* CANMSG;
CanTxRxMsg CAN_RecvMsg;
can_rx_callback can_rx_handler = NULL;
/**
* @brief CAN就收完成回调
*
* @param msg
*/
static void can_recv_handler(void *msg)
{
INTC_ClearPendingIRQ(CAN0REC_IRQn);
if (CAN_GetFlagStatus(CAN0, CAN_FLAG_REC) != RESET)
{
CAN_ClearFlag(CAN0, CAN_FLAG_REC);
CANMSG = CAN_Get_CANxMSGy(CAN0);
CAN_Receive_IT(CAN0, CANMSG, &CAN_RecvMsg);
if (can_rx_handler != NULL)
{
can_rx_handler(&CAN_RecvMsg);
}
}
}
/**
* @brief CAN初始�?
*
* @param config CAN初始结构体指�?
* @return uint8_t 0成功 1失败
*/
uint8_t rte_can_init(can_config_st_t *config)
{
GPIO_InitTypeDef GPIO_InitStruct;
CAN_InitTypeDef CAN_InitStruct;
/* GPIO AF set for CAN bus */
GPIO_PinAFConfig(GPIO_PORT5, GPIO_Pin_1, GPIO_P51, GROUP_AF_CTXD);
GPIO_PinAFConfig(GPIO_PORT5, GPIO_Pin_0, GPIO_P50, GROUP_AF_CRXD);
/****** GPIO for CAN bus init ******/
/* CTXD pin init */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Level = GPIO_Level_HIGH;
GPIO_InitStruct.GPIO_Ctrl = GPIO_Control_DIG;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIO_PORT5, &GPIO_InitStruct);
/* CRXD pin init */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Ctrl = GPIO_Control_DIG;
GPIO_Init(GPIO_PORT5, &GPIO_InitStruct);
/****** GPIO for STB init ******/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Ctrl = GPIO_Control_DIG;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Level = GPIO_Level_LOW;
GPIO_Init(GPIO_PORT5, &GPIO_InitStruct);
/****** CAN bus periphal init ******/
CAN_InitStruct.CAN_Prescaler = config->freq;
CAN_InitStruct.CAN_BitRatePrescaler = 2;
CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
CAN_InitStruct.CAN_BS1 = CAN_BS1_12tq;
CAN_InitStruct.CAN_BS2 = CAN_BS2_3tq;
CAN_InitStruct.CAN_OperateMode = CAN_OpMode_Initial;
CAN_InitStruct.MASK1 = config->MASK[0]; // 0x001fffffU;//进行滤波屏蔽
CAN_InitStruct.MASK2 = config->MASK[1];
CAN_InitStruct.MASK3 = config->MASK[2];
CAN_InitStruct.MASK4 = config->MASK[3];
CAN_Init(CAN0, &CAN_InitStruct);
can_rx_handler = config->rx_callback;
CAN_OperatingModeRequest(CAN0, CAN_OpMode_Normal);
CAN_ITConfig(CAN0, CAN_IT_REC, ENABLE);
ISR_Register(CAN0REC_IRQn, can_recv_handler);
INTC_EnableIRQ(CAN0REC_IRQn);
// ISR_DisRegister(CAN0REC_IRQn, can_recv_handler);
return 0;
}
/**
* @brief can反初始化
* @param CANx CAN0 �? CAN1
*
* @return uint8_t 0成功 1失败
*/
uint8_t rte_can_deinit(CAN_CH ch)
{
CAN_Type* CANx;
if (ch == CAN_CH_0)
{
CANx = CAN0;
can_rx_handler = NULL;
}
else
{
return 1;
}
CAN_DeInit(CANx);
return 0;
}
/**
* @brief 获取CAN是否BusOff
* @param CANx CAN0 �? CAN1
*
* @return uint8_t 0 没有busoff
* 1 错误的操�? 2 busoff
*/
uint8_t get_can_busoff(CAN_CH ch)
{
CAN_Type* CANx;
if (ch == CAN_CH_0)
{
CANx = CAN0;
}
else
{
return 1;
}
if(CAN_ErrorStat_BusOff == CAN_GetErrorStatus(CANx))
{
return 2;
}
return 0;
}
/**
* @brief 从busoff状态恢�?
*
* @param CANx CAN0 �? CAN1
* @return uint8_t 0成功 1失败
*/
uint8_t reset_busoff(CAN_CH ch)
{
uint16_t data;
CAN_Type* CANx;
if (ch == CAN_CH_0)
{
CANx = CAN0;
}
else
{
return 1;
}
data = CANx->CCTRL;
data &= 0xf8f8;
data |= 0x0007;
CANx->CCTRL = data;
data = CANMSG->CMCTRL;
data &= 0xfCfC;
data |= 0x0002;
CANMSG->CMCTRL = data;
data = CANx->CCTRL;
data &= 0xf8f8;
data |= 0x0100;
CANx->CCTRL = data;
return 0;
}
/* 下面是一些例�? 自己�?
CAN_SendMsg.Id = 0x00aa0432;
CAN_SendMsg.IDE = CAN_Id_Extended;
CAN_SendMsg.CacheType = CAN_CacheType_Tx;
CAN_SendMsg.RTR = CAN_RTR_Data;
CAN_RecvMsg.Interrupt = DISABLE;
CAN_SendMsg.DLC = 8;
CAN_SendMsg.Data[7] = 0x9F;
CAN_MessageCache_DeInit(CAN0MSG01);
CAN_MessageCache_Init(CAN0MSG01, &CAN_SendMsg);
CAN2_RecvMsg.Id = 0x00bb0432;
CAN2_RecvMsg.IDE = CAN_Id_Extended;
CAN2_RecvMsg.CacheType = CAN_CacheType_Rx_3Mask;
CAN2_RecvMsg.RTR = CAN_RTR_Data;
CAN2_RecvMsg.Interrupt = ENABLE;
CAN_MessageCache_DeInit(CAN0MSG08);
CAN_MessageCache_Init(CAN0MSG08, &CAN2_RecvMsg);
CAN_MessageCache_OverWriteConfig(CAN0MSG08, ENABLE);
CAN_RecvMsg.Id = 0x231;
CAN_RecvMsg.IDE = CAN_Id_Standard;
CAN_RecvMsg.CacheType = CAN_CacheType_Rx_1Mask;
CAN_RecvMsg.RTR = CAN_RTR_Data;
CAN_RecvMsg.Interrupt = ENABLE;
CAN_MessageCache_DeInit(CAN0MSG07);
CAN_MessageCache_Init(CAN0MSG07, &CAN_RecvMsg);
CAN_MessageCache_OverWriteConfig(CAN0MSG07, ENABLE);
CAN1_RecvMsg.Id = 0x032;
CAN1_RecvMsg.IDE = CAN_Id_Standard;
CAN1_RecvMsg.CacheType = CAN_CacheType_Rx_1Mask;
CAN1_RecvMsg.RTR = CAN_RTR_Data;
CAN1_RecvMsg.Interrupt = ENABLE;
CAN_MessageCache_DeInit(CAN0MSG06);
CAN_MessageCache_Init(CAN0MSG06, &CAN1_RecvMsg);
CAN_MessageCache_OverWriteConfig(CAN0MSG06, ENABLE);
CAN_Type* CANx = CAN0;
uint16_t data;
while(1)
{
CAN_SendMsg.Data[0] += 3;
CAN_Transmit(CAN0MSG01, &CAN_SendMsg);
m0_delay_us(100);
if(Read_RingBuff(&Can_Msg))
{
// printf("id=%x ,%x-%x-%x-%x-%x-%x-%x \r\n",Can_Msg.Id,Can_Msg.Data[0],Can_Msg.Data[1],Can_Msg.Data[2],Can_Msg.Data[3],Can_Msg.Data[4],\
// Can_Msg.Data[5],Can_Msg.Data[6]);
printf("count =%d,id=%x \r\n",count++,Can_Msg.Id);
}
if(CAN_ErrorStat_BusOff == CAN_GetErrorStatus(CAN0))
{
data = CANx->CCTRL;
data &= 0xf8f8;
data |= 0x0007;
CANx->CCTRL = data;
data = CANMSG->CMCTRL;
data &= 0xfCfC;
data |= 0x0002;
CANMSG->CMCTRL = data;
data = CANx->CCTRL;
data &= 0xf8f8;
data |= 0x0100;
CANx->CCTRL = data;
}
}
*/