piface / libpifacedigital

A simple C library for controlling PiFace Digital.
GNU General Public License v3.0
16 stars 10 forks source link

Intermittent incorrect button value latch #4

Open scm6079 opened 10 years ago

scm6079 commented 10 years ago

I'm experiencing an interesting problem with this library -- in testing I'm receiving intermittent invalid readings of input states showing the first input button continuously depressed when it is not. This is similar to what I would expect in a hardware problem of a floating input (e.g. input resistors NOT pulling the input high). HOWEVER, this only occurs with the C library, not the python library leading me to believe this is a software issue not an issue with the PiFace. No hardware is attached to the piface digital - this is using it "out of the box".

I put together a couple very simple tests to confirm. You must rapidly depress and release the first input button very rapidly to observe the failure (sometimes many dozen attempts are necessary for a failure).

Sample Python Control Test Case (FUNCTIONAL, no problems)

#!/usr/bin/env python3
from time import sleep
import pifacedigitalio
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

while(True):
        print(pfd.input_pins[0].value)
        sleep(.01)

Sample C Failure Case

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "pifacedigital.h"

int main( int argc, char *argv[] )
{
    uint8_t inputs;
    int hw_addr = 0;

    pifacedigital_open(hw_addr);

    while(1) {
        inputs = pifacedigital_read_reg(0x11, hw_addr );
        printf("Inputs: 0x%x\n", inputs);
        usleep(10000);
    }

    pifacedigital_close(hw_addr);
}

Once failed, you will observe an output stuck at 0xfe instead of 0xff.

Inputs: 0xfe
Inputs: 0xfe
Inputs: 0xfe
...

The issue does not clear - even after waiting - but will clear with an additional button press. I did reproduce the issue with an externally wired momentary push button switch as well.

scm6079 commented 10 years ago

After some in-depth review from the Microchip website and some more tests, I've found:

1) The problem ONLY occurs with the Interrupt driven latched value, not the GPIOB read value (e.g. register 0x11, NOT 0x13) 2) The Python code reads register 0x13 - thus is not impacted directly in my sample code above. 3) There appears to be an open bug in the Python version for PiFace dealing with interrupts - which may be related based on my research (and does use 0x11).

Overall - it is clear that the final interrupt should have been triggered when the input lines transitioned to the switch open state (0xff) - but that interrupt change was NOT latched. At this point I'm still unclear why that latch is missed.

tompreston commented 10 years ago

This is related to an old bug in the PiFace Digital Emulator too. When the emulator starts up, pin 0 would be set because an interrupt was fired. Pressing it once would clear it and then the Emulator would resume normal operation (though I haven't tested it extensively). I fixed it with a hack by reading the interrupt capture register during initialisation to clear that first interrupt before anyone could see anything.

I can replicate the issue in Python with:

#!/usr/bin/env python3
from time import sleep
import pifacedigitalio
pifacedigitalio.init()
pfd = pifacedigitalio.PiFaceDigital()

while(True):
        print(hex(pfd.intcapb.value))
        sleep(.01)

Prints out:

0xfe
0xfe
0xfe
0xfe
0xfe
0xfe
0xfe
0xfe
...