diff options
Diffstat (limited to 'bsp/nuclei/libraries')
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 *******************/ |
