Utilisation objet SPI MCP23S08 + objet SPI TFT_ESPI + objet SPI DAB . MCP23S08 perd la connection SPI après initialisation ?

Bonjour,

Je réalise en ce moment une Radio DAB + WEB radio + MP3 reader le tout sur le même PCB que j'ai réalisé avec KICAD8.0x. le soft DAB est basé sur le projet https://www.pe5pvb.nl/. il m'a fallu adapté ce soft à mon nouveau PCB à base de ESP32-S3. Vu le nombre de fonctions j'ai du ajouté un IO expander SPI MCP23S08 . le soft comporte 3 objets SPI un TFT 320*240

j'ai initialisé le MCP23S08 avec la fonction ci-dessous et en mode run

 #include "Adafruit_MCP23X08.h"

// dans le setup
MCP23S08_Start(CS_MCP23S08,IRQ_MCP23S08); // init SPI and  pin mode of the IO


void MCP23S08_Start(byte CS,byte IRQ)
{
    pinMode(IRQ, INPUT_PULLUP );  // ESP32-S3 pin
    pinMode(CS, OUTPUT );  // ESP32-S3 pin

    mcp.begin_SPI(CS, SCK_SPI, MISO,MOSI, 0);

    mcp.pinMode(0,INPUT); // MCP23S08
    mcp.pinMode(1,INPUT); // MCP23S08
    mcp.pinMode(2,INPUT); // MCP23S08
    mcp.pinMode(3,INPUT); // MCP23S08
    mcp.pinMode(4,INPUT); // MCP23S08
    mcp.pinMode(5,INPUT); // MCP23S08
    mcp.pinMode(6,INPUT); // MCP23S08
    mcp.pinMode(7,INPUT); // MCP23S08
   // mcp.pinMode8(PORTA ,INPUT); MPC23S17
    mcp.setupInterrupts(true, false, LOW);

    mcp.setupInterruptPin(ROTARY_PIN_B, CHANGE);// enable interrupt on encoder_pin b
    mcp.setupInterruptPin(ROTARY_PIN_2B, CHANGE);// enable interrupt on encoder_pin 2b
    mcp.setupInterruptPin(ROTARY_PIN_2A, CHANGE);// enable interrupt on encoder_pin 2a
    mcp.setupInterruptPin(ROTARY_PIN_A, CHANGE);// enable interrupt on encoder_pin a

    attachInterrupt(digitalPinToInterrupt(IRQ), check_encoder, LOW);

    Serial.println(" MCP23S08 is initialised in SPI and OK");
   
}

void check_encoder(void)
{
  if (rotarytemp = mcp.digitalRead(ROTARY_PIN_A) != savedrotary1A) {read_encoder; savedrotary1A = rotarytemp; } 
  if (rotarytemp = mcp.digitalRead(ROTARY_PIN_B) != savedrotary1B) {read_encoder; savedrotary1B = rotarytemp;}
  if (rotarytemp = mcp.digitalRead(ROTARY_PIN_2A) != savedrotary2A) {read_encoder2; savedrotary2A = rotarytemp;}
  if (rotarytemp = mcp.digitalRead(ROTARY_PIN_2B) != savedrotary2B) {read_encoder2; savedrotary2B = rotarytemp;}
}

au début du soft dans le setup j'ai aussitôt ajouté ceci pour tester le MCP après son initialisation

