ESP32 SPI To Wifi.clinet

What I want to achieve?

i want use may esp32 to use as a wifi copressor connected with Spi to a STM32F4/F7.

What i get so far?

managed to connect the esp to connect to a wife and open a tcp server and send communication to a client
and to connect the spi in slave with dma

Where is the problem?
the main problem that i got is that the WiFiClient::write(const uint8_t *buf, size_t size) function is blocking (measured with logicanalyzer by pulling a pin high while in write function)

so to work around this i wanted use the spi tranfer done interrupt to write in a ringbuffer while im in the WiFiClient::write(const uint8_t *buf, size_t size) this works for slow sending frame like every 1 second a communacation but when i will send frame after frame the esp crashes.

i added the code as attachments bc to much characters for this Forum

best regards

codeForPost.txt (8.68 KB)

The ESP32 has a built in ring buffer FreeRTOS (Supplemental Features) - ESP32 - — ESP-IDF Programming Guide latest documentation that works quite well.

Interested in seeing the code. Using freeRTOS?

hey ty for ur answer but can i mix the Espressif IDF code into Arduino code looks diffrent?

attached code to the first post

Isnt Arduino using FreeRtos everytime?

I code freeRTOS all the time in the Arduino IDE:

#include <WiFi.h>
#include <PubSubClient.h>
#include "certs.h" // include the connection infor for WiFi and MQTT
#include "sdkconfig.h" // used for log printing
#include "esp_system.h"
#include "freertos/FreeRTOS.h" //freeRTOS items to be used
#include "freertos/task.h"
//#include <Wire.h>
#include <SPI.h> // ada fruity needs this ...
#include <Adafruit_Sensor.h> // and this ...
#include <Adafruit_BME280.h> // to run this library
////
Adafruit_BME280 bme280( GPIO_NUM_5 ); // use hardware SPI, set GPIO pin to use
////
WiFiClient   wifiClient; // do the WiFi instantiation thing
PubSubClient MQTTclient( mqtt_server, mqtt_port, wifiClient ); do the MQTT instantiation thing
////
/*
 * This semaphore is used to stop or prevent a publish from happening during client.loop()
 */
SemaphoreHandle_t sema_MQTT_KeepAlive;
////
// interrupt service routine for WiFi events put into IRAM
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
}
////
void setup()
{
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 20000, NULL, 3, NULL, 1 ); // create and start the two tasks to be used, set those task to use 20K stack
  xTaskCreatePinnedToCore( DoTheBME280Thing, "DoTheBME280Thing", 20000, NULL, 4, NULL, 1);
} //void setup()
//
void DoTheBME280Thing( void *pvParameters )
{
  SPI.begin(); // initialize the SPI library
  bme280.begin(); // begin the BME280 show
  float temperature = 0.0f;
  float pressure    = 0.0f;
  float humidity    = 0.0f;
  //wait for a mqtt connection
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 250 );
  }
  for (;;)
  {
    temperature = ( 1.8f * bme280.readTemperature() ) + 32.0f;
    pressure    = bme280.readPressure() / 133.3223684f; // mmHg
    humidity    = bme280.readHumidity();
    log_i( " temperature %f, Pressure %f, Humidity %f", temperature, pressure, humidity);
    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    if ( MQTTclient.connected() )
    {
      MQTTclient.publish( topicInsideTemp, String(temperature).c_str() );
      vTaskDelay( 2 ); // gives the Raspberry Pi 4 time to receive the message and process
      MQTTclient.publish( topicInsideHumidity, String(humidity).c_str() );
      vTaskDelay( 2 ); // no delay and RPi is still processing previous message
      MQTTclient.publish( topicInsidePressure, String(pressure).c_str() );
    }
    xSemaphoreGive( sema_MQTT_KeepAlive );
    vTaskDelay( 1000 * 15 );
    log_i( "DoTheBME280Thing high watermark %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete ( NULL );
}
////
/*
    Important to not set vTaskDelay to less then 10. Errors begin to develop with the MQTT and network connection.
    makes the initial wifi/mqtt connection and works to keeps those connections open.
*/
void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  // setting must be set before a mqtt connection is made
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status %s WiFi status %s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    vTaskDelay( 250 ); //task runs approx every 250 mS
  }
  vTaskDelete ( NULL );
}
////
void connectToMQTT()
{
  // create client ID from mac address
  byte mac[6];
  WiFi.macAddress(mac);
  log_i( "mac address %d.%d.%d.%d.%d", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]  );
  String clientID = String(mac[0]) + String(mac[5]) ;
  log_i( "connect to mqtt as client %s", clientID );
  while ( !MQTTclient.connected() )
  {
    MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password );
    log_i( "connecting to MQTT" );
    vTaskDelay( 250 );
  }
  log_i("MQTT Connected");
}
//
void connectToWiFi()
{
  log_i( "connect to wifi" );
  while ( WiFi.status() != WL_CONNECTED )
  {
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    log_i(" waiting on wifi connection" );
    vTaskDelay( 4000 );
  }
  log_i( "Connected to WiFi" );
  WiFi.onEvent( WiFiEvent );
}
////
void loop() { }

Works well, lasts a long time.

The Arduino IDE only uses freeRTOS when you program the Arduino IDE to use freeRTOS.

than im not using Freertos.
do you using the spi in slave mode ?
how much data u expecting to get per communicaton from the other side? Im expect up to 258 bytes (i know that it isnt a multiple from 4 so i have to send 2 dummy bytes. the spi intern fifo is just 64 bytes what is to less thats why i decided to use the dma but cant give the dma a buffer and its using it cricular like in stm32 projects

ok found the problem why the Firmware crashes when im sending on SPI i called the function for add new transaction in the last transaction call back function to have everytime a transaction in queue. anyone got a idea when i can call it so its everytime a transaction in queue even when the loop is blockes by wifiClient.write()