Description
Basic Infos
- This issue complies with the issue POLICY doc.
- I have read the documentation at readthedocs and the issue is not addressed there.
- I have tested that the issue is present in current master branch (aka latest git).
- I have searched the issue tracker for a similar issue.
- If there is a stack dump, I have decoded it.
- I have filled out all fields below.
Platform
- Hardware: [ESP-8266-wroom2]
- Core Version: [latest git]
- Development Env: [Arduino IDE]
- Operating System: [Ubuntu]
Settings in IDE
- Module: [Generic ESP8266 Module]
- Flash Size: [2MB]
- lwip Variant: [v2 Lower Memory]
- Reset Method: [ck|nodemcu]
- Flash Frequency: [40Mhz]
- CPU Frequency: [80Mhz]
- Upload Using: [SERIAL]
- Upload Speed: [115200] (serial upload only)
Problem Description
Hi all,
We use 2 esp8266 (one in master and one in slave). We use only the read status command to simplify the setup. Here the Master code. We use the Example SPI Safe Master Demo and modify it to only use the readStatus method.
#include <SPI.h>
class ESPSafeMaster {
private:
uint8_t _ss_pin;
void _pulseSS() {
digitalWrite(_ss_pin, HIGH);
delayMicroseconds(5);
digitalWrite(_ss_pin, LOW);
}
public:
ESPSafeMaster(uint8_t pin): _ss_pin(pin) {}
void begin() {
pinMode(_ss_pin, OUTPUT);
_pulseSS();
}
uint32_t readStatus() {
_pulseSS();
SPI.transfer(0x04);
uint32_t status = (SPI.transfer(0xFF) | ((uint32_t)(SPI.transfer(0xFF)) << 8) | ((uint32_t)(SPI.transfer(0xFF)) << 16) | ((uint32_t)(SPI.transfer(0xFF)) << 24));
_pulseSS();
return status;
}
void writeStatus(uint32_t status) {
_pulseSS();
SPI.transfer(0x01);
SPI.transfer(status & 0xFF);
SPI.transfer((status >> 8) & 0xFF);
SPI.transfer((status >> 16) & 0xFF);
SPI.transfer((status >> 24) & 0xFF);
_pulseSS();
}
void readData(uint8_t * data) {
_pulseSS();
SPI.transfer(0x03);
SPI.transfer(0x00);
for (uint8_t i = 0; i < 32; i++) {
data[i] = SPI.transfer(0);
}
_pulseSS();
}
void writeData(uint8_t * data, size_t len) {
uint8_t i = 0;
_pulseSS();
SPI.transfer(0x02);
SPI.transfer(0x00);
while (len-- && i < 32) {
SPI.transfer(data[i++]);
}
while (i++ < 32) {
SPI.transfer(0);
}
_pulseSS();
}
String readData() {
char data[33];
data[32] = 0;
readData((uint8_t *)data);
return String(data);
}
void writeData(const char * data) {
writeData((uint8_t *)data, strlen(data));
}
};
ESPSafeMaster esp(SS);
void setup() {
Serial.begin(115200);
SPI.begin();
esp.begin();
delay(1000);
}
uint32_t status;
void loop() {
esp.readStatus();
}
On the slave we use this code.
#include <Arduino.h>
#include <SPISlave.h>
#include <ESP8266WiFi.h>
void setup() {
Serial.begin(921600);
Serial.setDebugOutput(true);
WiFi.mode(WIFI_STA);
WiFi.begin("MySSID","MyPassword");
SPISlave.begin();
SPISlave.setStatus(0x55);
}
void loop() {}
//In hspi_slave.c file
void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *arg)
{
uint32_t status;
uint32_t istatus;
USF(0) = 0x01; // To be able to debug it on MSO
istatus = SPIIR;
.......
}
With this configuration, the data of the status is 0x55 (checked with an MSO) and as soon as the WiFi is connected, the data of the status is 0x00 00 00 00 and the next word is 0xFF FF FF 00. No more 0x55 is returned.
From what I seen, the When the behaviour happen, the hspi or the interrupt are disabled for a short period of time and this result in a bad command received (in our case instead of 0x04 we detect 0x01) so the command write status is executed and the status is changed from 0x55 to 0xFF. Here the screen shot of the MSO that represent the problem. Remark that every rising edge of the SPI_CS, an ISR is trigged as we write 0x01 on the UART. When the problem occur, only 1 0x01 is outputed from the serial.
From that picture you can check with the cursor the correct and the missed isr.
Is it possible that the core (Wifi) has interrupt that isr priority is higher than the hspi isr ?
To me it's look like the hspi is not responding to the 0x04 command.
any idea of what can happen ?
Jonathan