i.MXRT1020 FlexIO for PWM dithering

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

i.MXRT1020 FlexIO for PWM dithering

Jump to solution
1,513 Views
SatPDG
Contributor II

Hi,

I am developing a firmware for an application on the i.MXRT1020. The MCU need to generate a PWM with a frequency that is changing over time. The PWM frequency is changing in the order of the following list : [300kHz, 333kHz, 375kHz, 400kHz].

To achieve this, I am using the FlexIO that is generating the PWM and I am using the PIT to generate an interrupt at 10Hz to change the frequency of the PWM. When I check the output of the PWM on a oscilloscope, I see only 2 frequency one after one (the 333kHz and the 400kHz or the 300kHz and the 375kHz). When I lower the PIT frequency to 1Hz, I see the four frequency one after one with some glitch in the cycle (sometimes, the 333kHz is skipped, etc.). The time the frequency is display on the oscilloscope, for both PIT frequency, always follow the PIT period.

It seems to me that the problem is from the fact that the value of the compare register in the peripheral is not updated... I setted the Fast Access bit to 1 in the FlexIO but that does not helped. I made sure the frequency of the FlexIO clock was fast enough. Something make the peripheral not always updating it's intern register... Is there something I am missing?

You have a sample of my code right here :

 

 

const int Periods[4] = {300000, 333333, 375000, 400000};
const int DutyCycle[4] = {50, 50, 50, 50};
int pwmDitheringIdx = 0;

void PWMModule_InitPWM()
{
  // Init mux pin
  IOMUXC_SetPinMux(IOMUXC_PIN_PAD, 0U);
  IOMUXC_SetPinConfig(IOMUXC_PIN_PAD, 0x10B0u);
  
  // Init flexio
  CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); // Select USB1 PLL CLK
  CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1);
  CLOCK_SetDiv(kCLOCK_Flexio1Div, 1);
  
  flexio_config_t fxioUserConfig;
  FLEXIO_GetDefaultConfig(&fxioUserConfig);
  fxioUserConfig.enableFastAccess = true;
  FLEXIO_Init(PWM_FLEXIO, &fxioUserConfig);
  
  flexio_timer_config_t fxioTimerConfig;
  fxioTimerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0U);
  fxioTimerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
  fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  fxioTimerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
  fxioTimerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
  fxioTimerConfig.pinSelect       = PWM_PIN; /* Set pwm output */
  fxioTimerConfig.timerMode       = kFLEXIO_TimerModeDisabled;
  fxioTimerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
  fxioTimerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
  fxioTimerConfig.timerDisable    = kFLEXIO_TimerDisableNever;
  fxioTimerConfig.timerEnable     = kFLEXIO_TimerEnabledAlways;
  fxioTimerConfig.timerReset      = kFLEXIO_TimerResetNever;
  fxioTimerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
  fxioTimerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;
  fxioTimerConfig.timerCompare = computeTimerCompare(frequency, dutyCycle);
  FLEXIO_SetTimerConfig(PWM_FLEXIO, 0, &fxioTimerConfig);

  // Init Timer
  PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, (24000000 / DITHERING_FREQUENCY) - 1);
  PIT_EnableInterrupts(PIT, kPIT_Chnl_1, kPIT_TimerInterruptEnable);
  EnableIRQ(PIT_IRQn);
}

void PIT_IRQHandler(void)
{
  // Stop pwm
  PWM_FLEXIO->TIMCTL[0] &= 0xFFFFFFFC;
  // Update the frequency of the flexio.
  PWM_FLEXIO->TIMCMP[0] = FLEXIO_TIMCMP_CMP(computeTimerCompare(Periods[pwmDitheringIdx], DutyCycle[pwmDitheringIdx]));
  
  // Start pwm
  PWM_FLEXIO->TIMCTL[0] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitPWM);
  
  pwmDitheringIdx = (pwmDitheringIdx + 1) % NUMBER_OF_FREQUENCY;
  
  // Clear IRQ flags
  PIT_ClearStatusFlags(PIT, kPIT_Chnl_1, kPIT_TimerFlag);
}

