diff --git a/bsp/gd32/arm/gd32527I-eval/board/Kconfig b/bsp/gd32/arm/gd32527I-eval/board/Kconfig index b1b64491f0e..7dbe2ec67bf 100644 --- a/bsp/gd32/arm/gd32527I-eval/board/Kconfig +++ b/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 diff --git a/bsp/gd32/arm/gd32h759i-eval/board/Kconfig b/bsp/gd32/arm/gd32h759i-eval/board/Kconfig index f2c35205f59..0ee1c1d6cc4 100644 --- a/bsp/gd32/arm/gd32h759i-eval/board/Kconfig +++ b/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 diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.c b/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.c index 1efeef1b1f9..6c0a12eb262 100644 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.c +++ b/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 @@ -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 */ diff --git a/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.h b/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.h index cf808844904..6cca0755c70 100644 --- a/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.h +++ b/bsp/gd32/arm/libraries/gd32_drivers/drv_spi.h @@ -13,6 +13,7 @@ #include #include +#include #include #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;