UART loses bytes

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UART loses bytes

1,125 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brattchess on Sat Jan 24 10:31:07 MST 2015
Hello,

I'm trying to communicate my LCP1114 with my PC.
The problem occurs when I send bytes without sleep(1) then the micro only captures the last byte.

I have a solution with the sleep function.
The real problem is using the RN4020 where I can not modify how the frame is sent.

Why the LCP1114 can not process the frame?


I have the same problem sending to 115200 or 19200.
Labels (1)
0 Kudos
10 Replies

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Sun Jan 25 22:28:38 MST 2015
I'm not sure why you are using this old CMSIS sample instead LPCOpen  :quest:

Anyway, I would recommend to use a more modern sample and test it with a file (= send a file with TeraTerm and let it echo this file later) 

Something like below:

/*
===============================================================================
 Name        : main.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : demo code to receive small files and echo them...
===============================================================================
*/

#include "LPC11xx.h"

#define UART_SPEED115200

#define IER_RBR0x01
#define IER_THRE0x02
#define IER_RLS0x04

#define IIR_PEND0x01
#define IIR_RLS0x03
#define IIR_RDA0x02
#define IIR_CTI0x06
#define IIR_THRE0x01

#define LSR_RDR0x01
#define LSR_OE0x02
#define LSR_PE0x04
#define LSR_FE0x08
#define LSR_BI0x10
#define LSR_THRE0x20
#define LSR_TEMT0x40
#define LSR_RXFE0x80

#define LCR_WLEN80x03
#define LCR_SBS_1BIT(0<<2)
#define LCR_PARITY_DIS (0<<3)
#define LCR_DLAB(1<<7)

#define FCR_FIFO(1<<0)
#define FCR_RX_RS(1<<1)
#define FCR_TX_RS(1<<2)
#define FCR_TRG_LEV2(2<<6)

#define TER_TXEN(1<<7)

#define UART_CLOCK 12

void UART_init(void);
void UART_tx(uint8_t *BufferPtr, uint32_t Length);

#ifdef __cplusplus
extern "C" {
#endif

volatile uint8_t r_buff[1024];//read buffer
volatile uint16_t counter=0;
volatile uint16_t i = 0;

void UART_IRQHandler(void)
{
 while (LPC_UART->LSR & LSR_RDR)
 {
  r_buff[counter] = LPC_UART->RBR & 0XFF;
  counter++;
  if(counter>= 1024) counter =0;
  i = 0;
 }
}

#ifdef __cplusplus
}
#endif


int main(void)
{
 SystemCoreClockUpdate();
 UART_init();
 while(1)
 {
  i++;
  if(i>5E4)
  {
   i=0;
   if(counter)
   {
    UART_tx((uint8_t*)&r_buff[0],counter);
counter =0;
   }
  }
 }
 return 0 ;
}


void UART_init(void)
{
 uint32_t div;
 //pin init
 LPC_IOCON->PIO1_6 &= ~0x3F;
 LPC_IOCON->PIO1_6 |=  0x01;//function1: RxD
 LPC_IOCON->PIO1_7 &= ~0x3F;
 LPC_IOCON->PIO1_7 |=  0x01; //function1: TxD
 /* Setup UART */
 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << UART_CLOCK);//enable clock
 LPC_SYSCON->UARTCLKDIV  =  1;
 /* Enable FIFOs by default, reset them */
 LPC_UART->FCR = (FCR_FIFO | FCR_RX_RS | FCR_TX_RS);
 /* Default 8N1, with DLAB disabled */
 LPC_UART->LCR = (LCR_WLEN8 | LCR_SBS_1BIT | LCR_PARITY_DIS);
 /* Disable fractional divider */
 LPC_UART->FDR = 0x10;
 /* Determine UART clock in rate without FDR */
 div = SystemCoreClock / (UART_SPEED * 16);
 LPC_UART->LCR |= LCR_DLAB;
