EmbeddedRelated.com
Forums

LPC2148 UART1 using interrupt stop sending data after amount of data

Started by rtoribio 5 years ago5 replieslatest reply 5 years ago171 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:

//----------------------------------------Data frame received---------------------

+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; 

     VICVectAddr7 = (unsigned) UART1Handler;//Vector 7

     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;

  }

   VICVectAddr = 0x00;

}

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

   Process_Datareceived();

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

  }

}



[ - ]
Reply by KocsonyaJanuary 6, 2020

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

ISR()
{
    if ( ( IRQ_source_reg & 0x0e ) == 0x04 ) { 
        process_receive_char; 
    }
    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 ) {
            store_receive_char_in_buffer;
        }
    }
    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 ) {
        ...        
[ - ]
Reply by rtoribioJanuary 6, 2020

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;            
    }    
}    
VICVectAddr = 0x00;
}
void SendCharUART1 (char str){
    U1THR = str;
    while( (U1LSR & 0x40) == 0 ); /* Wait till THRE bit becomes 1 which tells that transmission is completed */
}


Regards,

[ - ]
Reply by KocsonyaJanuary 6, 2020

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.

[ - ]
Reply by rtoribioJanuary 6, 2020

Thank you very much, you were correct the problem was not in the UART functions of sending or receiving. I was in a function that was overflowing an array.

[ - ]
Reply by mr_banditJanuary 6, 2020

A good way to find issues like this is write the simplest program you can have that (in this case) will just read the values and print them out. Basically, isolate the input and make sure it works.

A core concept is simplify, simplify, simplify. Get to the minimum program you can.