Hi Robin, I thank you for following me. I couldn't answer you before.
I'd like to give what I like to get from TPM counter.
Try If, you can, to analyze my firmware.
I'd like to obtain an high controlled pulse every xxx ms. As in the example I sent,
the TPM output must be rimain low for 5ms * times. Or 15 ms.
Then I'd like to have a pulse high where the duration is 2 ms. The TPM clock is set for 1,5 Mhz and the code of
TPM_SetupOutputCompare is a mere copy of function I found in your previous suggestion.
Is it correct the code construction to obtain this goal ?
It doesn't work as I would like.Infact if I break when the switch case is 0 I'm expecting that the TPM out is 1.
And this happens. Then when the first instruction to disable the channel in TPM_SetupOutputCompare is executed the output goes low. And I think it's correct again. Then I wait till mode change to disable channel is acknowledged and after I set the new compare mode.
In this case the new compare mode is CLEAR on compare mode again. But as soon as the instruction is executed the output goes high.
And I think it's not correct this.
When the code run it does not work properly as I'm expecting. I think I do something wrong.
Thanks
Attilio
void TPM_SetupOutputCompare(TPM_Type *base, UINT8 chnlNumber, tpm_output_compare_mode_t compareMode, uint32_t compareValue)
{
base->CONTROLS[chnlNumber].CnSC &= ~(TPM_CnSC_MSA_MASK |
TPM_CnSC_MSB_MASK |
TPM_CnSC_ELSA_MASK |
TPM_CnSC_ELSB_MASK);
/* Wait till mode change to disable channel is acknowledged */
while (0U != (base->CONTROLS[chnlNumber].CnSC & (TPM_CnSC_MSA_MASK |
TPM_CnSC_MSB_MASK |
TPM_CnSC_ELSA_MASK |
TPM_CnSC_ELSB_MASK)))
{
}
base->CONTROLS[chnlNumber].CnSC |= (uint32_t)compareMode;
base->CONTROLS[chnlNumber].CnV = (base->CONTROLS[chnlNumber].CnV + compareValue) % base->MOD ; // *** have a look here
/* Wait till mode change is acknowledged */
while (0U == (base->CONTROLS[chnlNumber].CnSC & (TPM_CnSC_MSA_MASK |
TPM_CnSC_MSB_MASK |
TPM_CnSC_ELSA_MASK |
TPM_CnSC_ELSB_MASK)))
{
}
}
void TPM0_IRQHandler(void)
{
static UINT8 ph;
UINT32 status;
status = TPM0->STATUS;
if(status & TPM_CH2_FLAG)
{
switch(ph++)
{
case 0: TPM_SetupOutputCompare(TPM0, TPM_CHANNEL_2, kTPM_ClearOnMatch, 7500); break; // 5ms
case 1: TPM_SetupOutputCompare(TPM0, TPM_CHANNEL_2, kTPM_ClearOnMatch, 7500); break; // 5ms
case 2: TPM_SetupOutputCompare(TPM0, TPM_CHANNEL_2, kTPM_ClearOnMatch, 7500); break; // 5ms
case 3:
TPM_SetupOutputCompare(TPM0, TPM_CHANNEL_2, kTPM_SetOnMatch, 3000); // 2ms
ph = 0;
break;
}
}
TPM0->STATUS = status;
}
void InitTimers(void)
{
/* TIMER 0 channels setting */
SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; // clock gating
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(0x10); // tpm clock source
TPM0->SC = TPM_SC_PS(0x04) | TPM_SC_CMOD(0x01); // prescaler divide 0x04 = 16 times
// tpm increment every tpm counter clock
TPM0->MOD = 60000; // timer period at 1,5 mhz of tpm clock = 40 ms
TPM0->CONTROLS[TPM_CHANNEL_2].CnSC = kTPM_ClearOnMatch +/
TPM_CnSC_CHIE_MASK;
TPM0->CONTROLS[TPM_CHANNEL_2].CnV = 7500; // first event after 5 ms
PORTA->PCR[5] = PORT_PCR_MUX(ALTERNATE_FUNCTION_3); // PTA5 wired to lamp
ConnectInterruptToCortex(TPM0_IRQn); // set TPM0 interrupt
}