How to use LPTMR KSDK driver in a FreeRTOS project

Document created by soledad Employee on Jul 25, 2016Last modified by soledad Employee on Oct 19, 2016
Version 3Show Document
  • View in full screen mode

The Kinetis Software Development Kit (KSDK) is a software framework for developing applications on Kinetis MCUs. The software components in the framework include peripheral drivers, middleware and real time operating systems.

 

KSDK provides FreeRTOS OS, selected drivers provide FreeRTOS support in form of an additional layer. This solution enables simple driver integration in RTOS-based applications.

Drivers with FreeRTOS layers are:

• UART / LPUART / LPSCI

• I2C / LPI2C

• SPI / LPSPI

The drivers for FreeRTOS OS is a layer built on top of standard KSDK peripheral drivers to achieve multithread (RTOS) awareness. The wrappers provide an API which blocks the calling task until the I/O operation completes and allows other tasks to run in the background. This is achieved by using the asynchronous API of the underlying driver along with RTOS task synchronization objects. Underlying drivers require enabled interrupts for proper operation.

 

In addition, it is possible to use the KSDK bare metal drivers. This document shows how to use the LPTMR Driver in a FreeRTOS and SDK 2.0 project. For this example it is used SDK 2.0, FRDMK64F and FreeRTOS.

 

If you want to know how to create a new SDK 2.0 with FreeRTOS project please check the below link: https://community.freescale.com/docs/DOC-330183

 

GPIO AND LPTMR EXAMPLE:

Introduction

This example toggle the Blue LED every 1 second. This example check the Timer Compare Flag bit, when this flag is set blue LED changes status.

 

Writing the example code

  1. First it is necessary to create a new SDK 2.0 with FreeRTOS project, please check the below link for do that.

     https://community.freescale.com/docs/DOC-330183

 

   2. After create a new project, open the pin_mux.c file in order to enable the port clock and configure the necessary pins as GPIO (for FRDM-K64F the RGB LED is connected   through GPIO signals: RED to PTB22, BLUE to PTB21 and GREEN to PTE26).

 

  3. In addition, it is necessary to enable the clock for the lptmr module, in the pin_mux.c file.

 

  4. In main.c file it is necessary to include the fsl_lptmr.h and fsl_gpio.h.

 

  5. In main function, create a new task. This task will initialize the LPTMR and GPIO drivers. For this example the new task function was named task_init.

/* Create RTOS task */

   xTaskCreate(

                 task_init,

                 "Task_Init",

                 configMINIMAL_STACK_SIZE,

                 NULL,

                 task_PRIORITY,

                 NULL);

 

    6. Write the task_init function code.

                  a. Using the KSDK GPIO driver:

To initialize the GPIO, define a pin configuration, either input or output, in the user file. Then, call the GPIO_PinInit() function.

In this case the pin PTB21 where blue LED is connected was configured as output.

 

gpio_pin_config_t ledB_config = {kGPIO_DigitalOutput, 0,};

GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config);

 

After configure the GPIO pins, it is possible to use the below GPIO operations:

 

GPIO OUTPUT OPERATIONS.

GPIO_WritePinOutput  (GPIO_Type *base, uint32_t pin, uint8_t output)

GPIO_SetPinsOutput (GPIO_Type *base, uint32_t mask)

GPIO_ClearPinsOutput (GPIO_Type *base, uint32_t mask)

GPIO_TogglePinsOutput (GPIO_Type *base, uint32_t mask)

 

GPIO INPUT OPERATIONS.

GPIO_ReadPinInput (GPIO_Type *base, uint32_t pin)

 

The board.h file contains definitions for this operations. For example:

 

/*!< Toggle on target LED_BLUE */

#define LED_BLUE_TOGGLE() \

GPIO_TogglePinsOutput(BOARD_LED_BLUE_GPIO, 1U << BOARD_LED_BLUE_GPIO_PIN)

 

                  b. Using the KSDK LPTMR driver:

The LPTMR_Init () should be called at the beginning of the application using the LPTMR driver. This function initializes the lptmr_config_t structure, this structure holds the configuration settings for the LPTMR peripheral. To initialize this structure to reasonable defaults, call the LPTMR_GetDefaultConfig () function and pass a pointer to your config structure instance. The config struct can be made const so it resides in flash.

The default values are:

 

config->timerMode = kLPTMR_TimerModeTimeCounter;

config->pinSelect = kLPTMR_PinSelectInput_0;

config->pinPolarity = kLPTMR_PinPolarityActiveHigh;

config->enableFreeRunning = false;

