EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

The uart of LPC2366 don't transmit data continuely

Started by Hieagle April 13, 2010
Hi, Can someone help me please.
I use KEIL uvision and ulink2 to test the uart of lpc2366.
There are a data packet of fifteen bytes to tranmit by uart of LPC2366 each second.
When I use the program below:
for(i=0;i<15;i++)
{
U2THR=txd_buf[i];
while ((U2LSR & 0x40) == 0);
}
The Uart2 can transmit data successfully.
But using FIFO of 8 bytes to receive data packet, the received data are wrong.
It seems like the uart don't transmit data continuely;
How to transmit data continuely using Uart of LPC2366?
Even using THRE Interupt to transmit data packet, it don't work finely for each time.

more program below:

uint8 status;
uint8 txd_buf[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

void __irq IRQ_UART0 (void)
{
uint8 i;
uint32 IIR = 0;

/* UART0 ISR */
while (((IIR = U0IIR) & 0x01) == 0)
{
switch (IIR & 0x0e)
{
case 0x02: // TX FIFO empty
if(status>)
{
status=0;
U2IER &= ~0x02;
}
else U2THR = aux2_buf[status];
status++;
break;

case 0x04:
break;

case 0x0c:
break;

default :
i=U0LSR;
break;
}
}
VICVectAddr = 0x00;
}

int main(void)
{
uint32 i = 0;
UART0_Init();
UART2_Init();
UART3_Init();

T0TC = 0;
T0PR = 0;
T0MCR = 0x03;
T0MR0 = (Fpclk); //1s

IO0DIR |= 0x3<<27;
IO0CLR |= 0x3<<27;

T0TCR = 0x01; //start Timer0
while (1)
{
IO0SET |= 0x3<<27;

if((T0IR & 0x01) != 0 )
//for(i=0;i<0x2FFFFF;i++);
{
T0IR=0x01;
for(i=0;i<15;i++)
{
U2THR=txd_buf[i];
while ((U2LSR & 0x40) == 0);
}
for(i=0;i<0x2FFFF;i++); //delay

for(i=0;i<15;i++)
{
U3THR=txd_buf[i];
while ((U3LSR & 0x40) == 0);
}
for(i=0;i<0x2FFFF;i++); //delay
}
}
return (0);
}

An Engineer's Guide to the LPC2100 Series

Hieagle wrote:
> The Uart2 can transmit data successfully.

How do you know?

> But using FIFO of 8 bytes to receive data packet, the received data are
> wrong.

Doesn't that point at reception problem?

> It seems like the uart don't transmit data continuely;

Why? Transmitting slower would be easier for the receiver, wouldn't it?

> How to transmit data continuely using Uart of LPC2366?

Making sure, that the SW manage to fill the transmit buffer fast enough.

> Even using THRE Interupt to transmit data packet, it don't work finely
> for each time.

*How* doesn't it work?

--

Timo

--- In l..., tike64@... wrote:
Thank you very much.

I use the hyperterminal to receive datawhich are all correct. So I think The Uart2 can transmit data successfully. In the case I make the board act as slave to transmit data.

Then I use another LPC2366 Board acted as host to receive the data. It uses 8bytes FIFO RX and enable RDA, CTI in ISR. By using the hyperterminal again to test, the second LPC2366 Board can receive and tranmit data paceket successfully.

But using the first LPC2366 to transmit data to second one, the second LPC2366 Board recevies data incorrectly.

What is wrong with it?

Hieagle wrote:
> I use the hyperterminal to receive datawhich are all correct. So I
> think The Uart2 can transmit data successfully. In the case I make the
> board act as slave to transmit data.

What do you mean by 'making it slave'?

> Then I use another LPC2366 Board acted as host to receive the data. It
> uses 8bytes FIFO RX and enable RDA, CTI in ISR. By using the
> hyperterminal again to test, the second LPC2366 Board can receive and
> tranmit data paceket successfully.

What do you mean by 'host'? Did you try to send bursts of data?

> But using the first LPC2366 to transmit data to second one, the second
> LPC2366 Board recevies data incorrectly.

But *how*? Does it lose characters or receive garbage or what?

> What is wrong with it?

Dunno. Need more details.

--

Timo

Thanks!

I take one Lpc2366 board as a slave to transmit data packet, another LPC2366 board as a host to receive datas.
By tracing the operation of the program, I found the uart2 can transmit data successfully.
The problem is the uart of host receives data packet incorrectly.
The setting of the uart is enabled 8 bytes RX FIFO, RDA interrupt, CTI interrupt and RLS interrupt.
When slave transmits a data packet of 15 bytes, the the uart of host gets into RLS interrupt, RDA interrupt, RLS interrupt, RLS interrupt, CTI interrupt, RLS interrupt sequentially.
The crystal is 11.0592KHz, the baudrate is 9600bps accurately in two board.

It makes me very confused.

some program as below:
void UART2_Init(void)
{
uint32 Fdiv = 0;

PCONP |= 1 << 24;
PINSEL0 |= (0x01 << 20) | (0x01 << 22);

U2LCR = 0x83;
Fdiv = (Fpclk / 16) / UART2_BAUD; //UART2_BAUD00
U2DLM = Fdiv / 256;
U2DLL = Fdiv % 256;
U2LCR = 0x03; //DLAB=0
U2FCR |= 0x87; //RX FIFO=8

U2FDR &= ~0x0f;
U2FDR |= 0x10;
U2IER = 0x05;

VICIntEnClr |= 1 << UART2_INT;
VICVectPri28 = 0x06;
VICVectAddr28 = (uint32)IRQ_UART2;
VICIntEnable |= 1 << UART2_INT;
}
void __irq IRQ_UART2 (void)
{
uint8 i;
uint32 IIR = 0;

/* UART2 ISR */
while (((IIR = U2IIR) & 0x01) == 0)
{
switch (IIR & 0x0e)
{
case 0x02: // THRE
break;

case 0x04: // RDA
for (i=0; i<8; i++)
{
rcv2_buf[i] = U2RBR;
}
break;

case 0x0c: // CTI
for (i=8; i<16; i++)
{
rcv2_buf[i] = U2RBR;
}
rcv2_new=2;
break;

case 0x06: // RLS
break;
default :
break;
}
}
VICVectAddr = 0x00;
}

See my comments below.

> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Hieagle
> Sent: Wednesday, April 14, 2010 8:32 PM
> To: l...
> Subject: [lpc2000] Re: The uart of LPC2366 don't transmit data
> continuely
> Thanks!
>
> I take one Lpc2366 board as a slave to transmit data packet,
> another LPC2366 board as a host to receive datas.
> By tracing the operation of the program, I found the uart2
> can transmit data successfully.
> The problem is the uart of host receives data packet incorrectly.
> The setting of the uart is enabled 8 bytes RX FIFO, RDA
> interrupt, CTI interrupt and RLS interrupt.
> When slave transmits a data packet of 15 bytes, the the uart
> of host gets into RLS interrupt, RDA interrupt, RLS
> interrupt, RLS interrupt, CTI interrupt, RLS interrupt sequentially.
> The crystal is 11.0592KHz, the baudrate is 9600bps accurately
> in two board.
>
> It makes me very confused.
>
> some program as below:
> void UART2_Init(void)
> {
> uint32 Fdiv = 0;
>
> PCONP |= 1 << 24;
> PINSEL0 |= (0x01 << 20) | (0x01 << 22);
>
> U2LCR = 0x83;
> Fdiv = (Fpclk / 16) / UART2_BAUD; //UART2_BAUD00
> U2DLM = Fdiv / 256;
> U2DLL = Fdiv % 256;
> U2LCR = 0x03; //DLAB=0
> U2FCR |= 0x87; //RX FIFO=8
>
> U2FDR &= ~0x0f;
> U2FDR |= 0x10;
> U2IER = 0x05;
>
> VICIntEnClr |= 1 << UART2_INT;
> VICVectPri28 = 0x06;
> VICVectAddr28 = (uint32)IRQ_UART2;
> VICIntEnable |= 1 << UART2_INT;
> }
> void __irq IRQ_UART2 (void)
> {
> uint8 i;
> uint32 IIR = 0;
>
> /* UART2 ISR */
> while (((IIR = U2IIR) & 0x01) == 0)
> {
> switch (IIR & 0x0e)
> {
> case 0x02: // THRE
> break;
>
> case 0x04: // RDA
> for (i=0; i<8; i++)
> {
> rcv2_buf[i] = U2RBR;
> }
> break;

Case 0x04 will probably work ok, but it is better to check
the RDR flag in the U2LSR register to determine if there are
anymore bytes in the FIFO. It is always a good idea to
completely empty the FIFO when one of the receive interrupts
are triggered.

>
> case 0x0c: // CTI
> for (i=8; i<16; i++)
> {
> rcv2_buf[i] = U2RBR;
> }
> rcv2_new=2;
> break;

Why do you think that there would be 8 bytes in the FIFO when
this interrupt is reached? This interrupt is generated on a
timeout, so there could be any number of bytes in the FIFO.
You must check the RDR flag here. Cases 0x04, and 0x0c can
use the same code if implemented correctly.

>
> case 0x06: // RLS
> break;

You may be hitting this due to an overrun, since you may not
be emptying the FIFO in the current implementation. If you
checked the error bits in U2LSR, you could find out the cause.

> default :
> break;
> }
> }
> VICVectAddr = 0x00;
> }
>

Good luck,

Mike

One more comment below.

> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Hieagle
> Sent: Wednesday, April 14, 2010 8:32 PM
> To: l...
> Subject: [lpc2000] Re: The uart of LPC2366 don't transmit data
> continuely


> void __irq IRQ_UART2 (void)
> {
> uint8 i;
> uint32 IIR = 0;
>
> /* UART2 ISR */
> while (((IIR = U2IIR) & 0x01) == 0)
> {
> switch (IIR & 0x0e)
> {
> case 0x02: // THRE
> break;
>
> case 0x04: // RDA
> for (i=0; i<8; i++)
> {
> rcv2_buf[i] = U2RBR;
> }
> break;
>
> case 0x0c: // CTI
> for (i=8; i<16; i++)
> {
> rcv2_buf[i] = U2RBR;
> }
> rcv2_new=2;
> break;
>
> case 0x06: // RLS
> break;

You need to read the U2LSR register to clear the RLS interrupt
flag. This is likely why you are seening multiple RLS interrupts.

> default :
> break;
> }
> }
> VICVectAddr = 0x00;
> }
>

Mike

After debugging carefully, I finally found the key to the problem.

The circuit of uart has little disturb in txd and rxd line.
The hyperterminal can receive datas correctly. Nevertheless, using the another board to receive datas would enlarge the disturb caused wrong data.By adjusting the baudrate lower, the communication is correct immediately.
Although the program works well now, it still need some improvements such as RLS interrupt.

Thanks a lot to all of you!


The 2024 Embedded Online Conference