Clocking the KL03 from the external crystal (FRDM-KL03Z)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Clocking the KL03 from the external crystal (FRDM-KL03Z)

1,680 Views
mjbcswitzerland
Specialist V

Hi All

I wonder whether anyone has tried clocking the KL03 from its 32kHz oscillator?

According to the user's manual it should be quite simple:

pastedImage_0.png

The device starts up in the 8MHz mode and may move directly to the EXT mode.

pastedImage_1.png

That means:

1. set 0x04 in MCG_C2

2. Modify MSCG_C1 from its default value of 0x40 (running from the 8MHz internal clock) to 0x80 (EXT mode)

If this is performed the processor loses its clock and the debugger stops working. Also the 32kHz oscillator is not yet running.

If an initial step of enabling the OSC (writing 0xa0 to OSC_CR) is performed the 32kHz is measurable on the crystal after step 1 and MCG_S shows that the oscillator has been initialised.

However again, when trying to mode the the EXT mode (step 2), the same thing happens - processor/debugger die.

Any ideas what is wrong?

Regards

Mark

Labels (1)
0 Kudos
6 Replies

760 Views
al_muir
NXP Employee
NXP Employee

Mark,

One possible solution would be to not write a value of 0x04 to MCG_C2 but use a value of 0x05. This keeps the LIRC in the 8 MHZ mode. It is not permitted to switch directly between the 2 MHz and 8 MHz modes of the LIRC.

Regards,

Alistair

760 Views
mjbcswitzerland
Specialist V

Hi Alistair

Unfortunately I have tried that but it doesn't change the behaviour. Here is the code that I have been attempting with (with the actual hex values written are shown to avoid any confusion):

OSC0_CR = (OSC_CR_ERCLKEN | OSC_CR_EREFSTEN); // enable the oscillator and allow it to continue oscillating in stop mode [0xa0]

MCG_C2 = (MCG_C2_EREFS | MCG_C2_IRCS); // select oscillator as external clock source [0x05]

while ((MCG_S & MCG_S_OSCINIT0) == 0) {} // wait for the oscillator to start [MCG_S becomes 0x06 when oscillator ready]

MCG_C1 = MCG_C1_CLKS_EXTERN_CLK; // select external clock source - EXT mode [0x80]

while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXT) {} // wait until the source is selected

The value 0x80 (EXT mode) is written to MCG_C1 and the debugger freezes.
When the board is left to run it gets as far as this line and stops, with the watchdog kicking in and the process starting over and over again.

However what is really strange is. If I leave it in this cycle for some time - maybe after a few minutes -  it will suddenly start and run the rest of the code (from a 32kHz clock because the code is operating at the correct speed). It is like it somehow manages to get past the clock source change after many attempts.

If I then reset the board (reset button) it always starts correctly.

When I do a power down/up again it then has the difficulty again and I have to wait a few minutes before it sometimes starts again.

If I use LIRC or HIRC it always runs normally so there looks to be some complication with the direct 32kHz crystal mode.

Regards

Mark

0 Kudos

760 Views
al_muir
NXP Employee
NXP Employee

Mark,

A few comments:

1) You appear to be enabling the oscillator "OSC0_CR =(OSC_CR_ERCLKEN | OSC_CR_EREFSTEN);" before you select the crystal oscillator by setting EREFS. This MAY result in the oscillator not starting reliably and you must set EREFS (and any other oscillator configurations like HGO, and for devices that support it, RANGE) before you enable the oscillator. I don't think this is necessarily the issue here but point it out as something that should be corrected.

2) The startup time of the 32kHz oscillator can be very long, up to 1 second depending on the crystal and load capacitance. With the COP running from the LPO, set to a nominal 1 second timeout as the default, it is very possible that when you let the code execute withut the debugger the oscillator has not started before hte COP times out. with the startup time so close to the COP timeout time it may well start before the COP times out and you service it. So you may want to service the COP in the loop waiting for OSCINIT to set.

3) In the case of the debugger, when you initially connect to the device you are running at 8MHz and you likely have an SWD clock of 100kHz or something like that. The SWD_CLK is likely slower than the MCU clock. Once you switch the CLKS mux, the core is now running at 32 kHz and is likely running slower than the SWD_CLK. While this is not "illegal", the access to the system registers will be much slower than the debug interface is operating and the debugger needs to support this and may need to "retry" the access several times. I am not sure how many retry times the various debugger tools support. So, in order to make sure the debugger can still communicate with the MCU at this slow speed I would suggest you limit the SWD_CLK speed to less than 32 kHz, maybe even taking it down to 4 kHz. This will make the dubug access incredivbly slow but may resolve the issue you are seeing with the debugger freezing when you switch to the 32 kHz clock.

