소스 검색

[bsp/gd32] 更新GD32 SPI驱动 #10657

WangShun 1 주 전
부모
커밋
f8a37bc42e

+ 16 - 7
bsp/gd32/arm/gd32527I-eval/board/Kconfig

@@ -258,19 +258,28 @@ menu "On-chip Peripheral Drivers"
         default n
         select RT_USING_SPI
         if BSP_USING_SPI
+            config BSP_USING_SPI0
+                bool "Enable SPI0 BUS"
+                default n
+
             config BSP_USING_SPI1
                 bool "Enable SPI1 BUS"
                 default n
 
-            config BSP_SPI1_TX_USING_DMA
-                bool "Enable SPI1 TX DMA"
-                depends on BSP_USING_SPI1
+            config BSP_USING_SPI2
+                bool "Enable SPI2 BUS"
+                default n
+
+            config BSP_USING_SPI3
+                bool "Enable SPI3 BUS"
+                default n
+
+            config BSP_USING_SPI4
+                bool "Enable SPI4 BUS"
                 default n
 
-            config BSP_SPI1_RX_USING_DMA
-                bool "Enable SPI1 RX DMA"
-                depends on BSP_USING_SPI1
-                select BSP_SPI1_TX_USING_DMA
+            config BSP_USING_SPI5
+                bool "Enable SPI5 BUS"
                 default n
         endif
 

+ 25 - 0
bsp/gd32/arm/gd32h759i-eval/board/Kconfig

@@ -99,6 +99,31 @@ menu "On-chip Peripheral Drivers"
                 endif
         endif
 
+    menuconfig BSP_USING_SPI
+        bool "Enable SPI BUS"
+        default n
+        select RT_USING_SPI
+        if BSP_USING_SPI
+            config BSP_USING_SPI0
+                bool "Enable SPI0 BUS"
+                default n
+            config BSP_USING_SPI1
+                bool "Enable SPI1 BUS"
+                default n
+            config BSP_USING_SPI2
+                bool "Enable SPI2 BUS"
+                default n
+            config BSP_USING_SPI3
+                bool "Enable SPI3 BUS"
+                default n
+            config BSP_USING_SPI4
+                bool "Enable SPI4 BUS"
+                default n
+            config BSP_USING_SPI5
+                bool "Enable SPI5 BUS"
+                default n
+        endif
+
     source "$(BSP_DIR)/../libraries/gd32_drivers/Kconfig"        
 endmenu
 

+ 162 - 32
bsp/gd32/arm/libraries/gd32_drivers/drv_spi.c

@@ -11,7 +11,7 @@
 
 #ifdef RT_USING_SPI
 
-#if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4)
+#if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5)
 #define LOG_TAG              "drv.spi"
 
 #include <rtdbg.h>
@@ -31,6 +31,9 @@ static struct rt_spi_bus spi_bus3;
 #ifdef BSP_USING_SPI4
 static struct rt_spi_bus spi_bus4;
 #endif
