Browse Source

添加HC32F460系列CAN设备驱动支持

xiaoxiaolisunny 3 years ago
parent
commit
a738849257

+ 10 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/Kconfig

@@ -78,6 +78,16 @@ menu "On-chip Peripheral Drivers"
                 depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
                 default n
         endif
+		
+	menuconfig BSP_USING_CAN
+        bool "Enable CAN"
+        default n
+        select RT_USING_CAN
+        if BSP_USING_CAN
+            config BSP_USING_CAN1
+                bool "using can1"
+                default n
+        endif
 
 endmenu
 

+ 0 - 4
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board.c

@@ -87,10 +87,6 @@ void SystemClock_Config(void)
 static void PeripheralClock_Config(void)
 {
 #if defined(HC32F460)
-#if defined(BSP_USING_CAN1)
-    CLK_SetCANClockSrc(CLK_CAN1, CLK_CANCLK_SYSCLK_DIV6);
-#endif
-
 #if defined(RT_USING_ADC)
     CLK_SetPeriClockSrc(CLK_PERIPHCLK_PCLK);
 #endif

+ 26 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.c

@@ -60,3 +60,29 @@ rt_err_t rt_hw_board_uart_init(CM_USART_TypeDef *USARTx)
 }
 #endif
 
+#if defined(RT_USING_CAN)
+void CanPhyEnable(void)
+{
+    GPIO_ResetPins(CAN_STB_PORT, CAN_STB_PIN);
+    GPIO_OutputCmd(CAN_STB_PORT, CAN_STB_PIN, ENABLE);
+}
+rt_err_t rt_hw_board_can_init(CM_CAN_TypeDef *CANx)
+{
+    rt_err_t result = RT_EOK;
+
+    switch ((rt_uint32_t)CANx)
+    {
+#if defined(BSP_USING_CAN1)
+case (rt_uint32_t)CM_CAN:
+    GPIO_SetFunc(CAN1_TX_PORT, CAN1_TX_PIN, CAN1_TX_PIN_FUNC);
+    GPIO_SetFunc(CAN1_RX_PORT, CAN1_RX_PIN, CAN1_RX_PIN_FUNC);
+    break;
+#endif
+default:
+    result = -RT_ERROR;
+    break;
+    }
+
+    return result;
+}
+#endif

+ 14 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/board_config.h

@@ -51,4 +51,18 @@
     #define USART4_TX_PIN                   (GPIO_PIN_06)
 #endif
 
+/***********  CAN configure *********/
+#if defined(BSP_USING_CAN1)
+    #define CAN1_TX_PORT                     (GPIO_PORT_B)
+    #define CAN1_TX_PIN                      (GPIO_PIN_07)
+    #define CAN1_TX_PIN_FUNC                 (GPIO_FUNC_50)
+
+    #define CAN1_RX_PORT                     (GPIO_PORT_B)
+    #define CAN1_RX_PIN                      (GPIO_PIN_06)
+    #define CAN1_RX_PIN_FUNC                 (GPIO_FUNC_51)
+
+    #define CAN_STB_PORT                     (GPIO_PORT_D)
+    #define CAN_STB_PIN                      (GPIO_PIN_15)
+#endif
+
 #endif

+ 119 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/config/can_config.h

