0

I designed a circuitboard and need to proof the function.Therefore i have to modify the code to read from Pins D1 instead of D2. Unfourtunatly i am not that familar with the high level programming so im not sure if i got all changes. Basically all PINS on the circuit are used.

Basecode foud here: Seeeduino XIAO write and read PWM duration (period) using timers

Reading short square waves with Seeeduino XIAO pin D2

// Setup TC4 to capture pulse-width and period on digital pin D2 on Seeeduino Xiao
volatile boolean periodComplete;
volatile uint32_t isrPeriod;
volatile uint32_t isrPulsewidth;
uint32_t period;
uint32_t pulsewidth;
void setup() { 
 SerialUSB.begin(115200); // Initialise the native serial port
 while(!SerialUSB); // Wait for the console to open
 
 PM->APBCMASK.reg |= PM_APBCMASK_EVSYS; // Switch on the event system peripheral
 GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | // Divide the 48MHz system clock by 1 = 48MHz
 GCLK_GENDIV_ID(4); // Set division on Generic Clock Generator (GCLK) 4
 GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
 GCLK_GENCTRL_GENEN | // Enable GCLK 4
 GCLK_GENCTRL_SRC_DFLL48M | // Set the clock source to 48MHz
 GCLK_GENCTRL_ID(4); // Set clock source on GCLK 4
 while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
 
 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | // Route GCLK4 to TC4 and TC5
 GCLK_CLKCTRL_GEN_GCLK4 | 
 GCLK_CLKCTRL_ID_TC4_TC5; 
 
 // Enable the port multiplexer on port pin PA10
 PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
 // Set-up the pin as an EIC (interrupt) on port pin PA10
 PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;
 EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO10; // Enable event output on external interrupt 10
 EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE2_HIGH; // Set event detecting a HIGH level
 EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT10; // Disable interrupts on external interrupt 10
 EIC->CTRL.reg |= EIC_CTRL_ENABLE; // Enable EIC peripheral
 while (EIC->STATUS.bit.SYNCBUSY); // Wait for synchronization
 
 EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) | // Attach the event user (receiver) to channel 0 (n + 1)
 EVSYS_USER_USER(EVSYS_ID_USER_TC4_EVU); // Set the event user (receiver) as timer TC4
 EVSYS->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_EIC_EXTINT_10) | // Set event generator (sender) as external interrupt 10
 EVSYS_CHANNEL_CHANNEL(0); // Attach the generator (sender) to channel 0
 TC4->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI | // Enable the TC event input
 //TC_EVCTRL_TCINV | // Invert the event input
 TC_EVCTRL_EVACT_PPW; // Set up the timer for capture: CC0 period, CC1 pulsewidth
 
 TC4->COUNT32.CTRLC.reg = TC_CTRLC_CPTEN1 | // Enable capture on CC1
 TC_CTRLC_CPTEN0; // Enable capture on CC0
 while (TC4->COUNT32.STATUS.bit.SYNCBUSY); // Wait for synchronization
 NVIC_SetPriority(TC4_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
 NVIC_EnableIRQ(TC4_IRQn); // Connect the TC4 timer to the Nested Vector Interrupt Controller (NVIC)
 
 TC4->COUNT32.INTENSET.reg = TC_INTENSET_MC1 | // Enable compare channel 1 (CC1) interrupts
 TC_INTENSET_MC0; // Enable compare channel 0 (CC0) interrupts
 
 TC4->COUNT32.CTRLA.reg = //TC_CTRLA_PRESCSYNC_PRESC | // Overflow on precaler clock, (rather than the GCLK)
 TC_CTRLA_PRESCALER_DIV1 | // Set prescaler to 1, 48MHz/1 = 48MHz
 TC_CTRLA_MODE_COUNT32; // Set TC4/TC5 to 32-bit timer mode
 
 TC4->COUNT32.CTRLA.bit.ENABLE = 1; // Enable TC4
 while (TC4->COUNT32.STATUS.bit.SYNCBUSY); // Wait for synchronization
}
void loop() { 
 if (periodComplete) // Check if the period is complete
 {
 noInterrupts(); // Read the new period and pulse-width
 period = isrPeriod; 
 pulsewidth = isrPulsewidth;
 interrupts();
 SerialUSB.print("PW: ");
 SerialUSB.print(pulsewidth);
 SerialUSB.print(F(" "));
 SerialUSB.print("P: ");
 SerialUSB.println(period);
 periodComplete = false; // Start a new period
 }
}
void TC4_Handler() // Interrupt Service Routine (ISR) for timer TC4
{ 
 // Check for match counter 0 (MC0) interrupt
 if (TC4->COUNT32.INTFLAG.bit.MC0) 
 {
 TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ | // Enable a read request
 TC_READREQ_ADDR(0x18); // Offset address of the CC0 register
 while (TC4->COUNT32.STATUS.bit.SYNCBUSY); // Wait for (read) synchronization
 isrPeriod = TC4->COUNT32.CC[0].reg; // Copy the period 
 periodComplete = true; // Indicate that the period is complete
 }
 // Check for match counter 1 (MC1) interrupt
 if (TC4->COUNT32.INTFLAG.bit.MC1) 
 {
 TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ | // Enable a read request
 TC_READREQ_ADDR(0x1A); // Offset address of the CC1 register
 while (TC4->COUNT32.STATUS.bit.SYNCBUSY); // Wait for (read) synchronization
 isrPulsewidth = TC4->COUNT32.CC[1].reg; // Copy the pulse-width
 }
}

