diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript index 6f2f6c5427a..65981919eed 100644 --- a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript @@ -19,6 +19,9 @@ if GetDepend('BSP_USING_CAN'): if GetDepend('BSP_USING_ECAP'): src += ['drv_ecap.c'] +if GetDepend('BSP_USING_SPI'): + src += ['drv_spi.c'] + group = DefineGroup('HAL_Drivers', src, depend = [''], CPPPATH = path) Return('group') diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.c new file mode 100644 index 00000000000..018341b9fa8 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-05-12 lugl first version + */ + +#include "board.h" +#include "drv_spi.h" +#include "drv_config.h" + +#ifdef RT_USING_SPI + +#define DRV_DEBUG +#define LOG_TAG "drv.spi" +#include + +#if !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && !defined(BSP_USING_SPI3) && \ + !defined(BSP_USING_SPI4) +#error "Please define at least one BSP_USING_SPIx" +#endif + +enum +{ +#ifdef BSP_USING_SPI1 + SPI1_INDEX, +#endif +#ifdef BSP_USING_SPI2 + SPI2_INDEX, +#endif +#ifdef BSP_USING_SPI3 + SPI3_INDEX, +#endif +#ifdef BSP_USING_SPI4 + SPI4_INDEX, +#endif +}; + +static struct ns800_spi_config spi_config[] = +{ +#ifdef BSP_USING_SPI1 + { + .name = "spi1", + .Instance = SPI1, + .rx_irq_type = SPI1_RX_IRQn, + .tx_irq_type = SPI1_TX_IRQn, + .sck_port = GPIOA, + .sck_pin = GPIO_PIN_18, + .sck_mux = ALT1_FUNCTION, + .mosi_port = GPIOA, + .mosi_pin = GPIO_PIN_16, + .mosi_mux = ALT1_FUNCTION, + .miso_port = GPIOA, + .miso_pin = GPIO_PIN_17, + .miso_mux = ALT1_FUNCTION, + }, +#endif +#ifdef BSP_USING_SPI2 + { + .name = "spi2", + .Instance = SPI2, + .rx_irq_type = SPI2_RX_IRQn, + .tx_irq_type = SPI2_TX_IRQn, + .sck_port = GPIOB, + .sck_pin = GPIO_PIN_0, + .sck_mux = ALT9_FUNCTION, + .mosi_port = GPIOB, + .mosi_pin = GPIO_PIN_1, + .mosi_mux = ALT9_FUNCTION, + .miso_port = GPIOB, + .miso_pin = GPIO_PIN_2, + .miso_mux = ALT9_FUNCTION, + }, +#endif +#ifdef BSP_USING_SPI3 + { + .name = "spi3", + .Instance = SPI3, + .rx_irq_type = SPI3_RX_IRQn, + .tx_irq_type = SPI3_TX_IRQn, + .sck_port = GPIOC, + .sck_pin = GPIO_PIN_0, + .sck_mux = ALT7_FUNCTION, + .mosi_port = GPIOC, + .mosi_pin = GPIO_PIN_1, + .mosi_mux = ALT7_FUNCTION, + .miso_port = GPIOC, + .miso_pin = GPIO_PIN_2, + .miso_mux = ALT7_FUNCTION, + }, +#endif +#ifdef BSP_USING_SPI4 + { + .name = "spi4", + .Instance = SPI4, + .rx_irq_type = SPI4_RX_IRQn, + .tx_irq_type = SPI4_TX_IRQn, + .sck_port = GPIOC, + .sck_pin = GPIO_PIN_4, + .sck_mux = ALT7_FUNCTION, + .mosi_port = GPIOC, + .mosi_pin = GPIO_PIN_5, + .mosi_mux = ALT7_FUNCTION, + .miso_port = GPIOC, + .miso_pin = GPIO_PIN_6, + .miso_mux = ALT7_FUNCTION, + }, +#endif +}; + +static struct ns800_spi spi_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0}; + +static void ns800_spi_gpio_init(const struct ns800_spi_config *config) +{ + RT_ASSERT(config != RT_NULL); + + GPIO_setPinConfig(config->sck_port, config->sck_pin, config->sck_mux); + GPIO_setAnalogMode(config->sck_port, config->sck_pin, GPIO_ANALOG_DISABLED); + GPIO_setPadConfig(config->sck_port, config->sck_pin, GPIO_PIN_TYPE_STD); + GPIO_setQualificationMode(config->sck_port, config->sck_pin, GPIO_QUAL_SYNC); + GPIO_setDirectionMode(config->sck_port, config->sck_pin, GPIO_DIR_MODE_OUT); + + GPIO_setPinConfig(config->mosi_port, config->mosi_pin, config->mosi_mux); + GPIO_setAnalogMode(config->mosi_port, config->mosi_pin, GPIO_ANALOG_DISABLED); + GPIO_setPadConfig(config->mosi_port, config->mosi_pin, GPIO_PIN_TYPE_STD); + GPIO_setQualificationMode(config->mosi_port, config->mosi_pin, GPIO_QUAL_SYNC); + GPIO_setDirectionMode(config->mosi_port, config->mosi_pin, GPIO_DIR_MODE_OUT); + + GPIO_setPinConfig(config->miso_port, config->miso_pin, config->miso_mux); + GPIO_setAnalogMode(config->miso_port, config->miso_pin, GPIO_ANALOG_DISABLED); + GPIO_setPadConfig(config->miso_port, config->miso_pin, GPIO_PIN_TYPE_PULLUP); + GPIO_setQualificationMode(config->miso_port, config->miso_pin, GPIO_QUAL_SYNC); + GPIO_setDirectionMode(config->miso_port, config->miso_pin, GPIO_DIR_MODE_IN); +} + +static rt_err_t ns800_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration) +{ + struct ns800_spi *spi; + SPI_TransferProtocol protocol; + SPI_BitWidth data_width; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + spi = rt_container_of(device->bus, struct ns800_spi, spi_bus); + + ns800_spi_gpio_init(spi->config); + + switch (configuration->mode & RT_SPI_MODE_3) + { + case RT_SPI_MODE_0: + protocol = SPI_PROT_POL0PHA0; + break; + case RT_SPI_MODE_1: + protocol = SPI_PROT_POL0PHA1; + break; + case RT_SPI_MODE_2: + protocol = SPI_PROT_POL1PHA0; + break; + case RT_SPI_MODE_3: + protocol = SPI_PROT_POL1PHA1; + break; + default: + protocol = SPI_PROT_POL0PHA0; + break; + } + + switch (configuration->data_width) + { + case 8: + data_width = SPI_BIT_WIDTH_8_BITS; + break; + case 16: + data_width = SPI_BIT_WIDTH_16_BITS; + break; + default: + data_width = SPI_BIT_WIDTH_8_BITS; + break; + } + + SPI_disableModule(spi->config->Instance); + + SPI_setConfig(spi->config->Instance, + protocol, + SPI_MASTER_MODE, + SPI_FULL_DUPLEX_COMM_MODE, + configuration->max_hz, + data_width); + + SPI_resetFifo(spi->config->Instance); + SPI_enableModule(spi->config->Instance); + + return RT_EOK; +} + +static rt_ssize_t ns800_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + struct ns800_spi *spi; + SPI_TypeDef *instance; + const rt_uint8_t *send_buf; + rt_uint8_t *recv_buf; + rt_size_t length; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + + spi = rt_container_of(device->bus, struct ns800_spi, spi_bus); + instance = spi->config->Instance; + length = message->length; + send_buf = message->send_buf; + recv_buf = message->recv_buf; + + if (message->cs_take) + { + rt_pin_write(device->cs_pin, PIN_LOW); + } + + while (length) + { + if (send_buf) + { + if (recv_buf) + { + recv_buf[0] = SPI_transmitReceive(instance, send_buf[0]); + recv_buf++; + } + else + { + SPI_transmitReceive(instance, send_buf[0]); + } + send_buf++; + } + else + { + if (recv_buf) + { + recv_buf[0] = SPI_transmitReceive(instance, 0xFF); + recv_buf++; + } + else + { + SPI_transmitReceive(instance, 0xFF); + } + } + length--; + } + + if (message->cs_release) + { + rt_pin_write(device->cs_pin, PIN_HIGH); + } + + return message->length; +} + +static const struct rt_spi_ops ns800_spi_ops = +{ + .configure = ns800_spi_configure, + .xfer = ns800_spi_xfer, +}; + +static void ns800_spi_clock_init(SPI_TypeDef *Instance) +{ +#ifdef BSP_USING_SPI1 + if (Instance == SPI1) + { + RCC_enableSpi1Clock(); + RCC_resetSpi1Module(); + RCC_releaseSpi1Module(); + } +#endif +#ifdef BSP_USING_SPI2 + if (Instance == SPI2) + { + RCC_enableSpi2Clock(); + RCC_resetSpi2Module(); + RCC_releaseSpi2Module(); + } +#endif +#ifdef BSP_USING_SPI3 + if (Instance == SPI3) + { + RCC_enableSpi3Clock(); + RCC_resetSpi3Module(); + RCC_releaseSpi3Module(); + } +#endif +#ifdef BSP_USING_SPI4 + if (Instance == SPI4) + { + RCC_enableSpi4Clock(); + RCC_resetSpi4Module(); + RCC_releaseSpi4Module(); + } +#endif +} + +int rt_hw_spi_init(void) +{ + rt_size_t i; + rt_err_t result; + + for (i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++) + { + ns800_spi_clock_init(spi_config[i].Instance); + + spi_obj[i].config = &spi_config[i]; + spi_obj[i].spi_bus.parent.user_data = &spi_config[i]; + + result = rt_spi_bus_register(&spi_obj[i].spi_bus, + spi_config[i].name, + &ns800_spi_ops); + if (result != RT_EOK) + { + LOG_E("rt_spi_bus_register(%s) failed: %d", spi_config[i].name, result); + } + } + + return RT_EOK; +} + +INIT_BOARD_EXPORT(rt_hw_spi_init); + +#endif + diff --git a/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.h new file mode 100644 index 00000000000..56bf9489bf6 --- /dev/null +++ b/bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_spi.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-05-12 lugl first version + */ + +#ifndef __DRV_SPI_H__ +#define __DRV_SPI_H__ + +#include +#include "rtdevice.h" +#include +#include + +#ifdef RT_USING_SPI + +struct ns800_spi_config +{ + const char *name; + SPI_TypeDef *Instance; + IRQn_Type rx_irq_type; + IRQn_Type tx_irq_type; + GPIO_TypeDef *sck_port; + GPIO_PinNum sck_pin; + GPIO_AltFunc sck_mux; + GPIO_TypeDef *mosi_port; + GPIO_PinNum mosi_pin; + GPIO_AltFunc mosi_mux; + GPIO_TypeDef *miso_port; + GPIO_PinNum miso_pin; + GPIO_AltFunc miso_mux; +}; + +struct ns800_spi +{ + SPI_TypeDef *Instance; + struct rt_spi_bus spi_bus; + struct ns800_spi_config *config; +}; + +int rt_hw_spi_init(void); + +#endif + +#endif /* __DRV_SPI_H__ */ + diff --git a/bsp/novosns/ns800/ns800rt7p65-nssinepad/.config b/bsp/novosns/ns800/ns800rt7p65-nssinepad/.config index 5eb647dc85a..3ff96063428 100644 --- a/bsp/novosns/ns800/ns800rt7p65-nssinepad/.config +++ b/bsp/novosns/ns800/ns800rt7p65-nssinepad/.config @@ -260,7 +260,15 @@ CONFIG_RT_CAN_NB_TX_FIFO_SIZE=256 # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_RTC is not set # CONFIG_RT_USING_SDIO is not set -# CONFIG_RT_USING_SPI is not set +CONFIG_RT_USING_SPI=y +CONFIG_RT_USING_SPI_ISR=y +# CONFIG_RT_USING_SPI_BITOPS is not set +# CONFIG_RT_USING_SOFT_SPI is not set +# CONFIG_RT_USING_QSPI is not set +# CONFIG_RT_USING_SPI_MSD is not set +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set @@ -268,6 +276,7 @@ CONFIG_RT_CAN_NB_TX_FIFO_SIZE=256 # CONFIG_RT_USING_LCD is not set # CONFIG_RT_USING_HWCRYPTO is not set # CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_RPMSG is not set # CONFIG_RT_USING_BLK is not set # CONFIG_RT_USING_REGULATOR is not set # CONFIG_RT_USING_POWER_SUPPLY is not set @@ -1453,4 +1462,9 @@ CONFIG_BSP_USING_UART1=y CONFIG_BSP_USING_ECAP=y CONFIG_BSP_USING_CAN=y CONFIG_BSP_USING_CANFD1=y +CONFIG_BSP_USING_SPI=y +CONFIG_BSP_USING_SPI1=y +# CONFIG_BSP_USING_SPI2 is not set +# CONFIG_BSP_USING_SPI3 is not set +# CONFIG_BSP_USING_SPI4 is not set # end of On-chip Peripheral Drivers diff --git a/bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig b/bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig index c4bbdf3080b..db71438c7fb 100644 --- a/bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig +++ b/bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig @@ -105,4 +105,26 @@ menu "On-chip Peripheral Drivers" endif + menuconfig BSP_USING_SPI + bool "Enable SPI" + select RT_USING_SPI + default n + if BSP_USING_SPI + menuconfig BSP_USING_SPI1 + bool "Enable SPI1" + default n + + menuconfig BSP_USING_SPI2 + bool "Enable SPI2" + default n + + menuconfig BSP_USING_SPI3 + bool "Enable SPI3" + default n + + menuconfig BSP_USING_SPI4 + bool "Enable SPI4" + default n + endif + endmenu diff --git a/bsp/novosns/ns800/ns800rt7p65-nssinepad/rtconfig.h b/bsp/novosns/ns800/ns800rt7p65-nssinepad/rtconfig.h index 380f2986c76..ed62ec1f9f8 100644 --- a/bsp/novosns/ns800/ns800rt7p65-nssinepad/rtconfig.h +++ b/bsp/novosns/ns800/ns800rt7p65-nssinepad/rtconfig.h @@ -149,6 +149,8 @@ #define RT_CANSND_BOX_NUM 1 #define RT_CANSND_MSG_TIMEOUT 100 #define RT_CAN_NB_TX_FIFO_SIZE 256 +#define RT_USING_SPI +#define RT_USING_SPI_ISR #define RT_USING_PIN /* end of Device Drivers */ @@ -424,6 +426,8 @@ #define BSP_USING_ECAP #define BSP_USING_CAN #define BSP_USING_CANFD1 +#define BSP_USING_SPI +#define BSP_USING_SPI1 /* end of On-chip Peripheral Drivers */ #endif