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

Thread: Dual SPI Advice

  1. #1
    Junior Member
    Join Date
    Aug 2019
    Posts
    2

    Dual SPI Advice

    Searched around and couldn't find conclusive information regarding a detail when using two SPI devices.

    Read about the better implementation (https://www.pjrc.com/better-spi-bus-design-in-3-steps/) and a question came to mind:

    Is there an advantage in using two separate SPI ports in comparison to two devices on the same port (implemented correctly in software)?

    Reason for asking the question:
    Built a T3.6 remote using a 240x240pixel SPI display and an SPI transceiver.

    Will switch to T4 and the second SPI port is on the bottom pads.
    I would like to avoid soldering a ribbon cable if dual SPI on the same port has no hardware disadvantage.

    Appreciate any info or experience related.

    Thanks!

  2. #2
    Senior Member
    Join Date
    Apr 2017
    Posts
    230
    I use a Teensy 3.2 and I use dual SDI devices all the time 1) an ILI9341 display and 2) and SD card. Both are on the same SPI lines but different CS of course. Works fine in my data logging application.

    I have recently experimented with dual ILI9341 displays on the same line (different DC and CS). I'm using the lib ILI9341_t3 and dual displays work but you are limited as to what CS pins can be used. I hear this lib is optimized and requires only certian pins for CS. I was not able to write different stuff to each display but had some weird update issue (1 display could not be updated 2x more frequent than the other) but I only spend a few hours messing with it.

    I've never used completely different SPI busses for multiple devices.

  3. #3
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,668
    Quote Originally Posted by zander View Post
    Searched around and couldn't find conclusive information regarding a detail when using two SPI devices.

    Read about the better implementation (https://www.pjrc.com/better-spi-bus-design-in-3-steps/) and a question came to mind:

    Is there an advantage in using two separate SPI ports in comparison to two devices on the same port (implemented correctly in software)?

    Reason for asking the question:
    Built a T3.6 remote using a 240x240pixel SPI display and an SPI transceiver.

    Will switch to T4 and the second SPI port is on the bottom pads.
    I would like to avoid soldering a ribbon cable if dual SPI on the same port has no hardware disadvantage.

    Appreciate any info or experience related.

    Thanks!
    It depends on how optimized the drivers are and whether the devices do things like tri-state MISO properly.

    Assuming you have done all things in the quoted document (pull-up resistors on the CS pins, verified the device tri-states MISO, and verified that the driver uses SPI.beginTranasaction and SPI.endTransaction), if the drivers are dumb, then it may not matter if if you have one SPI device or two. I suspect it will do one device and then another.

    However, if you have the proper driver with the appropriate magic, then it will speed things up, because the driver queues things up to do transfers in the background (using DMA) while it is free to do other things.

    Note, while I am familiar with things at a high level, for details you want the experts (KurtE, mjs513, defragster, and of course Paul S.).

    The 3.x world seems to be very different from the 4.0 world.

    In the 3.x world you could have 5 high speed options, spread over 9 pins. Note, some pins internally used the same ports, so you could use on or the other pin with high speed SPI, but not both. The pins are:


    Note, if your device uses a D/C pin, that must also come the list of fast pins.

    One of the canonical programs that does use dual SPI is uncannyEyes, which draws eyes on two 128x128 displays as fast as it can. In uncannyEyes, you need 3 fast pins (one for the CS for each display, and the third for the shared D/C pin). In my current configuration, I tend to use pins 23/22 as the two CS pins and 15 as the D/C pin, but I may be changing this to use a more standard CS pins 10/9.


    The author of uncannyEyes has been working on newer versions that target other microprocessors (Rasberry Pi, and the Adafruit Monster M4SK which uses an ARM Cortex M4). IIRC, in the Teensy version, he does one display, waits until it is finished and then does the other display. In the newer version that uses 240x240 displays instead of 128x128 displays (i.e. 4 times the data), I believe he does both SPI streams in parallel (using 2 SPI ports). If that is ever ported back to the Teensy 3.5/3.6, it would likely then need separate D/C pins for each display.

    While the Teensy 3.5/3.6 have multiple SPI buses, I think the other SPI buses are limited to a single fast pin. This doesn't help if you need both CS and D/C pins to be fast pins.

    Teensy 4.0 is a lot more complicated. The SPI internals changed, and also the memory caching behavior is causing some issues. My sense is for ultimate speed, you will devices on separate SPI buses. In addition to the pins meant to be soldered with a ribbon cable to connect to a SD drive (SPI3), there is a second SPI bus on the Teensy 4.0. You would need to solder two wires (or use a breakout shield) to pads #26 and 27 and use pins 0/1 to use SPI2. These pads are at standard 0.1" (2.54mm) spacing and should easier to solder than the SPI3 pins (1mm).

    You might want to read this thread:


    But the discussion has sprawled out to other high volume threads:


    Quote Originally Posted by KrisKasprzak View Post
    I use a Teensy 3.2 and I use dual SDI devices all the time 1) an ILI9341 display and 2) and SD card. Both are on the same SPI lines but different CS of course. Works fine in my data logging application.

    I have recently experimented with dual ILI9341 displays on the same line (different DC and CS). I'm using the lib ILI9341_t3 and dual displays work but you are limited as to what CS pins can be used. I hear this lib is optimized and requires only certian pins for CS. I was not able to write different stuff to each display but had some weird update issue (1 display could not be updated 2x more frequent than the other) but I only spend a few hours messing with it.

    I've never used completely different SPI busses for multiple devices.
    Do you have pull-up resistors for the CS and D/C pins? Somebody else had a similar issue and pull-up resistors helped. For me, I was having screen corruption, and adding 2.2K pull-up resistors allowed me to raise the SPI bus speed when I was talking to two different displays. A pull-up resistor would be a resistor that goes between the pin and 3.3v in parallel to the normal wire. I've used 2.2K pull-up resistors, which I also use for i2c buses.

  4. #4
    Junior Member
    Join Date
    Aug 2019
    Posts
    2
    Quote Originally Posted by MichaelMeissner View Post
    It depends on how optimized the drivers are and whether the devices do things like tri-state MISO properly.

    Assuming you have done all things in the quoted document (pull-up resistors on the CS pins, verified the device tri-states MISO, and verified that the driver uses SPI.beginTranasaction and SPI.endTransaction), if the drivers are dumb, then it may not matter if if you have one SPI device or two. I suspect it will do one device and then another.

    However, if you have the proper driver with the appropriate magic, then it will speed things up, because the driver queues things up to do transfers in the background (using DMA) while it is free to do other things.

    Note, while I am familiar with things at a high level, for details you want the experts (KurtE, mjs513, defragster, and of course Paul S.).

    The 3.x world seems to be very different from the 4.0 world.

    In the 3.x world you could have 5 high speed options, spread over 9 pins. Note, some pins internally used the same ports, so you could use on or the other pin with high speed SPI, but not both. The pins are:


    Note, if your device uses a D/C pin, that must also come the list of fast pins.

    One of the canonical programs that does use dual SPI is uncannyEyes, which draws eyes on two 128x128 displays as fast as it can. In uncannyEyes, you need 3 fast pins (one for the CS for each display, and the third for the shared D/C pin). In my current configuration, I tend to use pins 23/22 as the two CS pins and 15 as the D/C pin, but I may be changing this to use a more standard CS pins 10/9.


    The author of uncannyEyes has been working on newer versions that target other microprocessors (Rasberry Pi, and the Adafruit Monster M4SK which uses an ARM Cortex M4). IIRC, in the Teensy version, he does one display, waits until it is finished and then does the other display. In the newer version that uses 240x240 displays instead of 128x128 displays (i.e. 4 times the data), I believe he does both SPI streams in parallel (using 2 SPI ports). If that is ever ported back to the Teensy 3.5/3.6, it would likely then need separate D/C pins for each display.

    While the Teensy 3.5/3.6 have multiple SPI buses, I think the other SPI buses are limited to a single fast pin. This doesn't help if you need both CS and D/C pins to be fast pins.

    Teensy 4.0 is a lot more complicated. The SPI internals changed, and also the memory caching behavior is causing some issues. My sense is for ultimate speed, you will devices on separate SPI buses. In addition to the pins meant to be soldered with a ribbon cable to connect to a SD drive (SPI3), there is a second SPI bus on the Teensy 4.0. You would need to solder two wires (or use a breakout shield) to pads #26 and 27 and use pins 0/1 to use SPI2. These pads are at standard 0.1" (2.54mm) spacing and should easier to solder than the SPI3 pins (1mm).

    You might want to read this thread:


    But the discussion has sprawled out to other high volume threads:



    Do you have pull-up resistors for the CS and D/C pins? Somebody else had a similar issue and pull-up resistors helped. For me, I was having screen corruption, and adding 2.2K pull-up resistors allowed me to raise the SPI bus speed when I was talking to two different displays. A pull-up resistor would be a resistor that goes between the pin and 3.3v in parallel to the normal wire. I've used 2.2K pull-up resistors, which I also use for i2c buses.
    Hi Michael, very much appreciate the detailed response. Currently on the road but will do further research and I will be back with new findings and developments.

  5. #5
    Junior Member
    Join Date
    Feb 2019
    Posts
    4
    Quote Originally Posted by MichaelMeissner View Post
    It depends on how optimized the drivers are and whether the devices do things like tri-state MISO properly.

    Assuming you have done all things in the quoted document (pull-up resistors on the CS pins, verified the device tri-states MISO, and verified that the driver uses SPI.beginTranasaction and SPI.endTransaction), if the drivers are dumb, then it may not matter if if you have one SPI device or two. I suspect it will do one device and then another.

    However, if you have the proper driver with the appropriate magic, then it will speed things up, because the driver queues things up to do transfers in the background (using DMA) while it is free to do other things.

    Note, while I am familiar with things at a high level, for details you want the experts (KurtE, mjs513, defragster, and of course Paul S.).

    The 3.x world seems to be very different from the 4.0 world.

    In the 3.x world you could have 5 high speed options, spread over 9 pins. Note, some pins internally used the same ports, so you could use on or the other pin with high speed SPI, but not both. The pins are:


    Note, if your device uses a D/C pin, that must also come the list of fast pins.

    One of the canonical programs that does use dual SPI is uncannyEyes, which draws eyes on two 128x128 displays as fast as it can. In uncannyEyes, you need 3 fast pins (one for the CS for each display, and the third for the shared D/C pin). In my current configuration, I tend to use pins 23/22 as the two CS pins and 15 as the D/C pin, but I may be changing this to use a more standard CS pins 10/9.


    The author of uncannyEyes has been working on newer versions that target other microprocessors (Rasberry Pi, and the Adafruit Monster M4SK which uses an ARM Cortex M4). IIRC, in the Teensy version, he does one display, waits until it is finished and then does the other display. In the newer version that uses 240x240 displays instead of 128x128 displays (i.e. 4 times the data), I believe he does both SPI streams in parallel (using 2 SPI ports). If that is ever ported back to the Teensy 3.5/3.6, it would likely then need separate D/C pins for each display.

    While the Teensy 3.5/3.6 have multiple SPI buses, I think the other SPI buses are limited to a single fast pin. This doesn't help if you need both CS and D/C pins to be fast pins.

    Teensy 4.0 is a lot more complicated. The SPI internals changed, and also the memory caching behavior is causing some issues. My sense is for ultimate speed, you will devices on separate SPI buses. In addition to the pins meant to be soldered with a ribbon cable to connect to a SD drive (SPI3), there is a second SPI bus on the Teensy 4.0. You would need to solder two wires (or use a breakout shield) to pads #26 and 27 and use pins 0/1 to use SPI2. These pads are at standard 0.1" (2.54mm) spacing and should easier to solder than the SPI3 pins (1mm).

    You might want to read this thread:


    But the discussion has sprawled out to other high volume threads:



    Do you have pull-up resistors for the CS and D/C pins? Somebody else had a similar issue and pull-up resistors helped. For me, I was having screen corruption, and adding 2.2K pull-up resistors allowed me to raise the SPI bus speed when I was talking to two different displays. A pull-up resistor would be a resistor that goes between the pin and 3.3v in parallel to the normal wire. I've used 2.2K pull-up resistors, which I also use for i2c buses.
    Hi MichaelMeissner,
    I am currently working with a Teensy 4.0 and two different SPI devices: one ADC which is producing values at 18kHz (DR signal) and an SD Card.
    For speed reasons I want to use the two SPI ports. ADC on pins 10,11,12,13 and SD Card on pins 34,35,36,37.

    I am fairly new to software development and therefore I am not shure which adjustments to make to the different librarys. I have seen that pins_arduino.h does not define the second SPI bus. Do I need to make adjstments to the Sd2PinMap.h and add the second SPI pins? I do not know how to address the second SPI bus, since none of the methods (SPI.beginTransaction, SPI.transfer) is having a specifier for the different SPI busses.
    Thank you very much for your advice!

    Johannes

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,485
    Quote Originally Posted by JSCLadon View Post
    Hi MichaelMeissner,
    I am currently working with a Teensy 4.0 and two different SPI devices: one ADC which is producing values at 18kHz (DR signal) and an SD Card.
    For speed reasons I want to use the two SPI ports. ADC on pins 10,11,12,13 and SD Card on pins 34,35,36,37.

    I am fairly new to software development and therefore I am not shure which adjustments to make to the different librarys. I have seen that pins_arduino.h does not define the second SPI bus. Do I need to make adjstments to the Sd2PinMap.h and add the second SPI pins? I do not know how to address the second SPI bus, since none of the methods (SPI.beginTransaction, SPI.transfer) is having a specifier for the different SPI busses.
    Thank you very much for your advice!

    Johannes
    For the SPI #2 pins {34,35,36,37}, the best use of those "SD" pins for an SD Card follows 'BUILTIN_SDCARD' in the SD examples for 4 bit SDIO data transfers - like in example : "...\hardware\teensy\avr\libraries\SD\examples\Car dInfo\CardInfo.ino"

  7. #7
    Junior Member
    Join Date
    Feb 2019
    Posts
    4

    CardInfo.ino for SDIO?

    Quote Originally Posted by defragster View Post
    For the SPI #2 pins {34,35,36,37}, the best use of those "SD" pins for an SD Card follows 'BUILTIN_SDCARD' in the SD examples for 4 bit SDIO data transfers - like in example : "...\hardware\teensy\avr\libraries\SD\examples\Car dInfo\CardInfo.ino"

    Thanks for the quick response. When I look into the example and especially into SD2Card.h, i get the impression, that it is using SPI instead of SDIO.
    Unfortunately my current SD Card Reader does not seem to support SDIO.

    I will give it a try as soon as the new card reader arrived.

    Thanks again.

    Johannes

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,615
    Again I am not sure if I saw this mentioned on this thread or not. But potentially another reason to use two SPI busses is if your code (including device libraries) are setup to allow multiple things to go on at the same time with the devices. Typically this is done by using DMA.

    Example with several of our display drivers we have the ability to tell a display to update from the libraries internal "frame buffer" and to do so using DMA. And once you start up the DMA update your code is free to do something else, like startup a display update on another display. One such example of this is in the ST7735_t3 library examples with using uncanny eyes.

    @JSCLandon - nope that device does not support SDIO.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,485
    Quote Originally Posted by JSCLadon View Post
    Thanks for the quick response. When I look into the example and especially into SD2Card.h, i get the impression, that it is using SPI instead of SDIO.
    Unfortunately my current SD Card Reader does not seem to support SDIO.

    I will give it a try as soon as the new card reader arrived.

    Thanks again.

    Johannes
    Opps … It takes a dedicated socket direct wired to the right pins to get SDIO - like the T_3.6 has.

    Some DIY solutions on this thread : pjrc.com/threads/57913-Is-there-a-third-Teensy-4-0-breakout-board

    Not sure the SPI2 interface to those pins was officially added. Through the Beta @KurtE did work with it for displays and other - but maybe as FlexSPI using those pins?

    In some few weeks/months the T_3.6 sized NEW T_4.1 will hopefully be produced in quantity that will have the SD socket onboard. AFAIK Paul posted he is doing his best to get his design produced in these trying times.

    If waiting isn't in the cards - maybe connecting the USBHost pins to a FLASH drive, or Hard Drive would be an easier and faster alternative. There is a thread for that working with T4's USB Host.

  10. #10
    Junior Member
    Join Date
    Feb 2019
    Posts
    4
    @KurtE and defragster: Thanks a lot. I am fascinated how viral this community is!
    This is my plan now:
    1. Connect the ADC to SPI0 (10,11,12,13) and talk to it via the SPI Library only.
    2. Connect the (new) SD Card reader to the SDIO Pins (34,35,36,37,38,39) and talk to it through the SD Library.

    Hope that this is going to work

    I'll communicate the result!
    Johannes

  11. #11
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,668
    Quote Originally Posted by JSCLadon View Post
    @KurtE and defragster: Thanks a lot. I am fascinated how viral this community is!
    This is my plan now:
    1. Connect the ADC to SPI0 (10,11,12,13) and talk to it via the SPI Library only.
    2. Connect the (new) SD Card reader to the SDIO Pins (34,35,36,37,38,39) and talk to it through the SD Library.

    Hope that this is going to work

    I'll communicate the result!
    Johannes
    There are several different breakout boards to allow you to access the pins underneath the Teensy 4.0: https://github.com/TeensyUser/doc/wi...reakout-boards.

    There are 2 different sets of pins underneath the Teensy 4.0.

    Pins 24-33 are spaced at the standard 0.1" pitch, and are perhaps easier to access. 2 of the second SPI pins (MOSI1 == 26, SCK1 == 27) are in this lot. Unfortunately, the pinout card misses the other 2 pins (CS1 == 0, MISO1 == 1) that are needed for SPI1.

    Pins 34-39 are arranged for a micro-SD card. They are 1mm pitch, and a little harder to solder since they are smaller. Unfortunately, you can't just plop a micro-SD card reader on these pins. The 2 common methods are to solder an 8 pin FFC (flat cable) to those pins, and bring it out to either a micro SD card reader or to a micro SD card reader attached to a connector so you can remove the Teensy. The other method is to use special PCB that brings out the SD card pins.

  12. #12
    Junior Member
    Join Date
    Feb 2019
    Posts
    4
    Thanks Michael,

    I am not good in programming, but I have done quite some soldering. Therefore soldering to the SDIO (pin 34 - 39) is my choice as soon as the new card reader has arrived. I'll keep you posted.

    Johannes

Posting Permissions

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