K64F PWM

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

K64F PWM

2,139 Views
gerhardheinzel
Contributor I

I am using the FRDM-K64F evaluation board since a while, and have achieved already a lot with it, using the SD card, two UARTS in parallel, USB, numerous GPIOs etc. It is a remarkable piece of hardware, especially considering the low price which is important for me in a university environment which will not buy 100000 pieces, and therefore I am quite grateful for it and the software that comes with it.  The new SDK2 is so-so, too formal and too many levels of #defines for my taste, but ok. But now I am really struggling with the Pulse Width Modulation (PWM) on the Timer Module. My job is comparatively simple, I want to use FTM3 channels 0+1 in combined mode to produce an asymmetric PWM, and channels 2+3 for another PWM at the same base frequency but different duty cycle. I would not have thought that this is so difficult.

All examples that I found use interrupts, which I don't want to do, there will be more than enough interrupts in the final application and a PWM should really work without them.

There is no sample program in the SDK (as opposed to most other modules), only the "bubble.c" which apparently also uses interrupts.

The SDK functions do not work.

Trying to set the registers directly brought me a little further, after I found out that I have to enable a certain well-hidden clock first, which I found out only by serious debugging but not after reading several time Chapter 40 ("FlexTimer Module") of the chip manual. The SDK documentation is unreadable for humans in that respect. Most registers seem to be set ok now by directly setting bits with hex numbers, avoiding the SDK. But still I cannot set the most relevant ones, the FTM3_CnV registers that are supposed to hold the thresholds. I have no clue whether this is due to the mysterious WPDIS and WPEN bits which are described as bit 2 of the FTMx_MODE register :

WPDIS Write Protection Disable

When write protection is enabled (WPDIS = 0), write protected bits cannot be written. When write

protection is disabled (WPDIS = 1), write protected bits can be written. The WPDIS bit is the negation of

the WPEN bit. WPDIS is cleared when 1 is written to WPEN. WPDIS is set when WPEN bit is read as a 1

and then 1 is written to WPDIS. Writing 0 to WPDIS has no effect.

0 Write protection is enabled.

1 Write protection is disabled.

and as bit 6 in the FTMx_FMS register:

WPEN Write Protection Enable

The WPEN bit is the negation of the WPDIS bit. WPEN is set when 1 is written to it. WPEN is cleared

when WPEN bit is read as a 1 and then 1 is written to WPDIS. Writing 0 to WPEN has no effect.

0 Write protection is disabled. Write protected bits can be written.

1 Write protection is enabled. Write protected bits cannot be written.

This is highly confusing. But maybe I am also doing something wrong with the PWM SYNC features which are equally confusing and even less described.

I would be very grateful if you could point me to a working example of "combined mode" PWM operation without interrupts.

Tags (2)
0 Kudos
6 Replies

1,361 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Gerhard,

Can you tell me the exactly issue that confused you currently, please clarify it.

And you can find the ftm.c according to the Fig 1 illustrates.

2016-06-27_10-54-49.jpg


Have a great day,
Ping

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

0 Kudos

1,361 Views
gerhardheinzel
Contributor I

Hi Jeremy,

thanks for your patience and help.

I cannot see the attachment, see below.

As for the confusion, I don't remember all the mistakes I made until it finally ran, but here are a few things I remember:

- the discussion about the WPDIS and WPEN bits is very confusing

- It took me a while untile I found out (by tracing through the SDK code) that I need not only to turn on the FTM and set the Pin Mux functions, but also to call "CLOCK_EnableClock(kCLOCK_Ftm3);"    I did not find this anywhere in the FTM chapter.

- The description of the Sync mechanism is very confusing in the chip manual, I find. For example,

I think I first tried setting somewhat less bits in

FTM->SYNC = 0x0BU; // SYNCHOM,CNTMAX,CNTMIN

  FTM->SYNCONF = 0xFB4U; // enhanced sync mode, software sync

which failed. The description of the bits in  the SYNC and the SYNCONF registers is not easy to understand, some information seems to redundant in two places, for example "output mask synchronization", and how to enable the synchronization at all, e.g. PWMSYNC bit FTM->MODE and several other places that refer to each other in a circular fashion. It also took me a while to understand that the SWSYNC bit in the FTM->SYNC register does not enable or select the software trigger, but actually triggers it, once. And I could not find the  http://tinyurl.com/j462hf4 document before I came here and a kind person here pointed me to it; that would have been helpful as well.

With best greetings,

Gerhard

dump.jpg

0 Kudos

1,361 Views
bobpaddock
Senior Contributor III

This forum software has issues.

To see the attachment you must be logged in then click on the heading at the very top of the thread to expand the thread completely, then you see attachments.

0 Kudos

1,361 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Gerhard,

As you said "My job is comparatively simple, I want to use FTM3 channels 0+1 in combined mode to produce an asymmetric PWM, and channels 2+3 for another PWM at the same base frequency but different duty cycle." If you want to generate asymmetric PWM signal using FTM_CH0 and FTM_CH1, it seems that it is impossible.

You can use two pair of FTM channels, FTM_CH0/1 works in combined/complementary mode, FTM_CH2/3 works in combined/complementary mode, in this mode, the FTM_CH0/1 are complementary signals, FTM_CH2/3 are complementary signals, the FTM_CH0 and FTM_CH2 can implement so-called asymmetric PWM signals because both rising/fallinf edges of both FTM_CH0 and FTM_CH2 can be set independently.

You can download an5142 from the website, it has the example code to implement the asymmetric PWM signals.

http://tinyurl.com/j462hf4

The FTM.c has the example code to use combined mode as JmereZhou said, it is helpful, you can refer to it.

BR

XiangJun Rong

0 Kudos

1,361 Views
gerhardheinzel
Contributor I

Thanks. I could not find the FTM.c attachment, but in the meantime with lots of trial and error I have something that runs. I could not manage to achieve this with the SDK functions, and some of the necessary settings are not documented (or at least I could not find them). So here is the code, maybe it helps others:

int pwm_init(uint32_t f)

{

    float clk = (float) CLOCK_GetFreq(kCLOCK_BusClk);

    float modmax = 65530., fmod;

    uint16_t fms, prescale, prescale_bits;

    /* set prescaler 1...128 */

    for (prescale_bits = 0U; prescale_bits <= 8U; prescale_bits++)

    {

        prescale = 1U << prescale_bits;

        fmod = clk / prescale / (float) f;

        if (fmod < modmax)

            break;

    }

    if (prescale_bits > 7 || fmod < 100.)

    {

        PRINTF("no valid prescaler found\r\n");

        return 1;

    }

    CLOCK_EnableClock(kCLOCK_Ftm3);

    fms = PWM_FTM->FMS;

    if (fms & 0x40U) // write protection enabled

        PWM_FTM->MODE = 0x5U; // WPDIS=1, FTMEN=1

    else

        PWM_FTM->MODE = 0x1U; // don't touch WPDIS=1, FTMEN=1

    PWM_FTM->CNTIN = 0x0U; // start from zero

    PWM_FTM->CNT = 0x0U; // set this before setting MOD

    PWM_FTM->MOD = (uint32_t) floor((double) fmod - 0.5); // round(fmod-1.0)

    PWM_FTM->OUTINIT = 0x0FU; // High=inactive as default

    PWM_FTM->OUTMASK = 0x0U; // all unmask // ghh

    PWM_FTM->POL = 0x0U; // no inversion

    PWM_FTM->COMBINE = 0x2121U; // Combine 0+1 and 2+3

    PWM_FTM->SYNC = 0x0BU; // SYNCHOM,CNTMAX,CNTMIN

    PWM_FTM->SYNCONF = 0xFB4U; // enhanced sync mode, software sync

    PWM_FTM->PWMLOAD = 0x20FU; // Enable updates

    PWM_FTM->CONTROLS[0].CnSC = 0x4U; // low active

    PWM_FTM->CONTROLS[1].CnSC = 0x0U;

    PWM_FTM->CONTROLS[2].CnSC = 0x4U; // low active

    PWM_FTM->CONTROLS[3].CnSC = 0x00U;

    PWM_FTM->CONTROLS[4].CnSC = 0x00U;

    PWM_FTM->CONTROLS[5].CnSC = 0x00U;

    PWM_FTM->CONTROLS[6].CnSC = 0x00U;

    PWM_FTM->CONTROLS[7].CnSC = 0x00U;

    PWM_FTM->CONTROLS[0].CnV = 0x0U;

    PWM_FTM->CONTROLS[1].CnV = (PWM_FTM->MOD)/10;

    PWM_FTM->CONTROLS[2].CnV = ((PWM_FTM->MOD)/10)*5;

    PWM_FTM->CONTROLS[3].CnV = ((PWM_FTM->MOD)/10)*6;

    PWM_FTM->SC = 0x08U | prescale_bits; // clock=system, starts timer

    return 0;

}

void pwm_set_duty(float x1, float x2)

{

...

    PWM_FTM->CONTROLS[0].CnV = start1;

    PWM_FTM->CONTROLS[1].CnV = end1;

    PWM_FTM->CONTROLS[2].CnV = start2;

    PWM_FTM->CONTROLS[3].CnV = end2;

    PWM_FTM->SYNC = 0x80U; // Trigger Software Sync

}

0 Kudos

1,361 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Gerhard,

Thanks for your interest in NXP Semiconductor products and the opportunity to serve you.

I've attached the FTM.c which includes various kinds of the FTM function and the all functions are implemented by set the register directly.

Hope it helps.
Have a great day,
Ping

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

0 Kudos