How to change clock speed on Teensy 4.0?

Paul_M

Member
Clearly one of the most useful and amazing things about T4.0 is that, being that it is only using 100ma running full 600mhz, I should be able to run code 100% of the time at 24mhz using just 4ma whereas T3.6 is using about 17ma to do the same.

I am disappointed there does not seem to be a simple way, or any stated way without being an expert and pouring through beta test thread, to do this.

As a disclaimer, this thread (https://forum.pjrc.com/threads/57439-Teensy-4-0-F_BUS-F_BUS_ACTUAL-F_CPU-F_CPU_ACTUAL) does not answer this question.

Unlike the other Teensy models, the 4.0 in Arduino IDE does not have different Mhz preselections built into the menu.

This is one of my favorite things about Teensy, being able to select lower Mhz for lower power usage, and it is totally gone in Teensy 4.0 where the whole benefit to me is lower power at 24mhz.

I tried calling "set_arm_clock(12000000);" instead of 600000000 in startup.c. The results were very disappointing. First, it transformed by Serial.println-then-delay(1000)-loop test program into a sequence of fast-as-possible Serial prints. It ruined delay(1000); it didn't delay.

Second, the power consumption only dropped to 36ma even though I tested with 12mhz and would expect 2ma power consumption interpolating from 100ma/600mhz. That is way worse than T36, let alone better.

Further, it is an advertised feature of the Teensy 4.0 that "Teensy 4.0 provides support for dynamic clock scaling" "and Arduino functions like delay() and millis(), and Teensyduino's extensions like IntervalTimer and elapsedMillis, continue to work properly while the CPU changes speed".

This, combined with the way better power/mhz ratio, is why I got extremely excited about Teensy 4.0.

How can I lower the clock speed properly? Why is there a dearth of mhz selections in the IDE like with T36? How can I either dynamically or statically lower clock speed?

Thank you.
 
Look through the code/comments in this file : ...\hardware\teensy\avr\cores\teensy4\clockspeed.c

In setup running the set_arm_clock(24000000); might allow USB to work - need the extern "C" to the func.
 
@PaulStoffregen - you'll see a PaulStoffregen/cores/pull/391 as that code reads a bit funny?

@Paul_M : give the code change in that Pull Request a try - it will drop MCU voltage from 1.15V to 0.95V and that might help your current measure?
>> teensy4/clockspeed.c :: } else if (frequency <= 24000000) {

In sketch starting something like this:
Code:
#if defined(__IMXRT1062__)
extern "C" uint32_t set_arm_clock(uint32_t frequency);
void setup()
{
    set_arm_clock(24000000);
    Serial.begin(9600);
    while ( !Serial && millis() < 4000 ) ;
    Serial.print("F_CPU_ACTUAL=");
    Serial.println(F_CPU_ACTUAL);
#else
void setup()
{
    Serial.begin(9600);
    while ( !Serial && millis() < 4000 ) ;
    Serial.print("F_CPU=");
    Serial.println(F_CPU);
#endif
 
Got the T4 running at 24MHz and working USB with code above in sketch as below.

Using a new Production Bare Teensy 4::
> My DMM is showing 39 mA w/LED OFF and 42 mA w/LED ON before the pull request code change to get lower voltage.

Uploading with the pull/391 change made
> My DMM is showing 35.4 mA w/LED OFF and 38.4 mA w/LED ON before the pull request code change to get lower voltage.

Code:
#if defined(__IMXRT1062__)
extern "C" uint32_t set_arm_clock(uint32_t frequency);
#endif

uint32_t count, prior_count;
uint32_t prior_msec;
uint32_t count_per_second;

bool flip = true;
void setup() {
  Serial.begin(1000000); // edit for highest baud your board can use
  while (!Serial) ;
#if defined(__IMXRT1062__)
    set_arm_clock(24000000);
    Serial.print("F_CPU_ACTUAL=");
    Serial.println(F_CPU_ACTUAL);
#endif
  count = 10000000; // starting with 8 digits gives consistent chars/line
  prior_count = count;
  count_per_second = 0;
  prior_msec = millis();
  pinMode( LED_BUILTIN, OUTPUT );
  digitalWriteFast( LED_BUILTIN, flip );
}

void loop() {
  while (1) {
    Serial.print(" >count=");
    Serial.print(count);
    Serial.print(", lines/s=");
    Serial.print(count_per_second);
    if ( !(count % 4) ) {
      Serial.print(' ');
      Serial.println(millis() / 1000);
    }
    count = count + 1;
    uint32_t msec = millis();
    if (msec - prior_msec > 1000) {
      flip = !flip;
      digitalWriteFast( LED_BUILTIN, flip );
      if ( !Serial ) {
        delay( 50 );
        flip = !flip;
        digitalWriteFast( LED_BUILTIN, flip );
      }
      prior_msec = prior_msec + 1000;
      count_per_second = count - prior_count;
      prior_count = count;
    }
  }
}
 
One great way to modify the clock speed is to use Platform IO in VScode.

Inside the platformio.ini file, simply add the Teensy 4.0 config with:
Code:
board_build.f_cpu = CHOOSEN_CLOCK_SPEED_IN_HERTZ

For example:
Code:
[env:teensy40]
platform = teensy
board = teensy40
framework = arduino
board_build.f_cpu = 600000000
 
Back
Top