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

Thread: Teensy 4.1 SPI stops

  1. #1
    Junior Member
    Join Date
    Jul 2021
    Posts
    2

    Teensy 4.1 SPI stops

    Hi,

    i'm currently working on a project where the Teensy 4.1 sends data over SPI. When I reset the slave device, the master MOSI signal becomes stuck at 0 for the entirety of each transfer (and therefore the slave only receives zeros). The slave doesn't sent anything back, SS and SCK seem to work.

    Code:
    #define LOOP_TIME_MS 10
    #define SS_PIN 10
    
    uint8_t tArr[] = {4,2,3,4};
    
    #include "SPI.h"
    
    void setup() {
      pinMode(SS_PIN, OUTPUT);
      digitalWrite(SS_PIN, HIGH);
      
      SPI.begin();
    }
    
    void loop() {
      uint32_t timestamp = millis();
      SPI.beginTransaction(SPISettings(100000U, MSBFIRST, SPI_MODE0));
      digitalWrite(SS_PIN, LOW);
      SPI.transfer(tArr, 4);
      digitalWrite(SS_PIN, HIGH);
      SPI.endTransaction();
      while(millis() - timestamp < LOOP_TIME_MS);
    }

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,775
    I would like to try this, but I don't understand "When I reset the slave device".

    Can you be more specific about exactly which SPI device you have connected, and exactly what you're doing to "reset" it? I don't see anything in this code which looks like it would reset another chip, so I'm rather confused about how to perform this test.

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    And how do you see that? Do you use an LA or scope?

  4. #4
    Junior Member
    Join Date
    Jul 2021
    Posts
    2
    Found the issue.
    Code:
    SPI.transfer(pointer, bytecount)
    doesn't work. The same setup with
    Code:
    for(int i =0; i < sizeof(data); i++) 
    {
    SPI.transfer(((uint8_t*)&data)[i]); 
    }
    works.

    It's also never mentioned that
    Code:
    SPI.transfer(pointer, bytecount)
    is supported, but I guess it would have helped (for me at least) to mention it won't work like this in the producct page.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,054
    that's pretty unlikely...

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,775
    SPI.transfer(buffer, length) is used by Ethernet and other libraries. It does indeed work.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,775
    My guess is you're not dealing with the fact that SPI.transfer(buffer, length) overwrites the buffer with whatever is received on the MISO pin. Of course that's just guesswork since you only showed tiny code fragments, so nobody can know what the surrounding code does.


    But regarding those code fragments, there is a clear error. You replaced SPI.transfer(buffer, length) with this:

    Code:
    for(int i =0; i < sizeof(data); i++) {
      SPI.transfer(((uint8_t*)&data)[i]); 
    }
    But the actual functionality SPI.transfer(buffer, length) implements is this:

    Code:
    for(int i =0; i < sizeof(data); i++) {
      ((uint8_t*)&data)[i] = SPI.transfer(((uint8_t*)&data)[i]); 
    }
    You can't say SPI.transfer(buffer, length) is incorrect when you tested a replacement that isn't the same thing!



    I ran your code from msg #1 without anything connected, just my oscilloscope. Here's the result.

    Click image for larger version. 

Name:	file1.png 
Views:	5 
Size:	37.4 KB 
ID:	25439

    At first glance, this looks like the SPI port is failing to transmit your 4 data bytes. But it does indeed transmit them correctly, the first time loop() runs. Then they are overwritten with whatever MISO receives, which happens to be zeros when I tested here. That's why the blue trace doesn't show your 4 data bytes.

    But it I edit the code to always initialize the array with the data, indeed the data transmits every time.

    Code:
    #define LOOP_TIME_MS 10
    #define SS_PIN 10
    
    uint8_t tArr[] = {4,2,3,4};
    
    #include "SPI.h"
    
    void setup() {
      pinMode(SS_PIN, OUTPUT);
      digitalWrite(SS_PIN, HIGH);
      
      SPI.begin();
    }
    
    void loop() {
      uint32_t timestamp = millis();
      tArr[0] = 4;
      tArr[1] = 2;
      tArr[2] = 3;
      tArr[3] = 4;
      SPI.beginTransaction(SPISettings(100000U, MSBFIRST, SPI_MODE0));
      digitalWrite(SS_PIN, LOW);
      SPI.transfer(tArr, 4);
      digitalWrite(SS_PIN, HIGH);
      SPI.endTransaction();
      while(millis() - timestamp < LOOP_TIME_MS);
    }
    Click image for larger version. 

Name:	file2.png 
Views:	8 
Size:	38.7 KB 
ID:	25440

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,412
    Note: there is also a transfer of a buffer that allows you to not overwrite... SPI.transfer(buffer, return_buffer, count);
    Where buffer and/or retbuffer can be NULL. Like when you are not interested in what comes back on the MISO line
    SPI.transfer(tArr, nullptr, 4);

    Should transfer your array, and toss the results

Posting Permissions

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