Go Down

Topic: Changing SPI speed on the fly (Read 323 times) previous topic - next topic

rmetzner49

Jan 20, 2018, 11:48 pm Last Edit: Jan 20, 2018, 11:50 pm by rmetzner49
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:

Code: [Select]
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.

Code: [Select]
#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?

Code: [Select]
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?


SurferTim


rmetzner49

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.

SurferTim

#3
Jan 21, 2018, 04:49 pm Last Edit: Jan 21, 2018, 04:51 pm by SurferTim
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?
.

rmetzner49

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.

Go Up