I have written a code which intializes 2 UARTs, i.e., UART-1 and UART-2. The code works pretty fine. I am using the same code on two different controllers.
Simply say i have a board with two controllers and are connected by UART-2. (LPC2368) Now i using same program in the two controllers.
I have used a LED in both the controllers to make them glow just before the program enters the while loop.
Now my problem when i power up the board the LED is not being glowing. So i have to assume that my code did not reach the while loop.
I have observed that if i comment UART2 intialization (which is used for inter communication between the two controllers) then the LED glows and the code is working fine.
So again i removed the comments at UART-2 intialization and started debugging one of the controller. Again it works fine.
Now what i did is i have made one controller in reset at power ON and let the other controller intilaize. and after some time say 5 secs i have released the 1st controller from reset and let it intialize. Now also it is working.
Now my conclusion if i run the board with the same code in both the controllers it is not working. I mean both the controllers are trying to intialize the UART-2 at the same time.
So how can i handle this? What could be the reason for this problem? I am unable to debug since only after power up i can debug which leads to the two controllers intializing at different time intervals.
Can some one please help me with this.
Maybe your initialization code is broken, so it doesn't correctly handle an UART that already has pending data before you have fully initialized the receiving side.
Are you properly installing the ISR before you configure/enable interrupt handling so you don't get an interrupt out into the blue because the other side has already sent the first character?
Another thing - if one UART sends a character before the receiving side has properly initialized and set baudrate etc, then the second UART might get a parity error. Do your ISR properly handle such errors?
Thanks for your reply Per Westermark. My program is only intializing the UART. It didnt add any routines to send data on the serial ports.
I have added the UART intialization function below.
/*************************** UART Initialization ***************************************/
unsigned long UartInit(DWORD baudrate )
{
PCONP |= ( 1 << 24 ); // Turn on UART2 power
PINSEL0 |= 0x00500000; // Enable TxD2 P0.10; RxD2 P0.11
U2LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
Fdiv = ( Fpclk / 16 ) / baudrate ; // baud rate
U2DLM = Fdiv / 256;
U2DLL = Fdiv % 256;
U2LCR = 0x03; // DLAB = 0
U2FCR = 0x07;
// Enable and reset TX and RX FIFO.
if(install_irq( UART2_INT, (void *)Uart2Handler, 5) == FALSE)
return (0);
}
U2IER = IER_RBR | IER_THRE | IER_RLS; // Enable UART2 interrupt
return (1);
/*************************** Install IRQ ***************************************/ unsigned long install_irq( unsigned long IntNumber, void *HandlerAddr, unsigned long Priority )
DWORD *vect_addr;
DWORD *vect_prio;
VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
if ( IntNumber >= VIC_SIZE )
return (FALSE);
else
/* find first un-assigned VIC address for the handler */
vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);
vect_prio = (DWORD *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4);
*vect_addr = (DWORD)HandlerAddr; /* set interrupt vector */
*vect_prio = Priority;
VICIntEnable= 1 << IntNumber; /* Enable Interrupt */
return(TRUE);
/*************************** UART Interrupt Handler ***************************************/
void Uart2Handler (void) __irq
BYTE IIRValue, LSRValue;
BYTE Dummy = Dummy;
//IENABLE; // handles nested interrupt
IIRValue = U2IIR;
IIRValue >>= 1; // skip pending bit in IIR
IIRValue &= 0x07; // check bit 1~3, interrupt identification
if(IIRValue == IIR_RLS) // Receive Line Status
LSRValue = U2LSR; // Read LSR will clear the interrupt
if(LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) // Receive Line Status
{ // There are errors or break interrupt
Dummy = U2RBR;// Dummy read on RX to clear interrupt, then bail out
//IDISABLE;
VICVectAddr = 0; // Acknowledge Interrupt
return;
if(LSRValue & LSR_RDR) // Receive Data Ready
{ // If no error on RLS, normal ready, save into the data buffer.
Dummy = U2RBR;
//UART2_Receive(Dummy);
else if ( IIRValue == IIR_RDA ) // Receive Data Available
else if ( IIRValue == IIR_CTI ) // Character timeout indicator
{ // Character Time-out indicator
//UART2Status |= 0x100; // Bit 9 as the CTI error
else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */
/* THRE interrupt */
LSRValue = U2LSR; /* Check status in the LSR to see if
valid data in U3THR or not */
if ( LSRValue & LSR_THRE )
UART2TxEmpty = 1;
UART2TxEmpty = 0;
// IDISABLE;
You can see that I had handled errors also. As you suggested that i might get a parity error. But i have intialized the UART with No Parity bit.
Sorry i couldnt insert tabs for readability.
>>Sorry i couldnt insert tabs for readability.
Or apparently read the posting instructions telling you to use PRE tags for source code?
Ever connected a serial cable to a PC while you have a terminal program up and running and seen one or more random characters show up on the screen?
If the UART thinks it has seen the first flank of a start bit, it will start to run a full character cycle and then report back the outcome. So there is no need for the other side to actually send any character to trick the receiving end to think that a character has been sent.
So when initializing a UART, you need to always be prepared for data arriving - and be prepared for that data to be valid or invalid.