summaryrefslogtreecommitdiff
path: root/bsp/nuclei/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/nuclei/libraries')
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript21
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_config.h26
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c520
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.h51
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c347
-rw-r--r--bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h36
6 files changed, 1001 insertions, 0 deletions
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript
new file mode 100644
index 0000000000..4761127102
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/SConscript
@@ -0,0 +1,21 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+
+# add the general drivers.
+src = Split("""
+""")
+
+if GetDepend(['RT_USING_PIN']):
+ src += ['drv_gpio.c']
+
+if GetDepend(['RT_USING_SERIAL']):
+ src += ['drv_usart.c']
+
+path = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
+
+Return('group')
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_config.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_config.h
new file mode 100644
index 0000000000..bb24afa19e
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_config.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-04-08 hqfang first version
+ */
+
+#ifndef __DRV_CONFIG_H__
+#define __DRV_CONFIG_H__
+
+#include <board.h>
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c
new file mode 100644
index 0000000000..75ab81f18e
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-04-09 hqfang first version
+ */
+
+#include "drv_gpio.h"
+
+#ifdef RT_USING_PIN
+
+static const struct pin_index pins[] =
+{
+
+ __GD32_PIN(0, A, 0),
+ __GD32_PIN(1, A, 1),
+ __GD32_PIN(2, A, 2),
+ __GD32_PIN(3, A, 3),
+ __GD32_PIN(4, A, 4),
+ __GD32_PIN(5, A, 5),
+ __GD32_PIN(6, A, 6),
+ __GD32_PIN(7, A, 7),
+ __GD32_PIN(8, A, 8),
+ __GD32_PIN(9, A, 9),
+ __GD32_PIN(10, A, 10),
+ __GD32_PIN(11, A, 11),
+ __GD32_PIN(12, A, 12),
+ __GD32_PIN(13, A, 13),
+ __GD32_PIN(14, A, 14),
+ __GD32_PIN(15, A, 15),
+
+ __GD32_PIN(16, B, 0),
+ __GD32_PIN(17, B, 1),
+ __GD32_PIN(18, B, 2),
+ __GD32_PIN(19, B, 3),
+ __GD32_PIN(20, B, 4),
+ __GD32_PIN(21, B, 5),
+ __GD32_PIN(22, B, 6),
+ __GD32_PIN(23, B, 7),
+ __GD32_PIN(24, B, 8),
+ __GD32_PIN(25, B, 9),
+ __GD32_PIN(26, B, 10),
+ __GD32_PIN(27, B, 11),
+ __GD32_PIN(28, B, 12),
+ __GD32_PIN(29, B, 13),
+ __GD32_PIN(30, B, 14),
+ __GD32_PIN(31, B, 15),
+
+ __GD32_PIN(32, C, 0),
+ __GD32_PIN(33, C, 1),
+ __GD32_PIN(34, C, 2),
+ __GD32_PIN(35, C, 3),
+ __GD32_PIN(36, C, 4),
+ __GD32_PIN(37, C, 5),
+ __GD32_PIN(38, C, 6),
+ __GD32_PIN(39, C, 7),
+ __GD32_PIN(40, C, 8),
+ __GD32_PIN(41, C, 9),
+ __GD32_PIN(42, C, 10),
+ __GD32_PIN(43, C, 11),
+ __GD32_PIN(44, C, 12),
+ __GD32_PIN(45, C, 13),
+ __GD32_PIN(46, C, 14),
+ __GD32_PIN(47, C, 15),
+
+ __GD32_PIN(48, D, 0),
+ __GD32_PIN(49, D, 1),
+ __GD32_PIN(50, D, 2),
+ __GD32_PIN(51, D, 3),
+ __GD32_PIN(52, D, 4),
+ __GD32_PIN(53, D, 5),
+ __GD32_PIN(54, D, 6),
+ __GD32_PIN(55, D, 7),
+ __GD32_PIN(56, D, 8),
+ __GD32_PIN(57, D, 9),
+ __GD32_PIN(58, D, 10),
+ __GD32_PIN(59, D, 11),
+ __GD32_PIN(60, D, 12),
+ __GD32_PIN(61, D, 13),
+ __GD32_PIN(62, D, 14),
+ __GD32_PIN(63, D, 15),
+
+ __GD32_PIN(64, E, 0),
+ __GD32_PIN(65, E, 1),
+ __GD32_PIN(66, E, 2),
+ __GD32_PIN(67, E, 3),
+ __GD32_PIN(68, E, 4),
+ __GD32_PIN(69, E, 5),
+ __GD32_PIN(70, E, 6),
+ __GD32_PIN(71, E, 7),
+ __GD32_PIN(72, E, 8),
+ __GD32_PIN(73, E, 9),
+ __GD32_PIN(74, E, 10),
+ __GD32_PIN(75, E, 11),
+ __GD32_PIN(76, E, 12),
+ __GD32_PIN(77, E, 13),
+ __GD32_PIN(78, E, 14),
+ __GD32_PIN(79, E, 15),
+};
+
+static const struct pin_irq_map pin_irq_map[] =
+{
+ {GPIO_PIN_0, EXTI0_IRQn},
+ {GPIO_PIN_1, EXTI1_IRQn},
+ {GPIO_PIN_2, EXTI2_IRQn},
+ {GPIO_PIN_3, EXTI3_IRQn},
+ {GPIO_PIN_4, EXTI4_IRQn},
+ {GPIO_PIN_5, EXTI5_9_IRQn},
+ {GPIO_PIN_6, EXTI5_9_IRQn},
+ {GPIO_PIN_7, EXTI5_9_IRQn},
+ {GPIO_PIN_8, EXTI5_9_IRQn},
+ {GPIO_PIN_9, EXTI5_9_IRQn},
+ {GPIO_PIN_10, EXTI10_15_IRQn},
+ {GPIO_PIN_11, EXTI10_15_IRQn},
+ {GPIO_PIN_12, EXTI10_15_IRQn},
+ {GPIO_PIN_13, EXTI10_15_IRQn},
+ {GPIO_PIN_14, EXTI10_15_IRQn},
+ {GPIO_PIN_15, EXTI10_15_IRQn},
+};
+
+static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
+{
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+ {-1, 0, RT_NULL, RT_NULL},
+};
+static uint32_t pin_irq_enable_mask = 0;
+
+#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
+static const struct pin_index *get_pin(uint8_t pin)
+{
+ const struct pin_index *index;
+
+ if (pin < ITEM_NUM(pins))
+ {
+ index = &pins[pin];
+ if (index->index == -1)
+ index = RT_NULL;
+ }
+ else
+ {
+ index = RT_NULL;
+ }
+
+ return index;
+};
+
+static void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
+{
+ const struct pin_index *index;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return;
+ }
+
+ gpio_bit_write(index->gpio, index->pin, (bit_status)value);
+}
+
+static int gd32_pin_read(rt_device_t dev, rt_base_t pin)
+{
+ int value;
+ const struct pin_index *index;
+
+ value = PIN_LOW;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return value;
+ }
+
+ value = gpio_input_bit_get(index->gpio, index->pin);
+
+ return value;
+}
+
+static void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
+{
+ const struct pin_index *index;
+ rt_uint32_t pin_mode;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return;
+ }
+
+ pin_mode = GPIO_MODE_OUT_PP;
+
+ switch (mode)
+ {
+ case PIN_MODE_OUTPUT:
+ /* output setting */
+ pin_mode = GPIO_MODE_OUT_PP;
+ break;
+ case PIN_MODE_OUTPUT_OD:
+ /* output setting: od. */
+ pin_mode = GPIO_MODE_OUT_OD;
+ break;
+ case PIN_MODE_INPUT:
+ /* input setting: not pull. */
+ pin_mode = GPIO_MODE_IN_FLOATING;
+ break;
+ case PIN_MODE_INPUT_PULLUP:
+ /* input setting: pull up. */
+ pin_mode = GPIO_MODE_IPU;
+ break;
+ case PIN_MODE_INPUT_PULLDOWN:
+ /* input setting: pull down. */
+ pin_mode = GPIO_MODE_IPD;
+ break;
+ default:
+ break;
+ }
+
+ gpio_init(index->gpio, pin_mode, GPIO_OSPEED_50MHZ, index->pin);
+}
+
+rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
+{
+ int i;
+ for (i = 0; i < 32; i++)
+ {
+ if ((0x01 << i) == bit)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
+{
+ rt_int32_t mapindex = bit2bitno(pinbit);
+ if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
+ {
+ return RT_NULL;
+ }
+ return &pin_irq_map[mapindex];
+};
+
+static rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
+ rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+ const struct pin_index *index;
+ rt_base_t level;
+ rt_int32_t irqindex = -1;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return RT_ENOSYS;
+ }
+ irqindex = bit2bitno(index->pin);
+ if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
+ {
+ return RT_ENOSYS;
+ }
+
+ level = rt_hw_interrupt_disable();
+ if (pin_irq_hdr_tab[irqindex].pin == pin &&
+ pin_irq_hdr_tab[irqindex].hdr == hdr &&
+ pin_irq_hdr_tab[irqindex].mode == mode &&
+ pin_irq_hdr_tab[irqindex].args == args)
+ {
+ rt_hw_interrupt_enable(level);
+ return RT_EOK;
+ }
+ if (pin_irq_hdr_tab[irqindex].pin != -1)
+ {
+ rt_hw_interrupt_enable(level);
+ return RT_EBUSY;
+ }
+ pin_irq_hdr_tab[irqindex].pin = pin;
+ pin_irq_hdr_tab[irqindex].hdr = hdr;
+ pin_irq_hdr_tab[irqindex].mode = mode;
+ pin_irq_hdr_tab[irqindex].args = args;
+ rt_hw_interrupt_enable(level);
+
+ return RT_EOK;
+}
+
+static rt_err_t gd32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
+{
+ const struct pin_index *index;
+ rt_base_t level;
+ rt_int32_t irqindex = -1;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return RT_ENOSYS;
+ }
+ irqindex = bit2bitno(index->pin);
+ if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
+ {
+ return RT_ENOSYS;
+ }
+
+ level = rt_hw_interrupt_disable();
+ if (pin_irq_hdr_tab[irqindex].pin == -1)
+ {
+ rt_hw_interrupt_enable(level);
+ return RT_EOK;
+ }
+ pin_irq_hdr_tab[irqindex].pin = -1;
+ pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
+ pin_irq_hdr_tab[irqindex].mode = 0;
+ pin_irq_hdr_tab[irqindex].args = RT_NULL;
+ rt_hw_interrupt_enable(level);
+
+ return RT_EOK;
+}
+
+static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
+ rt_uint32_t enabled)
+{
+ const struct pin_index *index;
+ const struct pin_irq_map *irqmap;
+ rt_base_t level;
+ rt_int32_t irqindex = -1;
+ exti_trig_type_enum trigger_mode;
+
+ index = get_pin(pin);
+ if (index == RT_NULL)
+ {
+ return RT_ENOSYS;
+ }
+
+ if (enabled == PIN_IRQ_ENABLE)
+ {
+ irqindex = bit2bitno(index->pin);
+ if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
+ {
+ return RT_ENOSYS;
+ }
+
+ level = rt_hw_interrupt_disable();
+
+ if (pin_irq_hdr_tab[irqindex].pin == -1)
+ {
+ rt_hw_interrupt_enable(level);
+ return RT_ENOSYS;
+ }
+
+ irqmap = &pin_irq_map[irqindex];
+
+ switch (pin_irq_hdr_tab[irqindex].mode)
+ {
+ case PIN_IRQ_MODE_RISING:
+ trigger_mode = EXTI_TRIG_RISING;
+ break;
+ case PIN_IRQ_MODE_FALLING:
+ trigger_mode = EXTI_TRIG_FALLING;
+ break;
+ case PIN_IRQ_MODE_RISING_FALLING:
+ trigger_mode = EXTI_TRIG_BOTH;
+ break;
+ default:
+ rt_hw_interrupt_enable(level);
+ return RT_EINVAL;
+ }
+ /* connect EXTI line to GPIO pin */
+ gpio_exti_source_select(index->gpio, index->pin);
+
+ /* configure EXTI line */
+ exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode);
+ exti_interrupt_flag_clear((exti_line_enum)(index->pin));
+
+ /* enable and set interrupt priority */
+ ECLIC_SetShvIRQ(irqmap->irqno, ECLIC_NON_VECTOR_INTERRUPT);
+ ECLIC_SetLevelIRQ(irqmap->irqno, 1);
+ ECLIC_EnableIRQ(irqmap->irqno);
+ pin_irq_enable_mask |= irqmap->pinbit;
+
+ rt_hw_interrupt_enable(level);
+ }
+ else if (enabled == PIN_IRQ_DISABLE)
+ {
+ irqmap = get_pin_irq_map(index->pin);
+ if (irqmap == RT_NULL)
+ {
+ return RT_EINVAL;
+ }
+ if ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9))
+ {
+ if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9)))
+ {
+ ECLIC_DisableIRQ(irqmap->irqno);
+ }
+ }
+ else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15))
+ {
+ if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
+ {
+ ECLIC_DisableIRQ(irqmap->irqno);
+ }
+ }
+ else
+ {
+ ECLIC_DisableIRQ(irqmap->irqno);
+ }
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+
+ return RT_EOK;
+}
+const static struct rt_pin_ops _gd32_pin_ops =
+{
+ gd32_pin_mode,
+ gd32_pin_write,
+ gd32_pin_read,
+ gd32_pin_attach_irq,
+ gd32_pin_dettach_irq,
+ gd32_pin_irq_enable,
+};
+
+rt_inline void pin_irq_hdr(int irqno)
+{
+ if (pin_irq_hdr_tab[irqno].hdr)
+ {
+ pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
+ }
+}
+
+void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line)
+{
+ if (RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line)))
+ {
+ pin_irq_hdr(exti_line);
+ exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line));
+ }
+}
+
+void EXTI0_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(0);
+ rt_interrupt_leave();
+}
+void EXTI1_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(1);
+ rt_interrupt_leave();
+}
+void EXTI2_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(2);
+ rt_interrupt_leave();
+}
+void EXTI3_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(3);
+ rt_interrupt_leave();
+}
+void EXTI4_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(4);
+ rt_interrupt_leave();
+}
+void EXTI5_9_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(5);
+ GD32_GPIO_EXTI_IRQHandler(6);
+ GD32_GPIO_EXTI_IRQHandler(7);
+ GD32_GPIO_EXTI_IRQHandler(8);
+ GD32_GPIO_EXTI_IRQHandler(9);
+ rt_interrupt_leave();
+}
+void EXTI10_15_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ GD32_GPIO_EXTI_IRQHandler(10);
+ GD32_GPIO_EXTI_IRQHandler(11);
+ GD32_GPIO_EXTI_IRQHandler(12);
+ GD32_GPIO_EXTI_IRQHandler(13);
+ GD32_GPIO_EXTI_IRQHandler(14);
+ GD32_GPIO_EXTI_IRQHandler(15);
+ rt_interrupt_leave();
+}
+
+int rt_hw_pin_init(void)
+{
+ rcu_periph_clock_enable(RCU_GPIOA);
+ rcu_periph_clock_enable(RCU_GPIOB);
+ rcu_periph_clock_enable(RCU_GPIOC);
+ rcu_periph_clock_enable(RCU_GPIOD);
+ rcu_periph_clock_enable(RCU_GPIOE);
+ rcu_periph_clock_enable(RCU_AF);
+ return rt_device_pin_register("pin", &_gd32_pin_ops, RT_NULL);
+}
+INIT_BOARD_EXPORT(rt_hw_pin_init);
+
+#endif /* RT_USING_PIN */
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.h
new file mode 100644
index 0000000000..93d24a8317
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_gpio.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-11-06 balanceTWK first version
+ * 2020-04-15 hqfang Modify for gd32vf103
+ */
+
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rthw.h>
+#include <drv_config.h>
+
+#define __GD32_PORT(port) GPIO##port
+
+#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__GD32_PORT(PORTx) - (rt_base_t)GPIOA)/(0x0400UL) )) + PIN)
+
+#define __GD32_PIN(index, gpio, gpio_index) \
+ { \
+ index, GPIO##gpio, GPIO_PIN_##gpio_index \
+ }
+
+#define __GD32_PIN_RESERVE \
+ { \
+ -1, 0, 0 \
+ }
+
+/* GD32 GPIO driver */
+struct pin_index
+{
+ int index;
+ uint32_t gpio;
+ uint32_t pin;
+};
+
+struct pin_irq_map
+{
+ rt_uint16_t pinbit;
+ IRQn_Type irqno;
+};
+
+int rt_hw_pin_init(void);
+
+#endif /* __DRV_GPIO_H__ */
+
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c
new file mode 100644
index 0000000000..00fac33b3e
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-23 tyustli first version
+ * 2020-04-02 hqfang modified for Nuclei
+ */
+
+#include <drv_usart.h>
+
+#ifdef RT_USING_SERIAL
+
+#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) \
+ && !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4)
+ #error "Please define at least one BSP_USING_UARTx"
+ /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
+#endif
+
+enum
+{
+#ifdef BSP_USING_UART0
+ GDUART0_INDEX,
+#endif
+#ifdef BSP_USING_UART1
+ GDUART1_INDEX,
+#endif
+#ifdef BSP_USING_UART2
+ GDUART2_INDEX,
+#endif
+#ifdef BSP_USING_UART3
+ GDUART3_INDEX,
+#endif
+#ifdef BSP_USING_UART4
+ GDUART4_INDEX,
+#endif
+};
+
+static struct gd32_uart_config uart_config[] =
+{
+#ifdef BSP_USING_UART0
+ {
+ "uart0",
+ USART0,
+ USART0_IRQn,
+ },
+#endif
+#ifdef BSP_USING_UART1
+ {
+ "uart1",
+ USART1,
+ USART1_IRQn,
+ },
+#endif
+#ifdef BSP_USING_UART2
+ {
+ "uart2",
+ USART2,
+ USART2_IRQn,
+ },
+#endif
+#ifdef BSP_USING_UART3
+ {
+ "uart3",
+ USART3,
+ USART3_IRQn,
+ },
+#endif
+#ifdef BSP_USING_UART4
+ {
+ "uart4",
+ UART4,
+ UART4_IRQn,
+ },
+#endif
+};
+
+static struct gd32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
+
+static rt_err_t gd32_configure(struct rt_serial_device *serial,
+ struct serial_configure *cfg)
+{
+ struct gd32_uart *usart_obj;
+ struct gd32_uart_config *usart;
+ RT_ASSERT(serial != RT_NULL);
+ RT_ASSERT(cfg != RT_NULL);
+
+ usart_obj = (struct gd32_uart *) serial->parent.user_data;
+ usart = usart_obj->config;
+ RT_ASSERT(usart != RT_NULL);
+
+ usart_deinit(usart->uart_base);
+ usart_baudrate_set(usart->uart_base, cfg->baud_rate);
+
+ switch (cfg->data_bits)
+ {
+ case DATA_BITS_8:
+ usart_word_length_set(usart->uart_base, USART_WL_8BIT);
+ break;
+
+ case DATA_BITS_9:
+ usart_word_length_set(usart->uart_base, USART_WL_9BIT);
+ break;
+ default:
+ usart_word_length_set(usart->uart_base, USART_WL_8BIT);
+ break;
+ }
+
+ switch (cfg->stop_bits)
+ {
+ case STOP_BITS_1:
+ usart_stop_bit_set(usart->uart_base, USART_STB_1BIT);
+ break;
+ case STOP_BITS_2:
+ usart_stop_bit_set(usart->uart_base, USART_STB_2BIT);
+ break;
+ default:
+ usart_stop_bit_set(usart->uart_base, USART_STB_1BIT);
+ break;
+ }
+
+ switch (cfg->parity)
+ {
+ case PARITY_NONE:
+ usart_parity_config(usart->uart_base, USART_PM_NONE);
+ break;
+ case PARITY_ODD:
+ usart_parity_config(usart->uart_base, USART_PM_ODD);
+ break;
+ case PARITY_EVEN:
+ usart_parity_config(usart->uart_base, USART_PM_EVEN);
+ break;
+ default:
+ usart_parity_config(usart->uart_base, USART_PM_NONE);
+ break;
+ }
+ usart_hardware_flow_rts_config(usart->uart_base, USART_RTS_DISABLE);
+ usart_hardware_flow_cts_config(usart->uart_base, USART_RTS_DISABLE);
+ usart_receive_config(usart->uart_base, USART_RECEIVE_ENABLE);
+ usart_transmit_config(usart->uart_base, USART_TRANSMIT_ENABLE);
+ usart_enable(usart->uart_base);
+
+ return RT_EOK;
+}
+
+static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd,
+ void *arg)
+{
+ struct gd32_uart *usart_obj;
+ struct gd32_uart_config *usart;
+
+ RT_ASSERT(serial != RT_NULL);
+ usart_obj = (struct gd32_uart *) serial->parent.user_data;
+ usart = usart_obj->config;
+ RT_ASSERT(usart != RT_NULL);
+
+ switch (cmd)
+ {
+ case RT_DEVICE_CTRL_CLR_INT:
+ ECLIC_DisableIRQ(usart->irqn);
+ usart_interrupt_disable(usart->uart_base, USART_INT_RBNE);
+ break;
+ case RT_DEVICE_CTRL_SET_INT:
+ ECLIC_EnableIRQ(usart->irqn);
+ /* enable USART0 receive interrupt */
+ usart_interrupt_enable(usart->uart_base, USART_INT_RBNE);
+ break;
+ }
+
+ return RT_EOK;
+}
+
+static int gd32_putc(struct rt_serial_device *serial, char ch)
+{
+ struct gd32_uart *usart_obj;
+ struct gd32_uart_config *usart;
+
+ RT_ASSERT(serial != RT_NULL);
+ usart_obj = (struct gd32_uart *) serial->parent.user_data;
+ usart = usart_obj->config;
+ RT_ASSERT(usart != RT_NULL);
+
+ usart_data_transmit(usart->uart_base, (uint8_t) ch);
+ while (usart_flag_get(usart->uart_base, USART_FLAG_TBE) == RESET);
+
+ return 1;
+}
+
+static int gd32_getc(struct rt_serial_device *serial)
+{
+ int ch;
+ struct gd32_uart *usart_obj;
+ struct gd32_uart_config *usart;
+
+ RT_ASSERT(serial != RT_NULL);
+ usart_obj = (struct gd32_uart *) serial->parent.user_data;
+ usart = usart_obj->config;
+ RT_ASSERT(usart != RT_NULL);
+
+ ch = -1;
+ if (RESET != usart_flag_get(usart->uart_base, USART_FLAG_RBNE))
+ {
+ ch = usart_data_receive(usart->uart_base) & 0xff;
+ }
+
+ return ch;
+}
+
+static const struct rt_uart_ops gd32_uart_ops = { gd32_configure, gd32_control,
+ gd32_putc, gd32_getc,
+ RT_NULL
+};
+
+static void usart_isr(struct rt_serial_device *serial)
+{
+ struct gd32_uart *usart_obj;
+ struct gd32_uart_config *usart;
+
+ RT_ASSERT(serial != RT_NULL);
+ usart_obj = (struct gd32_uart *) serial->parent.user_data;
+ usart = usart_obj->config;
+ RT_ASSERT(usart != RT_NULL);
+
+ if ((usart_interrupt_flag_get(usart->uart_base, USART_INT_FLAG_RBNE)
+ != RESET)
+ && (RESET != usart_flag_get(usart->uart_base, USART_FLAG_RBNE)))
+ {
+ rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+ usart_interrupt_flag_clear(usart->uart_base, USART_INT_FLAG_RBNE);
+ usart_flag_clear(usart->uart_base, USART_FLAG_RBNE);
+ }
+ else
+ {
+ if (usart_flag_get(usart->uart_base, USART_FLAG_CTSF) != RESET)
+ {
+ usart_flag_clear(usart->uart_base, USART_FLAG_CTSF);
+ }
+
+ if (usart_flag_get(usart->uart_base, USART_FLAG_LBDF) != RESET)
+ {
+ usart_flag_clear(usart->uart_base, USART_FLAG_LBDF);
+ }
+
+ if (usart_flag_get(usart->uart_base, USART_FLAG_TC) != RESET)
+ {
+ usart_flag_clear(usart->uart_base, USART_FLAG_TC);
+ }
+ }
+}
+
+#ifdef BSP_USING_UART0
+
+void USART0_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ usart_isr(&uart_obj[GDUART0_INDEX].serial);
+
+ rt_interrupt_leave();
+}
+
+#endif
+
+#ifdef BSP_USING_UART1
+
+void USART1_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ usart_isr(&uart_obj[GDUART1_INDEX].serial);
+
+ rt_interrupt_leave();
+}
+
+#endif
+
+#ifdef BSP_USING_UART2
+
+void USART2_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ usart_isr(&uart_obj[GDUART2_INDEX].serial);
+
+ rt_interrupt_leave();
+}
+
+#endif
+
+#ifdef BSP_USING_UART3
+
+void UART3_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ usart_isr(&uart_obj[GDUART3_INDEX].serial);
+
+ rt_interrupt_leave();
+}
+
+#endif
+
+#ifdef BSP_USING_UART4
+
+void UART4_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ usart_isr(&uart_obj[GDUART4_INDEX].serial);
+
+ rt_interrupt_leave();
+}
+
+#endif
+
+int rt_hw_usart_init(void)
+{
+ rt_size_t obj_num;
+ int index;
+
+ obj_num = sizeof(uart_obj) / sizeof(struct gd32_uart);
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ rt_err_t result = 0;
+
+ for (index = 0; index < obj_num; index++)
+ {
+ /* init UART object */
+ uart_obj[index].config = &uart_config[index];
+ uart_obj[index].serial.ops = &gd32_uart_ops;
+ uart_obj[index].serial.config = config;
+
+ /* register UART device */
+ result = rt_hw_serial_register(&uart_obj[index].serial,
+ uart_obj[index].config->name,
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
+ | RT_DEVICE_FLAG_INT_TX, &uart_obj[index]);
+ RT_ASSERT(result == RT_EOK);
+ }
+
+ return result;
+}
+
+#endif /* RT_USING_SERIAL */
+
+/******************** end of file *******************/
diff --git a/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h
new file mode 100644
index 0000000000..176720c4a2
--- /dev/null
+++ b/bsp/nuclei/libraries/gd32vf103/HAL_Drivers/drv_usart.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-04-15 hqfang first version
+ */
+#ifndef __DRV_UART_H__
+#define __DRV_UART_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drv_config.h>
+
+/* gd32 config class */
+struct gd32_uart_config
+{
+ const char *name;
+ uint32_t uart_base;
+ IRQn_Type irqn;
+};
+
+/* gd32 uart dirver class */
+struct gd32_uart
+{
+ struct gd32_uart_config *config;
+ struct rt_serial_device serial;
+};
+
+int rt_hw_usart_init(void);
+
+#endif /* __DRV_USART_H__ */
+
+/******************* end of file *******************/