4
\$\begingroup\$

I've probed this serial stream coming out of a scoreboard controller and it seems like a proprietary protocol. How would I go about trying to software-decode this?

Serial stream

The start bit is 7.8us long. All the data bits are about 3.85us, giving a bus speed of around 260KHz. A logic HIGH bit starts with a 3.1us HIGH period then a ~800ns LOW. A logic LOW bit is the same but the periods are switched. Each packet is made of 255 bits, so about one packet is sent every millisecond.

I've thought of triggering on the rising edge and then reading the pin level after a short delay, but I don't think an interrupt-driven scheme would work that well because of the overhead.

Any ideas?

\$\endgroup\$
6
  • 1
    \$\begingroup\$ What micro are you planning to use? \$\endgroup\$ Commented May 14, 2014 at 7:32
  • \$\begingroup\$ I don't think an AVR will be fast enough for this so i'm using a Teensy 3.0. \$\endgroup\$
    – xyk2
    Commented May 14, 2014 at 8:49
  • 1
    \$\begingroup\$ Not sure how this is a duplicate? The signals are not the same (one is RS232-like and the other a proprietary protocol). Also asking different questions... This is asking for how to efficiently decode a high speed serial line, not identification. \$\endgroup\$
    – xyk2
    Commented May 14, 2014 at 12:57
  • \$\begingroup\$ You might look at a programmable logic device, though doing a cycle-counted solution on a microcontroller dedicated to this task may actually be easier to develop. I'd be tempted to first capture a bunch of data to disk with a cheap streaming logic analyzer and decode it offline to make sure I understood the format. \$\endgroup\$ Commented May 14, 2014 at 15:31
  • 1
    \$\begingroup\$ @DaveTweed Sorry, I was one of the guilty parties. Both questions were from the same person, involved serial protocols with scoreboards, and had similar looking timing diagrams (although looking closer I can see they are different). So I jumped to the conclusion there were duplicates. \$\endgroup\$
    – tcrosley
    Commented May 14, 2014 at 21:28

3 Answers 3

3
\$\begingroup\$

You say that the overhead of interrupt handling would be too high, but I don't think that's necessarily true. A cheap microcontroller may not be able to do much useful processing of the data stream, but it should be powerful enough to serve as an ad-hoc converter.

Let's take an AVR chip as an example: the ATmega328P that serves as the core of the Arduino dev board. At the maximum clock rate of 20MHz, you get 77 clock cycles per bit. According to the datasheet (page 15) it takes about 7 clock cycles to enter an ISR and 4 cycles to exit.

Assuming you spend half of each data bit in a spin-loop waiting for the right time to sample the input, you're left with about 27 cycles per bit outside of the interrupt handler. Most AVR instructions are single-cycle, so that should be plenty of time to frame the bits into bytes and shove them onto an SPI link to your host processor.

(I've glossed over the problem of detecting start bits. One option is to reset one of the built-in timers at the beginning of every bit, and use the output compare to determine whether the interval between two rising edges exceeds a threshold.)

\$\endgroup\$
1
  • \$\begingroup\$ +1. Yes, a 25 clock spin loop at 20 MHz is pretty reasonable. Maybe the start-bit detection could fit into those 25 clocks? The remaining time is roughly equivalent to an ATmega328 at 10 MHz -- Lots of people run the ATmega328 at 10 MHz or less, and get useful stuff done. \$\endgroup\$
    – davidcary
    Commented May 16, 2014 at 13:35
2
\$\begingroup\$

I've decoded signals like this with AVRs. I did it with a pin change interrupt and a free-running timer. You could also do it with a capture input on the timer, but I was also waking on the data so I needed the asynchronous detection capability.

Basically what I did was every time I got a pin change interrupt, I looked at the time and the state of the pin. I could then say "the pin was 3us high" or "the pin was 3us low" and shift the 1 or 0 into an input data word. I used a @#define@ to determine the threshold time of a high or low and empirically determined a good value to use. My received data words were 33 bits long, so after I counted 33 bits I flagged the reception as complete and flagged the main routine to actually verify and decode the data word.

For robustness, I also reset a timer which had a period of about 10ms. If that interrupt fired it meant that I should reset my receive subsystem since there wasn't any data coming in and my bit counter hadn't counted enough data to consider the message complete.

\$\endgroup\$
1
\$\begingroup\$

One way to decode this would be to invert it and then feed it to a UART that's set for 2.6 Mbps (a bit extreme, but some UARTs can be set this high).

The rising edge of each pulse would become a falling edge — a start bit — for the UART, and each type of pulse would produce a unique data pattern in the UART receiver: a "1" would become 0x80, a "0" would become 0xFE, and a "start bit" would become 0x00 (and possibly cause an "overrun" error). The firmware would convert these byte values into bits and then decode the protocol as appropriate.

It's possible that you could set the UART to 1.3 Mbps and receive two of the signal pulses per byte — the decoding gets a little trickier, but you'd have only half the interrupt rate to deal with.

  • 0x00 → start pulse
  • 0x7F → 0 followed by 0
  • 0x0F → 0 followed by 1
  • 0x74 → 1 followed by 0
  • 0x04 → 1 followed by 1

A completely different approach would be to use a pair of retriggerable monostable multivibrators. One would be set to a period of about 1.9 µs; it would create a clock edge in the center of each bit. The other would be set to a period of about 5 µs; it would detect the "start" pulse.

You would then connect these signals to a SPI slave port on your micro: the original data signal to MOSI, the clock signal to SCLK, and the start signal to SSEL. The SPI interface would collect 8 bits at a time, and deliver them to the firmware at a rate of about 32 kB/sec.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.