PDA

View Full Version : Serial Port Handshaking/Flow Control


kbanks
06-18-2008, 09:36 AM
(Posted from a customer phone call)

I have an application that uses TRANSPARENT MODE, and it works OK if I have flow control turned off (my script does initUart(baudRate, False)).

It does not seem to be working if I try to run with flow control turned on (if my script does initUart(baudrate, True)).

How does RF Engine flow control work, and what is keeping my application from working?

The serial interfaces on the RF Engine are either 2-pin or 4-pin, depending on the second parameter of the most recent initUart() call.

In the following discussion, I am going to refer to the pins for the first serial port (UART0). The same rules apply to the second serial port (UART1), but the relevent pins are GPIO 7-10 instead of GPIO 3-6

Note that GPIO pin numbers are not the same as the pin numbers on the 24 pin RFE header!

Because the header pins start at 1, the first header pin is a GND, and the GPIO numbering starts at 0, you must add 2 to the GPIO pin number to get the correct header pin number.

When initUart(baud, False) is used, the serial interface only uses two pins:

RX AKA GPIO 3 - serial data coming into the RF Engine
TX AKA GPIO 4 - serial data going out of the RF Engine

The RTS and CTS pins are ignored (and are available for use as GPIOs).

When initUart(baud, True) is used, two additional pins come into play:

CTS AKA GPIO 5 - an output from the RFE to the connected device

CTS pin low means the RFE can accept more serial data
CTS pin high means the RFE can not accept more data (if you send it more characters anyway, they will likely be dropped).

RTS AKA GPIO 6 - an input to the RFE from the connected device

The RFE monitors the RTS pin, and requires the connected device to provide the same type of signaling on the RTS pin as the RFE provides on the CTS pin.

RTS pin low means the connected device can accept more data
If the connected device does not drive RTS low, then the RF Engine will not send it any data.

RTS pin high means the connected device is "running out of room", and wants the RFE to stop sending it data.

So, my guess is that your connected device is not controlling the RTS line in the way that the RFE expects/requires.

kbanks
06-18-2008, 01:35 PM
If you put something like the following routine in your existing SNAPpy script, you can use it on the fly to check the value of individual pins.

Reminder 1: For "print" statements to appear in Portal, you need to click on the "Intercept STDOUT" button on the Node Info toolbar.

Reminder 2: You can invoke SNAPpy script routines by clicking on their name in the Node Info window.

Reminder 3: The RTS pin for the second serial port (the one that has a DB-9 connector) is GPIO 10.


def printPin(pin):
print "Pin ",pin,"=",readPin(pin)

reltronix
06-23-2008, 11:22 AM
It is my understanding that RTS (Request To Send) is an output from the device that, when asserted, indicates my device is ready to send data to the communication device (RFE in this case) and the device's serial port will not transmit until CTS (Clear To Send) is asserted from the communication device. After my device completes the message it drops RTS and when CTS goes low my device is ready to receive characters.

I have tried several different cable wirings to attach the RFE's SN163 to our device and an Applied Systems Engineering protocol test set and have not been able to establish communication. I am using a Techtronix digital o-scope to monitor the RTS and CTS under operation. It seems that the SN163 is holding CTS high (asserted). I do see RTS going high and low according to the state of the data that the ASE is sending. Of course this means that the RFE can not or will not accept data. I have worked with serial communications equipment for years and have successfully worked through many different vendors communications equipment (fiber modems, radios, fsk modems, etc) so I’m not new to this technology.

I am using the point-to-point script (datamode1 and datamode2) to do perform my evaluation. The system works fine without “flow control” but I’m experiencing problems when “flow control” is implemented.

Here is something that is confusing me. In the “Serial Port Handshaking/Flow Control” post you show the script example of setting up the UART: initUart(baud, False) but in the datamode1 and datamode2 scripts the UART is initialized by the script entry: initUart(1, 9600). Am I missing something here? I’m new to this scripting language and will be the first to admit I am not an expert programmer but I need some help.

