Hello,
I'm trying to use create a BPSK signal using the TPM timers on the KL03. I have used the TPM1 CH0 and CH1 timers to create the two different phases of signal with edge-aligned PWM. This works fine. I now want to use an interrupt on TPM0 to shift the phase of one of the two outputs. I can set-up the interrupt without issue, but all of my attempts at trying to shift the phase have failed. Primarily, I have been trying to get the phase to shift by changing the ELSB:ELSA pins on the TPM1 channel inside the TPM0 interrupt service routine, but this seems to have no effect. I'm assuming that I'm misunderstanding the meaning of this paragraph from the user's manual:
Can you explain? Does it mean that it will not change the mode until the counter goes to zero? If so, which counter in my case? TPM1 or TPM0?
Is there any other way to change the phase of a TPM output signal?
Thanks,
Sara
已解决! 转到解答。
It is not the TPM counters that are the issue.
The ARM CPU Core and the TPM are running from different clock sources and they must be synchronized when communicating between them.
/*
* Channel must first be disabled and this must be acknowledged
* in the TPM counter clock domain:
*/
clk_timeout_u32 = CLOCK_TIMEOUT_SET;
do{
--clk_timeout_u32;
TPM_CxSC = TPM_CnSC_CHF_MASK; /* Clear the channel flag by writing '1' */
TPM_CxSC = 0UL; /* Disable */
}while( (0U != (TPM_CxSC & ~TPM_CnSC_CHF_MASK)) && (0U != clk_timeout_u32) ); /* Wait for match */
Set up new TPM values here...
Hi Bob,
I have tried this and it works as expected. However, I have noted that when I shift the phase, there is a discontinuity in time which will ultimately screw up the phase of my BPSK output. Is there another way to shift the phase of a TPM output?
Thanks,
Sara
Take a look at the Global Time Base (GTB) option (if the 03 has it, I'm more familiar with the 27).
Without using GTB there is no guarantee that the TPM0 and TPM1 are in any way synchronized.
Without knowing more about your set up I don't know if that is important.
It may also be possible to do something with the event triggers.
I use this format to play Nokia Ring Tones. Via using DMA the various clock latencies and synchronizations are taken care of at the hardware level:
* Alarm sound sequence are done by pointing DMA at first sound sequence in tone table.
* When the end of that table is reached a DMA IRQ happens that loads the PIT silence timer.
* When the PIT silence timer expires it loads next DMA tone sequence.
*
* DMA -> PIT -> DMA -> PIT sequence repeates until the last state is
* reached in the state-machine that starts it all over again.
Doing something alone that line will probably lead to less phase discontinuity.
Hi Bob,
I'm not very familiar with the global time base. My understanding is that it will clock all the TPM channels together and keep the synchronized. Does this mean that I can then go about changing the phase of one of the TPM channels in the same way I was doing before (stopping the timer, disabling it, changing the ELSA bit, then restarting it again) and I won't have any weird "blips"?
Can you explain more about event triggers. I'm not sure what you mean.
Thanks,
Sara
Stopping the counter and restarting is certain to have phase anomalies.
Look for a way to anticipate the coming change.
Direct Digital Synthesizer (DDS) such as used in BPSK31 in the many open source packages might be worth looking into.
As to trigger events:
"
Trigger Select Selects the input trigger to use for starting, reloading and/or pausing the counter. The source of the trigger (external or internal to the TPM) is configured by the TRGSRC field. This field should only be changed when the TPM counter is disabled. Refer to the chip configuration section for available external trigger options. |
Hi Bob,
Thanks for clearing that up.
Do you know if the TPM MOD can be changed on the fly without stopping the timer? It doesn't actually say in the manual. If this counter can be changed without stopping the timer, then I should be able to modify it during an interrupt and create the phase shift that I'm seeking. It will likely have to be done in assembly code though.
Let me know!
Thanks,
Sara
It is not the TPM counters that are the issue.
The ARM CPU Core and the TPM are running from different clock sources and they must be synchronized when communicating between them.
/*
* Channel must first be disabled and this must be acknowledged
* in the TPM counter clock domain:
*/
clk_timeout_u32 = CLOCK_TIMEOUT_SET;
do{
--clk_timeout_u32;
TPM_CxSC = TPM_CnSC_CHF_MASK; /* Clear the channel flag by writing '1' */
TPM_CxSC = 0UL; /* Disable */
}while( (0U != (TPM_CxSC & ~TPM_CnSC_CHF_MASK)) && (0U != clk_timeout_u32) ); /* Wait for match */
Set up new TPM values here...