Teensy 3.2 - SPI Clock over 30 MHz.

Status
Not open for further replies.
Hello friends, how can i get the SPI clock frequency over 30 MHz?

My Teensy 3.2 runs @ 144 MHz very stable.

Thanks for the help!

here is a Video that shows 40 MHz SPI.

https://www.youtube.com/watch?v=gJxs3Rm0aTU

SPI clock is derived from F_BUS and is always less or equal F_BUS/2.

using standard Teensy settings, highest F_BUS is 60 MHZ (for F_CPU = 120 MHz)

You find the different F_BUS settings in mk20dx128.c.
You may change the different dividers to obtain a different F_BUS, but there may be undesired side effects, as other functionalities depend on F_BUS settings. Some modules may not compile when presented with a novel F_BUS value, other modules may simply not work.

But it is a Teensy and the playground is huge.
 
Code:
#elif F_CPU == 144000000
	// config divisors: 144 MHz core, 48 MHz bus, 28.8 MHz flash, USB = 144 / 3
	SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(4); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!
	SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2);

Works perfect with ILI9341_t3 lib!

Here some stats:

Code:
120 MHz ORIGINAL:
Benchmark                Time (microseconds)
Screen fill              224993
Text                     14827
Lines                    58642
Horiz/Vert Lines         18471
Rectangles (outline)     11711
Rectangles (filled)      467956
Circles (filled)         74776
Circles (outline)        62526
Triangles (outline)      14228
Triangles (filled)       156410
Rounded rects (outline)  28057
Rounded rects (filled)   512189
Done!

and now:
Code:
144 MHz with change:
Benchmark                Time (microseconds)
Screen fill              94117
Text                     8952
Lines                    26150
Horiz/Vert Lines         7780
Rectangles (outline)     4907
Rectangles (filled)      195995
Circles (filled)         35346
Circles (outline)        33565
Triangles (outline)      6660
Triangles (filled)       67744
Rounded rects (outline)  14395
Rounded rects (filled)   215777
Done!

This is insane!

Many thanks to WMXZ!

how much is the SPI Clock now?
 
Do you want a proof picture or video?

EDIT:
Proof_Teensy.jpg
 
Last edited:
Can you trust the reported timing in microseconds is correct, after changing the clocks? Could be confirmed if you use an outside timer to confirm 1000000 Overclocked-Teensy microseconds actually equal one real-world second.
 
wait a moment. I test it now.

EDIT:

Code:
void loop() {
if(micros() - asdf > 60000000){
  Serial.println("60 seconds over!");
  }
}

Checked with an iPhone 6

Proof pics:

IMG_1526.jpg

Without delay from myself i think it is 60 seconds :D
 
Last edited:
Great !
Its no only SPI that is faster, everything else is running faster, too. Even a skecth without much periphal accesses runs faster.
Unfortunately, its not that easy to use it in every case - There are changes to the libs needed to "repair" the timing of F_BUS clocked devices.

Btw, you can add this lines in your Setup(), too.
 
which line you mean?

Code:
#elif F_CPU == 144000000
	// config divisors: 144 MHz core, 48 MHz bus, 28.8 MHz flash, USB = 144 / 3
	SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(4); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!
	SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(2);

This lines?

that would be great!

Later i can test the changes with an NRF24l01.
 
yes, use :
Code:
#if F_CPU == 144000000
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(4); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!
#endif

Edit: The #if ensures that it changes the setting for 144MHz only.

Hm, isn't it 36MHZ for SPI? 144 / 2 / 2 = 36. Am i wrong ?
Edit: or is it 72 MHz ???
 
Last edited:
I dont know! i don't understand the commands..

sample:
Code:
SIM_CLKDIV1_OUTDIV2(0)

what makes the 0 in the ()? and what makes the the OUTDIV2?

OUTDIV2 gives the divider? then i can write OUTDIV3-4-5-6... ?

the (0) i don't understand.

EDIT: ok no OUTDIV2.3.4.5... makes no changes.

but this makes the sketch a tiny bit faster:

Code:
 #if F_CPU == 144000000
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(3); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!
#endif

and all works perfect!
 
Last edited:
I dont know! i don't understand the commands..

sample:
Code:
SIM_CLKDIV1_OUTDIV2(0)

what makes the 0 in the ()? and what makes the the OUTDIV2?

OUTDIV2 gives the divider? then i can write OUTDIV3-4-5-6... ?

the (0) i don't understand.

EDIT: ok no OUTDIV2.3.4.5... makes no changes.

but this makes the sketch a tiny bit faster:

Code:
 #if F_CPU == 144000000
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(3); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!
#endif

