rt-thread-official/bsp/CME_M7/drivers/uart.c

218 lines
5.2 KiB
C
Raw Normal View History

2014-08-30 00:19:16 +08:00
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/* CME-M7 uart driver */
struct CME_M7_uart
{
UART0_Type* uart_device;
IRQn_Type irq;
};
#ifdef RT_USING_UART0
struct CME_M7_uart uart0 =
{
UART0,
UART0_INT_IRQn,
};
static struct rt_serial_device serial0;
#endif /* RT_USING_UART0 */
#ifdef RT_USING_UART2
struct CME_M7_uart uart2 =
{
UART2,
UART2_INT_IRQn,
};
static struct rt_serial_device serial2;
#endif /* RT_USING_UART2 */
2014-09-21 21:46:50 +08:00
static rt_err_t CME_M7_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
2014-08-30 00:19:16 +08:00
{
struct CME_M7_uart* uart;
2022-01-09 20:19:55 +08:00
UART_InitTypeDef init;
2014-08-30 00:19:16 +08:00
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = (struct CME_M7_uart *)serial->parent.user_data;
2022-01-09 20:19:55 +08:00
init.UART_BaudRate = cfg->baud_rate;
init.UART_StopBits = UART_StopBits_1;
2014-08-30 00:19:16 +08:00
init.UART_Parity = UART_Parity_None;
2022-01-09 20:19:55 +08:00
init.UART_LoopBack = FALSE;
init.UART_RxEn = TRUE;
init.UART_CtsEn = FALSE;
2014-08-30 00:19:16 +08:00
UART_Init(uart->uart_device, &init);
2014-09-21 21:46:50 +08:00
uart->uart_device->RX_RESET = 1;
2022-01-09 20:19:55 +08:00
UART_Enable(uart->uart_device, TRUE);
2014-09-21 21:46:50 +08:00
uart->uart_device->RX_RESET = 0;
2014-08-30 00:19:16 +08:00
return RT_EOK;
}
2014-09-21 21:46:50 +08:00
static rt_err_t CME_M7_control(struct rt_serial_device *serial, int cmd, void *arg)
2014-08-30 00:19:16 +08:00
{
struct CME_M7_uart* uart;
2014-09-21 21:46:50 +08:00
NVIC_InitTypeDef NVIC_InitStructure;
2014-08-30 00:19:16 +08:00
RT_ASSERT(serial != RT_NULL);
uart = (struct CME_M7_uart *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* disable rx irq */
2014-09-21 21:46:50 +08:00
NVIC_InitStructure.NVIC_IRQChannel = uart->irq;
2022-01-09 20:19:55 +08:00
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE;
NVIC_Init(&NVIC_InitStructure);
2014-09-21 21:46:50 +08:00
2022-01-09 20:19:55 +08:00
UART_EnableInt(uart->uart_device, UART_Int_RxNotEmpty, FALSE);
2014-08-30 00:19:16 +08:00
break;
case RT_DEVICE_CTRL_SET_INT:
/* enable rx irq */
2014-09-21 21:46:50 +08:00
NVIC_InitStructure.NVIC_IRQChannel = uart->irq;
2022-01-09 20:19:55 +08:00
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE;
NVIC_Init(&NVIC_InitStructure);
2014-09-21 21:46:50 +08:00
2022-01-09 20:19:55 +08:00
UART_ClearInt(uart->uart_device, UART_Int_RxNotEmpty);
UART_EnableInt(uart->uart_device, UART_Int_RxNotEmpty, TRUE);
2014-08-30 00:19:16 +08:00
break;
}
return RT_EOK;
}
2014-09-21 21:46:50 +08:00
static int CME_M7_putc(struct rt_serial_device *serial, char ch)
2014-08-30 00:19:16 +08:00
{
struct CME_M7_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct CME_M7_uart *)serial->parent.user_data;
2014-09-21 21:46:50 +08:00
while(uart->uart_device->STATUS_b.TF); //waits for transmitter FIFO not full.
uart->uart_device->TX_BUF = ch;
2014-08-30 00:19:16 +08:00
return 1;
}
2014-09-21 21:46:50 +08:00
static int CME_M7_getc(struct rt_serial_device *serial)
2014-08-30 00:19:16 +08:00
{
int ch;
struct CME_M7_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct CME_M7_uart *)serial->parent.user_data;
ch = -1;
2014-09-21 21:46:50 +08:00
if(uart->uart_device->STATUS_b.RNE)
{
ch = uart->uart_device->RX_BUF & 0x00FF; /* Get Data from UART RX */
}
2014-08-30 00:19:16 +08:00
return ch;
}
static const struct rt_uart_ops CME_M7_uart_ops =
{
2014-09-21 21:46:50 +08:00
CME_M7_configure,
CME_M7_control,
CME_M7_putc,
CME_M7_getc,
2014-08-30 00:19:16 +08:00
};
int rt_hw_uart_init(void)
{
2022-01-09 20:19:55 +08:00
struct CME_M7_uart* uart;
struct rt_serial_device *serial;
2014-08-30 00:19:16 +08:00
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef RT_USING_UART0
uart = &uart0;
2014-09-21 21:46:50 +08:00
serial = &serial0;
2014-08-30 00:19:16 +08:00
2014-09-21 21:46:50 +08:00
serial->ops = &CME_M7_uart_ops;
serial->config = config;
2014-08-30 00:19:16 +08:00
2022-01-09 20:19:55 +08:00
/* register UART device */
2014-09-21 21:46:50 +08:00
rt_hw_serial_register(serial,
2014-08-30 00:19:16 +08:00
"uart0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
#endif /* RT_USING_UART0 */
#ifdef RT_USING_UART2
uart = &uart2;
serial = &serial2;
serial->ops = &CME_M7_uart_ops;
serial->config = config;
2022-01-09 20:19:55 +08:00
/* register UART device */
2014-08-30 00:19:16 +08:00
rt_hw_serial_register(serial,
"uart2",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
#endif /* RT_USING_UART2 */
2022-01-09 20:19:55 +08:00
return RT_EOK;
2014-08-30 00:19:16 +08:00
}
INIT_BOARD_EXPORT(rt_hw_uart_init);
2014-09-21 21:46:50 +08:00
static void CME_UART_IRQHandler(struct rt_serial_device *serial)
{
struct CME_M7_uart* uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct CME_M7_uart *)serial->parent.user_data;
if(UART_GetIntStatus(uart->uart_device, UART_Int_RxNotEmpty))
{
UART_ClearInt(uart->uart_device, UART_Int_RxNotEmpty);
rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
}
if(UART_GetIntStatus(uart->uart_device, UART_Int_RxThresholdReach))
{
UART_ClearInt(uart->uart_device, UART_Int_RxThresholdReach);
}
if(UART_GetIntStatus(uart->uart_device, UART_Int_OverrunError))
{
UART_ClearInt(uart->uart_device, UART_Int_OverrunError);
}
if(UART_GetIntStatus(uart->uart_device, UART_Int_FrameError))
{
UART_ClearInt(uart->uart_device, UART_Int_FrameError);
}
if(UART_GetIntStatus(uart->uart_device, UART_Int_ParityError))
{
UART_ClearInt(uart->uart_device, UART_Int_ParityError);
}
}
2014-08-30 00:19:16 +08:00
#ifdef RT_USING_UART0
void UART0_IRQHandler(void)
{
2014-09-21 21:46:50 +08:00
CME_UART_IRQHandler(&serial0);
2014-08-30 00:19:16 +08:00
}
#endif /* RT_USING_UART0 */
#ifdef RT_USING_UART2
void UART2_IRQHandler(void)
{
2014-09-21 21:46:50 +08:00
CME_UART_IRQHandler(&serial2);
2014-08-30 00:19:16 +08:00
}
#endif /* RT_USING_UART2 */