ESP8266 SPI hardware trop lent

Bonjour à tous,
Cela fait plusieurs jours que je bute sur un problème avec la librairie SPI fournie avec la plateforme ESP8266 sur IDE Arduino. Mon problème est que ma vitesse de transfer SPI est bien plus basse que prévue.

Ma vitesse d'horloge est de 40 MHz, il faut 8 coups d'horloge pour envoyer 8 bits. Le calcul donne 0.2 µs pour envoyer un octet. Or, mon programme me donne 4.25 µs.

J'ai beau chercher, je ne n'arrive pas à trouver ce qui se passe. Si quelqu'un a une idée?

#include <SPI.h>
#define s 15
#define SL (GPOC=(1<<15))
#define SH (GPOS=(1<<15))
uint8_t a;uint r=0;
void setup() {
  Serial.begin(115200);Serial.println("");
  pinMode(15, OUTPUT);
  SPI.begin();
  SPI.setFrequency(40000000L);
  r=micros();

  SL;
  SPI.write(1);
  SH;

  SL;
  SPI.write(2);
  SH;

  SL;
  SPI.write(1);
  SH;

  SL;
  SPI.write(2);
  SH;

  SL;
  SPI.write(1);
  SH;

  SL;
  SPI.write(2);
  SH;

  SL;
  SPI.write(1);
  SH;

  SL;
  SPI.write(255);
  SH;

  Serial.printf("Durée:%0.8f microsecondes pour transmettre 1 octets\n",(micros()-r)/8.0);
}

void loop() {

}

Bonjour,
il serait intéressant de mesurer chaque groupe

SL;
  SPI.write(255);
  SH;

SL et SH doivent s'exécuter en plusieurs coup d'horloge.

Il faudrait aussi faire le calcule de durée avant le sérial print

durée= (micros()-r)/8.0

Merci Leptro de m'avoir répondu.

J'ai réduit le source et mosifié comme demandé.
Résultat: 20 µs
Résultat en mettant SPI.transfer(1); en commentaire: 5 µs

Donc pour SPI.write seul: 15µs

Je trouve tout cela bien lent pour un micro qui tourne à 80 MHz et pour tout dire assez déçu. Je voulais utiliser le spi avec un 74HC595 pour commander un display 3.5" TFT 8080-8 parallèle. Ca marche mais horriblement lent par rapport à une solution basée sur l'utilisation de trois 74HC173 montés en expanseur de GPIO (bus 4 bit en entrée, bus 8 bit en sortie + 3 sorties pour WR, CS et RS.

Nota:
Finalement, avec un spi à 80MHz, une horloge CPU à 160 MHz, en modifiant le type de carte dans le menu Outils j'arrive à descendre à 10 µs sans arriver aux résultat antérieur de 5 µs. Tout ça parce que entre temps, j'ai essayé d'installer le compilateur ESP32 dans mon Arduino.
Je commence à avoir des doutes sur cet environnement.

#include <SPI.h>

#define SL (GPOC=(1<<15))
#define SH (GPOS=(1<<15))

int start=0, fin=0;

void setup() {
  Serial.begin(115200);Serial.println("");
  pinMode(15, OUTPUT);
  
  SPI.begin();
  SPI.setFrequency(40000000);
  
  start=micros();
  
  SL;
   SPI.transfer(1);
  SH;

  fin=micros();

Serial.print("Durée en microsecondes: "); Serial.println(fin-start);
  
}

void loop() {

}

SPI.setFrequency(40000000);

Bonjour,
tu es peut-être un peu gourmand là
qu'est-ce que ça donne avec des fréquences raisonnables, genre 1000000 Hz ?

Dans un circuit espressif (en fait un micro "à terminer" de la société Xtensa) tout ne fonctionne pas à la fréquence horloge.
Un micro Xtensa n'est pas un ARM mais comme les ARM il y a "plusieurs branches" d'horloge.
Certaines branches sont pilotées avec une horloge divisée par 2 ou plus.
Il faudrait trouver dans la documentation du micro la valeur de l'horloge qui pilote le SPI, sachant que la fréquence max du SPI sera cette horloge divisée par 2.

