I am trying to generate a 38kHz square wave using the MK20DN512VLL10's FTM0 module running under MQX (I don't think MQX would make any difference). The purpose of this is to send out a modulated IR signal for object detection.
The code that I'm using is (and was validated in AN5142 as well as a number of posts on the community forum here):
// Enable Flex Timer Clock
SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK;
FTM0_SC = 0; // Make sure FTM0 is off before writing to it
FTM0_MODE |= FTM_MODE_WPDIS_MASK; /* Disable write protection */
FTM0_MODE |= FTM_MODE_FTMEN_MASK;
FTM0_CONF |= FTM_CONF_BDMMODE(3); // counter run in BDM mode
FTM0_CNTIN = 0x00;
FTM0_CNT = 0; // Reset Counter
FTM0_MOD = 48000000 / 38000; // Set PWM frequency; MODULO = Fclk/Fpwm
FTM0_C7SC |= FTM_CnSC_MSB_MASK; // Set FTM0 Channel 7 Operation
FTM0_C7SC |= FTM_CnSC_ELSB_MASK;
FTM0_C7SC &= ~FTM_CnSC_ELSA_MASK;
FTM0_C7V = FTM0_MOD / 2; // THIS SHOULD BE A 50% duty Cycle
// Status and Control bits
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
PORTD_PCR7 |= PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK; // FTM0 CH7 - high power operation
The PWM period is perfect but the duty cycle is above 77% (Period is 26.4us and the High part of the signal is 20.4us).
I'm taking the period value and dividing it by two - anybody see where my problem is?
Thanx,
myke
Here's another data point:
I tried manually setting the compare value (FTM0_C7V) and discovered that the change in terms of the PWM isn't linear. The timing values (measured on an oscilloscope) I got are:
FTM0_C7V | Period (us) | PWM High (us) | PWM Low (us) | C7V / PWM High |
---|---|---|---|---|
631 | 26.4 | 20.4 | 6.0 | 0.032330 |
300 | 26.4 | 13.6 | 12.8 | 0.045333 |
275 | 26.4 | 13.2 | 13.2 | 0.048000 |
250 | 26.4 | 12.4 | 14 | 0.049600 |
It looks like the PWM counter/Compare module (FTM0_C7V & "output modes logic") is getting a different clock from the "FTM counter" and the "FTM0_MOD" register. This doesn't make any sense when I look at the FTM block diagram (Figure 38-1) in the K20P100M100SF2V2RM (Reference Manual) documentation - I'm looking at Rev. 2 Jun 2012 which is the current at NXP.com.
Any ideas what's going on here? In the short term, I know what gives me a 50% duty cycle (FTM0_C7V = 275) but this doesn't make sense according to the documentation, other posts and example code.
Hi myke,
Have you try to observe the register value during debug in CodeWarrior11?
For example:FTM0_C7V and FTM0_MOD and FTM0_C7SC
Seems you have select EPWM:
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hai,
Am using MC9S08SG8 micro controller ,and am using code warrior V6.3 software ,here am using PWM in 7th pin ,
my problem is in output duty cycle first pulse is grater then the other pulse ,like this. plz any one can help me.
Hi Robin,
Thank you for the reply. Yes, I am verifying the register values using CW.
I did use that table from the Reference Manual for setting up the PWM and the bits you highlighted have been set with the three lines:
FTM0_C7SC |= FTM_CnSC_MSB_MASK; // Set FTM0 Channel 7 Operation
FTM0_C7SC |= FTM_CnSC_ELSB_MASK;
FTM0_C7SC &= ~FTM_CnSC_ELSA_MASK;
When I check the FTM0_C7SC register in CW, I see the MS7B = 1, ELS7B = 1 & ELS7A = 0.
Thanx again.
The easiest way to get a 50% duty cycle is to choose Output Compare mode and configure it Toggle Output on match.
Please try to use this mode first.
You'd better to give me the register value screen capture, so that I can check if the register of FTM is correct or not.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hey Robin,
Sorry for taking a few days to reply - I had a busy weekend and start to the new week (and I'm not even celebrating Thanksgiving).
As requested, here are the register values, taken as screen shots from CW 11:
Let's start with FTM0_COMBINE (which includes DECAPEN# & COMBINE):
- DECAPEN# - All Bits Reset
- COMBINE# - All Bits Reset
Now, the documentation says that this is for "n = 6" - do I want for "n = 7" as I'm using FTM0_C7?
For FTMO_SC:
- Bit 5 CPWMS (Center-Aligned PWM Select) - Reset which is what we want
Next is FTMO_C7SC:
Using the datasheet:
Bit 5 - MSB (Channel Mode Select) - Set which is what we want
Bit 4 - MSA (Channel Mode Select) - Reset as it is a don't care for this application of the FTM
Bit 3 - ELSB (Edge or Level Select) - Set which is what we want
Bit 2 - ELSA (Edge or Level Select) - Reset which what we want for this application (ELSB:ELSA = 1:0 is "Clear Output on Match)
Any comments? Other than the DECAPEN/COMBINE confusion regarding using them for FTMO_C7, I think I'm good.
myke
If you want to get 50% duty PWM when FTM0_MOD=0x4ef, you should configure FTM0_C7V=0x277
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Robin,
Totally agree with what you're saying but...
When I run with the original values with the register set up and manually writing in 0x113:
I get the waveform:
Now, when I put in the expected 50% duty cycle value (0x277 as you noted) with the registers:
I get the waveform:
I'm sure there's something that I'm doing wrong, but for the life of me, I can't figure out what it is.
Any ideas?
myke
Hi Myke
I just set up a uTasker project on a K20, running at 96MHz (as yours, with 48MHz bus clock):
PWM_INTERRUPT_SETUP pwm_setup;
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.int_handler = 0;
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_1 | PWM_EDGE_ALIGNED); // clock PWM timer from the system clock with /1 pre-scaler
pwm_setup.int_handler = 0; // no user interrupt call-back on PWM cycle
pwm_setup.pwm_reference = (_TIMER_0 | 7); // timer module 0, channel 7
pwm_setup.pwm_frequency = PWM_FREQUENCY(38000, 1); // generate 1000Hz on PWM output
pwm_setup.pwm_value = _PWM_PERCENT(50, pwm_setup.pwm_frequency); // 50% PWM (high/low)
fnConfigureInterrupt((void *)&pwm_setup); // enter configuration for PWM test on PTD7
I measured then 38kHz on PTD7 and 50% mark-space.
These are all the FTM0 registers
(I also had an output on channel 2 but ignore that).
I notice you have a very slow falling edge on your output but it my be due to loading you have.
I don't know whether it helps in any way but the setting above give the expected output.
Regards
Mark
Hi Mark,
Thank you for your reply.
Here are my registers:
The differences between your values and mine are listed in the table below:
Register | Mark Value | Myke Value | Comments |
---|---|---|---|
FTM0_MOD | 0x4EE | 0x4EF | FTM Count Register/No issue |
FTM0_C2SC | 0xA8 | FTM0_C4SC/FTM0_C5SC: 0x28 | Comparing to my _C4SC & _C5SC which have not run yet |
FTM0_STATUS | 0xA4 | 0xA0 | Mark's value indicates that Channel 2 has overflowed |
FTM0_MODE | 4 | 5 | Myke has FTM Enable Active |
So, unless the FTM Enable bit affects things, I think I have exactly the same operating environment as you do - comments?
Finally, I'm scoping at the anode of an IR LED which is driven by a variable current supply, so the rounded edges when the signal goes low isn't that much of a surprise.
Thanx for the comparison point - maybe something will come of it!
myke
Nobody has commented in a while. Anybody with any ideas?
Thanx!
Myke
FTM EN just allows the extended mode registers (those that the FlexTimer has but the TPM doesn't) to be used and shouldn't have any effect for basic PWM operation.
I have used the TPM and Flex Timers on most Kinetis part and can't reproduce your problem so I am wondering whether it is coming from another part of the system or due to some measurement strangeness (?)
If you do need it solved I offer a professional service via Remote Desktop. There is a 40 minute free session which would probably do it, so there wouldn't be any complications with having to find funding. If you prefer directly at NXP they also do a service where you can trial direct support for 2 hours for $500.-
Regards
Mark
Hi Mark,
Have you worked with the MK20DN512VLL10 and its FTM0? I'm wondering if this is a peculiarity of the part because what I'm seeing doesn't make sense (and it doesn't matter where I probe it).
I will kick this back to my FAE and see if NXP has any ideas.
Thanx,
myke
Hi Myke
I specifically tested on a K20FX512VLQ12 and a K60DN512VMD10, whereby both should be equivalent to your part with regards to FTM0 and clocks, with the second essentially identical if Ethernet is not used.
If you tell me your clock source (oscillator or crystal and which crystal loading) and the pin your FTM0 output is on I can also give you a binary to try with on any part (unlike when using the NXP libraries I can build for any part without needing to port anything).
These are the mainstream boards that I have (plus I also have a lot of boards from industrial product developments which have some variations): http://www.utasker.com/kinetis.html
Regards
Mark
Hi Mark,
I smiled at the phrase "should be equivalent". I've been in this game to know that "should be" doesn't mean necessarily - I don't think either one of those components use the same die.
Clock source is a Crystal 8MHz with 18pF caps and a 1M resistor. The clocking mode is "High Gain". Figure 26-4 of the Reference Manual shows the circuit used.
Please send me your code and I'm going to try them on my TWR and Freedom boards (as well as with my code).
Thanx,
myke
Please check the attached project.
See also the registers value and the waveform of IR on TWR-K40D100M.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Myke
I have attached a binary file that I hope will run on the MK20DN512VLL10, driven by 8MHz crystal in high gain mode.
I configured for 96MHz PLL with 48MHz bus clock with a toggling output on PTC10 (pin 82) at 2.5Hz as a heat beat (to signal life).
There should be a 50% PWM signal on FTM0_CH7 (on PTD7 - pin 100). [FlexTimer clocked from bus clock with no pre-scaler to give the same values as you]
Since I don't have exact HW for this I simulated it only (see below) and the results look OK and your K20 matches closely to the 100 pin K60DN512 (which I set as major config).
Assuming that you can load a binary and it operates you can then check the output to see whether there is the unexpected mark-space or whether it is 50%.
Good luck
Regards
Mark
P.S: I don't know of any K20 tower or freedom board with your processor on.
P.P.S. I changed the attached file on 19.12.2018 at 17:16 because I had used the wrong linker script the first time....
Additional data point.
I *thought* that I could single step through the code (in "Instruction Stepping Mode") and see the FTM0_CNT register increment but this doesn't seem to work (I'm using a Segger debug tool and this is MQX 4.0.1 running in CW 11).
Any other ideas as where I can look to understand what's happening?