LPC11U14 and USART (UART) problem

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC11U14 and USART (UART) problem

302 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fjarnjak on Mon Jul 09 00:58:45 MST 2012
Hello all,

I have noticed a strange problem on USART for LPC11U14 MCU (LPCXpresso board).

If I use this loop in main() method to send some string and watch TX using protocol analyzer I get correct string output.

while(1)
{
UARTSend(buff, 4);
sleep_ms(10);
}

If I ***remove*** sleep_ms(10); call I get garbage out....framing errors being reported on the other side, etc. Same if I connect a real device and not a protocol analyzer (logic analyzer).


UART Init code:


void UARTInit(uint32_t baudrate)
{

  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16); /* Enable IOCON block */

  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/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. */
  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 */
  }

}


Sending function:


void UARTSend(uint8_t *BufferPtr, uint32_t Length)
{
 
  //while ( !(LPC_USART->LSR & LSR_TEMT) );

  while ( Length != 0 )
  {
  while ( !(LPC_USART->LSR & LSR_THRE) );
  LPC_USART->THR = *BufferPtr;

      BufferPtr++;
      Length--;
  }
  return;
}

This code above seems not to block on while ( !(LPC_USART->LSR & LSR_THRE) ); in subsequent calls to the function when there is no sleep_ms(10); Otherwise, I would not get garbage but I would get data appened one after the other (or strings...).

I also put another while (now commented out) at the beggining to ensure TX FIFO is empty, but same thing happens. So I commented it out.

Also, when I get garbage, my protocol analyzer reports some strange baud rate. With sleep it works fine - selected baud rate is discovered one. 

I have tested above at 9600, 38400 and 57600 bps. CPU is @ 48MHZ.

Any suggestions?

Labels (1)
0 Kudos
2 Replies

90 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Thu Jul 12 12:11:41 MST 2012
There's also the synchronization instructions DSB, DMB, ISB that are for making sure data access happens in the right order.

In my code since I know how much room is in the FIFO when the threshold bit is set, I just dump a burst in (for writes) or pull a burst (for reads).

Example below:

<code>
void Host_Print_String(char *string) {  // send string to host
  int i;

  FeedWDT;  // give us the full WDT timeout to send the string in case the FIFO is busy
            // will reboot if it can't send the string before the WDT times out, normally shouldn't happen

  while(*string) {  // keep going until we hit null
    while(!(LPC_UART->LSR & 1<<5)) {  // wait for FIFO empty
      vTaskDelay(1);  // wait a tick and try again
    }
    i = 16;  // prepare for burst
    while(i-- && *string) {  // send up to i characters or end of string
      LPC_UART->THR = *(string++);  // send the character and update the pointer
    }
  }
}
</code>
0 Kudos

90 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Wed Jul 11 07:21:01 MST 2012
It's not surprising.

The state machines in the UART are operating asynchronously to the CPU Clock, depending on the clock division factor you are using, and sometimes the baud rate.

if you try to read the THREmpty flag immediately after writing to the uart then it may not have been cleared.

after writing each character to the uart you need to allow sufficient time for the flags to be set before testing them.

on some processor the read may even occur before the write due to write buffers, so beware of this and use a barrier when necessary.

a simple delay in the while loop updating the fifo should solve the problem.


regards

Phil.
0 Kudos