From 29ae740490e16c1bf27e34bba82d46fe50500b02 Mon Sep 17 00:00:00 2001 From: ZYH Date: Mon, 18 Mar 2019 16:58:16 +0800 Subject: [PATCH] Add SPI driver --- bsp/k210/applications/mnt.c | 9 +- bsp/k210/driver/Kconfig | 61 +++++++++- bsp/k210/driver/SConscript | 7 +- bsp/k210/driver/drv_io_config.c | 28 +++-- bsp/k210/driver/drv_io_config.h | 14 ++- bsp/k210/driver/drv_spi.c | 190 ++++++++++++++++++++++++++++++++ bsp/k210/driver/drv_spi.h | 16 +++ 7 files changed, 303 insertions(+), 22 deletions(-) create mode 100644 bsp/k210/driver/drv_spi.c create mode 100644 bsp/k210/driver/drv_spi.h diff --git a/bsp/k210/applications/mnt.c b/bsp/k210/applications/mnt.c index d528a7424d..29557d71b2 100644 --- a/bsp/k210/applications/mnt.c +++ b/bsp/k210/applications/mnt.c @@ -8,8 +8,15 @@ */ #include - +#include +#include int mnt_init(void) { + msd_init("sd0", "spi10"); + if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + rt_kprintf("Mount \"/dev/sd0\" on \"/\"\n"); + } return 0; } +INIT_ENV_EXPORT(mnt_init); diff --git a/bsp/k210/driver/Kconfig b/bsp/k210/driver/Kconfig index 739ee4958c..7ba893a6f0 100644 --- a/bsp/k210/driver/Kconfig +++ b/bsp/k210/driver/Kconfig @@ -19,10 +19,64 @@ config BSP_USING_I2C1 select RT_USING_I2C default n -config BSP_USING_SPI1 - bool "Enable SPI1 (GPIO0/1)" +menuconfig BSP_USING_SPI1 + bool "Enable SPI1" select RT_USING_SPI default n +if BSP_USING_SPI1 + config BSP_USING_SPI1_AS_QSPI + bool + default n + config BSP_SPI1_CLK_PIN + int "spi1 clk pin number" + default 29 + config BSP_SPI1_D0_PIN + int "spi1 d0 pin number" + default 30 + config BSP_SPI1_D1_PIN + int "spi1 d1 pin number" + default 31 + if BSP_USING_SPI1_AS_QSPI + config BSP_SPI1_D2_PIN + int "spi1 d2 pin number" + default 32 + config BSP_SPI1_D3_PIN + int "spi1 d3 pin number" + default 33 + endif + menuconfig BSP_SPI1_USING_SS0 + bool "SPI1 Enable SS0" + default n + if BSP_SPI1_USING_SS0 + config BSP_SPI1_SS0_PIN + int "spi1 ss0 pin number" + default 24 + endif + menuconfig BSP_SPI1_USING_SS1 + bool "SPI1 Enable SS1" + default n + if BSP_SPI1_USING_SS1 + config BSP_SPI1_SS1_PIN + int "spi1 ss1 pin number" + default 25 + endif + menuconfig BSP_SPI1_USING_SS2 + bool "SPI1 Enable SS2" + default n + if BSP_SPI1_USING_SS2 + config BSP_SPI1_SS2_PIN + int "spi1 ss2 pin number" + default 26 + endif + menuconfig BSP_SPI1_USING_SS3 + bool "SPI1 Enable SS3" + default n + if BSP_SPI1_USING_SS3 + config BSP_SPI1_SS3_PIN + int "spi1 ss3 pin number" + default 27 + endif +endif menuconfig BSP_USING_LCD bool "Enable LCD on SPI0" @@ -73,5 +127,8 @@ if BSP_USING_CAMERA config BSP_CAMERA_CMOS_PCLK_PIN int "CMOS PCLK pin number for camera" default 15 + config BSP_CAMERA_CMOS_HREF_PIN + int "CMOS HREF pin number for camera" + default 17 endif diff --git a/bsp/k210/driver/SConscript b/bsp/k210/driver/SConscript index e3515d3ac7..30eca625f9 100644 --- a/bsp/k210/driver/SConscript +++ b/bsp/k210/driver/SConscript @@ -7,15 +7,13 @@ src = Split(''' board.c heap.c drv_uart.c +drv_io_config.c ''') CPPPATH = [cwd] if GetDepend('BSP_USING_LCD'): src += ['drv_lcd.c'] -if GetDepend('RT_USING_PIN'): - src += ['drv_gpio.c'] - if GetDepend('RT_USING_HWTIMER'): src += ['drv_hw_timer.c'] @@ -31,9 +29,6 @@ if GetDepend('RT_USING_SPI'): if GetDepend('RT_USING_PWM'): src += ['drv_pwm.c'] -if GetDepend('RT_USING_RTC'): - src += ['drv_rtc.c'] - if GetDepend('RT_USING_WDT'): src += ['drv_wdt.c'] diff --git a/bsp/k210/driver/drv_io_config.c b/bsp/k210/driver/drv_io_config.c index a5447e3085..706dd2b89f 100644 --- a/bsp/k210/driver/drv_io_config.c +++ b/bsp/k210/driver/drv_io_config.c @@ -25,23 +25,31 @@ static struct io_config {BSP_CAMERA_CMOS_PWDN_PIN, FUNC_CMOS_PWDN}, {BSP_CAMERA_CMOS_XCLK_PIN, FUNC_CMOS_XCLK}, {BSP_CAMERA_CMOS_PCLK_PIN, FUNC_CMOS_PCLK}, + {BSP_CAMERA_CMOS_PCLK_PIN, FUNC_CMOS_HREF}, #endif #ifdef BSP_USING_SPI1 - {17, FUNC_CMOS_HREF}, - {24, FUNC_SPI1_SS3}, - {29, FUNC_SPI1_SCLK}, - {30, FUNC_SPI1_D0}, - {31, FUNC_SPI1_D1}, + {BSP_SPI1_CLK_PIN, FUNC_SPI1_SCLK}, + {BSP_SPI1_D0_PIN, FUNC_SPI1_D0}, + {BSP_SPI1_D1_PIN, FUNC_SPI1_D1}, #ifdef BSP_USING_SPI1_AS_QSPI - {32, FUNC_SPI1_D2}, - {33, FUNC_SPI1_D3}, + {BSP_SPI1_D2_PIN, FUNC_SPI1_D2}, + {BSP_SPI1_D3_PIN, FUNC_SPI1_D3}, +#endif +#ifdef BSP_SPI1_USING_SS0 + {BSP_SPI1_SS0_PIN, HS_GPIO(SPI1_CS0_PIN)}, +#endif +#ifdef BSP_SPI1_USING_SS1 + {BSP_SPI1_SS1_PIN, HS_GPIO(SPI1_CS1_PIN)}, +#endif +#ifdef BSP_SPI1_USING_SS2 + {BSP_SPI1_SS2_PIN, HS_GPIO(SPI1_CS2_PIN)}, +#endif +#ifdef BSP_SPI1_USING_SS3 + {BSP_SPI1_SS3_PIN, HS_GPIO(SPI1_CS3_PIN)}, #endif #endif -#ifdef BSP_USING_SDCARD - {32, HS_GPIO(SD_CS_PIN)}, -#endif }; diff --git a/bsp/k210/driver/drv_io_config.h b/bsp/k210/driver/drv_io_config.h index d067c777f3..c5c00161fe 100644 --- a/bsp/k210/driver/drv_io_config.h +++ b/bsp/k210/driver/drv_io_config.h @@ -6,9 +6,17 @@ enum HS_GPIO_CONFIG #ifdef BSP_USING_LCD LCD_DC_PIN = 0, /* LCD DC PIN */ #endif - -#ifdef BSP_USING_SDCARD - SD_CS_PIN, /* SD_CS_PIN */ +#ifdef BSP_SPI1_USING_SS0 + SPI1_CS0_PIN, +#endif +#ifdef BSP_SPI1_USING_SS1 + SPI1_CS1_PIN, +#endif +#ifdef BSP_SPI1_USING_SS2 + SPI1_CS2_PIN, +#endif +#ifdef BSP_SPI1_USING_SS3 + SPI1_CS3_PIN, #endif }; diff --git a/bsp/k210/driver/drv_spi.c b/bsp/k210/driver/drv_spi.c new file mode 100644 index 0000000000..01e2b4f7e6 --- /dev/null +++ b/bsp/k210/driver/drv_spi.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ZYH first version + */ + +#include +#include + +#ifdef RT_USING_SPI +#include "drv_spi.h" +#include +#include +#include +#include +#include +#include + +#define DRV_SPI_DEVICE(spi_bus) (struct drv_spi_bus *)(spi_bus) + +struct drv_spi_bus +{ + struct rt_spi_bus parent; + spi_device_num_t spi_instance; + dmac_channel_number_t dma_send_channel; + dmac_channel_number_t dma_recv_channel; +}; + +struct drv_cs +{ + int cs_index; + int cs_pin; +}; + +static volatile spi_t *const spi_instance[4] = +{ + (volatile spi_t *)SPI0_BASE_ADDR, + (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, + (volatile spi_t *)SPI3_BASE_ADDR +}; + +static rt_err_t drv_spi_configure(struct rt_spi_device *device, + struct rt_spi_configuration *configuration) +{ + rt_err_t ret = RT_EOK; + struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus); + struct drv_cs * cs = (struct drv_cs *)device->parent.user_data; + RT_ASSERT(bus != RT_NULL); + + gpiohs_set_drive_mode(cs->cs_pin, GPIO_DM_OUTPUT); + gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH); + +#ifdef BSP_USING_SPI1_AS_QSPI + /* Todo:QSPI*/ +#else + spi_init(bus->spi_instance, configuration->mode & RT_SPI_MODE_3, SPI_FF_STANDARD, configuration->data_width, 0); +#endif + spi_set_clk_rate(bus->spi_instance, configuration->max_hz); + + return ret; +} + +extern void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const void *cmd_buff, + size_t cmd_len, void *rx_buff, size_t rx_len); + + + + +static rt_uint32_t drv_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus); + struct drv_cs * cs = (struct drv_cs *)device->parent.user_data; + struct rt_spi_configuration *cfg = &device->config; + const uint8_t * tx_buff = message->send_buf; + uint8_t * rx_buff = message->recv_buf; + uint32_t dummy[1024]; + size_t send_size, recv_size; + + send_size = message->length; + recv_size = message->length; + + RT_ASSERT(bus != RT_NULL); + + if(message->cs_take) + { + gpiohs_set_pin(cs->cs_pin, GPIO_PV_LOW); + } + if(message->length) + { + if(!tx_buff) + { + tx_buff = (uint8_t *)&dummy; + send_size = 1; + } + + if(!rx_buff) + { + rx_buff = (uint8_t *)&dummy; + recv_size = 1; + } + spi_dup_send_receive_data_dma(bus->dma_send_channel, bus->dma_recv_channel, bus->spi_instance, cs->cs_index, tx_buff, send_size, rx_buff, recv_size); + } + + if(message->cs_release) + { + gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH); + } + + return message->length; +} + +const static struct rt_spi_ops drv_spi_ops = +{ + drv_spi_configure, + drv_spi_xfer +}; + +int rt_hw_spi_init(void) +{ + rt_err_t ret = RT_EOK; + +#ifdef BSP_USING_SPI1 + { + static struct drv_spi_bus spi_bus1; + spi_bus1.spi_instance = SPI_DEVICE_1; + spi_bus1.dma_send_channel = DMAC_CHANNEL1; + spi_bus1.dma_recv_channel = DMAC_CHANNEL2; + ret = rt_spi_bus_register(&spi_bus1.parent, "spi1", &drv_spi_ops); + +#ifdef BSP_SPI1_USING_SS0 + { + static struct rt_spi_device spi_device10; + static struct drv_cs cs10 = + { + .cs_index = SPI_CHIP_SELECT_0, + .cs_pin = SPI1_CS0_PIN + }; + + rt_spi_bus_attach_device(&spi_device10, "spi10", "spi1", (void *)&cs10); + } +#endif + +#ifdef BSP_SPI1_USING_SS1 + { + static struct rt_spi_device spi_device11; + static struct drv_cs cs11 = + { + .cs_index = SPI_CHIP_SELECT_1, + .cs_pin = SPI1_CS1_PIN + }; + rt_spi_bus_attach_device(&spi_device11, "spi11", "spi1", (void *)&cs11); + } +#endif + +#ifdef BSP_SPI1_USING_SS2 + { + static struct rt_spi_device spi_device12; + static struct drv_cs cs12 = + { + .cs_index = SPI_CHIP_SELECT_2, + .cs_pin = SPI1_CS2_PIN + }; + rt_spi_bus_attach_device(&spi_device12, "spi12", "spi1", (void *)&cs12); + } +#endif + +#ifdef BSP_SPI1_USING_SS3 + { + static struct rt_spi_device spi_device13; + static struct drv_cs cs13 = + { + .cs_index = SPI_CHIP_SELECT_2, + .cs_pin = SPI1_CS2_PIN + }; + rt_spi_bus_attach_device(&spi_device13, "spi13", "spi1", (void *)&cs13); + } +#endif + } +#endif + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_spi_init); +#endif diff --git a/bsp/k210/driver/drv_spi.h b/bsp/k210/driver/drv_spi.h new file mode 100644 index 0000000000..78c973e0ef --- /dev/null +++ b/bsp/k210/driver/drv_spi.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ZYH first version + */ + +#ifndef DRV_SPI_H__ +#define DRV_SPI_H__ + +int rt_hw_spi_init(void); + +#endif