/* * File : board.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2009 RT-Thread Develop 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 * 2010-03-08 Bernard The first version for LPC17xx * 2010-04-10 fify Modified for M16C */ #include #include #include "iom16c62p.h" #include "bsp.h" #include "uart.h" #if defined(RT_USING_UART0) && defined(RT_USING_DEVICE) struct rt_uart_m16c { struct rt_device parent; /* buffer for reception */ rt_uint8_t read_index, save_index; rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; }uart_device; void u0rec_handler(void) { rt_ubase_t level; rt_uint8_t c; struct rt_uart_m16c* uart = &uart_device; while(ri_u0c1 == 0) ; c = (char) u0rb; /* Receive Data Available */ uart->rx_buffer[uart->save_index] = c; level = rt_hw_interrupt_disable(); uart->save_index ++; if (uart->save_index >= RT_UART_RX_BUFFER_SIZE) uart->save_index = 0; rt_hw_interrupt_enable(level); /* invoke callback */ if(uart->parent.rx_indicate != RT_NULL) { rt_size_t length; if (uart->read_index > uart->save_index) length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index; else length = uart->save_index - uart->read_index; uart->parent.rx_indicate(&uart->parent, length); } } static rt_err_t rt_uart_init (rt_device_t dev) { rt_uint32_t level; /* set UART0 bit rate generator bit rate can be calculated by: bit rate = ((BRG count source / 16)/baud rate) - 1 Baud rate is based on main crystal or PLL not CPU core clock */ //pclk1 = 1; /// seleck F1SIO u0brg = (unsigned char)(((CPU_CLK_FREQ/16)/BAUD_RATE)-1); //(N+1) /* UART Transmit/Receive Control Register 2 */ ucon = 0x00; /* 00000000 b0 U0IRS UART0 transmit irq cause select bit, 0 = transmit buffer empty b1 U1IRS UART1 transmit irq cause select bit, 0 = transmit buffer empty b2 U0RRM UART0 continuous receive mode enable bit, set to 0 in UART mode b3 U1RRM UART1 continuous receive mode enable bit, set to 0 in UART mode b4 CLKMD0 CLK/CLKS select bit 0, set to 0 in UART mode b5 CLKMD1 CLK/CLKS select bit 1, set to 0 in UART mode b6 RCSP Separate CTS/RTS bit, b7 Reserved, set to 0 */ /* UART0 transmit/receive control register 0 */ /* f1 count source, CTS/RTS disabled, CMOS output */ u0c0 = 0x10; /* 00010000 b1:b0 CLK01:CLK0 BRG count source select bits //01 F8SIO b2 CRS CTS/RTS function select bit b3 TXEPT Transmit register empty flag b4 CRD CTS/RTS disable bit b5 NCH Data output select bit b6 CKPOL CLK polarity select bit,set to 0 in UART mode b7 UFORM Transfer format select bit,set to 0 in UART mode */ /* UART0 transmit/receive control register 1 */ /* disable transmit and receive, no error output pin, data not inverted */ u0c1 = 0x00; /* 00000000 b0 TE Transmit enable bit b1 TI Transmit buffer empty flag b2 RE Receive enable bit b3 RI Receive complete flag b5:b4 Reserved, set to 0 b6 UOLCH Data logic select bit b7 UOERE Error signal output enable bit */ /* UART0 transmit/receive mode register */ /* 8-bit data,asynch mode, internal clock, 1 stop bit, no parity */ u0mr = 0x05; /* 00000101 b2:b0 SMD12:SMD1 Serial I/O Mode select bits b3 CKDIR Internal/External clock select bit, CKDIR b4 STPS Stop bit length select bit, STPS b5 PRY Odd/even parity select bit, PRY b6 PRYE Parity enable bit, PRYE b7 IOPOL TxD, RxD I/O polarity reverse bit */ /* clear UART0 receive buffer by reading */ u0tb = u0rb; /* clear UART0 transmit buffer */ u0tb = 0; /* disable irqs before setting irq registers */ level = rt_hw_interrupt_disable(); /* Enable UART0 receive interrupt, priority level 4 */ s0ric = 0x04; /* Enable all interrupts */ rt_hw_interrupt_enable(level); /* UART0 transmit/receive control register 1 */ /* enable transmit and receive */ u0c1 = 0x05; /* 00000101 enable transmit and receive b0 TE Transmit enable bit b1 TI Transmit buffer empty flag b2 RE Receive enable bit b3 RI Receive complete flag b5:b4 Reserved, set to 0 b6 UOLCH Data logic select bit b7 UOERE Error signal output enable bit */ return RT_EOK; } static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag) { RT_ASSERT(dev != RT_NULL); if (dev->flag & RT_DEVICE_FLAG_INT_RX) { /* Enable the UART Interrupt */ } return RT_EOK; } static rt_err_t rt_uart_close(rt_device_t dev) { RT_ASSERT(dev != RT_NULL); if (dev->flag & RT_DEVICE_FLAG_INT_RX) { /* Disable the UART Interrupt */ } return RT_EOK; } static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_uint8_t* ptr; struct rt_uart_m16c *uart = (struct rt_uart_m16c*)dev; RT_ASSERT(uart != RT_NULL); /* point to buffer */ ptr = (rt_uint8_t*) buffer; if (dev->flag & RT_DEVICE_FLAG_INT_RX) { while (size) { /* interrupt receive */ rt_base_t level; /* disable interrupt */ level = rt_hw_interrupt_disable(); if (uart->read_index != uart->save_index) { *ptr = uart->rx_buffer[uart->read_index]; uart->read_index ++; if (uart->read_index >= RT_UART_RX_BUFFER_SIZE) uart->read_index = 0; } else { /* no data in rx buffer */ /* enable interrupt */ rt_hw_interrupt_enable(level); break; } /* enable interrupt */ rt_hw_interrupt_enable(level); ptr ++; size --; } return (rt_uint32_t)ptr - (rt_uint32_t)buffer; } return 0; } static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { char *ptr; ptr = (char*)buffer; if (dev->flag & RT_DEVICE_FLAG_STREAM) { /* stream mode */ while (size) { if (*ptr == '\n') { while(ti_u0c1 == 0) ; u0tb = '\r'; } /* THRE status, contain valid data */ while(ti_u0c1 == 0) ; u0tb = *ptr; ptr ++; size --; } } else { while ( size != 0 ) { /* THRE status, contain valid data */ while(ti_u0c1 == 0) ; u0tb = *ptr; ptr++; size--; } } return (rt_size_t) ptr - (rt_size_t) buffer; } void rt_hw_uart_init(void) { struct rt_uart_m16c* uart; /* get uart device */ uart = &uart_device; /* device initialization */ uart->parent.type = RT_Device_Class_Char; rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer)); uart->read_index = uart->save_index = 0; /* device interface */ uart->parent.init = rt_uart_init; uart->parent.open = rt_uart_open; uart->parent.close = rt_uart_close; uart->parent.read = rt_uart_read; uart->parent.write = rt_uart_write; uart->parent.control = RT_NULL; uart->parent.private = RT_NULL; rt_device_register(&uart->parent, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX); } #endif /* end of UART */ /*@}*/