Error Handling

The Slink-e has rather poor error handling. The commands to send port messages don't generate responses, so you can't tell if they worked or not. There is no redundancy in the commands, so the Slink-e usually doesn't detect errors; the Slink-e does not even use RS-232 parity. The data stream does not have synchronization built into it, so a single dropped or duplicated byte can wreak havoc with a whole stream of commands.

The types of errors we're mostly concerned with are errors low in the communication stack such as those caused by electrical noise or improper handshaking. The thing that makes these so difficult to deal with is that devices that talk to the Slink-e on the programming interface (e.g. a computer) usually don't synchronize sending and receiving at that low level. There is a buffer of outgoing characters and a buffer of incoming characters, and the device simply can't change the output stream immediately in response to an error report that it receives in the input stream.

Needs Resume State

To make up for this partially, the Slink-e has the Needs Resume state. When the Slink-e detects an error of one of various kinds, called synchronizing errors, it generates an error report describing it and enters the Needs Resume state. In the Needs Resume state, the Slink-e ignores absolutely everything sent to it on the programming interface except a Resume command. When it sees a Resume command, it leaves the Needs Resume state and resumes normal function (without sending a response to the Resume command).

Here is an example: You send a series of Send Port Message commands and a Send Port Message End command to make the Slink-e generate an IR message to turn on your VCR. Early in the stream, a bit gets flipped in the serial line and causes a framing error at the Slink-e. The Slink-e knows it did not get the right data, and in fact can't even tell now where the end of the Send Port Message command is. How many characters did it miss?

So the Slink-e sends a Framing Error report and enters Needs Resume state.

You already have more Send Port Message commands in the pipeline, and by the time you see the Framing Error report, you will have put even more in. But the Slink-e ignores them all, because it is in Needs Resume state.

Eventually, you see the Framing Error report. You respond by sending a Resume command, after whatever is still in the outgoing pipeline. And you recognize that something somewhere in the pipeline (something you sent after the last time you got a response from the Slink-e and before now) has failed.

In this case, the Needs Resume state has 1) prevented the Slink-e from doing random things based on its out-of-sync interpretation of your command stream; and 2) allowed you and the Slink-e to get back in sync.

For some reason, possibly just implementation convenience, the Slink-e actually stops operating completely while in Needs Resume state. It won't receive port messages either.

So what are the synchronizing errors (errors that cause the Slink-e to enter Needs Resume state)? Look at the descriptions of the error reports. Each one tells whether the errors it reports are synchronizing errors.

How to Program For Errors

Send Port Message and Send Port Message End don't generate responses. So in the example above, you aren't waiting for anything, so you won't necessarily see the Framing Error report for a long time, and may have a hard time connecting it with the port message you tried to send in the past. So a good strategy is to follow up each port message send, or group of them, with a Get Version command (or any other command that generates a response). Then wait for that response. When you get it, you'll know that your port message has been sent and there were no errors. If instead you get an error report, then you'll know your stream stopped somewhere. Because of the Needs Resume state, the Slink-e will ignore your Get Version command, so you won't have that response to deal with. In effect, you're forcing a response -- either normal or error -- to your port message send sequence.

For best integrity, it's a good idea to prefix every command that can stand on its own (as opposed to a Send Port Message command in the middle of a sequence) with a Resume command. There's no point in letting some unrelated prior command, maybe hours ago, affect this new command. Doing this is essentially using the Resume command as the frame sync codes you often see in more advanced channel protocols.

Since the Slink-e suspends receiving as well while in Needs Resume state, make sure you respond to any error report of a syncrhonizing error with Needs Resume, rather than rely on the prefix described above.

One more thing for you to keep in mind in evaluating the risk of loss of synchronization is that the first byte of each command tells how many more bytes are in the command. If that byte gets corrupted, the Slink-e is totally lost, and doesn't even know it. The Slink-e is looking at an entirely different command stream than you are.

Special note: Command Data Underrun

I should point out here that the most vexing of the synchronizing errors is the Command Data Underrun. You can actually cause this at a high level in your program, even when the serial channel is working perfectly. If you do not feed your serial port data as fast as the Slink-e needs it to maintain sending a port message, you get this error. That's why you need big buffers and can't think too much between Send Port Message commands.