#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 */ static rt_err_t CME_M7_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct CME_M7_uart* uart; UART_InitTypeDef init; RT_ASSERT(serial != RT_NULL); RT_ASSERT(cfg != RT_NULL); uart = (struct CME_M7_uart *)serial->parent.user_data; init.UART_BaudRate = cfg->baud_rate; init.UART_StopBits = UART_StopBits_1; init.UART_Parity = UART_Parity_None; init.UART_LoopBack = FALSE; init.UART_RxEn = TRUE; init.UART_CtsEn = FALSE; UART_Init(uart->uart_device, &init); uart->uart_device->RX_RESET = 1; UART_Enable(uart->uart_device, TRUE); uart->uart_device->RX_RESET = 0; return RT_EOK; } static rt_err_t CME_M7_control(struct rt_serial_device *serial, int cmd, void *arg) { struct CME_M7_uart* uart; NVIC_InitTypeDef NVIC_InitStructure; 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 */ NVIC_InitStructure.NVIC_IRQChannel = uart->irq; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; NVIC_Init(&NVIC_InitStructure); UART_EnableInt(uart->uart_device, UART_Int_RxNotEmpty, FALSE); break; case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */ NVIC_InitStructure.NVIC_IRQChannel = uart->irq; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; NVIC_Init(&NVIC_InitStructure); UART_ClearInt(uart->uart_device, UART_Int_RxNotEmpty); UART_EnableInt(uart->uart_device, UART_Int_RxNotEmpty, TRUE); break; } return RT_EOK; } static int CME_M7_putc(struct rt_serial_device *serial, char ch) { struct CME_M7_uart* uart; RT_ASSERT(serial != RT_NULL); uart = (struct CME_M7_uart *)serial->parent.user_data; while(uart->uart_device->STATUS_b.TF); //waits for transmitter FIFO not full. uart->uart_device->TX_BUF = ch; return 1; } static int CME_M7_getc(struct rt_serial_device *serial) { int ch; struct CME_M7_uart* uart; RT_ASSERT(serial != RT_NULL); uart = (struct CME_M7_uart *)serial->parent.user_data; ch = -1; if(uart->uart_device->STATUS_b.RNE) { ch = uart->uart_device->RX_BUF & 0x00FF; /* Get Data from UART RX */ } return ch; } static const struct rt_uart_ops CME_M7_uart_ops = { CME_M7_configure, CME_M7_control, CME_M7_putc, CME_M7_getc, }; int rt_hw_uart_init(void) { struct CME_M7_uart* uart; struct rt_serial_device *serial; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; #ifdef RT_USING_UART0 uart = &uart0; serial = &serial0; serial->ops = &CME_M7_uart_ops; serial->config = config; /* register UART device */ rt_hw_serial_register(serial, "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; /* register UART device */ rt_hw_serial_register(serial, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); #endif /* RT_USING_UART2 */ return RT_EOK; } INIT_BOARD_EXPORT(rt_hw_uart_init); 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); } } #ifdef RT_USING_UART0 void UART0_IRQHandler(void) { CME_UART_IRQHandler(&serial0); } #endif /* RT_USING_UART0 */ #ifdef RT_USING_UART2 void UART2_IRQHandler(void) { CME_UART_IRQHandler(&serial2); } #endif /* RT_USING_UART2 */