dirkx / SMPTE-EBU-TimecodeGenerator-ESP32

ESP32 based SMPTE/EBU timecode generator, with NTP slaving, for Leitch and similar studio/broadcast clocks.
Apache License 2.0
51 stars 16 forks source link

Problems in rmt_isr_handler fixed #8

Closed mikemccauley closed 2 years ago

mikemccauley commented 2 years ago

Hi. Love this software, but have been battling with an intermittent issue for some weeks and have found a fx.

Im running the software on ESP-WROOM-32, compiled on Linux arduino with esp32 board package version 1.0.6. I have several instances connected to Leitch ADC-5100 analog display clocks.

The problem was that periodically, a clock would enter what I call flashy-flashy mode. The clock would:

Reading the timecode output from the ESP32 with ltctools and an anaog input card: ./jltcdump system:capture_1 showed that when the clock was exibiting this behaviour the timecode decode with reported discontinuitites, and sometims time jumping back by 1 or more seconds for 12 frame.

Also this behaviour was very loosely associated with messages on the Serial output of the ESP32: IRQ while filling 2

I think that what is happening is that the interrupt service routine rmt_isr_handler() very occasionally (and wrongly) gets called twice for a single RMT threshold event. When this happens,the double buffering breaks, and the CPU will be writing to the same buffer that the RMT is reading, leading to occasional errors, depending on the exact timing. And this state will continue until another wrong double interrupt, when the clock will recover.

Looking at rmt_isr_handler I see that the critical section protection with mux is unnecessary (since the ISR can interrupt itself) so I have removed that. I have also found that clearing the interrupt twice prevents the flashy-flashy problem and there are no reports of IRQ while filling 2.

So now my isr is essentially:

void IRAM_ATTR rmt_isr_handler(void *arg) { // Clear the interrupt RMT.int_clr.ch0_tx_thr_event = 1;

refill ++;

// It seems that clearing the interrupt again here prevents // spurious duplicate interrupts, which causes us to emit occasional // broken SMPTE frames which causes // the clock to do its red-light flashing thing. Mikem RMT.int_clr.ch0_tx_thr_event = 1; }

With that fix, I have not seen any erros for a week now.

mikemccauley commented 2 years ago

That should read: since the ISR cannot interrupt itself