-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
With high network traffic or an IRQ latency fuzzer, lirc_rpi starts to generate errors in the decoded stream. The root cause is that IRQ latency between the edge-triggered GPIO interrupt going off and being able to read the timestamp at which it occurred causes incorrect decoding.
The minimum pulse width that needs to be correctly recorded is 562.5uS (NEC protocol "0" bit). Sony SIRC has a slightly longer duration at 600uS. RC-5 and RC-6 are slower.
There is no scope for moving GPIO interrupts to the FIQ pin. The ARMCTRL routing only allows for a single interrupt to be wired up to the FIQ pin at any one time.
The proposed solution is to move to a polled method. On Pi 1, the FIQ is triggered reliably from a 8kHz source clock (USB start-of-frame, which is almost never masked) giving 125uS sample points. This is sufficient resolution to decode GPIO edges into mark-space bitstreams from an IR receiver. On Pi 2, the option exists to use an (as yet undocumented) local timer to trigger a FIQ on a completely independent core in the same fashion.
The Pi 1 solution makes IR decoding dependent on the use of the USB FIQ, but nearly everyone uses that anyway so the dependency should be minimal.
In either case, the polling routine would read the GPIO level register for the pin(s) in question and do a delta comparison. If a delta is found, it would then read the system time counter (STC, monotonic increase at 1uS intervals) and write both the value and the delta to a ring-buffer-like interface and then stimulate an interrupt. On Pi 1, a DMA engine with a dummy read transfer can be used to provoke an interrupt. On Pi 2, the local mailboxes can be used.
The Pi 2 solution would be a lot more robust and include other use cases such as logic analysis with reasonable (kHz) sampling rates.