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

Thread: LPSPI speed limit and QSPI

  1. #1
    Senior Member
    Join Date
    May 2022
    Posts
    298

    LPSPI speed limit and QSPI

    I'd like to know the maximum SPI clock that a Teensy4 can support. Wading through some of the NXP documents (which is painful), the normal LPSPI clock is limited to f_peripheralclock/2. Can't seem to find where or how to set this peripheral clock and what it's limits are. Can someone let me know what f_max would be for the SPI clock? And as a bonus, how one would set it to that speed?

    My application is an external ADC, but I haven't chosen it yet. Would really like to know how fast one can practically read a 16 bit ADC using SPI. It affects my choice of ADC.

    From what I understand there is a FlexSPI, which is supposedly faster, but honestly don't know how to use it. It seems in FlexIOSPI_simple.ino the example is limited to a 20Mbps clock. That doesn't seem faster than LPSPI. Or is that example limited by the writer's oscilloscope?

    Is it possible to use QSPI? If I give up using the SD card (and other external memory) on a 4.1, is it possible to interface to an ADC that way? That would reduce the clock speed by a factor of 4.

    Any insights on this would be helpful.

    Looking to add a better ADC to digitize PIN diode detector pulses for metal identification. A lot of SW has been written, but the onboard ADC is not up to the task. Not enough ENOB.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,783
    LPSPI - I know somewhere in the PDFs, it says like LPSPI should not exceed something like 25 or was it 30mhz.

    The QSPI is a setting on LPSPI so would have the same speeds. However, I am pretty sure that there are not enough of the signal pins associated with any of the SPI object on the T4.x to support QSPI mode.

    If you look at section 48.2.5 for the signals and you would need DATA(0)->DATA(3)
    Click image for larger version. 

Name:	Screenshot.jpg 
Views:	17 
Size:	71.2 KB 
ID:	30269

    And going through the different pins for the LPSPI pins we see:
    Click image for larger version. 

Name:	Screenshot1.jpg 
Views:	23 
Size:	324.2 KB 
ID:	30270

    For example on the main SPI object that uses LPSPI4 with have DATA0(12), DATA1(11), DATA2(36)
    But not PCS3/DATA3

    Which if you look at the pinouts, like the table:
    Click image for larger version. 

