## LPC2148 UART1 using interrupt stop sending data after amount of data

Started by 7 months ago5 replieslatest reply 7 months ago54 views

Hello everyone,

I have configured the UART1 of my LPC2148 with

speed(9600 / 8bits / N parity /1bit stop)  with interruption.

The UART1 connects to an ESP-01 I can send and receive

information perfectly. The problem I present is when receiving

a certain amount of data from the ESP-01, the microcontroller

for some reason stops transmitting information and I do not understand what

the reason is. below I leave the configuration and the information that I am

receiving from the ESP when receiving 6 times this frame the microcontroller

stops.

Data frame:

+IPD,4,346:HTTP/1.1 200 OK

Date: Sat, 04 Jan 2020 13:12:46 GMT

Server: xxxxx/x.x.xx (xxxxxx)

Vary: Accept-Encoding

Content-Length: 155

Connection: close

Content-Type: text/html; charset=UTF-8

[{"count":"6","image":"0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,

0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,"}]

OK

//-------------------------------------------------------------------------------------------

Code:

//----------------------------Structure for Data recieved------------------------------------------

typedef struct {

int in;

int out;

char buffer[400];

}p;

p *ptr2,datos_serial2;

//---------------------------Init UART1---------------------------------------------

void uart1_init(void)//9600 BAUD pclock 48MHZ
{
PCONP |= 0x00000010;/* PCRTC = 1 */
PINSEL0 |= 0x00050000; /* Enable RxD1 and TxD1*/
U1LCR=0X83;            //8-data bits, 1 Stop bit, Disable Parity and Enable DLAB
U1DLL=0x38;// MULVAL = 0x5 and DIVADDVAL = 14
U1DLM=1;
U1LCR=0X03;            //cleared DLAB
U1IER= 0x00000001;//Enable Interrupt
}

//---------------------------------Send Char----------------

void SendCharUART1 (char str){

U1THR = str;

while( (U1LSR & 0x40) == 0 ); /* Wait till THRE bit becomes 1 which tells that transmission is completed */

}

//--------------------------------Interrupt enable------------------------------------------------------

void UART1_Interrupt_EN(void)

{

// VICIntSelect = 0x00000000;

VICVectCntl7 = 0x00000020 | 7; //select UART1 interrupt as IRQ i.e vector 7

VICIntEnable |=(1UL<<7);//interrupt ena.

}

//------------------------------------------Interrupt IRQ--------------------------------------------

void UART1Handler (void)  __irq

{

//    /* Serial Receive Interrupt. */

char recieved;

if ((U1IIR & 0x0E) == 0x04) {

recieved=U1RBR;

ptr2 = &datos_serial2;

if(ptr2->in>=399)

ptr2->in=0;

ptr2->buffer[ptr2->in++]=recieved;

}

}

//-----------------------------------------Main-------------------

int main()

{

uart1_init();

UART1_Interrupt_EN();

while(1){

sendata_esp01();      //Process to send data to ESP01

delay()

//----------------- Algorithm to process the received data------------------//

//--------------------------------------------------------------------------------------//

}

}

[ - ]

A possible issue is that in your ISR you have the following:

ISR()
{
if ( ( IRQ_source_reg & 0x0e ) == 0x04 ) {
}
clear_the_VIC;}

The problem is, when you enable the RX IRQ, you also enable the the RX timeout IRQ (see the description of the RBR bit for the U1IER reg in the User manual) which has the code of 0x0c. So if that IRQ ever comes in, you will never clear it and thus will just spin in the ISR - as soon as you clear the IRQ on the VIC, you get an other one, as the UART will still assert its request line.

I'm not saying that that is the problem, but it can be if you ever miss a character. Your ISR clears only one char from the FIFO, which should be OK as long as you never disable the IRQ for more than 1 character, but if you do, then you might have that problem, so it probably is worth to take a look. Maybe something like this:

ISR()
{
int temp;

temp = IRQ_source_reg & 0x0e;
if ( temp == 0x04 || temp == 0x0c ) {
while ( line_status_reg & 0x01 ) {
}
}
clear_the_VIC;
}                     

In fact, since you don't enable any other interrupt, you don't even need to check what the IIR contains, it's enough if you read it, then you move to the line status reg loop:

ISR()
{
(void) IQR_source_reg;
while ( line_status_reg & 0x01 ) {
...        
[ - ]

What you raise is correct, I made the changes you recommended but the

problem continues. I must emphasize that upon receiving 6 continuous

data frames, the microcontroller specifically stops 6.

void UART1Handler (void)  __irq{
int temp; char recieved;
temp = U1IIR & 0x0e;
if ( temp == 0x04 || temp == 0x0c ) {
while ( U1LSR & 0x01 ) {
recieved=U1RBR;
ptr2 = &datos_serial2;
if(ptr2->in>=399)
ptr2->in=0;
ptr2->buffer[ptr2->in++]=recieved;
}
}
}

void SendCharUART1 (char str){
U1THR = str;
while( (U1LSR & 0x40) == 0 ); /* Wait till THRE bit becomes 1 which tells that transmission is completed */
}

Regards,

[ - ]

Do you have one or more spare port pin(s) to which you can put a scope?

You could toggle them every time you enter and leave the ISR and also every time you enter an leave the send routine. Like, setting them to 1 on entry and clear to 0 on leave. Then when your code stops, you can see whether it's stuck in one those routines.

It might be possible that your UART handler has no problems, but the rest of the code, which processes the requests and creates the response gets stuck somewhere after 6 frames received.

This port-pin toggling business is painful, but I found that it can help to solve very ugly software bugs when you have no other means of debug. Plus it needs no extra RAM, has minimal effect on timing and in general, it's the least intrusive debug tool you can have.

[ - ]