int computeTimerCompare(unsigned int frequency, unsigned int dutyCycle)
{
  //The clock of the FLEXIO Timer[0] is the PLL3 (USB1) clock divided by the predivisor+1 (4+1) and the divisor (7+1)
  //The number of timer count (sum) required to generate the desired period is Timer[0]_Clock/[Desired Frequency]
  unsigned int sum = ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / (1 + 1U) / (1 + 1U)) * 2 / frequency + 1) / 2;        //...*2+1)/2 -> Round to nearest
  
  //In 8-bit PWM high mode, the lower 8-bits configure the high period of the output to (CMP[7:0] + 1) and
  //the upper 8-bits configure the low period of the output to (CMP[15:8] + 1).
  //low/high period is the number of timer count where to output is low/high.
  //PWM output is hardware inverted...
  unsigned int lowerValue = (sum * dutyCycle / 50 + 1) / 2;
  unsigned int upperValue = sum - lowerValue;
  return ((upperValue -1) <<  | (lowerValue - 1);
}

 

 

 

Labels (1)
0 Kudos
1 Solution
1,449 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Sorry for the reply late.
After several rounds of investigation, I find the root cause is missing the __DSB in the PIT_IRQHandler(void), the modified code is attached below, you can give a try again.

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

#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_flexio.h"
#include "board.h"
#include "fsl_pit.h"

#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define DEMO_TIME_DELAY_FOR_DUTY_CYCLE_UPDATE (2000000U)
#define DEMO_FLEXIO_BASEADDR FLEXIO1
#define DEMO_FLEXIO_OUTPUTPIN (5U) /* Select FLEXIO1_FLEXIO05 as PWM output */
#define DEMO_FLEXIO_TIMER_CH (0U)  /* Flexio timer0 used */

/* Select USB1 PLL (480 MHz) as flexio clock source */
#define FLEXIO_CLOCK_SELECT (3U)
/* Clock pre divider for flexio clock source */
#define FLEXIO_CLOCK_PRE_DIVIDER (4U)
/* Clock divider for flexio clock source */
#define FLEXIO_CLOCK_DIVIDER (7U)
#define DEMO_FLEXIO_CLOCK_FREQUENCY \
    (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / (FLEXIO_CLOCK_PRE_DIVIDER + 1U) / (FLEXIO_CLOCK_DIVIDER + 1U))
/* FLEXIO output PWM frequency */
#define DEMO_FLEXIO_FREQUENCY (48000U)
#define FLEXIO_MAX_FREQUENCY (DEMO_FLEXIO_CLOCK_FREQUENCY / 2U)
#define FLEXIO_MIN_FREQUENCY (DEMO_FLEXIO_CLOCK_FREQUENCY / 256U)

/* Get source clock for PIT driver */
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_OscClk)
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief Configures the timer as a 8-bits PWM mode to generate the PWM waveform
 *
 * @param freq_Hz PWM frequency in hertz, range is [FLEXIO_MIN_FREQUENCY, FLEXIO_MAX_FREQUENCY]
 * @param duty Specified duty in unit of %, with a range of [1, 99]
 */
static void flexio_pwm_init(uint32_t freq_Hz, uint32_t duty);

/*!
 * @brief Enables the timer by setting TIMOD to 8-bits PWM and start generating the PWM
 */
static void flexio_pwm_start(void);

/*******************************************************************************
 * Variables
 *******************************************************************************/
unsigned int idx = 0;
uint32_t freq[4] = {50000,48000,300000,400000};
/*******************************************************************************
 * Code
 ******************************************************************************/
static void flexio_pwm_init(uint32_t freq_Hz, uint32_t duty)
{
    assert((freq_Hz < FLEXIO_MAX_FREQUENCY) && (freq_Hz > FLEXIO_MIN_FREQUENCY));

    uint32_t lowerValue = 0; /* Number of clock cycles in high logic state in one period */
    uint32_t upperValue = 0; /* Number of clock cycles in low logic state in one period */
    uint32_t sum        = 0; /* Number of clock cycles in one period */
    flexio_timer_config_t fxioTimerConfig;

    /* Check parameter */
    if ((duty > 99) || (duty == 0))
    {
        duty = 50;
    }

    /* Configure the timer DEMO_FLEXIO_TIMER_CH for generating PWM */
    fxioTimerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0U);
    fxioTimerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
    fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
    fxioTimerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
    fxioTimerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
    fxioTimerConfig.pinSelect       = DEMO_FLEXIO_OUTPUTPIN; /* Set pwm output */
    fxioTimerConfig.timerMode       = kFLEXIO_TimerModeDisabled;
    fxioTimerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
    fxioTimerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
    fxioTimerConfig.timerDisable    = kFLEXIO_TimerDisableNever;
    fxioTimerConfig.timerEnable     = kFLEXIO_TimerEnabledAlways;
    fxioTimerConfig.timerReset      = kFLEXIO_TimerResetNever;
    fxioTimerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
    fxioTimerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;

    /* Calculate timer lower and upper values of TIMCMP */
    /* Calculate the nearest integer value for sum, using formula round(x) = (2 * floor(x) + 1) / 2 */
    /* sum = DEMO_FLEXIO_CLOCK_FREQUENCY / freq_H */

    sum = (DEMO_FLEXIO_CLOCK_FREQUENCY * 2 / freq_Hz + 1) / 2;
    PRINTF("\r\n freq_Hz is %d,sum is %d\r\n",freq_Hz,sum);
    /* Calculate the nearest integer value for lowerValue, the high period of the pwm output */
    /* lowerValue = sum * duty / 100 */
    lowerValue = (sum * duty / 50 + 1) / 2;
    /* Calculate upper value, the low period of the pwm output */
    upperValue                   = sum - lowerValue;
    fxioTimerConfig.timerCompare = ((upperValue - 1) << 8U) | (lowerValue - 1);
    PRINTF("\r\n fxioTimerConfig.timerCompare is %d\r\n",fxioTimerConfig.timerCompare);

    FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASEADDR, DEMO_FLEXIO_TIMER_CH, &fxioTimerConfig);

}