/* High and low halves of the divider */
 LPC_UART->DLM = (uint32_t) div / 256;
 LPC_UART->DLL = (uint32_t) div - ((uint32_t)LPC_UART->DLM * 256);
 LPC_UART->LCR &= ~LCR_DLAB;

 LPC_UART->LCR = (LCR_WLEN8 | LCR_SBS_1BIT);
 LPC_UART->FCR = (FCR_FIFO | FCR_TRG_LEV2);

 LPC_UART->IER |= (IER_RBR | IER_RLS);
 NVIC_EnableIRQ(UART_IRQn);
}

void UART_tx(uint8_t *BufferPtr, uint32_t length)
{
 while (length != 0)
 {
  while (!(LPC_UART->LSR & LSR_THRE));
  LPC_UART->THR = *BufferPtr;
  BufferPtr++;
  length--;
 }
}

0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brattchess on Sun Jan 25 06:32:43 MST 2015
Hello,

I changed it:

LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS;/* Enable UART interrupt */

void UART_IRQHandler(void){

  uint8_t Dummy    = Dummy;
  uint8_t IIRValue = LPC_UART->IIR;
  uint8_t RBRValue = LPC_UART->RBR;
  LPC_UART->FCR &= ~0x31;
  LPC_UART->FCR |= 0x01;


  _changeValueDebug(DEBUG_PORT,DEBUG_BIT);


  IIRValue >>= 1;/* skip pending bit in IIR */
  IIRValue &= 0x07;/* check bit 1~3, interrupt identification */
  if (IIRValue == IIR_RLS){/* Receive Line Status */

  uint8_t 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 */
  comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS]  = RBRValue;
  comm_buffer_in_idx_LULA_BUS++;
  }


  }else if(IIRValue == IIR_RDA){/* Receive Data Available */



  //comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS] = LPC_UART->RBR;
  comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS]  = RBRValue;
  comm_buffer_in_idx_LULA_BUS++;


  if( comm_buffer_in_idx_LULA_BUS >= 3 /*&&
      comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS-2]== 0x0D &&
      comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS-1]== 0x0A*/ ){



  _changeValueDebug(LED_PORT,LED_BIT);
  //_changeValueDebug(DEBUG_PORT,DEBUG_BIT);
  }
  if( comm_buffer_in_idx_LULA_BUS >= NUM_BYTES_BUFFER_IN_LULA_BUS ){
  comm_buffer_in_idx_LULA_BUS = 0;

  }


  /*if( comm_buffer_in_idx_LULA_BUS >= NUM_BYTES_BUFFER_LULA_BUS ){
  comm_buffer_in_idx_LULA_BUS = 0;

  _changeValueDebug(DEBUG_PORT,DEBUG_BIT);
  }*/



  }else if(IIRValue == IIR_CTI){/* Character timeout indicator */

  //_changeValueDebug();

  }else if (IIRValue == IIR_THRE){/* THRE, transmit holding register empty */

  if( comm_buffer_out_idx_LULA_BUS >= comm_buffer_out_len_LULA_BUS ){ // if the frame is sent

  }else{ SEND_BYTE_LULA_BUS; }

  }

  //_changeValueDebug(DEBUG_PORT,DEBUG_BIT);


  return;
}


I have not any interrupt by IIR_RLS.
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by capiman on Sun Jan 25 04:42:08 MST 2015
U0LSR could tell you, if there was an error like an overrun.
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by capiman on Sun Jan 25 04:34:54 MST 2015
Additional to what R2D2 already wrote, are you sure that

LPC_IOCON->PIO1_6 |= 0x09; /* configure UART RXD pin */ \
LPC_IOCON->PIO1_7 |= 0x11; /* configure UART TXD pin */ \
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); /*enable clock to UART (sec. 3.5.14)*/ \
LPC_SYSCON->UARTCLKDIV |= 0x9B; /*0x9B will give approx. 19.2K baud signal (sec. 3.5.16)*/ \
LPC_UART->FCR |= 0x01; /*enable UART FIFOs (necessary for operation) (sec. 13.5.6)*/ \
LPC_UART->LCR |= 0x0B; /*set for 8bit data, 1 stop, parity odd */ \
LPC_UART->TER |= 0x80; /*transmit enable (sec. 13.5.16)*/ \

will set the values you want?

Just an example:

LPC_UART->LCR |= 0x0B;

What happens when there was

