Can we Change FTM Mod value Simultaneously

cancel
Showing results for 
Search instead for 
Did you mean: 

Can we Change FTM Mod value Simultaneously

Jump to solution
821 Views
sujinvincent
Contributor II

Hi all,

I am Using kinetis K26 uc

For my application i am using FTM0 Channel 0 and Channel 1 for Beep soung generation. 

I need to Generate different frequency PWM signals on both channels Simultaneously. is that FTM module support for this?

thanks and Regards,

Sujin

0 Kudos
1 Solution
235 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

The FTM0_C0V and FTM0_C1V can be used to generate different duty cycle PWM signals.
The Channel 0 and Channel 1 share the same FTM0_MOD register, so you can't generate different frequency PWM signals on both channels Simultaneously.
Please try to use different FTM modules.

Best Regards,

Robin

 

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

View solution in original post

6 Replies
236 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

The FTM0_C0V and FTM0_C1V can be used to generate different duty cycle PWM signals.
The Channel 0 and Channel 1 share the same FTM0_MOD register, so you can't generate different frequency PWM signals on both channels Simultaneously.
Please try to use different FTM modules.

Best Regards,

Robin

 

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

View solution in original post

235 Views
sujinvincent
Contributor II

thank you

I got your point

so let me ask you one thing, we can't able to generate different frequencies on different channels of FTM_0 Module then what is the use of multiple channels in same FTM module.

I think It can only useful to generate PWM signals for motor applications

Thanks and Regards,

Sujin Vincent

0 Kudos
235 Views
egoodii
Senior Contributor III

If the 'overall rate' of FTM-generated edges you need is 'tolerable' (say less than 100K/s overall) then you can always go the 'timer banged sequence generation' route.  That is, like 'bit banged I/O' firmware sets each edge, BUT in the case of 'timer-banged' generation the timer-hardware precisely places each edge for you, AND your firmware only has to respond to the high-priority interrupt that the 'latest edge time has been consumed' to set up the NEXT edge event, then return to 'normal' work.  It is easiest if you let the base FTM counter free-run (MOD FFFF), then just use 16-bit unsigned math to calculate from each 'previous edge' to 'next edge' based on the next timing requirement.  This is used 'all the time' to 'fake' another UART TX (RX too, but that is a little harder) but certainly can be used to make ANY firmware-calculatable sequence.

0 Kudos
235 Views
sujinvincent
Contributor II

I couldn't get you

are you telling we can generate different frequencies?

0 Kudos
235 Views
egoodii
Senior Contributor III

Absolutely!!!   ---well, within reason!   I haven't had occasion to run this kind of process on Kinetis yet, but have done so 'many times' on S08, and the timer-peripheral is (for better or worse) 'very similar'.

Firstly, you run the FTM's channels in 'output compare' mode, table 45-3 in K26 RM, '01 01' -- for this generation, 'toggle output' is probably sufficient here; for other waveform generation you may want to force 'one' or 'zero' on the next time-compare.

Let's say you run FTM at 10MHz, with MOD of course at 0xFFFF (152.6Hz overflow rate) --- said FTM frequency is a tradeoff between frequency-resolution and lowest-possible frequency being >= 1/2 overflow rate.  And let's further posit that you want (at this time) to make 2400Hz and 2800Hz.  That makes for 4800 edges and 5600 edges, otherwise defined then as 2083 'counts' between edges for 2400.4Hz, 1786 for 2799.5Hz.  So then you have (in-psuedo-code) an ISR like this:

FTM0_IRQHandler()

{

if(channel 0 interrupt)

  clear interrupt; ////FTM0_C0SC &= ~FTM_CnSC_CHF_MASK;

  FTM0_C0V = FTM0_C0V+2083;

if(channel 1 interrupt)

  clear interrupt;

  FTM0_C1V = FTM0_C1V+1786;

}