En fait, après plein d'essais, je me suis rendu compte que GPOC=(1<<15) ne fonctionne pas correctement. Cette instruction qui est sensée accéder directement aux registres gpio et aller beaucoup plus vite que digitalWrite(15,LOW) est encore plus lente que cette dernière. Il en est de même pour GPOS=(1<<15) et digitalWrite(15,HIGH).

Dans le code ci-dessous, si on utilise SL et SH, on obtient 5 µs et si on utilise digitalWite(15,LOW) et digitalWrite(15,HIGH) on obtient 2 µs.

Noter qu'ici, on n'utilise pas le spi et micros() utilise 1 microseconde.

De toute façon, on devrait dans tous les cas obtenir des temps inférieurs à la microseconde ce qui est loin d'être le cas.

J'ai trouvé un blogeur qui a fait des essais: Vitesse IO sur module ESP8266 – Microclub
Le temps obtenu est de 175 ns. Alors, je me dis que c'est peut-être mon nodemcu-esp12 qui a un problème?

#define SL (GPOC=(1<<15))
#define SH (GPOS=(1<<15))

uint32_t start=0, fin=0;

void setup() {
  Serial.begin(115200);Serial.println("");
  pinMode(15, OUTPUT);
  
  SPI.begin();
  SPI.setFrequency(40000000);
  int off1=micros();
  int off2=micros();
  int duree=off2-off1;
  Serial.printf("\temps mort=%d\n",duree);
  yield();

  start=micros();
  SL;
  //digitalWrite(15,0);
  //GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << 15);
  //SPI.write(1);
  //GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << 15);
  SH;
  //digitalWrite(15,1);
  fin=micros();

Serial.print("Durée en microsecondes: "); Serial.println(fin-start);
}

void loop() {
}

J'ai trouvé un blogeur qui a fait des essais: Vitesse IO sur module ESP8266 – Microclub

J'ai un problème de base avec ton "expert blogeur" et un GROS.
Il dit que les micro Espressif sont des ARM c'est totalement faux et j'ai souvent lu cette connerie.

ARM c'est bien particulier et ce n'est pas parce qu'un micro est 32 bits que c'est un ARM.

Espressif ne développe pas de microcontrôleur, il utilise des microcontrôleur Xtensa qui sont des microcontrôleurs que le client "peut terminer" avec ses propres fonctions.
C'est une procédure assez courante pour les petites sociétés qui n'ont pas les moyens de développer un microcontrôleur de A à Z.

Espressif achète de la propriété intellectuelle : les points d'entrée de la techno Xtensa, simule ses extensions (Wifi, Bluetooth, etc), transmet les fichiers à Xtensa qui ajoute les extensions au cœur du microcontrôleur et fabrique la puce.

Le seul point de vrai est que : comme dans les ARM les différents sous ensembles du microcontrôleur (dont le SPI) fonctionnent à des vitesse d'horloge différentes (plus basses) de celles du cœur du microcontrôleur.

Bon d'accord, il se trompe en pensant que le coeur du ESP8266 est un ARM. Mais faut-il jeter le bb avec l'eau du bain. Ce mec s'est quand même cassé le tronc pour mettre en ligne le résultat des essais qu'il a menés avec son analyseur.

Je ne comprends pas pourquoi, je n'arrive pas aux mêmes résultats. Pourtant je suis à fond partout. Ma fréquence cpu est overclockée à 160 MHz, ma fréquence SPI à 80 Mhz, j'utilise un accès direct aux registres gpio. Ya un loup qq part c'est sûr mais je n'ai pa trouvé.

En tout cas, un merci chaleureux à ceux qui on bien voulu se pencher sur mon cas.

Nota:
Pour info, j'ai réalisé un driver pour afficheur 3.5 pouces tft 320x480 avec une interface basé sur 3 x 74HC173 (san spi donc) et le même driver piloté à partir d'une interface à base d'un 74HC595. Résultat des course pour le test d'un un fillScreen (remplissage de l'écran en couleur CYAN):

74HC595: 580 millisecondes
74HC173: 180 millisecondes.

La messe est dite.. L'interface parallèle sur 4 bit est 3.15 fois plus rapide que l'interface spi.