I am working with a legacy device that uses a "SPI like" protocol. This device acts like a:

  • SPI "master", but expects to talk with only one "slave" device. It does not expect any output/data exchange from the slave
  • sends out LSB first
  • pulses the 'Slave select' (active low) line to signify the start of a "command" (hence instead of this being a chip select line in SPI, it's more of an indicator that a command is going to be sent by the master)
  • multiple, variable list of data bytes might follow after each such "command" (as long as the 'Slave select' is active, data following the first/leading data byte is interpreted as parameters for the command)
  • a new "command" can start only after the 'Slave select' line has gone inactive and can be pulsed active again

The protocol the master expects the "slave" device to follow is captured in the following diagram (Pg 12 of http://uglyduck.ath.cx/PDF/misc/PT6959.pdf):

enter image description here

I am going to emulate the "slave" device using a PIC18F2550.

Given this information, how do I detect the start of a command?

I have written some code to capture the data from the master and forward it over the UART but can't figure out how to

  • do the same when using the USB Framework (as I am using busy polling to read data from the SPI port and once all 8 bits are in, I send the byte over UART)
  • detect when the 'Slave select' line goes active or not (I am afraid hooking up an interrupt could mess around with the built in SPI library)

Perhaps what I am asking is "how do I do the following":

  1. detect that the 'Slave select' is active or not
  2. capture the incoming data from the master without loosing any bytes sent (since the slave device has no way to tell the master to retransmit the data)
  3. do the above two while keeping the USB link alive and not making it timeout (which can happen if the slave is often busy polling the SPI lines for data)

Suggestions and sample code for atleast the first two points will be highly appreciated

  • \$\begingroup\$ What do you know about the speed with which the data is being sent? The Microchip SPI implementations I'm familiar with require that the chip be able to respond to SPI events between the last clock pulse of one byte and the first clock pulse of the next--a constraint that may be hard or impossible to meet without external hardware. \$\endgroup\$
    – supercat
    Apr 18 '13 at 17:16
  • \$\begingroup\$ @supercat: good question. The clock speed is ~1.25Mhz \$\endgroup\$
    – sekharan
    Apr 18 '13 at 17:47
  • \$\begingroup\$ How much time is there between the end of one byte and the start of the next? If a byte is being sent every 6us, there's no way you'll keep up without some hardware help; the simplest thing may be to convert the SPI data into a 9-bit async data stream and feed that to a UART (since the PIC uarts are buffered). \$\endgroup\$
    – supercat
    Apr 18 '13 at 18:08
  • \$\begingroup\$ @supercat: adding a shift register and having the PIC reset it on every byte read is not an issue. Since the PIC itself has a double buffered SPI peripheral this should provide sufficient time? My first question is : How do I check if 'Slave select' went active or not from inside the SSP interrupt handler? \$\endgroup\$
    – sekharan
    Apr 18 '13 at 18:20
  • 1
    \$\begingroup\$ The PIC has no inherent facilities to do so. If there is enough time between the end of a byte and the next falling edge on /STB, it might be possible to wire /STB to an edge-triggered interrupt. The problem is that if the time is short enough than an SPI interrupt which is running a little late might not run until after the next falling edge of /STB, it may be impossible to distinguish between a falling edge of /STB that occurred before the byte just read from one that occurred after unless you add external hardware to make such a determination. \$\endgroup\$
    – supercat
    Apr 18 '13 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.