-->
Page 1 of 1

ESP-WROOM-02 SPI config not working as Slave

PostPosted: Thu Feb 17, 2022 6:28 am
by bmalbusca
I tried to config the ESP-wroom-02, which have an ESP8266 core, as a SPI slave. But didnĀ“t found much information about SPI configuration besides the technical reference ESP8266. The project have the a arduino nano iot 33 (samd21g18 arm-m0) as Master communicating with Slave ESP8266.
I checked the master sending data and clock, using the logic analyser but the slave does not respond. I also tested to use a arduino uno as slave and worked with a arduino iot SPI Master.

The pins setup:

- On ESP: IO14->SCK, IO12->MISO,IO13->MOSI, IO15->CS

- On Arduino: D12 -> MISO,D13->SCK, D11->MOSI, D10->CS

The Slave code:

the main routine
Code: Select all#include "hspiESP8266.h"
#include <iostream>
using namespace std;

#define MISO 12
#define MOSI 13

extern uint8_t bdata[LENGTH];
char c = 'c';
bdata[0] = (uint8_t)c;
void setup() {
  Serial.begin(115200);
 
  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);

  HSPISlave SPIS;

  attachInterrupt(digitalPinToInterrupt(SYNC), sync_isr, FALLING);
  SPIS.begin();



 
}

void loop() {

  delay(100);
 Serial.println((data[0] << 16));               
}


header file
Code: Select all#include "hspiESP8266.h"


         
volatile bool data_ready = false;   // set by HSPI interrupt handler when data is received
volatile bool new_readings = false; // set by sync pin interrupt when readings are extracted from raw data

CACHE_RAM_ATTR sync_isr();
void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *);



uint8_t bdata[LENGTH];

uint8_t* read_hspi(){

   return bdata;
}


void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *) {
    uint32_t istatus = SPIIR;
    if(istatus & (1 << SPII1)) {      //SPI1 ISR
        uint32_t status = SPI1S;
        SPI1S &= ~(0x3E0);            //disable interrupts
        SPI1S |= SPISSRES;            //reset
        SPI1S &= ~(0x1F);             //clear interrupts
        SPI1S |= (0x3E0);             //enable interrupts

        if(status & SPISWBIS) {
            uint8_t *p = bdata;
            for(int i = 0; i < LENGTH / 4; i++) {
                uint32_t dword = SPI1W(i);
                *p++ = dword;
                *p++ = dword >> 8;
                *p++ = dword >> 16;
                *p++ = dword >> 24;
            }
            data_ready = true;
        }
    } else if(istatus & (1 << SPII0)) { //SPI0 ISR
        SPI0S &= ~(0x3ff);//clear SPI ISR
    } else if(istatus & (1 << SPII2)) {} //I2S ISR
}



void ICACHE_RAM_ATTR sync_isr() {                           // Sync pin interrupt on falling edge
  SPI1S |= SPISSRES;                                        // Reset HSPI slave
  SPI1S &= ~SPISSRES;
  SPI1CMD = SPICMDUSR;                                      // Start HSPI slave
  static bool glitch = false;
  if(data_ready) {                                          // If a data has been received by the HSPI
    data_ready = false;
      
    if( glitch) {                 // reject samples that have been shifted right by noise on the clock line?
      glitch = false;                                       // sample accepted
      new_readings = true;                                  // new raw readings ready
    }
    else
      glitch = true;                                        // only reject one sample
  }
}





//contructor
HSPISlave::HSPISlave(){

}

void HSPISlave::begin(){
   pinMode(SCK, SPECIAL);                  // Both inputs in slave mode
    pinMode(MOSI, SPECIAL);
    SPI1C = 0;                              // SPI_CTRL_REG MSB first, single bit data mode.
    SPI1S = SPISE | SPISBE | SPISCD | 0x3E0;// SPI_SLAVE_REG, set slave mode, WR/RD BUF enable, CMD define, enable interrupts
    SPI1U = SPIUSSE;                        // SPI_USER_REG.  SPI_CK_I_EDGE
    SPI1CLK = 0;                            // SPI_CLOCK_REG
    SPI1U1 = 7 << SPILADDR;                 // SPI_USER1_REG, set address LENGTH to 8 bits
    SPI1U2 = 7 << SPILCOMMAND;              // SPI_USER2_REG, set command LENGTH to 8 bits
    SPI1S1 = (LENGTH * 8 - 1) << SPIS1LBUF; // SPI_SLAVE1_REG, SPI_SLV_BUF_BITLEN = 12 bytes
    SPI1S3 = 0xF1F200F3;                    // SPI_SLAVE3_REG,, Define command 0 to be write buffer, others something doesn't match
    SPI1P = 1 << 19;                        // SPI_PIN_REG, Clock idle high, seems to cause contension on the clock pin if set to idle low.
    ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler, 0);
    ETS_SPI_INTR_ENABLE();

}

void HSPISlave::end(){
       SPI1S |= SPISSRES;
    SPI1CMD = 0;
    pinMode(SCK, INPUT);                  // Return to inputs to avoid glicthing the PZEM-021 during reset
    pinMode(MOSI, INPUT);

}

void HSPISlave::INTreset(){

   SPI1S &= ~(0x3E0);            //disable interrupts
    SPI1S |= SPISSRES;            //reset
    SPI1S &= ~(0x1F);             //clear interrupts
    SPI1S |= (0x3E0);             //enable interrupts

}

void HSPISlave::reset(){

  SPI1S |= SPISSRES;                                        // Reset HSPI slave
  SPI1S &= ~SPISSRES;
  SPI1CMD = SPICMDUSR;                                      // Start HSPI slave
   
}