I'm setting up the PWMH2 and PWML2 to be in sync with the PWML4 (Pin D9) and it needs to be center-aligned. Here is my code for those two modules. But I see a difference of 10 us between the two halves of the PWMH2 waveform (which ideally would be equal since it's center aligned to the edge of the green (PWML4) wave).
void PWM_clockinit() {
// PWM Set-up on pins PC21 (PWML4 = D9)
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // PWM power ON
PWM->PWM_DIS = PWM_DIS_CHID4; // Disable PWM channel 4
// Select Instance=PWM; Signal=PWML4 (channel 4); I/O Line=PC21; Peripheral type B
PIOC->PIO_PDR |= PIO_PDR_P21; // Set the pin to the peripheral PWM, not the GPIO
PIOC->PIO_ABSR |= PIO_PC21B_PWML4; // Set PWM pin perhipheral type B
PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(7); // Set the PWM clock rate to 2MHz (84MHz/42) (?)
PWM->PWM_CH_NUM[4].PWM_CMR = PWM_CMR_CPRE_CLKA; // clock source as CLKA on channel 2
PWM->PWM_CH_NUM[4].PWM_CPRD = 500; // Channel 2 : Set the PWM frequency 2MHz/(2* CPRD) = F ;
PWM->PWM_CH_NUM[4].PWM_CDTY = 250; // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD) * 100 %
PWM->PWM_IER1 = PWM_IER1_CHID4; // Interrupt on end of counter period (2*CPRD)
NVIC_EnableIRQ(PWM_IRQn); // Enable PWM interrupt
PWM->PWM_ENA = PWM_ENA_CHID4; // Enable PWM Channel 4
}
void PWM_Handler() {
PWM->PWM_ISR1; // Clear status register
PIOC->PIO_SODR = 1 << 24; // Business monitor set
if (State == Idle) {
PIOC -> PIO_CODR = 1 << 13; //R1 RED ON
PIOC -> PIO_SODR = 1 << 12; //G1 GREEN OFF
PIOB -> PIO_CODR = 1 << 14; //B1 BLUE OFF
PWM->PWM_CH_NUM[2].PWM_CDTY = 500; //100% duty cycle
}
if (State == Run) {PWM->PWM_CH_NUM[2].PWM_CDTY = 100; //1/3rd duty cycle
PIOC -> PIO_CODR = 1 << 14; //R1 RED OFF
PIOC -> PIO_SODR = 1 << 13; //G1 GREEN ON
PIOB -> PIO_CODR = 1 << 14; //B1 BLUE OFF
}
PIOC -> PIO_CODR = 1 << 24;
}
void pwmc_setup(){
// PWM Set-up on pins PC7 and PC6 (Arduino Pins 39(PWMH2) and 38(PWML2))
PWM->PWM_DIS = PWM_DIS_CHID2; // Disable PWM channel 2
// Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pin 39, see pinout diagram) ; Peripheral type =B
PIOC->PIO_PDR |= PIO_PDR_P7; // Set the pin to the peripheral PWM, not the GPIO
PIOC->PIO_ABSR |= PIO_PC7B_PWMH2; // Set PWM pin perhipheral type B
// Select Instance=PWM; Signal=PWML2 (channel 2); I/O Line=PC6 (P6, Arduino pin 38, see pinout diagram) ; Peripheral=B
PIOC->PIO_PDR |= PIO_PDR_P6; // Set the pin to the peripheral PWM, not the GPIO
PIOC->PIO_ABSR |= PIO_PC6B_PWML2; // Set PWM pin perhipheral type B
// Enable the PWM channel 2 (see datasheet page 973)
PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(42); // Set the PWM clock rate to 2MHz (84MHz/42). Adjust DIVA for the resolution you are looking for
PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKA | PWM_CMR_CALG; // The period is center aligned, clock source as CLKA on channel 2
PWM->PWM_CH_NUM[2].PWM_CPRD = 500;
PWM->PWM_ENA = PWM_ENA_CHID2; //Enable PWM Channel 2
}
Can this be avoided in software? 10 us seems to be a big difference, I was wondering if there was something I'm missing.
@MartinL , @ard_newbie I've read a few posts of both your codes and came up with mine here. Putting the whole code on here would probably obscure my point - but I can put it in if it's necessary.