LPC_UART->LCR |= 0x0F;

before? Do you really want to set only these bits or also all other bits to 0?


0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brattchess on Sun Jan 25 04:34:09 MST 2015
Hello,

I have not enable the IER_RLS.
I only want the interrupt of Data available.

Is it not correct?
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Sun Jan 25 04:20:12 MST 2015

Quote: brattchess
My conclusion is the LCP1114 UART needs a little delay between sended bytes...





That's not the 'LCP1114 UART' that's your code...

if (IIRValue == IIR_RLS){ /* Receive Line Status */
[color=#f00]/*  where is the code here ????? */[/color]
}
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brattchess on Sun Jan 25 04:06:40 MST 2015
Hello,

Conf UART:

#define CONF_UART                       
                                                                                                                                                                                                       \
/*SET UP UART (sec. 13.2 in datasheet "BASIC CONFIGURATION")*/\
LPC_IOCON->PIO1_6         |= 0x09; /* configure UART RXD pin */\
LPC_IOCON->PIO1_7   |= 0x11;      /* configure UART TXD pin */\
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);    /*enable clock to UART (sec. 3.5.14)*/\
LPC_SYSCON->UARTCLKDIV    |= 0x9B;       /*0x9B will give approx. 19.2K baud signal (sec. 3.5.16)*/\
LPC_UART->FCR             |= 0x01;       /*enable UART FIFOs (necessary for operation) (sec. 13.5.6)*/       \
LPC_UART->LCR             |= 0x0B;       /*set for 8bit data, 1 stop, parity odd */    \
LPC_UART->TER             |= 0x80;       /*transmit enable (sec. 13.5.16)*/     \
                                                                                                                                                                                      \
/* Enable the UART Interrupt */      \
NVIC_EnableIRQ(UART_IRQn);      \
LPC_UART->IER = IER_RBR | IER_THRE;/* Enable UART interrupt */




Interrupt function:

void UART_IRQHandler(void){

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


  }else if(IIRValue == IIR_RDA){/* Receive Data Available */

  comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS] = LPC_UART->RBR;
  comm_buffer_in_idx_LULA_BUS++;


  if( comm_buffer_in_idx_LULA_BUS >= 2 /*&&
      comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS-2]== 0x0D &&
      comm_buffer_in_LULA_BUS[comm_buffer_in_idx_LULA_BUS-1]== 0x0A*/ ){

  _changeValueDebug(LED_PORT,LED_BIT);
  //_changeValueDebug(DEBUG_PORT,DEBUG_BIT);
  }
  if( comm_buffer_in_idx_LULA_BUS >= NUM_BYTES_BUFFER_IN_LULA_BUS ){
  comm_buffer_in_idx_LULA_BUS = 0;

  }


  /*if( comm_buffer_in_idx_LULA_BUS >= NUM_BYTES_BUFFER_LULA_BUS ){
  comm_buffer_in_idx_LULA_BUS = 0;

  _changeValueDebug(DEBUG_PORT,DEBUG_BIT);
  }*/



  }else if(IIRValue == IIR_CTI){/* Character timeout indicator */

  //_changeValueDebug();

  }else if (IIRValue == IIR_THRE){/* THRE, transmit holding register empty */

  if( comm_buffer_out_idx_LULA_BUS >= comm_buffer_out_len_LULA_BUS ){ // if the frame is sent

  }else{ SEND_BYTE_LULA_BUS; }

  }
  return;
}



My conclusion is the LCP1114 UART needs a little delay between sended bytes, but the PC can read it without problems.
But the module that I am using, I can not modify the firmware to wide this gap.
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by capiman on Sun Jan 25 02:02:43 MST 2015
Perhaps show us your code or even upload the complete project?
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by brattchess on Sun Jan 25 01:25:59 MST 2015
Hello,

My interrupt function is very short.
I save the received byte in a buffer then I add a counter to know the number of bytes received.

If I put a sleep(1) between each sended byte, the LCP1114 receives the frame correctly.

Thanks.
0 Kudos

1,031 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by capiman on Sat Jan 24 10:34:25 MST 2015
Show or explain us, how you receive the bytes on LPC1114.
0 Kudos