SPI code stops working with Teensyduino 1.58

Heymor

New member
Hi,

I have code (snippet below) which uses SPI on the Teeny 4.1. The code works consistently when using the 1.57.2 Teensyduino in the Boards Manager in Arduino IDE 2.1.0.

When switching to 1.58 in the Boards Manager, the code causes the Teensy to restart (can be seen through the current consumption reducing). I see this in 1.58.1 as well.

It seems that any call to SPI1 makes the Teensy restart. I'm putting this in the `Bugs` forum as I couldn't find any mention of a new required initialization function for SPI in the changelogs, please let me know if this is incorrect. Thanks!

Code:
SPI1.beginTransaction(_spi_settings);
digitalWriteFast(_cs_pin, LOW);

// Send command
SPI1.transfer(tx_buf, rx_buf, sizeof(tx_buf));
response = buf_to_val(rx_buf);
place_response(response);
_write_reg_flag = true;

// Update tx_buf with reg_val
val_to_buf(reg_val, tx_buf);
SPI1.transfer(tx_buf, rx_buf, sizeof(tx_buf));

// Read in the incoming data and throw it out
for(size_t i = 0; i < NUM + 1; i++) {
    SPI1.transfer(NULL, rx_buf, sizeof(rx_buf));
}

// End the SPI communication
digitalWriteFast(_cs_pin, HIGH);
SPI1.endTransaction();
 
Please reply with this as a complete program I can copy into Arduino and upload to Teensy 4.1 to reproduce the problem. Even if the rest of the program is "trivial", please eliminate the guesswork needed to reproduce the problem.
 
Thank you for the quick response.

Yes, will do - I’ll get a minimal example of this restarting behavior together soon.
 
With the code below, I see restarting behavior on 1.58.1. I do not see the restarting behavior in 1.57.2. I am using `Dual Serial` and `CPU Speed: 816MHz`. I confirmed it was restarting through looking at the current consumption and the addition of the LED light clause in the `init()` function.

Code:
#include <string.h>
#include <SPI.h>

#define MISO1      1
#define CS0        25
#define MOSI1      26
#define SCLK1      27
#define IRQ        17
#define SYNC_RESET 41
#define LED        13

void init();

class Example {
public:
  Example(uint8_t cs_pin, uint8_t irq_pin, 
        uint8_t sync_reset_pin, SPIClass spi_port, usb_serial_class comp_serial_port) 
    : _cs_pin(cs_pin), _irq_pin(irq_pin), _sync_reset_pin(sync_reset_pin), 
    _spi_port(spi_port), _comp_serial_port(comp_serial_port) {
    
    _cmd_bytes = 3; 

    _spi_settings = SPISettings(14500000, MSBFIRST, SPI_MODE1);
  }

  void write_reg(uint16_t reg, uint16_t reg_val) {
    uint16_t response;
    uint8_t tx_buf[_cmd_bytes] = { 0 };
    uint8_t rx_buf[_cmd_bytes] = { 0 };

    uint16_t cmd = (0x6000) | (reg << 7);
    val_to_buf(cmd, tx_buf);

    _spi_port.beginTransaction(_spi_settings);
    digitalWriteFast(_cs_pin, LOW);

    _spi_port.transfer(tx_buf, rx_buf, sizeof(tx_buf));
    response = buf_to_val(rx_buf);

    val_to_buf(reg_val, tx_buf);
    _spi_port.transfer(tx_buf, rx_buf, sizeof(tx_buf));

    for (size_t i = 0; i < 4 + 1; i++) {
      _spi_port.transfer(NULL, rx_buf, sizeof(rx_buf));
    }

    digitalWriteFast(_cs_pin, HIGH);
    _spi_port.endTransaction();
  }

  void send_reset_pulse(uint32_t duration_us) {
    digitalWriteFast(_sync_reset_pin, HIGH);
    delayMicroseconds(duration_us);
    digitalWriteFast(_sync_reset_pin, LOW);
    delayMicroseconds(duration_us);
    digitalWriteFast(_sync_reset_pin, HIGH);
  }

private:
  size_t _cmd_bytes;

  uint8_t _cs_pin;
  uint8_t _irq_pin;
  uint8_t _sync_reset_pin;

  SPISettings _spi_settings;
  SPIClass _spi_port;

  usb_serial_class _comp_serial_port;

  uint16_t buf_to_val(uint8_t* buf) {
      return (buf[0] << 8) | buf[1];
  }

  void val_to_buf(uint16_t val, uint8_t* buf) {
      buf[0] = (val >> 8) & 0xFF;
      buf[1] = val & 0xFF;
  }
};

Example adc(CS0, IRQ, SYNC_RESET, SPI1, Serial);

void setup() {
  // Begin the Serial for direct communication
  Serial.begin(912600); 
  SerialUSB1.begin(912600);  

  // No interrupts for the duration of the setup
  noInterrupts();

  init();

  interrupts();
}

void loop() {
}

void init() {
  // Pin setup
  pinMode(CS0, OUTPUT);
  pinMode(SYNC_RESET, OUTPUT);
  pinMode(IRQ, INPUT);
  pinMode(LED, OUTPUT);
  digitalWriteFast(LED, HIGH);
  delay(1000);
  digitalWriteFast(LED, LOW);
  delay(500);

  // Reset ADCs
  adc.send_reset_pulse(1000);

  digitalWrite(CS0, HIGH);

  SPI1.begin();

  // Send initialization command
  adc.write_reg(0x03, 0x0F83);
}
 
Back
Top