QE8 TPMxMOD update in TOF ISR?

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

QE8 TPMxMOD update in TOF ISR?

979 Views
iansmusical
Contributor V

Hi Everyone,

 

I am refering to design reference DRM093.PDF which uses an AW60 and have shown only the code of interest below:

 

void TIMER1_TOF_ISR(void) {

    byte dummy_read;

       ...

    if (ModifyFreq){

    TPM1MOD = ColorTMOD[Freq];    <---------------- defined as a word array

    }

    ...

  dummy_read = TPM1SC;          

  TPM1SC_TOF =0; // clear TOF flag

}

 

I have created the same interrupt with the following init code for an QE8:

 

TPM1C2V = 0x0;

TPM1MOD = 33333 - 1;

TPM1C2SC = 0x3C; // edge PWM

TPM1SC = 0x4B; // Prescaler 8, bus clock

 

However, if with ModifyFreq set and ColorTMOD[Freq] containing a 16 bit value, say 5000 decimal, TPM1MOD doesn't update with the new value. I have tried writing it as two 8 bit values, high then low but TPM1MOD still doesn't update.

 

Does anyone have any ideas please?

 

Thanks very much in advance,

 

Ian

Labels (1)
Tags (4)
6 Replies

757 Views
eduardo_viramon
NXP Employee
NXP Employee

Ian,

QE8 has TPMv3 (as opposed to TPMv2 in AW60) a critical difference in these two versions is a latching mechanism added to the modulo and channel value registers. When they are written, the value is actually latched in a buffer and later updated to the actual register when the timer counter reaches the last count. This mechanism is there to prevent glitches in PWM duty cycle or frequency updates, in other words, the value will in fact become updated, on the next period. More info in the reference manual:

Capture.PNG.png

Also notice that you can override this latching mechanism by temporarily turning off the timer clock CLKSB and A = 0, updating and turning them back on.

/Eduardo

757 Views
iansmusical
Contributor V

Hi Eduardo,

Thank you for your answer. I had noticed about v2 and v3 but didn't realise the differences were the latching mechanism. I had also read section 16.3.3 a few times and felt that as I'm using the bus clock, CLKSB (0) and CLKSA (1) would therefore be not cleared and thus the update would naturally occur via the latching mechanism when the counter changes from max - 1 to max. This I haven't seen occur or is it additionally necessary to write to TPMxSC or temporarily turn off the timer clock, as you suggested to defeat the latching mechanism?

Thank you again,

Ian

0 Kudos

757 Views
eduardo_viramon
NXP Employee
NXP Employee

How are you verifying that the module value is written? Are you reading back the register or through a measurement of the output frequency?

If you are reading, are you reading with the BDM active (in other words, are you debugging at the same time?), the parargraph just below the screenshot I posted before explains that in BDM active mode, the latch is frozen, so if you are reading with BDM, you would read back the first value.

I also noticed that your initialization includes writing a zero to the channel value, this would mean that your output stays on all the time (as you have low-true pulses), you would have no way of determining frequency through  the oscilloscope.

/Eduardo

0 Kudos

757 Views
iansmusical
Contributor V

Hi Eduardo,

Firstly let me add some detail. I'm using the DEMOQE board and although the channel value is initially zero it actually is set in the TOF interrupt via a 12 bit ADC value. I realise the ADC value doesn't span the full 16 bit timer range but I'm just experimenting at the moment.

I am verifying that the TPMxMOD value is written via the BDM and understand that the latch is frozen while the BDM is active. However, having let the code run for a few periods after and having paused execution to look at the TPMxMOD register, it still shows the old value and therefore isn't automatically updating. I of course could apply the procedures that you mentioned in the last reply for testing purposes but the automatic update should occur according to 16.3.3?

I have attached my experimental project for your reference.

Thanks for your continued help.

Ian

0 Kudos

757 Views
eduardo_viramon
NXP Employee
NXP Employee

Ian, are you actually waiting enough clock counts? Remember you have a preescaler of 8, with a modulo of 3332 you basically have to wait up to 3332 * 8 = 26656 bus clock cycles for the value to be latched. It might actually be easier if you write a while loop with an if inside that compares the new and old Modulo value and enter once it's different, put a breakpoint inside.

Lastly, notice that the BDM driver does not necessarily update variables and register. Make sure that either you've configured it for automatic periodic updates or click on refresh once you've stopped the code running.

/Eduardo

0 Kudos

757 Views
iansmusical
Contributor V

Hi Eduardo,

Apologies for my delay in replying to you. I believe I was waiting enough bus clock cycles based on letting the code run for several seconds before breaking and viewing the registers. I will try as you suggest of using a while loop etc and making sure I force an update of the registers. At the moment though the method of stopping the bus clock to the TPM module that you suggested, changing the MOD value and then re-enabling the bus clock has sufficed for my testing needs.

Thanks for all your support,

Ian