Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: SPI Slave

  1. #1
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    495

    SPI Slave

    I'm trying to transfer data very quickly between 2 Teensy 3.6's. I'm trying to use SPI, since that should be the fastest method. I'm using the following config for my SPI master Teensy 3.6:
    * CS: 10
    * MOSI: 11
    * MISO: 12
    * SCK: 13

    I'm using the following config for my SPI slave Teensy 3.6:
    * CS: 2
    * MOSI: 11
    * MISO: 12
    * SCK: 14

    This is my master code:
    Code:
    #include "SPI.h"
    
    void setup()
    {
      Serial.begin(115200);
      delay(5000);
      pinMode(10, OUTPUT);
      SPI.begin();
      SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0));
      digitalWriteFast(10, LOW);
      SPI.transfer16(10);
      digitalWriteFast(10, HIGH);
      SPI.endTransaction();
    }
    
    void loop()
    {
    }
    And my slave code:
    Code:
    #include "SPI.h"
    
    void spi0_isr(void) {
      Serial.println(SPI0_POPR);
      SPI0_SR |= SPI_SR_RFDF;
    }
    
    void setup()
    {
      Serial.begin(115200);
      SIM_SCGC6 |= SIM_SCGC6_SPI0; // enable slave clock
      SPI0_MCR |= SPI_MCR_HALT | SPI_MCR_MDIS; // stop
      SPI0_CTAR0_SLAVE = SPI_CTAR_FMSZ(15) & SPI0_CTAR0_SLAVE & (~(SPI_CTAR_CPOL | SPI_CTAR_CPHA) | 0x00 << 25);
      SPI0_RSER = 0x00020000;
      CORE_PIN14_CONFIG = PORT_PCR_MUX(2);
      CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
      CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
      CORE_PIN2_CONFIG =  PORT_PCR_PS | PORT_PCR_MUX(2); // this uses pin 2 for the CS so Serial2 can be used instead.
      SPI0_MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS; // start
      NVIC_ENABLE_IRQ(IRQ_SPI0); // enable CS IRQ
    }
    
    void loop()
    {
    
    }
    I took gratuitously from this thread: https://forum.pjrc.com/threads/48749...ler-for-teensy

    My issues is that I would expect to see the slave print the number 10. Instead, I'm seeing 65535. Hoping that someone here will see my mistake.

    Cheers!
    Brian

  2. #2
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,011
    Hey Brian.
    Never could get spislave mode to work reliably. You might me better off using tonton81's spi_mst library to transfer data.

  3. #3
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    or take a peek at TSPISlave library that supports SPI slave mode among LC and T3.x for all available SPI ports (SPI,SPI1,SPI2)

    also if you are getting 65535, make sure your MOSI and MISO lines are not reversed and make sure theyre common ground

  4. #4
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    495
    Quote Originally Posted by tonton81 View Post
    or take a peek at TSPISlave library that supports SPI slave mode among LC and T3.x for all available SPI ports (SPI,SPI1,SPI2)

    also if you are getting 65535, make sure your MOSI and MISO lines are not reversed and make sure theyre common ground
    Oh wow, TSPISlave looks exactly like what I want. Going to give that a try, cheers!

  5. #5
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    the only issue i would correct of that library but didnt have time yet to do is instead of declaring a void isr function of the core was to overwrite the existing vector with a new isr function, this is because if i would change the vector to a new function, we can #include <SPI.h> after, otherwise the SPI.h complains about the spi0_isr already declared...

    vector modification would allow both mastar and slave capability at same time
    library in its current state can be SPI slave only until thats done
    Last edited by tonton81; 02-08-2019 at 04:19 AM.

  6. #6
    @tonton81: So it only transfers 16-bit bytes, then?

  7. #7
    Sorry, I should be more specific. I'm trying to create what might be a similar device to what brtaylor is doing. I'm using I2C to tell the Teensy 3.6 *what* I want to read from the SPI port; the problem is...actually reading it. This will be 8-bit data (rather a lot of it) that I'm sending. If single 8-bit transfers aren't available, I can use structs or unions (or just bit shifting) to do the dirtywork of storing the data on the slave. Same for decoding on the master. Or is there another library I should be looking at?

  8. #8
    Has anyone managed to get any of the SPI slave code, from any of the libraries, to work? I've downloaded tonton's library, and tested it; it hangs immediately when data reception begins. My setup is really, really basic; two Teensy 3.6-es, connected as specified, using SPI0.
    Connections are CS0 <-> CS0, MOSI0 <-> MOSI0, MISO0 <-> MISO0, SCK0 <-> SCK0 (on a 3.6, that's 10, 11, 12, and 13, respectively).

    Master code is:
    Code:
    #include "SPI.h"
    
    void setup()
    {
      Serial.begin(115200);
      delay(5000);
      pinMode(10, OUTPUT);
      SPI.begin();
    }
    
    void loop()
    {
      SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
      digitalWriteFast(10, LOW);
      Serial.println(SPI.transfer16(10));
      digitalWriteFast(10, HIGH);
      SPI.endTransaction();
      delay(500);
    }
    Slave code is:
    Code:
    #include "TSPISlave.h"
    
    uint8_t miso = 12;
    uint8_t mosi = 11;
    uint8_t sck = 13;
    uint8_t cs = 10;
    uint8_t spimode = 16;
    
    TSPISlave mySPI = TSPISlave(SPI, miso, mosi, sck, cs, spimode);
    
    void setup() {
      Serial.begin(115200);
      mySPI.onReceive(myFunc);
    }
    
    void loop() {
      delay(1000);
      Serial.println(millis());
    }
    
    void myFunc() {
      Serial.println("START: ");
      uint16_t arr[2] = { 0x1111, 0x2222 };
      uint8_t i = 0;
      while ( mySPI.active() ) {
        if (mySPI.available()) {
          mySPI.pushr(arr[i++]);
          Serial.print("VALUE: 0x");
          Serial.println(mySPI.popr(), HEX);
        }
      }
      Serial.println("END");
    }
    The output from the slave is clearly incorrect; it's too long to copy, but consists of this (after several seconds of operation):
    START:
    END
    START:
    END
    START:
    END
    START:
    END
    START:
    E18300


    And the output from the master is:
    65535
    65535
    65535
    65535
    65535
    65535
    65535
    65535
    65535

    You'd think after three years and change I'd know how to deal with this, but this one is definitely over my head. And seems to be quite the rare bird, too; reading high-speed data from an SPI slave is something that not many people seem to need to do. But in this case, I need to be able to read rather a lot of data from another Teensy 3.6. I2C and UART are out of the question; it's a LOT of data and needs to be transferred quickly.

    I know there are folks out there who have the "well, if you don't understand it, you don't need to use it" mind-set; I've encountered four (on other sites' forums) already this morning; and the "why don't you use a Raspberry Pi for that much data" folks as well. And the "Why aren't you using an Arduino, since it's better understood" folks. Please understand that my persistence is not mere stubbornness; I understand my technical problem, I really do, and I know how I want to solve it.

  9. #9
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    change spimode to “8” instead of 16 for 8 bit transfers, if your getting 65535 verify your miso is not swapped with mosi, you can always swap them to see if it works or use a scope. To so a simple test, send a spi byte every second from a master device amd verify the slave connections/code until you start seeing data

  10. #10
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    if you want to transfer arrays you could also try out SPI_MSTransfer, where it has peripheral controls and callback payload transfers in both directions

    This library was developed for high speed data transfers between one or more teensies

    use the final.zip file in the repo if you go that route, it was the last updated edition

  11. #11
    tonton:

    I decided to give SPI_MSTransfer a shot. I commented at the end of your development thread. The demos aren't working (although they are compiling). I tried crossing/uncrossing the streams, and moving CS pins around; no luck. I also replaced the library files with the ones from the .zip file, still no luck.

    I'm trying to build a small peripheral, based on a Teensy 3.6. The Teensy has some sensors on it; I will tell it which sensor I want data for by writing a command over I2C. That part is working; there's tons of code out there for that; I can even get back the number of bytes I want to transfer back from the slave to the master over SPI. The data I'm sending back will all be 8-bit data, no 16-bit data.

    I have to say, though...your code is really pretty advanced, and I'm having a difficult time reading it, though it's starting to make (a little) sense. But the SPI stuff isn't working at all, or doesn't seem to be. I'm guessing that you and defragster were using SPI to get GPS data back from another Teensy with a GPS sensor unit on it, but I'm having extreme difficulty adapting your example.

  12. #12
    Junior Member
    Join Date
    Feb 2019
    Posts
    1
    I'm trying to set up a SPI bus between 2 teensy 3.6 too. But I am unable to start any function on my slave to reply something when the master is asking. I tried to use the code from ariesboy571 but I didn't have any "START/END" printing from the slave (only the time from millis() in the loop). So I assume myFunction() is never called but I used the same code ase you...
    One of my 2 teensy is warming up a lot too.. I hope it isn't broken but I still have the feedback from Serial.println() so I think it's still working.
    Any guess on any solution to call a function on my slave when the master transfer some byte ?

  13. #13
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    sorry i didnt have much time lately in the process of changing work locations and hours, and snow, i need a few more days to stabilize

  14. #14
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,964
    getting ready for work soon but this morning I decided to setup a T3.5 and a T3.6 unit for testing SPI_MST

    Here is the last sketch that has worked on latest build of SPI_MST:
    https://forum.pjrc.com/threads/50008...l=1#post179524

    I must admit my code is not easy to look at, but I was still learning to code

    As per above last code, I modified it for my setup, you can download it here:
    Code:
    MST.zip
    On the T3.5 (Master) ------> T3.6 (Slave)

    GND (next to pin 0) ---------> GND (next to pin 0)
    ^-- *** DO NOT RELY ON USB COMMON GROUND ***

    pin 10 -----------> pin 2
    pin 11 -----------> pin 11
    pin 12 -----------> pin 12
    pin 14 -----------> pin 14


    As far as that goes, thats whats running as we speak now, validate it on your setup and if it doesn't work check the cabling. Also be aware the slave starts accepting traffic only after 5 seconds of boot, so just wait for it to kick in.
    Once you have it working you can strip out the rest of the uneeded bloat in the example thats not useful to you and you'll find the callback there where you can send data between teensies at SPI speeds

    Video: https://www.youtube.com/watch?v=VKtNqssDjS4
    Last edited by tonton81; 02-26-2019 at 06:54 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •