Beaglebone black PRU - counting pin state changes

No, but in the spirit of ‘The proof of the pudding is in the eating’, I will describe one way to do it. It might take me 5 to 10 hours to code, test, and deploy a project like this, but only 5 to 10 minutes to describe it.

so, the overall outline of the project:

  1. set up pwm signal of duration 1us, duty cycle 20% (200ns) … this will be your application clock that will govern the timing of the pin states. I have the details of how to set up a pwm if you need them. do you have an oscilloscope to verify the timings of this project?

  2. you will need 7 (seven) general purpose registers
    a) one for each pin to keep count of the changes (so 4)
    b) one to keep the current state of each pin (say the lower 4 bits as in a binary switch)
    c) one to record the ‘time’ of the change… if you increment this register every time your pwm signal goes high, it will last 68 minutes and 15 seconds before rolling over. (4G/1M = 4k … 4k seconds ~= 68 min, 15 seconds)
    d) one register to indicate that a change of one or more of the pin status has been made in this iteration of the loop (I leave to you any optimization that makes a separate register unnecessary)

  3. set up a ring buffer between the pru and the linux ‘c’ program. This will serve as the communication link for reporting (to linux). A ring buffer assures that all changes will be reported as opposed to a ‘c’ program polling for current state and potentially missing some changes. A good example of how to do this is here Turnkey PRU deskclock application for BBB … the example uses the pru as the reader, and the ‘c’ program as the writer, but this is easily reversed.

  4. Main loop:
    a) wait for pwm signal to go high, increment register used for timing … set change indicator to 0
    b) check the state of p8-11, if changed from saved state: 1) update current state … 2) increment counter for p8-11 … 3) increment indicator that change has been made
    c) same as b) for p8-12
    d) same as b) for p8-15
    e) same as b) for p8-16
    f) if any pin changed, write to ring buffer which will be read by ‘c’ program
    g) repeat from step a)
    this assumes that you can do steps b thru f in 1us which is about 200 instructions… use oscilloscope to VERIFY.

  5. you’ll need the ‘c’ linux program set up to run as root so that you access to /dev/mem … again see Turnkey PRU deskclock application for BBB for example of how to do this… This program would simply read the ring buffer, and report the changes.

5a) report:
a) 1 word … timer register … for determining how fast this change came after the previous one
b) 4 words … one for the count of each pin
c) 1 word … with the current state of each pin
the format of your report I leave to you.

good luck
gomer

1 Like