Dynamically switching on & off oscillator output on selected pin.


In my small project with MKR 1400 and MS5540C sensors, I would like to be able to turn on & of oscillator output on the selected pin.

To run a 32kHz clock on D7 pin I've used an awesome piece of code by @MarinL which I've attached at the bottom. My question is if it is possible to turn on and off such an oscillator on that pin?

Or maybe a more drastic solution is possible and I could "destroy" this clock dynamically, and restart it after if needed?

Thank you in advance for any help,

// Pressure sesors needs 32kHz clock for SPI comunication
 REG_GCLK_GENDIV = GCLK_GENDIV_DIV(96) |          // 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
                     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 TCC0 PWM channel 3 (digital pin D7), SAMD21 pin PA21
    PORT->Group[g_APinDescription[7].ulPort].PINCFG[g_APinDescription[7].ulPin].bit.PMUXEN = 1;

    // Connect the TCC0 timer to the port outputs - port pins are paired odd PMUO and even PMUXE
    // F & E specify the timers: TCC0, TCC1 and TCC2
    PORT->Group[g_APinDescription[7].ulPort].PMUX[g_APinDescription[7].ulPin >> 1].reg |= /*PORT_PMUX_PMUXO_F |*/ PORT_PMUX_PMUXO_F;

    // Normal (single slope) PWM operation: timer countinuouslys count up to PER register value and then is reset to 0
    TCC0->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;        // Setup single slope PWM on TCC0
    while (TCC0->SYNCBUSY.bit.WAVE);                // Wait for synchronization

    // Each timer counts up to a maximum or TOP value set by the PER register,
    // this determines the frequency of the PWM operation:
    TCC0->PER.reg =  15;                            // Set the frequency of the PWM on TCC0 to 32kHz
    while (TCC0->SYNCBUSY.bit.PER);                 // Wait for synchronization

    // The CCx register value corresponds to the pulsewidth in microseconds (us)
    TCC0->CC[3].reg = 8;                            // TCC0 CC3 - 50% duty cycle on D7
    while (TCC0->SYNCBUSY.bit.CC3);                 // Wait for synchronization

    // Divide the 48MHz signal by 1 giving 48MHz (20.8ns) timer tick and enable timer TCC0
    TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1;    // Divide GCLK4 by 1
    TCC0->CTRLA.bit.ENABLE = 1;                     // Enable the TCC0 output
    while (TCC0->SYNCBUSY.bit.ENABLE);              // Wait for synchronization
digitalWrite(7, 0); //?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.