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.

CC2540 clock initialization

Other Parts Discussed in Thread: CC2540, CC2541

Hi,

We are using cc2540 in our project. I started with trying out some code on cc2540 Keyfob and tested SimplePeriphiralBLE application. Everything worked fine. However we I ported the application on my actual board. 

I'm facing issues  in HAL_BOARD_INIT() in hal_board_cfg.h. The cc2540 on custom board in not able to switch to 32MHz external cystal. 

I found this macro for switching to xosc.

// switch to the 16MHz HSOSC and wait until it is stable
#define SET_OSC_TO_HSOSC() \
{ \
CLKCONCMD = (CLKCONCMD & 0x80) | CLKCONCMD_16MHZ; \
while ( (CLKCONSTA & ~0x80) != CLKCONCMD_16MHZ ); \
}

// switch to the 32MHz XOSC and wait until it is stable
#define SET_OSC_TO_XOSC() \
{ \
CLKCONCMD = (CLKCONCMD & 0x80) | CLKCONCMD_32MHZ; \
while ( (CLKCONSTA & ~0x80) != CLKCONCMD_32MHZ ); \
}

where

/* CLKCONCMD bit definitions */
#define OSC BV(6)
#define TICKSPD(x) (x << 3)
#define CLKSPD(x) (x << 0)
#define CLKCONCMD_32MHZ (0)
#define CLKCONCMD_16MHZ (CLKSPD(1) | TICKSPD(1) | OSC)

Above are define in hal_mcu.h

However in cc2540 user guide swru191f.pdf in Power management and clock chapter. The CLKCONCMD register has different configuration. Bit 6 of CLKCONCMD.OSC is meant for XOSC selection. 

So the above code should be 

#define SET_OSC_TO_HSOSC() \
{ \
CLKCONCMD = (CLKCONCMD & 0x40) | CLKCONCMD_16MHZ; \
while ( (CLKCONSTA & 0x40) != CLKCONCMD_16MHZ ); \
}\

where CLKCONCMD_16MHZ = BV(6)

#define SET_OSC_TO_XOSC() \
{ \
CLKCONCMD = (CLKCONCMD & ~0x40) | CLKCONCMD_32MHZ; \
while ( (CLKCONSTA & 0x40) != CLKCONCMD_32MHZ ); \
}\

where CLKCONCMD_32MHZ = (0)

Also there is another macro in hal_board_cfg.h

#define START_HSOSC_XOSC() \
{ \
SLEEPCMD &= ~OSC_PD; /* start 16MHz RCOSC & 32MHz XOSC */ \
while (!(SLEEPSTA & XOSC_STB)); /* wait for stable 32MHz XOSC */ \
}

where OSC_PD defined ias BV(2) and XOSC_STB as BV(6). However as per user guide swru191f.pdf both these bit are reserved in SLEEPCMD and SLEEPSTA register. 

However if I program cc2540 Keyfob with changes are per user guide  it is not working which mean that there is something wrong. Please let know which one should I follow the code example which is working or swru191f.pdf  user guide clock command register description.

Thanks and Regards,

Pradeep

  • Hi Pradeep,

    You are right that the current implementation is not strictly following the recommendations in the user guide. This is due to code reuse from older devices with slightly different functionality. That being said, the code will work perfectly fine.

    Since you seem to have issues with both the original code and your modified code I would suspect some kind of HW issue. Is the crystal mounted correctly? Are the crystal specs in line with the requirements in the CC2541 datasheet? Are the load caps correctly dimensioned? Have you tried probing the crystal with an oscilloscope to see what is happening?

    Cheers,
    Fredrik