roadlabs / webiopi

Automatically exported from code.google.com/p/webiopi
0 stars 0 forks source link

Agree on delivered values when reading an GPIO output channel #96

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Some chips have an electronic architecture for their digital ports that can 
lead to different values when reading the value of an output port depending on 
whats going on behind the pin. Mostly this is the case with flip-flop driven 
open drain ports that invert the signal. Examples for such chips are the DS2408 
and the DS2413, others may also exist.

To change the output, some value is written direct to the output latches. This 
value gets inverted by the latch flip-flop and then drives the port FET. The 
sensed input level is not measured by taking the current value of the latches, 
it is mesured at the open drain position. This leads to the situation that the 
values of the latch and those at the open drain sensed level may be seldom but 
still sometime different depending on whether weak pullups or pulldowns are 
used or othr kinds of driving components.

Aside those electronic details, the simple question at the bottom line now is:

If a digital port is configured as an output and reading methods are called 
(e.g. digitalRead or portRead), which values have then to be sent back? The 
values of the output latches or the sensed levels of the pins? And, will there 
be a difference between reading the whole port at once with portRead and 
reading only a single channel with digitalRead. Plus, keep in mind the 
situation where you have a mixture of input and output ports (e.g. 3 inputs and 
5 outputs), what does readPort deliver then?

Last point, many drivers read the status of all output latches (as byte value) 
when they handle digitalWrite, mask the channel output value bit to be updated 
into the byte and write this byte back to the output latches. However, if the 
read values are not taken from the latches but form the sensed level and if for 
some reason the sensed level is different to the current latch level, this may 
lead to an unwanted accidential update of an other port. To avaid this there is 
a clear reason to be able to read the output latches and many chips give direct 
access to those latches by special registers.

I don't have an answer to this right now, but when looking at drivers code I 
have the impression that this is not handeled unique in all drivers. So best 
would be to agree on what way to follow and check all digital port drivers if 
they implement this way. My proposal would be to deliver the values of the 
output latches back when reading an output port and not the sensed levels. But, 
if there is a mixed input/output configuration, this will mean that portRead 
will have to mix the values form sensing for inputs and latches for outputs to 
be consistent.

Hope you understand my question, maybe a more detailed discussion is necessary 
in this topic.

Andreas

Original issue reported on code.google.com by andreas....@googlemail.com on 11 Apr 2014 at 4:54

GoogleCodeExporter commented 9 years ago
In the meanwhile I finished intensive work and testing with the DS2408/DS2413 
driver as well with the upcoming PCA9698 and PCA9530 drivers.

I came to the conclusion that the following strategy is best for getting most 
functionality and stability for digital I/O drivers:

- If a port is an input, the sensed input level is read

- If a port is an input, writing to it is assumed to be ignored or have no 
effect

- If a port is an output, the value of the output latch (if available) is read

- If a port is an output, writing to it is done to the output latches

- portRead mixes together the values from the sensed levels for inputs and the 
read values from the output latches for outputs

- portWrite just writes direct to the output latches assuming that writing to 
the output latches of ports configured as inputs have no effect (which is the 
case for the most or all chips)

- If for some reason the explicit sensing of levels for output ports may be 
necessary in special cases this may be implemented in future with some 
additional methods and a dedicated REST mapping for this case.

I have implemented this concept within the drivers above, you find all generic 
code for the input/output masking e.g. in the PCA9698 class. Maybe that code 
should make its way up to __init__ to avoid copied code, I did this not for the 
moment.

In order to have this concept used on all digital I/O drivers it will be 
necessary to update the MCPxxxx driver and use the output latch registers of 
those chips as well. As I have a MCP23008 and a MCP23017 at hand, I may be able 
to do and test this, the SPI chips testing would have to be provided by someone 
else.

The PCF8574 seems to need no update as it has quasi-bidirectional ports and has 
no output latch registers that could be used.

Andreas

Original comment by andreas....@googlemail.com on 30 Apr 2014 at 11:08