@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2022, Xiaohua Semiconductor Co., Ltd.
+ * Copyright (c) 2022, xiaoxiaolisunny
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author                   Notes
+ * 2022-06-07     xiaoxiaolisunny          first version
+ */
+
+#ifndef __CAN_CONFIG_H__
+#define __CAN_CONFIG_H__
+
+#include <rtthread.h>
+#include "irq_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BSP_USING_CAN1
+#ifndef CAN1_INIT_PARAMS
+#define CAN1_INIT_PARAMS                                    \
+    {                                                       \
+       .name = "can1",                                      \
+    }
+#endif /* CAN1_INIT_PARAMS */
+#endif /* BSP_USING_CAN1 */
+
+/* Bit time config
+  Restrictions: u32TimeSeg1 >= u32TimeSeg2 + 1, u32TimeSeg2 >= u32SJW.
+
+  Baudrate = CANClock/(u32Prescaler*(u32TimeSeg1 + u32TimeSeg2))
+  TQ = u32Prescaler / CANClock.
+  Bit time = (u32TimeSeg1 + u32TimeSeg2) x TQ.
+
+  The following bit time configures are based on CAN Clock 8M
+*/
+#define CAN_BIT_TIME_CONFIG_1M_BAUD                         \
+    {                                                       \
+        .u32Prescaler = 1,                                  \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_800K_BAUD                       \
+    {                                                       \
+        .u32Prescaler = 1,                                  \
+        .u32TimeSeg1 = 6,                                  \
+        .u32TimeSeg2 = 4,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_500K_BAUD                       \
+    {                                                       \
+        .u32Prescaler = 2,                                  \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_250K_BAUD                       \
+    {                                                       \
+        .u32Prescaler = 4,                                  \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_125K_BAUD                       \
+    {                                                       \
+        .u32Prescaler = 8,                                 \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_100K_BAUD                       \
+    {                                                       \
+        .u32Prescaler = 10,                                 \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_50K_BAUD                        \
+    {                                                       \
+        .u32Prescaler = 20,                                 \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_20K_BAUD                        \
+    {                                                       \
+        .u32Prescaler = 50,                                \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#define CAN_BIT_TIME_CONFIG_10K_BAUD                        \
+    {                                                       \
+        .u32Prescaler = 100,                                \
+        .u32TimeSeg1 = 5,                                  \
+        .u32TimeSeg2 = 3,                                   \
+        .u32SJW = 3                                         \
+    }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CAN_CONFIG_H__ */
+
+

+ 1 - 0
bsp/hc32/ev_hc32f460_lqfp100_v2/board/drv_config.h

@@ -22,6 +22,7 @@ extern "C" {
 #include "dma_config.h"
 #include "uart_config.h"
 #include "gpio_config.h"
+#include "can_config.h"
 
 #ifdef __cplusplus
 }

+ 30 - 4
bsp/hc32/libraries/hc32_drivers/drv_can.c

@@ -5,8 +5,9 @@
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
- * Date           Author       Notes
- * 2022-04-28     CDT          first version
+ * Date           Author               Notes
+ * 2022-04-28     CDT                  first version
+ * 2022-06-07     xiaoxiaolisunny      add hc32f460 series
  */
 
 #include "drv_can.h"
@@ -26,6 +27,11 @@
     #define CAN2_INT_SRC                                    (INT_SRC_CAN2_HOST)
 #endif
 
+#if defined (HC32F460)
+    #define FILTER_COUNT                                    (16)
+    #define CAN1_INT_SRC                                    (INT_SRC_CAN_INT)
+#endif
+
 enum
 {
 #ifdef BSP_USING_CAN1
@@ -66,6 +72,7 @@ typedef struct
 
 static can_device g_can_dev_array[] =
 {
+#if defined (HC32F4A0)
 #ifdef BSP_USING_CAN1
     {
         {0},
@@ -80,6 +87,17 @@ static can_device g_can_dev_array[] =
         .instance = CM_CAN2,
     },
 #endif
+#endif
+
+#if defined (HC32F460)
+#ifdef BSP_USING_CAN1
+    {
+        {0},
+        CAN1_INIT_PARAMS,
+        .instance = CM_CAN,
+    },
+#endif
+#endif
 };
 
 static rt_uint32_t _get_can_baud_index(rt_uint32_t baud)
@@ -350,6 +368,8 @@ static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t
     }
     /* Set up the DLC */
     stc_tx_frame.DLC = pmsg->len & 0x0FU;
+    /* Set up the IDE */
+    stc_tx_frame.IDE = pmsg->ide;
     /* Set up the data field */
     rt_memcpy(&stc_tx_frame.au8Data, pmsg->data, sizeof(stc_tx_frame.au8Data));
     ll_ret = CAN_FillTxFrame(p_can_dev->instance, CAN_TX_BUF_PTB, &stc_tx_frame);
@@ -380,7 +400,7 @@ static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
         return -RT_ERROR;
 
     /* get id */
-    if (CAN_ID_STD == ll_rx_frame.IDE)
+    if (0 == ll_rx_frame.IDE)
     {
         pmsg->ide = RT_CAN_STDID;
     }
@@ -540,6 +560,12 @@ static void _can_clock_enable(void)
     FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_CAN2, ENABLE);
 #endif
 #endif
+
+#if defined(HC32F460)
+#if defined(BSP_USING_CAN1)
+    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_CAN, ENABLE);
+#endif
+#endif
 }
 
 static void _can_irq_config(void)
@@ -593,7 +619,7 @@ int rt_hw_can_init(void)
         rt_memset(g_can_dev_array[i].ll_init.pstcFilter, 0, sizeof(stc_can_filter_config_t) * FILTER_COUNT);
         g_can_dev_array[i].ll_init.pstcFilter[0].u32ID = 0U;
         g_can_dev_array[i].ll_init.pstcFilter[0].u32IDMask = 0x1FFFFFFF;
-        g_can_dev_array[i].ll_init.pstcFilter[0].u32IDType = CAN_ID_STD;
+        g_can_dev_array[i].ll_init.pstcFilter[0].u32IDType = CAN_ID_STD_EXT;
         g_can_dev_array[i].ll_init.u16FilterSelect = CAN_FILTER1;
         g_can_dev_array[i].rt_can.config = rt_can_config;