Logomatic / LPC2148 UART Read

<edited, my initial post was prematurely submitted>

Hello, I am extremely new at working with microcontrollers, and I’m new at C as well.

I’m working on the Logomatic main.c code, we have the board set to record analog inputs and then also record what is received on UART0 along with each sample.

The plan was to take the code that was executed for the UART-reading ISR and execute it during the analog-reading ISR.

I took all of the initialization code from the UART mode and inserted it into the analog mode initialization code.

These are the UART initialization commands I am executing:

U0LCR = 0x83; // 8 bits, no parity, 1 stop bit, DLAB = 1

if(baud == 1200)

else if(baud == 115200)

{

U0DLM = 0x00;

U0DLL = 0x20;

}

U0FCR = 0x01;

U0LCR = 0x03;

U0IER = 0x01;

Now when the analog-reading ISR is triggered, I execute the default analog collection commands but I also add in UART collection commands. I have shortened them down to the following code:

while(1)

{

RX_array1[RX_in] = U0RBR;

if(RX_array1[RX_in] != 0x00)

{

rprintf("found something ");

rprintf(“read from uart = %c\n\r”,RX_array1[RX_in]);

RX_in++;

}

}

I have run the program with the board connected to my computer via a TTL/RS-232 converter. When I send the program a message in the terminal, only the first letter of the message is received and echoed back to me. So if I send it “Hello there”, in response I get is “found something read from uart = H”.

The desired behavior is for the board to read every character I send to the UART (H e l l o t h e r e), but it’s not happening. I suspect there is a buffer or timing issue. Before I put the command RX_array[…] = U0RBR in a while loop, I wasn’t reading anything. Does anyone have any pointers?

Thank you!

You need to wait until bit 0 of the status register U0LSR is 1 before attempting to get the next character from U0RBR.

Thank you so much. I can’t wait to give that a try when I get back to the lab.

Hello cfb,

Thank you for the pointer regarding U0LSR. However, my code is still not reading anything more than the first character I send to it. Here is what I set up:

while(1)

{

BRLSRValue = U0LSR; //BRLSRValue is declared as type BYTE, defined as typedef unsigned char BYTE;

if((BRLSRValue & 0x01)== 1) // check if bit 0 is equal to 1

{

RX_array1[RX_in] = U0RBR;

if(RX_array1[RX_in] != 0x00)

{

rprintf("found something ");

rprintf(“read from uart = %c\n\r”,RX_array1[RX_in]);

RX_in++;

}

}

}

My results haven’t changed, my program only echos back the first character I send to it via a terminal. So if I send it “hi there” I get “found something read from uart = h”

Any more ideas?

Thank you!

You copied the setup code for the UART including enabling the receiver interrupt. (U0IER = 1) So the surprising thing isn’t that you only see one character but that you see any at all.

Okay, so enabling the receiver interrupt should prevent me from reading U0RBR. Thank you.

Hmm, removing U0IER = 0x01; or even manually setting it to 0x00 doesn’t result in the program echoing back any more than the first character sent to it.

okay, this is weird. If I send the UART a really long string, it echos back more than 1 character. It echos back the 1st character, and then either the 66th or 67th character.

Make sure that BRLSRValue, U0LSR and U0RBR are declared as volatile otherwise a ‘smart’ C compiler might decide it only needs to read them once and optimize away any successive reads.

Thanks Chris, but I think I got it.

The function rprintf, which is used elsewhere in the code to send text over the serial line, was messing with the UART buffer. To figure it out I had to first switch over to some code that writes to the sd card instead of printing to screen. Another problem that came up was the while(1) loop. There is a main while(1) loop of the code that is used for dumping the log_array variables to the sd card when they get full. But when I used while(1) in my code (which is in an ISR that gets triggered while the main while(1) loop is churning), the main while(1) loop wasn’t getting any cycles to execute. Changing the while(1) that used to be at the top of my code into a while loop that uses a timer and byte counter relieved that problem.

Here is what the final bit of code looks like:

k=0;

timer = 0;

while((k<67)&&(timer<1000000)) //read in 67 bytes or wait x cycles

{

BRLSRValue = U0LSR;

if((BRLSRValue & 0x01) == 1)

{

if(RX_in < 512)

{

RX_array1[RX_in] = U0RBR;

//rprintf(“1read from uart = %c\n\r”,RX_array1[RX_in]);

RX_in++;

if(RX_in == 512) log_array1 = 1;

}

else if(RX_in >= 512)

{

RX_array2[RX_in-512] = U0RBR;

//rprintf(“2read from uart = %c\n\r”,RX_array2[RX_in-512]);

RX_in++;

if(RX_in == 1024)

{

log_array2 = 1;

RX_in = 0;

}

}

k++;

}

timer++;

}