tinygo-org / drivers

TinyGo drivers for sensors, displays, wireless adaptors, and other devices that use I2C, SPI, GPIO, ADC, and UART interfaces.
https://tinygo.org
BSD 3-Clause "New" or "Revised" License
584 stars 180 forks source link

irremote unreliable on SAMD51 #668

Open suurkivi opened 3 months ago

suurkivi commented 3 months ago

IR receiving appears to be unreliable on SAMD51. I've seen this issue on both a feather-m4-can board and also a custom itsybitsy-m4 board, but the same code works flawlessly on SAMD21 (qtpy).

After adding some debugging code, I've noticed occasional spikes in duration between pinChange() calls up to around 730µs instead of the usual 610µs. For example:

dur => 0 00 3.030151367s
dur => 1 00 9.155273ms
dur => 2 00 4.394532ms
dur => 3 00 610.351µs
dur => 4 00 610.352µs
dur => 3 01 610.351µs
dur => 4 01 488.282µs
dur => 3 02 610.351µs
dur => 4 02 488.281µs
dur => 3 03 610.352µs
dur => 4 03 488.281µs
dur => 3 04 732.422µs            <---- spike
dur => 0 00 488.281µs
dur => 1 00 610.352µs
dur => 0 00 488.281µs
dur => 1 00 610.352µs
dur => 0 00 488.281µs
dur => 1 00 610.351µs
dur => 0 00 610.352µs
dur => 1 00 610.352µs

These are the values of ir.necState, ir.bitIndex, and duration at the top of each pinChange(). You can see that after bit 4, the duration spikes to 732.422µs, which exceeds the 700µs threshold in the code.

The SAMD21 board I used (qtpy) doesn't show these spikes and works with high reliability.

I've also captured the output from the TSOP38238 on a logic analyzer during several of these failures, and the 730µs spike does not show up there.

If I slightly relax some of the thresholds in pinChange(), e.g., 700µs -> 750µs, I can reliably receive IR codes.

The common denominator seems to be SAMD51, but I could be wrong here. My theory is something is causing occasional delays on SAMD51 but not on SAMD21. Could it be longer GC cycles due to more memory? More peripherals and interrupts?