and all works perfect!

unfortunately you have to dig into the 1000+ pages of the freescale documentation https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf (eg. page 259 for SIM_CLKDIV1)
But the values are typically given as n-1, so (0) means multiply/divide by 1
 
Hm, isn't it 36MHZ for SPI? 144 / 2 / 2 = 36. Am i wrong ?
Edit: or is it 72 MHz ???

I think that is right. F_CPU @ 144mhz, F_BUS @72MHz, so SPI CLK is 36MHz when using the SIM_CLKDIV1 of 0 1 4?. Does the 0 0 4 setting actually run F_BUS at 144mhz???

EDIT: with CPU @144MHz and DIV1 0 0 4 setting my "unconnected" SPI perf runs at 65 mbs (megabits/sec). With 0 1 4 setting, runs at 32.8 mbs. CPU @120mhz, runs at 27.3 mbs
 
Last edited:
I think that is right. F_CPU @ 144mhz, F_BUS @72MHz, so SPI CLK is 36MHz when using the SIM_CLKDIV1 suggested above.

In the meantime I read the manual. 0 is a divisor 1, so indeed F_BUS is 144 MHz. SPI 72MHz.

The manual mentions a maximum of 50 Mhz for F_BUS!
We have 3x overclocking here... amazing!

It works good with all my Teensys.
 
Last edited:
Hi friends,

today i tested the NRF24L01 and it doesn't work.

my problem is that i need the fast SPI clock for the display but i also need the NRF24L01 working.

any ideas?

OK solved the problem!

Code:
#elif defined(ARDUINO) && !defined (RF24_SPI_TRANSACTIONS)
	// Minimum ideal SPI bus speed is 2x data rate
	// If we assume 2Mbs data rate and 16Mhz clock, a
	// divider of 4 is the minimum we want.
	// CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz
	
      #if !defined (SOFTSPI)	
		_SPI.setBitOrder(MSBFIRST);
		_SPI.setDataMode(SPI_MODE0);
		_SPI.setClockDivider(SPI_CLOCK_DIV4);
      #endif

I changed SPI_CLOCK_DIV2 to DIV4. now all works.

but why i need to change this line in the RF42.cpp and not in the Setup void with that:

Code:
void setup(){

  #if F_CPU == 144000000
  SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(4);
#endif

_SPI.setClockDivider(SPI_CLOCK_DIV4);
 
Last edited:
Question:
I normally run my Teensy at 96MHz, I could jump to 120 MHz confidently. Is this SPI speedup limited to 144 MHz? What would the code look like for 96 or 120 MHz?

FYI: I'm just cutting and pasting and have no idea what the net effect is on my Teensy and clock speeds. I'll go rewrite my sketch to enable and print out USB_SERIAL to make sure it works. When I went to 120MHz with this code added - it failed to program a couple times - I had to button press to take it offline first.

Using the SPI 128x128 code of sumotoy in the sketch here my screen updates at 120 MHz went from 62 to 111 putting this line in setup() and at 96MHz goes from 52 up to 90 FPS - Very ugly ( which was the point of this sketch ) but that is a great increase in speed!:

SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(3); //SIM_CLKDIV1_OUTDIV2(0) war auf 2!!

<edit> : UPDATE - I put in Serial.print()'s and they work at 96 and 120MHz - with no loss in abusive speed. ANd no problem in re-programming updates from the IDE (using TYQT of course).

NOTE: At 120MHz - After running a minute or so unrestrained at 111FPS the display just went all white, I added a 1ms elapsedMillis limiter and the update speed dropped to 99 FPS - I'll see if it runs 'forever' now. I posted this updated code on sumotoy's thread. - if I should modify for 96 and 120 MHZ please advise.
 
Last edited:
with this line you will have a SPI speed @60 Mhz i think. 120/1/2=60 MHz

@96 MHz you have a SPI speed of 48 MHz.
 
AndiIsl - thanks I didn't want to do 'math in public' and be wrong. But it works - Serial.print is stable and all seems well - and much faster and smoother - even a clearScreen doesn't flash as much.
The sketch posted in the other thread slowed serial output to 1/sec and denotes runtime in seconds. Just passed 6.5 minutes at 120 MHz with MAXVAL=1 putting some delay on the SPI thrashing at 60 MHz!

<edit> One hour and counting at full update speed 111 FPS at 120MHz - no problem. (i.e. MAXVAL = 0 in linked sketch). Just edited boards for 144MHZ - 70MHz SPI seems to be too fast for this Teensy or the display? - it won't even complete programming or start right.
 
Last edited:
Status
Not open for further replies.
Back
Top