TWR-K65F UART baudrate issue at 120/180MHz

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

TWR-K65F UART baudrate issue at 120/180MHz

Jump to solution
1,413 Views
treefrog
Contributor II

Hi!

I'm assembling my FreeRTOS environment to a TWR-K65F devboard. The MCUXpresso SDK is SDK_2.9.0_MK65FN2M0xxx18. This package contains the same clock config scheme in many instances (under boards/frdmk66f with the name of config_clock.c). My preferred selection is the 180MHz high speed mode, so the following are taken from config_clock.c:

const mcg_config_t mcgConfig_BOARD_BootClockHSRUN = {
    .mcgMode         = kMCG_ModePEE,                              /* PEE - PLL Engaged External */
    .irclkEnableMode = kMCG_IrclkEnable | kMCG_IrclkEnableInStop, /* MCGIRCLK enabled as well as in STOP mode */
    .ircs            = kMCG_IrcSlow,                              /* Slow internal reference clock selected */
    .fcrdiv          = 0x0U,                                      /* Fast IRC divider: divided by 1 */
    .frdiv           = 0x0U,                                      /* FLL reference clock divider: divided by 32 */
    .drs             = kMCG_DrsLow,                               /* Low frequency range */
    .dmx32           = kMCG_Dmx32Default,                         /* DCO has a default range of 25% */
    .oscsel          = kMCG_OscselOsc,                            /* Selects System Oscillator (OSCCLK) */
    .pll0Config =
        {
            .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */
            .prdiv      = 0x0U,            /* PLL Reference divider: divided by 1 */
            .vdiv       = 0xeU,            /* VCO divider: multiplied by 30 */
        },
    .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */
};
const sim_clock_config_t simConfig_BOARD_BootClockHSRUN = {
    .pllFllSel  = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */
    .pllFllDiv  = 0,                           /* PLLFLLSEL clock divider divisor: divided by 1 */
    .pllFllFrac = 0,                           /* PLLFLLSEL clock divider fraction: multiplied by 1 */
    .er32ksrc=SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */
    .clkdiv1    = 0x2260000U,                  /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /3, OUTDIV3: /3, OUTDIV4: /7 */
};
const osc_config_t oscConfig_BOARD_BootClockHSRUN = {
    .freq        = 12000000U,            /* Oscillator frequency: 12000000Hz */
    .capLoad     = (OSC_CAP0P),          /* Oscillator capacity load: 0pF */
    .workMode    = kOSC_ModeOscLowPower, /* Oscillator low power */
    .oscerConfig = {
        .enableMode =
            kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */
        .erclkDiv = 0,        /* Divider for OSCERCLK: divided by 1 */
    }};

/*******************************************************************************
 * Code for BOARD_BootClockHSRUN configuration
 ******************************************************************************/
void BOARD_BootClockHSRUN(void)
{
    /* Set HSRUN power mode */
    SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
    SMC_SetPowerModeHsrun(SMC);
    while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun)
    {
    }
    /* Set the system clock dividers in SIM to safe value. */
    CLOCK_SetSimSafeDivs();
    /* Initializes OSC0 according to board configuration. */
    CLOCK_InitOsc0(&oscConfig_BOARD_BootClockHSRUN);
    CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockHSRUN.freq);
    /* Configure the Internal Reference clock (MCGIRCLK). */
    CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockHSRUN.irclkEnableMode, mcgConfig_BOARD_BootClockHSRUN.ircs,
                                  mcgConfig_BOARD_BootClockHSRUN.fcrdiv);
    /* Configure FLL external reference divider (FRDIV). */
    CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockHSRUN.frdiv);
    /* Set MCG to PEE mode. */
    CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockHSRUN.oscsel, mcgConfig_BOARD_BootClockHSRUN.pllcs,
                        &mcgConfig_BOARD_BootClockHSRUN.pll0Config);
    /* Set the clock configuration in SIM module. */
    CLOCK_SetSimConfig(&simConfig_BOARD_BootClockHSRUN);
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK;
}

Everything is fine as long as I want to set up UART2 (PTE16-17) for 115200-8N1 console purposes. (UART2 is wired to the companion Kinetis MCU on the board and that converts it to a USB device appearing as /dev/ttACM* in linux). This is the key part in my console driver:

UART_Init(desc->uart, &ucfg, CLOCK_GetBusClkFreq());

After transmitting bytes with UART2, only garbage can be seen in minicom terminal emulator. However, if I change the above statement to this:

UART_Init(desc->uart, &ucfg, 80000000UL);

minicom begins receiving what it's supposed to.

I don't think that either minicom or linux CDC ACM driver is faulty. Instead, that 80MHz is very suspicious. In theory (and according to SIM clockdiv settings) the peripheral bus cannot go over 60MHz, but with 60MHz in UART_Init the baudrate is inadequate. Raising it to 80MHz seems to generate nice baudrate (the real expected 115200bps). I simply don't understand this (calculation error in UART driver module?).

The same happens if I select the 120MHz config.

The manual says peripheral bus must not run over 60MHz, and inspecting SIM clockdiv settings the divisor for peripheral bus clock is proper.

Also suspicious that 80MHz is 33% more than 60MHz.

Could you please help me out with this? I don't want to use 80000000 instead of 60000000, because it's a hack and I'll have to use UART for other purposes too (e.g. RS485) where the exact baudrate generation is crucial.

0 Kudos
1 Solution
1,372 Views
treefrog
Contributor II

I could make new 96, 120 and 180MHz CPU clock configs with MCUXpresso, so now all seem to be running fine. The UART also operates as expected.

 

View solution in original post

12 Replies
1,379 Views
treefrog
Contributor II

After executing SystemCoreClockUpdate() function the CPU frequency is much higher than expected. Exactly 33% higher So for a 120MHz config it's running at 160MHz, and for a 180MHz config it's running at 240MHz. Good to know that it can be seriously overclocked

As I don't want to manually edit the clock config, I'll make MCUXpresso generate a proper config for me.

0 Kudos
1,373 Views
treefrog
Contributor II

I could make new 96, 120 and 180MHz CPU clock configs with MCUXpresso, so now all seem to be running fine. The UART also operates as expected.

 

1,405 Views
mjbcswitzerland
Specialist V

Hi

Try https://github.com/uTasker/uTasker-Kinetis

It contains a TWR-K65 FreeRTOS configuration (just enable target TWR_K65F180M) and chose between high speed run mode (enable USE_HIGH_SPEED_RUN_MODE) or not (don't enable this for 120MHz).

Beware that in HSRUN mode you can't write to flash and there are few other subtle restrictions.

It has a console on UART2 by default (change the define DEMO_UART from 2 to any other one as required) and will default to 115.2kBaud.

It can run in Visual Studio as simulated K65 so that full operating details can be easily checked and the simulation informs of clock speeds and the UART baud obtained:
- 180MHz core, 60MHz bus, 25.714285 MHz Flash and 115'163Baud

mjbcswitzerland_1-1613411164543.png

As you probably know UARTs 0 and 1 use core clock and the other UARTs use the bus clock so your calculating with the bus clock would be correct of UART2. This solution does need clock generation and automates the details internally and can be used either as faster project solution or as comparison to help debug code configured or generate by the configuration tools.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/kinetis/TWR-K65F180M.html

0 Kudos
1,395 Views
treefrog
Contributor II

I'll definitely check uTasker and FreeRTOS config, thanks for the hint.

I'm new to K65F and rather surprised to get informed about some restrictions in HSMODE. Having a quick glance at the K65F reference manual I can confirm that HSMODE introduces some restrictions. Perhaps I'll switch back to 120MHz, because e.g. runtime flash read/write is necessary in our projects.

0 Kudos
1,393 Views
mjbcswitzerland
Specialist V

Hi

The HSRUN mode restrictions are a bit of a nuisance so it is easier to just run at 120MHz if that is adequate.

If you are just starting out on a project and may needs more performance I would certain look at an iMX RT 1021 instead of a K65F. It is cheaper and knocks spots off it in performance and features. uTasker Kinetis users (eg. those who use if for their K6x projects) just switch a project define from KINETIS to i.MX and their project work on these parts instead so no porting effort or new learning curves are needed (although if one needs to understand the i.MXs they are a tad more complicated under the bonnet).

The i.MX RT 1021: https://www.utasker.com/iMX/RT1020.html costs $2.29 in quantity (or around $6 in small numbers from distributors) and has the same EMAC and HSUSB (but dual!) as in the K65 but runs at up to 500MHz with 256k internal RAM. It does need a $0.50 QSPI Flash to boot from but can then run encrypted code on-the-fly from it at up to 133MHz, whereby its instruction and data caches ensure much better performance in this situation too (2 x SDHC controller, 8 x LPUARTs, 2 x FlexCAN, TRNG etc.). It also has double-precision floating point (Cortex-M7) against the K65's single-precision unit.

See https://www.utasker.com/iMX/developers.html for a complete out-of-the-box encrypted loader concept, complete applications (USB, TCP/IP FAT, MODBUS, etc.)  and chip simulation - with video guides.
Unless there is a special reason for selecting the K65 there is no more development complication with the more modern alternative nowadays.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1020.html

0 Kudos
1,410 Views
myke_predko
Senior Contributor III

Hi @treefrog 

Are you using MCUXpresso?  If you are, could I suggest that you use the clock wizard to set up the clocks in your system?  I'm suggesting that you do that becasue it will throw errors if you have an invalid configuration (ie running the Bus clock at more than 60MHz).  

I know that the clock wizard is somewhat user hostile and it takes a bit of banging on different parts along with studying the RM to get what you want at the end of the day, you can be sure that things are running as desired and you're not adding constants to get things working. 

Using clock wizard also means that you can trust the generated clock_config.c/.h files and not have to worry about them yourself - this may feel like a overly optimistic assumption, but I haven't had any issues with what the clock wizard has produced.  

NXP really needs to do a video/Ap Note/documentation page on the clock wizard because while it looks like it's easy to use it never seems to respond to me in the way that I expect.  

If there is information explailning how to use clock wizard then please post a pointer to it.

myke

0 Kudos
1,396 Views
treefrog
Contributor II

No, I don't use MCUXpresso, but the SDK was just recently generated by nxp.com and the supplied config_clock.c has a header like this:

/***********************************************************************************************************************
 * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
 * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
 **********************************************************************************************************************/

 So this makes me uncertain that the clock config is wrong... but what else could go wrong...?

Anyways, I'll give MCUXpresso clock configurator a try. Some years ago when I brought up K64F the Processor Expert was useful for the same task...

 

0 Kudos
1,391 Views
myke_predko
Senior Contributor III

Hiya @treefrog 

That message is telling you that the clock_config.c/.h files were generated automatically by the clock wizard and if you make any changes to them and then use MCUXpresso to update the configuration then the files will be overwritten.  

It's one of the reasons why I recommend using the clock wizard when you are using MCUXpresso as you have one location for the clock configuration source code generation that you can review (I find looking at a graphical representation of the clock configuration with different values presented to be useful).  

As you're not using MCUXpresso, then you don't have to worry about these files being updated - what development tool are you using?  

myke

0 Kudos
1,380 Views
treefrog
Contributor II

I prefer my favourite editor + linux GCC toolchain in my own build system with integrated KSDK. Compiling from command line.

0 Kudos
1,340 Views
myke_predko
Senior Contributor III

@treefrog 

Good to hear that you were able to create the clock_config files for different clock speeds and everything works as expected.  

With your build process, it sounds like it's a bit cumbersome, but it works.  What do you use for debugging your application?

myke

0 Kudos
1,334 Views
treefrog
Contributor II

Of course there's a complex and feature-rich build system under the hood, so I don't invoke the cross-gcc from command line. I wasn't accurate enough. But the compile itself is initiated from command line. I prefer to avoid dragging mouse and clicking around as much as possible during development, keyboard is much faster and efficient. Therefore I don't prefer Eclipse and others either.

Debugging:

- intuition;

- serial console, LEDs;

- Segger Ozone;

 

0 Kudos
1,331 Views
myke_predko
Senior Contributor III

@treefrog 

Interesting - personally, I place a lot more importance on source code debugging as well as having a single development tool which brings in the libraries (and the're development, as in the case of clock_config) than I do on the code editor.  

I've found that spending a few minutes seeing the code work with different test cases saves hours down the road trying to figure out why things are going sideways.  The same with being able to see all the components to a project.  Different strokes, I guess.  

Thanx - Keep well and safe!

myke

0 Kudos