I'm using the Teensy LC and I'm having trouble configuring the TPM0 for complementary output. It should be as easy as setting the ELSnB:ELSnA bits, in the TPMx_CnSC register, but I'm having no luck. The channel 1 of TPM0 seems stuck in "High-true pulses (clear Output on match, set Output on reload)" mode.
Please take a look at my code below and help me see where I've gone wrong. Thanks!
The end application requires two channels of PWM, with variable frequency and duty-cycle. The falling edge of one channel must align with the rising edge of the complementary channel. I would configure the channel values as following:
I have this working using the Teensy 3 and FlexTimerModule, but hope to port it to the LowCost version of Teensy
Please take a look at my code below and help me see where I've gone wrong. Thanks!
HTML:
// Pin 34 - PTC1 - TPM0-CH0 - LC-22 - ALT4
// Pin 35 - PRC2 - TPM0-CH1 - LC-23 - ALT4
const int ledPin = 13;
#define TPM_C 48000000 // peripheral clock, for calculation only
int PWM_FREQ = 60000; // PWM frequency [Hz]
float dutyCycle = 0.25;
void setup() {
pinMode(ledPin, OUTPUT);
init_TPM0();
TPM0_C0V = getDutyPeriod(); // Pin22
TPM0_C1V = getMOD() - getDutyPeriod(); // Pin23
TPM0_SC = 0x08; // enable timer clock
}
void loop() {
digitalWrite(ledPin, HIGH); // set the LED on
delay(1000); // wait a bit
digitalWrite(ledPin, LOW); // set the LED off
delay(1000); // wait a bit
}
void init_TPM0(){
TPM0_SC = 0x00; // disable timer clock
TPM0_C0SC = 0x28; // Edge-aligned PWM, MSnB:MSnA (10), ELSnB:ELSnA (10)
TPM0_C1SC = 0x24; // Edge-aligned PWM, MSnB:MSnA (10), ELSnB:ELSnA (01)
TPM0_MOD = getMOD(); // Period register
CORE_PIN22_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; //TPM0-CH0
CORE_PIN23_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; //TPM0-CH1
}
int getMOD(){
int MODULO = (TPM_C / PWM_FREQ);
return MODULO;
}
int getDutyPeriod(){
int PWM = (int) getMOD() * dutyCycle;
return PWM;
}
The end application requires two channels of PWM, with variable frequency and duty-cycle. The falling edge of one channel must align with the rising edge of the complementary channel. I would configure the channel values as following:
HTML:
TPM0_C0V = getDutyPeriod();
TPM0_C1V = getMOD() - getDutyPeriod();
I have this working using the Teensy 3 and FlexTimerModule, but hope to port it to the LowCost version of Teensy