Hello i am aware that what i am asking involves(can only be achieved?) some register manipulation that is way way over me, thus i am here.
What i would like is to create is an inverted pwm signals between 2 pwm pins for example pin 1 is 101010 and pin 2 is 010101. I was hoping to do it ONLY with software with NO EXTERNAL COMPONENTS since the driver has an alternate mode which i plan on using so i would also like to ask how to revert it to being an ordinary digital pin. Also would you believe or not am running out on digital pins. The plan is to pair all 12 PWM pins, to which pin number can a pin be pair that i do not know yet.
arduino due's sam3x datasheet seems to show some some graph of an inverted PWM by having CPOL to an opposing value but i have no idea how to implement that in code or if even that path will lead me to my goal.
Did you see pwm_lib from antodom ?
For each of the 8 PWM channels, the microcontroller outputs automatically 2 inverted signals: PWMHx/PWMLx. You just have to set the correct pins to the PWM peripheral, e.g.:
/******************************************************************************/
/* PWMH0_PWML0 1 MHz */
/******************************************************************************/
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // PWM power ON
PIOC->PIO_PDR |= PIO_PDR_P3; // Set pin to a peripheral (page 973)
PIOC->PIO_ABSR |= PIO_PC3B_PWMH0; // Set PWM pin peripheral type B for PWMH0 (Arduino pin 35)
PIOC->PIO_PDR |= PIO_PDR_P2; // Set pin to a peripheral
PIOC->PIO_ABSR |= PIO_PC2B_PWML0; // Set PWM pin peripheral type B for PWML0 (Arduino pin 34)
PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(2); // select Frequency for clock B: Mck/2 = 42 MHz
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKB; // The period is left aligned, clock source as CLKB on channel 0
PWM->PWM_CH_NUM[0].PWM_CPRD = 42; // Set the PWM frequency 42 MHz/PWM_CPRD
PWM->PWM_CH_NUM[0].PWM_CDTY = 21; // Set the PWM duty cycle = (CPRD/CDTY) * 100 %
PWM->PWM_IER1 = PWM_IER1_CHID0; // Interrupt on PWM Channel 0 counter
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt
PWM->PWM_ENA = PWM_ENA_CHID0; // Enable PWM channel 0
}
void loop() {
// update PWM frequency with PWM->PWM_CH_NUM[0].PWM_CPRDUPD = ....;
}
void PWM_Handler() {
static uint32_t Count;
PWM->PWM_ISR1; // Clear status register
if (Count++ == 1000000) {
PIOB->PIO_ODSR ^= PIO_ODSR_P27; //Blink LED at 1 Hz
Count = 0;
}
}