+#ifdef BSP_USING_SPI5
+static struct rt_spi_bus spi_bus5;
+#endif
 
 static const struct gd32_spi spi_bus_obj[] = {
 
@@ -40,12 +43,16 @@ static const struct gd32_spi spi_bus_obj[] = {
         "spi0",
         RCU_SPI0,
         RCU_GPIOA,
+        RCU_GPIOA,
+        RCU_GPIOA,
         &spi_bus0,
         GPIOA,
-#if defined SOC_SERIES_GD32F4xx
+        GPIOA,
+        GPIOA,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
         GPIO_AF_5,
 #endif
-#if defined SOC_SERIES_GD32E23x
+#if defined (SOC_SERIES_GD32E23x)
         GPIO_AF_0,
 #endif
         GPIO_PIN_5,
@@ -60,20 +67,20 @@ static const struct gd32_spi spi_bus_obj[] = {
         "spi1",
         RCU_SPI1,
         RCU_GPIOB,
+        RCU_GPIOB,
+        RCU_GPIOB,
         &spi_bus1,
         GPIOB,
-#if defined SOC_SERIES_GD32F4xx
+        GPIOB,
+        GPIOB,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
         GPIO_AF_5,
 #endif
 #if defined SOC_SERIES_GD32E23x
         GPIO_AF_0,
 #endif
 
-#if defined SOC_SERIES_GD32E23x
         GPIO_PIN_13,
-#else
-        GPIO_PIN_12,
-#endif
         GPIO_PIN_14,
         GPIO_PIN_15,
     },
@@ -85,9 +92,13 @@ static const struct gd32_spi spi_bus_obj[] = {
         "spi2",
         RCU_SPI2,
         RCU_GPIOB,
+        RCU_GPIOB,
+        RCU_GPIOB,
         &spi_bus2,
         GPIOB,
-#if defined SOC_SERIES_GD32F4xx
+        GPIOB,
+        GPIOB,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
         GPIO_AF_6,
 #endif
         GPIO_PIN_3,
@@ -102,9 +113,13 @@ static const struct gd32_spi spi_bus_obj[] = {
         "spi3",
         RCU_SPI3,
         RCU_GPIOE,
+        RCU_GPIOE,
+        RCU_GPIOE,
         &spi_bus3,
-        GPIOB,
-#if defined SOC_SERIES_GD32F4xx
+        GPIOE,
+        GPIOE,
+        GPIOE,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
         GPIO_AF_5,
 #endif
         GPIO_PIN_2,
@@ -119,16 +134,43 @@ static const struct gd32_spi spi_bus_obj[] = {
         "spi4",
         RCU_SPI4,
         RCU_GPIOF,
+        RCU_GPIOF,
+        RCU_GPIOF,
         &spi_bus4,
         GPIOF,
-#if defined SOC_SERIES_GD32F4xx
+        GPIOF,
+        GPIOF,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
         GPIO_AF_5,
 #endif
         GPIO_PIN_7,
         GPIO_PIN_8,
         GPIO_PIN_9,
-    }
+
+    },
 #endif /* BSP_USING_SPI4 */
+
+#ifdef BSP_USING_SPI5
+    {
+        SPI5,
+        "spi5",
+        RCU_SPI5,
+        RCU_GPIOG,
+        RCU_GPIOG,
+
+        RCU_GPIOG,
+        &spi_bus5,
+        GPIOG,
+        GPIOG,
+        GPIOG,
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx)
+        GPIO_AF_5,
+#endif
+        GPIO_PIN_13,
+        GPIO_PIN_12,
+        GPIO_PIN_14,
+    }
+#endif /* BSP_USING_SPI5 */
 };
 
 /* private rt-thread spi ops function */
@@ -150,24 +192,38 @@ static void gd32_spi_init(struct gd32_spi *gd32_spi)
 {
     /* enable SPI clock */
     rcu_periph_clock_enable(gd32_spi->spi_clk);
-    rcu_periph_clock_enable(gd32_spi->gpio_clk);
+    rcu_periph_clock_enable(gd32_spi->sck_gpio_clk);
+    rcu_periph_clock_enable(gd32_spi->miso_gpio_clk);
+    rcu_periph_clock_enable(gd32_spi->mosi_gpio_clk);
 
-#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x
+#if defined (SOC_SERIES_GD32F4xx) || defined (SOC_SERIES_GD32H7xx) || (defined SOC_SERIES_GD32F5xx) || (defined SOC_SERIES_GD32E23x)
     /*GPIO pin configuration*/
-    gpio_af_set(gd32_spi->spi_port, gd32_spi->alt_func_num, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
-
-    gpio_mode_set(gd32_spi->spi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
-    #if defined SOC_SERIES_GD32E23x
-    gpio_output_options_set(gd32_spi->spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
+    gpio_af_set(gd32_spi->sck_spi_port, gd32_spi->alt_func_num, gd32_spi->sck_pin);
+    gpio_af_set(gd32_spi->miso_spi_port, gd32_spi->alt_func_num, gd32_spi->miso_pin);
+    gpio_af_set(gd32_spi->mosi_spi_port, gd32_spi->alt_func_num, gd32_spi->mosi_pin);
+    gpio_mode_set(gd32_spi->sck_spi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gd32_spi->sck_pin);
+    gpio_mode_set(gd32_spi->miso_spi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gd32_spi->miso_pin);
+    gpio_mode_set(gd32_spi->mosi_spi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gd32_spi->mosi_pin);
+    #if defined (SOC_SERIES_GD32H7xx)
+    gpio_output_options_set(gd32_spi->sck_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, gd32_spi->sck_pin);
+    gpio_output_options_set(gd32_spi->miso_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, gd32_spi->miso_pin);
+    gpio_output_options_set(gd32_spi->mosi_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, gd32_spi->mosi_pin);
+    #elif defined (SOC_SERIES_GD32E23x)
+    gpio_output_options_set(gd32_spi->sck_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin);
+    gpio_output_options_set(gd32_spi->miso_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gd32_spi->miso_pin);
+    gpio_output_options_set(gd32_spi->mosi_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gd32_spi->mosi_pin);
     #else
-    gpio_output_options_set(gd32_spi->spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
+    gpio_output_options_set(gd32_spi->sck_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gd32_spi->sck_pin);
+    gpio_output_options_set(gd32_spi->miso_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gd32_spi->miso_pin);
+    gpio_output_options_set(gd32_spi->mosi_spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gd32_spi->mosi_pin);
     #endif
 #else
     /* Init SPI SCK MOSI */
-    gpio_init(gd32_spi->spi_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin | gd32_spi->mosi_pin);
+    gpio_init(gd32_spi->sck_spi_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin);
+    gpio_init(gd32_spi->mosi_spi_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, gd32_spi->mosi_pin);
 
     /* Init SPI MISO */
-    gpio_init(gd32_spi->spi_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, gd32_spi->miso_pin);
+    gpio_init(gd32_spi->miso_spi_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, gd32_spi->miso_pin);
 #endif
 
 }
@@ -186,6 +242,17 @@ static rt_err_t spi_configure(struct rt_spi_device* device,
     /* Init SPI */
     gd32_spi_init(spi_device);
 
+#if defined SOC_SERIES_GD32H7xx
+    /* data_width */
+    if(configuration->data_width >=4 && configuration->data_width <= 32)
+    {
+        spi_init_struct.data_size = CFG0_DZ(configuration->data_width - 1);
+    }
+    else
+    {
+        return -RT_EIO;
+    }
+#else
     /* data_width */
     if(configuration->data_width <= 8)
     {
@@ -199,6 +266,7 @@ static rt_err_t spi_configure(struct rt_spi_device* device,
     {
         return -RT_EIO;
     }
+#endif
 
     /* baudrate */
     {
@@ -306,19 +374,30 @@ static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* m
     struct rt_spi_bus * gd32_spi_bus = (struct rt_spi_bus *)device->bus;
     struct gd32_spi *spi_device = (struct gd32_spi *)gd32_spi_bus->parent.user_data;
     struct rt_spi_configuration * config = &device->config;
-    rt_base_t cs_pin = (rt_base_t)device->parent.user_data;
     uint32_t spi_periph = spi_device->spi_periph;
 
     RT_ASSERT(device != NULL);
     RT_ASSERT(message != NULL);
 
     /* take CS */
-    if(message->cs_take)
+    if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
     {
-        rt_pin_write(cs_pin, PIN_LOW);
-        LOG_D("spi take cs\n");
+        if (device->config.mode & RT_SPI_CS_HIGH)
+        {
+            rt_pin_write(device->cs_pin, PIN_HIGH);
+        }
+        else
+        {
+            rt_pin_write(device->cs_pin, PIN_LOW);
+        }
     }
 
+    LOG_D("%s transfer prepare and start", spi_device->bus_name);
+    LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
+          spi_device->bus_name,
+          (uint32_t)message->send_buf,
+          (uint32_t)message->recv_buf, message->length);
+
     {
         if(config->data_width <= 8)
         {
@@ -339,12 +418,20 @@ static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* m
 
                 /* Todo: replace register read/write by gd32f4 lib */
                 /* Wait until the transmit buffer is empty */
+                #if defined (SOC_SERIES_GD32H7xx)
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP));
+                #else
                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
+                #endif
                 /* Send the byte */
                 spi_i2s_data_transmit(spi_periph, data);
 
                 /* Wait until a data is received */
+                #if defined (SOC_SERIES_GD32H7xx)
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP));
+                #else
                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
+                #endif
                 /* Get the received data */
                 data = spi_i2s_data_receive(spi_periph);
 
@@ -371,12 +458,52 @@ static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* m
                 }
 
                 /* Wait until the transmit buffer is empty */
+                #if defined (SOC_SERIES_GD32H7xx)
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP));
+                #else
                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
+                #endif
                 /* Send the byte */
                 spi_i2s_data_transmit(spi_periph, data);
 
                 /* Wait until a data is received */
+                #if defined (SOC_SERIES_GD32H7xx)
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP));
+                #else
                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
+                #endif
+                /* Get the received data */
+                data = spi_i2s_data_receive(spi_periph);
+
+                if(recv_ptr != RT_NULL)
+                {
+                    *recv_ptr++ = data;
+                }
+            }
+        }
+        #if defined SOC_SERIES_GD32H7xx
+        else if(config->data_width <= 32)
+        {
+            const rt_uint32_t * send_ptr = message->send_buf;
+            rt_uint32_t * recv_ptr = message->recv_buf;
+            rt_uint32_t size = message->length;
+
+            while(size--)
+            {
+                rt_uint32_t data = 0xFF;
+
+                if(send_ptr != RT_NULL)
+                {
+                    data = *send_ptr++;
+                }
+
+                /* Wait until the transmit buffer is empty */
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TP));
+                /* Send the byte */
+                spi_i2s_data_transmit(spi_periph, data);
+
+                /* Wait until a data is received */
+                while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RP));
                 /* Get the received data */
                 data = spi_i2s_data_receive(spi_periph);
 
