// ======================================= static void UART1Init (uint32_t baudrate) { uint32_t Fdiv; uint32_t pclk; // Assign txd, rxd lines to pins. LPC_IOCON->PIO0_8 = 0x02; LPC_IOCON->PIO0_9 = 0x02; // SYSAHBCLKCTRL 12. bit should be set to 1. pclk = UART_INPUT_FREQ; LPC_UART1->LCR = 0x83; // 8 bits, no Parity, 1 Stop bit Fdiv = ( pclk / 16 ) / baudrate ; // baud rate LPC_UART1->DLM = Fdiv / 256; LPC_UART1->DLL = Fdiv % 256; LPC_UART1->LCR = 0x03; // DLAB = 0 LPC_UART1->FCR = 0x07; // Enable and reset TX and RX FIFO. //LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; // Enable UART0 interrupt //LPC_UART0->IER = IER_RBR; // Enable UART0 interrupt (Only the receive data available interrupt is enabled.) //NVIC_EnableIRQ (UART1_IRQn); } |
unsigned char lsrValue; UART0RcvSignal = 0; ledState = 0; counter = 0; // Disable watchdog LPC_WDT->MOD = 0x00; LPC_WDT->FEED = 0xAA; LPC_WDT->FEED = 0x55; // UART0Init (9600); UART1Init (9600); // enable all interrupts (Is this necessary ???) //__asm volatile ("cpsie i"); LPC_GPIO0->DIR = LEDPIN; LPC_GPIO0->OUT = LEDPIN; // Initially the led is on. // Enter an infinite loop while (1) { counter++; if (counter >= COUNTER_MAX) { counter = 0; LPC_UART1->THR = 'A'; } lsrValue = LPC_UART1->LSR; if (lsrValue & 0x01) { UART0RcvSignal = 1; UART0RcvData = LPC_UART1->RBR; } if (UART0RcvSignal) { // Echo back the character LPC_UART1->THR = (UART0RcvData + 1); // Blink the led if (ledState) { ledState = 0; LPC_GPIO0->OUT = LEDPIN; } else { ledState = 1; LPC_GPIO0->OUT = 0; } UART0RcvSignal = 0; } } |
LPC_IOCON->PIO0_8 &= ~(0x07); |
LPC_IOCON->PIO0_8 |= (0x02); |
LPC_IOCON->PIO0_8 &= ~(0x07); |
/** * @briefInitializes UART. * @param[in]setThe desired settings for UART. * @return0 on error, else 1. * @remarkImplements the fractional bit rate algorithm outlined in NXP manual. * @remarkFor NXP122x, Bit length must be in the range 5-8. */ int init_uart(uart_settings set){ double pclk = MainClock / PCLK_DIVIDER_VALUE;// Calculate peripheral clock uint8_t divaddval, mulval, dlm = 0, dll = 0;// Register fields UART_settings = set; // PART A: Calculate register values double frest = INITIAL_FREST; double dlest = pclk / (16.0 * ((double)(set.bit_rate))); uint16_t dlest_int = ((uint16_t)dlest); uint8_t isodd = FALSE, offset = 0; if(((double)dlest_int) != dlest){// If dlest is not an integer... do { // Try FRest values between (INITIAL_FREST - FREST_RANGE) and (INITIAL_FREST + FREST_RANGE); 1.1-1.9 by default. if(isodd){ frest = (INITIAL_FREST) + (offset++) * (UART0_BITRATE_ALGO_STEP_SIZE); isodd = FALSE; } else{ frest = (INITIAL_FREST) - (offset) * (UART0_BITRATE_ALGO_STEP_SIZE); isodd = TRUE; } dlest_int = (uint16_t)(pclk / (16.0 * ((double)(set.bit_rate)) * frest)); if(dlest_int == 0) goto cfg_error; frest = pclk / (16.0 * ((double)(set.bit_rate)) * ((double)dlest_int)); } while ((frest <= (INITIAL_FREST - FREST_RANGE) || frest >= (INITIAL_FREST + FREST_RANGE)) && (offset <= FREST_RANGE / UART0_BITRATE_ALGO_STEP_SIZE)); // Get LUT index int i = find_uart_lut_index(frest); // Look up fractional values in LUT divaddval = uart_divaddval_lut; mulval = uart_mulval_lut; dlm = (dlest_int>>8); dll = (dlest_int); } else {// dlest was an integer; no need for fractional division. divaddval = 0; mulval = 1; dll = 1; } // PART B: Set registers // Different registers for each UART. switch(set.uart_port){ case UART0: ENABLE_UART0;// UART0 MUST BE ENABLED FOR REGISTERS TO ACCEPT VALUES!!!!! It took me FOREVER to figure this out... SET_UART0_DLAB; (LPC_UART0 -> DLL) = dll; (LPC_UART0 -> DLM) = dlm; CLEAR_UART0_DLAB; (LPC_UART0 -> FDR) = ((mulval << MULVAL_OFFSET) | divaddval); (LPC_UART0 -> LCR) = (set.payload_length - 5) | (set.stop_bit << 2) | (set.parity != 0) | (set.parity != 0 ? set.parity - 1 : 0x0);// Sets UART parameters (LPC_UART0 -> FCR) = (1 << UART0_FIFOEN_BIT);// Enable FIFO //(LPC_UART0 -> IER) = (1<<UART0_RBRIE_BIT);// Enable receive interrupt break; case UART1: ENABLE_UART1; SET_UART1_DLAB; (LPC_UART1 -> DLL) = dll; (LPC_UART1 -> DLM) = dlm; CLEAR_UART1_DLAB; (LPC_UART1 -> FDR) = ((mulval << MULVAL_OFFSET) | divaddval); (LPC_UART1 -> LCR) = (set.payload_length - 5) | (set.stop_bit << 2) | (set.parity != 0) | (set.parity != 0 ? set.parity - 1 : 0x0);// Sets UART parameters (LPC_UART1 -> FCR) = (1<<UART1_FIFOEN_BIT)|(1<<UART1_RX_RESET_BIT)|(1<<UART1_TX_RESET_BIT);// Enable FIFO + clear RX & TX FIFOs (LPC_UART1 -> IER) = (1<<UART1_RBRIE_BIT);// Enable receive interrupt break; } return 1;// Exit normally. cfg_error:// Error handler. return 0; } |
char s = LPC_UART1 -> RBR; |
/***************************************************************************** * uart.c: UART API file for [COLOR=Red]NXP LPC11xx[/COLOR] Family Microprocessors * * Copyright(C) 2008, NXP Semiconductor * All rights reserved. * * History * 2009.12.07 ver 1.00 Preliminary version, first Release * ******************************************************************************/ #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_UART->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_UART->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_UART->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_UART->RBR; if (UARTCount == BUFSIZE) { UARTCount = 0; /* buffer overflow */ } } } else if (IIRValue == IIR_RDA) /* Receive Data Available */ { /* Receive Data Available */ UARTBuffer[UARTCount++] = LPC_UART->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_UART->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; } /***************************************************************************** ** 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->PIO1_6 &= ~0x07; /* UART I/O config */ LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */ LPC_IOCON->PIO1_7 &= ~0x07; LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */ /* Enable UART clock */ LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */ LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ regVal = LPC_SYSCON->UARTCLKDIV; Fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ; /*baud rate */ LPC_UART->DLM = Fdiv / 256; LPC_UART->DLL = Fdiv % 256; LPC_UART->LCR = 0x03; /* DLAB = 0 */ LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ /* Read to clear the line status. */ regVal = LPC_UART->LSR; /* Ensure a clean start, no data in either TX or RX FIFO. */ // CodeRed - added parentheses around comparison in operand of & while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) ); while ( LPC_UART->LSR & LSR_RDR ) { regVal = LPC_UART->RBR; /* Dump data from RX FIFO */ } /* Enable the UART Interrupt */ NVIC_EnableIRQ(UART_IRQn); #if CONFIG_UART_ENABLE_TX_INTERRUPT==1 LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */ #else LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */ #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_UART->THR = *BufferPtr; UARTTxEmpty = 0; /* not empty in the THR until it shifts out */ #else while ( !(LPC_UART->LSR & LSR_THRE) ); LPC_UART->THR = *BufferPtr; #endif BufferPtr++; Length--; } return; } /****************************************************************************** ** End Of File ******************************************************************************/ |