static void flexio_pwm_start(void)
{
    /* Set Timer mode to kFLEXIO_TimerModeDual8BitPWM to start timer */
    DEMO_FLEXIO_BASEADDR->TIMCTL[DEMO_FLEXIO_TIMER_CH] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitPWM);
}

/*!
 * @brief Main function
 */
int main(void)
{
    uint32_t i;
    uint32_t duty = 100;
    flexio_config_t fxioUserConfig;

    /* Init board hardware */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* Clock setting for Flexio */
    CLOCK_SetMux(kCLOCK_Flexio1Mux, FLEXIO_CLOCK_SELECT);
    CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, FLEXIO_CLOCK_PRE_DIVIDER);
    CLOCK_SetDiv(kCLOCK_Flexio1Div, FLEXIO_CLOCK_DIVIDER);

    /* Init flexio, use default configure
     * Disable doze and fast access mode
     * Enable in debug mode
     */
    FLEXIO_GetDefaultConfig(&fxioUserConfig);
    FLEXIO_Init(DEMO_FLEXIO_BASEADDR, &fxioUserConfig);

    // Init Timer
    CLOCK_SetMux(kCLOCK_PerclkMux, 1U); // Take the osc clock source 24MHz
    CLOCK_SetDiv(kCLOCK_PerclkDiv, 0U); // divide the clock by 1
    pit_config_t pitConfig;
    PIT_GetDefaultConfig(&pitConfig);
    PIT_Init(PIT, &pitConfig);
    PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, USEC_TO_COUNT(1000000U, PIT_SOURCE_CLOCK));
    PIT_EnableInterrupts(PIT, kPIT_Chnl_1, kPIT_TimerInterruptEnable);
    EnableIRQ(PIT_IRQn);
    PIT_StartTimer(PIT, kPIT_Chnl_1);

    PRINTF("\r\nFLEXIO_PWM demo start.\r\n");
    flexio_pwm_init(freq[idx], 50);
    flexio_pwm_start();
    while (1)
    {
//        flexio_pwm_init(DEMO_FLEXIO_FREQUENCY, --duty);
//        flexio_pwm_start();

//        for (i = 0; i < DEMO_TIME_DELAY_FOR_DUTY_CYCLE_UPDATE; i++)
//        {
//            __NOP();
//        }

//        if (duty == 0)
//        {
//            duty = 100;
//        }
    }
}




void PIT_IRQHandler(void)
{
  PIT_ClearStatusFlags(PIT, kPIT_Chnl_1, kPIT_TimerFlag);
  idx = (idx + 1) % 4;
  PRINTF("\r\n idx is %d\r\n",idx);
  flexio_pwm_init(freq[idx], 50);
  flexio_pwm_start();

  /* Added for, and affects, all PIT handlers. For CPU clock which is much larger than the IP bus clock,
   * CPU can run out of the interrupt handler before the interrupt flag being cleared, resulting in the
   * CPU's entering the handler again and again. Adding DSB can prevent the issue from happening.
   */
  //__DSB();
}


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

0 Kudos
5 Replies
1,507 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
To provide the fastest possible support, I'd highly recommend you refer to the flexio3_pwm in the SDK library to modify both frequency and duty of output PWM.
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,502 Views
SatPDG
Contributor II

Hi,

