SPI not working (or I just can't start it)

Tried to start up SPI communication and here what I've noticed:

Case1:  hardware.configure(SPI_257);
        hardware.spi257.configure(  SIMPLEX_RX | MSB_FIRST | CLOCK_IDLE_LOW, 100);
The clock on pin5 goes wild (always ticking till IMP is woked up no matter if I never call spi.read).

Case2:
       hardware.configure(SPI_257);
       hardware.spi257.configure(  SIMPLEX_TX | MSB_FIRST | CLOCK_IDLE_LOW, 100);
No clock whatsoever (no matter if I call hardware.spi257.read)

Case 3:
        hardware.configure(SPI_257);
        hardware.spi257.configure(  MSB_FIRST | CLOCK_IDLE_LOW, 100);
No clock whatsoever (no matter if I call hardware.spi257.read)

What I need to do: have 2 bytes read during a chip select (CS=0, active low).
I want to achieve this by setting pin8 as digital output and using it as CS. Than simply setting CS to 0, calling spi.read twice for the two bytes, than setting CS=1 to disable my sensor. The chip select working fine (checked on scope).

Questions:
1. In readonly (SIMPLEX_RX) mode why SPI clock is always ticking? (this is the mode what I need basically since my sensor is a dumb read only temp sensor). Is always ticking even if nothing is connected to the SPI pins.

2. Help shows TODO spi.read() but when I tried hardware.spi257.read() I got error saying size required.
Does hardware.spi257.read(1) is the correct sequence and does it read 1 byte? Also tried hardware.spi.read(1) - is not really clear from the help what is the good sequence ...

3. Comparing the CS and the clock pin (pin5) I saw that even if I fire one spi.read I could count 25 SPI clocks during CS was active. That's not 1 byte for sure. Why?

Also tried the complicated solution suggested here (http://forums.electricimp.com/discussion/95/spi-newbie-question)
with setting 2,5,7 pins as input before and selecting spi257 SIMPLEX_RX mode only after CS is active, read 2 bytes, than setting 2,5,7 pins input again, deactivate CS. This also results in clocks for 6-7 bytes rather than 2 and I see zero's as result of reading.

I can do scope screenshots if necessary but I think what I wrote is not too complicated to understand.

Please check the SPI and if it's possible give a simple byte read/write example because the current solution does not works neither with jwjames CC1101 and neither with my TC77 (http://ww1.microchip.com/downloads/en/devicedoc/20092a.pdf). Or we are both making the same mistake ...

  1. Is a bug.
    2. This is TX only so won’t receive
    3. Is what you currently want, due to 1 not working

    Read returns the current FIFO state when there is data. You need to generate clocks by writing, so:

    hardware.spi257.write(0xff); // dummy
    local a = hardware.spi257.read(1); // read first byte
    hardware.spi257.write(0xff); // dummy
    local b = hardware.spi257.read(1); // read second byte

    You should see two distinct sets of 8 clocks for each write, at which point the imp clocks out the write data and the read data concurrently.

Brown,

Here is a correction to Hugo's code which I have tested by hooking MISO to MOSI and reading back the result.  The hardware.spi257.configure parameters are important here as you will not be able to use SIMPLE_RX until the free running clock bug is fixed.  This also means that MOSI (pin7) will be driven by the SPI engine.  I have selected to spit out 0xAB and 0xCD, but you could just as easily send 0xFF to keep MOSI from toggling.

//Loop SPI back on itself

imp.configure("SPI Loopback", [], []);

hardware.configure(SPI_257);
//It is important that you not use SIMPLE_TX or SIMPLE_RX
//in the configure as that will not work
hardware.spi257.configure( 0 , 100);
    
hardware.spi257.write(format("%c",0xAB)); // dummy
local a = hardware.spi257.read(1);        // read first byte
hardware.spi257.write(format("%c",0xCD)); // dummy
local b = hardware.spi257.read(1);        // read second byte

//Prints out 0xAB 0xCD
server.log(format("0x%02X 0x%02X", a[0], b[0]));

@brandonWell, good thing - I tested your code and I’m getting your same results. On to figure out why my device is being whacky.

Ty Brandon and Hugo for the feedback - I’ll try it on Monday and let You know the results.
My dummy temp sensor does not even have MOSI connected (does not have one) so it shouldn’t be a problem to transmit something for receive.

James
Might be that You should send something which fit’s in CC1101 communication - AB and CD might not be good :slight_smile:

Right, Brown. I was just commenting that the test works, so we can rule out an issue with SPI’s transmit & receive portion and that I need to figure out why either my device doesn’t work or my code isn’t working. :slight_smile:

The "workaround" works - the clock looks ok, the data is real temperature.

Ofc I still wait a fix for the read (wihout write) since a more complicated sensor/rf chip will not like to get a write 0xFF on every read. And that's my next step - this temp sensor was just a testing project :)

Umm, your sensor will always get data on every SPI read; there is no “fix” for that as it’s inherent with the protocol (unlike I2C or UART).


Because SPI has separate TX and RX lines, there is no way to indicate when TX or RX data is valid - when there’s a clock, data will flow in both directions.

Different chips deal with this in different ways. Mostly, they expect a particular command/data format with framing provided by the nCS line, and will ignore TX data from the imp when it does not make sense to be receiving at that point. You can see this on the timing diagrams they provide in their datasheets.

The “read (without write)” implementation will just implicitly send 0xff during a read, vs you having to specify data to send.

Ups - You're right, my mistake. Keeping MOSI on 0 or 1 during 8 clock's means sending 0x00 or 0xFF ... Sorry, this happens when I try to do/understand too many things in the same time :)