Fail to send a string via UART to the Terminal with KE06

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

Fail to send a string via UART to the Terminal with KE06

711 Views
MAPC
Senior Contributor I

Hello,

I'm facing such a strange issue when I send a string to the Terminal. I'm using FRDM_KE06Z to perform the tests. I did something very simple in KDS. Acording to the character typed on the Terminal and received by UART Receive Buffer interrupt, I print a message back on the Terminal. That is my code:

void envia_string(byte *dado_string){

  for(x=0;x<strlen(dado_string);x++){

  if(UART1_S1&UART_S1_TDRE_MASK)

     UART1_D=dado_string[x];

     while(UART1_S1&UART_S1_TC_MASK==0){}

     }

}

int main(void)

{

  PE_low_level_init();

  for(;;){

   if(dado_recebido=='1'){

  envia_string("You typed 1\r\n");

  dado_recebido=0;

   }

   if(dado_recebido=='2'){

   envia_string("You typed 2\r\n");

  dado_recebido=0;

    }

   if(dado_recebido=='3'){

   envia_string("You typed 3\r\n");

  dado_recebido=0;

    }

When I put it to run, only the first letter or some letters are printed on the Terminal. If I run "envia_string" function step by step on Debugger, it prints all the messages correctly. I'm very confused about that.

Can anybody help me on it, please?

pastedImage_14.png

Thanks!

Marco Coelho

4 Replies

468 Views
mjbcswitzerland
Specialist V

Marco

You need to read how the flags work and then you will unserstand the problem.

I would simplify as follows:

void envia_string(byte *dado_string){

  for(x=0;x<strlen(dado_string);x++){

     while((UART1_S1&UART_S1_TDRE_MASK) == 0) {} // wait until there is space in the output

     UART1_D=dado_string[x]; // write to the output buffer

}

However your code is blocking and so not advisable unless used under a pre-emptive operating sytem or in just the simplest of test cases.

You should look an interrupt driven driver.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

KE: http://www.utasker.com/kinetis/FRDM-KE02Z.html / http://www.utasker.com/kinetis/FRDM-KE02Z40M.html / http://www.utasker.com/kinetis/FRDM-KE04Z.html / http://www.utasker.com/kinetis/FRDM-KE06Z.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

468 Views
MAPC
Senior Contributor I

Mark,

You are right!

Using "if" only tests the TDRE flag, but it doesn't wait for the transmission to be complete and the buffer to be empty. That is why the most of my data is lost during communication.

I should have thought better before post this question. I feel very embarrassed about that.

Again, thank you very much!

Marco Coelho

0 Kudos

468 Views
MAPC
Senior Contributor I

Mark,

Thank you very much.

It is working now!

But I still don't understand why my code didn't work.

  if(UART1_S1&UART_S1_TDRE_MASK)

to me, it is the same as:

     while((UART1_S1&UART_S1_TDRE_MASK) == 0) {}

They are different ways to do the same thing.

0 Kudos

468 Views
mjbcswitzerland
Specialist V

Marco

You were using two different flags, which have very different timing. If you step the code it will work because there are no timing issues:

In your case you check the TDRE mask and "quit" the loop if it is 0.

In my case I "wait" until TDRE is zero (that is, the UART can accept a new byte) and never quit the loop until all data has been sent.

In your original case, if there is a short period of time where TDRE is '0' and TC is '1' you will quit the loop and so it will fail.

Since TDRE and TC are signalling different things it is a risk to use them both, where TDRE is the (only) flag that the transmitter should use to avoid tx overruns.

Therefore your solution didn't look incorrect but was over-complicated (complication can distinguish problems, so aim at simplicity for best reliability and generally also best overall solution) and involved understanding the UART HW operation down to the ns level, which is not documented, to really be sure that it could work.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

KE: http://www.utasker.com/kinetis/FRDM-KE02Z.html / http://www.utasker.com/kinetis/FRDM-KE02Z40M.html / http://www.utasker.com/kinetis/FRDM-KE04Z.html / http://www.utasker.com/kinetis/FRDM-KE06Z.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos