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.

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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.