Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 49

Thread: Teensy 3.0 as SPI Slave

  1. #1
    Junior Member
    Join Date
    Mar 2013
    Posts
    1

    Teensy 3.0 as SPI Slave

    Could someone point me to an example of how to program Teensy 3.0 as an SPI Slave? I am a little confused at the moment.

    Thanks,
    Ed

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,685
    I wish I could. So far, I've not used this mode and I haven't seen anyone who has publish any code.

  3. #3
    I'm working on it ebrady. But I am having problems clocking in my data. Have you had any luck?

  4. #4
    Here's where I'm at with it, and begging for help from some Jedi Master out there:

    From my research, doing SPI slave mode should be pretty easy.
    1) Configure the MCR register for slave mode, write MCR = 0x00000000.
    2) Configure the CTAR0_SLAVE register for the correct frame size, clock polarity, and clock phase (same as the master uses).
    3) Clock in data to the SIN pin.
    4) Use the RXCTR and the POPR register to grab the data from the RX FIFO registers.

    But I can't get data to clock in!

    According to the datasheet (MK20 Datasheet):
    1) In Slave Mode "The SCK signal and the PCS[0]/SS signals are configured as inputs and driven by an SPI bus master."
    So...once in slave mode, no further configuration of these pins is necessary?

    2) "SPI data is added to the RX FIFO at the completion of a transfer when the received data in the shift register is transferred into the RX FIFO...The RX FIFO is filled with the received SPI data from the shift register. While the RX FIFO is not full, SPI frames from the shift register are transferred to the RX FIFO. Every time an SPI frame is transferred to the RX FIFO, the RX FIFO Counter is incremented by one."
    I can't get my RXCTR to increment, meaning that I'm not getting anything to shift into the RX FIFO registers.

    Maybe I am mis-reading something somewhere. I have even tried re-assigning CLK pin 13 to CLK pin 14 (I thought maybe there was hardware interference with the LED).
    I feel like my spi module isn't receiving clocks.

    Here is the sketch I'm running...there is a serial print of MCR, CTAR0_SLAVE, SR, RSER, and the RXFR0 registers, and also an indicator showing that I am receiving clock cycles.
    Code:
    uint32_t ctar0, ctar1, ctar_slave, mcr;
    bool serialPrint_ONS=LOW;
    long clkCTU=0;
    unsigned long serialTMR=0;
    
    void setup(){
      
      Serial.begin(57600);
      
      SPCR =0x40; // |= _BV(SPE);  //From Arduino, dosn't work without it??
      SPI0_MCR         = 0x01000400;
      SPI0_RSER        = 0x00000000;
      SPI0_CTAR0_SLAVE = 0x38000000; //0x11000000;
      
      //take clock off pin 13
      CORE_PIN13_CONFIG = PORT_PCR_MUX(1);
      //put clock on pun 14
      CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
      
      pinMode(SS, INPUT);      //Pin 10
      pinMode(MISO, INPUT);    //Pin 12
      pinMode(14, INPUT);      //Clock
    }
    
    void loop(){
      if (digitalReadFast(14)){
        clkCTU++;}
    
      if (serialPrint_ONS == LOW){
        serialTMR = millis();
        serialPrint_ONS = HIGH;}
      if(millis() - serialTMR > 1000){ 
        
        //These numbers show what bit you are looking at
        Serial.println("                      33222222222211111111110000000000");
        Serial.println("                      10987654321098765432109876543210");
        Serial.println("                      --------------------------------");
        
        //Zeros are uses for placeholders
        Serial.print("SPIO_MCR:             0000000");
        Serial.println(SPI0_MCR,BIN);
        Serial.print("SPIO_CTAR0_SLAVE:     00");
        Serial.println(SPI0_CTAR0_SLAVE,BIN);
        Serial.print("SPI_SR:               0");
        Serial.println(SPI0_SR,BIN);
        Serial.print("SPI_RSER:             0000000000000000000000000000000");
        Serial.println(SPI0_RSER,BIN);
        Serial.println("                      --------------------------------");
        Serial.print("SPI_RXFR              ");
        Serial.println(SPI0_RXFR0,BIN);
        Serial.print("Clock (not accurate)  ");
        Serial.println(clkCTU);
        Serial.println();
        Serial.println();
        Serial.println();
        serialPrint_ONS = LOW;
      }
    }
    Last edited by btmcmahan; 05-27-2013 at 11:23 PM.

  5. #5
    I'm receiving SPI data on my slave. I have a lot of cleanup to do with the logic, but I'm getting data.
    Thanks CMASON & PLOVEDAY...I'm using big chunks of code that you two did before me.
    I'll try post something more significant in the next couple of days.

  6. #6
    I have a functioning teensy 3.0 spi master/slave set. Need to run some speed tests, I'll post everything tomorrow after work.

  7. #7
    Here's what I have so far. The slave is interrupt based, but it works at 24Mhz (I don't have an oscope so I can't verify that I'm clocking 24Mhz). It works for 8 & 16 bits.
    The examples serial.print several transfer statistics.

    @ 24MHz, On 16 bit transfers, 1000 transfers per packet, looping 500 times, I get 1.25 MBpS (my FOR loop is probably slowing it down a lot).

    The Slave is using the clock input on pin14, Master clock is pin13.
    ChipSelect pin is 10 on both Master and Slave.
    DataOut is Pin11 on the master.
    DataIn is pin12 on the slave.


    I have not set it up yet for slave to master transfers, so it is currently one-way master to slave. I intend to post some updates, make the library more universal, use other CTAR's, CS pins, and enable slave to master transfers. Please post or message any questions or comments. And feel free to suggest changes.

    Teensy 3.0 Master & Slave (on GitHub)
    Last edited by btmcmahan; 09-01-2013 at 05:32 AM.

  8. #8
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,643
    Good work ... but the github link doesn't work for me ???
    ... though it is possible github is having problems.... i'll try again later

  9. #9
    it works for me. maybe it was on their end
    Last edited by btmcmahan; 06-02-2013 at 04:54 PM.

  10. #10
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,643
    yep, github is working now. code looks good.

    Just curious why use pin 14 for clk and not 13? (I don't really understand the gray-ed out pin names on the "pin assignment" image ...)
    thanks

  11. #11
    Ya, the gray pins indicate alternate pin setups. I used Pin14 for the clock because it frees up the LED. Here is a Thread about pin reassignment. If you do reassign some pins, you have to do it different ways for inputs & outputs.

  12. #12
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,643
    I looked at your SPI on logic analyzer. with DIV2 (0), groups of 16 bits are clocked at 24mhz, with a 0.7188us gap between each 16-bit group. Looks good.

    In an earlier thread I compared unconnected SPI speeds for AVR-emulation mode and SDfat lib's optimized SPI. Those results are summarized at

    https://github.com/manitou48/DUEZoo/...er/SPIperf.txt

  13. #13
    yes, there is a "wait" function being used after every data TX, it can be removed for even faster rates. When I removed it, I couldn't communicate with my SPI digi potentiometer, so I guess it depends on your application.
    I would think that at 24mhz, if the SPI_wait() was removed, the master might over-run the slave. There are only 4 registers in the slave RX buffer, so if you don't call the interrupt fast enough, you're gonna start skipping data.
    The RX interrupt could probably be streamlined to get a little more speed out of it.

    I know nothing about DMA, but I'm guessing we would get much higher speeds if we used DMA instead of the interrupt. I don't know if I have the energy or patience to attempt it.

    What Logic Analyzer do you use? I want to get one.
    Last edited by btmcmahan; 06-02-2013 at 08:40 PM.

  14. #14
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,643
    Quote Originally Posted by btmcmahan View Post

    What Logic Analyzer do you use? I want to get one.
    saleae.com logic16 and a not-so-fast, but cheap Parallax USB PropScope

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,685
    I have the Saleae Logic16. I use Linux as my primary system, and I would absolutely NOT recommend Saleae to anyone who uses Linux. Their software crashes frequently, often causing total data loss.

    I saw them at Maker Faire and mentioned this. Apparently at that very moment, they were trying to run it on one of their computers which someone had installed Linux upon. It was crashing. They mentioned a new developer was hired and hopefully improved software will be out by the end of the summer. I'm hopeful, because it does seem like a nice product (and I did use it once, but it took many tries to get a capture saved to a text file which I then anayzed by writing Perl scripts).

    Saleae probably runs much better on Windows, maybe Mac too? But if you use Linux, the software is so buggy it's pretty much unusable.

  16. #16
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,643
    Quote Originally Posted by PaulStoffregen View Post
    Saleae probably runs much better on Windows, maybe Mac too? But if you use Linux, the software is so buggy it's pretty much unusable.
    I have had same experience with Linux, and I run logic16 on old XP laptop. Saleae said they are working on fixing the linux version, but I haven't tried it with Linux recently ...

  17. #17
    Senior Member
    Join Date
    Apr 2013
    Posts
    106
    Quote Originally Posted by btmcmahan View Post
    Here's what I have so far. The slave is interrupt based, but it works at 24Mhz (I don't have an oscope so I can't verify that I'm clocking 24Mhz). It works for 8 & 16 bits.
    The examples serial.print several transfer statistics.

    @ 24MHz, On 16 bit transfers, 1000 transfers per packet, looping 500 times, I get 1.25 MBpS (my FOR loop is probably slowing it down a lot).

    The Slave is using the clock input on pin14, Master clock is pin13.
    ChipSelect pin is 10 on both Master and Slave.
    DataOut is Pin11 on the master.
    DataIn is pin12 on the slave.


    I have not set it up yet for slave to master transfers, so it is currently one-way master to slave. I intend to post some updates, make the library more universal, use other CTAR's, CS pins, and enable slave to master transfers. Please post or message any questions or comments. And feel free to suggest changes.

    Teensy3.0 SPI Master & Slave Set (on GitHub)
    Nice work,

    btw. did I see that right the slave can only receive messages and not answer?

  18. #18
    yes. I haven't checked it yet, but you should be able to use PUSHR_SLAVE to queue data to be shifted out. And the master can use POPR to get it.

  19. #19
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    415
    Quote Originally Posted by btmcmahan View Post
    What Logic Analyzer do you use? I want to get one.
    Just a comment on this. I saw this list someone had compiled a while back about Logic Analyzers under $500:
    Logic Analyzers under $500

    I have a Zeroplus and I highly recommend it (I have a 16128+, but IMO the 16128 is at the best price/performance point). The software is Windows only, unfortunately no idea if it would run under Wine or such. I think for analyzers the software is really almost more important than the hardware. I would recommend running any demos if they exist.

    The Zeroplus analyzers can decode a large number of protocols, nothing else even comes close (and they usually have a 30 free protocol offer). Only caveat I've found is that it doesn't effectively trigger on an arbitrary software protocol condition. This is because protocols are decoded on the PC and it doesn't stream continuously (reason for that is because it can capture at 200MHz). In the program software triggers exist, but I haven't quite figured out how to use them effectively. What it requires is a hardware trigger (eg. for I2C something like SDA falling-edge while SCL high), but once triggered the protocol decoders kick in and you can search for and jump around to specific protocol patterns. I had some captures shown in this thread if your curious what it looks like.

  20. #20
    I have uploaded a more complete library for using SPI master & slave.

    This lib lets you:
    1) send data from the slave back to the master
    2) use any SPI pin, including the alternate pins (gray on the pinout chart)
    3) easily begin SPI and setup custom CTAR's
    4) see statistical data from your sending/receiving (SPI registers, mbps, uSec per byte, ect.)
    5) extensive readme.txt explaining the purpose & use of all functions

    Teensy 3.0 Master & Slave (on GitHub)
    Last edited by btmcmahan; 09-01-2013 at 05:32 AM.

  21. #21
    Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    89
    Quote Originally Posted by btmcmahan View Post
    I have uploaded a more complete library for using SPI master & slave.


    Teensy 3.0 Master & Slave (on GitHub)
    Thanks for the great library!
    It looks like that due to v1.15 SPI0_PUSHR_PCS and SPI0_PUSHR_CTAS need to be charged to SPI_PUSHR_PCS and SPI_PUSHR_CTAS in t3spi.cpp
    After that change it works great!

  22. #22
    Updated the lib link

  23. #23
    Has anyone tested this with the Teensy 3.1?

  24. #24
    I have. It works. I have updated the library some, and I've learned some new tricks with it. Let me know if you need any assistance.

  25. #25
    Thanks!

    I've only managed to get it compiling (by changing the things John mentioned about).

Posting Permissions

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