Thank you for your answer. The code I wrote is based upon the flexIO PWM example in the SDK. This morning I modify the flexIO PWM example. I had the same problem. The frequency output of the flexIO was always 50kHz and 48kHz back and forth or 300kHz and 400kHz, but never 50k, 300k, 48k and 400k as I would expect... You can try it be yourself, the code in the attach is exactly the main of the flexIO pwm project with some modifications.

Thank you

 

0 Kudos
1,450 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Sorry for the reply late.
After several rounds of investigation, I find the root cause is missing the __DSB in the PIT_IRQHandler(void), the modified code is attached below, you can give a try again.

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

#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_flexio.h"
#include "board.h"
#include "fsl_pit.h"

#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define DEMO_TIME_DELAY_FOR_DUTY_CYCLE_UPDATE (2000000U)
#define DEMO_FLEXIO_BASEADDR FLEXIO1
#define DEMO_FLEXIO_OUTPUTPIN (5U) /* Select FLEXIO1_FLEXIO05 as PWM output */
#define DEMO_FLEXIO_TIMER_CH (0U)  /* Flexio timer0 used */

/* Select USB1 PLL (480 MHz) as flexio clock source */
#define FLEXIO_CLOCK_SELECT (3U)
/* Clock pre divider for flexio clock source */
#define FLEXIO_CLOCK_PRE_DIVIDER (4U)
/* Clock divider for flexio clock source */
#define FLEXIO_CLOCK_DIVIDER (7U)
#define DEMO_FLEXIO_CLOCK_FREQUENCY \
    (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / (FLEXIO_CLOCK_PRE_DIVIDER + 1U) / (FLEXIO_CLOCK_DIVIDER + 1U))
/* FLEXIO output PWM frequency */
#define DEMO_FLEXIO_FREQUENCY (48000U)
#define FLEXIO_MAX_FREQUENCY (DEMO_FLEXIO_CLOCK_FREQUENCY / 2U)
#define FLEXIO_MIN_FREQUENCY (DEMO_FLEXIO_CLOCK_FREQUENCY / 256U)

/* Get source clock for PIT driver */
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_OscClk)
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief Configures the timer as a 8-bits PWM mode to generate the PWM waveform
 *
 * @param freq_Hz PWM frequency in hertz, range is [FLEXIO_MIN_FREQUENCY, FLEXIO_MAX_FREQUENCY]
 * @param duty Specified duty in unit of %, with a range of [1, 99]
 */
static void flexio_pwm_init(uint32_t freq_Hz, uint32_t duty);

/*!
 * @brief Enables the timer by setting TIMOD to 8-bits PWM and start generating the PWM
 */
static void flexio_pwm_start(void);

/*******************************************************************************
 * Variables
 *******************************************************************************/
unsigned int idx = 0;
uint32_t freq[4] = {50000,48000,300000,400000};
/*******************************************************************************
 * Code
 ******************************************************************************/
static void flexio_pwm_init(uint32_t freq_Hz, uint32_t duty)
{
    assert((freq_Hz < FLEXIO_MAX_FREQUENCY) && (freq_Hz > FLEXIO_MIN_FREQUENCY));

    uint32_t lowerValue = 0; /* Number of clock cycles in high logic state in one period */
    uint32_t upperValue = 0; /* Number of clock cycles in low logic state in one period */
    uint32_t sum        = 0; /* Number of clock cycles in one period */
    flexio_timer_config_t fxioTimerConfig;

    /* Check parameter */
    if ((duty > 99) || (duty == 0))
    {
        duty = 50;
    }

    /* Configure the timer DEMO_FLEXIO_TIMER_CH for generating PWM */
    fxioTimerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0U);
    fxioTimerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
    fxioTimerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
    fxioTimerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
    fxioTimerConfig.pinPolarity     = kFLEXIO_PinActiveHigh;
    fxioTimerConfig.pinSelect       = DEMO_FLEXIO_OUTPUTPIN; /* Set pwm output */
    fxioTimerConfig.timerMode       = kFLEXIO_TimerModeDisabled;
    fxioTimerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
    fxioTimerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
    fxioTimerConfig.timerDisable    = kFLEXIO_TimerDisableNever;
    fxioTimerConfig.timerEnable     = kFLEXIO_TimerEnabledAlways;
    fxioTimerConfig.timerReset      = kFLEXIO_TimerResetNever;
    fxioTimerConfig.timerStart      = kFLEXIO_TimerStartBitDisabled;
    fxioTimerConfig.timerStop       = kFLEXIO_TimerStopBitDisabled;

    /* Calculate timer lower and upper values of TIMCMP */
    /* Calculate the nearest integer value for sum, using formula round(x) = (2 * floor(x) + 1) / 2 */
    /* sum = DEMO_FLEXIO_CLOCK_FREQUENCY / freq_H */

    sum = (DEMO_FLEXIO_CLOCK_FREQUENCY * 2 / freq_Hz + 1) / 2;
    PRINTF("\r\n freq_Hz is %d,sum is %d\r\n",freq_Hz,sum);
    /* Calculate the nearest integer value for lowerValue, the high period of the pwm output */
    /* lowerValue = sum * duty / 100 */
    lowerValue = (sum * duty / 50 + 1) / 2;
    /* Calculate upper value, the low period of the pwm output */
    upperValue                   = sum - lowerValue;
    fxioTimerConfig.timerCompare = ((upperValue - 1) << 8U) | (lowerValue - 1);
    PRINTF("\r\n fxioTimerConfig.timerCompare is %d\r\n",fxioTimerConfig.timerCompare);

    FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASEADDR, DEMO_FLEXIO_TIMER_CH, &fxioTimerConfig);

}

