Hi, I'm looking for a way to output a SAMD51 event on a pin. I have followed @MartinL 's helpful posts on similar themes but these all seem to be using the event system as inputs. I'm using ItsyBitsy M4 for intial development but have access to Metro M4 if needed.
Here's what I have so far. I get 10 kHz square wave on D10, as expected as a TCC output pin, but nothing on D9, which is where I'm trying to route the event.
void setup() {
init_tcc1(); // start a 10 kHz waveform on D10
init_evsys(); // start the event system to feed count from TCC to D9
void loop() {
}
void init_evsys(void)
{
// Event System ///////////////////////////////////////////////////////////////////////////////
MCLK->APBBMASK.reg |= MCLK_APBBMASK_EVSYS; // Switch on the event system peripheral
// Select the event system user on channel 0 (USER number = channel number + 1)
EVSYS->USER[EVSYS_ID_USER_PORT_EV_0].reg = EVSYS_USER_CHANNEL(1); // Set the event user (receiver) as TCC1 Overflow (must be set async in generator)
// Select the event system generator on channel 0
EVSYS->Channel[0].CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT | // No event edge detection
EVSYS_CHANNEL_PATH_ASYNCHRONOUS | // Set event path as asynchronous
EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_TCC1_OVF); // Set event generator (sender) TCC1 overflow
// For testing, set D9 (PA19) as EVENT output
PORT->Group[PORTA].DIRSET.reg = PORT_PA19;
PORT->Group[PORTA].EVCTRL.reg = PORT_EVCTRL_EVACT0_OUT | // Set pin to follow event level output for event 0
PORT_EVCTRL_PID0(19); // Set Pin 19 (PA19/D9) as the output for event 0
// Have also tried, without success:
// PORT->Group[g_APinDescription[9].ulPort].PINCFG[g_APinDescription[9].ulPin].bit.PMUXEN = 1;
// Set the peripheral multiplexer to peripheral (even or odd port number) to mode E/O(5): TCC0, Channel x
// PORT->Group[g_APinDescription[9].ulPort].PMUX[g_APinDescription[9].ulPin >> 1].reg |= PORT_PMUX_PMUXO(0); // PMUXO because PA19 is odd, (0) = peripheral function A = EIC
}
void init_tcc1(void)
{
// Using TCC1 and enabling waveform outputs on channel 4 (PA20)
// Set up the generic clock (GCLK7) to clock timer TCC1
GCLK->GENCTRL[7].reg = GCLK_GENCTRL_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1 = 48MHz
GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK7
GCLK_GENCTRL_SRC_DFLL; // Select 48MHz DFLL clock source
while (GCLK->SYNCBUSY.bit.GENCTRL7); // Wait for synchronization
GCLK->PCHCTRL[25].reg = GCLK_PCHCTRL_CHEN | // Enable the TCC1 peripheral channel
GCLK_PCHCTRL_GEN_GCLK7; // Connect generic clock 7 to TCC1
// Enable the peripheral multiplexer on pins
PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].bit.PMUXEN = 1;
// Set the peripheral multiplexer to peripheral (even or odd port number) to mode E/O(5): TCC0, Channel x
PORT->Group[g_APinDescription[10].ulPort].PMUX[g_APinDescription[10].ulPin >> 1].reg |= PORT_PMUX_PMUXE(5); // PMUXE because PA20 is even, (5) = peripheral function F
TCC1->CTRLA.reg = TC_CTRLA_PRESCALER_DIV8 | // Set prescaler to 8, 48MHz/8 = 6MHz
TC_CTRLA_PRESCSYNC_PRESC; // Set the reset/reload to trigger on prescaler clock
TCC1->WAVE.reg = TCC_WAVE_WAVEGEN_NFRQ; /* Set-up TCC0 timer for single slope PWM mode with interrupt/event at the top (DSTOP) */
while (TCC1->SYNCBUSY.bit.WAVE); // Wait for synchronization
// set up event output on overflow for event channel 0
TCC1->EVCTRL.reg = TCC_EVCTRL_OVFEO;
TCC1->PER.reg = 299; // Set-up the PER (period) register 10kHz PWM
while (TCC1->SYNCBUSY.bit.PER); // Wait for synchronization
TCC1->CTRLA.bit.ENABLE = 1; // Enable timer TCC1
while (TCC1->SYNCBUSY.bit.ENABLE); // Wait for synchronization
}
Please could anyone familiar with SAMD51 comment on what I might be doing wrong here?