start/stopEvent bodies should be in atomic blocks

This commit is contained in:
Allen Hill
2026-06-18 13:17:30 -07:00
parent d054806567
commit 26b0d6c55f
+10 -6
View File
@@ -176,8 +176,9 @@ constexpr uint16_t mic_quiet_ticks = (uint16_t)((F_CPU / 1024UL) / 2UL);
/* Disable non-read related interrupts (USART RX, PIT, TCA) during AVCLAN reads. /* Disable non-read related interrupts (USART RX, PIT, TCA) during AVCLAN reads.
*/ */
static inline void stopEvent() { static inline void stopEvent() {
RTC.PITINTCTRL &= ~(1 << RTC_PI_bp); ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
USART0.CTRLA &= ~(1 << USART_RXCIE_bp); RTC.PITINTCTRL &= ~RTC_PI_bm;
USART0.CTRLA &= ~USART_RXCIE_bm;
// WO1 toggles don't depend on OVF interrupt, but the OVF interrupt *DOES* // WO1 toggles don't depend on OVF interrupt, but the OVF interrupt *DOES*
// count the toggles So, disabling the OVF interrupt alone is insufficient, // count the toggles So, disabling the OVF interrupt alone is insufficient,
@@ -191,20 +192,23 @@ static inline void stopEvent() {
// intervals (low) // intervals (low)
TCA0.SINGLE.CTRLA &= ~TCA_SINGLE_ENABLE_bm; TCA0.SINGLE.CTRLA &= ~TCA_SINGLE_ENABLE_bm;
} }
}
// Re-enable serial and periodic interrupts. // Re-enable serial and periodic interrupts.
static inline void startEvent() { static inline void startEvent() {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (AVCLAN_isPlaying()) // Reenable PIT interrupt if currently playing if (AVCLAN_isPlaying()) // Reenable PIT interrupt if currently playing
RTC.PITINTCTRL |= (1 << RTC_PI_bp); RTC.PITINTCTRL |= RTC_PI_bm;
USART0.CTRLA |= (1 << USART_RXCIE_bp); USART0.CTRLA |= USART_RXCIE_bm;
// Resume/re-arm mic-press timer only while a press is in progress. // Resume/re-arm mic-press timer only while a press is in progress.
// Enable before unmasking so a pending final-phase OVF lands after re-enable // Enable before unmasking so a pending final-phase OVF lands after
// and the ISR's own ENABLE clear wins (no spurious extra period). // re-enable and the ISR's own ENABLE clear wins (no spurious extra period).
if (mic_ntoggles) { if (mic_ntoggles) {
TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm; TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;
TCA0.SINGLE.INTCTRL |= TCA_SINGLE_OVF_bm; TCA0.SINGLE.INTCTRL |= TCA_SINGLE_OVF_bm;
} }
} }
}
// clang-format off // clang-format off
static inline void AVCLAN_setBusIdle() { static inline void AVCLAN_setBusIdle() {