Serial.print ("MODEBUTTON = ");
  Serial.println (mcp.digitalRead(MODEBUTTON));
  Serial.print ("ROTARY_PIN_B = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_B));
  Serial.print ("ROTARY_BUTTON2 = ");
  Serial.println (mcp.digitalRead(ROTARY_BUTTON2));
  Serial.print ("ROTARY_PIN_2B = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_2B));
  Serial.print ("ROTARY_PIN_2A =");
  Serial.println (mcp.digitalRead(ROTARY_PIN_2A));
  Serial.print ("ROTARY_BUTTON = ");
  Serial.println (mcp.digitalRead(ROTARY_BUTTON));
  Serial.print ("SLBUTTON = ");
  Serial.println (mcp.digitalRead(SLBUTTON));
  Serial.print ("ROTARY_PIN_A = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_A));

le résultat est correct et je connais bien l'état des boutons. la liaison SPI fonctionne correctement sur mon analyseur logique. je vois bien le CS qui descend et les SCK, MOSI et MISO sont bien actifs

ensuite j'ai initialisé le TFT avec la librairie

Serial.println ( "tft.init()");
  tft.init();

/***************************************************************************************
** Function name:           init (tc is tab colour for ST7735 displays only)
** Description:             Reset, then initialise the TFT display registers
***************************************************************************************/
void TFT_eSPI::init(uint8_t tc)
{
  if (_booted)
  {
    initBus();

#if !defined (ESP32) && !defined(TFT_PARALLEL_8_BIT) && !defined(ARDUINO_ARCH_RP2040) && !defined (ARDUINO_ARCH_MBED)
  // Legacy bitmasks for GPIO
  #if defined (TFT_CS) && (TFT_CS >= 0)
    cspinmask = (uint32_t) digitalPinToBitMask(TFT_CS);
  #endif

  #if defined (TFT_DC) && (TFT_DC >= 0)
    dcpinmask = (uint32_t) digitalPinToBitMask(TFT_DC);
  #endif

  #if defined (TFT_WR) && (TFT_WR >= 0)
    wrpinmask = (uint32_t) digitalPinToBitMask(TFT_WR);
  #endif

  #if defined (TFT_SCLK) && (TFT_SCLK >= 0)
    sclkpinmask = (uint32_t) digitalPinToBitMask(TFT_SCLK);
  #endif

  #if defined (TFT_SPI_OVERLAP) && defined (ARDUINO_ARCH_ESP8266)
    // Overlap mode SD0=MISO, SD1=MOSI, CLK=SCLK must use D3 as CS
    //    pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss);
    //spi.pins(        6,          7,           8,          0);
    spi.pins(6, 7, 8, 0);
  #endif

  spi.begin(); // This will set HMISO to input

#else
  #if !defined(TFT_PARALLEL_8_BIT) && !defined(RP2040_PIO_INTERFACE)
    #if defined (TFT_MOSI) && !defined (TFT_SPI_OVERLAP) && !defined(ARDUINO_ARCH_RP2040) && !defined (ARDUINO_ARCH_MBED)
      spi.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1); // This will set MISO to input

    #else
      spi.begin(); // This will set MISO to input
    #endif
  #endif
#endif
    lockTransaction = false;
    inTransaction = false;
    locked = true;

    INIT_TFT_DATA_BUS;


#if defined (TFT_CS) && !defined(RP2040_PIO_INTERFACE)
  // Set to output once again in case MISO is used for CS
  if (TFT_CS >= 0) {
    pinMode(TFT_CS, OUTPUT);
    digitalWrite(TFT_CS, HIGH); // Chip select high (inactive)
  }
#elif defined (ARDUINO_ARCH_ESP8266) && !defined (TFT_PARALLEL_8_BIT) && !defined (RP2040_PIO_SPI)
  spi.setHwCs(1); // Use hardware SS toggling
#endif


  // Set to output once again in case MISO is used for DC
#if defined (TFT_DC) && !defined(RP2040_PIO_INTERFACE)
  if (TFT_DC >= 0) {
    pinMode(TFT_DC, OUTPUT);
    digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode
  }
#endif

    _booted = false;
    end_tft_write();

  } // end of: if just _booted

  // Toggle RST low to reset
#ifdef TFT_RST
  #if !defined(RP2040_PIO_INTERFACE)
    // Set to output once again in case MISO is used for TFT_RST
    if (TFT_RST >= 0) {
      pinMode(TFT_RST, OUTPUT);
    }
  #endif
  if (TFT_RST >= 0) {
    writecommand(0x00); // Put SPI bus in known state for TFT with CS tied low
    digitalWrite(TFT_RST, HIGH);
    delay(5);
    digitalWrite(TFT_RST, LOW);
    delay(20);
    digitalWrite(TFT_RST, HIGH);

  }
            
  else writecommand(TFT_SWRST); // Software reset
#else
  writecommand(TFT_SWRST); // Software reset
#endif

  delay(150); // Wait for reset to complete
  begin_tft_write();
  tc = tc; // Suppress warning

  // This loads the driver specific initialisation code  <<<<<<<<<<<<<<<<<<<<< ADD NEW DRIVERS TO THE LIST HERE <<<<<<<<<<<<<<<<<<<<<<<
#if   defined (ILI9341_DRIVER) || defined(ILI9341_2_DRIVER) || defined (ILI9342_DRIVER)
    #include "TFT_Drivers/ILI9341_Init.h"

#elif defined (ST7735_DRIVER)
    tabcolor = tc;
    #include "TFT_Drivers/ST7735_Init.h"

#elif defined (ILI9163_DRIVER)
    #include "TFT_Drivers/ILI9163_Init.h"

#elif defined (S6D02A1_DRIVER)
    #include "TFT_Drivers/S6D02A1_Init.h"

#elif defined (ST7796_DRIVER)
    #include "TFT_Drivers/ST7796_Init.h"

#elif defined (ILI9486_DRIVER)
    #include "TFT_Drivers/ILI9486_Init.h"

#elif defined (ILI9481_DRIVER)
    #include "TFT_Drivers/ILI9481_Init.h"

#elif defined (ILI9488_DRIVER)
    #include "TFT_Drivers/ILI9488_Init.h"

#elif defined (HX8357D_DRIVER)
    #include "TFT_Drivers/HX8357D_Init.h"

#elif defined (ST7789_DRIVER)
    #include "TFT_Drivers/ST7789_Init.h"

#elif defined (R61581_DRIVER)
    #include "TFT_Drivers/R61581_Init.h"

#elif defined (RM68140_DRIVER)
	#include "TFT_Drivers/RM68140_Init.h"

#elif defined (ST7789_2_DRIVER)
    #include "TFT_Drivers/ST7789_2_Init.h"

#elif defined (SSD1351_DRIVER)
    #include "TFT_Drivers/SSD1351_Init.h"

#elif defined (SSD1963_DRIVER)
    #include "TFT_Drivers/SSD1963_Init.h"

#elif defined (GC9A01_DRIVER)
     #include "TFT_Drivers/GC9A01_Init.h"

#elif defined (ILI9225_DRIVER)
     #include "TFT_Drivers/ILI9225_Init.h"

#elif defined (RM68120_DRIVER)
     #include "TFT_Drivers/RM68120_Init.h"

#elif defined (HX8357B_DRIVER)
    #include "TFT_Drivers/HX8357B_Init.h"

#elif defined (HX8357C_DRIVER)
    #include "TFT_Drivers/HX8357C_Init.h"

#endif

#ifdef TFT_INVERSION_ON
  writecommand(TFT_INVON);
#endif

#ifdef TFT_INVERSION_OFF
  writecommand(TFT_INVOFF);
#endif


  end_tft_write();
  setRotation(rotation);
#if defined (TFT_BL) && defined (TFT_BACKLIGHT_ON)
  if (TFT_BL >= 0) {
    pinMode(TFT_BL, OUTPUT);
    digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
  }
#else
  #if defined (TFT_BL) && defined (M5STACK)
    // Turn on the back-light LED
    if (TFT_BL >= 0) {
      pinMode(TFT_BL, OUTPUT);
      digitalWrite(TFT_BL, HIGH);
    }
  #endif
#endif
}

le TFT s'initialise correctement et affiche le Logo de la DABradio

je rajoute de nouveau le même test des boutons après l'initialisation du TFT et maintenant le résultat est mauvais.
la liaison SPI n'ai plus active sur mon analyseur logique. je vois bien le CS qui descend et les SCK, MOSI et MISO restent désespérément à 1 pas de SCK ...

Serial.print ("MODEBUTTON = ");
  Serial.println (mcp.digitalRead(MODEBUTTON));
  Serial.print ("ROTARY_PIN_B = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_B));
  Serial.print ("ROTARY_BUTTON2 = ");
  Serial.println (mcp.digitalRead(ROTARY_BUTTON2));
  Serial.print ("ROTARY_PIN_2B = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_2B));
  Serial.print ("ROTARY_PIN_2A =");
  Serial.println (mcp.digitalRead(ROTARY_PIN_2A));
  Serial.print ("ROTARY_BUTTON = ");
  Serial.println (mcp.digitalRead(ROTARY_BUTTON));
  Serial.print ("SLBUTTON = ");
  Serial.println (mcp.digitalRead(SLBUTTON));
  Serial.print ("ROTARY_PIN_A = ");
  Serial.println (mcp.digitalRead(ROTARY_PIN_A));

j'obtiens la même chose si je fais ce test en activant le DAB à la place du TFT.

Si vous avez des idées je suis très intéressé car cela fait plusieurs jours que je suis bloqué sur ce point.

Merci.
Joël14600

Tout le code n'est pas là mais je pense que l'init spi que tu fais dans le setup est modifié par tft. Il n'y a pas de retour possible dans le setup. Si ce n'est pas cela c'est au moins une piste

Bonjour,

finalement, J'ai trouvé la solution. j'ai remplacé la bibliothèque ADAFRUIT MCP23S17 par la bibliothèque MCP23S08 de Rob Tillard et j'ai ensuite créé un nouvel objet SPI pour le MCP23S08

SPIClass MCP23S08_SPI;
MCP23S08 mcp(CS_MCP23S08, ADR_MCP23S08 , &MCP23S08_SPI);


void MCP23S08_Start(byte CS,byte IRQ)
{
    pinMode(IRQ, INPUT_PULLUP );  // ESP32-S3 pin
    pinMode(CS, OUTPUT );  // ESP32-S3 pin
    digitalWrite(CS, HIGH );  // ESP32-S3 pin
    MCP23S08_SPI.begin(SCK_SPI,MISO,MOSI,CS_MCP23S08);

    mcp.begin(1);
    mcp.pinMode1(0,INPUT); // MCP23S08
    mcp.pinMode1(1,INPUT); // MCP23S08
    mcp.pinMode1(2,INPUT); // MCP23S08
    mcp.pinMode1(3,INPUT); // MCP23S08
    mcp.pinMode1(4,INPUT); // MCP23S08
    mcp.pinMode1(5,INPUT); // MCP23S08
    mcp.pinMode1(6,INPUT); // MCP23S08
    mcp.pinMode1(7,INPUT); // MCP23S08
   
    mcp.setInterruptPolarity(LOW);

    mcp.enableInterrupt(ROTARY_PIN_B, CHANGE);// enable interrupt on encoder_pin b
    mcp.enableInterrupt(ROTARY_PIN_2B, CHANGE);// enable interrupt on encoder_pin 2b
    mcp.enableInterrupt(ROTARY_PIN_2A, CHANGE);// enable interrupt on encoder_pin 2a
    mcp.enableInterrupt(ROTARY_PIN_A, CHANGE);// enable interrupt on encoder_pin a

    attachInterrupt(digitalPinToInterrupt(IRQ), interrup_IRQ_MCP23S08, CHANGE);
    Serial.println(" MCP23S08 is initialised in SPI and OK");
   
}

Voilà et tout est entré dans l'ordre.

Cordialement. Joel14600

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.