On another note, along the same lines, I successfully set up a multi-drop communications test using the transparentMaster.py and transparentSlave.py scripts and have good statistics (about 96% good but noticed that when the module running transparentMaster.py announces it’s master status there is an interruption to serial communications causing several “no answers”. I decreased the period to which the master announces and gets the other nodes status by increasing secondCounter >= 10 to 100 the no answers improve. If I increase the counter to 1000 it gets even better:

# Periodically announce 'master' status to all slaves
secondCounter += 1
if secondCounter >= 10:
announceMaster()
secondCounter = 0

I think that there is a higher interrupt priority processing this multicast that is used for the RFE’s interface to the RS232 drivers/port. If I turn off this multicast “Master announcement” then the statistics is 100% or just a tiny bit lower. Would there be any way to swap the priority so that the RS232 port is higher than the multicast operation processing?

kbanks
06-23-2008, 01:29 PM
It is my understanding that RTS (Request To Send) is an output from the device that, when asserted, indicates my device is ready to send data to the communication device (RFE in this case) and the device's serial port will not transmit until CTS (Clear To Send) is asserted from the communication device. After my device completes the message it drops RTS and when CTS goes low my device is ready to receive characters.

Your understanding is correct for most (but not all) RS-232 devices. As explained both on the phone and in previous posts in this thread, the SNAP/RF Engine usage of the RTS pin is different from what you are used to seeing from other RS-232 devices. We basically chose to use the RTS pin as sort of a "reverse CTS pin", so that we could get bi-directional flow control with only 4 pins.

I have tried several different cable wirings to attach the RFE's SN163 to our device and an Applied Systems Engineering protocol test set and have not been able to establish communication. I am using a Techtronix digital o-scope to monitor the RTS and CTS under operation. It seems that the SN163 is holding CTS high (asserted). I do see RTS going high and low according to the state of the data that the ASE is sending. Of course this means that the RFE can not or will not accept data. I have worked with serial communications equipment for years and have successfully worked through many different vendors communications equipment (fiber modems, radios, fsk modems, etc) so I’m not new to this technology.

I am using the point-to-point script (datamode1 and datamode2) to do perform my evaluation. The system works fine without “flow control” but I’m experiencing problems when “flow control” is implemented.

At the 3.3 volt logic level, these signals are active low, so I am not sure what you mean when you say "high (asserted)". However, let's look at your next question first...

Here is something that is confusing me. In the “Serial Port Handshaking/Flow Control” post you show the script example of setting up the UART: initUart(baud, False) but in the datamode1 and datamode2 scripts the UART is initialized by the script entry: initUart(1, 9600). Am I missing something here? I’m new to this scripting language and will be the first to admit I am not an expert programmer but I need some help.

This confusion is my fault. The scripts are correct, my previous post is wrong. It takes two function calls to fully configure a serial port.

The function initUart(uart, baudRate) sets the baudrate, a separate function flowControl(uart, True/False) turns flow control on or off.

This is probably why you are seeing the CTS issue in your most recent testing. After a call to flowControl(uart, True), CTS should be low (the RF Engine should be saying he is ready to receive data) until you "fill him up".

To get characters to come out of the RF Engine (with flow control turned on), you will have to take RTS low on the other device when it is ready to receive characters. If you do not have full control of the other device, you may just want to force this line to always be low (this makes the flow control one-sided, and the other device must be able to "keep up").

On another note, along the same lines, I successfully set up a multi-drop communications test using the transparentMaster.py and transparentSlave.py scripts and have good statistics (about 96% good but noticed that when the module running transparentMaster.py announces it’s master status there is an interruption to serial communications causing several “no answers”. I decreased the period to which the master announces and gets the other nodes status by increasing secondCounter >= 10 to 100 the no answers improve. If I increase the counter to 1000 it gets even better:

# Periodically announce 'master' status to all slaves
secondCounter += 1
if secondCounter >= 10:
announceMaster()
secondCounter = 0

I think that there is a higher interrupt priority processing this multicast that is used for the RFE’s interface to the RS232 drivers/port. If I turn off this multicast “Master announcement” then the statistics is 100% or just a tiny bit lower. Would there be any way to swap the priority so that the RS232 port is higher than the multicast operation processing?

1) No, the priority is not selectable
2) The "priority issue" is probably not where you think. The conflict between the data packets and the "announce" packets is probably occurring "in the air". The packets are probably colliding, and since multicast packets are neither acknowledged nor retried, the collision results in a loss of data.

In the upcoming 2.1 release of the SNAP firmware, we have implemented some additional "collision detection/collision avoidance"" support to boost the performance of exactly the sort of test you are running, but that code is not available yet (and I don't currently have an estimated date for when it will be).

To get the most reliable "over the air" transfer of serial data, you need to use point-to-point data mode, not multicast mode (even in the upcoming 2.1 firmware, point-to-point will out-perform multicast mode).

reltronix
06-24-2008, 09:14 AM
Thanks for your help!
I did understand your implementation and explanation. I just wanted to post it so the information may help others. Most of my previous post had, in fact, been explained before.

If we develop a product using the RF engine, could we change the way that RTS and CTS are used to emulate a more “standard” usage of these handshake signals? Currently our products use RTS, CTS, and DCD for control of serial communications.

reltronix
06-24-2008, 09:18 AM
At the 3.3 volt logic level, these signals are active low, so I am not sure what you mean when you say "high (asserted)". However, let's look at your next question first...

I was referring to the signals on the outside of the RS232 driver/receiver. The signals usually are inverted by the driver/receiver. When I say “RTS is asserted” I mean a high is seen at the 9-pin serial connection of the proto boards.

kbanks
06-24-2008, 10:58 AM
If we develop a product using the RF engine, could we change the way that RTS and CTS are used to emulate a more “standard” usage of these handshake signals? Currently our products use RTS, CTS, and DCD for control of serial communications.

The current handshaking scheme is implemented in the "core" firmware of the RF Engine (not in the user changable SNAPpy scripts). So unless you license the source code to SNAP core (no idea what such a thing would cost), you won't be able to change this behavior on your own.

Changes that we make to SNAP core come from two sources:

1) When a customer (like you) makes a suggestion, it goes into the "feature ideas" bucket for the product. Based on how much we like the idea, how much time we think it will take to implement, how much code space we think it will take up, and how many other people ask for the same thing, some of these suggestions make it into future code releases on their own.

I've added your suggestion to that "feature bucket", and we will evaluate it when time permits.

2) Customers with very strict or unusual requirements sometimes take the "Custom Solutions" path. It is possible to have SNAP customizations made on a contract basis. If you needed to go this route, your first step would be to contact John White at 256-852-7888 x 119.