summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
author似水流年 <[email protected]>2021-09-21 14:56:40 +0800
committer似水流年 <[email protected]>2021-09-21 14:56:40 +0800
commite923ba2884525112532959d2b6e9c544fdff7a16 (patch)
treefcbfffe1bfda1f7cfb31bf49dc072b1f750b2c21 /bsp
parentf4305df3f571d9e7b80180d9b1ce7ebd62222f57 (diff)
Add v85xx spi driver first version
Diffstat (limited to 'bsp')
-rw-r--r--bsp/Vango_V85xx/drivers/board.h1
-rw-r--r--bsp/Vango_V85xx/drivers/drv_spi.c287
-rw-r--r--bsp/Vango_V85xx/drivers/drv_spi.h16
-rw-r--r--bsp/Vango_V85xx/rtconfig.h1
4 files changed, 305 insertions, 0 deletions
diff --git a/bsp/Vango_V85xx/drivers/board.h b/bsp/Vango_V85xx/drivers/board.h
index a48528df35..215ad0b194 100644
--- a/bsp/Vango_V85xx/drivers/board.h
+++ b/bsp/Vango_V85xx/drivers/board.h
@@ -15,6 +15,7 @@
#include <target.h>
#include "drv_gpio.h"
+#include "drv_spi.h"
/* Internal SRAM memory size[Kbytes] <8-64>, Default: 32*/
#define V85XX_SRAM_SIZE 32
diff --git a/bsp/Vango_V85xx/drivers/drv_spi.c b/bsp/Vango_V85xx/drivers/drv_spi.c
new file mode 100644
index 0000000000..54bb9f9f92
--- /dev/null
+++ b/bsp/Vango_V85xx/drivers/drv_spi.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-06-05 tanek first implementation.
+ * 2018-04-19 misonyo Porting for gd32f30x
+ * 2019-03-31 xuzhuoyi Porting for gd32e230
+ */
+
+#include "drv_spi.h"
+#include "board.h"
+#include <rtthread.h>
+
+#if defined(RT_USING_SPI) && defined(RT_USING_PIN)
+#include <rtdevice.h>
+
+#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1)
+#error "Please define at least one SPIx"
+#endif
+
+/* #define DEBUG */
+#ifdef DEBUG
+#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
+#else
+#define DEBUG_PRINTF(...)
+#endif
+
+/* private rt-thread spi ops function */
+static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
+static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
+
+static struct rt_spi_ops gd32_spi_ops =
+{
+ configure,
+ xfer
+};
+
+static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration)
+{
+ spi_parameter_struct spi_init_struct;
+
+ rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
+
+ RT_ASSERT(device != RT_NULL);
+ RT_ASSERT(configuration != RT_NULL);
+
+ if(configuration->data_width <= 8)
+ {
+ spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
+ }
+ else if(configuration->data_width <= 16)
+ {
+ spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
+ }
+ else
+ {
+ return RT_EIO;
+ }
+
+ {
+ rcu_clock_freq_enum spi_src;
+ rt_uint32_t spi_apb_clock;
+ rt_uint32_t max_hz;
+
+ max_hz = configuration->max_hz;
+
+ DEBUG_PRINTF("sys freq: %d\n", rcu_clock_freq_get(CK_SYS));
+ DEBUG_PRINTF("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2));
+ DEBUG_PRINTF("max freq: %d\n", max_hz);
+
+ if (spi_periph == SPI1)
+ {
+ spi_src = CK_APB1;
+ }
+ else
+ {
+ spi_src = CK_APB2;
+ }
+ spi_apb_clock = rcu_clock_freq_get(spi_src);
+
+ if(max_hz >= spi_apb_clock/2)
+ {
+ spi_init_struct.prescale = SPI_PSC_2;
+ }
+ else if (max_hz >= spi_apb_clock/4)
+ {
+ spi_init_struct.prescale = SPI_PSC_4;
+ }
+ else if (max_hz >= spi_apb_clock/8)
+ {
+ spi_init_struct.prescale = SPI_PSC_8;
+ }
+ else if (max_hz >= spi_apb_clock/16)
+ {
+ spi_init_struct.prescale = SPI_PSC_16;
+ }
+ else if (max_hz >= spi_apb_clock/32)
+ {
+ spi_init_struct.prescale = SPI_PSC_32;
+ }
+ else if (max_hz >= spi_apb_clock/64)
+ {
+ spi_init_struct.prescale = SPI_PSC_64;
+ }
+ else if (max_hz >= spi_apb_clock/128)
+ {
+ spi_init_struct.prescale = SPI_PSC_128;
+ }
+ else
+ {
+ /* min prescaler 256 */
+ spi_init_struct.prescale = SPI_PSC_256;
+ }
+ } /* baudrate */
+
+ switch(configuration->mode & RT_SPI_MODE_3)
+ {
+ case RT_SPI_MODE_0:
+ spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
+ break;
+ case RT_SPI_MODE_1:
+ spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
+ break;
+ case RT_SPI_MODE_2:
+ spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
+ break;
+ case RT_SPI_MODE_3:
+ spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
+ break;
+ }
+
+ /* MSB or LSB */
+ if(configuration->mode & RT_SPI_MSB)
+ {
+ spi_init_struct.endian = SPI_ENDIAN_MSB;
+ }
+ else
+ {
+ spi_init_struct.endian = SPI_ENDIAN_LSB;
+ }
+
+ spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
+ spi_init_struct.device_mode = SPI_MASTER;
+ spi_init_struct.nss = SPI_NSS_SOFT;
+
+ spi_init(spi_periph, &spi_init_struct);
+
+ spi_crc_off(spi_periph);
+
+ spi_enable(spi_periph);
+
+ return RT_EOK;
+};
+
+static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
+{
+ rt_base_t gd32_cs_pin = (rt_base_t)device->parent.user_data;
+ rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
+ struct rt_spi_configuration * config = &device->config;
+
+ RT_ASSERT(device != NULL);
+ RT_ASSERT(message != NULL);
+
+ /* take CS */
+ if(message->cs_take)
+ {
+ rt_pin_write(gd32_cs_pin, PIN_LOW);
+ DEBUG_PRINTF("spi take cs\n");
+ }
+
+ {
+ if(config->data_width <= 8)
+ {
+ const rt_uint8_t * send_ptr = message->send_buf;
+ rt_uint8_t * recv_ptr = message->recv_buf;
+ rt_uint32_t size = message->length;
+
+ DEBUG_PRINTF("spi poll transfer start: %d\n", size);
+
+ while(size--)
+ {
+ rt_uint8_t data = 0xFF;
+
+ if(send_ptr != RT_NULL)
+ {
+ data = *send_ptr++;
+ }
+
+ // Todo: replace register read/write by gd32f3 lib
+ //Wait until the transmit buffer is empty
+ while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
+ // 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_RBNE));
+ // Get the received data
+ data = spi_i2s_data_receive(spi_periph);
+
+ if(recv_ptr != RT_NULL)
+ {
+ *recv_ptr++ = data;
+ }
+ }
+ DEBUG_PRINTF("spi poll transfer finsh\n");
+ }
+ else if(config->data_width <= 16)
+ {
+ const rt_uint16_t * send_ptr = message->send_buf;
+ rt_uint16_t * recv_ptr = message->recv_buf;
+ rt_uint32_t size = message->length;
+
+ while(size--)
+ {
+ rt_uint16_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_TBE));
+ // 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_RBNE));
+ // Get the received data
+ data = spi_i2s_data_receive(spi_periph);
+
+ if(recv_ptr != RT_NULL)
+ {
+ *recv_ptr++ = data;
+ }
+ }
+ }
+ }
+
+ /* release CS */
+ if(message->cs_release)
+ {
+ rt_pin_write(gd32_cs_pin, PIN_HIGH);
+ DEBUG_PRINTF("spi release cs\n");
+ }
+
+ return message->length;
+};
+
+int gd32_hw_spi_init(void)
+{
+ int result = 0;
+#ifdef RT_USING_SPI0
+ static struct rt_spi_bus spi_bus0;
+ spi_bus0.parent.user_data = (void *)SPI0;
+
+ result = rt_spi_bus_register(&spi_bus0, "spi0", &gd32_spi_ops);
+
+ rcu_periph_clock_enable(RCU_GPIOA);
+ rcu_periph_clock_enable(RCU_SPI0);
+
+ /* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */
+ gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
+ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
+ gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
+#endif
+#ifdef RT_USING_SPI1
+ static struct rt_spi_bus spi_bus1;
+ spi_bus1.parent.user_data = (void *)SPI1;
+
+ result = rt_spi_bus_register(&spi_bus1, "spi1", &gd32_spi_ops);
+
+ rcu_periph_clock_enable(RCU_SPI1);
+ rcu_periph_clock_enable(RCU_GPIOB);
+
+ /* SPI1 GPIO config: SCK/PB13, MISO/PB14, MOSI/PB15 */
+ gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15);
+ gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15);
+ gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15);
+#endif
+ return result;
+}
+INIT_BOARD_EXPORT(gd32_hw_spi_init);
+#endif
diff --git a/bsp/Vango_V85xx/drivers/drv_spi.h b/bsp/Vango_V85xx/drivers/drv_spi.h
new file mode 100644
index 0000000000..352ee5a4e3
--- /dev/null
+++ b/bsp/Vango_V85xx/drivers/drv_spi.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2012-01-01 aozima first implementation.
+ *
+ */
+
+#ifndef __DRV_SPI_H__
+#define __DRV_SPI_H__
+
+
+#endif // __DRV_SPI_H__
diff --git a/bsp/Vango_V85xx/rtconfig.h b/bsp/Vango_V85xx/rtconfig.h
index a1a5cba83d..4aa2d4b8d4 100644
--- a/bsp/Vango_V85xx/rtconfig.h
+++ b/bsp/Vango_V85xx/rtconfig.h
@@ -89,6 +89,7 @@
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
+#define RT_USING_SPI
/* Using USB */