Changing SPI speed on the fly

I have a fairly ambitious project where I'm using an ESP32's VSPI channel and hope to communicate with THREE SPI devices, all at different speeds. Admittedly, I don't know enough about how well all three vendors' SPI parameters are set in the libraries. If I look at Adafruit's RA8875 Library (working) and I see how it is called, the following code is used:

boolean Adafruit_RA8875::begin(enum RA8875sizes s) {
  _size = s;

    _width = 800;
    _height = 480;

  pinMode(_cs, OUTPUT);
  digitalWrite(_cs, HIGH);
  pinMode(_rst, OUTPUT);
    
  digitalWrite(_rst, LOW);
  delay(100);
  digitalWrite(_rst, HIGH);
  delay(100);
 // REM CHANGED FROM 2000000 
  spi_speed = 4000000;  //  4MHZ IS ALL SHE WROTE!! (Theoretical is 3.333)
  SPI.begin();

Then further along, Transaction Support actually USES spi_speed.

#ifdef SPI_HAS_TRANSACTION
    static inline void spi_begin(void) __attribute__((always_inline));
    static inline void spi_begin(void) {
        // max speed!
        SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0));
    }
    static inline void spi_end(void) __attribute__((always_inline));
    static inline void spi_end(void) {
        SPI.endTransaction();
    }
#else
    #define spi_begin()
    #define spi_end()
#endif

All appearances are changing SPI speed works as it should. Yay for Adafruit!

So my fundamental question is; If this code MAKES an SPI object at 4MHz, can I just ask it to go slower and where is the best place to do that? In the case of Rob Tilaart's PCF8574 Library, it doesn't use transactions from what I can tell. Do we believe that merely setting the SPI speed before accessing the PCF8574 will produce a slower Read and Write? Then obviously it has to be reset again when hitting the display. Or do I have to re-initialize the entire object?

PCF8574::PCF8574(int address) 
{
  _address = address;
  spi_speed=100000;                 //  ?????  PCF8574 is slower than Display  ??????
  Wire.begin();
}

uint8_t PCF8574::read8()
{
  Wire.beginTransmission(_address);
  Wire.requestFrom(_address, 1);

Has anyone else had similar experience?

https://www.arduino.cc/en/Reference/SPISettings

If you just want to change the speed on the fly, then use this
https://www.arduino.cc/en/Reference/SPISetClockDivider

Thanks, I think that will get me on my way. I guess the right order then is to set the display up first at 4MHz and then without issuing an "EndTransaction" slow it down to access the PCF8574. Because if I understand correctly, the EndTransaction detaches the MOSI,MISO, and SCLK pins.

The MISO pin is "detached" on the client (PCF8574) when the SS pin for that device goes HIGH. Ensure the SS pin is HIGH when you change the speed, or any other setting on the SPI bus.

Why are you not using the SPISettings function when calling SPI.beginTransaction? .

I apologize ... I mixed up the PCF8574 with the TDI1000. The 8574 is I2C so obviously doesn't care about transaction support.

With regard to the TDC1000, I've had to massage the example code I found significantly so I believe I can incorporate Transaction Support.

Since the original code was written around TI's TDC7200 Stopwatch Chip commanding the TDC1000, I had to massage a LOT of code to make it work in Arduino and the ESP32. There appears also to be TI's MP430 doing some work but none of the graphics display for the PC that this does is needed. So I'm going forward since I believe I can measure Time-Of-Flight with the ESP32. The whole purpose of this exercise is to tell when a liquid has air bubbles in the fluid and also if the fluid is the correct type, so I may not even need to measure it but simply run an internal comparator.

You've helped me a lot getting my head around this. Thanks again.

Hello rmetzner49,

Did you ever get this project working? I am working on a project very similar to yours. I had a customized pcb board made with the TDC1000 and am trying to use SPI communication with an esp32 to monitor the TOF value but I don’t know where to start with the coding for the esp32.

Thanks

I sort of gave up on the TDC1000 and switched to the MAX35101. Sadly, I never got that fully working either even though I bought their EVAL board. I strongly believe the results you get with Ultrasonic Monitoring is directly tied to the transducers. Crappy transducers, crappy results.

As for the coding, I simply made an object out of the MAX35101 and coded functions I thought I needed to query the chip. Sadly my motivation for the project died with my son.

Regards,

Bob Metzner