problems with set_arm_clock() on Teensy 4.0

Status
Not open for further replies.

ossi

Well-known member
If I call set_arm_clock() with certain frequencies the clock is not set to the right value. I use the following program:

Code:
extern "C" uint32_t set_arm_clock(uint32_t frequency);

int led = 13;

void setup() {
  pinMode(led, OUTPUT);
  while(!Serial) ;
  Serial.println("teensy40setClockSpeedError1...") ;
  Serial.printf("F_CPU_ACTUAL=%u",F_CPU_ACTUAL);

//set_arm_clock(120000000);
  set_arm_clock(24000000);
  Serial.printf("F_CPU_ACTUAL=%u",F_CPU_ACTUAL);

  while(1){
    CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;
    CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK;
    }
  }

void loop(){
 }

The while loop needs 4 cycles per loop and I measure its frequency with a counter.
If I call set_arm_clock(120000000) the cpu frequency changes to 120MHz, so that works. If I call set_arm_clock(24000000) the frequency is changed to approximately 30MHz (I think other users observed this already). If I call set_arm_clock(144000000) the frequency changes to 120MHz.

If I first call set_arm_clock(120000000); and thereafter set_arm_clock(24000000); the second call now changes the clock frequency to 24MHz as wanted. This trick also works with 144MHz: First set to 120MHz, then to 144MHz and the frequency changes to 144MHz.

I am currently looking at the source code of set_arm_clock(), but the function is quite complicated.

Any ideas what goes wrong in set_arm_clock(24000000) ?
 
The delay at the place shown below within set_arm_clock() seems to help, at least in the cases I mentioned.
Code:
uint32_t div_ipg = (frequency + 149999999) / 150000000;
  if (div_ipg > 4) div_ipg = 4;
  if ((cbcdr & CCM_CBCDR_IPG_PODF_MASK) != (CCM_CBCDR_IPG_PODF(div_ipg - 1))) {
    cbcdr &= ~CCM_CBCDR_IPG_PODF_MASK;
    cbcdr |= CCM_CBCDR_IPG_PODF(div_ipg - 1);
    // TODO: how to safely change IPG_PODF ??
    CCM_CBCDR = cbcdr;
  }
delay(1000) ;
 
Seems I have not used the latest version of the library. Sorry, I will switch to the newest library as soon as possible.
 
Status
Not open for further replies.
Back
Top