Skip to content

Very rare but possible glitching on PRU signal generation that can cause unexpected flashes #49

@bigjosh

Description

@bigjosh

While the vast, vast majority of 0 bits coming out of the PRU are 300ns-370ns wide, I am seeing a very rare case where a 0 bit can be as wide as 540ns, which is wide enough to be seen as a 1 by some WS2812B chips.

When the problem happens, it seems to stretch all output bits being transmitted at that moment, although there is only material impact on 0 bits since 1 bits just become slightly longer 1 bits.

Outwardly, this appears as a row of pixels flashing for a single frame. It is especially noticeable when running strings in demo mode "black" when all bits should be 0. It is possible this is only visible on WS2812B chips with a shorter-than-spec T1H minimum time.

I verified the problem by attaching a scope to an output and setting to trigger on minimum pulse width of 450ns. Then I ran the "black" demo mode. In this mode, all bits should be 0 so I should never see a pulse wider than 450ns. Yet I was (rarely) able to capture pulses as wide as 540ns.

The stretched bits seem to happen more frequently when the ARM is under heavy memory stress so I think this might be caused by a worst-case series of cache misses when the PRU accesses the data in ARM RAM.

The current approach of timing the bit phases uses the cycle counter. Is it possible that the cycle counter does not not count cycle where the PRU is stalled because it is waiting for a cache miss when reading external RAM? The STALL COUNT register possibly indicates this...

STALLCOUNT
This value is incremented by 1 for every cycle during which the PRU
is enabled and the counter is enabled (both bits ENABLE and
COUNTENABLE set in the PRU control register), and the PRU was
unable to fetch a new instruction for any reason.

Possible solutions might include...

  1. Rearrange current code so that all of the accesses to external RAM occur between bits rather than during the T0H phase of the bits. This would still add jitter to the time between bits when cache misses occur, but as long as this time is less than RESET, then the only impact should be (very) slightly diminished performance rather than bad data.
  2. Rewrite PRU code to copy pixel data into PRU RAM first and then transmit the bits directly from local PRU RAM during the timing sensitive frame.
  3. Rewrite the PRU code to use the IEP_TIMER to time the signal phases rather than the cycle counter. The IEP_COUNTER seems to be able to run deterministicly at 200MHz no matter what is happening with PRU accesses.

I can try to tackle either of these approaches, but just want a sanity check before doing the work. Has anyone else ever seen these wide bits (or the flashes they produce)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions