Over a million developers have joined DZone.

Tutorial: Blinky With the FRDM-KL27Z and Kinetis SDK v2

Getting started from the beginning with this ARM-based embedded processor, using Kinetis in Eclipse.

· IoT Zone

Access the survey results 'State of Industrial Internet Application Development' to learn about latest challenges, trends and opportunities with Industrial IoT, brought to you in partnership with GE Digital.

I’m using the FRDM-KL25Z in my classes, and that board is very popular: low price (<$15), reasonable features (48 MHz ARM Cortex M0+, 128 KByte of FLASH, 16 KByte of RAM), and many tutorials elsewhere and on McuOnEclipse :-).

For the next (Fall) semester I’m looking for alternative boards, and one is the Freescale (now NXP) FRDM-KL27Z:

FRDM-KL27Z with Box

FRDM-KL27Z with box

FRDM-KL27Z Board

Compared to the KL25Z, the KL27Z board has only half of the flash size (64 KByte instead of 128 KByte), but runs at same frequency (48 MHz ARM Cortex M0+) and has same amount of SRAM (16 KByte). But it does have two push buttons which I miss on the FRDM-KL25Z.

FRDM-KL27Z Board

FRDM-KL27Z board

The FRDM-KL25Z is sold for CHF 14.82 by Farnell, and the FRDM-KL27Z costs CHF 20.07! So this is a big price increase. But I kind of like that board as it comes with the jumpers populated and is one of the newer Kinetis devices with bootloader and crystal-less USB operations.

The KL27Z is supported by the new Kinetis SDK v2, but that SDK does not include Processor Expert :-(. Porting existing KL25Z applications to the KL27Z is easy: one of the main advantages of Processor Expert is that it makes porting from one microcontroller to another one a matter of a few mouse-clicks.

Note: The KL27Z is supported by the Kinetis SDK v1.3 which *does* include SDK Processor Expert components. But these components are incompatible with any previous non-SDK components, and I rather want to be on the latest SDK which is v2.0 now. Porting later things from v1.3 to v2.0 would be time-consuming, as the API between the SDKs are very different (or better to say: completely incompatible). On the plus side, the SDK v2.0 is easier to use, so I want to go with that one and not spending time on the v1.3.

This post is about the usual starting points for embedded projects: blink an LED :-) As IDE I’m using Eclipse Luna in Kinetis Design Studio V3.1.0.

Kinetis SDK With Kinetis Expert Portal

See this article about how to use the Kinetis SDK v2 with Kinetis Design Studio. On http://kex.nxp.com I have created a new configuration for the FRDM-KL27Z and built the SDK package for the board (see “First NXP Kinetis SDK Release: SDK V2.0 with Online On-Demand Package Builder“):

Kinetis SDK for FRDM-KL27Z

Kinetis SDK for FRDM-KL27Z

I have placed content (unzipped) into the following folder on my disk:

C:\nxp\KSDK\SDK_2.0_FRDM-KL27Z

Project Creating

In Kinetis Design Studio, I use the wizard menu to create a new project:

New Kinetis SDK v2.0 wizard

New Project Wizard for the Kinetis SDK v2.0

I have added the location of the SDK and select it for my new project:

Kinetis SDK Folder

Kinetis SDK Folder

In the next step I select the board with minimal drivers:

Board Selection

Board Selection

Then finish creating the project. This creates my new blinky project:

Blinky Project Created

Blinky Project Created

Build and Debug

Click on the Build hammer to build the debug configuration:

Build

This should build without errors, so I can debug it:

Note: make sure your debug configuration has not the problem described here Solving “Launching: Configuring GDB Aborting Configuring GDB”

  1. Select project
  2. Press debug button
  3. Select debug connection
  4. Press OK
Debug

Note: The FRDM-KL27Z comes with the P&E OpenSDA firmware loaded by default.

With this, I’m successfully debugging the FRDM-KL27Z board the first time :-)

First Debug

First Debug

Blink!

That project does not do anything, so I have to add the code to blink the LED. Looking at the schematics shows the following pins are used:

  • Red: PTB18
  • Green: PTB19
  • Blue: PTA13
RGB LED Schematic of FRDM-KL27Z

RGB LED Schematic of FRDM-KL27Z (Source: NXP)

So, I need to:

  1. Enable the clocks for Port A and B. Without the peripheral clocked, it will not work or even will create a fault when I try to use it.
  2. Mux the pins. Every pin can be routed (or muxed) to different ports.
  3. Configure the pins. This configures the pin for the specified operation (e.g. input or output).

Later I can use the pins in the application e.g. to turn the LED on or off.

Init Pins

In main() there is already a call to BOARD_InitPins():

#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"

/*!
 * @brief Application entry point.
 */
int main(void) {
  /* Init board hardware. */
  BOARD_InitPins();
  BOARD_BootClockRUN();
  BOARD_InitDebugConsole();

  /* Add your code here */

  for(;;) { /* Infinite loop to avoid leaving the main function */
    __asm("NOP"); /* something to use as a breakpoint stop while looping */
  }
}

In the project created this calls the BOARD_InitPins() inside pin_mux.c:

#include "fsl_device_registers.h"
#include "fsl_port.h"
#include "pin_mux.h"

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Initialize all pins used in this example
 *
 * @param disablePortClockAfterInit disable port clock after pin
 * initialization or not.
 */
void BOARD_InitPins(void)
{
    /* Initialize LPUART0 pins below */
    /* Ungate the port clock */
    CLOCK_EnableClock(kCLOCK_PortA);
    /* Affects PORTA_PCR1 register */
    PORT_SetPinMux(PORTA, 1u, kPORT_MuxAlt2);
    /* Affects PORTA_PCR2 register */
    PORT_SetPinMux(PORTA, 2u, kPORT_MuxAlt2);
}

Currently it does initialize the UART (which I’m not interested in for now). It already enables the clock for port A with:

/* Ungate the port clock */
CLOCK_EnableClock(kCLOCK_PortA);

Which uses the following interface from fsl_clock.h:

void CLOCK_EnableClock(clock_ip_name_t name);

So I add this to enable the clock for port B:

CLOCK_EnableClock(kCLOCK_PortB); /* enable clocks for port B */

Next I set the muxing for each pin and set the ‘mux’ for GPIO function. fsl_port.h has the following interface to mux a pin:

void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux);

To mux all three LED pins I use this:

PORT_SetPinMux(PORTA, 13u, kPORT_MuxAsGpio); /* blue led, PTA13 */
PORT_SetPinMux(PORTB, 18u, kPORT_MuxAsGpio); /* red led, PTB18 */
PORT_SetPinMux(PORTB, 19u, kPORT_MuxAsGpio); /* green led, PTB19 */

Next, the pins are configured as output pins. For this I need a configuration struct like this:

static const gpio_pin_config_t LED_configOutput = {
  kGPIO_DigitalOutput,  /* use as output pin */
  1,  /* initial value */
};

The first entry in the struct configures the pin as output pin, and the second entry is the initialization value. As the LEDs are connected with the cathode side to the microcontroller pin, writing a ‘1’ (logical high) will have the LED turned off.

Because that struct and interface is in a header file, I have to include it:

#include "fsl_gpio.h" /* include SDK GPIO interface */

The following interface in fsl_gpio.h is used to initialize a pin:

void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config);

To initialize all pins I can use:

GPIO_PinInit(GPIOA, 13u, &LED_configOutput); /* mux PTA13 as output */
GPIO_PinInit(GPIOB, 18u, &LED_configOutput); /* mux PTB18 as output */
GPIO_PinInit(GPIOB, 19u, &LED_configOutput); /* mux PTB19 as output */

I have highlighted the needed lines for the 3 LEDs below:

#include "fsl_device_registers.h"
#include "fsl_port.h"
#include "pin_mux.h"
#include "fsl_gpio.h" /* include SDK GPIO interface */

static const gpio_pin_config_t LED_configOutput = {
  kGPIO_DigitalOutput,  /* use as output pin */
  1,  /* initial value */
};

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Initialize all pins used in this example
 *
 * @param disablePortClockAfterInit disable port clock after pin
 * initialization or not.
 */

void BOARD_InitPins(void)
{
    /* Initialize LPUART0 pins below */
    /* Ungate the port clock */
    CLOCK_EnableClock(kCLOCK_PortA);
    /* Affects PORTA_PCR1 register */
    PORT_SetPinMux(PORTA, 1u, kPORT_MuxAlt2);
    /* Affects PORTA_PCR2 register */
    PORT_SetPinMux(PORTA, 2u, kPORT_MuxAlt2);

    /* additional clock and configuration for RGB LEDs (PTA13, PTB18 and PTB19) */
    CLOCK_EnableClock(kCLOCK_PortB); /* enable clocks for port B */
    PORT_SetPinMux(PORTA, 13u, kPORT_MuxAsGpio); /* blue led, PTA13 */
    PORT_SetPinMux(PORTB, 18u, kPORT_MuxAsGpio); /* red led, PTB18 */
    PORT_SetPinMux(PORTB, 19u, kPORT_MuxAsGpio); /* green led, PTB19 */

    GPIO_PinInit(GPIOA, 13u, &LED_configOutput); /* mux PTA13 as output */
    GPIO_PinInit(GPIOB, 18u, &LED_configOutput); /* mux PTB18 as output */
    GPIO_PinInit(GPIOB, 19u, &LED_configOutput); /* mux PTB19 as output */
}

Blinking the LEDs

To blink the LEDs I can use the following API from fsl_gpio.h:

void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask);
void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask);
void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask);

With above functions I can put the pin either low, high or toggle it. The first parameter is a pointer to the port, followed by a bitmask for the pin (or multiple pins if they are on the same port).

To slow down the blinking, I add a very simply delay function:

static void delay(volatile uint32_t nof) {
  while(nof!=0) {
    __asm("NOP");
    nof--;
  }
}

Note: I have marked the parameter with ‘volatile’ to prevent compiler optimization, otherwise the compiler generate very fast code for that delay function.

With this, I can add my blinky LED functionality to the main() loop:

int main(void) {
  /* Init board hardware. */
  BOARD_InitPins();
  BOARD_BootClockRUN();
  BOARD_InitDebugConsole();

  /* Add your code here */
  for(;;) {
    GPIO_ClearPinsOutput(GPIOA, 1<<13u); /* blue led on */
    delay(1000000);
    GPIO_SetPinsOutput(GPIOA, 1<<13u); /* blue led off */
    delay(1000000);

    GPIO_ClearPinsOutput(GPIOB, 1<<18u); /* red led on */
    delay(1000000);
    GPIO_SetPinsOutput(GPIOB, 1<<18u); /* red led off */
    delay(1000000);

    GPIO_ClearPinsOutput(GPIOB, 1<<19u); /* green led on */
    delay(1000000);
    GPIO_SetPinsOutput(GPIOB, 1<<19u); /* green led off */
    delay(1000000);
  }
  for(;;) { /* Infinite loop to avoid leaving the main function */
    __asm("NOP"); /* something to use as a breakpoint stop while looping */
  }
}

Running it on the board, and I have a nice ‘blinky’ board application! :-)


Summary

I kind of like the FRDM-KL27Z board which is supported by the SDK v2. But the SDK v2.0 does not come with Processor Expert which makes porting all the existing projects to the board difficult and time-consuming. And the price of the board is much higher (CHF 20) than the FRDM-KL25Z (CHF 15). I like the two push buttons and the pre-installed jumpers, but that’s a big price add-on with for half of the FLASH memory. And the FRDM-KL25Z is currently better supported by software and tools.

So while I kind a like the board, I’m not sure if I should switch to that board. Students have to pay more if they want to keep the board, they have to learn the new SDK v2 (easier than SDK v1.3, but still more time), and they will be slower and less productive than before with using Processor Expert. With Processor Expert it is a matter of minutes to run a blinky LED application on a brand new board. As someone said: “faster than you can eat a slice of pizza”). Now bigger slices of pizza or needed? Sounds more like to change the type of of lunch? Not sure what will be healthier ;-).

On the bright side, the SDK v2 is much cleaner and easier to use compared to SDK v1.3. Using the SDK v1.3 was not reasonable before, now the SDK v2 could be considered. What I’m thinking about is that there could be some ways to continue using Processor Expert with the SDK v2: to combine the best of two worlds? Maybe worth to explore?

The project created in this tutorial is available on GitHub here.

Happy Blinking :-)

The IoT Zone is brought to you in partnership with GE Digital.  Discover how IoT developers are using Predix to disrupt traditional industrial development models.

Topics:
kinetis ,freescale ,arm

Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}