Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Correct way to use same SPI pins with different SPI master and Slave libraries? T3.6

  1. #1

    Correct way to use same SPI pins with different SPI master and Slave libraries? T3.6

    Greetings,

    I have a fairly large program that I can build to use the TSPISlave library to operate as an SPI slave. This works fine.

    I can also build the program to use the ILI9341_t3n, and SPIN, libraries using the T3.6 as a SPI master to drive an SPI tft display over the same pins. That too works fine.

    These two functions are never required at the same time, but I now have a use case where it would be useful to have a single build of the code, and switch from one of these uses of the SPI port to the other. Taking a naive approach and simply trying to start the tft display library after using the slave library hangs at tft.begin().

    Is there a generally accepted "correct" way to do stuff like this? Should these libraries have a way of gracefully letting go of the hardware resources? I guess I'll start digging into the libraries and figure it out but I thought I would ask for general guidance.
    Cheers
    Doug

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,490
    Quick FYI - My later versions of ILI9341_t3n no longer needs/uses SPIN library. Decide to excise it from there.

    As for TSPISlave library, I have not tried it. My quick look through the code looks like a bunch of stuff is setup on constructor and I don't see anything like a begin/end.

    That is everything is done at the creation of the object. Maybe the library owner (@tonton81) might have some suggestions.

  3. #3
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,441
    you can't use master and slave on same bus at same time, or switch, well, you can switch but you need to change the whole bus configuration to do so every time. better to use 2 spi busses

    if you still deem it necessary to use a single bus, you need to disable the interrupt of the spi slavr before changing the spi port settings, then rerun spi.begin() before using tft functions, then, copy paste the spi slave setup from source to your sketch and activate the slave through the sketch manually. unfortunately i never added a begin because the constructor was sufficient enough to activate the bus in slave mode

    if the tft lcd talks back on the spi bus, thats bad for slave mode since it may see both devices accessing it

  4. #4
    Quote Originally Posted by tonton81 View Post
    you can't use master and slave on same bus at same time, or switch, well, you can switch but you need to change the whole bus configuration to do so every time. better to use 2 spi busses
    Yeah, I realize that, and the system doesn't ever have a need for using these two modes at close to the same time. This is a piece of hardware that uses the SPI Slave mode for a one-time calibration and then, in some configurations may use SPI master mode for controlling a display. Indeed, the use cases have evolved since the system was designed a few years ago. The goal is to avoid having a change of pinout so that hardware that's deployed with customers isn't now of a different revision than I'm building today.

    For me, it's fine for the system to wake up in SPI slave mode (in case it needs calibration) and then, if necessary, reconfigure the bus if it receives the command that tells it that it's actually got a display hooked onto these pins. Less than elegant, perhaps, but definitely fit-for-purpose.

    cheers
    Doug

  5. #5
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,441
    if the slave is ready though to accept calibration data from another mcu the tft SI/SO lines may interfere in the data process, even if only one of it's line is tri-stated, so data corruption will be creeping your way, unless you decided to shut off the devices before switching to slave mode

  6. #6
    Quote Originally Posted by tonton81 View Post
    if the slave is ready though to accept calibration data from another mcu the tft SI/SO lines may interfere in the data process, even if only one of it's line is tri-stated, so data corruption will be creeping your way, unless you decided to shut off the devices before switching to slave mode
    No, that's not a problem. The use case is quite different. The system header that contains this bus has one cable plugged in for a calibration process, or for use in certain use cases, and a different cable plugged in for use with the display. There really is no hardware problem with the way the bus is used, and I'm just trying to rationalize the software so that it can switch between the different use cases (that happen minutes or hours apart).

  7. #7
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,441
    you should be able to copy the relevant spi bus block in tspislave and run that in your sketch to switch to slave, but just need to run spi.begin after to control the lcd then

  8. #8
    Quote Originally Posted by tonton81 View Post
    you should be able to copy the relevant spi bus block in tspislave and run that in your sketch to switch to slave, but just need to run spi.begin after to control the lcd then
    I'm not in front of the system right now, but I thought I had already done that. I had the system start in SPI Slave mode, as normal, and then attempted to start the LCD SPI system, which resulted in a hang. But, I'll need to look at that again. If that should work fine I'll spend some time on it.

  9. #9
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,441
    be sure spi.begin() runs first before having tft take over

  10. #10
    Quote Originally Posted by tonton81 View Post
    be sure spi.begin() runs first before having tft take over
    ok, I'll check that. Thx

  11. #11
    Quote Originally Posted by DougMcK View Post
    ok, I'll check that. Thx
    Hmm, it looks like more head-scratching is required. Here's a minimal test program that I've been using to look at this. With either SPISLAVE or TFT_DISP defined, things are fine. If both are defined, which is a proxy for the use case I'm interested in, the code hangs on the tft.begin() statement.
    The behavior is the same with or without SPI.begin() or SPI1.begin(). I was hoping that would overwrite the SPISLAVE setup.

    Any pointers? Doug

    Code:
    #define SPISLAVE
    #define TFT_DISP
    
    #include <SPI.h>
    
    #ifdef SPISLAVE
      #include "TSPISlave.h" // for SPI receive on SPI1
      uint8_t SPI1_miso = 1;
      uint8_t SPI1_mosi = 0;
      uint8_t SPI1_sck = 32;
      uint8_t SPI1_cs = 31;
      uint8_t SPI1_spimode = 8;  //8 bit transfers.
      TSPISlave mySPI = TSPISlave(SPI1, SPI1_miso, SPI1_mosi, SPI1_sck, SPI1_cs, SPI1_spimode);
    #endif
    
    #ifdef TFT_DISP
      #include "ILI9341_t3n.h" //display
      #define TFT_DC 6 // 0xe4  was 6 , 31
      #define TFT_CS 31 // 0xe5
      #define TFT_SCK 32 // 0xe2
      #define TFT_MISO 1 // 0xe3
      #define TFT_MOSI 0 // 0xe1
      #define TFT_RESET 7
      //ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RESET, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN1);
      ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RESET, TFT_MOSI, TFT_SCK, TFT_MISO);
    #endif
    
    void setup() {
      Serial.begin(19200);
      delay(100);
      Serial.println("In Setup");
      delay(100);
    #ifdef TFT_DISP
          SPI.begin();
          tft.begin();      
          tft.setRotation(3);   // rotation ranges from 0 to 4
          tft.fillScreen(ILI9341_BLACK);
          tft.setCursor(40, 40);
          tft.setTextColor(ILI9341_YELLOW);
          tft.setTextSize(2);
          tft.println("Hello World!");
    #endif
    }
    
    void loop() {
      delay(1000); Serial.println("Loop");
    }

  12. #12
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,441
    try to disable slave's NVICIRQ before modifying it for master, maybe it's stuck in there when the peripheral transitions and it's not handled

  13. #13
    Quote Originally Posted by tonton81 View Post
    try to disable slave's NVICIRQ before modifying it for master, maybe it's stuck in there when the peripheral transitions and it's not handled
    That seemed to work in my test program. Thx. I shall get back to fiddling around with the real program.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •