Can we generate PWM of less than 100 Hz using Flex IO

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

Can we generate PWM of less than 100 Hz using Flex IO

4,024 Views
nitinverma
Contributor III

Dear Support Team,

We have two issues when we are configuring Flexio as PWMO.

1.We are using FRDM PK 144-100. We have a requirement to generate the PWM of 10 to 500 Hz frequency with different range of duty cycle using FLEX IO module. However We are not able to generate the frequency less than 100 Hz. We have selected SIRC as clock source for FLEX IO module and configure it with 2 Mhz(Minimum) with divisor of 64(Maximum). Please guide us to meet the requirements.

2. We observed some inaccuracy in frequency, it is deviated by 1%. Please guide if can resolve this issue as well.

Please find the attached screen shot for clock setting.

Thanks,

BR,

Nitin verma

10 Replies

2,728 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi,

The minimum PWM frequency in Dual 8-bit PWM Mode is limited with the clock on which the timer decrements.

If the timer decrements on FlexIO clock (TIMCFG [TIMDEC]), which can be min 2MHz/64, then with 8-bit counters the minimum PWM frequency is around 100Hz.

 

However, a timer output can be used to decrement any other timer. So you can have one timer in Single 16-bit counter mode TIMCTL[TIMOD] and when this timer overflows it decrements other timer in Dual 8-bit counters PWM high mode.

 

As per S32K1xx Data Sheet, the SIRC frequency deviation can be max 3%. FIRC is more precise, max 1%, typically 0.5%.

 

Regards,

Daniel

2,728 Views
nitinverma
Contributor III

Dear Deniel,

I tried out with the nesting of timers with the configuration you have mentioned in the comment abut didn't help. Probably configuration which i did is wrong. I requests if you could share some example code to configure the two flex io timers as per the above resolution.

Thanks

Nitin verma 

0 Kudos

2,728 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi,

Please try the code below.

Timer0 decrements on FlexIO clock whereas Timer1 decrements on Timer0 output.

/* Output port for Timer1 only */
 
    PCC-> PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;
    PORTD->PCR[0] |= PORT_PCR_MUX(6); // PortD0, alt function 6, FXIO_D0
 
/* FlexIO Timer 0, counter decrements on FLexIO clock */
 
    FLEXIO->TIMCFG[0] = 0x00000000;
    // [21-20] TIMDEC 00b - Decrement counter on FlexIO clock
 
    FLEXIO->TIMCMP[0] = 0x00000FFF;
 
    FLEXIO->TIMCTL[0] = 0x00000003;
    // [17-16] PINCFG 00b - Timer pin output disabled
    // [1-0]   TIMOD  11b - Single 16-bit counter mode.
 
/* FlexIO Timer 1, counter decrement on Timer0 output (both edges)  */
 
    FLEXIO->TIMCFG[1] = 0x00100000;
    // [21-20] TIMDEC 01b - Decrement counter on Trigger input (both edges)
 
    FLEXIO->TIMCMP[1] = 0x0000FFFF;  // Duty cycle 50%
 
    FLEXIO->TIMCTL[1] = 0x03430002;
    // [27-24] TRGSEL 0011b - 4*N+3 (Timer 0 trigger output = 4*0+3 = 3)
    // [23]    TRGPOL 0b    - Trigger active high
    // [22]    TRGSRC 1b    - internal trigger selected (a timer output)
    // [17-16] PINCFG 11b   - Timer pin output
    // [10-8]  PINSEL 000b  - Pin 0 as output
    // [7]     PINPOL 0b    - Pin is active high
    // [1-0]   TIMOD  10b   - Dual 8-bit counters PWM high mode.
 
/* FlexIO module  */
 
    FLEXIO->CTRL = 1;
    // [0] FLEXEN 1b - FlexIO module is enabled.

Regards,

Daniel

2,728 Views
nitinverma
Contributor III

Hi Daniel,

Thanks for your support it's working now. We wanted to generate a PWM of desired frequency and duty cycle which we could be able to generate, if we Decrements timer1 through FLEXIO clock, but when we decrements timer1 through timer0(Which decrements through FlexIO clock) it becomes complicated. We don't know how to calculate the period of Timer1.

In RM it is mentioned for TIMCMP register in PWM mode lower byte configure to high period and upper byte configure to low period but when i give 

0x00FF dutycycle of output signal is not 100% it is about 99 %.

Kindly let me know the relation between Timer 0 Value for what we configure it and desired frequency when FlexioClock is SIRC(2MHz). I need to know the frequency of input clock(output of TIMER0) Timer1 to calculate the duty cycle accurately.

Thanks Nitin

2,727 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Nitin,

Regarding the duty cycle in PWM mode, it cannot be 100% because upper 8-bits of TIMCMPn[CMP] configure the low period of the PWM output to (CMP[15:8] + 1). It means that if TIMCMPn[CMP] is set to 0x00FF, the duty cycle will be 1:256.

 

The timer 0 is a simple clock divider with a division factor that is equal to TIMCMP0[CMP + 1].

For instance, with the following configuration:

FLEXIO->TIMCMP[0] = 0x00000009;  // 2MHz / (9 + 1)     = 200kHz (5us)
FLEXIO->TIMCMP[1] = 0x00000004;  // Low  CMP[15-8] + 1 = 1      (5us)
                                 // High CMP[7-0]  + 1 = 5      (25us)

the PWM output signal:

PWM.png

Regards,

Daniel

0 Kudos

2,728 Views
nitinverma
Contributor III

Thanks Denial for your prompt response.

I am able to generate frequency from 10 hz to 500 hz. My concern is about accuracy of frequency and duty cycle of generated PWMO.

Below is the driver code for flexio configuration for PWM. Timer 1 uses FLEXIO clock(SIRC/64 = 31250 hz) for decrement  and timer0 used output of timer 1 output frequency(1000Hz) for decrement. I am not able to generate PWM with precision. At low frequencies error in frequency is about 40% (Not acceptable as per my requirements) while duty cycle is correct and at high frequencies error in duty cycles is about 25%(not acceptable) while frequency is under 10% of error(which is acceptable as per my requirements). I have to generate PWM signal of frequency 10 - 500 Hz with duty cycle 10 to 100 percent.

FLEXIO_Type *base = FLEXIO;
uint32_t lu32_vTimerValue = (uint32_t)0,lu32_vubFact=(uint32_t)0;
uint32_t lu32_vTimer1Value = (uint32_t)0;
uint16_t lu16_vCalDutycycle;

Timer 1
lu32_vTimer1Value = ((31250/2000)-1); // formula take by the link Understanding FlexIO 

// Timer1 configuration for 16bit mode, Input clock is Flexio clock(SIRC/64 = 31250)

FLEXIO_HAL_SetTimerDecrement(base, FLEXIO_TIMER1, FLEXIO_TIMER_DECREMENT_CLK_SHIFT_TMR);
FLEXIO_HAL_SetTimerCompare(base, FLEXIO_TIMER1,lu32_vTimer1Value);
FLEXIO_HAL_SetTimerPin(base, FLEXIO_TIMER1, TIMER0_PIN, FLEXIO_PIN_POLARITY_HIGH, FLEXIO_PIN_CONFIG_OUTPUT);
FLEXIO_HAL_SetTimerMode(base, FLEXIO_TIMER1, FLEXIO_TIMER_MODE_16BIT);

Timer 0

FLEXIO_HAL_SetTimerDecrement(base, FLEXIO_TIMER0, FLEXIO_TIMER_DECREMENT_TRG_SHIFT_TMR);
FLEXIO_HAL_SetTimerTrigger(base, FLEXIO_TIMER0,7, FLEXIO_TRIGGER_POLARITY_HIGH, FLEXIO_TRIGGER_SOURCE_INTERNAL);
FLEXIO_HAL_SetTimerPin(base, FLEXIO_TIMER0, TIMER1_PIN, FLEXIO_PIN_POLARITY_HIGH, FLEXIO_PIN_CONFIG_OUTPUT);
FLEXIO_HAL_SetTimerMode(base, FLEXIO_TIMER0, FLEXIO_TIMER_MODE_8BIT_PWM);


lu32_vTimerValue = (uint32_t)(1000/(100 + 1));  // Forumula to fine and tune the frequency of PWMO 
base->TIMCMP[0] = (uint32_t)(lu32_vTimerValue * (lu16_DutyCycle / 100.0f));
base->TIMCMP[0] = (uint32_t)(((base->TIMCMP[0] << 8u) |
(uint32_t)(lu32_vTimerValue * ((100 - lu16_DutyCycle) / 100.0f))));

Your guidance will be highly appreciated.

Thanks 

Nitin verma

0 Kudos

2,728 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Nitin,

Sorry for the delay.

 

Firsty let me clarify my previous answer.

Output of a timer in 16-bit counter mode divides the FlexIO clock by (CMP(15-0) + 1)  / 2. Because it toggles the output when it overflows (it is reloaded) and therefore it needs to be reloaded twice in order to complete one output period. But since the second timer in PWM mode decrements on both edges. It can be calculated as if the division factor was (CMP[15-0] + 1).

 

To your code, I think your calculation is not correct. I don’t see the point of dividing SIRC clock by 64, because 2MHz clock is convenient.

 

In my opinion, the PWM period should be always the same and only the duty cycle should change.

For instance, period 200 = ((CMP[15-8] + 1) + (CMP[7-0] + 1)).

10%: CMP[15-8] = 179 (0xB3), CMP[7-0] = 19  (0x13)

90%: CMP[15-8] = 19,  (0x13)  CMP[7-0] = 179 (0xB3)

 

Then, in order to have clock for 500Hz and 10Hz PWM, only change the value in CMP register of the timer in 16-bit counter mode.

Using 2MHz SIRC clock divided by 1:

2MHz / (CMP[19]  + 1) = 100kHz,  / 200 (PWM period) = 500Hz
2MHz / (CMP[999] + 1) = 2kHz,     / 200 (PWM period) = 10 Hz

The code for 500Hz, 90%:

FLEXIO_Type *base = FLEXIO;
FLEXIO_HAL_SetEnable(base, 0);

FLEXIO_HAL_SetTimerDecrement(base, 1, FLEXIO_TIMER_DECREMENT_CLK_SHIFT_TMR);
FLEXIO_HAL_SetTimerCompare(base, 1, 0x13); // Hex
FLEXIO_HAL_SetTimerPin(base, 1, 0, FLEXIO_PIN_POLARITY_HIGH, FLEXIO_PIN_CONFIG_OUTPUT);
FLEXIO_HAL_SetTimerMode(base, 1, FLEXIO_TIMER_MODE_16BIT);

FLEXIO_HAL_SetTimerDecrement(base, 0, FLEXIO_TIMER_DECREMENT_TRG_SHIFT_TMR);
FLEXIO_HAL_SetTimerCompare(base, 0, 0x000013B3);  // Hex
FLEXIO_HAL_SetTimerTrigger(base, 0, 7, FLEXIO_TRIGGER_POLARITY_HIGH, FLEXIO_TRIGGER_SOURCE_INTERNAL);
FLEXIO_HAL_SetTimerPin(base, 0, 1, FLEXIO_PIN_POLARITY_HIGH, FLEXIO_PIN_CONFIG_OUTPUT);
FLEXIO_HAL_SetTimerMode(base, 0, FLEXIO_TIMER_MODE_8BIT_PWM);

FLEXIO_HAL_SetEnable(base, 1);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

PWM 500Hz, 90%:

500Hz_90.png

PWM 500Hz, 10%:

500Hz_10.png

PWM 10Hz, 90%:

10Hz_90.png

PWM 10Hz, 10%:

10Hz_10.png

The lower signal is the output of the timer in 16-bit counter mode.

Please try the code.

 

Regards,

Daniel

0 Kudos

2,728 Views
nitinverma
Contributor III

Thanks Daniel for your support.

We are able generate the PWM of desired frequency and duty cycle.

But I have doubt that,
For instance, period 200 = ((CMP[15-8] + 1) + (CMP[7-0] + 1)).
10%: CMP[15-8] = 179 (0xB3), CMP[7-0] = 19 (0x13)
90%: CMP[15-8] = 19, (0x13) CMP[7-0] = 179 (0xB3)
is shown in example given by you and I am not able to understand that why you have taken period as 200.
Please guide me through this. 

0 Kudos

2,728 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Nitin,

I simply chose 200.

Regards,

Daniel

0 Kudos

2,728 Views
nitinverma
Contributor III

Thanks a lot Daniel for your prompt response. I hope the given resolution will work.

0 Kudos