Do i only have to change the IOs: from:
PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;
to:
PORT->Group[PORTA].PINCFG[4].bit.PMUXEN = 1;
PORT->Group[PORTA].PMUX[4 >> 1].reg |= PORT_PMUX_PMUXE_A;

or do i need to mod more code?

Thanks for helping.

asked Oct 21, 2022 at 9:56
0

1 Answer 1

0

In addition to the changes you mentioned, your EIC_EVCTRL_EXTINTEO10, EIC_INTENCLR_EXTINT10, and EVSYS_ID_GEN_EIC_EXTINT_10 usages will need to be changed to EIC_EVCTRL_EXTINTE4, EIC_INTENCLR_EXTINT4 and to EVSYS_ID_GEN_EIC_EXTINT_4, to re-target the event system source, because PORT_PMUX_PMUXE_A on both these pins routes the signal to the EIC, but not to the exact same interrupt number. The EIC->CONFIG line needs to change to the first group of 8 ([0]) and fourth SENSE within that group (EIC_CONFIG_SENSE4_HIGH) to the change to D1 (PA04) uses EXTINT4. This is something I'd left out of the first edit before I'd been able to test. I did eventually find a XIAO to test with and these modifications seem to make it work just fine on digital pin 1 now instead of digital pin 2.

EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTE4;
EIC->CONFIG[0].reg |= EIC_CONFIG_SENSE4_HIGH;
EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT4;
EIC->CTRL.reg |= EIC_CTRL_ENABLE;
while (EIC->STATUS.bit.SYNCBUSY);

...

EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT | 
 EVSYS_CHANNEL_PATH_ASYNCHRONOUS |
 EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_4) |
 EVSYS_CHANNEL_CHANNEL(0);

The changes you'd mentioned and those I've said above as diff:

--- original.ino
+++ modified.ino
@@ -24,14 +24,14 @@
 GCLK_CLKCTRL_GEN_GCLK4 | 
 GCLK_CLKCTRL_ID_TC4_TC5; 
 
- // Enable the port multiplexer on port pin PA10
- PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
- // Set-up the pin as an EIC (interrupt) on port pin PA10
- PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;
+ // Enable the port multiplexer on port pin PA04
+ PORT->Group[PORTA].PINCFG[4].bit.PMUXEN = 1;
+ // Set-up the pin as an EIC (interrupt) on port pin PA04
+ PORT->Group[PORTA].PMUX[4 >> 1].reg |= PORT_PMUX_PMUXE_A;
 
- EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO10; // Enable event output on external interrupt 10
- EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE2_HIGH; // Set event detecting a HIGH level
- EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT10; // Disable interrupts on external interrupt 10
+ EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO4; // Enable event output on external interrupt 4
+ EIC->CONFIG[0].reg |= EIC_CONFIG_SENSE4_HIGH; // Set event detecting a HIGH level
+ EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT4; // Disable interrupts on external interrupt 4
 EIC->CTRL.reg |= EIC_CTRL_ENABLE; // Enable EIC peripheral
 while (EIC->STATUS.bit.SYNCBUSY); // Wait for synchronization
 
@@ -40,7 +40,7 @@
 
 EVSYS->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_EIC_EXTINT_10) | // Set event generator (sender) as external interrupt 10
+ EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_4) | // Set event generator (sender) as external interrupt 4
 EVSYS_CHANNEL_CHANNEL(0); // Attach the generator (sender) to channel 0
 
 TC4->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI | // Enable the TC event input
answered Oct 21, 2022 at 11:49

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.