config->bypassPrescaler = true;

config->prescalerClockSource = kLPTMR_PrescalerClock_1;

config->value = kLPTMR_Prescale_Glitch_0;

 

After configure the LPTMR, it is necessary to set the timer period. The LPTMR_SetTimerPeriod(), the timer counts from 0 till it equals the count value set here. The count value is written to the CMR register.

Finally start the timer using the LPTMR_StarTimer (). After calling this function, the timer counts up to the CMR register value. Each time the timer reaches CMR value and then increments, it generates a trigger pulse and sets the timeout interrupt flag. An interrupt will also be triggered if the timer interrupt is enabled.

For this example the below lines configure and start the LPTMR.

 

/* Configure LPTMR */

LPTMR_GetDefaultConfig(&lptmrConfig);

/* Initialize the LPTMR */

LPTMR_Init(LPTMR0, &lptmrConfig);

/* Set timer period */

LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(1000000U, LPTMR_SOURCE_CLOCK));

/* Start counting */

LPTMR_StartTimer(LPTMR0);

 

                  c. This example check the Timer Compare Flag bit, when this flag is set blue LED changes status. So in an infinity loop the LPTMR_GetStatusFlags() function check  

                    the status flag, if this flag is set then toggle the LED and clear the flag using the the LPTMR_ClearStatusFlags() function.

 

while (1)

   {

   if (LPTMR_GetStatusFlags(LPTMR0) )

          {

LED_BLUE_TOGGLE();                       LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);                }

}

 

  7. At this point you can build and debug the example.

 

 

Complete Code GPIO and LPTMR Example

 

#include <string.h>

#include "board.h"

#include "pin_mux.h"

#include "clock_config.h"

#include "fsl_debug_console.h"

#include "fsl_device_registers.h"

#include "fsl_lptmr.h"

#include "fsl_gpio.h"

 

/* FreeRTOS kernel includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "timers.h"

 

/* Task priorities. */

#define task_PRIORITY (configMAX_PRIORITIES - 1)

 

/*******************************************************************************

* Definitions

******************************************************************************/

 

/* Get source clock for LPTMR driver */

#define LPTMR_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_LpoClk)

 

static void task_init(void *pvParameters);

/*******************************************************************************

* Variables

******************************************************************************/

 

volatile uint32_t lptmrCounter = 0U;

 

int main(void) {

       /* Init board hardware. */

       BOARD_InitPins();

       BOARD_BootClockRUN();

       BOARD_InitDebugConsole();

 

 

       /* Add your code here */

 

       /* Create RTOS task */

       xTaskCreate(

                     task_init,

                     "Task_Init",

                     configMINIMAL_STACK_SIZE,

                     NULL,

                     task_PRIORITY,

                     NULL);

 

       vTaskStartScheduler();

 

       for(;;) { /* Infinite loop to avoid leaving the main function */

              __asm("NOP"); /* something to use as a breakpoint stop while looping */

       }

}

 

 

static void task_init(void *pvParameters) {

       for (;;) {

 

              lptmr_config_t lptmrConfig;

 

              PRINTF("You are running the initialization task.\r\n");

 

              /* Init output LED GPIO. */

              gpio_pin_config_t ledB_config = {kGPIO_DigitalOutput, 0,};

              GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PIN, &ledB_config);

              PRINTF("LED BLUE initialized \r\n");

 

              /* Configure LPTMR */

              /*

               * lptmrConfig.timerMode = kLPTMR_TimerModeTimeCounter;

               * lptmrConfig.pinSelect = kLPTMR_PinSelectInput_0;

               * lptmrConfig.pinPolarity = kLPTMR_PinPolarityActiveHigh;

               * lptmrConfig.enableFreeRunning = false;

               * lptmrConfig.bypassPrescaler = true;

               * lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_1;

               * lptmrConfig.value = kLPTMR_Prescale_Glitch_0;

               */

              LPTMR_GetDefaultConfig(&lptmrConfig);

              /* Initialize the LPTMR */

              LPTMR_Init(LPTMR0, &lptmrConfig);

              /* Set timer period */

              LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(1000000U, LPTMR_SOURCE_CLOCK));

              PRINTF("Low Power Timer module initialized \r\n");

              /* Start counting */

              LPTMR_StartTimer(LPTMR0);

 

              while (1)

              {

                     if (LPTMR_GetStatusFlags(LPTMR0) )

                     {

                           lptmrCounter++;

                           LED_BLUE_TOGGLE();

                           LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);

 

                     }

              }

       }

}

Attachments

    Outcomes