AnsweredAssumed Answered

TPM K27 - CnSC register updating on output compare mode

Question asked by attilio rossi on Nov 27, 2019
Latest reply on Dec 3, 2019 by attilio rossi

Hi, I'd like to generate a pwm with output compare mode on TPM in the FRDMK27 board.

I want to do this, without using the pwm function mode. It works fine.

I want to do this by output compare mode.

In this condition seem to be impossible to update the CnSC register to move the output pin high or low.

Only simply, I want to change the output with different timing

I show my simple code.

Can someone check this ?

 

Thanks.

Attilio

 

// init timer

void InitTimers(void)
{
    SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK;                                        // clock gating
    SIM->SOPT2 |= SIM_SOPT2_TPMSRC(0x10);                                    // tpm clock source

 

    TPM0->SC  = TPM_SC_PS(0x07) | TPM_SC_CMOD(0x01);             // prescaler divide 0x07 = 128 times
                                                                                                                   // tpm increment every tpm counter clock

 


    TPM0->MOD = (UINT32)65535;                                                      // timer period value

 

    TPM0->CONTROLS[TPM_CHANNEL_2].CnSC = 0x00 +\
                                         TPM_CnSC_CHIE_MASK          +\
                                         TPM_CnSC_MSA_MASK           +\
                                         TPM_CnSC_ELSB_MASK         +\
                                         TPM_CnSC_ELSA_MASK;                               // out comp. set

 

    TPM0->CONTROLS[TPM_CHANNEL_2].CnV  = 5000;                         // first match after ~27ms

 

    PORTA->PCR[5] = PORT_PCR_MUX(ALTERNATE_FUNCTION_3);      // PTA5 wired to lamp
    ConnectInterruptToCortex(TPM0_IRQn);                                                 // set TPM0 interrupt
}

 

// int.handler

void TPM0_IRQHandler(void)
{
    static    UINT8        counter, break_test;
            UINT16        cnV;
            UINT32      cnsC, status;
            TPM_Type    *tim = TPM0;

 


    status = tim->STATUS;

 

    // OVERFLOW
    if(status & TPM_OVERFLOW_COUNTER)
    {
        break_test = 1;
    }

 

    // CH2
    if(status & TPM_CH2_FLAG)
    {
        tim->CONTROLS[TPM_CHANNEL_2].CnSC |= 0x80;      // flag reset

 

        cnsC = tim->CONTROLS[TPM_CHANNEL_2].CnSC;
        cnV  = tim->CONTROLS[TPM_CHANNEL_2].CnV;


        if(counter++ & 0x01)
        {    // next match clear
            cnsC &= ~TPM_CnSC_ELSA_MASK;                           // change
            cnV  = (cnV + 2000);
        }
        else
        {    // next match set
            cnsC |=  TPM_CnSC_ELSA_MASK;                           // change
            cnV  = (cnV + 15000);
        }
        tim->CONTROLS[TPM_CHANNEL_2].CnV  = cnV;            // update regs
        tim->CONTROLS[TPM_CHANNEL_2].CnSC = cnsC;
    }
    tim->STATUS |= status;                                                   // flag reset
}

Outcomes