ESP-WROOM-02 SPI config not working as Slave
Posted: Thu Feb 17, 2022 6:28 am
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
header file
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
}