views:

70

answers:

3

Update

Turns out the error was in the crypto processor code, that is fixed. But now running into what seems like it might be a handshaking issue.

On first transmission, we get a single byte back from the device with value 0xFF(don't know why, the engineer I'm working with isn't too experienced with RS-232 either). Then, things run as normal (just sending the device one byte at a time, and waiting for a matching echo). However, neither the device nor the .NET app can send more than a couple of bytes at a time before one of them locks up and refuses to send or receive.


At work I'm writing an app that interfaces over RS232 with a crypto processor inside a device to reprogram flash modules inside the device.

To just take things slow and make sure all our headers are right, we're writing one byte at a time with SerialPort.Write(). However, when we run the code on the crypto processor, it reads an extra NULL in between each byte. When I test the .NET code on my local machine with two serial ports and a crossover cable, I capture the output in HyperTerminal or Putty and there are no extra NULLs when I view the log in Notepad++.

However, to further complicate things, when we manually type messages byte-per-byte via HyperTerminal to the crypto processor, it reads the input as a single byte only, no extra NULLs (as compared to the .NET app). Anybody have any experience with .NET doing mysterious things when it writes to a SerialPort?

We're initializing a test chunk with this:

byte[] testBytes = new byte[] { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H' };
byte[] byteArray = new byte[256];
for (int i = 0; i < 32; i++)
{
    testBytes.CopyTo(byteArray, i * 8);
}

And sending it with this:

public void StutterSend(byte[] data, long delayMs)
{
    bool interactive = false;
    if (delayMs < 0)
        interactive = true;

    for (int i = 0; i < data.Length; i++)
    {
        serialPort.Write(data, i, 1);
        if (interactive)
        {
            WriteLine("Sent byte " + (i + 1) + " of " + data.Length + ". Press any key to send moar.");
            Console.ReadKey();
        }
        else
        {
            double timer = DateTime.Now.TimeOfDay.TotalMilliseconds;
            do { } while ((DateTime.Now.TimeOfDay.TotalMilliseconds - timer) < delayMs);
        }
    }
    WriteLine("Done sending bytes.");
}

Our SerialPort is configured with all the matching parameters (stop bits, data bits, parity, baud rate, port name), and our handshake is set to None (it's just how our uart driver works).

A: 

SerialPort sets the Parity property to Parity.None if you don't specify any. This means in case your receiver expects a Partity bit, it will never get one as long as you don't tell SerialPort explicitely to send along a Parity Bit with the transmitted data.

And the fact that it went well on HyperTerminal could be that HyperTerminal uses a Parity bit by default ( I don't know HyperTerminal well).

Sander Pham
+1  A: 

What is the Encoding property for the serialPort set to? The docs for SerialPort.Write( byte[], int, int) say that it runs its data through an Encoder object (which doesn't really make sense to me for a byte[]). It's supposed to default to ASCIIEncoding, but it seems like it might be set to something else. try explicitly setting it to ASCIIEncoding and see if that helps. I can't recall if this was an issue for me back when I did some serial port stuff in .NET to talk to an embedded board...

Note that even with ASCIIEncoding in use, you'll get some (probably unwanted) transformation of data - if you try to send something above value 127, the encoder will convert it to '?' since it's not a valid ASCII character. I can't recall off the top of my head how I got the serial port to simply leave my data alone - I'll have to dig around in some source code...

Michael Burr
+1  A: 

Regarding your update, it sounds like your crypto processor has some more problems. Getting a 0xff back can be the result of an unexpected glitch of <= 1 bit time on the Tx line of the RS232 port. This is interpreted as a start bit by the PC. After the glitch, the Tx line returns to the mark state and now that the UART on the PC has a start bit, it interprets the "data" bits as all ones (the value for the mark state). The mark state is also the correct value for the stop bit(s) so your PC's UART has received a valid byte with a value of 0xff. Note that the glitch can be very fast relative to the RS232 data rate and still be interpreted as a start bit so have your engineer look at this line with an oscilloscope in normal mode/single sequence trigger to confirm this.

semaj
bearcdp