Monday, July 5, 2021

Software timers and Ring Buffered UART Com for Kinetis K82 MCU

In this article, I would like discuss about using Kinetis K82 MCU with MCUXpresso IDE. I will use FRDM-K82F development board as a hardware platform. Setting up environment for K82 development is discussed in previous article at the following link.

http://cool-emerald.blogspot.com/2020/01/getting-started-with-frdm-k82f.html



SDK Example

Let us start with MCUXpresso's SDK example 'led_blinky' using FRDM K82 development board. Click 'Import SDK example(s)' in the lower left pane, choose frdmk82f SDK, and click next as shown in the following figure.


Figure. Importing SDK example.


Then choose 'led_blinky' and click 'Finish'. The example blinks red LED using SysTick. I will rename the project as "K82_Tmr_Com" by clicking on the project and choose rename.

Soft Timers

Software timers are easy to implement. I have developed sotware timer module called "ceTmr" as an simplified alternative to software timer provided by FreeRTOS. You first need to copy "ceTmr.h" and "ceTmr.c" into source folder. They are available at the following repository.

https://github.com/yan9a/k82/tree/main/K82_Tmr_Com/source

To use the software timer:
  • Include the header file ceTmr.h

    #include "ceTmr.h"
    


  • Set Systick configuration to enable Syttick timer at desired interval

    // Set systick reload value to generate 1ms interrupt
    if (SysTick_Config(SystemCoreClock / 1000U)) { while (1) { } }
    


  • Define callback function to execute at timeout

    void sby_led_to(void){
    	GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
    }
    


  • Create the timer by calling "ceTmrCreate" with interval, setting argument for oneshot as false to use autoreload timer, and callback

    ceTmr_t* sbyLED = ceTmrCreate(500,false,sby_led_to);
    


  • Start the timer by calling "ceTmrStart"

    ceTmrStart(sbyLED); // start the standby led timer
    


  • And calling "ceTmrTask" in the main loop

    while (1)
    {
        ceTmrTask();
    }
    


If you want to use other timer tick function instead of SysTick handler, you can modified the following line in ceTmr.h.

#define ceTmrTick SysTick_Handler // define timer tick function


The maximum number of timers can be defined there also.

#define CE_TMR_MAX_NUMBER 10 // maximum number of timer


The resulting main file is as follows.

// Project: K82_Tmr_Com
// Author: Yan Naing Aye
// Description: K82 software timer 

#include "board.h"
#include "pin_mux.h"
#include "ceTmr.h"
#define BOARD_LED_GPIO     BOARD_LED_RED_GPIO
#define BOARD_LED_GPIO_PIN BOARD_LED_RED_PIN

void sby_led_to(void){
	GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
}

int main(void)
{
    BOARD_InitPins();
    BOARD_InitBootClocks();
    //-----------------------------------------------------------------------------
    // Init software timer
    // Set systick reload value to generate 1ms interrupt
    if (SysTick_Config(SystemCoreClock / 1000U)) { while (1) { } }
    // create timer with interval 500 ms, not oneshot, call back function 'sby_led_to'
    ceTmr_t* sbyLED = ceTmrCreate(500,false,sby_led_to);
    ceTmrStart(sbyLED); // start the standby led timer
    //-----------------------------------------------------------------------------
    while (1)
    {
        ceTmrTask();
    }
    //-----------------------------------------------------------------------------
}


Com

Next thing I would like to discuss is using ring buffered UART communication module which I developed. It is called 'ceCom' and it provides functions to use all the UARTs on K82 in non-blocking way. As an example, I will demonstrate using UART4 which is the com port attached to OpenSDA USB port on FRDM-K82 development board. Copy "ceCom.h" and "ceCom.c" into source folder. They are available at the following repository, the same one mentioned above.

https://github.com/yan9a/k82/tree/main/K82_Tmr_Com/source

To use ceCom:
  • Include the header file ceCom.h

    #include "ceCom.h"
    


  • Define callback function which will called everytime a character is received. The function name is ceComOnRx0 for UART0, ceComOnRx1 for UART1, etc. In this example, we will echo back the character.

    void ceComOnRx4(uint8_t b)
    {
    	ceComPutch(4,b);
    }
    


  • Initialize the module by calling "ceComInitialize". You can customized UART configuration such as pins, baud rate, etc. in ceCom.c.

      // Init UART
      ceComInitialize();
    


  • Transmitting can be performed by calling functions defined in ceCom.h such as ceComPrint with respective UART number.

    ceComPrint(4,"Hello\n");
    


  • And calling "ceComTask" in the main loop

    while (1)
    {
        ceComTask();
    }
    


The resulting main file implementing both ceTmr and ceCom is shown below.

// Project: K82_Tmr_Com
// Author: Yan Naing Aye
// Description: K82 software timer and com example

#include "board.h"
#include "pin_mux.h"
#include "ceTmr.h"
#include "ceCom.h"
#define BOARD_LED_GPIO     BOARD_LED_RED_GPIO
#define BOARD_LED_GPIO_PIN BOARD_LED_RED_PIN

void sby_led_to(void){
	GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN);
}

void ceComOnRx4(uint8_t b)
{
	ceComPutch(4,b);
}

int main(void)
{
    BOARD_InitPins();
    BOARD_InitBootClocks();
    //-----------------------------------------------------------------------------
    // Init software timer
    // Set systick reload value to generate 1ms interrupt
    if (SysTick_Config(SystemCoreClock / 1000U)) { while (1) { } }
    // create timer with interval 500 ms, not oneshot, call back function 'sby_led_to'
    ceTmr_t* sbyLED = ceTmrCreate(500,false,sby_led_to);
    ceTmrStart(sbyLED); // start the standby led timer
    //-----------------------------------------------------------------------------
    // Init UART
    ceComInitialize();
    ceComPrint(4,"Hello\n");
	//-----------------------------------------------------------------------------
    while (1)
    {
        ceTmrTask();
        ceComTask();
    }
    //-----------------------------------------------------------------------------
}



The purpose of this article is to provide simple, light weight, easy to implement timer and communication modules which can be easily modified to be used on similar MCUs.

References

[1] Cool Emerald. Circular Buffered UART Com Module for 8051 Microcontroller. 2010 Jun 10.
url: http://cool-emerald.blogspot.com/2010/06/circular-buffered-uart-com-module-for.html.



No comments:

Post a Comment

Comments are moderated and don't be surprised if your comment does not appear promptly.