Using the 8 MHz Crystal on the FRDM-KL25Z Freedom Board

The ARM Cortex-M0+ on the KL25Z Freedom Board (FRDM-KL25Z) runs up to 48 MHz. For this, the 8 MHz crystal on the board is used. A 48 MHz is required for USB communication, to have the needed oversampling on USB data lines. I have shown in my USB CDC post how such a clock is configured, using the white pre-production board. To my surprise, when I tried the same code on the black production boards, it did not work on the production black boards. Even worse: it worked on some, but not on every board :-(.

What I observed with the debugger was this: the microprocessor hangs during clock initialization (line 3 below):

/* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
MCG_C6 = 0x00U;
while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
}

So definitely something is different between the boards in respect to the clock setup? Having a close look to the boards indeed shows a difference:

Can you spot the difference?

Can you spot the difference?

Having a closer look makes it more obvious:

R25 difference

R25 difference

The difference is that R25 is populated on the left board, but not on right one. I find that R25 1 MOhm resistor populated on the ‘white’ pre-production Freedom Boards (see my first Freedom board post).

Checking the latest schematics of the board on the element14 site, it shows that R25 as marked as DNP (Do Not Populate):

DNP R25

DNP R25

But black boards get shipped with or without that R25 populated (see as well the comment in this post by luismgc).

In order to get the 48 MHz clock working with a board without R25, I need to set the clock configuration to ‘low power’ mode. That setting is controlled by the CPU Processor Expert properties:

Oszillator operating mode

Oszillator operating mode

This setting is reflected in the HGO0 bit of the MCG_C2 of the Kinetis processor. In ‘high gain’ mode, this bit is set to 1:

/* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=1,EREFS0=1,LP=0,IRCS=1 */
MCG_C2 = MCG_C2_RANGE0(0x02) |
MCG_C2_HGO0_MASK |
MCG_C2_EREFS0_MASK |
MCG_C2_IRCS_MASK;

In ‘low power’ mode, this HGO0 bit is set to zero:

/* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK | MCG_C2_IRCS_MASK);

So depending on that bit, and depending on your crystal circuit, the clock initialization will work or not.

Note: Not having that R25 on the board makes sense from a low power perspective: there should be less leaking current without this 1 MOhm resistor.

Conclusions

  1. Carefully check the clock circuit on your board. That R25 1 MOhm Resistor might or might not be populated on the board.
  2. The resistor is *not* populated, a clock configuration in ‘high gain’ mode will fail.
  3. ‘Low power’ oscillator mode (‘high gain’ *not* set) works on both clock circuit variants.
  4. If downloading/using existing code, check the board configuration it was created for (with or without resistor), and if has the HGO flag set or not.
  5. Even with ‘same’ boards, it is worth to have a look at the actual board components. Maybe something is missing like this R25.

Happy Resisting 🙂

33 thoughts on “Using the 8 MHz Crystal on the FRDM-KL25Z Freedom Board

  1. Luckily my board came with the R25, but I’d like to know, apart from the reduction in consumption, other functional differences between the two modes (Low power and high gain).

    Like

  2. For what it’s worth I see I’m using High Gain mode on my Flexis projects.

    In high-frequency low-power mode the Kinetis MCU provides the feedback resistor internally.

    I also note this from the datasheet: (Too bad they don’t practice this in CodeWarrior beans.) I’d had my share of trouble getting Freescale MCU oscillators to run on my own PCBs before I got the tuning of the caps and Rf and Rs down.

    <<>>

    Like

    • I would need to dig into the forums, but I remember seeing discussions where the result is that you have to use an external (and accurate) crystal for Freescale microprocessors to use USB. An accurate clock is required because of the needed oversampling of the D+ and D- lines. So you might try to use the FLL, but I think it will not work, or will not work reliably. Let me know if you get it work, that would be interesting to see.

      Like

      • Using the FLL (47.9MHz) speed seems to be producing a result where the USB device is enumerated, but is unrecognizable by the PC. It sees a USB device, but it’s an unknown device.

        Like

        • You really have to use the more accurate external quartz in PLL mode to reach exactly the 48 MHz. The USB peripheral on these ‘older’ Kinetis devices won’t work without it, or it will be very unreliable. Some newer Kinetis have ‘crystal-less’ USB implemented, where you could use a more accurate internal clock.

          Like

    • The C and R network around the crystal really depend on the crystal used. You need to check the specs/datasheet of the crystal for the values and what you need. Taking the circuit of the FRDM board and using different components likely will not work.

      Like

    • Personally I’ve found these oscillator circuits a little fiddly to get going sometimes. My advice there is to prepare your PCB layout with the “full circuit” for the oscillator. Rf and Rs can be tuned once you try your board. And wash the soldering flux off the board. It acts like R and C that varies with humidity.

      Like

      • Hi Bill,

        Is there any place where we could read your recommendations for getting the oscillator circuits to work? It seems like many people are posting questions about the oscillators on custom boards. But nobody has posted a good “how-to” for newbies (that I know of).

        I have a custom KL46 circuit where my external oscillator isn’t working. It could be that the R and C values need to be tuned like you mention. But it could also be that the KL46 MCU is not allowing the crystal to oscillate. My only hint is CW’s console log: it tells me that it cannot enter background mode. I’m using a P&E Multilink FX with both the custom board and an FRDM-KL46Z. My test app works fine when I program it on my FRDM-KL46Z with the Multilink. But it doesn’t download unto the custom board.

        Anyway, thanks for sharing your tips here! Your comments usually come in handy in my projects!

        Like

        • Freescale has a bunch of application notes that address crystal oscillator design and PCB layout effects on it. But I’m not actually working with any Kinetis parts so I can’t point you to one specific to these MCUs.

          Some tips:
          • Do not place any signal trace (except the ground traces) near the crystal circuit or across the bottom side of the circuit.
          • Place the oscillator circuit components to the EXTAL and XTAL pins (crystal, feedback resistor, and loading capacitors) as close as possible.

          And of course you need a crystal with the right range of required load capacitance to match the oscillator ckt in the chip.

          Can you post a picture of your PCB layout someplace?
          -Bill

          Like

  3. Hi Bill,

    Thanks for your reply! It seems like the 8 MHz crystal’s connections and component values are fine after all. Also, I realized that the KL46 is supposed to initiate the external crystal and that the SWD programming interface should not depend on whether or not a custom board has an external crystal. The KL46Z runs by default on its 32 kHz internal oscillator.

    By now I’ve reduced the problem to the SWD interface’s RESET_n signal:

    Using an oscilloscope I discovered that the SWD’s RESET_n signal is never asserted on the custom board when I click on CW’s Debug button. That’s the only difference I see on the SWD burst sequence between the FRDM-KL46Z and the custom board. Other than that the burst sequence looks identical for both boards. Then the FRDM-KL46Z continues to show activity on the SWD lines while the custom board’s SWD_CLK and SWD_IO lines go back to their idle state after CW displays the “can not enter background mode error”.

    I thought that it was the Multilink’s responsibility to assert the RESET_n signal. So I’m not sure why the reset is not asserted for the custom board. I already checked that I have continuity between the Multilink’s SWD pins and the corresponding KL46Z pins and that my power supply and ground pins are showing the proper voltages.

    Also, a coworker has already spent about a week checking out the custom board before me and neither of us have found any other issues except for the reset signal.

    Any ideas about troubleshooting the SWD communications would be welcome and of course we will share the solution as soon as we figure this out.

    Thanks again!

    Like

  4. Man!!! This post saved my life!! my board came without the resistor soldered, as soon as I got the HGO bit cleared, the MCG_S register began to work properly as expected…

    I truly love this site!! good good good job with the kl25 stuff… thanks for sharing all your hours of knowledge!!!

    Like

    • Then I’m so glad you have found that post 🙂 And you are welcome: I’m thankful too about all the other engineers out there sharing their knowlege, and I want to contribute back what I have learned for myself, so others can benefit. So thanks for letting me know that this post was useful, so I know the time spent on writing it was worthwile :-))

      Like

  5. Hello Erich,

    I’m noticing that the KL46Z processor might be running much slower than the 48 MHz we’re using as the core clock. We ran a test to toggle a pin indefinitely to check the toggling period using an oscilloscope. Here’s the test code:

    ————————
    Cpu_DisableInt();
    while(1) {
    Testpin_1_PutVal(1);
    Testpin_1_PutVal(0);
    }
    Cpu_EnableInt();

    The resulting waveform shows a high period of 800 ns and low period of 800ns. We would expect to see 20 ns for a core clock of 48 MHz. We checked the crystal and it is indeed oscillating at 8 MHz and our USB communications seem to be working just fine. We discovered this problem while reading from an SPI interface. We started isolating the problem code block and we realized that it was taking too long to perform the reading procedures. So we decided to test the simple toggling of a pin.

    Do you have any advice or troubleshooting suggestions? Is it possible that the CPU is running on a slower clock than the core clock? Processor Expert says that the core clock is configured for 48 MHz just like your tutorial for using the USB CDC interface.

    Thanks in advance!

    Like

    • Hi Carlos,
      interesting question! Have you counted in all the instructions for the LED toggling? The core clock is used for the instructions, but with the access to the pins you are accessing the bus which is using the bus clock which is 24 MHz max. Maybe this is what you see? if you want to test the core clock you should run a series of Nops (e.g. for 100 ms) and measure it. You can use the WAIT component, and then toggle a LED. The LED toggling is still using the bus clock, but then the overhead is not so much.

      Like

      • Hi Erich
        Im working with Carlos on this issue. Here is a snippet from the lst file:

        Cpu_DisableInt();
        12160: f7fe fce6 bl 10b30
        while(1)
        {
        Testpin_1_PutVal(1);
        12164: 4b06 ldr r3, [pc, #24] ; (12180 )
        12166: 6b1b ldr r3, [r3, #48] ; 0x30
        12168: 1c18 adds r0, r3, #0
        1216a: 2101 movs r1, #1
        1216c: f7ff f8b0 bl 112d0
        Testpin_1_PutVal(0);
        12170: 4b03 ldr r3, [pc, #12] ; (12180 )
        12172: 6b1b ldr r3, [r3, #48] ; 0x30
        12174: 1c18 adds r0, r3, #0
        12176: 2100 movs r1, #0
        12178: f7ff f8aa bl 112d0
        }
        1217c: e7f2 b.n 12164
        1217e: 46c0 nop ; (mov r8, r8)
        12180: 1fffe6b0 .word 0x1fffe6b0

        00012184 :
        Cpu_EnableInt();

        As far as I can see, these are just few commands that should take few clock pulses to execute. A 24MHz bus should only delay this by about 40nS, still far from the 800ns.

        I will experiment with nop instructions.
        I would be happy for any comment as I do not understand this slow speed.

        Best regards
        Baldur

        Liked by 1 person

      • Hi Erich
        (I was not able to comment directly on your last post (no button was visible) so I just comment here)

        You are right, when I started to count the instructions and cycles the cycles seems to be about 39 to set the pin high (equals to 800ns if clock frequency is 48MHz). The reason is mostly due to that even the Testpin_1_PutVal(1); is just a macro it is made a subroutine in assembler (bl 112d0 command).

        I measured the on-time for the code above and foud it to be 830ns. I repeated the experiment with 100 nop’s between the Testpin_1_PutVal(1); and the Testpin_1_PutVal(0); and found the on-time to be 3080ns:
        (3080-830)/100=22ns/instruction
        which is not far from expected.

        (the 40ns in previous post is the period time for bus clock of 24MHz)

        So, the result is that the processor is running on 48MHz.
        This question originated from slow processing (SPI flash read takes too long time) and it seems like it could be due to lack of optimization of the code.

        Thanks,
        Baldur

        Like

  6. Hello Erich,

    Perhaps it would be good to explain what Baldur and I are trying to accomplish. We’re using a DataFlash chip as an external memory peripheral to store some measurements performed by our custom board. This chip uses an SPI interface. We want to read contiguous bytes from the DataFlash as fast as possible and then send them through the USB CDC interface. We’re using Freescale’s SPI Master LDD PEx component to talk to the DataFlash chip.

    We noticed that it takes too long to read each DataFlahs byte so we started measuring the readout time by toggling a GPIO pin. Thanks to you, we now know that our core clock is fine. But we haven’t figured out why it takes so long to complete each iteration of our SPI read loop.

    Our pseudocode is as follows:

    Tell the SPI chip that we want to read X number of bytes.
    Loop until X bytes have been read out {
    Set GPIO pin to high.
    Receive one byte.
    Set GPIO pin to low.
    }

    When we look at the waveform generated by the GPIO pin, we notice that it takes about 5 microseconds to read out one byte. But then we have a long low GPIO state until the next rising edge of the pulse. I don’t remember the exact length of the low part of the waveform. It was maybe 20 microseconds. The waveform looks very regular.

    Our goal is to find out why it takes so long until the next rising edge so we can optimize the code and reduce the loop’s period. My best idea so far is to use the micro trace buffer to check if there’s some interrupt service routines that are deterministically bothering our SPI communications. Other than that my best guesses are that the handshake between the SPI module and the MCU takes very long. Maybe we need to optimize the PEx SPI Master LDD settings. Maybe we should be using DMA transfers.

    Do you have any suggestions?

    Thanks again Erich!

    Like

    • Unfortunately I don’t have much (if any) time to look into this. But my guess is that the SPI Master LDD code itself probably is not efficient enough. You might consider to replace it with your own SPI driver?

      Like

  7. Hi Eric,
    I developed custom pcb and i use 8 mhz without 1M resistor. When i set system clock external 8 mhz., it works but when i activeted MCG / PEE, my apps. don’t work . :/
    Thank u for helping.

    Like

    • Hi emreoz,
      You need to match the R’s and C’s around your crystal based on the datasheet of your crystal. Have you done this? You cannot copy the values from one board, as the values are specific to your crystal.
      Then: have you played with the high gain/low power settings too?

      Like

      • Thank you Erich, may i ask one question more 🙂 I use Timer Unit and counter frequency is 1Mhz. I wrote code only LED1_Neg() but when i sens to saleae logic anly. i see only about 330khz. Have u any idea for help me ?

        Like

        • So what would be your expectation? Keep in mind that several assembly instructions will be used for that LED toggling. You might turn on compiler optimization too.

          To verify if your clocks are working properly, I suggest that you use a slower toggling frequency (say 100 Hz) and measure that with the Logic analyzer, just to be sure you do not overload the system. And you might need to run with maximum core clock (48 MHz) if you want to do things fast.

          Like

    • Hi Vishal,
      the capacitors depend on the oscillator you are using on your board. You need to consult the data sheet of that device what values you should use. Usually, I use external capacitor with the values specified in the data sheet. The KL25Z and other Freescale Kinetis devices have internal capacitors you can enable and use them instead of using external capacitors. This reduces the amount of parts needed. But in my designs I always have used external capacitors.

      Like

  8. Hi Erich,
    One of the documents posted by Freescale suggests that the USB can be run through internal reference clock.

    For your reference:

    Click to access AN4905.pdf

    But I don’t quite understand what “Enable the 48 MHz IRC clock (set USB_CLK_RECOVER_IRC_EN[IRC_EN]).” mean. I don’t see the IRC Clock being enabled at 48MHz in the reference manual of KL25z. Can you shed some light on this, please.

    Regards,
    Naruto

    Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.