You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
845 lines
19 KiB
845 lines
19 KiB
#include "stm32f10x_can.h"
|
|
#include "common.h"
|
|
#include "kernel.h"
|
|
#include "CanApp.h"
|
|
|
|
|
|
int h_can1 = -1;
|
|
|
|
KERNEL_DEVICE_INIT("dev_can1")
|
|
|
|
extern void user_process_can1_send_interface(INT32U msg_id);
|
|
extern void user_process_can1_error_interface(void);
|
|
|
|
#define USER_CAN_MODE CAN_Mode_Normal;
|
|
#define BUSY 0x55
|
|
#define IDLE 0x00
|
|
#define CAN_MAIL_BUFF_SIZE 64
|
|
|
|
// 定义为扩展帧类型
|
|
#define CAN_FRAME_TYPE CAN_FRAME_EXT
|
|
#define CAN_FRAME_STD 0
|
|
#define CAN_FRAME_EXT 1
|
|
|
|
KERNEL_TYPE unsigned char CanEvent = 0;
|
|
|
|
//每封CAN邮件基本格式
|
|
typedef struct
|
|
{
|
|
unsigned int MailID; // 扩展帧使??9位ID
|
|
unsigned short int MailLenth;
|
|
unsigned char MailBuffer[8];
|
|
} CANMAILMESSAGE;
|
|
|
|
//定义每个存储的循环缓冲大??
|
|
typedef struct
|
|
{
|
|
unsigned int Head;
|
|
unsigned int Tail;
|
|
CANMAILMESSAGE MailBuffer[CAN_MAIL_BUFF_SIZE];
|
|
} CAN_FIFO;
|
|
|
|
KERNEL_TYPE CAN_FIFO can_rx;
|
|
KERNEL_TYPE CAN_FIFO can_tx;
|
|
|
|
KERNEL_TYPE void CAN_RCC_Configuration(void)
|
|
{
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
|
}
|
|
|
|
KERNEL_TYPE void CAN_GPIO_Configuration(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
// 如需重映射CAN引脚可启??
|
|
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
|
|
// CAN_RX - PA11
|
|
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
|
|
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
|
GPIO_Init(GPIOB, &GPIO_InitStruct);
|
|
// CAN_TX - PA12
|
|
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //TX
|
|
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
GPIO_Init(GPIOB, &GPIO_InitStruct);
|
|
}
|
|
|
|
KERNEL_TYPE void CAN_NVIC_Configuration(void)
|
|
{
|
|
NVIC_InitTypeDef NVIC_InitStructure;
|
|
// 接收中断
|
|
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
NVIC_Init(&NVIC_InitStructure);
|
|
// 发送中??
|
|
NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
NVIC_Init(&NVIC_InitStructure);
|
|
// 错误中断 - 最高优先级
|
|
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
|
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
NVIC_Init(&NVIC_InitStructure);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
unsigned short int BPS;
|
|
unsigned char SJW;
|
|
unsigned char BS1;
|
|
unsigned char BS2;
|
|
unsigned short int Prescaler;
|
|
} CAN_BAUD_Struct_t;
|
|
|
|
KERNEL_TYPE CAN_BAUD_Struct_t CAN_BaudTab[] =
|
|
{ //采样点:%81.25
|
|
/*0*/ {125, CAN_SJW_1tq, CAN_BS1_14tq, CAN_BS2_3tq, 16},
|
|
/*1*/ {250, CAN_SJW_1tq, CAN_BS1_14tq, CAN_BS2_3tq, 8},
|
|
// /*2*/ {500, CAN_SJW_2tq, CAN_BS1_13tq, CAN_BS2_4tq, 4}, //SysClock 72MHz
|
|
/*2*/ {500, CAN_SJW_2tq, CAN_BS1_14tq, CAN_BS2_3tq, 6}, //SysClock 108MHz
|
|
/*3*/ {1000, CAN_SJW_1tq, CAN_BS1_14tq, CAN_BS2_3tq, 2}
|
|
};
|
|
|
|
KERNEL_TYPE int CAN_Configuration(void)
|
|
{
|
|
unsigned char can_baud_index;
|
|
|
|
CAN_InitTypeDef CAN_InitStructure;
|
|
|
|
CAN_StructInit(&CAN_InitStructure);
|
|
|
|
//关闭时间触发模式
|
|
CAN_InitStructure.CAN_TTCM = DISABLE;
|
|
//关闭自动离线管理
|
|
CAN_InitStructure.CAN_ABOM = DISABLE;
|
|
//关闭自动唤醒模式
|
|
CAN_InitStructure.CAN_AWUM = DISABLE;
|
|
//禁止报文自动重传
|
|
CAN_InitStructure.CAN_NART = ENABLE; //只发送一??
|
|
//FIFO 溢出时报文覆盖源文件
|
|
CAN_InitStructure.CAN_RFLM = DISABLE;
|
|
//报文发送优先级取决于请求顺??
|
|
CAN_InitStructure.CAN_TXFP = ENABLE;
|
|
//正常的工作模??
|
|
CAN_InitStructure.CAN_Mode = USER_CAN_MODE;
|
|
|
|
can_baud_index = 2;// 使用500kbps波特??
|
|
CAN_InitStructure.CAN_SJW = CAN_BaudTab[can_baud_index].SJW;
|
|
CAN_InitStructure.CAN_BS1 = CAN_BaudTab[can_baud_index].BS1;
|
|
CAN_InitStructure.CAN_BS2 = CAN_BaudTab[can_baud_index].BS2;
|
|
CAN_InitStructure.CAN_Prescaler = CAN_BaudTab[can_baud_index].Prescaler;
|
|
|
|
//初始化CAN
|
|
CAN_Init(CAN1, &CAN_InitStructure);
|
|
|
|
//使能接收中断
|
|
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
|
|
|
//发送中??
|
|
CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE); //邮箱空中断使??
|
|
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_EPV);
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_BOF);
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_LEC);
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_EWG);
|
|
|
|
//CAN_ITConfig(CAN1, CAN_IT_ERR | CAN_IT_LEC | CAN_IT_BOF | CAN_IT_EPV, ENABLE);
|
|
|
|
CAN_ITConfig(CAN1, CAN_IT_ERR | CAN_IT_BOF , ENABLE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define CAN_LIST_SZIE 32
|
|
|
|
unsigned int CAN_FilterList[CAN_LIST_SZIE];
|
|
unsigned int CAN_FilterList_Mask[CAN_LIST_SZIE];
|
|
|
|
KERNEL_TYPE int CAN_FilterCount = 0;
|
|
KERNEL_TYPE int CAN_FilterMaskCount = 0;
|
|
|
|
KERNEL_TYPE int CAN_FilterAdd(int filterID) //添加后不生效
|
|
{
|
|
// 扩展帧ID范围检??
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
if (filterID < 0 || filterID > 0x7FF)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#else
|
|
if (filterID < 0 || filterID > 0x1FFFFFFF)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#endif
|
|
|
|
if (CAN_FilterCount >= CAN_LIST_SZIE)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
CAN_FilterList[CAN_FilterCount++] = filterID;
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
KERNEL_TYPE int CAN_FilterMaskAdd(int filterMask) //添加后不生效
|
|
{
|
|
// 扩展帧掩码范围检??
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
if (filterMask < 0 || filterMask > 0x7FF)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#else
|
|
if (filterMask < 0 || filterMask > 0x1FFFFFFF)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#endif
|
|
|
|
if (CAN_FilterMaskCount >= CAN_LIST_SZIE)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
CAN_FilterList_Mask[CAN_FilterMaskCount++] = filterMask;
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
KERNEL_TYPE int CAN_FilterEnable(void)
|
|
{
|
|
CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
|
int FilterNumber = 0;
|
|
int num = 0;
|
|
int index = 0;
|
|
int mask_index = 0;
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
|
|
FilterNumber = CAN_FilterCount / 4;
|
|
|
|
//屏蔽模式
|
|
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;
|
|
//16位寄存器
|
|
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
|
|
//过滤??0 关联??FIFO0
|
|
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
//使能过滤??
|
|
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
|
for (num = 0; num < FilterNumber; num++)
|
|
{
|
|
CAN_FilterInitStructure.CAN_FilterNumber = num;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterList[index++] << 5;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = CAN_FilterList[index++] << 5;
|
|
//屏蔽位高16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = CAN_FilterList[index++] << 5;
|
|
//屏蔽位低16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = CAN_FilterList[index++] << 5;
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
}
|
|
|
|
if (CAN_FilterCount % 4)
|
|
{
|
|
CAN_FilterInitStructure.CAN_FilterNumber = num;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterList[index] << 5;
|
|
//??6??
|
|
if (index < CAN_FilterCount)
|
|
{
|
|
index++;
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = CAN_FilterList[index] << 5;
|
|
}
|
|
|
|
//屏蔽位高16??
|
|
if (index < CAN_FilterCount)
|
|
{
|
|
index++;
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = CAN_FilterList[index] << 5;
|
|
}
|
|
|
|
//屏蔽位低16??
|
|
if (index < CAN_FilterCount)
|
|
{
|
|
index++;
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = CAN_FilterList[index] << 5;
|
|
}
|
|
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
}
|
|
|
|
#else
|
|
|
|
//屏蔽模式
|
|
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
//32位寄存器- 扩展帧必须使??2位模??
|
|
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
//过滤??0 关联??FIFO0
|
|
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
//使能过滤??
|
|
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
|
if(CAN_FilterInitStructure.CAN_FilterMode == CAN_FilterMode_IdList)
|
|
{
|
|
FilterNumber = CAN_FilterCount / 2;
|
|
|
|
for (num = 0; num < FilterNumber; num++)
|
|
{
|
|
CAN_FilterInitStructure.CAN_FilterNumber = num;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterList[index] >> 13;
|
|
//??6位,包含IDE??0x0004表示扩展??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_FilterList[index++] << 3) | 0x0004;
|
|
//屏蔽位高16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = CAN_FilterList[index] >> 13;
|
|
//屏蔽位低16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = (CAN_FilterList[index++] << 3) | 0x0004;
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
}
|
|
|
|
if (CAN_FilterCount % 2)
|
|
{
|
|
CAN_FilterInitStructure.CAN_FilterNumber = num;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterList[index] >> 13;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_FilterList[index] << 3) | 0x0004;
|
|
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
}
|
|
}
|
|
|
|
if(CAN_FilterInitStructure.CAN_FilterMode == CAN_FilterMode_IdMask)
|
|
{
|
|
FilterNumber = CAN_FilterCount;
|
|
|
|
for (num = 0; num < FilterNumber; num++)
|
|
{
|
|
CAN_FilterInitStructure.CAN_FilterNumber = num;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = CAN_FilterList[index] >> 13;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_FilterList[index++] << 3) | 0x0004;
|
|
//屏蔽位高16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = CAN_FilterList_Mask[mask_index] >> 13;
|
|
//屏蔽位低16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = (CAN_FilterList_Mask[mask_index++] << 3) | 0x0004;
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
KERNEL_TYPE int CAN_FilterMaskEnable(void)
|
|
{
|
|
CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
//屏蔽模式
|
|
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
//32位寄存器
|
|
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
|
|
//屏蔽位高16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
|
|
//屏蔽位低16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
|
|
#else
|
|
//屏蔽模式
|
|
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
//32位寄存器
|
|
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
|
|
//??6??
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0004;
|
|
//屏蔽位高16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
|
|
//屏蔽位低16??
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0004;
|
|
#endif
|
|
//过滤??0 关联??FIFO0
|
|
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
//使能过滤??
|
|
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
|
CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
|
|
|
//初始化过滤器
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
#define CAN_TSR_TMEx_MASK (0x07 << 26)
|
|
#define CAN_TSR_TMEx_isEmpty (CAN1->TSR & CAN_TSR_TMEx_MASK) //空闲邮箱状??
|
|
#define CAN_FIFO_0_FMP0_MASK 0x03
|
|
#define CAN_FIFO_0_NUM (CAN1->RF0R & CAN_FIFO_0_FMP0_MASK) //FIFO 0 接收到的报文数目
|
|
|
|
CanTxMsg TxMessage;
|
|
//启动发??
|
|
KERNEL_TYPE void CAN_send_mail(void)
|
|
{
|
|
if (CAN_TSR_TMEx_isEmpty)
|
|
{
|
|
if (can_tx.Head != can_tx.Tail)
|
|
{
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
TxMessage.StdId = can_tx.MailBuffer[can_tx.Tail].MailID;
|
|
#else
|
|
TxMessage.ExtId = can_tx.MailBuffer[can_tx.Tail].MailID;
|
|
#endif
|
|
TxMessage.DLC = can_tx.MailBuffer[can_tx.Tail].MailLenth;
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
TxMessage.IDE = CAN_ID_STD;
|
|
#else
|
|
TxMessage.IDE = CAN_ID_EXT;
|
|
#endif
|
|
TxMessage.RTR = CAN_RTR_DATA;
|
|
memcpy(TxMessage.Data, can_tx.MailBuffer[can_tx.Tail].MailBuffer, TxMessage.DLC);
|
|
TASK_LOCK;
|
|
can_tx.Tail++;
|
|
if (can_tx.Tail >= CAN_MAIL_BUFF_SIZE) can_tx.Tail = 0;
|
|
TASK_UNLOCK;
|
|
CAN_Transmit(CAN1, &TxMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
KERNEL_TYPE void CAN_read_fifo(void)
|
|
{
|
|
CanRxMsg rx_message;
|
|
|
|
unsigned short int lTimer = 0;
|
|
lTimer = clock();
|
|
while (1) //等待缓冲区空出空??
|
|
{
|
|
if (((can_rx.Head + 1) == can_rx.Tail) || (can_rx.Tail == 0 && ((can_rx.Head + 1) == CAN_MAIL_BUFF_SIZE)))
|
|
{
|
|
if ((Get1MsTickInterval(lTimer)) >= 10) //10ms 等待超时
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
CAN_Receive(CAN1, CAN_FIFO0, &rx_message);
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
can_rx.MailBuffer[can_rx.Head].MailID = rx_message.StdId;
|
|
#else
|
|
can_rx.MailBuffer[can_rx.Head].MailID = rx_message.ExtId;
|
|
#endif
|
|
can_rx.MailBuffer[can_rx.Head].MailLenth = rx_message.DLC;
|
|
memcpy(can_rx.MailBuffer[can_rx.Head].MailBuffer, rx_message.Data, rx_message.DLC);
|
|
TASK_LOCK;
|
|
can_rx.Head++;
|
|
if (can_rx.Head >= CAN_MAIL_BUFF_SIZE) can_rx.Head = 0;
|
|
TASK_UNLOCK;
|
|
}
|
|
*/
|
|
////CAN邮箱数据接收中断
|
|
//void USB_LP_CAN1_RX0_IRQHandler(void)
|
|
//{
|
|
// //CAN接收
|
|
// CAN_read_fifo();
|
|
//}
|
|
|
|
extern u8 ReceiveOTA_flg;
|
|
//CAN邮箱存在空中??
|
|
void USB_HP_CAN1_TX_IRQHandler(void)
|
|
{
|
|
if (CAN1->TSR & (1 << 26))
|
|
{
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_RQCP0);
|
|
}
|
|
|
|
if (CAN1->TSR & (1 << 27))
|
|
{
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_RQCP1);
|
|
}
|
|
|
|
if (CAN1->TSR & (1 << 28))
|
|
{
|
|
CAN_ClearFlag(CAN1, CAN_FLAG_RQCP2);
|
|
}
|
|
|
|
if((UpgradeRequest)||(UserCanRxSignal.JumpToBOOT_flg==1))
|
|
{
|
|
UserCanRxSignal.JumpToBOOT_flg =1;
|
|
UpgradeRequest = 0;
|
|
NVIC_SystemReset();
|
|
}
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
//user_process_can1_send_interface(TxMessage.StdId);
|
|
#else
|
|
//user_process_can1_send_interface(TxMessage.ExtId);
|
|
#endif
|
|
|
|
CAN_send_mail();
|
|
|
|
if (CAN_TSR_TMEx_isEmpty == CAN_TSR_TMEx_MASK) //全为空才是闲
|
|
{
|
|
CanEvent = IDLE;
|
|
}
|
|
else if (CAN_TSR_TMEx_isEmpty == 0)
|
|
{
|
|
CanEvent = BUSY;
|
|
}
|
|
}
|
|
|
|
////CAN1 错误终端入口
|
|
//void CAN1_SCE_IRQHandler(void)
|
|
//{
|
|
// CAN_ClearFlag(CAN1, CAN_FLAG_EPV);
|
|
// CAN_ClearFlag(CAN1, CAN_FLAG_BOF);
|
|
// CAN_ClearFlag(CAN1, CAN_FLAG_LEC);
|
|
//
|
|
// //user_process_can1_error_interface();
|
|
//}
|
|
|
|
KERNEL_TYPE int WriteOneMessage(CanTxMsg *TxMessage)
|
|
{
|
|
unsigned short int lTimer = 0;
|
|
lTimer = clock();
|
|
while (1) //等待缓冲区空出空??
|
|
{
|
|
if (((can_tx.Head + 1) == can_tx.Tail) || (can_tx.Tail == 0 && ((can_tx.Head + 1) == CAN_MAIL_BUFF_SIZE)))
|
|
{
|
|
if ((Get1MsTickInterval(lTimer)) >= 10)
|
|
{
|
|
close(h_can1);
|
|
h_can1 = open("dev_can1", 0);
|
|
return K_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
memcpy(can_tx.MailBuffer[can_tx.Head].MailBuffer, TxMessage->Data, TxMessage->DLC);
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
can_tx.MailBuffer[can_tx.Head].MailID = TxMessage->StdId;
|
|
#else
|
|
can_tx.MailBuffer[can_tx.Head].MailID = TxMessage->ExtId;
|
|
#endif
|
|
can_tx.MailBuffer[can_tx.Head].MailLenth = TxMessage->DLC;
|
|
|
|
//关闭中断
|
|
TASK_LOCK;
|
|
can_tx.Head++;
|
|
if (can_tx.Head >= CAN_MAIL_BUFF_SIZE)
|
|
{
|
|
can_tx.Head = 0;
|
|
}
|
|
TASK_UNLOCK;
|
|
if (CanEvent == IDLE)
|
|
{
|
|
//启动发??
|
|
CanEvent = BUSY;
|
|
CAN_send_mail();
|
|
}
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
|
|
KERNEL_TYPE int GetNextMailID(void)
|
|
{
|
|
if (can_rx.Head == can_rx.Tail)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
return can_rx.MailBuffer[can_rx.Tail].MailID;
|
|
}
|
|
|
|
KERNEL_TYPE int GetOneMessage(CanRxMsg *message)
|
|
{
|
|
if (can_rx.Head == can_rx.Tail)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
message->StdId = can_rx.MailBuffer[can_rx.Tail].MailID;
|
|
#else
|
|
message->ExtId = can_rx.MailBuffer[can_rx.Tail].MailID;
|
|
#endif
|
|
|
|
message->DLC = can_rx.MailBuffer[can_rx.Tail].MailLenth & 0x0F;
|
|
|
|
//qiuadd
|
|
message->IDE = CAN_ID_EXT;
|
|
|
|
memcpy(message->Data, can_rx.MailBuffer[can_rx.Tail].MailBuffer, message->DLC);
|
|
|
|
TASK_LOCK;
|
|
can_rx.Tail++;
|
|
if (can_rx.Tail >= CAN_MAIL_BUFF_SIZE)
|
|
{
|
|
can_rx.Tail = 0;
|
|
}
|
|
TASK_UNLOCK;
|
|
|
|
if (message->DLC == 0)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
//
|
|
|
|
//设备接口实现
|
|
|
|
//
|
|
KERNEL_TYPE int device_ioctl(unsigned int cmd, unsigned long arg);
|
|
KERNEL_TYPE int device_open(int flags)
|
|
{
|
|
if (kernel_device_status == TRUE)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
CAN_DeInit(CAN1);
|
|
CAN_RCC_Configuration();
|
|
CAN_GPIO_Configuration();
|
|
CAN_NVIC_Configuration();
|
|
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x02);
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x03);
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x7DF);
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x200);
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x202);
|
|
// device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x20C);
|
|
//qiuadd
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x1840FF20);//变速器当前档位
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x1843FF20);//变速器总档??
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x1844FF20);//变速成功与否的报文
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x1845FF20);//变速器发送的故障报文
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_ADD, 0x1825FF20);//变速器心跳
|
|
|
|
device_ioctl(IOCTL_CMD_CAN_FILTER_INIT, 0);
|
|
|
|
// device_ioctl(IOCTL_CAN_SET_FILTER_ALL, 0);
|
|
|
|
CAN_Configuration();
|
|
|
|
can_tx.Head = 0;
|
|
can_tx.Tail = 0;
|
|
|
|
can_rx.Head = 0;
|
|
can_rx.Tail = 0;
|
|
CanEvent = IDLE;
|
|
|
|
kernel_device_status = TRUE;
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
//param 第三个参数作??CAN_ID
|
|
KERNEL_TYPE int device_write(unsigned char *buff, unsigned int len, void *param)
|
|
{
|
|
int i = 0, pack_count = 0, less = 0;
|
|
CanTxMsg TxMessage;
|
|
KERNEL_CHECK_OPEN;
|
|
|
|
if (param == NULL)
|
|
{
|
|
return K_FAIL; //ID参数传入??
|
|
}
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
TxMessage.StdId = *((int *)param);
|
|
|
|
if (TxMessage.StdId > 0x7FF)
|
|
{
|
|
return K_FAIL; //ID不合??
|
|
}
|
|
#else
|
|
TxMessage.ExtId = *((int *)param);
|
|
|
|
if (TxMessage.ExtId > 0x1FFFFFFF)
|
|
{
|
|
return K_FAIL; //ID不合??
|
|
}
|
|
#endif
|
|
|
|
pack_count = len / 8;
|
|
less = len % 8;
|
|
|
|
for (i = 0; i < pack_count; i++)
|
|
{
|
|
TxMessage.DLC = 8;
|
|
TxMessage.IDE = CAN_ID_EXT; // 设置为扩展帧
|
|
TxMessage.RTR = CAN_RTR_DATA;
|
|
|
|
memcpy(TxMessage.Data, &(buff[i * 8]), 8);
|
|
|
|
WriteOneMessage(&TxMessage);
|
|
}
|
|
|
|
if (less)
|
|
{
|
|
TxMessage.DLC = less;
|
|
TxMessage.IDE = CAN_ID_EXT; // 设置为扩展帧
|
|
TxMessage.RTR = CAN_RTR_DATA;
|
|
|
|
memcpy(TxMessage.Data, &(buff[i * 8]), less);
|
|
|
|
WriteOneMessage(&TxMessage);
|
|
}
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
|
|
KERNEL_TYPE int device_read(unsigned char *buff, unsigned int len, void *param)
|
|
{
|
|
CanRxMsg message;
|
|
int last_id = 0;
|
|
int next_id = 0;
|
|
int r_len = 0;
|
|
KERNEL_CHECK_OPEN;
|
|
|
|
if (param == NULL)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
|
|
if (GetOneMessage(&message) == K_FAIL)
|
|
{
|
|
return 0;
|
|
}
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
last_id = message.StdId;
|
|
#else
|
|
last_id = message.ExtId;
|
|
#endif
|
|
memcpy(buff, message.Data, message.DLC);
|
|
r_len += message.DLC;
|
|
*(int *)param = last_id;
|
|
|
|
while (r_len < len)
|
|
{
|
|
next_id = GetNextMailID();
|
|
if (next_id == K_FAIL)
|
|
{
|
|
return r_len;
|
|
}
|
|
if (next_id != last_id)
|
|
{
|
|
return r_len;
|
|
}
|
|
GetOneMessage(&message);
|
|
|
|
#if (CAN_FRAME_TYPE == CAN_FRAME_STD)
|
|
if (last_id != message.StdId)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#else
|
|
if (last_id != message.ExtId)
|
|
{
|
|
return K_FAIL;
|
|
}
|
|
#endif
|
|
memcpy(&buff[r_len], message.Data, message.DLC);
|
|
r_len += message.DLC;
|
|
}
|
|
|
|
return r_len;
|
|
}
|
|
|
|
KERNEL_TYPE int device_ioctl(unsigned int cmd, unsigned long arg)
|
|
{
|
|
int Status = K_SUCCESS;
|
|
|
|
switch (cmd)
|
|
{
|
|
case IOCTL_CMD_CAN_FILTER_ADD:
|
|
Status = CAN_FilterAdd(arg);
|
|
break;
|
|
|
|
case IOCTL_CMD_CAN_FILTER_MASK_ADD:
|
|
Status = CAN_FilterMaskAdd(arg);
|
|
break;
|
|
|
|
case IOCTL_CMD_CAN_FILTER_INIT:
|
|
CAN_FilterEnable();
|
|
break;
|
|
|
|
case IOCTL_CAN_SET_FILTER_ALL:
|
|
CAN_FilterMaskEnable();
|
|
break;
|
|
|
|
case IOCTL_CAN_GET_NEXTMAILID:
|
|
return GetNextMailID();
|
|
break;
|
|
|
|
default:
|
|
return K_FAIL;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
KERNEL_TYPE int device_clsoe(void)
|
|
{
|
|
KERNEL_CHECK_OPEN;
|
|
|
|
kernel_device_status = FALSE;
|
|
|
|
CAN_DeInit(CAN1);
|
|
can_tx.Head = 0;
|
|
can_tx.Tail = 0;
|
|
|
|
can_rx.Head = 0;
|
|
can_rx.Tail = 0;
|
|
CanEvent = 0;
|
|
|
|
return K_SUCCESS;
|
|
}
|
|
|
|
KERNEL_TYPE const file_operations ops = {
|
|
/*open*/ device_open,
|
|
/*write*/ device_write,
|
|
/*read*/ device_read,
|
|
/*ioctl*/ device_ioctl,
|
|
/*close*/ device_clsoe,
|
|
};
|
|
|
|
|
|
register_driver(ops)
|
|
|