static void flexio_pwm_start(void)
{
    /* Set Timer mode to kFLEXIO_TimerModeDual8BitPWM to start timer */
    DEMO_FLEXIO_BASEADDR->TIMCTL[DEMO_FLEXIO_TIMER_CH] |= FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitPWM);
}

/*!
 * @brief Main function
 */
int main(void)
{
    uint32_t i;
    uint32_t duty = 100;
    flexio_config_t fxioUserConfig;

    /* Init board hardware */
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* Clock setting for Flexio */
    CLOCK_SetMux(kCLOCK_Flexio1Mux, FLEXIO_CLOCK_SELECT);
    CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, FLEXIO_CLOCK_PRE_DIVIDER);
    CLOCK_SetDiv(kCLOCK_Flexio1Div, FLEXIO_CLOCK_DIVIDER);

    /* Init flexio, use default configure
     * Disable doze and fast access mode
     * Enable in debug mode
     */
    FLEXIO_GetDefaultConfig(&fxioUserConfig);
    FLEXIO_Init(DEMO_FLEXIO_BASEADDR, &fxioUserConfig);

    // Init Timer
    CLOCK_SetMux(kCLOCK_PerclkMux, 1U); // Take the osc clock source 24MHz
    CLOCK_SetDiv(kCLOCK_PerclkDiv, 0U); // divide the clock by 1
    pit_config_t pitConfig;
    PIT_GetDefaultConfig(&pitConfig);
    PIT_Init(PIT, &pitConfig);
    PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, USEC_TO_COUNT(1000000U, PIT_SOURCE_CLOCK));
    PIT_EnableInterrupts(PIT, kPIT_Chnl_1, kPIT_TimerInterruptEnable);
    EnableIRQ(PIT_IRQn);
    PIT_StartTimer(PIT, kPIT_Chnl_1);

    PRINTF("\r\nFLEXIO_PWM demo start.\r\n");
    flexio_pwm_init(freq[idx], 50);
    flexio_pwm_start();
    while (1)
    {
//        flexio_pwm_init(DEMO_FLEXIO_FREQUENCY, --duty);
//        flexio_pwm_start();

//        for (i = 0; i < DEMO_TIME_DELAY_FOR_DUTY_CYCLE_UPDATE; i++)
//        {
//            __NOP();
//        }

//        if (duty == 0)
//        {
//            duty = 100;
//        }
    }
}




void PIT_IRQHandler(void)
{
  PIT_ClearStatusFlags(PIT, kPIT_Chnl_1, kPIT_TimerFlag);
  idx = (idx + 1) % 4;
  PRINTF("\r\n idx is %d\r\n",idx);
  flexio_pwm_init(freq[idx], 50);
  flexio_pwm_start();

  /* Added for, and affects, all PIT handlers. For CPU clock which is much larger than the IP bus clock,
   * CPU can run out of the interrupt handler before the interrupt flag being cleared, resulting in the
   * CPU's entering the handler again and again. Adding DSB can prevent the issue from happening.
   */
  //__DSB();
}


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,441 Views
SatPDG
Contributor II

Hi,

Thank you for your answer. It works. I made some test on my own. I think that the problem is that the store instruction, that clear the interrupt flag, was made at the end of the interruption. The interruption was finished before the store could be made and then the interruption was start another time. When I add the __DSP instruction, the MCU wait for the store to be complete before ending the interruption. That could explain my problem.

Thank you.

0 Kudos
1,490 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
It seems a bit weird, I'll give it a try later.
And I'd highly recommend you to use the logic analyzer to capture a period of output PWM, it can help us to figure out what exactly happens.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos