From c004cd438724063007eec0f43a4681e84a839252 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 16 Jan 2013 12:43:17 +0700 Subject: [PATCH] add uart for lpc11uxx and retarget successfully --- demos/bsp/boards/board.h | 13 +- demos/bsp/boards/board_at86rf2xx.c | 25 +++ demos/bsp/boards/board_lpcxpresso1347.c | 19 +- demos/bsp/boards/printf_retarget.c | 2 +- demos/bsp/lpc11uxx/uart.c | 238 ++++++++++++++++++++++++ demos/bsp/lpc11uxx/uart.h | 55 ++++++ demos/device/keyboard/.cproject | 6 +- tests/test/test_fifo.c | 1 + tests/test/test_template.c | 2 +- tinyusb/common/fifo.c | 6 +- tinyusb/common/fifo.h | 3 +- tinyusb/common/mcu/mcu.h | 8 +- 12 files changed, 355 insertions(+), 23 deletions(-) create mode 100644 demos/bsp/lpc11uxx/uart.c create mode 100644 demos/bsp/lpc11uxx/uart.h diff --git a/demos/bsp/boards/board.h b/demos/bsp/boards/board.h index a7f207e4..b5fd17db 100644 --- a/demos/bsp/boards/board.h +++ b/demos/bsp/boards/board.h @@ -58,9 +58,8 @@ #include #define BSP_TICKS_PER_SECOND 1000 - -#define BSP_UART_ENABLE 1 -#define BSP_UART_BAUDRATE 115200 +#define BSP_UART_ENABLE 1 +#define BSP_UART_BAUDRATE 115200 /// n-th Bit @@ -68,9 +67,9 @@ #define BIT_(n) (1 << (n)) #endif -#define BOARD_NGX4330 1 -#define BOARD_LPCXPRESSO1347 2 -#define BOARD_AT86RF2XX 3 +#define BOARD_AT86RF2XX 0 +#define BOARD_LPCXPRESSO1347 1 +#define BOARD_NGX4330 2 #if BOARD == BOARD_NGX4330 @@ -85,6 +84,8 @@ /// Init board peripherals : Clock, UART, LEDs, Buttons void board_init(void); void board_leds(uint32_t mask, uint32_t state); +uint32_t board_uart_send(uint8_t *buffer, uint32_t length); +uint32_t board_uart_recv(uint8_t *buffer, uint32_t length); extern volatile uint32_t system_ticks; diff --git a/demos/bsp/boards/board_at86rf2xx.c b/demos/bsp/boards/board_at86rf2xx.c index f0db2cdf..310f16c1 100644 --- a/demos/bsp/boards/board_at86rf2xx.c +++ b/demos/bsp/boards/board_at86rf2xx.c @@ -41,6 +41,7 @@ #include "LPC11Uxx.h" #include "lpc11uxx/gpio.h" +#include "lpc11uxx/uart.h" #define CFG_LED_PORT (1) #define CFG_LED_PIN (31) @@ -55,12 +56,36 @@ void board_init(void) GPIOSetDir(CFG_LED_PORT, CFG_LED_PIN, 1); board_leds(0x01, 0); // turn off the led first + +#if BSP_UART_ENABLE + UARTInit(BSP_UART_BAUDRATE); +#endif } +//--------------------------------------------------------------------+ +// LEDS +//--------------------------------------------------------------------+ void board_leds(uint32_t mask, uint32_t state) { if (mask) GPIOSetBitValue(CFG_LED_PORT, CFG_LED_PIN, mask & state ? CFG_LED_ON : CFG_LED_OFF); } +//--------------------------------------------------------------------+ +// UART +//--------------------------------------------------------------------+ +#if BSP_UART_ENABLE +uint32_t board_uart_send(uint8_t *buffer, uint32_t length) +{ + UARTSend(buffer, length); + return length; +} + +uint32_t board_uart_recv(uint8_t *buffer, uint32_t length) +{ +// *buffer = get_key(); TODO cannot find available code for uart getchar + return 0; +} +#endif + #endif diff --git a/demos/bsp/boards/board_lpcxpresso1347.c b/demos/bsp/boards/board_lpcxpresso1347.c index cd1f014a..c4565765 100644 --- a/demos/bsp/boards/board_lpcxpresso1347.c +++ b/demos/bsp/boards/board_lpcxpresso1347.c @@ -58,10 +58,14 @@ void board_init(void) GPIOSetDir(CFG_LED_PORT, CFG_LED_PIN, 1); LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN); - // Uart Init +#if BSP_UART_ENABLE UARTInit(BSP_UART_BAUDRATE); +#endif } +//--------------------------------------------------------------------+ +// LEDS +//--------------------------------------------------------------------+ void board_leds(uint32_t mask, uint32_t state) { if (mask) @@ -70,16 +74,21 @@ void board_leds(uint32_t mask, uint32_t state) } } -uint32_t board_uart_send(uint8_t *p_buffer, uint32_t length) +//--------------------------------------------------------------------+ +// UART +//--------------------------------------------------------------------+ +#if BSP_UART_ENABLE +uint32_t board_uart_send(uint8_t *buffer, uint32_t length) { - UARTSend(p_buffer, length); + UARTSend(buffer, length); return length; } -uint32_t board_uart_recv(uint8_t *p_buffer, uint32_t length) +uint32_t board_uart_recv(uint8_t *buffer, uint32_t length) { - *p_buffer = get_key(); + *buffer = get_key(); return 1; } +#endif #endif diff --git a/demos/bsp/boards/printf_retarget.c b/demos/bsp/boards/printf_retarget.c index 948521b4..f53da4d1 100644 --- a/demos/bsp/boards/printf_retarget.c +++ b/demos/bsp/boards/printf_retarget.c @@ -48,7 +48,7 @@ int __sys_write (int iFileHandle, char *pcBuffer, int iLength) { (void) iFileHandle; - return board_uart_send(pcBuffer, iLength); + return board_uart_send((uint8_t*)pcBuffer, iLength); } // Called by bottom level of scanf routine within RedLib C library to read diff --git a/demos/bsp/lpc11uxx/uart.c b/demos/bsp/lpc11uxx/uart.c new file mode 100644 index 00000000..0bc87acd --- /dev/null +++ b/demos/bsp/lpc11uxx/uart.c @@ -0,0 +1,238 @@ +/***************************************************************************** + * uart.c: UART API file for NXP LPC11xx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.12.07 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ + +#include +#include "LPC11Uxx.h" +#include "uart.h" + +volatile uint32_t UARTStatus; +volatile uint8_t UARTTxEmpty = 1; +volatile uint8_t UARTBuffer[BUFSIZE]; +volatile uint32_t UARTCount = 0; + +/***************************************************************************** +** Function name: UART_IRQHandler +** +** Descriptions: UART interrupt handler +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void UART_IRQHandler(void) +{ + uint8_t IIRValue, LSRValue; + uint8_t Dummy = Dummy; + + IIRValue = LPC_USART->IIR; + + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + if (IIRValue == IIR_RLS) /* Receive Line Status */ + { + LSRValue = LPC_USART->LSR; + /* Receive Line Status */ + if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI)) + { + /* There are errors or break interrupt */ + /* Read LSR will clear the interrupt */ + UARTStatus = LSRValue; + Dummy = LPC_USART->RBR; /* Dummy read on RX to clear + interrupt, then bail out */ + return; + } + if (LSRValue & LSR_RDR) /* Receive Data Ready */ + { + /* If no error on RLS, normal ready, save into the data buffer. */ + /* Note: read RBR will clear the interrupt */ + UARTBuffer[UARTCount++] = LPC_USART->RBR; + if (UARTCount == BUFSIZE) + { + UARTCount = 0; /* buffer overflow */ + } + } + } + else if (IIRValue == IIR_RDA) /* Receive Data Available */ + { + /* Receive Data Available */ + UARTBuffer[UARTCount++] = LPC_USART->RBR; + if (UARTCount == BUFSIZE) + { + UARTCount = 0; /* buffer overflow */ + } + } + else if (IIRValue == IIR_CTI) /* Character timeout indicator */ + { + /* Character Time-out indicator */ + UARTStatus |= 0x100; /* Bit 9 as the CTI error */ + } + else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty */ + { + /* THRE interrupt */ + LSRValue = LPC_USART->LSR; /* Check status in the LSR to see if + valid data in U0THR or not */ + if (LSRValue & LSR_THRE) + { + UARTTxEmpty = 1; + } + else + { + UARTTxEmpty = 0; + } + } + return; +} + +#if MODEM_TEST +/***************************************************************************** +** Function name: ModemInit +** +** Descriptions: Initialize UART0 port as modem, setup pin select. +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void ModemInit( void ) +{ + LPC_IOCON->PIO2_0 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO2_0 |= 0x01; /* UART DTR */ + LPC_IOCON->PIO0_7 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO0_7 |= 0x01; /* UART CTS */ + LPC_IOCON->PIO1_5 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO1_5 |= 0x01; /* UART RTS */ +#if 1 + LPC_IOCON->DSR_LOC = 0; + LPC_IOCON->PIO2_1 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO2_1 |= 0x01; /* UART DSR */ + + LPC_IOCON->DCD_LOC = 0; + LPC_IOCON->PIO2_2 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO2_2 |= 0x01; /* UART DCD */ + + LPC_IOCON->RI_LOC = 0; + LPC_IOCON->PIO2_3 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO2_3 |= 0x01; /* UART RI */ + +#else + LPC_IOCON->DSR_LOC = 1; + LPC_IOCON->PIO3_1 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO3_1 |= 0x01; /* UART DSR */ + + LPC_IOCON->DCD_LOC = 1; + LPC_IOCON->PIO3_2 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO3_2 |= 0x01; /* UART DCD */ + + LPC_IOCON->RI_LOC = 1; + LPC_IOCON->PIO3_3 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO3_3 |= 0x01; /* UART RI */ +#endif + LPC_USART->MCR = 0xC0; /* Enable Auto RTS and Auto CTS. */ + return; +} +#endif + +/***************************************************************************** +** Function name: UARTInit +** +** Descriptions: Initialize UART0 port, setup pin select, +** clock, parity, stop bits, FIFO, etc. +** +** parameters: UART baudrate +** Returned value: None +** +*****************************************************************************/ +void UARTInit(uint32_t baudrate) +{ + uint32_t Fdiv; + uint32_t regVal; + + UARTTxEmpty = 1; + UARTCount = 0; + + NVIC_DisableIRQ(UART_IRQn); + + LPC_IOCON->PIO0_18 &= ~0x07; /* UART I/O config */ + LPC_IOCON->PIO0_18 |= 0x01; /* UART RXD */ + LPC_IOCON->PIO0_19 &= ~0x07; + LPC_IOCON->PIO0_19 |= 0x01; /* UART TXD */ + /* Enable UART clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */ + + LPC_USART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ + regVal = LPC_SYSCON->UARTCLKDIV; + + Fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ; /*baud rate */ + + LPC_USART->DLM = Fdiv / 256; + LPC_USART->DLL = Fdiv % 256; + LPC_USART->LCR = 0x03; /* DLAB = 0 */ + LPC_USART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ + + /* Read to clear the line status. */ + regVal = LPC_USART->LSR; + + /* Ensure a clean start, no data in either TX or RX FIFO. */ +// CodeRed - added parentheses around comparison in operand of & + while (( LPC_USART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) ); + while ( LPC_USART->LSR & LSR_RDR ) + { + regVal = LPC_USART->RBR; /* Dump data from RX FIFO */ + } + + /* Enable the UART Interrupt */ + NVIC_EnableIRQ(UART_IRQn); + +#if CONFIG_UART_ENABLE_INTERRUPT==1 +#if CONFIG_UART_ENABLE_TX_INTERRUPT==1 + LPC_USART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */ +#else + LPC_USART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */ +#endif +#endif + return; +} + +/***************************************************************************** +** Function name: UARTSend +** +** Descriptions: Send a block of data to the UART 0 port based +** on the data length +** +** parameters: buffer pointer, and data length +** Returned value: None +** +*****************************************************************************/ +void UARTSend(uint8_t *BufferPtr, uint32_t Length) +{ + + while ( Length != 0 ) + { + /* THRE status, contain valid data */ +#if CONFIG_UART_ENABLE_TX_INTERRUPT==1 + /* Below flag is set inside the interrupt handler when THRE occurs. */ + while ( !(UARTTxEmpty & 0x01) ); + LPC_USART->THR = *BufferPtr; + UARTTxEmpty = 0; /* not empty in the THR until it shifts out */ +#else + while ( !(LPC_USART->LSR & LSR_THRE) ); + LPC_USART->THR = *BufferPtr; +#endif + BufferPtr++; + Length--; + } + return; +} + +/****************************************************************************** +** End Of File +******************************************************************************/ diff --git a/demos/bsp/lpc11uxx/uart.h b/demos/bsp/lpc11uxx/uart.h new file mode 100644 index 00000000..9f00ab8a --- /dev/null +++ b/demos/bsp/lpc11uxx/uart.h @@ -0,0 +1,55 @@ +/***************************************************************************** + * uart.h: Header file for NXP LPC1xxx Family Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2009.12.07 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ +#ifndef __UART_H +#define __UART_H + +#define RS485_ENABLED 0 +#define TX_INTERRUPT 0 /* 0 if TX uses polling, 1 interrupt driven. */ +#define MODEM_TEST 0 + +#define IER_RBR 0x01 +#define IER_THRE 0x02 +#define IER_RLS 0x04 + +#define IIR_PEND 0x01 +#define IIR_RLS 0x03 +#define IIR_RDA 0x02 +#define IIR_CTI 0x06 +#define IIR_THRE 0x01 + +#define LSR_RDR 0x01 +#define LSR_OE 0x02 +#define LSR_PE 0x04 +#define LSR_FE 0x08 +#define LSR_BI 0x10 +#define LSR_THRE 0x20 +#define LSR_TEMT 0x40 +#define LSR_RXFE 0x80 + +#define BUFSIZE 0x40 + +/* RS485 mode definition. */ +#define RS485_NMMEN (0x1<<0) +#define RS485_RXDIS (0x1<<1) +#define RS485_AADEN (0x1<<2) +#define RS485_SEL (0x1<<3) +#define RS485_DCTRL (0x1<<4) +#define RS485_OINV (0x1<<5) + +void ModemInit( void ); +void UARTInit(uint32_t Baudrate); +void UART_IRQHandler(void); +void UARTSend(uint8_t *BufferPtr, uint32_t Length); + +#endif /* end __UART_H */ +/***************************************************************************** +** End Of File +******************************************************************************/ diff --git a/demos/device/keyboard/.cproject b/demos/device/keyboard/.cproject index 1d41d9ec..2d74a477 100644 --- a/demos/device/keyboard/.cproject +++ b/demos/device/keyboard/.cproject @@ -27,7 +27,7 @@ - +