Hi Robin,
Exactly how are you measuring the FLL acquisition time? In your case, this parameter applies from the time the reference is trimmed but I don't see how you could be measuring this externally (i.e., via a port pin). I suggest toggling a port pin just before the internal reference is trimmed and then again just after the wait for lock.
For situations like this I often like to see the code the Processor Expert generates. I initiated a simple project using the S08RN8, trimmed the internal reference for 39.0625kHz and set the bus at 20MHz. Here is the relevant resulting generated code:
void _EntryPoint(void)
{
/* ### MC9S08RN16_48 "Cpu" init code ... */
/* PE initialization code after reset */
/* WDOG_CNT: CNT=0xC520 */
setReg16(WDOG_CNT, 0xC520U); /* First part of the WDG unlock sequence */
/* WDOG_CNT: CNT=0xD928 */
setReg16(WDOG_CNT, 0xD928U); /* Second part of the WDG unlock sequence */
/* WDOG_TOVAL: TOVAL=4 */
setReg16(WDOG_TOVAL, 0x04U);
/* WDOG_CS2: WIN=0,FLG=0,??=0,PRES=0,??=0,??=0,CLK=1 */
setReg8(WDOG_CS2, 0x01U);
/* WDOG_CS1: EN=0,INT=0,UPDATE=0,TST=0,DBG=0,WAIT=0,STOP=0 */
setReg8(WDOG_CS1, 0x00U); /* Disable watchdog */
/* Common initialization of the write once registers */
/* SYS_SOPT1: FWAKE=0,STOPE=0 */
clrReg8Bits(SYS_SOPT1, 0x03U);
/* PMC_SPMSC1: LVWIE=0,LVDRE=1,LVDSE=1,LVDE=1,BGBDS=0,BGBE=0 */
clrSetReg8Bits(PMC_SPMSC1, 0x23U, 0x1CU);
/* PMC_SPMSC2: LVDV=0,LVWV=0 */
clrReg8Bits(PMC_SPMSC2, 0x70U);
/* System clock initialization */
/*lint -save -e923 Disable MISRA rule (11.3) checking. */
if (*(uint8_t*)0xFF6FU != 0xFFU) { /* Test if the device trim value is stored on the specified address */
ICS_C3 = *(uint8_t*)0xFF6FU; /* Initialize ICS_C3 register from a non volatile memory */
ICS_C4 = (uint8_t)((*(uint8_t*)0xFF6EU) & (uint8_t)0x01U); /* Initialize ICS_C4 register from a non volatile memory */
}
/*lint -restore Enable MISRA rule (11.3) checking. */
/* ICS_C1: CLKS=0,RDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */
setReg8(ICS_C1, 0x06U); /* Initialization of the ICS control register 1 */
/* ICS_C2: BDIV=0,LP=0,??=0,??=0,??=0,??=0 */
setReg8(ICS_C2, 0x00U); /* Initialization of the ICS control register 2 */
/* ICS_C4: LOLIE=0,CME=0 */
clrReg8Bits(ICS_C4, 0xA0U);
/*** End of PE initialization code after reset ***/
/*lint -save -e950 Disable MISRA rule (1.1) checking. */
__asm jmp _Startup ; /* Jump to C startup code */
/*lint -restore Enable MISRA rule (1.1) checking. */
}
The reset vector points to _EntryPoint(). We can see that the very first thing that the code does is disable the watchdog :smileygrin:. It then configures a few write-once registers and trims the internal reference. Following this it configures the Internal Clock Source and doesn't bother to wait for the FLL to lock. I find this to be a bit curious, but it does essentially equate to the information provided in the reference manual in Example 7.3.1.1 "FEI mode initialization routine":
/* the following code segment demonstrates setting ICS to FEI mode generating 20MHz bus*/
ICS_C2 = 0x00;
ICS_C1 = 0x04; /* internal reference clock to FLL */
ICS_C2 = 0x00; /* BDIV = 0, no prescalar */
ICS_C3 = TRIM_VALUE_39K0625HZ; /* FLL output 20MHz, TRIM_VALUE_39K0625HZ is ~0x50 typically */
I guess that changing the internal reference from 32.768kHz to 39.0625kHz presents little risk of clocking problems. But I would prefer to err on the side of caution and wait for the FLL to lock as you do. Although you should measure the FLL acquisition time as I mention above.
Your code snippet starts at main() but what's happening before this? Or is the reset vector pointing to main() - which is usually a bad idea. Using Processor Expert the reset vector points to _EntryPoint(), which is the hardware initialization routine. Once complete, code execution jumps to _Startup(), the software initialization routine. The standard ANSII C software initialization is usually a three-step procedure that performs:
- a "zero out" (initializing global and static variables to zero), then
- a "copy down" (initializing all non-zero global and static variables), then
- initialization of the stack pointer
_Startup ends by jumping directly to main().
So there can be a lot going on prior to main() executing. I suggest taking a look at where your code starts coming out of reset.
Best Regards,
Derrick