From 885301bb14f34e840beb14ca2ee1b7b28012e294 Mon Sep 17 00:00:00 2001 From: weety Date: Sun, 21 Jul 2013 15:01:42 +0800 Subject: [PATCH] =?UTF-8?q?update=20AT91SAM9260=20usart=20driver=EF=BC=8C?= =?UTF-8?q?=20using=20serial=20driver=20component.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/at91sam9260/SConscript | 2 +- bsp/at91sam9260/board.c | 223 +-------------- bsp/at91sam9260/board.h | 2 - bsp/at91sam9260/console.c | 180 ------------ bsp/at91sam9260/rtconfig.h | 20 +- bsp/at91sam9260/startup.c | 57 +--- bsp/at91sam9260/usart.c | 413 +++++++++++++++++++++++++++ libcpu/arm/at91sam926x/at91sam926x.h | 3 +- libcpu/arm/at91sam926x/serial.c | 282 ------------------ libcpu/arm/at91sam926x/serial.h | 76 ----- 10 files changed, 436 insertions(+), 822 deletions(-) delete mode 100755 bsp/at91sam9260/console.c create mode 100644 bsp/at91sam9260/usart.c delete mode 100755 libcpu/arm/at91sam926x/serial.c delete mode 100755 libcpu/arm/at91sam926x/serial.h diff --git a/bsp/at91sam9260/SConscript b/bsp/at91sam9260/SConscript index 4fe0f874fc..c754911e9d 100755 --- a/bsp/at91sam9260/SConscript +++ b/bsp/at91sam9260/SConscript @@ -3,7 +3,7 @@ Import('RTT_ROOT') from building import * src_bsp = ['application.c', 'startup.c', 'board.c'] -src_drv = ['console.c'] +src_drv = ['usart.c'] if GetDepend('RT_USING_LED'): src_drv += ['led.c'] diff --git a/bsp/at91sam9260/board.c b/bsp/at91sam9260/board.c index 1ea8bfa5c6..81f156d158 100755 --- a/bsp/at91sam9260/board.c +++ b/bsp/at91sam9260/board.c @@ -29,218 +29,7 @@ extern void rt_hw_mmu_init(void); extern void rt_hw_get_clock(void); extern void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn); extern void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv); - -/*set debug serial port*/ -//#define USE_UART1 -//#define USE_UART3 -//#define USE_DBGU - -#define DBGU ((struct uartport *)0xfffff200) -#define UART0 ((struct uartport *)AT91SAM9260_BASE_US0) -#define UART1 ((struct uartport *)AT91SAM9260_BASE_US1) -#define UART2 ((struct uartport *)AT91SAM9260_BASE_US2) -#define UART3 ((struct uartport *)AT91SAM9260_BASE_US3) -#define UART4 ((struct uartport *)AT91SAM9260_BASE_US4) -#define UART5 ((struct uartport *)AT91SAM9260_BASE_US5) - -struct serial_int_rx uart0_int_rx; -struct serial_device uart0 = -{ - DBGU, - &uart0_int_rx, - RT_NULL -}; -struct rt_device uart0_device; - -struct serial_int_rx uart1_int_rx; -struct serial_device uart1 = -{ - UART0, - &uart1_int_rx, - RT_NULL -}; -struct rt_device uart1_device; - -struct serial_int_rx uart2_int_rx; -struct serial_device uart2 = -{ - UART1, - &uart2_int_rx, - RT_NULL -}; -struct rt_device uart2_device; - -struct serial_int_rx uart3_int_rx; -struct serial_device uart3 = -{ - UART2, - &uart3_int_rx, - RT_NULL -}; -struct rt_device uart3_device; - -struct serial_int_rx uart4_int_rx; -struct serial_device uart4 = -{ - UART3, - &uart4_int_rx, - RT_NULL -}; -struct rt_device uart4_device; - - -/** - * This function will handle serial - */ -void rt_serial_handler(int vector, void *param) -{ - int status; - struct rt_device *dev = (rt_device_t)param; - - switch (vector) - { - #ifdef RT_USING_UART0 - case AT91SAM9260_ID_US0: - status = readl(AT91SAM9260_BASE_US0+AT91_US_CSR); - if (!(status & readl(AT91SAM9260_BASE_US0+AT91_US_IMR))) - { - return; - } - rt_hw_serial_isr(dev); - break; - #endif - #ifdef RT_USING_UART1 - case AT91SAM9260_ID_US1: - status = readl(AT91SAM9260_BASE_US1+AT91_US_CSR); - if (!(status & readl(AT91SAM9260_BASE_US1+AT91_US_IMR))) - { - return; - } - rt_hw_serial_isr(dev); - break; - #endif - #ifdef RT_USING_UART2 - case AT91SAM9260_ID_US2: - status = readl(AT91SAM9260_BASE_US2+AT91_US_CSR); - if (!(status & readl(AT91SAM9260_BASE_US2+AT91_US_IMR))) - { - return; - } - rt_hw_serial_isr(dev); - break; - #endif - #ifdef RT_USING_UART3 - case AT91SAM9260_ID_US3: - status = readl(AT91SAM9260_BASE_US3+AT91_US_CSR); - if (!(status & readl(AT91SAM9260_BASE_US3+AT91_US_IMR))) - { - return; - } - rt_hw_serial_isr(dev); - break; - #endif - default: break; - } - -} - -void uart_port_init(rt_uint32_t base) -{ - #define BAUDRATE 115200 - rt_uint32_t cd; - - writel(AT91_US_RSTTX | AT91_US_RSTRX | - AT91_US_RXDIS | AT91_US_TXDIS, - base + AT91_US_CR); - writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | - AT91_US_CHRL_8 | AT91_US_PAR_NONE | - AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL, - base + AT91_US_MR); - cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE; - writel(cd, base + AT91_US_BRGR); - writel(AT91_US_RXEN | AT91_US_TXEN, base + AT91_US_CR); - - writel(0x1, base + AT91_US_IER); -} - -/** - * This function will handle init uart - */ -void rt_hw_uart_init(void) -{ -#ifdef RT_USING_UART0 - at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US0); - at91_sys_write(AT91_PIOB + PIO_IDR, (1<<4)|(1<<5)); - at91_sys_write(AT91_PIOB + PIO_PUER, (1<<4)); - at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<5)); - at91_sys_write(AT91_PIOB + PIO_ASR, (1<<4)|(1<<5)); - at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5)); - uart_port_init(AT91SAM9260_BASE_US0); - /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, - (void *)&uart1_device, "UART0"); - rt_hw_interrupt_umask(AT91SAM9260_ID_US0); -#endif -#ifdef RT_USING_UART1 - at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1); - at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7)); - at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6)); - at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7)); - at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7)); - at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7)); - uart_port_init(AT91SAM9260_BASE_US1); - /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, - (void *)&uart2_device, "UART1"); - rt_hw_interrupt_umask(AT91SAM9260_ID_US1); -#endif -#ifdef RT_USING_UART2 - at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US2); - at91_sys_write(AT91_PIOB + PIO_IDR, (1<<8)|(1<<9)); - at91_sys_write(AT91_PIOB + PIO_PUER, (1<<8)); - at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<9)); - at91_sys_write(AT91_PIOB + PIO_ASR, (1<<8)|(1<<9)); - at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9)); - uart_port_init(AT91SAM9260_BASE_US2); - /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, - (void *)&uart3_device, "UART2"); - rt_hw_interrupt_umask(AT91SAM9260_ID_US2); -#endif -#ifdef RT_USING_UART3 - at91_sys_write(AT91_PMC_PCER, 1<> 20) @@ -254,12 +43,13 @@ static rt_uint32_t pit_cnt; /* access only w/system irq blocked */ void rt_timer_handler(int vector, void *param) { #ifdef RT_USING_DBGU - if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) { - //rt_kprintf("DBGU interrupt occur\n"); - rt_hw_serial_isr(&uart0_device); + if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) + { + rt_dbgu_isr(); } #endif - if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { + if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) + { unsigned nr_ticks; /* Get number of ticks performed before irq, and ack it */ @@ -339,6 +129,7 @@ void rt_hw_board_init() /* initialize uart */ rt_hw_uart_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); /* initialize mmu */ rt_hw_mmu_init(); diff --git a/bsp/at91sam9260/board.h b/bsp/at91sam9260/board.h index 39764aff39..59992480ed 100755 --- a/bsp/at91sam9260/board.h +++ b/bsp/at91sam9260/board.h @@ -16,9 +16,7 @@ #define __BOARD_H__ #include -#include void rt_hw_board_init(void); -//void rt_hw_sdcard_init(void); #endif diff --git a/bsp/at91sam9260/console.c b/bsp/at91sam9260/console.c deleted file mode 100755 index 03836fb014..0000000000 --- a/bsp/at91sam9260/console.c +++ /dev/null @@ -1,180 +0,0 @@ -#include - -#include - -#define RT_CONSOLE_WIDTH 240 -#define RT_CONSOLE_HEIGHT 320 - -#define RT_CONSOLE_FONT_WIDTH 8 -#define RT_CONSOLE_FONT_HEIGHT 16 - -#define RT_CONSOLE_COL (RT_CONSOLE_WIDTH/RT_CONSOLE_FONT_WIDTH) -#define RT_CONSOLE_ROW (RT_CONSOLE_HEIGHT/RT_CONSOLE_FONT_HEIGHT) - -#define RT_CONSOLE_TAB 4 - -#define RT_CONSOLE_FOREPIXEL (0x001f) - -extern struct serial_device uart0; - -struct rt_console -{ - rt_uint8_t* video_ptr; - rt_uint8_t* font_ptr; - - /* bpp and pixel of width */ - rt_uint8_t bpp; - rt_uint32_t pitch; - - /* current cursor */ - rt_uint8_t current_col; - rt_uint8_t current_row; -}; -struct rt_console console; - -void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp); -void rt_hw_console_newline(void); -void rt_hw_console_putc(char c); -void rt_hw_console_clear(void); - -void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp) -{ - rt_memset(&console, 0, sizeof(struct rt_console)); - - console.video_ptr = video_ptr; - console.font_ptr = font_ptr; - console.bpp = bpp; - console.pitch = console.bpp * RT_CONSOLE_WIDTH; - - rt_hw_console_clear(); -} - -void rt_hw_console_putc(char c) -{ - switch (c) - { - case 10: - case 11: - case 12: - case 13: - /* to next line */ - rt_hw_console_newline(); - console.current_col = 0; - break; - - case 9: - console.current_col += RT_CONSOLE_TAB; - break; - - default: - { - rt_uint8_t* font_ptr; - register rt_uint32_t cursor; - register rt_uint32_t i, j; - - if (console.current_col == RT_CONSOLE_COL) - { - rt_hw_console_newline(); - console.current_col = 0; - - rt_hw_console_putc(c); - return; - } - - font_ptr = console.font_ptr + c * RT_CONSOLE_FONT_HEIGHT; - cursor = (console.current_row * RT_CONSOLE_FONT_HEIGHT) * console.pitch - + console.current_col * RT_CONSOLE_FONT_WIDTH * console.bpp; - - for (i = 0; i < RT_CONSOLE_FONT_HEIGHT; i ++ ) - { - for (j = 0; j < RT_CONSOLE_FONT_WIDTH; j ++) - { - if ( ((font_ptr[i] >> (7-j)) & 0x01) != 0 ) - { - /* draw a pixel */ - rt_uint8_t *ptr = &(console.video_ptr[cursor + i * console.pitch + j * console.bpp]); - switch(console.bpp) - { - case 1: - *ptr = RT_CONSOLE_FOREPIXEL; - break; - case 2: - *(rt_uint16_t*)ptr = RT_CONSOLE_FOREPIXEL; - break; - case 3: - ptr[0] = RT_CONSOLE_FOREPIXEL & 0xff; - ptr[1] = (RT_CONSOLE_FOREPIXEL >> 8) & 0xff; - ptr[2] = (RT_CONSOLE_FOREPIXEL >> 16) & 0xff; - break; - case 4: - *(rt_uint32_t*)ptr = RT_CONSOLE_FOREPIXEL; - break; - } - } - } - } - - console.current_col ++; - } - break; - } -} - -void rt_hw_console_newline() -{ - console.current_row ++; - if (console.current_row >= RT_CONSOLE_ROW) - { - rt_uint32_t i; - - /* scroll to next line */ - for (i = 0; i < RT_CONSOLE_ROW - 1; i ++) - { - rt_memcpy(console.video_ptr + i * RT_CONSOLE_FONT_HEIGHT * console.pitch, - console.video_ptr + (i + 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch, - RT_CONSOLE_FONT_HEIGHT * console.pitch); - } - - /* clear last line */ - rt_memset(console.video_ptr + (RT_CONSOLE_ROW - 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch, - 0, - RT_CONSOLE_FONT_HEIGHT * console.pitch); - - console.current_row = RT_CONSOLE_ROW - 1; - } -} - -void rt_hw_console_clear() -{ - console.current_col = 0; - console.current_row = 0; - - rt_memset(console.video_ptr, 0, RT_CONSOLE_HEIGHT * console.pitch); -} - -/* write one character to serial, must not trigger interrupt */ -void rt_hw_serial_putc(const char c) -{ - /* - to be polite with serial console add a line feed - to the carriage return character - */ - if (c=='\n')rt_hw_serial_putc('\r'); - - while (!(uart0.uart_device->USART_CSR & TXRDY)); - uart0.uart_device->USART_THR = (c & 0x1FF); -} - -/** - * This function is used by rt_kprintf to display a string on console. - * - * @param str the displayed string - */ -void rt_hw_console_output(const char* str) -{ - while (*str) - { - rt_hw_serial_putc(*str++); - } -} - diff --git a/bsp/at91sam9260/rtconfig.h b/bsp/at91sam9260/rtconfig.h index ab5f3e5c51..176c84c0a0 100755 --- a/bsp/at91sam9260/rtconfig.h +++ b/bsp/at91sam9260/rtconfig.h @@ -62,18 +62,27 @@ /* Using SLAB Allocator */ #define RT_USING_SLAB -/* SECTION: Device System */ -/* Using Device System */ -#define RT_USING_DEVICE +/* SECTION: the runtime libc library */ +/* the runtime libc library */ +#define RT_USING_NEWLIB +#define RT_USING_PTHREADS /* Using Module System */ #define RT_USING_MODULE #define RT_USING_LIBDL +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE + +#define RT_USING_DEVICE_IPC +#define RT_USING_SERIAL + /* SECTION: Console options */ #define RT_USING_CONSOLE /* the buffer size of console */ #define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "dbgu" /* SECTION: finsh, a C-Express shell */ /* Using FinSH as Shell*/ @@ -83,11 +92,6 @@ #define FINSH_USING_DESCRIPTION #define FINSH_THREAD_STACK_SIZE 4096 -/* SECTION: the runtime libc library */ -/* the runtime libc library */ -#define RT_USING_NEWLIB -#define RT_USING_PTHREADS - /* SECTION: C++ support */ /* Using C++ support */ /* #define RT_USING_CPLUSPLUS */ diff --git a/bsp/at91sam9260/startup.c b/bsp/at91sam9260/startup.c index 3e3d85cd2e..2a06126b36 100755 --- a/bsp/at91sam9260/startup.c +++ b/bsp/at91sam9260/startup.c @@ -19,14 +19,8 @@ #ifdef RT_USING_FINSH #include #endif - -#ifdef RT_USING_DEVICE -#include -#endif - extern void rt_hw_interrupt_init(void); extern void rt_hw_board_init(void); -extern void rt_serial_init(void); extern void rt_system_timer_init(void); extern void rt_system_scheduler_init(void); extern void rt_thread_idle_init(void); @@ -37,9 +31,6 @@ extern void rt_system_heap_init(void*, void*); extern void rt_hw_finsh_init(void); extern void rt_application_init(void); -extern struct serial_device uart0; -extern struct rt_device uart0_device; - /** * @addtogroup at91sam9260 */ @@ -109,50 +100,6 @@ void rtthread_startup(void) /* initialize scheduler system */ rt_system_scheduler_init(); -#ifdef RT_USING_DEVICE -#ifdef RT_USING_DBGU - /* register dbgu */ - rt_hw_serial_register(&uart0_device, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX, - &uart0); -#endif - -#ifdef RT_USING_UART0 - /* register uart0 */ - rt_hw_serial_register(&uart1_device, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX, - &uart1); -#endif - -#ifdef RT_USING_UART1 - /* register uart1 */ - rt_hw_serial_register(&uart2_device, "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX, - &uart2); -#endif - -#ifdef RT_USING_UART2 - /* register uart2 */ - rt_hw_serial_register(&uart3_device, "uart3", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX, - &uart3); -#endif - -#ifdef RT_USING_UART3 - /* register uart3 */ - rt_hw_serial_register(&uart4_device, "uart4", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX, - &uart4); -#endif - -#ifdef RT_USING_DFS - //rt_hw_sdcard_init(); -#endif - - /*init all registed devices */ - rt_device_init_all(); -#endif - /* initialize application */ rt_application_init(); @@ -160,9 +107,7 @@ void rtthread_startup(void) /* initialize finsh */ finsh_system_init(); #ifdef RT_USING_DEVICE -#ifdef RT_USING_DBGU - finsh_set_device("uart0"); -#endif + finsh_set_device(RT_CONSOLE_DEVICE_NAME); #endif #endif diff --git a/bsp/at91sam9260/usart.c b/bsp/at91sam9260/usart.c new file mode 100644 index 0000000000..11823b9c8c --- /dev/null +++ b/bsp/at91sam9260/usart.c @@ -0,0 +1,413 @@ +#include +#include +#include +#include + +#define RXRDY 0x01 +#define TXRDY (1 << 1) + +typedef struct uartport +{ + volatile rt_uint32_t CR; + volatile rt_uint32_t MR; + volatile rt_uint32_t IER; + volatile rt_uint32_t IDR; + volatile rt_uint32_t IMR; + volatile rt_uint32_t CSR; + volatile rt_uint32_t RHR; + volatile rt_uint32_t THR; + volatile rt_uint32_t BRGR; + volatile rt_uint32_t RTOR; + volatile rt_uint32_t TTGR; + volatile rt_uint32_t reserved0[5]; + volatile rt_uint32_t FIDI; + volatile rt_uint32_t NER; + volatile rt_uint32_t reserved1; + volatile rt_uint32_t IFR; + volatile rt_uint32_t reserved2[44]; + volatile rt_uint32_t RPR; + volatile rt_uint32_t RCR; + volatile rt_uint32_t TPR; + volatile rt_uint32_t TCR; + volatile rt_uint32_t RNPR; + volatile rt_uint32_t RNCR; + volatile rt_uint32_t TNPR; + volatile rt_uint32_t TNCR; + volatile rt_uint32_t PTCR; + volatile rt_uint32_t PTSR; +}uartport; + +#define CIDR FIDI +#define EXID NER +#define FNR reserved1 + +#define DBGU ((struct uartport *)AT91SAM9260_BASE_DBGU) + +#define UART0 ((struct uartport *)AT91SAM9260_BASE_US0) +#define UART1 ((struct uartport *)AT91SAM9260_BASE_US1) +#define UART2 ((struct uartport *)AT91SAM9260_BASE_US2) +#define UART3 ((struct uartport *)AT91SAM9260_BASE_US3) + +struct at91_uart { + uartport *port; + int irq; +}; + + + +/** + * This function will handle serial + */ +void rt_at91_usart_handler(int vector, void *param) +{ + int status; + struct at91_uart *uart; + rt_device_t dev = (rt_device_t)param; + uart = (struct at91_uart *)dev->user_data; + status = uart->port->CSR; + if (!(status & uart->port->IMR)) + { + return; + } + rt_interrupt_enter(); + rt_hw_serial_isr(dev); + rt_interrupt_leave(); +} + +/** +* UART device in RT-Thread +*/ +static rt_err_t at91_usart_configure(struct rt_serial_device *serial, + struct serial_configure *cfg) +{ + int div; + int mode = 0; + struct at91_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + uart = (struct at91_uart *)serial->parent.user_data; + + uart->port->CR = AT91_US_RSTTX | AT91_US_RSTRX | + AT91_US_RXDIS | AT91_US_TXDIS; + mode |= AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | + AT91_US_CHMODE_NORMAL; + switch (cfg->data_bits) + { + case DATA_BITS_8: + mode |= AT91_US_CHRL_8; + break; + case DATA_BITS_7: + mode |= AT91_US_CHRL_7; + break; + case DATA_BITS_6: + mode |= AT91_US_CHRL_6; + break; + case DATA_BITS_5: + mode |= AT91_US_CHRL_5; + break; + default: + mode |= AT91_US_CHRL_8; + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + mode |= AT91_US_NBSTOP_2; + break; + case STOP_BITS_1: + default: + mode |= AT91_US_NBSTOP_1; + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + mode |= AT91_US_PAR_ODD; + break; + case PARITY_EVEN: + mode |= AT91_US_PAR_EVEN; + break; + case PARITY_NONE: + default: + mode |= AT91_US_PAR_NONE; + break; + } + + uart->port->MR = mode; + div = (clk_get_rate(clk_get("mck")) / 16 + cfg->baud_rate/2) / cfg->baud_rate; + uart->port->BRGR = div; + uart->port->CR = AT91_US_RXEN | AT91_US_TXEN; + uart->port->IER = 0x01; + + return RT_EOK; +} + +static rt_err_t at91_usart_control(struct rt_serial_device *serial, + int cmd, void *arg) +{ + struct at91_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct at91_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + rt_hw_interrupt_mask(uart->irq); + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + rt_hw_interrupt_umask(uart->irq); + break; + } + + return RT_EOK; +} + +static int at91_usart_putc(struct rt_serial_device *serial, char c) +{ + rt_uint32_t level; + struct at91_uart *uart = serial->parent.user_data; + + while (!(uart->port->CSR & TXRDY)); + uart->port->THR = c; + + return 1; +} + +static int at91_usart_getc(struct rt_serial_device *serial) +{ + int result; + struct at91_uart *uart = serial->parent.user_data; + + if (uart->port->CSR & RXRDY) + { + result = uart->port->RHR & 0xff; + } + else + { + result = -1; + } + + return result; +} + +static const struct rt_uart_ops at91_usart_ops = +{ + at91_usart_configure, + at91_usart_control, + at91_usart_putc, + at91_usart_getc, +}; + +#if defined(RT_USING_DBGU) +static struct rt_serial_device serial_dbgu; +static struct serial_ringbuffer dbgu_int_rx; +struct at91_uart dbgu = { + DBGU, + AT91_ID_SYS +}; + +#endif + +#if defined(RT_USING_UART0) +static struct rt_serial_device serial0; +static struct serial_ringbuffer uart0_int_rx; +struct at91_uart uart0 = { + UART0, + AT91SAM9260_ID_US0 +}; +#endif + +#if defined(RT_USING_UART1) +static struct rt_serial_device serial1; +static struct serial_ringbuffer uart1_int_rx; +struct at91_uart uart1 = { + UART1, + AT91SAM9260_ID_US1 +}; +#endif + +#if defined(RT_USING_UART2) +static struct rt_serial_device serial2; +static struct serial_ringbuffer uart2_int_rx; +struct at91_uart uart2 = { + UART2, + AT91SAM9260_ID_US2 +}; +#endif + +#if defined(RT_USING_UART3) +static struct rt_serial_device serial3; +static struct serial_ringbuffer uart3_int_rx; +struct at91_uart uart3 = { + UART3, + AT91SAM9260_ID_US3 +}; +#endif + +void at91_usart_gpio_init(void) +{ + rt_uint32_t val; + +#ifdef RT_USING_DBGU + at91_sys_write(AT91_PIOB + PIO_IDR, (1<<14)|(1<<15)); + //at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6)); + at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<14)|(1<<15)); + at91_sys_write(AT91_PIOB + PIO_ASR, (1<<14)|(1<<15)); + at91_sys_write(AT91_PIOB + PIO_PDR, (1<<14)|(1<<15)); + at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS); +#endif + +#ifdef RT_USING_UART0 + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US0); + at91_sys_write(AT91_PIOB + PIO_IDR, (1<<4)|(1<<5)); + at91_sys_write(AT91_PIOB + PIO_PUER, (1<<4)); + at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<5)); + at91_sys_write(AT91_PIOB + PIO_ASR, (1<<4)|(1<<5)); + at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5)); +#endif + +#ifdef RT_USING_UART1 + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1); + at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7)); + at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6)); + at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7)); + at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7)); + at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7)); +#endif + +#ifdef RT_USING_UART2 + at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US2); + at91_sys_write(AT91_PIOB + PIO_IDR, (1<<8)|(1<<9)); + at91_sys_write(AT91_PIOB + PIO_PUER, (1<<8)); + at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<9)); + at91_sys_write(AT91_PIOB + PIO_ASR, (1<<8)|(1<<9)); + at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9)); +#endif + +#ifdef RT_USING_UART3 + at91_sys_write(AT91_PMC_PCER, 1< - -#include "serial.h" - -/** - * @addtogroup AT91SAM926X - */ -/*@{*/ - -/* RT-Thread Device Interface */ -/** - * This function initializes serial - */ -static rt_err_t rt_serial_init (rt_device_t dev) -{ - struct serial_device* uart = (struct serial_device*) dev->user_data; - - if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) - { - - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_memset(uart->int_rx->rx_buffer, 0, - sizeof(uart->int_rx->rx_buffer)); - uart->int_rx->read_index = uart->int_rx->save_index = 0; - } - - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - rt_memset(uart->int_tx->tx_buffer, 0, - sizeof(uart->int_tx->tx_buffer)); - uart->int_tx->write_index = uart->int_tx->save_index = 0; - } - - dev->flag |= RT_DEVICE_FLAG_ACTIVATED; - } - - return RT_EOK; -} - -/* save a char to serial buffer */ -static void rt_serial_savechar(struct serial_device* uart, char ch) -{ - rt_base_t level; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch; - uart->int_rx->save_index ++; - if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE) - uart->int_rx->save_index = 0; - - /* if the next position is read index, discard this 'read char' */ - if (uart->int_rx->save_index == uart->int_rx->read_index) - { - uart->int_rx->read_index ++; - if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) - uart->int_rx->read_index = 0; - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); -} - -static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) -{ - RT_ASSERT(dev != RT_NULL); - - return RT_EOK; -} - -static rt_err_t rt_serial_close(rt_device_t dev) -{ - RT_ASSERT(dev != RT_NULL); - - return RT_EOK; -} - -static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) -{ - rt_uint8_t* ptr; - rt_err_t err_code; - struct serial_device* uart; - - ptr = buffer; - err_code = RT_EOK; - uart = (struct serial_device*)dev->user_data; - - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_base_t level; - - /* interrupt mode Rx */ - while (size) - { - if (uart->int_rx->read_index != uart->int_rx->save_index) - { - *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; - size --; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - uart->int_rx->read_index ++; - if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) - uart->int_rx->read_index = 0; - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - } - else - { - /* set error code */ - err_code = -RT_EEMPTY; - break; - } - } - } - else - { - /* polling mode */ - while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) - { - while (uart->uart_device->USART_CSR & RXRDY) - { - *ptr = uart->uart_device->USART_RHR & 0xff; - ptr ++; - } - } - } - - /* set error code */ - rt_set_errno(err_code); - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; -} - -static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) -{ - rt_uint8_t* ptr; - rt_err_t err_code; - struct serial_device* uart; - - err_code = RT_EOK; - ptr = (rt_uint8_t*)buffer; - uart = (struct serial_device*)dev->user_data; - - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - /* interrupt mode Tx */ - while (uart->int_tx->save_index != uart->int_tx->write_index) - { - /* save on tx buffer */ - uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++; - - -- size; - - /* move to next position */ - uart->int_tx->save_index ++; - - /* wrap save index */ - if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE) - uart->int_tx->save_index = 0; - } - - /* set error code */ - if (size > 0) - err_code = -RT_EFULL; - } - else - { - /* polling mode */ - while (size) - { - /* - * to be polite with serial console add a line feed - * to the carriage return character - */ - if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) - { - while (!(uart->uart_device->USART_CSR & TXRDY)); - uart->uart_device->USART_THR = '\r'; - } - - while (!(uart->uart_device->USART_CSR & TXRDY)); - uart->uart_device->USART_THR = (*ptr & 0xFF); - - ++ptr; --size; - } - } - - /* set error code */ - rt_set_errno(err_code); - - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; -} - -static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args) -{ - RT_ASSERT(dev != RT_NULL); - - switch (cmd) - { - case RT_DEVICE_CTRL_SUSPEND: - /* suspend device */ - dev->flag |= RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_RESUME: - /* resume device */ - dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; - break; - } - - return RT_EOK; -} - -/* - * serial register - */ -rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial) -{ - RT_ASSERT(device != RT_NULL); - - device->type = RT_Device_Class_Char; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = rt_serial_read; - device->write = rt_serial_write; - device->control = rt_serial_control; - device->user_data = serial; - - /* register a character device */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); -} - -/* ISR for serial interrupt */ -void rt_hw_serial_isr(rt_device_t device) -{ - struct serial_device* uart = (struct serial_device*) device->user_data; - - /* interrupt mode receive */ - RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); - - /* save on rx buffer */ - while (uart->uart_device->USART_CSR & RXRDY) - { - rt_serial_savechar(uart, uart->uart_device->USART_RHR & 0xff); - } - - /* invoke callback */ - if (device->rx_indicate != RT_NULL) - { - rt_size_t rx_length; - - /* get rx length */ - rx_length = uart->int_rx->read_index > uart->int_rx->save_index ? - UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index : - uart->int_rx->save_index - uart->int_rx->read_index; - - device->rx_indicate(device, rx_length); - } -} - -/*@}*/ diff --git a/libcpu/arm/at91sam926x/serial.h b/libcpu/arm/at91sam926x/serial.h deleted file mode 100755 index 67f6d3c659..0000000000 --- a/libcpu/arm/at91sam926x/serial.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef __RT_HW_SERIAL_H__ -#define __RT_HW_SERIAL_H__ - -#include -#include - -#include "at91sam926x.h" - -#define RXRDY 0x01 -#define TXRDY (1 << 1) -#define BPS 115200 /* serial baudrate */ - -#define UART_RX_BUFFER_SIZE 64 -#define UART_TX_BUFFER_SIZE 64 - -struct serial_int_rx -{ - rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE]; - rt_uint32_t read_index, save_index; -}; - -struct serial_int_tx -{ - rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE]; - rt_uint32_t write_index, save_index; -}; - -typedef struct uartport -{ -/* USART register offsets */ - volatile rt_uint32_t USART_CR; - volatile rt_uint32_t USART_MR; - volatile rt_uint32_t USART_IER; - volatile rt_uint32_t USART_IDR; - volatile rt_uint32_t USART_IMR; - volatile rt_uint32_t USART_CSR; - volatile rt_uint32_t USART_RHR; - volatile rt_uint32_t USART_THR; - volatile rt_uint32_t USART_BRGR; - volatile rt_uint32_t USART_RTOR; - volatile rt_uint32_t USART_TTGR; - volatile rt_uint32_t reseverd0[5]; - volatile rt_uint32_t USART_FIDI; - volatile rt_uint32_t USART_NER; - volatile rt_uint32_t USART_XXR; - volatile rt_uint32_t USART_IFR; - volatile rt_uint32_t reserved1[44]; - volatile rt_uint32_t USART_RPR; - volatile rt_uint32_t USART_RCR; - volatile rt_uint32_t USART_TPR; - volatile rt_uint32_t USART_TCR; - volatile rt_uint32_t USART_RNPR; - volatile rt_uint32_t USART_RNCR; - volatile rt_uint32_t USART_TNPR; - volatile rt_uint32_t USART_TNCR; - volatile rt_uint32_t USART_PTCR; - volatile rt_uint32_t USART_PTSR; -}uartport; - - -struct serial_device -{ - uartport* uart_device; - - /* rx structure */ - struct serial_int_rx* int_rx; - - /* tx structure */ - struct serial_int_tx* int_tx; -}; - -rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial); - -void rt_hw_serial_isr(rt_device_t device); - -#endif