#include <Adafruit_ZeroTimer.h> stops AudioZero from working

AudiZero works fine for me, but if I #include <Adafruit_ZeroTimer.h> it stops working, specifically it hangs at the following line. I’m using SerialUSB to debug, “before” gets printed, “after” does not.

 void AudioZeroClass::tcConfigure(uint32_t sampleRate) {
     __Configured = true;
    // Enable GCLK for TCC2 and TC5 (timer counter input clock)
    GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
    while (GCLK->STATUS.bit.SYNCBUSY);
    tcReset();
    // Set Timer counter Mode to 16 bits
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
    // Set TC5 mode as match frequency
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
    TC5->COUNT16.CC[0].reg = (uint16_t) (SystemCoreClock / sampleRate - 1);	
    while (tcIsSyncing());

    // Configure interrupt request
    NVIC_DisableIRQ(TC5_IRQn);
    NVIC_ClearPendingIRQ(TC5_IRQn);
    NVIC_SetPriority(TC5_IRQn, 0);
    NVIC_EnableIRQ(TC5_IRQn);
		
_HardSerial->println("before");
_HardSerial->flush();

    // Enable the TC5 interrupt request
    TC5->COUNT16.INTENSET.bit.MC0 = 1;
		
_HardSerial->println("after");
_HardSerial->flush();

    while (tcIsSyncing());
}

Why would just including Adafruit_ZeroTimer.h break this code, I’m not using the library, but just including it stops AudioZero from working???

AudiZero works fine for me, but if I #include <Adafruit_ZeroTimer.h> it stops working, specifically it hangs at the following line. I’m using SerialUSB to debug, “before” gets printed, “after” does not.

 void AudioZeroClass::tcConfigure(uint32_t sampleRate) {
     __Configured = true;
    // Enable GCLK for TCC2 and TC5 (timer counter input clock)
    GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
    while (GCLK->STATUS.bit.SYNCBUSY);
    tcReset();
    // Set Timer counter Mode to 16 bits
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
    // Set TC5 mode as match frequency
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
    TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
    TC5->COUNT16.CC[0].reg = (uint16_t) (SystemCoreClock / sampleRate - 1); 
    while (tcIsSyncing());

    // Configure interrupt request
    NVIC_DisableIRQ(TC5_IRQn);
    NVIC_ClearPendingIRQ(TC5_IRQn);
    NVIC_SetPriority(TC5_IRQn, 0);
    NVIC_EnableIRQ(TC5_IRQn);
 
_HardSerial->println("before");
_HardSerial->flush();

    // Enable the TC5 interrupt request
    TC5->COUNT16.INTENSET.bit.MC0 = 1;
 
_HardSerial->println("after");
_HardSerial->flush();

    while (tcIsSyncing());
}

Why would just including Adafruit_ZeroTimer.h break this code, I’m not using the library, but just including it stops AudioZero from working???

I'm not using the library, but just including it stops AudioZero from working?

If you are not using the library, whet is the point of including it?

What library is that method from?

Post links to ALL non-standard libraries you are using.

Hi boggydew,

It could be that writing to the TC5's counter compare CC[0] register needs to occur before the TC5 counter is enabled, like this:

// Set TC5 mode as match frequency
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
TC5->COUNT16.CC[0].reg = (uint16_t) (SystemCoreClock / sampleRate - 1);
while (tcIsSyncing());
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
while (tcIsSyncing());

The reason is that setting the ENABLE bit triggers a write synchronization. On peripherals such as the TCx timers that use the "common synchronizer register synchronization" method, writing to another register during synchronization (in this case the CC[0] register) can cause the SAMD21's peripheral bus to stall.

@boggydew, please do not cross-post. Threads merged.

Sorry. Thing is, is that you often get a quick response if you post in the programming section, but at the same time because so many posts are made in that section you can quickly fall off the radar without getting a response. Where as here your post might sit at the top of the queue for days before getting a response.

What strategy should I adopt in the future? I guess I should just post my samd questions here and be more patient.

PaulS:
If you are not using the library, whet is the point of including it?

Hi Paul. I did want to use both the AudioZero library and Adafruit_zeroTimer library in the same sketch, but it causes conflict. In trying to debug I was surprised that just including the Adafruit_zeroTimer library broke the code without throwing a compile error. Live and learn I spose.

MartinL:
It could be that writing to the TC5’s counter compare CC[0] register needs to occur before the TC5 counter is enabled, like this:

Thanks Martin, nice pick up. That got me over that hurdle. Cheers.

boggydew:
What strategy should I adopt in the future?

Ask for the thread to be moved when you believe a different location is beneficial.

If meaningful information becomes available, add it to the thread.