Regards,

Alistair

0 Kudos

760 Views
mjbcswitzerland
Specialist V

Hi Alistair

1. I don't actually think that the order of the two instructions make any difference in thsi circumance since the oscillator input is not actually connected to anything until later on. However I tried the reversed odering and it didn't change the behaviour in any way.

2. I did think that there may be a slow starup involved but it doesn't start when the watchdog is disabled either. If I watch the oscillation on the crystal itself it is quite fast - when the watchdog fires and the board resets the oscillator virtually continues running across the reset.

3. When I set to 4kHz the debugger still doesn't operate correctly.

However I have realised something and that is that the program is actually not hanging at the clock initialisation but rather does run further due to the fact that there is an LED being turned on before the "freeze" occurs. This output is initialised (before the clock setting) to an output driving '1' which means that the LED is initially turned off. The LED is turned on a little later after variable initialisation has taken place.

With this clock speed, debugging is seemingly not possible (with the tools that I am presenty using) but I am now believing that the problem lies elsewhere, but is due to the slow speed.

What I have been able to determine by using some port output debugging is that the SYSTICK is programmed (with a value of 0x665 to give 50ms) but this interrupt is not firing.

The same code (of course with higher SYSTICK match reload value) at 8MHz or 48MHz clock rate is reliable.

As mentioned earlier - if I leave the board for 5 or 10 minuted in the watchdog cycle (resets every 1s due to missing timer) it starts working at some random point in time! (LED flashes at 50ms rate). I can make as many resets as I want to the board now and each time it starts immediately. As soon as I perform a power cycle I have to wait 5..10 minutes again before it starts working once more.

My intermediate conclusion is thus that there is no probelm with changing the clock mode but rather due to having a slow clock (32kHz) - related to the SYSTICK or its interrupt. There looks to be some state held across warm resets but if it can somehow manage to get a first TICK interrupt it then runs normally until the next power cycle. There is no "freeze" involved because it is certainly spinning in main() waiting for the interrupt.

I have attached the binary in case anyone would like to see its behaviour and or see whether a debugger can connect to it.

Regards

Mark

0 Kudos

760 Views
al_muir
NXP Employee
NXP Employee

Mark,

I am afraid I have been out of the office for the past several weeks.

I loaded your binary on a KL03 Freedom board and I see the board resetting every 9ms or so. I am not sure what board your code was written for and whether there is some conflict that causes such a fast reset period. Without seeing your source code it is going to be next to impossible to debug this issue.

In terms of you debugging your code I can only suggest you move the LED toggle down through your code to help identify the point at which you stop seeing the LED toggle and so identify the area of the code at which it is getting stuck or is perhaps taking an interrupt.

The fact that the code does run using a faster clock source does suggest there is some timing relationship between code execution and some timer over-flowing (SYSTICK I assume). You may want to focus on that.

Regards,

Alistair

0 Kudos

760 Views
mjbcswitzerland
Specialist V

Hi

This thread is rather old and no more work was performed related to 32kHz oscillator clocking of the KL03 until today, when some low power testing was performed. The following link is to the topic that referenced this original post - http://www.utasker.com/forum/index.php?topic=1908.0

When the 32kHz clocking was attempted again it worked. Although there is no definite explanation as to why it works today but didn't work then it is suspected that different flash configuration values are being used. However the code that is operating successfully can be shown:

    MCG_C2 = (MCG_C2_EREFS | MCG_C2_IRCS);                               // select oscillator as external clock source
    OSC0_CR = (OSC_CR_ERCLKEN | OSC_CR_EREFSTEN);                        // enable the oscillator and allow it to continue oscillating in stop mode
    SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 16)); // prepare bus clock divides
    while ((MCG_S & MCG_S_OSCINIT0) == 0) {                              // wait for the oscillator to start
    }
    MCG_C1 = MCG_C1_CLKS_EXTERN_CLK;                                     // select external clock source
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXT) {              // wait until the source is selected
    }

Regards

Mark

0 Kudos