Author Topic: Serial port with CTS & RTS  (Read 6782 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Serial port with CTS & RTS
« on: October 29, 2007, 12:36:38 PM »
Hi,
  I am using a serial port with handshaking  lines CTS & RTS. If a send from the application is made to the port, and the device is not ready, indicated from CTS . How does utasker handle this?

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3162
    • View Profile
    • uTasker
Re: Serial port with CTS & RTS
« Reply #1 on: October 29, 2007, 01:09:08 PM »
Hi Neil

The uTasker serial driver supports XON/XOFF but not completely RTS/CTS.

In fact the SAM7X project does have this support but it hasn't been ported to all devices.

It can work in two ways: either using 'normal ports' and interrupts, or on some serial interfaces by using hardware specific controls (this is then processor [and often UART] specific but the final result should be more or less equivalent).

Please send me an email detailing the UART and lines which you intend to use. It should be possible to activate it quite quickly.

Regards

Mark

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3162
    • View Profile
    • uTasker
Re: Serial port with CTS & RTS
« Reply #2 on: October 29, 2007, 11:46:36 PM »
Neil

To answer the original question:

Flow control on transmission ensures that the transmitter stops if the remote receiver signals that it can not receive any more data. It then continues when the remote receiver signals that it can again accept data.
In the other direction, the receiver signals to the remote transmitter if its input buffer is so full that it shoudl not receive any more data for the time being. Once the receiver buffer has adequate space again it signals that it can receive again.

By enabling USE_XON_OFF when the UART is opened (or configured / re-configured) it will set it to software flow control mode where XOFF (control character 0x13) is used to signal that the transmitter should pause and XON (control character 0x11) that the transmitter may continue again. Both sides must be configured to use XON/XOFF for it to operate correctly. This is not always suitable for connections where binary data is sent where these control characters can occur in the data stream - although many higher level protocols (eg. PPP) allow such control characters to be escaped so that they are avoided. In the uTasker project ensure also that SERIAL_SUPPORT_XON_XOFF is enabled so that the support is really in the code. All uTasker supported devices always support XON/XOFF mode of operation.

By enabling RTS_CTS when the UART is configured, hardware flow control is activated. This works like XON/XOFF but instead of the control signals being escape characters the HW control lines RTS and CTS are used. When a receiver can not receive any more characters is negates its CTS line - this is connected to the transmitters RTS input and this must stop sending when it detectes that the receiver is not ready to receive. Again, both sides must be configured to use the same flow control technique for it to work correctly.

Whether RTS_CTS mode is actually supported depends on the processor. As of writing the M5223X project doesn't contain this support but it will be added in accordance to this description. Watch the thread for more details.

In both cases (SW or HW flow control) there is a question as to when the input buffer becomes critically full, resulting in the flow being quenched. And also when it is adequately empty to allow more data to be received.

There are two methods in the uTasker project:
Enabling SUPPORT_FLOW_HIGH_LOW in config.h allows these levels to be set when configuring the interface. Generally they are set at 20% and 80% of the input buffer size but other values may be more suitable for particular projects. See the demo project (applicatio.c) for an example of configuring the values:
   tInterfaceParameters.ucFlowHighWater = temp_pars->temp_parameters.ucFlowHigh;
   tInterfaceParameters.ucFlowLowWater = temp_pars->temp_parameters.ucFlowLow;

where the default values are 80 and 20.

If the luxury of SUPPORT_FLOW_HIGH_LOW is not required, the values can alternatively be configured in config.h:
    #define HIGH_WATER_MARK   20     // stop flow control when the input buffer has less than this space (if variable settings are required, use SUPPORT_FLOW_HIGH_LOW define)
    #define LOW_WATER_MARK    20       // restart when the input buffer content falls below this value


When supported, the RTS input is handled as a interrupt to control the transmitter. In the other direction, the CTS output is automatically controlled by the driver receiver depending on the amount of received data in its input buffer waiting to be read.

Note that if the UART is used in DMA mode XON/XOFF operation will generally not be possible. There are some chips (like the 68302 which has a communications processor built in which does DMA transfers and also checks for flow control characters) but most can not do this and so it will not work. When using DMA mode, RTS/CTS mode of operation is possible. Whether this is implemented depends on the development state. Initially RTS/CTS will be implemented in interrupt driven mode and then RTS/CTS/DMA combinations may be looked at.

Regards

Mark

« Last Edit: November 03, 2007, 01:45:33 AM by mark »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3162
    • View Profile
    • uTasker
Re: Serial port with CTS & RTS
« Reply #3 on: November 03, 2007, 03:04:49 AM »
Hi Neil

Here's an update.

It was not as simple as I expected but I have managed to implement HW flow control support in interrupt mode. This is possible on all 3 UARTs (I tested all on UART 0) with the following restrictions:

- RTS/CTS lines for UART0 are the UARTs dedicated pins RTS0 and CTS0.

- When UART1 is on Port UB the RTS/CTS lines are the UARTs dedicated pins RTS1 and CTS1 on Port UB. When UART1 is on Port QS the RTS/CTS lines are the UARTs dedicated pins RTS1 and CTS1 on Port QS. [Theoretically it is possible to mix these pins between the two ports but such a configuration seems over-complicated]

- Although UART2 can have its TXD and RXD lines mapped to Port UC, Port UB or Port AS, its RTS and CTS lines are fixed to the dedicated pins RTS2 and CTS2 on port UC. This is because they are only physically available there. Furthermore there is no support on 80 pin packages on this UART due to the absence of these pins.

The RTS/CTS flow control is fully implemented in software. This ensures a generic solution, even when the M5223X does offer some automatic control possibilities. Specifically there are the following capabilities but I found some of them unsuitable for the flow control solution according to my understanding. If any one sees it differently please comment!

RXRTS in the UMR1 register
- This is a very nice feature. Its goal is to automatically negate the RTS line when the input FIFO is full. This would stop the FIFO overrunning if the software running on the board were for some not capable of handling the interrupts.
I activate this so that it could signal an input buffer problem for short periods of time - and hopefully also stop an overrun.

TXRTS in UMR2 register
- This allows the RTS line to be automatically deactivated after a transmission has terminated. This is useful when the output is controlling a modem which shoudl only be driven during actual data transmission but not suitable for the hardware flow control. It is thus not activated.

TXCTS in UMR2 register
This allows the transmitter to automatically stop sending when the CTS line has been negated by the other side. It doesn't disturb the character which may have been in the process of transmission at the time the negation was detected but will freeze the transmitter afterwards until the CTS line has been asserted again.
I decided against activating this due to the fact that the CTS interrupt does the same (usually very quickly) and the flow control is not normally that critical (the 'high water' mark means that it is getting critical but normally the input buffer can still received a number of characters before it actually overflows).
Additionally, there may be complications when the transmitter freezes unexpectedly - I'm not sure and I didn't experiment. So perhaps it could also be activated without any issues - I just see any really big advantage.

In my development version I also added RTS/CTS line support to the simulator. This means that CTS changes cause the interrupt routine to be executed and the RTS output of the mapped COM port is controlled accordingly. Since it was possible to activate the PCs HW flow control in the transmission direction, the transmission reaction is fast. In the reception direction the RTS line is controlled completely by the driver software and has a short reaction delay due to the simulator's operation. It is however still very useful for testing general behaviour of serial connections using HW flow control.

The addition has involved changes in a number of files, so it is not that simple to add complete simulation support without changing all file. The next SP will include everything but if you would like to start using it (at least on the target) I can give you the 'necessary' parts so that you can get going. Send me a mail with the data you need them and I'll help you with the integration via Skype. If you don't need it a.s.a.p. I may be able to get DMA HW flow control ready too.

Regards

Mark
 
« Last Edit: November 03, 2007, 01:59:04 PM by mark »