Cannot get SPI working on Arduino M0 (SOLVED)

Hi, I’ve been working on getting a SPI interface working on a M0 for days with no luck.

After failing with my own code, I’m using the below code from Adafruit Example for SERCOM1 still with no success.

I’ve modified the code to toggle Pin 4 to be sure I can actually control a pin.

My status:

  • I’m using an oscilloscope to view the signal (or lack of)
  • I have verified Pin 4 is toggling.
  • The TX LED is blinking
  • There are no signals on pins 11, 12 or 13 and on any others except for Pin 4
  • I have added a 10K from pins 12 & 13 to 3.3V with no change in signals.

My code:

// except as noted, this is an exact copy of the SERCOM1 example from this webpage.
//https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports?view=all#creating-a-new-spi



#include <SPI.h>
#include "wiring_private.h" // pinPeripheral() function

SPIClass mySPI (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);

void setup() {
  SerialUSB.begin(115200);
  pinMode(4,OUTPUT);

  // do this first, for Reasons
  mySPI.begin();

  // Assign pins 11, 12, 13 to SERCOM functionality
  pinPeripheral(11, PIO_SERCOM);
  pinPeripheral(12, PIO_SERCOM);
  pinPeripheral(13, PIO_SERCOM);
}

uint8_t i=0;
void loop() {
  if(digitalRead(4))        // added toggling output on pin 4.
    {digitalWrite(4,0);}
  else {digitalWrite(4,1);}
  SerialUSB.println(i);
  mySPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // speed was 8000000
  mySPI.transfer(i++);
  mySPI.endTransaction();
  delay(400);
}

Has anyone been successful with the SPI on this board? If so can you post the basic SPI setup you are using?

Thanks

John

----UPDATE—

I had been using the USB to program, power and monitor the above program. I have since tried using an external 5V source without the USB.

Results:
On power up there are no SPI signals.
Pushing the reset button, the clock and the Blue TX LED run for 5 seconds then stop. Clock frequency is 10 Hz.

So i’m still very lost :frowning:

John

why not use the preconfigured SPI on the SPI header with the SPI library?

Thank you, the default worked :)

In desperation (and with your suggestion) I just deleted all the "extra" configuration code and reverted back to the same code that had run on a Pro Mini. It is now working.

Still it is still frustrating that I cannot setup a different SPI port on this board :( I would still like to understand why the example did not work.

John

I now have SERCOM1 working on my Arduino M0 board. I’m using a MAX31855 T/C converter reading via the SPI.

My Code is:

/***************************************************************************************************/
/*
Target Board: Arduino M0
Target Sensor: MAX31855k

2019-11-06  R00.1 Initial Release  we need to review _CS sequence..!!!!!!!!!!!!!!

 MAX31855k Thermocouple A/D Converter  - JRF
The MAX31855 uses the SPI bus but only sends data, does not receive.  All the data is in one 32bit
"register" which is read by two SPI16 reads.

Sampling is controlled by the _CS pin:
    _CS HIGH = disables the SPI output and enables the sampling the T/C value
                we need to keep _CS HIGH if other devices need to use the same SPI bus.
    _CS LOW = enables the SPI bus and can be read by the µP.
It seems the 1st reading after power up is 20° high. Not clear why.  If the T/C compensation value
was not yet valid, the output would be low by 20° not high.

This version reads the whole 32 bit register.  For compensated temperature and "FAULT" data we
really only need to read the MSB (16 bits).  Perhaps in the next revision.

MISO = Pin 12
SCK  = Pin 13
MOSI = Pin 11 (not used for the MAX31855)
ChipSelect  = Pin 4
MAX31855k Power = 5V (from M0 on board regulator)

*/
/***************************************************************************************************/

#include <SPI.h>
#include "wiring_private.h"      // pinPeripheral function

#define _CS 4                    // use pin 4 as chip select.
#define TypeK_Conversion 100     // 100 ms max by spec
#define TypeK_Powerup_delay 200  // 200 ms min for delay from Vpwrup to conversion.

bool Typek_Fault = false;


 //SPIClass mySPI (&PERIPH_SPI,  PIN_SPI_MISO,  PIN_SPI_SCK,  PIN_SPI_MOSI, SercomSpiTXPad, SercomRXPad);
 SPIClass mySPI (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);

// *** function prototypes ****************************************************
float ReadTypeKTemp(void);
// ****************************************************************************

void setup()
{
  pinMode(_CS, OUTPUT);
  digitalWrite(_CS, HIGH);       //disables SPI interface for MAX31855, but it will initiate measure

  SerialUSB.begin(115200);
  delay(3000);
  SerialUSB.println("Opening serial port...");

  mySPI.begin();

  pinPeripheral(11, PIO_SERCOM);
  pinPeripheral(12, PIO_SERCOM);
  pinPeripheral(13, PIO_SERCOM);
  delay(2500);
}

void loop()
{
  SerialUSB.print("  temperature ..   ");
  SerialUSB.println(ReadTypeKTemp(),2);
  SerialUSB.println(Typek_Fault);
  delay(2000);
}

// ---  Functions  -----------------------------------------------------------

float ReadTypeKTemp(void){
  digitalWrite(_CS, LOW);      // measurement paused
  delayMicroseconds(5);
  digitalWrite(_CS, HIGH);     //start measurement
  delay(200);
  digitalWrite(_CS, LOW);
  uint32_t _rawData = 0;
  mySPI.beginTransaction(SPISettings(1000000UL, MSBFIRST, SPI_MODE0));  //MAX31855 Max SPI speed is 5 Meg
  for (uint8_t i = 0; i < 2; i++)     // read two 16 bit
    {
      _rawData = (_rawData << 16) | mySPI.transfer16(0x00);     // 0x00 is sent to an open pin, MAX31855 does not have an input
    }
  digitalWrite(_CS, HIGH);    // probably not needed and likely needs to be removed if using other SPI
  mySPI.endTransaction();
if (bitRead(_rawData,16)) Typek_Fault = true;
  _rawData = _rawData >> 18; //clear D17..D0 bits
  return (float)_rawData * 0.25;
}


// --- eof ---

Hi John
It seems like an old issue, but I also post it because it is a bit frustrating.
The M0 board is set as follows. “variant.cpp” , This could be found in this file.

sercom0 - Uart Serial
sercom1 - Uart Serial
sercom2 - Uart Serial
sercom3 - I2C Wire
sercom4 - SPI
sercom5 - Serial(EDGB)