/* * File : uart_dev.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006-2013, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rt-thread.org/license/LICENSE * * Change Logs: * Date Author Notes * 2009-01-05 Bernard the first version * 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode * 2013-05-13 aozima update for kehong-lingtai. */ #include "uart/uart.h" #include "uart_dev.h" #include "ae210p.h" #include "board.h" #include "bsp_hal.h" #include "rtdevice.h" #include "serial.h" #define UART_ENABLE_IRQ(n) hal_intc_irq_enable(n) #define UART_DISABLE_IRQ(n) hal_intc_irq_disable(n) struct uart_device { uint32_t uart_base; uint32_t irq; }; static rt_err_t __uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct uart_device *uartDev = RT_NULL; RT_ASSERT(serial != RT_NULL); RT_ASSERT(cfg != RT_NULL); uartDev = (struct uart_device *)serial->parent.user_data; __drv_uart_init(uartDev->uart_base, cfg->baud_rate); // todo : enable FIFO threshold, enable rx & rx timeout(threshold) interrupt return RT_EOK; } static rt_err_t __uart_control(struct rt_serial_device *serial, int cmd, void *arg) { struct uart_device *uartDev = RT_NULL; RT_ASSERT(serial != RT_NULL); uartDev = (struct uart_device *)serial->parent.user_data; switch (cmd) { case RT_DEVICE_CTRL_CLR_INT: /* disable rx irq */ UART_DISABLE_IRQ(uartDev->irq); break; case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */ UART_ENABLE_IRQ(uartDev->irq); break; default: break; } return RT_EOK; } static int __uart_putc(struct rt_serial_device *serial, char c) { struct uart_device *uartDev = RT_NULL; RT_ASSERT(serial != RT_NULL); uartDev = (struct uart_device *)serial->parent.user_data; __drv_uart_put_char(uartDev->uart_base, c); // Transmit Data return 1; } static int __uart_getc(struct rt_serial_device *serial) { int ch = -1; struct uart_device *uartDev = RT_NULL; RT_ASSERT(serial != RT_NULL); uartDev = (struct uart_device *)serial->parent.user_data; ch = -1; if (__drv_uart_is_kbd_hit(uartDev->uart_base)) { ch = __drv_uart_get_char(uartDev->uart_base) & 0x00FF; } return ch; } static const struct rt_uart_ops __uart_ops = { __uart_configure, __uart_control, __uart_putc, __uart_getc, RT_NULL }; #if RT_USING_UART01 struct uart_device uartDev01 = { // UART01 device driver structure UART1_BASE, IRQ_UART1_VECTOR }; struct rt_serial_device serial01; void URT01_IRQHandler(void) { struct uart_device *uartDev = RT_NULL; uartDev = &uartDev01; rt_interrupt_enter(); /* enter interrupt */ // if (uart->uart_device->Interrupt & ((1 << bsUART_TIMEOUT_INTENAB) | (1 << bsUART_RECEIVE_INTENAB))) // RX // { // rt_hw_serial_isr(&serial01, RT_SERIAL_EVENT_RX_IND); // } // // if (uart->uart_device->Interrupt & (1 << bsUART_TRANSMIT_INTENAB)) // TX // { // ; // } // // /* clear all interrupt */ // uart->uart_device->IntClear = (1 << bsUART_RECEIVE_INTENAB) // | (1 << bsUART_TRANSMIT_INTENAB) // | (1 << bsUART_TIMEOUT_INTENAB); rt_interrupt_leave(); /* leave interrupt */ } #endif /* RT_USING_UART01 */ #if RT_USING_UART02 struct uart_device uartDev02 = { // UART02 device driver structure UART2_BASE, IRQ_UATR2_VECTOR }; struct rt_serial_device serial02; void URT02_IRQHandler(void) { struct uart_device *uartDev = RT_NULL; uartDev = &uartDev02; rt_interrupt_enter(); /* enter interrupt */ uartDev = uartDev; rt_interrupt_leave(); /* leave interrupt */ } #endif /* RT_USING_UART02 */ void rt_hw_usart_init(void) { struct uart_device *uartDev = RT_NULL; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; #if RT_USING_UART01 uart = &uartDev01; config.baud_rate = BAUD_RATE_38400; serial01.ops = &__uart_ops; serial01.config = config; // set interrupt priority level // disable interrupt // register UART01 device rt_hw_serial_register(&serial01, "uart01", RT_DEVICE_FLAG_RDWR /*| RT_DEVICE_FLAG_INT_RX*/, uartDev); #endif /* RT_USING_UART01 */ #if RT_USING_UART02 uartDev = &uartDev02; config.baud_rate = BAUD_RATE_38400; serial02.ops = &__uart_ops; serial02.config = config; // set interrupt priority level // disable interrupt /* register UART02 device */ rt_hw_serial_register(&serial02, "uart02", RT_DEVICE_FLAG_RDWR /*| RT_DEVICE_FLAG_INT_RX*/, uartDev); #endif /* RT_USING_UART02 */ }