Hi,
I have spent the last week reading through everything on this thread: https://forum.arduino.cc/index.php?topic=346731.105 I am hoping someone can help me.
I am using a Seeedstudio XIAO microcontroller which uses the SAMD21 chip (ATSAMD21G18-QFN48). Schematic is attached.
I am trying to have 2 PWM signals with dead time so that neither signal is HIGH at the same time. I want to be able to adjust the frequency and duty cycle. Same frequency on both though, I don't need 2 different frequencies at the same time. Essentially I want to have one PWM turn on and and then cascade off while the other cascades on without them ever both being on/high at the same time. I was hoping the DTI function could do this and tried modifying examples I found but haven't had any luck.
Is this possible with the DTI function or should I look at something else?
Just for now I would be happy just getting 2 PWM signals where one is like 50% duty cycle and the other is 45% duty cycle and the 2nd one is inverted and about 5% dead time between them. Something like in the attached picture. I can pretty much use any of the pins on the XIAO microcontroller but cant figure out how to get this working. I got this working on the Arduino Mega2560 but its a different chip essentially I did it with a lot of while loops and manipulating the OCR1A and OCR1B registers. I was hoping there is a better/cleaner way.
When I run the below code I get the attached image on the scope (current code scope results.png)
Sample code I tried to change that MartinL wrote on a different thread:
/*
Currently trying to use pins D2 and D3 which according to the schematic is PA10 and PA11.
XIAO D2 is PA10 (even port so PMUXE)
XIAO D3 is PA11 (odd port so PMUXO)
*/
void setup()
{
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW .....Duty Cycle
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(4); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Enable the port multiplexer for the digital pins desired (this has to be done when using the multiplexer and before the next PORT->Group below)
PORT->Group[g_APinDescription[2].ulPort].PINCFG[g_APinDescription[2].ulPin].bit.PMUXEN = 1;
PORT->Group[g_APinDescription[3].ulPort].PINCFG[g_APinDescription[3].ulPin].bit.PMUXEN = 1;
// Connect the TCC0 timer to the port output D3 and D7 - port pins are paired odd PMUXO and even PMUXE
// F & E specify the timers: TCC0, TCC1 and TCC2
PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg = PORT_PMUX_PMUXE_F;// | PORT_PMUX_PMUXE_F;
PORT->Group[g_APinDescription[3].ulPort].PMUX[g_APinDescription[3].ulPin >> 1].reg = PORT_PMUX_PMUXO_F;// | PORT_PMUX_PMUXE_F;
// Feed GCLK4 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1 //Enabling the clock and syncronizing it
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Normal (single slope) PWM operation: timers countinuously count up to PER register value and then is reset to 0
REG_TCC0_WAVE |= TCC_WAVE_WAVEGEN_NPWM; // Setup single slope PWM on TCC0....Normal Pulse-Width Modulation (NPWM)
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
// Set the output matrix so that D3 and D7 are set to output CC0 and enable low and high dead time insertion
REG_TCC0_WEXCTRL |= TCC_WEXCTRL_DTHS(100) | TCC_WEXCTRL_DTLS(100) | //Was 100 and 100
TCC_WEXCTRL_DTIEN0 | TCC_WEXCTRL_DTIEN1 | TCC_WEXCTRL_OTMX(0x2); /// OTMX is Output Matrix ....0x2 is CC0 from page 644...DTIEN 3 and 1
// Invert the driver on TCC0/WO[7], which by coincidence happens to be Arduino digtal pin D7
//REG_TCC0_DRVCTRL |= TCC_DRVCTRL_INVEN3;
// Each timer counts up to a maximum or TOP value set by the PER register,
// this determines the frequency of the PWM operation:
REG_TCC0_PER = 319; // Set the frequency of the PWM on TCC0 to 150kHz ////was 319 for 150kHz
while(TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
// Set the PWM signal to output 50% duty cycle on D3, 50% on D7
REG_TCC0_CCB0 = 159; // TCC0 CCB0 - on output on D3 and inverted output on D7 ////was 159
while(TCC0->SYNCBUSY.bit.CCB0); // Wait for synchronization
// Divide the 48MHz signal by 1 giving 48MHz (20.83ns) TCC0 timer tick and enable the outputs
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
TCC_CTRLA_ENABLE; // Enable the TCC0 output
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
}
void loop(){}
Seeeduino XIAO_v1.0_SCH_191112.pdf (41.6 KB)