Huaqi Fang 7761923ec5 bsp/nuclei: Add more drivers support for gd32vf103_rvstar board
Squashed commit of the following:

commit 32dd349ccff85cdcad81021b5185f8f7347786db
Author: Huaqi Fang <578567190@qq.com>
Date:   Thu Jun 11 16:08:08 2020 +0800

    bsp/nuclei: Add more documentation about how to use RT-Thread in RV-STAR

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit c9474c20a558e9d7934a3d72cc9bb17a98c20871
Author: Huaqi Fang <578567190@qq.com>
Date:   Thu Jun 11 14:06:42 2020 +0800

    bsp/nuclei: remove comments in rt_hw_*_drvinit

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit 89b5caa2c3e55dc352b13f8e33229f03351b7049
Author: Huaqi Fang <578567190@qq.com>
Date:   Thu Jun 11 13:52:12 2020 +0800

    bsp/nuclei: Add a entry README.md for nuclei bsp

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit ae50d6e9bdc92ca4767c5ac7d0ded7252314a42e
Author: Huaqi Fang <578567190@qq.com>
Date:   Thu Jun 11 11:52:52 2020 +0800

    bsp/nuclei: update README.md cover more pinmux section

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit 1a42d85dfe5bc7b009f057784249d54d0c82de0f
Author: Huaqi Fang <578567190@qq.com>
Date:   Thu Jun 11 08:52:06 2020 +0800

    bsp/nuclei: clean up unused code in drv_spi.c

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit b40edcdf59c96ef261f65a0c023a24ac78cabb39
Author: Huaqi Fang <578567190@qq.com>
Date:   Wed Jun 10 14:09:15 2020 +0800

    bsp/nuclei: Format the code comments for hw pinmux init

    Signed-off-by: Huaqi Fang <578567190@qq.com>

commit c8ae9fdfdb989bbff85d911fee3124abd9d145db
Author: Huaqi Fang <578567190@qq.com>
Date:   Mon Jun 8 17:12:43 2020 +0800

    bsp/nuclei: Add more drivers support for gd32vf103

    * More drivers are supported for rvstar board, see README.md
    * If user want to use these supported drivers, menuconfig is required
    * User also need to setup pinmux for its coresponding driver in
    board/board.c

    Signed-off-by: Huaqi Fang <578567190@qq.com>

Signed-off-by: Huaqi Fang <578567190@qq.com>
2020-06-16 09:35:58 +08:00

364 lines
8.3 KiB
C

/*
* 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 -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable UART */
#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",
UART3,
UART3_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_CTS_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;
#ifdef BSP_USING_UART0
rcu_periph_clock_enable(RCU_USART0);
#endif
#ifdef BSP_USING_UART1
rcu_periph_clock_enable(RCU_USART1);
#endif
#ifdef BSP_USING_UART2
rcu_periph_clock_enable(RCU_USART2);
#endif
#ifdef BSP_USING_UART3
rcu_periph_clock_enable(RCU_UART3);
#endif
#ifdef BSP_USING_UART4
rcu_periph_clock_enable(RCU_UART4);
#endif
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 *******************/