Your time-counts would surely be 'pre-calculated unsigned-16bit variables' somewhere, not the shown constants, but that is the idea.  It MIGHT be faster to have a uint16_t static-var that keeps the running-timer-count for each channel, like FTM_ch0_next_count += Freq0_count; then just write that to FTM0_C0V, as the process to fetch the peripheral-register is slower than RAM-access (but causes a second global-address-load-instruction and two back-to-back write-ops, so maybe NOT faster??? Interesting...).

This interrupt MUST be allowed to be serviced faster than your lowest half-period, else the 'time for the next event' will already have 'passed' when you get here, meaning this 'simple math' will delay the next edge one whole FTM overflow.  This is easiest to achieve if said FTM channel is the highest-level interrupt, and never disabled.   See also my priority-comments in:

https://community.nxp.com/message/872684?commentID=872684#comment-872684 

As for overhead, we might guess this IRQ to take a microsecond or so, so for our combined 10,400 edges/s we take ~1% of the CPU for these two examples.

FWIW, this is an S08 interrupt-handler for full timer-banged-UART-waveform generation (of a fixed-size 8-byte message):

#define BAUDRATE (1000000/38400)       //uS per bit, assume 8MHz Busclk and /8 prescale
            /* TPMC0SC: CH1F=0,CH1IE=1,MS0B=0,MS0A=1,ELS0B=1,ELS0A=1,??=0,??=0--to set a 'one' */
#define MARK  0xD8   ////SC values for INVERTED UART waveform (mark=0V, space=Vdd)
#define SPACE 0xDC

static uint8_t serbyte;                          //Byte currently going out serial stream
static uint8_t ser_bit_cnt;                      //Bit count within said byte
static uint8_t ser_byte_cnt;                     //Count within total stream

enum SIOState {SIO_Idle, SIO_SendStrt, SIO_SendByte,
    SIO_SendStop, SIO_WaitIdle} SIO_State=SIO_Idle;

ISR (Tim1_OutComp)

{
    (void)TPMC1SC;
    /* TPMC0SC: CH0F=0 */
    clrReg8Bits(TPMC1SC, 0x80);                   /* Reset compare interrupt request flag */

    if( SIO_State != SIO_Idle )
    {
        setReg16(TPMC1V, TPMC1V+BAUDRATE);        /* 'Default' Compare 1 value for next bit */
        if( SIO_State == SIO_SendByte )
        {
            if( (serbyte & 0x01) == 0x01 )        //Set up for next bit
                setReg8(TPMC1SC, MARK);
            else
                setReg8(TPMC1SC, SPACE);
            serbyte >>= 1;
            ser_bit_cnt--;
            if( ser_bit_cnt == 0 )
            {
                SIO_State = SIO_SendStop;
                setReg8(TPMC1SC, MARK);

            }
        }else if( SIO_State == SIO_SendStop )
        {
            if( ser_byte_cnt != 8 )
            {
                SIO_State = SIO_SendByte;
            
                setReg8(TPMC1SC, SPACE);
                ser_byte_cnt++;
                serbyte = ValidData[ser_byte_cnt];
                ser_bit_cnt = 9;
            }else
            {
                SIO_State = SIO_WaitIdle;
                setReg16(TPMC1V, TPMCNT+1000);    //Wait 1ms from now for 'Idle'
            }
        }else if( SIO_State == SIO_WaitIdle )
        {
                if( ser_byte_cnt != 8 )
                    SIO_State = SIO_SendStop;         //Start up bit stream next bit time
                else
                {
                    SIO_State = SIO_Idle;
                    KBISC_KBIE = 1;                   //Start looking for input edges
                    PTAD_PTAD4 = 0;                   //Re-enable debug port serial
                }
        }
    }else
    {
        setReg16(TPMC1V, TPMCNT+127);     //Wait another while of 'nothing'
    }
}

235 Views
egoodii
Senior Contributor III

Did this 'timer-banged' process get you the waveforms you needed?

0 Kudos