Name:	Screenshot2.png 
Views:	20 
Size:	143.3 KB 
ID:	30271
    You will see that there is only one possible pin for this signal, and it is not exported on any of the T4.x...

    Similar for the other LPSPI objects as well

    Edit: I should mention, the SPI library does not have any support for QSPI as for obvious reasons.
    Also to use this, the chip you are talking to would also have to support QSPI.
    You might be able to hack it up for 2 pin SPI mode...

  3. #3
    Senior Member
    Join Date
    Oct 2016
    Posts
    1,216
    You might want to look at this recent thread (https://forum.pjrc.com/threads/72003...eedup-question), but I've been curious about this because it seems to be a common question, so I'll try to answer. The SPI clock frequency for T4 is set in function beginTransaction() of file SPI.h. By adding a printf(), here's what I see. Hopefully others with more experience will comment/correct as necessary.

    - base clock frequency is 240 MHz (there are multiple possible clock sources, but the one being used is 240 MHz)
    - beginTransaction() computes a clock divisor() to get as close to requested frequency as possible without going over
    - for the default SPI clock frequency of 4 MHz, the computed divisor is (58+2)=60
    - the table below shows the actual SCK frequency for requested frequencies from 1-120 MHz
    - at high frequencies, the divisor gets small, so the actual frequency can diverge from requested
    - above 20 MHz, you can get exactly 20, 24, 30, 40, 48, 60, 80, 120, and a few in between

    Code:
    _clock =   1000000   clkhz = 240000000   div = 238+2=240   actual =   1000000
    _clock =   2000000   clkhz = 240000000   div = 118+2=120   actual =   2000000
    _clock =   3000000   clkhz = 240000000   div =  78+2= 80   actual =   3000000
    _clock =   4000000   clkhz = 240000000   div =  58+2= 60   actual =   4000000
    _clock =   5000000   clkhz = 240000000   div =  46+2= 48   actual =   5000000
    _clock =   6000000   clkhz = 240000000   div =  38+2= 40   actual =   6000000
    _clock =   7000000   clkhz = 240000000   div =  33+2= 35   actual =   6857142
    _clock =   8000000   clkhz = 240000000   div =  28+2= 30   actual =   8000000
    _clock =   9000000   clkhz = 240000000   div =  25+2= 27   actual =   8888888
    _clock =  10000000   clkhz = 240000000   div =  22+2= 24   actual =  10000000
    _clock =  11000000   clkhz = 240000000   div =  20+2= 22   actual =  10909090
    _clock =  12000000   clkhz = 240000000   div =  18+2= 20   actual =  12000000
    _clock =  13000000   clkhz = 240000000   div =  17+2= 19   actual =  12631578
    _clock =  14000000   clkhz = 240000000   div =  16+2= 18   actual =  13333333
    _clock =  15000000   clkhz = 240000000   div =  14+2= 16   actual =  15000000
    _clock =  16000000   clkhz = 240000000   div =  13+2= 15   actual =  16000000
    _clock =  18000000   clkhz = 240000000   div =  12+2= 14   actual =  17142857
    _clock =  19000000   clkhz = 240000000   div =  11+2= 13   actual =  18461538
    _clock =  20000000   clkhz = 240000000   div =  10+2= 12   actual =  20000000
    _clock =  22000000   clkhz = 240000000   div =   9+2= 11   actual =  21818181
    _clock =  24000000   clkhz = 240000000   div =   8+2= 10   actual =  24000000
    _clock =  27000000   clkhz = 240000000   div =   7+2=  9   actual =  26666666
    _clock =  30000000   clkhz = 240000000   div =   6+2=  8   actual =  30000000
    _clock =  35000000   clkhz = 240000000   div =   5+2=  7   actual =  34285714
    _clock =  40000000   clkhz = 240000000   div =   4+2=  6   actual =  40000000
    _clock =  48000000   clkhz = 240000000   div =   3+2=  5   actual =  48000000
    _clock =  60000000   clkhz = 240000000   div =   2+2=  4   actual =  60000000
    _clock =  80000000   clkhz = 240000000   div =   1+2=  3   actual =  80000000
    _clock = 120000000   clkhz = 240000000   div =   0+2=  2   actual = 120000000

  4. #4
    Senior Member
    Join Date
    May 2022
    Posts
    298
    @KurtE, thanks for the tables. How are the QSPI memories supported ? Or the SD card on the T4.1? Some specialized driver?

    If I wanted a QSPI ADC, yeah, I'd have to search for one. Probably not many to choose from.

  5. #5
    Senior Member
    Join Date
    May 2022
    Posts
    298
    Quote Originally Posted by joepasquariello View Post
    You might want to look at this recent thread (https://forum.pjrc.com/threads/72003...eedup-question), but I've been curious about this because it seems to be a common question, so I'll try to answer. The SPI clock frequency for T4 is set in function beginTransaction() of file SPI.h. By adding a printf(), here's what I see. Hopefully others with more experience will comment/correct as necessary.

    - base clock frequency is 240 MHz (there are multiple possible clock sources, but the one being used is 240 MHz)
    - beginTransaction() computes a clock divisor() to get as close to requested frequency as possible without going over
    - for the default SPI clock frequency of 4 MHz, the computed divisor is (58+2)=60
    - the table below shows the actual SCK frequency for requested frequencies from 1-120 MHz
    - at high frequencies, the divisor gets small, so the actual frequency can diverge from requested
    - above 20 MHz, you can get exactly 20, 24, 30, 40, 48, 60, 80, 120, and a few in between

    Code:
    _clock =   1000000   clkhz = 240000000   div = 238+2=240   actual =   1000000
    _clock =   2000000   clkhz = 240000000   div = 118+2=120   actual =   2000000
    _clock =   3000000   clkhz = 240000000   div =  78+2= 80   actual =   3000000
    _clock =   4000000   clkhz = 240000000   div =  58+2= 60   actual =   4000000
    _clock =   5000000   clkhz = 240000000   div =  46+2= 48   actual =   5000000
    _clock =   6000000   clkhz = 240000000   div =  38+2= 40   actual =   6000000
    _clock =   7000000   clkhz = 240000000   div =  33+2= 35   actual =   6857142
    _clock =   8000000   clkhz = 240000000   div =  28+2= 30   actual =   8000000
    _clock =   9000000   clkhz = 240000000   div =  25+2= 27   actual =   8888888
    _clock =  10000000   clkhz = 240000000   div =  22+2= 24   actual =  10000000
    _clock =  11000000   clkhz = 240000000   div =  20+2= 22   actual =  10909090
    _clock =  12000000   clkhz = 240000000   div =  18+2= 20   actual =  12000000
    _clock =  13000000   clkhz = 240000000   div =  17+2= 19   actual =  12631578
    _clock =  14000000   clkhz = 240000000   div =  16+2= 18   actual =  13333333
    _clock =  15000000   clkhz = 240000000   div =  14+2= 16   actual =  15000000
    _clock =  16000000   clkhz = 240000000   div =  13+2= 15   actual =  16000000
    _clock =  18000000   clkhz = 240000000   div =  12+2= 14   actual =  17142857
    _clock =  19000000   clkhz = 240000000   div =  11+2= 13   actual =  18461538
    _clock =  20000000   clkhz = 240000000   div =  10+2= 12   actual =  20000000
    _clock =  22000000   clkhz = 240000000   div =   9+2= 11   actual =  21818181
    _clock =  24000000   clkhz = 240000000   div =   8+2= 10   actual =  24000000
    _clock =  27000000   clkhz = 240000000   div =   7+2=  9   actual =  26666666
    _clock =  30000000   clkhz = 240000000   div =   6+2=  8   actual =  30000000
    _clock =  35000000   clkhz = 240000000   div =   5+2=  7   actual =  34285714
    _clock =  40000000   clkhz = 240000000   div =   4+2=  6   actual =  40000000
    _clock =  48000000   clkhz = 240000000   div =   3+2=  5   actual =  48000000
    _clock =  60000000   clkhz = 240000000   div =   2+2=  4   actual =  60000000
    _clock =  80000000   clkhz = 240000000   div =   1+2=  3   actual =  80000000
    _clock = 120000000   clkhz = 240000000   div =   0+2=  2   actual = 120000000
    Thanks for that. This is a helpful table.

    The question somewhat remains - how fast can it really go? I'd think the actual I/O drivers on the outputs wouldn't be able to drive 120MHz without heroics. Don't think that one could juice up the current drive enough to run for very long. 40 MHz might be interesting to try though. I'd guess that any of the higher speeds would have to be characterized to see if they work under various conditions. Sort of one's own qualification.

  6. #6
    Senior Member
    Join Date
    Oct 2016
    Posts
    1,216
    Quote Originally Posted by clinker8 View Post
    The question somewhat remains - how fast can it really go?
    In the thread I linked previously, @DrM seemed to have it working at 30 MHz. I'm nowhere near enough of a hardware person to say where h/w limits would begin to apply, but if 30 works, then I suspect 40 would, too. Do you have any SPI parts that are spec'd over 20 MHz that you could try?

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,783
    Quote Originally Posted by clinker8 View Post
    @KurtE, thanks for the tables. How are the QSPI memories supported ? Or the SD card on the T4.1? Some specialized driver?

    If I wanted a QSPI ADC, yeah, I'd have to search for one. Probably not many to choose from.
    The QSPI memory does not use LPSPI it instead uses: FLEXSPI controller (Chapter 27) - There are two of these, one for main memory and second for those bottom chips.
    Pins 48-54 - Mode 8 If my quick look is correct.

    SD cards also don't use LPSPI, they use the uSDHC (Chapter 26), which again has specific pins defined for it. pins 42-47 (mode 0)...

  8. #8
    Senior Member
    Join Date
    May 2022
    Posts
    298
    Quote Originally Posted by joepasquariello View Post
    In the thread I linked previously, @DrM seemed to have it working at 30 MHz. I'm nowhere near enough of a hardware person to say where h/w limits would begin to apply, but if 30 works, then I suspect 40 would, too. Do you have any SPI parts that are spec'd over 20 MHz that you could try?
    Probably none that are spec'd that fast in my possession at the moment. Best I can do is try to drive an ILI9341 faster and see what happens. I have one installed on a PCB I can try.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,460
    3 peripherals have SPI capability: LPSPI, FlexIO, FlexSPI

    LPSPI is the normal SPI ports. Officially the datasheet says 30 MHz is the maximum, on page 67. Anything over 30 MHz is considered overclocking. Many people have reported success with SPI displays around 50 to 60 MHz.

    FlexIO is complicated. Probably not much faster than LPSPI in practice.

    FlexSPI is the interface used for PSRAM and flash on the bottom side of Teensy 4.1. Default speed is 88 MHz, usable range is about 49 to 132 MHz. It is designed for memory chips and probably not usable for a ADC chip.

  10. #10
    Senior Member
    Join Date
    May 2022
    Posts
    298
    Quote Originally Posted by PaulStoffregen View Post
    3 peripherals have SPI capability: LPSPI, FlexIO, FlexSPI

    LPSPI is the normal SPI ports. Officially the datasheet says 30 MHz is the maximum, on page 67. Anything over 30 MHz is considered overclocking. Many people have reported success with SPI displays around 50 to 60 MHz.

    FlexIO is complicated. Probably not much faster than LPSPI in practice.

    FlexSPI is the interface used for PSRAM and flash on the bottom side of Teensy 4.1. Default speed is 88 MHz, usable range is about 49 to 132 MHz. It is designed for memory chips and probably not usable for a ADC chip.
    Thanks for the actual numbers. Appreciate that.

  11. #11
    Senior Member
    Join Date
    Oct 2016
    Posts
    1,216
    @DrM reports that he is using 16-bit ADC at 30 MHz. Part number MCP33131D-10-I/MS

  12. #12
    Senior Member
    Join Date
    May 2022
    Posts
    298
    Quote Originally Posted by KurtE View Post
    The QSPI memory does not use LPSPI it instead uses: FLEXSPI controller (Chapter 27) - There are two of these, one for main memory and second for those bottom chips.
    Pins 48-54 - Mode 8 If my quick look is correct.

    SD cards also don't use LPSPI, they use the uSDHC (Chapter 26), which again has specific pins defined for it. pins 42-47 (mode 0)...
    Does your library ILI9341_t3n allow (ie. not overwrite a user supplied setting) a SPI CLOCK setting of 60MHz? I just want to do a test. No point of dragging out the oscilloscope if I know the setting is not observed. Kind of hard to tell from a casual glance at your source code. It compiles, but does it use 60MHz if I set it in tft.begin(60000000, 20000000)?

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    17,426
    From the included ILI9341_t3 and assuming in the _t3n extension library use: void setClock(unsigned long clk) { _clock = clk;}

    The default is 30Mhz and if 60 MHz is used in setClock() that value will be used for all SPI transfers using the beginTransaction() and end...() wrapping in the library.

Posting Permissions

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