Go Down

Topic: SPI in slave mode (Read 406 times) previous topic - next topic



I'm stuck

I have an existing project running on Mega. Using SPI I want send data (from mrk1000) gathered from the internet (and interpreted) to It.

All arduino spi slave examples do not work (they work on uno) because of avr/sand differences.

I found  a sample that kinda works:
But the problem is that "data" is always 0.

My master test code:

Code: [Select]

#include <SPI.h>
const int slaveAPin = 53;

SPISettings settingsWiFi(48000000, MSBFIRST, SPI_MODE0);

void setup() {
  // put your setup code here, to run once:
 // set the Slave Select Pins as outputs:
  pinMode (slaveAPin, OUTPUT);
  // initialize SPI:

uint8_t c=1;
void loop() {
  // put your main code here, to run repeatedly:

    digitalWrite (slaveAPin, LOW);


    SPI.transfer (c);

  digitalWrite (slaveAPin, HIGH);


My slave code:

Code: [Select]

#include <SPI.h>

const int slaveAPin = 10;

void setup() {


  pinMode(slaveAPin, INPUT_PULLUP);

  attachInterrupt(slaveAPin, SERCOM4_Handler, FALLING);



void loop() {
  //waste some time in a loop
  int var = 0;
  while(var < 200){


void spiSlave_init()
  //Configure SERCOM4 SPI PINS 
    //Set PB08 as input (MOSI) - on A1
    //Set PB09 as input (SCK) - on A2
    //Set PB10 as input (SS) - on D23 / MOSI
    //Set PB11 as output (MISO) - on D24 / SCK
  PORT->Group[PORTB].PINCFG[9].bit.PMUXEN = 0x1; //Enable Peripheral Multiplexing for SERCOM4 SPI PB08 Arduino PIN16
  //PORT->Group[g_APinDescription[A2].ulPort].PINCFG[g_APinDescription[A2].ulPin].bit.PMUXEN = 1;
  PORT->Group[PORTB].PMUX[4].bit.PMUXO = 0x3; //SERCOM 4 is selected for peripherial use of this pad (pheripherial D=?3)
  //PORT->Group[g_APinDescription[A2].ulPort].PMUX[g_APinDescription[A2].ulPin >> 1].reg = PORT_PMUX_PMUXO_D;
  PORT->Group[PORTB].PINCFG[10].bit.PMUXEN = 0x1; //Enable Peripheral Multiplexing for SERCOM4 SPI PB10 Arduino PIN23
  PORT->Group[PORTB].PMUX[5].bit.PMUXE = 0x3; //SERCOM 4 is selected for peripherial use of this pad (pheripherial D=?3)
  PORT->Group[PORTB].PINCFG[11].bit.PMUXEN = 0x1; //Enable Peripheral Multiplexing for SERCOM4 SPI PB11 Arduino PIN24
  PORT->Group[PORTB].PMUX[5].bit.PMUXO = 0x3; //SERCOM 4 is selected for peripherial use of this pad (pheripherial D=?3)
  PORT->Group[PORTA].PINCFG[12].bit.PMUXEN = 0x1; //Enable Peripheral Multiplexing for SERCOM4 SPI PA12 Arduino PIN22
  PORT->Group[PORTA].PMUX[6].bit.PMUXE = 0x3; //SERCOM 4 is selected for peripherial use of this pad (pheripherial D=?3)
  //Disable SPI 1
  //Reset SPI 1
  //Setting up NVIC
  //Setting Generic Clock Controller!!!!
            GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is the source
            GCLK_CLKCTRL_CLKEN; // Enable Generic Clock Generator
  while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); //Wait for synchronisation
  //Set up SPI Control A Register
  SERCOM4->SPI.CTRLA.bit.DORD = 0; //MSB first
  SERCOM4->SPI.CTRLA.bit.CPOL = 0; //SCK is low when idle, leading edge is rising edge
  SERCOM4->SPI.CTRLA.bit.CPHA = 0; //data sampled on leading sck edge and changed on a trailing sck edge
  SERCOM4->SPI.CTRLA.bit.FORM = 0x0; //Frame format = SPI
  SERCOM4->SPI.CTRLA.bit.DIPO = 0x2; //DATA PAD2 MOSI is used as input (slave mode)
  SERCOM4->SPI.CTRLA.bit.DOPO = 0; //DATA PAD0 MISO is used as output
  SERCOM4->SPI.CTRLA.bit.MODE = 0x2; //SPI in Slave mode
  SERCOM4->SPI.CTRLA.bit.IBON = 0x1; //Buffer Overflow notification
  SERCOM4->SPI.CTRLA.bit.RUNSTDBY = 1; //wake on receiver complete
  //Set up SPI control B register
  //SERCOM4->SPI.CTRLB.bit.RXEN = 0x1; //Enable Receiver
  SERCOM4->SPI.CTRLB.bit.SSDE = 0x1; //Slave Selecte Detection Enabled
  SERCOM4->SPI.CTRLB.bit.CHSIZE = 0; //character size 8 Bit
  //SERCOM4->SPI.CTRLB.bit.PLOADEN = 0x1; //Enable Preload Data Register
  //while (SERCOM4->SPI.SYNCBUSY.bit.CTRLB); 
  //Set up SPI interrupts
  SERCOM4->SPI.INTENSET.bit.SSL = 0x1; //Enable Slave Select low interrupt       
  SERCOM4->SPI.INTENSET.bit.RXC = 0x1; //Receive complete interrupt
  SERCOM4->SPI.INTENSET.bit.TXC = 0x1; //Receive complete interrupt
  SERCOM4->SPI.INTENSET.bit.ERROR = 0x1; //Receive complete interrupt
  SERCOM4->SPI.INTENSET.bit.DRE = 0x1; //Data Register Empty interrupt
  //init SPI CLK 
  //SERCOM4->SPI.BAUD.reg = SERCOM_FREQ_REF / (2*4000000u)-1;
  //Enable SPI
  SERCOM4->SPI.CTRLB.bit.RXEN = 0x1; //Enable Receiver, this is done here due to errate issue
  while(SERCOM4->SPI.SYNCBUSY.bit.CTRLB); //wait until receiver is enabled


void SERCOM4_Handler()
  Serial.println("In SPI Interrupt");
  uint8_t data = 0;
  data =(uint8_t)SERCOM4->SPI.DATA.reg;
  uint8_t interrupts = SERCOM4->SPI.INTFLAG.reg; //Read SPI interrupt register
  if(interrupts & (1<<3))
    Serial.println("SPI SSL Interupt");
    SERCOM4->SPI.INTFLAG.bit.SSL = 1; //clear slave select interrupt
  if(interrupts & (1<<2))
    Serial.println("SPI Data Received Complete Interrupt");
    data = SERCOM4->SPI.DATA.reg; //Read data register
    Serial.print("DATA: "); Serial.println(data);
    SERCOM4->SPI.INTFLAG.bit.RXC = 1; //clear receive complete interrupt
  if(interrupts & (1<<1))
    Serial.println("SPI Data Transmit Complete Interrupt");
    SERCOM4->SPI.INTFLAG.bit.TXC = 1; //clear receive complete interrupt
  if(interrupts & (1<<0))
    Serial.println("SPI Data Register Empty Interrupt");
    SERCOM4->SPI.DATA.reg = 0xAA;
  Serial.print("DATA: "); Serial.println(data);
  //Serial.print("CTRLA: "); Serial.println(SERCOM4->SPI.CTRLA.reg); 

I get interrupts every 10s (so it is kinda working) but Data is always 0.

Maybe SPI is not the solution ?

Basically I want to replace esp8266 (It was too unstable and died on me). I could use MRK1000 as master but there are lots of other parts that are connected to mega

Go Up