IMX8MN - GPT - Capture Input mode - Detect rising or falling edge

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

IMX8MN - GPT - Capture Input mode - Detect rising or falling edge

Jump to solution
1,793 Views
Cupcake
Contributor II

Hi,

We are using an iMX8MN board with CM7 co-processor.

We have a radio chip connected to the GPT Input Capture 1 pin,

The signal from the radio chip is a pulse wave with a unknown and variable frequency.

We need to process the signal to get an array with the duration of each 0 and 1 transition

 

My idea was to use the GPT 1 in input capture mode configured to trigger an interrupt for both rising and falling edge and in the interrupt, get the duration of the bit (0/1) and store it in an array. (Should be made with DMA later..)

 

But I have some questions:

1. If we configure the GPT to trigger an interrupt for both rising/falling edge, how to know if the interrupt is triggered by a falling or rising edge ? (The SR register just contains "Input capture 1 Flag")

2. Is it normal that when the GPT is configured in restart mode the counter is not restarted when the "Input Capture event" is triggered ? (So to measure the duration of a bit we need to store the previous value ?)

3. Someone know where is defined/set the kCLOCK_IpgClk frequency ? I have something like 66666666Hz, i don't know where this value is set.

 

Here some example of code:

 

/* Freescale includes. */
#include "board.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "fsl_device_registers.h"
#include "fsl_gpio.h"
#include "fsl_clock.h"
#include "fsl_gpt.h"
#include "pin_mux.h"

volatile bool gptIsrFlag = false;


void GPT1_IRQHandler(void) {
    /* Clear interrupt flag.*/
    GPT_ClearStatusFlags(GPT1, kGPT_InputCapture1Flag);

    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
}

void main(void) {
    /* Init board hardware. */
    /* M7 has its local cache and enabled by default,
     * need to set smart subsystems (0x28000000 ~ 0x3FFFFFFF)
     * non-cacheable before accessing this address region */
    BOARD_InitMemory();

    /* Board specific RDC settings */
    BOARD_RdcInit();

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

    uint32_t previousCapture = 0;
    uint32_t captureVal = 0;
    uint32_t currentCount = 0;
    gpt_config_t gptConfig;
    gptConfig.divider = 4095;
    GPT_GetDefaultConfig(&gptConfig);
    GPT_Init(GPT1, &gptConfig);
    GPT_SetInputOperationMode(GPT1, kGPT_InputCapture_Channel1, kGPT_InputOperation_BothEdge);
    GPT_EnableInterrupts(GPT1, kGPT_InputCapture1InterruptEnable);
    EnableIRQ(GPT1_IRQn);
    GPT_StartTimer(GPT1);

    PRINTF("kCLOCK_IpgClk = %d Hz\n", CLOCK_GetFreq(kCLOCK_IpgClk));
    PRINTF("kCLOCK_PerClk = %d Hz\n", CLOCK_GetFreq(kCLOCK_PerClk));

    while (true) {
        /* Check whether occur interupt */
        if (true == gptIsrFlag) {
            captureVal = GPT_GetInputCaptureValue(GPT1, kGPT_InputCapture_Channel1);
            currentCount = GPT_GetCurrentTimerCount(GPT1);
            PRINTF("Capture value = %d, currentCount = %d, difference: %d\n", captureVal, currentCount, captureVal - previousCapture);
            previousCapture = captureVal;
            gptIsrFlag = false;
        } else {
            __WFI();
        }
    }
}

 

Labels (1)
0 Kudos
Reply
1 Solution
1,702 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

Reviewing the i.MXRT1170 of mentioned case, the reference manual of this MCU has almost the same GPT module and has the same description as i.MX8MN for restart mode of input capture so, it seems that it is recommended measure the duration between events with interruptions and calculate the difference between current and previous counter value.

Best regards.

Jorge.

View solution in original post

0 Kudos
Reply
3 Replies
1,774 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

1. If we configure the GPT to trigger an interrupt for both rising/falling edge, how to know if the interrupt is triggered by a falling or rising edge? (The SR register just contains "Input capture 1 Flag")

By the functionality of GPT input capture and status/configuration registers, it seems that there is no way to difference between rising and fall edge interrupt.

2. Is it normal that when the GPT is configured in restart mode the counter is not restarted when the "Input Capture event" is triggered? (So, to measure the duration of a bit we need to store the previous value?)

It should reset to 0x00000000 and resumes counting, by bit 9 (FRR) of GPT Control Register (GPTx_CR).

Free-Run or Restart mode.

The FFR bit determines the behavior of the GPT when a compare event in channel 1 occurs.

• In Restart mode, after a compare event, the counter resets to 0x00000000 and resumes counting (after the occurrence of a compare event).

• In Free-Run mode, after a compare event, the counter continues counting until 0xFFFFFFFF and then rolls over to 0.

0 Restart mode.

1 Free-Run mode.

Any write access to the Compare register of Channel 1 will reset the GPT counter. This is done to avoid possibly missing a compare event when compare value is changed from a higher value to lower value while counting is proceeding.

If you still having this issue, you could use GPT Input Capture Register to take the value that was in the counter during the last capture event.

3. Someone know where is defined/set the kCLOCK_IpgClk frequency ? I have something like 66666666Hz, i don't know where this value is set.

The peripheral clock it is part of the Arm Cortex-M7 Clocks (working at 66MHz) and the GPT has a 12-bit prescaler, which provides a programmable clock frequency derived from multiple clock sources.

You can change this on GPT Prescaler Register (GPTx_PR): The GPT Prescaler Register (GPT_PR) contains bits that determine the divide value of the clock that runs the counter.

I hope it helps.

Best regards.

Jorge

0 Kudos
Reply
1,736 Views
Cupcake
Contributor II

Concerning the point #2, are you sure that it works like this in "Input Capture" mode ?

This is also what I understand when I read the docs, but in the reality it doesn't seems to work like this.

--> For me "Restart Mode" is not working when we use the input capture mode and I was asking to get a confirmation.

 

For exemple I see a post going in this direction but for another processor:

https://community.nxp.com/t5/i-MX-Processors/Reset-GPT-Counter-of-IMXRT-on-Capture-Event/m-p/1588556...

 

Attached you will find a software example to reproduce what I say, and the logs related to this example.

  • In this example the restart mode is used and we display the ICR1 & CNT registers of the GPT (to display the last event count and current count).
  • I start this example on a board and I was playing the input capture pin (setting it to 3v3)
  • In the logs we can see that the CNT is always increasing and the ICR1 is also always increasing

 

So, is this a normal situation ?

0 Kudos
Reply
1,703 Views
JorgeCas
NXP TechSupport
NXP TechSupport

Hello,

Reviewing the i.MXRT1170 of mentioned case, the reference manual of this MCU has almost the same GPT module and has the same description as i.MX8MN for restart mode of input capture so, it seems that it is recommended measure the duration between events with interruptions and calculate the difference between current and previous counter value.

Best regards.

Jorge.

0 Kudos
Reply