Skip to content

Hspi in slave mode miss interrupt when WIFI is enabled #5921

Open
@dumarjo

Description

@dumarjo

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.

scope_124

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedHelp needed from the community

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions