// =======================================
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
******************************************************************************/
|