|
|
@@ -0,0 +1,429 @@
|
|
|
+#include "common.h"
|
|
|
+#include "drv_can.h"
|
|
|
+
|
|
|
+//********************************************************CAN-START**********************************************************
|
|
|
+static uint8_t can_tx_buf[CAN_TX_BUF_MAX];
|
|
|
+static uint8_t can_rx_buf[CAN_RX_BUF_MAX];
|
|
|
+static uint16_t tx_count = 0,rx_count = 0,tx_buf_size = 0;
|
|
|
+
|
|
|
+static uint16_t can_filter_id_array[CAN_FILTER_ID_MAX];
|
|
|
+
|
|
|
+
|
|
|
+static void Reset_Can_Rx_Buffer(void)
|
|
|
+{
|
|
|
+ memset(can_rx_buf,0x00,sizeof(can_rx_buf));
|
|
|
+ rx_count = 0;
|
|
|
+}
|
|
|
+
|
|
|
+uint16_t Get_Data_Can(uint8_t * dbuf,uint16_t dbuf_len)
|
|
|
+{
|
|
|
+ if(dbuf == NULL || dbuf_len < rx_count)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy(dbuf,can_rx_buf,rx_count);
|
|
|
+ dbuf_len = rx_count;
|
|
|
+ Reset_Can_Rx_Buffer();
|
|
|
+
|
|
|
+ return dbuf_len;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+uint8_t Send_One_Frame_Can(uint8_t *data,uint8_t data_len)
|
|
|
+{
|
|
|
+ CanTxMsg TxMessage;
|
|
|
+
|
|
|
+ if(data == NULL || data_len == 0 || data_len > 8)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* Transmit */
|
|
|
+ TxMessage.StdId = SUR_ID;
|
|
|
+ TxMessage.ExtId = 0x00;
|
|
|
+ TxMessage.RTR = CAN_RTR_DATA;
|
|
|
+ TxMessage.IDE = CAN_ID_STD;
|
|
|
+ TxMessage.DLC = data_len;
|
|
|
+ memcpy(TxMessage.Data,data,data_len);
|
|
|
+
|
|
|
+ return CAN_Transmit(CAN1,&TxMessage);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+#define test_1
|
|
|
+int8_t Send_Data_Can(uint8_t *data,uint16_t size)
|
|
|
+{
|
|
|
+
|
|
|
+#ifdef test_1
|
|
|
+ if(data == NULL ||size == 0 || size > sizeof(can_tx_buf))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memset(can_tx_buf,0xFA,CAN_FRAME_START_LEN);
|
|
|
+ Send_One_Frame_Can(can_tx_buf,(uint8_t)CAN_FRAME_START_LEN);
|
|
|
+
|
|
|
+ memcpy(can_tx_buf,data,size);
|
|
|
+ tx_count = 0;
|
|
|
+ tx_buf_size = size;
|
|
|
+ CAN_ITConfig(CAN1, CAN_IT_TME,ENABLE);
|
|
|
+
|
|
|
+#else
|
|
|
+ if(data == NULL ||size == 0 || size + CAN_FRAME_START_LEN > sizeof(can_tx_buf))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memset(can_tx_buf,0xFA,CAN_FRAME_START_LEN);
|
|
|
+ memcpy(&can_tx_buf[CAN_FRAME_START_LEN],data,size);
|
|
|
+ tx_count = 0;
|
|
|
+ tx_buf_size = size + CAN_FRAME_START_LEN;
|
|
|
+ CAN_ITConfig(CAN1, CAN_IT_TME,ENABLE);
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return 1;
|
|
|
+
|
|
|
+}
|
|
|
+static void Can_NVIC_Config(void)
|
|
|
+{
|
|
|
+ NVIC_InitTypeDef NVIC_InitStructure;
|
|
|
+
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
|
|
+
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init(&NVIC_InitStructure);
|
|
|
+
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
|
|
|
+
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
|
|
|
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
|
+ NVIC_Init(&NVIC_InitStructure);
|
|
|
+}
|
|
|
+
|
|
|
+static int8_t CAN_Set_Filter(uint16_t f_id)
|
|
|
+{
|
|
|
+ uint8_t f_index;
|
|
|
+ CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
+
|
|
|
+ if(f_id == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ for(f_index = 0; f_index < CAN_FILTER_ID_MAX;f_index++)
|
|
|
+ {
|
|
|
+ if(can_filter_id_array[f_index] == 0)
|
|
|
+ {
|
|
|
+ can_filter_id_array[f_index] = f_id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(f_index >= CAN_FILTER_ID_MAX)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /* CAN filter init */
|
|
|
+ CAN_FilterInitStructure.CAN_FilterNumber = f_index;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdHigh = (can_filter_id_array[f_index]<<5);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;//0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
+ CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void CAN_GPIO_Initial(void)
|
|
|
+{
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
|
|
+
|
|
|
+ /* Configure CAN pin: RX */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ /* Configure CAN pin: TX */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
+ // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
|
|
|
+
|
|
|
+ //cs
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+ Silent_Enable(0);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void CAN_Initial(void)
|
|
|
+{
|
|
|
+ CAN_InitTypeDef CAN_InitStructure;
|
|
|
+
|
|
|
+ /* GPIO clock enable */
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
|
|
+
|
|
|
+ /* CANx Periph clock enable */
|
|
|
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
|
|
+
|
|
|
+
|
|
|
+ /* CAN register init */
|
|
|
+ CAN_DeInit(CAN1);
|
|
|
+ CAN_StructInit(&CAN_InitStructure);
|
|
|
+
|
|
|
+ /* CAN cell init */
|
|
|
+ CAN_InitStructure.CAN_TTCM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_ABOM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_AWUM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_NART = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_RFLM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_TXFP = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
|
|
+
|
|
|
+ /* CAN Baudrate = 1MBps*/
|
|
|
+ CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
|
|
|
+ CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
|
|
|
+ CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
|
|
+ CAN_InitStructure.CAN_Prescaler = 4;
|
|
|
+ CAN_Init(CAN1, &CAN_InitStructure);
|
|
|
+
|
|
|
+}
|
|
|
+/**
|
|
|
+ * @brief Configures the CAN.
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+void CAN_Config(void)
|
|
|
+{
|
|
|
+ //nt8_t f_index = 0;
|
|
|
+ //nt16_t f_id = 2;
|
|
|
+ #if 1
|
|
|
+ GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
+
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
|
|
+
|
|
|
+ /* Configure CAN pin: RX */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ /* Configure CAN pin: TX */
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
+ // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+
|
|
|
+ GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
|
|
|
+
|
|
|
+ //cs
|
|
|
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
|
|
|
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
|
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
+ Silent_Enable(0);
|
|
|
+#else
|
|
|
+ //CAN_GPIO_Initial();
|
|
|
+#endif
|
|
|
+ //CAN_Initial();
|
|
|
+
|
|
|
+ CAN_InitTypeDef CAN_InitStructure;
|
|
|
+
|
|
|
+ /* GPIO clock enable */
|
|
|
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
|
|
+
|
|
|
+ /* CANx Periph clock enable */
|
|
|
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
|
|
+
|
|
|
+
|
|
|
+ /* CAN register init */
|
|
|
+ CAN_DeInit(CAN1);
|
|
|
+ CAN_StructInit(&CAN_InitStructure);
|
|
|
+
|
|
|
+ /* CAN cell init */
|
|
|
+ CAN_InitStructure.CAN_TTCM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_ABOM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_AWUM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_NART = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_RFLM = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_TXFP = DISABLE;
|
|
|
+ CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
|
|
+
|
|
|
+ /* CAN Baudrate = 1MBps*/
|
|
|
+ CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
|
|
|
+ CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
|
|
|
+ CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
|
|
+ CAN_InitStructure.CAN_Prescaler = 4;
|
|
|
+ CAN_Init(CAN1, &CAN_InitStructure);
|
|
|
+#if 0
|
|
|
+ //memset(can_filter_id_array,0x00,sizeof(can_filter_id_array));
|
|
|
+ //CAN_Set_Filter(2);
|
|
|
+ //uint8_t f_index = 0;
|
|
|
+ //uint16_t f_id = 2;
|
|
|
+ CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
+
|
|
|
+ /*if(f_id == 0)
|
|
|
+ return ;
|
|
|
+
|
|
|
+ for(f_index = 0; f_index < CAN_FILTER_ID_MAX;f_index++)
|
|
|
+ {
|
|
|
+ if(can_filter_id_array[f_index] == 0)
|
|
|
+ {
|
|
|
+ can_filter_id_array[f_index] = f_id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(f_index >= CAN_FILTER_ID_MAX)
|
|
|
+ return ;*/
|
|
|
+
|
|
|
+ /* CAN filter init */
|
|
|
+ CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdHigh = (2<<5);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;//0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
+ CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
+#else
|
|
|
+ CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
+ /* CAN filter init */
|
|
|
+ CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdHigh = (DIS_ID<<5);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
+ CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
+
|
|
|
+ CAN_FilterInitStructure.CAN_FilterNumber = 1;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdHigh = (2<<5);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
|
|
+ CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
+ CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+ Can_NVIC_Config();
|
|
|
+
|
|
|
+ CAN_ITConfig(CAN1, CAN_IT_FMP0,ENABLE);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void USB_HP_CAN1_TX_IRQHandler(void)
|
|
|
+{
|
|
|
+ uint8_t data[8];
|
|
|
+ uint16_t data_len;
|
|
|
+
|
|
|
+ if(CAN_GetITStatus(CAN1,CAN_IT_TME) != RESET)
|
|
|
+ {
|
|
|
+ CAN_ClearITPendingBit(CAN1,CAN_IT_TME);
|
|
|
+
|
|
|
+ if(tx_count >= tx_buf_size)
|
|
|
+ {
|
|
|
+ memset(data,0xFB,CAN_FRAME_END_LEN);
|
|
|
+ Send_One_Frame_Can(data,CAN_FRAME_END_LEN);
|
|
|
+ CAN_ITConfig(CAN1, CAN_IT_TME,DISABLE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef test_1
|
|
|
+
|
|
|
+ data_len = tx_buf_size - tx_count;
|
|
|
+ if(data_len > sizeof(data))
|
|
|
+ {
|
|
|
+ data_len = sizeof(data);
|
|
|
+ }
|
|
|
+#else
|
|
|
+ if(tx_count == 0)
|
|
|
+ data_len = CAN_FRAME_START_LEN;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ data_len = tx_buf_size - tx_count;
|
|
|
+ if(data_len > sizeof(data))
|
|
|
+ {
|
|
|
+ data_len = sizeof(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ memcpy(data,&can_tx_buf[tx_count],data_len);
|
|
|
+ Send_One_Frame_Can(data,(uint8_t)data_len);
|
|
|
+ tx_count += data_len;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void USB_LP_CAN1_RX0_IRQHandler(void)
|
|
|
+{
|
|
|
+ CanRxMsg Rxmessage;
|
|
|
+ uint8_t data[8];
|
|
|
+
|
|
|
+ CAN_Receive(CAN1, CAN_FIFO0, &Rxmessage);
|
|
|
+
|
|
|
+ if(Rxmessage.DLC == CAN_FRAME_START_LEN)
|
|
|
+ {
|
|
|
+ memset(data,0xFA,CAN_FRAME_START_LEN);
|
|
|
+ if(memcmp(Rxmessage.Data,data,CAN_FRAME_START_LEN) == 0)
|
|
|
+ {
|
|
|
+ rx_count = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(Rxmessage.DLC == CAN_FRAME_END_LEN)
|
|
|
+ {
|
|
|
+ memset(data,0xFB,CAN_FRAME_END_LEN);
|
|
|
+ if(memcmp(Rxmessage.Data,data,CAN_FRAME_END_LEN) == 0)
|
|
|
+ {
|
|
|
+ g_event |= EVENT_CAN_RECEIVE_FINISH;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(rx_count + Rxmessage.DLC >= sizeof(can_rx_buf))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ memcpy(&can_rx_buf[rx_count],Rxmessage.Data,Rxmessage.DLC);
|
|
|
+ rx_count += Rxmessage.DLC;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//********************************************************CAN-END**********************************************************
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|