@@ -386,13 +513,16 @@ static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* m
                 }
             }
         }
+        #endif
     }
 
     /* release CS */
-    if(message->cs_release)
+    if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE))
     {
-        rt_pin_write(cs_pin, PIN_HIGH);
-        LOG_D("spi release cs\n");
+        if (device->config.mode & RT_SPI_CS_HIGH)
+            rt_pin_write(device->cs_pin, PIN_LOW);
+        else
+            rt_pin_write(device->cs_pin, PIN_HIGH);
     }
 
     return message->length;
@@ -420,7 +550,7 @@ rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name,
         rt_pin_write(cs_pin, PIN_HIGH);
     }
 
-    result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
+    result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
 
     if (result != RT_EOK)
     {
@@ -455,6 +585,6 @@ int rt_hw_spi_init(void)
 
 INIT_BOARD_EXPORT(rt_hw_spi_init);
 
-#endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4*/
+#endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */
 #endif /* RT_USING_SPI */
 

+ 8 - 3
bsp/gd32/arm/libraries/gd32_drivers/drv_spi.h

@@ -13,6 +13,7 @@
 
 #include <rthw.h>
 #include <rtthread.h>
+#include <rtdevice.h>
 #include <board.h>
 
 #ifdef __cplusplus
@@ -31,10 +32,14 @@ struct gd32_spi
     uint32_t spi_periph;
     char *bus_name;
     rcu_periph_enum spi_clk;
-    rcu_periph_enum gpio_clk;
+    rcu_periph_enum sck_gpio_clk;
+    rcu_periph_enum miso_gpio_clk;
+    rcu_periph_enum mosi_gpio_clk;
     struct rt_spi_bus *spi_bus;
-    uint32_t spi_port;
-#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x
+    uint32_t sck_spi_port;
+    uint32_t miso_spi_port;
+    uint32_t mosi_spi_port;
+#if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x || defined SOC_SERIES_GD32H7xx || defined SOC_SERIES_GD32F5xx
     uint32_t alt_func_num;
 #endif
     uint16_t sck_pin;