3636* PCAL9538
3737* TODO
3838
39+ Note: Some devices have the same command set and register, but different i2c addresses and register
40+ defaults. These devices should work fine with this class, but make sure the addresses are set right
41+ when initializing them.
42+
43+ :Note: By default if an (non-latched) interrupt enabled pin changes state, but changes back before
44+ the GPIO state register is read, the interrupt state will be cleared. Setting the interrupt
45+ latch will cause the device to latch on a state change of the input pin. With latching
46+ enabled, on a state change to the pin, the interrupt pin will be asserted and will not
47+ deassert until the input register is read. The value read from the input register will be
48+ the value that caused the interrupt, not nessecarially the current value of the pin. If the
49+ pin changed state, but changed back before the input register was read, the changed state
50+ will be what is returned in the register. The state change back to the original state will
51+ not trigger another interrupt as long as it happens before the input register is read. If
52+ the input register is read before the pin state changes back to the original value, both
53+ state changes will cause an interrupt.
54+
3955Heavily based on the code written by Tony DiCola for the MCP230xx library.
4056
4157* Author(s): Pat Satyshur
@@ -80,12 +96,12 @@ def __init__(self, i2c, address=_PCAL9554_ADDRESS, reset=True):
8096 super ().__init__ (
8197 i2c , address , False
8298 ) # This initializes the PCA9554 compatible registers.
83- self .capability = (
99+ self ._capability = (
84100 _enable_bit (0x00 , Capability .PULL_UP )
85101 | _enable_bit (0x00 , Capability .PULL_DOWN )
86102 | _enable_bit (0x00 , Capability .INVERT_POL )
87- ) # TODO: This device does not really have a capability to set drive mode the way
88- # digitalio is expecting. I should probably not set this here.
103+ )
104+
89105 if reset :
90106 self .reset_to_defaults ()
91107
@@ -118,6 +134,26 @@ def clear_int_pin(self, pin):
118134 self ._validate_pin (pin )
119135 self .irq_mask = _enable_bit (self .irq_mask , pin )
120136
137+ def get_interrupts (self ):
138+ """Returns a list of pins causing an interruptn along with the value of those pins.
139+ It is possible for multiple pins to be causing an interrupt. Calling this function
140+ clears the interrupt state.
141+
142+ :return: Returns a list of dicts containing items "pin" and "value". If no
143+ interrupts are triggered, this function returns none.
144+ """
145+ output = []
146+ int_status = self .irq_status
147+ pin_values = self .gpio
148+
149+ for i in range (self .maxpins ):
150+ if bool ((int_status >> i ) & 1 ):
151+ pin_val = bool (((pin_values >> i ) & 1 ))
152+ output .append ({"pin" : i , "value" : pin_val })
153+ if not output :
154+ return None
155+ return output
156+
121157 def get_int_pins (self ):
122158 """Returns a list of pins causing an interrupt. It is possible for multiple pins
123159 to be causing an interrupt. Calling this function will not clear the interrupt state.
@@ -151,16 +187,6 @@ def clear_int_latch(self, pin):
151187 self ._validate_pin (pin )
152188 self .input_latch = _clear_bit (self .input_latch , pin )
153189
154- """Interrupt latch behavior
155- By default (non-latched) if an interrupt enabled pin changes state, but changes back before the GPIO state register is read, the interrupt state
156- will be cleared. Setting the interrupt latch will cause the device to latch on a state change of the input pin. With latching enabled, on a state
157- change to the pin, the interrupt pin will be asserted and will not deassert until the input register is read. The value read from the input register
158- will be the value that caused the interrupt, not nessecarially the current value of the pin. If the pin changed state, but changed back before the
159- input register was read, the changed state will be what is returned in the register. The state change back to the original state will not trigger
160- another interrupt as long as it happens before the input register is read. If the input register is read before the pin state changes back to the
161- original value, both state changes will cause an interrupt.
162- """
163-
164190 def get_pupd (self , pin ):
165191 """Checks the state of a pin to see if pull up/down is enabled.
166192
@@ -292,7 +318,11 @@ def reset_to_defaults(self):
292318
293319 @property
294320 def out_drive (self ):
295- """Output drive strength of pins 0-7."""
321+ """The raw 'output drive strength' register. Controls the drive strength of the pins.
322+ Read and written as a 16 bit number.
323+
324+ Register address: 0x40, 0x41.
325+ """
296326 return self ._read_u16le (_PCAL9554_OUTPUT_DRIVE_1 )
297327
298328 @out_drive .setter
@@ -301,7 +331,12 @@ def out_drive(self, val):
301331
302332 @property
303333 def input_latch (self ):
304- """Sets latching or non-latching interrupts per pin."""
334+ """The raw 'input latch' register. Each bit represents the latch configuration for the
335+ matching pin. A zero indicates that the corresponding input pin is not latched. Read and
336+ written as a 8 bit number.
337+
338+ Register address: 0x42.
339+ """
305340 return self ._read_u8 (_PCAL9554_INPUT_LATCH )
306341
307342 @input_latch .setter
@@ -310,7 +345,14 @@ def input_latch(self, val):
310345
311346 @property
312347 def pupd_en (self ):
313- """reads the pull up/down status"""
348+ """The raw 'pull-up/pull-down enable' register. Each bit represents the enabled state of
349+ the pull up/down resistors for that pin. A one indicates that the pull up/down resistors
350+ are enabled. The selection of pull-up vs pull-down is done with the 'pull-up/pull-down
351+ selection register'. A zero indicates that the pull up/down resistors are disconnected.
352+ Read and written as a 8 bit number.
353+
354+ Register address: 0x43.
355+ """
314356 return self ._read_u8 (_PCAL9554_PUPD_EN )
315357
316358 @pupd_en .setter
@@ -319,7 +361,13 @@ def pupd_en(self, val):
319361
320362 @property
321363 def pupd_sel (self ):
322- """reads the pull up/down status"""
364+ """The raw 'pull-up/pull-down selection' register. Each bit enables either a pull-up or
365+ pull-down resistor on that corresponding pin. A one selects a pull-up and a zero selects a
366+ pull-down. Internal pull up/down resistors are ~100 KOhm (+/-50 KOhm). Read and written as
367+ a 8 bit number.
368+
369+ Register address: 0x44.
370+ """
323371 return self ._read_u8 (_PCAL9554_PUPD_SEL )
324372
325373 @pupd_sel .setter
@@ -328,7 +376,12 @@ def pupd_sel(self, val):
328376
329377 @property
330378 def irq_mask (self ):
331- """Masks or unmasks pins for generating interrupts."""
379+ """The raw 'interrupt mask' register. Setting a bit to one will mask interrupts on that
380+ corresponding pin. All interrupts are masked by default. Read and written as a 8 bit
381+ number.
382+
383+ Register address: 0x45.
384+ """
332385 return self ._read_u8 (_PCAL9554_IRQ_MASK )
333386
334387 @irq_mask .setter
@@ -337,7 +390,13 @@ def irq_mask(self, val):
337390
338391 @property
339392 def irq_status (self ):
340- """Indicates which pin caused an interrupt."""
393+ """The raw 'interrupt status' register. Reading this register will tell the source of an
394+ interrupt. A one read from a bit in this register indicates that the corresponding pin
395+ caused the interrupt. This register is read only. Reading from this register does not clear
396+ the interrupt state. Read and written as a 8 bit number.
397+
398+ Register address: 0x46.
399+ """
341400 return self ._read_u8 (_PCAL9554_IRQ_STATUS )
342401
343402 @irq_status .setter
@@ -347,9 +406,15 @@ def irq_status(self, val):
347406
348407 @property
349408 def out_port_config (self ):
350- """Sets output banks to open drain or push-pull operation."""
409+ """The raw 'output port configuration' register. Use bit zero of this register to set the
410+ output pins to either open-drain or push-pull operation. Set the bit to zero to configure
411+ the pins as push-pull. Set to one to configure the pins as open-drain. All other bits are
412+ reserved. Read and written as a 8 bit number.
413+
414+ Register address: 0x4F.
415+ """
351416 return self ._read_u8 (_PCAL9554_OUTPUT_PORT_CONFIG )
352417
353418 @out_port_config .setter
354419 def out_port_config (self , val ):
355- self ._write_u8 (_PCAL9554_OUTPUT_PORT_CONFIG , val )
420+ self ._write_u8 (( _PCAL9554_OUTPUT_PORT_CONFIG & 0x01 ) , val )
0 commit comments