0

I have been reading up on handshaking and hardware flow control for serial communication and I have a question that I can't seem to find an answer to.

If you set up hardware flow control for a serial port on cubeMX it will set the pins up that are required. I know you can use alternative pins as well and this can be done through cubeMX.

My question is, could you set up hardware flow control manually by using different pins or do you strictly have to use the implemented pins?

I am using a STM32F207ZETx and I am using USB as well as serial - however when using the USB peripheral it blocks the hardware flow control pins for USART1 which I need, and I need hardware flow control for my project! The alternate pins for hardware flow control are also already used so I'm in a bit of a pickle.

Alex_embedded
  • 21
  • 2
  • 7

1 Answers1

3

My question is, could you set up hardware flow control manually by using different pins or do you strictly have to use the implemented pins?

You can do hardware flow control yourself in software, and in fact it is quite simple to do.

The USART1_RTS is an output pin. It is set/high when the USART1 is ready to receive data. The USART1_CTS is an input pin. The other end sets it high when it is ready to receive data, and low when it is not.

Let's say that you send and receive one character at a time, and use two GPIO pins for USART1_RTS and USART1_CTS instead of the hardware support.

Normally, you keep USART1_RTS high. When receiving data, if you are running out of receive buffer, you set USART1_RTS low. When you make more room in the receive buffer, you set USART1_RTS high. (If you have a buffering scheme that cannot run out of receive buffer, you can tie the RTS line high.)

Before sending each character, you check if USART1_CTS is high. If it is low, you don't send the data, but wait for USART1_CTS to become high before you do.

That's it.

Nominal Animal
  • 38,216
  • 5
  • 59
  • 86
  • This clears it up very well - thank you Mr Penguin (Normal Animal)! – Alex_embedded Sep 06 '18 at 04:04
  • Note you will either need to implement a pin change interrupt on the GPIO pin used as CTS or constantly need to poll the handshake line. – tofro Sep 06 '18 at 07:26
  • @tofro Unless using DMA it is simple enough and reasonably efficient to poll CTS before loading the TX data register. – Clifford Sep 06 '18 at 13:15
  • 1
    @Clifford once tx is paused by CTS, how efficient is to have to poll the CTS line at e.g. character rate to re-start transmit? Having an interrupt on CTS going high sounds useful and also allows immediate restart of transmit without the delay of whatever polling time has been chosen. – DisappointedByUnaccountableMod Sep 06 '18 at 16:58
  • I'm not very familiar with STM32's, but based on the datasheet, it looks like the best approach for USART1 is an interrupt-based per-byte send and receive functions. Another interrupt for CTS going high is a simple addition, as it can send the next byte and enable the interrupt for the next outgoing byte. Since CTS ought to be sampled before sending the next byte, I'm not sure you can easily use DMA for sending. For receiving, DMA should be fine, especially if you also use an interrupt to receive the "final" byte (sent just before RTS/RTR was dropped low). – Nominal Animal Sep 08 '18 at 06:36