i.MX 8M EVK : how to calculate the frequency values for a 1ms timer ?

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

i.MX 8M EVK : how to calculate the frequency values for a 1ms timer ?

Jump to solution
604 Views
martindenion
Contributor II

Hello,
I want to implement a simple "GPT" timer that generates an interrupt every 1ms.
However, I get an interrupt exactly every 3ms (instead of the desired 1ms).

Where is my error? What values should I set to get a 1ms timer?

Here is my calculation for the GPT timer:

/* EXPLANATION OF TIMER VALUES */
/*
* We take for source clock the PLL1 DIV2 400MHz
* We define the root divisor at 4 => 400MHz / 4 = 100MHz
*
* 100MHz = one increment every 10ns
* We want an interrupt to be generated every 1 ms
* So we have :
* Output_compare_value = delay_time x GPT_frequency
* 1
* Output_compare_value = 1 x 10^-3 x ---------- = 100
* 10 x 10^-9
*/

Here is my code (I change the state of a GPIO at each interrupt to check the operation of my timer on the oscilloscope):

 

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_gpt.h"
#include "fsl_gpio.h"

#include "fsl_common.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define GPT_IRQ_ID  GPT1_IRQn
#define EXAMPLE_GPT GPT1
//#define EXAMPLE_GPT_CLK_FREQ                                                                \
//    (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootGpt1)) / \
//     (CLOCK_GetRootPostDivider(kCLOCK_RootGpt1)) / 2) /* SYSTEM PLL1 DIV2 */
#define EXAMPLE_GPT_CLK_FREQ	100000
#define EXAMPLE_GPT_IRQHandler GPT1_IRQHandler

#define EXAMPLE_LED_GPIO     GPIO3
#define EXAMPLE_LED_GPIO_PIN 23U

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

volatile bool gptIsrFlag = false;
/* The PIN status */
volatile bool g_pinSet = false;

/*******************************************************************************
 * Code
 ******************************************************************************/
void EXAMPLE_GPT_IRQHandler(void)
{
    /* Clear interrupt flag.*/
    GPT_ClearStatusFlags(EXAMPLE_GPT, kGPT_OutputCompare1Flag);

    gptIsrFlag = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping
  exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U)
    __DSB();
#endif
}

/*!
 * @brief Main function
 */
int main(void)
{
    uint32_t gptFreq;
    gpt_config_t gptConfig;

    /* Define the init structure for the output LED pin*/
    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};

    /* Board pin, clock, debug console init */
    /* Board specific RDC settings */
    BOARD_RdcInit();

    BOARD_InitBootPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    BOARD_InitMemory();

    CLOCK_SetRootMux(kCLOCK_RootGpt1, kCLOCK_GptRootmuxSysPll1Div2); /* Set GPT1 source to SYSTEM PLL1 DIV2 400MHZ */
    CLOCK_SetRootDivider(kCLOCK_RootGpt1, 1U, 4U);                   /* Set root clock to 400MHZ / 4 = 100MHZ */

    GPT_GetDefaultConfig(&gptConfig);

    /* Initialize GPT module */
    GPT_Init(EXAMPLE_GPT, &gptConfig);

    /* Divide GPT clock source frequency by 3 inside GPT module */
    GPT_SetClockDivider(EXAMPLE_GPT, 1);

    /* Get GPT clock frequency */
    gptFreq = EXAMPLE_GPT_CLK_FREQ;

    /* GPT frequency is divided by 3 inside module */
    gptFreq /= 1;

    /* Set both GPT modules to 1 second duration */
    GPT_SetOutputCompareValue(EXAMPLE_GPT, kGPT_OutputCompare_Channel1, gptFreq);

    /* Enable GPT Output Compare1 interrupt */
    GPT_EnableInterrupts(EXAMPLE_GPT, kGPT_OutputCompare1InterruptEnable);

    /* Enable at the Interrupt */
    EnableIRQ(GPT_IRQ_ID);

    PRINTF("\r\nPress any key to start the example");
    GETCHAR();

    /* Init output LED GPIO. */
    GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);

    /* Start Timer */
    PRINTF("\r\nStarting GPT timer ...");
    GPT_StartTimer(EXAMPLE_GPT);

    while (true)
    {
        /* Check whether occur interupt and toggle LED */
        if (true == gptIsrFlag)
        {
            PRINTF("\r\n GPT interrupt is occurred !");
            gptIsrFlag = false;
            if (g_pinSet)
            {
                GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
                g_pinSet = false;
            }
            else
            {
                GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
                g_pinSet = true;
            }
        }
        else
        {
            __WFI();
        }
    }
}

 

0 Kudos
1 Solution
588 Views
martindenion
Contributor II

I found out what my problem was with the timer. The truth is that all my values were fine, but it was the execution of the logging that was taking time (line PRINTF("GPT interrupt is occurred !");) So I could have lowered my reload value even more, but I would still have the logging that was taking time to run.

View solution in original post

0 Kudos
1 Reply
589 Views
martindenion
Contributor II

I found out what my problem was with the timer. The truth is that all my values were fine, but it was the execution of the logging that was taking time (line PRINTF("GPT interrupt is occurred !");) So I could have lowered my reload value even more, but I would still have the logging that was taking time to run.

0 Kudos