Teensy 4.1: Setup routine ends early without obvious reason

Status
Not open for further replies.

jakobJakobson

New member
Hello all,

I am trying to read-out an optical encoder (Renishaw) via SPI & a BiSS Interface (iC-MB4 eval board containing an iC-MB100: https://www.ichaus.de/upload/pdf/MB100_datasheet_B1en.pdf). I've successfully done this in Python via a raspberry, now I am trying to implement this on a Teensy 4.1 in C. My current problem however is, that my set-up routine, where I write the registers of the iC-MB4 via SPI for configuration purposes, doesn't completely run through to its end. It somehow always stops early without an obvious reason - at least I don't see one, hopefully someone does.

Here is a minimal code example of my set-up routine and the serial output, when I run the program:

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

#define DEBUG 1

// SPI CONFIGURATION
const int SPI_SPEED = 16000000;
const int SPI_BUS = 0;
const int SPI_MODE = 0;
const int SPI_SS = 10; // tbd

// SPI COMMAND DEFINITIONS
const int CMD_WRITE = 0x02;
const int CMD_READ = 0x03;
const int CMD_INSTRUCTION = 0x07;
const int CMD_STATUS = 0x05;

// SLAVE DATA ADRESSES
const int SLAVE_1_BYTE1 = 0x00;
const int SLAVE_2_BYTE2 = 0x01;

// DATA REGISTER ADRESS
const int SCDATA1_ADR_1 = 0x00;
const int SCDATA1_ADR_2 = 0x01;
const int SCDATA1_ADR_3 = 0x02;
const int SCDATA1_ADR_4 = 0x03;

// MASTER CONFIG
const int MASTER_FREQAGS_ADR = 0xE8;
const int MASTER_FREQAGS_VAL = 0x7C;

// INTRUCTION CONFIG
const int INSTR_ADR = 0xF5;
const int INSTR_VAL = 0b00000100;

// SLAVE CONFIG
const int SLAVE_HEAD1_ADR = 0xC0;
const int SLAVE_HEAD1_VAL = 0b01100000;

const int SLAVE_HEAD2_ADR = 0xD0;
const int SLAVE_HEAD2_VAL = 0b01100000;

// CHANNEL CONFIG
const int CHANNEl_SLAVELOC_ADR = 0xEC;
const int CHANNEl_SLAVELOC_VAL = 0b00010000;

const int CHANNEl_CFGCH_ADR = 0xED;
const int CHANNEl_CFGCH_VAL = 0b00000101;

// data structure
// int readValues;

void setup() {
  //
  delay(1000);
  
  // put your setup code here, to run once:
  Serial.println("Starting setup...");
  
  SPI.begin();
  SPI.setDataMode(SPI_MODE);
  pinMode(SPI_SS, OUTPUT);
  delay(100);
  digitalWrite(SPI_SS, HIGH);

  Serial.begin(9600);
  Serial.println("Setup finished");

#ifdef DEBUG
  Serial.println("Starting encoder configuration...");
#endif

  // channel config
  writeRegister(CHANNEl_SLAVELOC_ADR, CHANNEl_SLAVELOC_VAL);
  delay(250);

  Serial.println("Channel_SLAVELOC_ARD set");
  
  // master config
  writeRegister(MASTER_FREQAGS_ADR, MASTER_FREQAGS_VAL);
  delay(250);

  Serial.println("MASTER_FREQAGS_ADR set");

  // slave config
  writeRegister(SLAVE_HEAD1_ADR, SLAVE_HEAD1_VAL);
  delay(250);

  Serial.println("SLAVE_HEAD1_ADR set");

  writeRegister(CHANNEl_CFGCH_ADR, CHANNEl_CFGCH_VAL);
  delay(250);

  Serial.println("CHANNEl_CFGCH_ADR set");

  // instr config
  writeRegister(INSTR_ADR, INSTR_VAL);
  delay(250);

  Serial.println("INSTR_ADR set");

#ifdef DEBUG
  Serial.println("Encoder configuration finished!");
#endif

  // run configuration of Encoder
  // run_configuration();
  Serial.println("Start Delay now!");
  delay(5000);
}

void loop() {
  // nothing here
}

void writeRegister(int registerAddress, int value) {
#ifdef DEBUG
  Serial.println("Writing register: ");
  Serial.print("    Adress:   ");
  Serial.println(registerAddress, HEX);
  Serial.print("    Value:    ");
  Serial.println(value, BIN);
#endif

  // Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(SPI_SS, LOW);
  // Transfer write command
  SPI.transfer(CMD_WRITE);
  // Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  // Transfer the desired register value over SPI.
  // ignored the reture of SPI.transfer in writer operation
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(SPI_SS, HIGH);

#ifdef DEBUG
  Serial.println("Writing register done!");
#endif
}

HTML:
Starting setup...
Setup finished
Starting encoder configuration...
Writing register: 
    Adress:   EC
    Value:    10000
Writing register done!
Channel_SLAVELOC_ARD set
Writing register: 
    Adress:   E8
    Value:    1111100
Writing register done!
MASTER_FREQAGS_ADR set
Writing register: 
    Adress:   C0
    Value:    1100000
Writing register done!

I've tried to switch up the order of which registers are written, it doesn't seem to matter - it simply doesn't proceed to the end of the setup routine, usually the process seems to be stopped after 3 or 4 registers are written (according to the Serial output).

Any ideas what might be the problem here?

Thanks a lot in advance to anyone who might help!
 
What version of TeensyDuino? Try version 1.55 if not using that or the 1.56 beta already.

Is the Teensy showing signs of a restart after like 8 seconds?

It may be suffering a detectable Crash and adding this to setup() might help pinpoint it:
Code:
void setup() {
  while (!Serial );
  if (CrashReport) {
    Serial.print(CrashReport);
  }

// ...

If the Teensy is Crashing all pending output might not make it - so it might be after the visible prints. Moving a { Serial.flush(); delay(100); } down the code path after prints may help see for sure which is the last.
 
I am using Teensyduino 1.54 & Arduino 1.8.15.

I just implemented your advice + I've noticed, that in my original draft I used Serial.println("Starting setup..."); before I even initialized Serial with Serial.begin(9600) ...

The code now looks like this:

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

#define DEBUG 1

// SPI CONFIGURATION
const int SPI_SPEED = 16000000;
const int SPI_BUS = 0;
const int SPI_MODE = 0;
const int SPI_SS = 10; // tbd

// SPI COMMAND DEFINITIONS
const int CMD_WRITE = 0x02;
const int CMD_READ = 0x03;
const int CMD_INSTRUCTION = 0x07;
const int CMD_STATUS = 0x05;

// SLAVE DATA ADRESSES
const int SLAVE_1_BYTE1 = 0x00;
const int SLAVE_2_BYTE2 = 0x01;

// DATA REGISTER ADRESS
const int SCDATA1_ADR_1 = 0x00;
const int SCDATA1_ADR_2 = 0x01;
const int SCDATA1_ADR_3 = 0x02;
const int SCDATA1_ADR_4 = 0x03;

// MASTER CONFIG
const int MASTER_FREQAGS_ADR = 0xE8;
const int MASTER_FREQAGS_VAL = 0x7C;

// INTRUCTION CONFIG
const int INSTR_ADR = 0xF5;
const int INSTR_VAL = 0b00000100;

// SLAVE CONFIG
const int SLAVE_HEAD1_ADR = 0xC0;
const int SLAVE_HEAD1_VAL = 0b01100000;

const int SLAVE_HEAD2_ADR = 0xD0;
const int SLAVE_HEAD2_VAL = 0b01100000;

// CHANNEL CONFIG
const int CHANNEl_SLAVELOC_ADR = 0xEC;
const int CHANNEl_SLAVELOC_VAL = 0b00010000;

const int CHANNEl_CFGCH_ADR = 0xED;
const int CHANNEl_CFGCH_VAL = 0b00000101;

// data structure
// int readValues;

void setup() {
  //
  Serial.begin(9600);
  delay(1000);

  while(!Serial){
    ; //wait until Serial is ready}
  }

  if (CrashReport) {
    Serial.print(CrashReport);
  }
  
  // put your setup code here, to run once:
  Serial.println("Starting setup...");

  SPI.begin();
  SPI.setDataMode(SPI_MODE);
  pinMode(SPI_SS, OUTPUT);
  delay(100);
  digitalWrite(SPI_SS, HIGH);
  
  Serial.println("Setup finished");

#ifdef DEBUG
  Serial.println("Starting encoder configuration...");
#endif

  // channel config
  writeRegister(CHANNEl_SLAVELOC_ADR, CHANNEl_SLAVELOC_VAL);
  delay(250);

  Serial.println("Channel_SLAVELOC_ARD set");

  // master config
  writeRegister(MASTER_FREQAGS_ADR, MASTER_FREQAGS_VAL);
  delay(250);

  Serial.println("MASTER_FREQAGS_ADR set");

  // slave config
  writeRegister(SLAVE_HEAD1_ADR, SLAVE_HEAD1_VAL);
  delay(250);

  Serial.println("SLAVE_HEAD1_ADR set");

  writeRegister(CHANNEl_CFGCH_ADR, CHANNEl_CFGCH_VAL);
  delay(250);

  Serial.println("CHANNEl_CFGCH_ADR set");

  // instr config
  writeRegister(INSTR_ADR, INSTR_VAL);
  delay(250);

  Serial.println("INSTR_ADR set");

#ifdef DEBUG
  Serial.println("Encoder configuration finished!");
#endif

  // run configuration of Encoder
  // run_configuration();
  Serial.println("Start Delay now!");
  delay(5000);
}

void loop() {
  // nothing here
}

void writeRegister(int registerAddress, int value) {
#ifdef DEBUG
  Serial.println("Writing register: ");
  Serial.print("    Adress:   ");
  Serial.println(registerAddress, HEX);
  Serial.print("    Value:    ");
  Serial.println(value, BIN);
#endif

  // Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(SPI_SS, LOW);
  // Transfer write command
  SPI.transfer(CMD_WRITE);
  // Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  // Transfer the desired register value over SPI.
  // ignored the reture of SPI.transfer in writer operation
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(SPI_SS, HIGH);

#ifdef DEBUG
  Serial.println("Writing register done!");
#endif
}

and seems to work just like expected:


HTML:
Starting setup...
Setup finished
Starting encoder configuration...
Writing register: 
    Adress:   EC
    Value:    10000
Writing register done!
Channel_SLAVELOC_ARD set
Writing register: 
    Adress:   E8
    Value:    1111100
Writing register done!
MASTER_FREQAGS_ADR set
Writing register: 
    Adress:   C0
    Value:    1100000
Writing register done!
SLAVE_HEAD1_ADR set
Writing register: 
    Adress:   ED
    Value:    101
Writing register done!
CHANNEl_CFGCH_ADR set
Writing register: 
    Adress:   F5
    Value:    100
Writing register done!
INSTR_ADR set
Encoder configuration finished!
Start Delay now!

Thanks a lot for your quick help!
 
Status
Not open for further replies.
Back
Top