UART help... plzz.....

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

UART help... plzz.....

1,501 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by karanmehta93 on Wed Nov 07 12:12:43 MST 2012
I am trying to use my own fifo as the internal fifo is not useful for my application. Can you see the code and tell me when the UART0ExtPrintbin function will be called and it is a THRE interrupt handler.

void ExtPrintbin(unsigned short channel,unsigned short variable,unsigned short value){

switch(channel){
//-----------------------------------
case COM0:
switch(variable){
//--------------------------------
case 1:
if((U0LSR & 0x60) ==0x60){
U0THR=value;
}
else{
uart0tx[0] = value;
uart0txdone[0] = 1;
}
break;
//--------------------------------
case 2:
if((U0LSR & 0x60) ==0x60){
U0THR=value;
}
else{
uart0tx[1] = value;
uart0txdone[1] = 1;
}
break;
//--------------------------------
case 3:
if((U0LSR & 0x60) ==0x60){
U0THR=value;
}
else{
uart0tx[2] = value;
uart0txdone[2] = 1;
}
break;
//--------------------------------
case 4:
if((U0LSR & 0x60) ==0x60){
U0THR=value;
}
else{
uart0tx[3] = value;
uart0txdone[3] = 1;
}
break;
//--------------------------------
}
}
void uart0ExtPrintbin(void){

static short txcount = 0;
unsigned short done = 1,count = 0;
while(done && (count < 4)){

if(txcount == 0){

txcount = 1;
count++;
if(uart0txdone[0] == 1){

if( (U0LSR & 0x60) !=0x60 ){
U0THR = uart0tx[0];
uart0txdone[0] = 0;
}
done = 0;
}
}
else if(txcount == 1){

txcount = 2;
count++;
if(uart0txdone[1] == 1){

if( (U0LSR & 0x60) !=0x60 ){
U0THR = uart0tx[1];
uart0txdone[1] = 0;
}
done = 0;
}
}
else if(txcount == 2){

txcount = 3;
count++;
if(uart0txdone[2] == 1){

if( (U0LSR & 0x60) !=0x60 ){
U0THR = uart0tx[2];
uart0txdone[2] = 0;
}
done = 0;
}
}
else if(txcount == 3){

txcount = 0;
count++;
if(uart0txdone[3] == 1){

if( (U0LSR & 0x60) !=0x60 ){
U0THR = uart0tx[3];
uart0txdone[3] = 0;
}
done = 0;
}
}
}
}
Please reply fast......!!!
0 Kudos
Reply
8 Replies

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Fri Nov 09 22:33:35 MST 2012
I take it you have the FIFOEN bit cleared.

Just from reading the data sheet it's not clear to me exactly what happens but most of those flags work on the top byte in the FIFO, if there's no FIFO I would think they still work, after all the THR still gets emptied when the byte has gone so the THRE interrupt would still be invoked.

How about writing a 3-line program that puts a byte into the THR and an ISR for THRE and see if it fires.
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by karanmehta93 on Thu Nov 08 10:15:24 MST 2012
Sorry for the "#" first of all. I am new and therefore I didn't knew that.
The fact is that this code works perfectly. The FIFO's are disabled. Don't worry about DLAB  it's appropriately set .

The uart0txdone is a variable that changes it's value once the number is sent.
See the following case:
You work at 120 MHz clock speed and your UART baud rate is 9600 bps.
You are continuously sending four numbers.
The speed of excecution of program will be much faster.
If I write the following code
void Printbin(unsigned short channel,unsigned short value)
{
 switch (channel)
  {
  case COM0:
    while((U0LSR & 0x60) !=0x60);
 U0THR=value;
break;

  case COM1:
while((U1LSR & 0x60) != 0x60);
 U1THR=value;
break;

case COM2:
while((U2LSR & 0x60) != 0x60);
 U2THR=value;
break;

  case COM3:
while((U3LSR & 0x60) != 0x60);
 U3THR=value;
break;
}
}

Then the program will have to wait till it sends one number. Thus my work will slow down. So I want to transfer this work on interrupt so that it works automatically. I am using THRE interrupt for it. and this works. That is why I am not getting When is the THRE interrupt being called inspite of FIFO's being disabled.
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Thu Nov 08 08:09:25 MST 2012
Just to give you some idea how verbose that code is, here's an example of this sort of thing

unsigned short tx_fifo[4];
unsigned short wr_offset = 0;
volatile unsigned short rd_offset = 0;
volatile unsigned short count = 0;


void ExtPrintbin(unsigned short channel, unsigned short value)  {
  
  if((U0LSR & 0x60) ==0x60) {
    U0THR = value;
  } else  {
    tx_fifo[wr_offset++] = value;
    wr_offset &= 0x03;    // wrap the offset from 3 to 0
    count++;
  }
}

void ISR_uart0ExtPrintbin(void) {

  if (count) {
    U0THR = tx_fifo[rd_offset--];
    rd_offset &= 0x03;
    count--;
  }  
}


This is not the full deal, for example there's no bounds test on the array, but it's close to what is normal I think.. This implements a proper FIFO as well.
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Thu Nov 08 07:35:20 MST 2012
So as I understand it

uart0ExtPrintbin() is the ISR.
ExtPrintbin() is a function you call to send bytes.

There's so much duplicated code there it makes my brain hurt.

#ExtPrintbin(COM1,1,64);
#ExtPrintbin(COM1,2,192);
What language is this with # at the start of a line?

If the FIFO is set up correctly uart0ExtPrintbin() should trigger when the FIFO is empty. Is the THREIE bit set to enable the interrupt?

Also, I think the DLAB bit has to be cleared before you can write to the FIFO. Is that the case?

BTW the array you have set up is not a FIFO, more some form of random-access buffer. Do you really need a FIFO (aka circular buffer) or will you always be sending 4 bytes? Your example code shows 2 bytes.

uart0txdone[1] = 1;
What does the 1 do after every byte that is written into the uart0txdone buffer? For that matter what's the uart0txdone array for?
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by karanmehta93 on Thu Nov 08 06:39:06 MST 2012
Uart0Ext printbin is THRE interrupt handler function. and the ExtPrintbin is the function to which I will send the value which is to be transmitted through UART.
The UART fifo is the variable uart0tx. while the internal fifo's are disabled.

Now I want to know that when will the interrupt handler be called?
Supposing there are two lines in my code
#ExtPrintbin(COM1,1,64);
#ExtPrintbin(COM1,2,192);

in an infinite loop. My sytem clock is at 120 Mhz through PLL but the baud rate is just 9600.
So just tell me when the interrupt will be called
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Thu Nov 08 04:33:49 MST 2012

Quote:
tell me when the UART0ExtPrintbin function will be called

Is UART0ExtPrintbi() a weakly-defined ISR on your system? It's not on mine, so how are we supposed to know when it's called without all the code?

And for those who don't want to download a DOC file

void uart0ExtPrintbin(void) {

  static short txcount = 0;
  unsigned short done = 1,count = 0;
  while(done && (count < 4))  {

    if(txcount == 0)  {

      txcount = 1;
      count++;
      if(uart0txdone[0] == 1) {
    
        if( (U0LSR & 0x60) !=0x60 ) {
          U0THR = uart0tx[0];
          uart0txdone[0] = 0;
        }
        done = 0;
      }
    }
    else if(txcount == 1) {
      
      txcount = 2;
      count++;
      if(uart0txdone[1] == 1) {
    
        if( (U0LSR & 0x60) !=0x60 ) {
          U0THR = uart0tx[1];
          uart0txdone[1] = 0;
        }
        done = 0;
      }
    }
    else if(txcount == 2) {
      
      txcount = 3;
      count++;
      if(uart0txdone[2] == 1) {
    
        if( (U0LSR & 0x60) !=0x60 ) {
          U0THR = uart0tx[2];
          uart0txdone[2] = 0;
        }
        done = 0;
      }
    }
    else if(txcount == 3) {
      
      txcount = 0;
      count++;
      if(uart0txdone[3] == 1) {
    
        if( (U0LSR & 0x60) !=0x60 ) {
          U0THR = uart0tx[3];
          uart0txdone[3] = 0;
        }
        done = 0;
      }
    } 
  }
}

void ExtPrintbin(unsigned short channel,unsigned short variable,unsigned short value)  {
  
  switch(channel) {
    //-----------------------------------
    case COM0:
      switch(variable)  {
        //--------------------------------
        case 1:
          if((U0LSR & 0x60) ==0x60) {
            U0THR=value;
          }
          else  {
            uart0tx[0] = value;
            uart0txdone[0] = 1;
          }
        break;
        //--------------------------------
        case 2:
          if((U0LSR & 0x60) ==0x60) {
            U0THR=value;
          }
          else  {
            uart0tx[1] = value;
            uart0txdone[1] = 1;
          }
        break;
        //--------------------------------
        case 3:
          if((U0LSR & 0x60) ==0x60) {
            U0THR=value;
          }
          else  {
            uart0tx[2] = value;
            uart0txdone[2] = 1;
          }
        break;
        //--------------------------------
        case 4:
          if((U0LSR & 0x60) ==0x60) {
            U0THR=value;
          }
          else  {
            uart0tx[3] = value;
            uart0txdone[3] = 1;
          }
        break;
        //--------------------------------
      }
    break;
}
karanmehta93, learn to use the # button at the top of the editing area to insert CODE tags around line of code.

Both those functions are badly written, is one a variation on the other? Are they supposed to be variations on a THRE interrupt handler?

Where is your "FIFO", is that the 4-byte array you're indexing into?
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by karanmehta93 on Thu Nov 08 03:22:12 MST 2012
See the attachements...
0 Kudos
Reply

1,486 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Wed Nov 07 16:43:46 MST 2012
Please format your code so it's readable.....!!!
0 Kudos
Reply