This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2541 clock frequency divides by 32

Other Parts Discussed in Thread: CC2541
Hi all,

I'm having a strange issue with the clock frequency on a Sensortag demoboard, hope someone can help me out.

In the original Sensortag code when I initialize the Timer3Ch1 in PWM mode on P1.4 pin I see the frequency changes on the scope:

Inline image 4
Inline image 1
Inline image 3

During transition from sleep the change from 16MHz RCosc to 32MHz crystal osc can be observed: the PWM frequency changes from 62.5kHz to 125kHz. (As I understood, this is correct behaviour during Power mode transitions)
Problem is: at some point the PWM frequency  drops by a factor of 32, period increases from 8us to 256us.
After 400us to 1600us time (varies if device is connected or advertising) it changes back.

Same happens with the SPI clock, it drops from 800kHz to 25kHz and back.
I see that some interrupts are not serviced during this period.
Same happens when POWER_SAVING is not used:

Inline image 5

I found nothing in the errata, but I found some hints in the CC2541 User's guide chapter 4.4.3:
...calibration of the 32-kHz RCOSC starts up and is performed once if the 32-kHz RCOSC is selected. During calibration, a divided version of the 32-MHz XOSC is used. The result of the calibration is that the 32-kHz RSOSC is running at 32.753 kHz. The 32-kHz RCOSC calibration may take up to 2 ms to complete. Calibration can be disabled by setting SLEEPCMD.OSC32K_CALDIS to 1.
I tried to disable the oscillator calibration by setting SLEEPCMD.OSC32K_CALDIS=1, it didn't help.

Same effect can be observed whether POWER_SAVING is defined or not and with/without the debugger being connected.

I tried to add a task to monitor and trap when CLKCONCMD or CLKCONSTAT change it's value, it didn't work, they remain 0x80.
(Could it be changed and set back again by other blocking task?)

Sensortag runs on a power supply, voltage drops issues could be discarded.
The crystal oscillator runs stable at 32MHz, no glitches there.
The code to initialize PWM and pin in Sensotag_main.c:

main()
{

... original code ...

////////////////////////////////////////////// 
// my stuff:
// Init T3Ch1 as PWM to P1.4

T3CTL = 0x03;       // presc=1, running, up-dn mode
T3CCTL1 = 0x24;     // up-dn running
T3CC0 = 0x80;       // period
T3CC1 = 0x40;       // duty
 
T3CTL |= 0x10;       // presc=1, running, up-dn mode
   
P1SEL |= 0x10;        // set bit4 peripheral mode   

P2SEL &= 0x03;  
P2SEL |= 0x60;  // set priority

P1DIR |= 0x10;        // set bit4 as output

SLEEPCMD |= 0x80; // OSC32K_CALDIS=1  <-- doesn't make any change

// my stuff ends here

////////////////////////////////////////////// 

  /* Start OSAL */
  osal_start_system(); // No Return from here
 }
    

Could someone please give me some hint what's going on?
Thank you for your effort!

  • Hi,

    You can define a constant tick speed by writing to the register called CLKCONCMD.TICKSPD. If you write 0x5 << 3 to CLKCONCMD you will set a constant 1 MHz tick speed to the PWM generation.

    If you have included hal_mcu.h, you can do CLKCONCMD = (CLKCONCMD & ~(0x07 << 3) | (0x05 << 3);. This will clear the existing setting and set 1 Mhz.

    The reason you get varying tick speeds is likely that you have HaltOnRf and ClkDivOnHalt enabled. See hci.h for the API to turn this on and off.

    Best regards,
    Aslak

  • Dear Aslak,

    thanks for the quick reply and for the good ideas, you're right!

    In Sensortag.c I found the following:

     // Enable clock divide on halt

     // This reduces active current while radio is active and CC254x MCU

     // is halted

    HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );

     

    Changing this to

    HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_DISABLE_CLK_DIVIDE_ON_HALT );

    solved the issue.

    Thx & Regards,

    Laszlo