Author Topic: Half duplex UART and STM32  (Read 11707 times)

0 Members and 1 Guest are viewing this topic.

Offline darko31Topic starter

  • Regular Contributor
  • *
  • Posts: 103
  • Country: cs
Half duplex UART and STM32
« on: August 13, 2016, 06:25:23 pm »
Hi guys, I've got couple of questions about using half duplex UART. I want to interface STM32VL board with AX-12 servo, and I've got the transimt part working, but receive part isn't chooching as it should.

For the moment I'm using STM's HAL. As I've managed to gather from various examples, by default, the uart is in TX mode. In order to get it to RX, enabling RX with HAL is with HAL_HalfDuplex_EnableTransmitter().

So the function for reading data from servos goes like this, ignore the error handler, it isn't implemented yet

Code: [Select]
uint16_t AX12_read_data(uint8_t id){

uint8_t rxBuffer[7]={0};
uint8_t length=0;
uint8_t error=0;
uint16_t return_value;

HAL_HalfDuplex_EnableReceiver(&huart2);

HAL_UART_Receive(&huart2, (uint8_t*) rxBuffer, sizeof(rxBuffer), 200);

if (rxBuffer[0] == 0xFF && rxBuffer[1] == 0xFF){

}
else //Error_Handler();

length = rxBuffer[3]-2; //ax12 magic, see manual
error = rxBuffer[4];

if (error != 0){}
//Error_Handler();
else if (length == 0){}
//Error_Handler();
else {
if (length > 1){
return_value = (rxBuffer[6] << 8) + rxBuffer[5];
return return_value;
}

else {
return_value = rxBuffer[5];
return return_value;
}
}

HAL_HalfDuplex_EnableTransmitter(&huart2);

return 0;
}

This function is called right after transmitting some command.
Problem is the received data doesn't seem right, first is 255 which is right, but receiving some random numbers after that, usually zeroes.

Am I missing something obvious, and what exactly does timeout parameter in uart send and receive do?
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Half duplex UART and STM32
« Reply #1 on: August 13, 2016, 06:32:06 pm »
At least here is one evil thing:

   if (rxBuffer[0] == 0xFF && rxBuffer[1] == 0xFF){

   }
   else //Error_Handler();

   length = rxBuffer[3]-2;   //ax12 magic, see manual
   error = rxBuffer[4];

I will leave it as an exercise for you to figure it out.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Half duplex UART and STM32
« Reply #2 on: August 13, 2016, 06:47:06 pm »
It is a good habit to always use the braces {} with the if-statements, while-loops and for-loops:

Code: [Select]
if (cond1)
{
    do_something1();
}
else if (cond2)
{
   do_something2();
}
else
{
   do_something_else();
}

Probably you have by now figured out why  >:D
 
The following users thanked this post: Kilrah

Offline darko31Topic starter

  • Regular Contributor
  • *
  • Posts: 103
  • Country: cs
Re: Half duplex UART and STM32
« Reply #3 on: August 13, 2016, 07:16:51 pm »
Yeah, will add them, though it should work as it is. The code was written quick and dirty.

But I've commented out all the error checking stuff, with a bit of delay after receiving bytes, and it kinda, sorta works, but for some reason now there are three 255 at the start of the message. Hm, too tired to debug it more, will continue later.
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: Half duplex UART and STM32
« Reply #4 on: August 13, 2016, 07:24:29 pm »
Yeah, will add them, though it should work as it is.

Nope, there's at least one line that's executed when it shouldn't due to your "quick and dirty" shortcut.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Half duplex UART and STM32
« Reply #5 on: August 13, 2016, 07:54:13 pm »
Quote
The code was written quick and dirty.

agree with others: "quick and dirty" is usually deadly.
================================
https://dannyelectronics.wordpress.com/
 

Offline darko31Topic starter

  • Regular Contributor
  • *
  • Posts: 103
  • Country: cs
Re: Half duplex UART and STM32
« Reply #6 on: August 13, 2016, 09:11:07 pm »
Ok, but forget the error checking and quick and dirty at the moment. Not about that.

When reading from UART more bytes than expected, what's gonna be stored at those bytes, zeroes,  previous values or something else?

And does timeout when using UART specify how long  to "wait" for bytes to arrive before ending the message?
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: Half duplex UART and STM32
« Reply #7 on: August 13, 2016, 09:40:26 pm »
When reading from UART more bytes than expected, what's gonna be stored at those bytes, zeroes,  previous values or something else?
The datasheet may mention that, but it's likely unspecified i.e. random.

On some STMs if you do a buffer overrun/underrun you can actually completely lock up the whole MCU, so checking the flags, handling errors and doing things right is essential.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Half duplex UART and STM32
« Reply #8 on: August 14, 2016, 01:48:12 am »
Quote
When reading from UART more bytes than expected, what's gonna be stored at those bytes, zeroes,  previous values or something else?

Unknown.

The point is that such a situation should not have happened. The general process is to read from the receiving register / buffer to a user string, until the end of transmission is detected -> you will have to decide a protocol on what signals the end of your transmission.

If you have DMA set up, it is a natural circular buffer.
================================
https://dannyelectronics.wordpress.com/
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Half duplex UART and STM32
« Reply #9 on: August 14, 2016, 10:38:51 am »
Maybe you cannot see the problem, so I just make it clear for you. Sometimes this happens when one looks at his/her own code too long. Been there, too. Here we go:
 
The original, evil code:

   if (rxBuffer[0] == 0xFF && rxBuffer[1] == 0xFF){

   }
   else //Error_Handler();

   length = rxBuffer[3]-2;   //ax12 magic, see manual
   error = rxBuffer[4];

Here's how the compiler will see it due to the fact that you have commented the else-clause's statement out:

   if (rxBuffer[0] == 0xFF && rxBuffer[1] == 0xFF){

   }
   else //Error_Handler();

   length = rxBuffer[3]-2;   //ax12 magic, see manual
   error = rxBuffer[4];

Which is equivalent to this:

   if (rxBuffer[0] == 0xFF && rxBuffer[1] == 0xFF){

   }
   else
       length = rxBuffer[3]-2;   //ax12 magic, see manual
   error = rxBuffer[4];

Thus the else-clause "length = rxBuffer[3]-2;" will be executed unless buffer's first and second value are 0xff.
 

Offline darko31Topic starter

  • Regular Contributor
  • *
  • Posts: 103
  • Country: cs
Re: Half duplex UART and STM32
« Reply #10 on: August 14, 2016, 07:36:04 pm »
Yes, I see now what were you reffering to, will sort all the error checking stuff.

Thing is, AX12 return messages can have different length, so in order to check how long is the message, first you have to check value of fourth length byte.

Is it okay to first read first four bytes then after reading the legth byte read appropriate ammount after? Or to have different read functions with different lengths?

Also timeout to receive message from AX12 is variable by default it's 160us, or there about. Should I set that time in timeout in uart read function, or add a little delay before reading uart?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf