Interpreting data over SPI bus, but no SS connection (Solved)

Hi folks.

I need to decode a stream of data over a SPI bus. I need my Arduino to act as a SPI slave.

Fortunately i found Nick Gammon’s tut here: Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino

I tested the example and it works just fine. So long so good.

I have a device which transmits 14 hex values over SPI which i need to put into some byte values that my program then decides what to do with.

14 bytes are transmitted in a row, then comes a delay of about 21 ms, then the data repeats with any changes from the transmitter circuit.

As i do not have the SS line to trigger from, what is the smartest way to do this - capture one byte at a time, and when i’ve counted 14 received bytes, it’s back to start, or maybe starting a timer and using that to figure out what is start and stop…

I have DATA and CLOCK available. The Arduino won’t me doing much else that receiving this string of data and toggling some outputs according to the bytes sent to it.

This snippet of code replicated accurately what my circuit is sending out:

// Written by Nick Gammon
// February 2011


#include <SPI.h>

void setup (void)
{

  digitalWrite(SS, HIGH);  // ensure SS stays high for now

  // Put SCK, MOSI, SS pins into output mode
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  SPI.begin ();

  // Slow down the master a bit
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  
}  // end of setup


void loop (void)
{

  char c;

  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10

SPI.transfer(0x00);
SPI.transfer(0xB7);
SPI.transfer(0x05);
SPI.transfer(0xFC);
SPI.transfer(0x09);
SPI.transfer(0xFC);
SPI.transfer(0x0D);
SPI.transfer(0xFE);
SPI.transfer(0x10);
SPI.transfer(0xA4);
SPI.transfer(0x17);
SPI.transfer(0x53);
SPI.transfer(0x00);
SPI.transfer(0x39);

  // disable Slave Select
  digitalWrite(SS, HIGH);

  delay (21);  // 1 seconds delay 
}  // end of loop

I would like to capture the data and then in the 21 ms delay toggle ports depending on what the bytes were.

for example, if the second byte is 0xAD instead of 0xB7, turn output 0 high.

Any advice for a n00b how to handle this in a nice manner ?

Regards, Per.

How is the slave arduino to know it is to be an SPI slave if the external master is not taking the SS line low? You need to fix that.

With no SS there is no way to sync with the master unless you can detect the inter-frame idle.

As you have a 21mS idle period I would run MOSI to an interrupt pin and time since the last edge, after a reasonable time (say 10/15mS) you can assume that you are in sync and the next 14 bytes are good.

AFAIK without timing or SS it is not possible to detect the start of a frame with SPI.


Rob

Graynomad: With no SS there is no way to sync with the master unless you can detect the inter-frame idle.

Yeah, thought so :-/

If it's any help Byte 2 and 13 is always 0x00, i could technically sync to that, but i'm not entirely sure that those will remain 0x00 for all time and eternity...

So the smart way would be to connect SCL to an interrupt pin beside the SCL pin, then start a timer, if the timer can run for, say 15 ms without interruption, then jump to capture section and capture the bytes and throw into respective bytes.

Maybe that is the way to go.

I will have to think up a way to do it - after all it should be doable.

// Per.

Byte 2 and 13 is always 0x00, i could technically sync to that,

I'm afraid you can't, once you are out of sync with SPI you cannot trust any byte, you could read the last 4 bits from byte 1 and the first 4 bits from byte 2, so you will never see the 0x00.

Conversely if say bytes 5 and 6 are 0xF0 and 0x0F you may read the two 0 nibbles and think that's a 0x00.

You have to use timing.

You can have an ISP oops ISR that simply records the millis() value and your main code checks millis() for the ISP saved value + 15. If true start looking for a frame.


Rob

Hey, whaddya know, there IS a SS signal after all, just needed to find it on the board :)

Screenshot: http://ragelse.com/i/y5gGNZh

So now my work is a lot easier 8)

I'll let you guys know how i get on with the project, thanks so far.

// Per.