Skip to content

Commit 8d15178

Browse files
committed
adds pca9534, pca9536, pca9537 and pca9557 IO Expander drivers.
1 parent 340b99a commit 8d15178

File tree

4 files changed

+329
-0
lines changed

4 files changed

+329
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
2+
3+
from micropython import const # NOQA
4+
import io_expander_framework
5+
6+
7+
EXIO1 = 0x01
8+
EXIO2 = 0x02
9+
EXIO3 = 0x03
10+
EXIO4 = 0x04
11+
EXIO5 = 0x05
12+
EXIO6 = 0x06
13+
EXIO7 = 0x07
14+
EXIO8 = 0x08
15+
16+
17+
_OUTPUT_PORT_REG = const(0x00)
18+
_INPUT_PORT_REG = const(0x02)
19+
_POLARITY_INVERSION_REG = const(0x02)
20+
_CONFIGURATION_REG = const(0x03)
21+
22+
23+
class Pin(io_expander_framework.Pin):
24+
_config_settings = 0x00
25+
_output_states = 0x00
26+
_reg_int_pins = []
27+
28+
@property
29+
def __bit(self):
30+
return 1 << (self._id - 1)
31+
32+
def __read_reg(self, reg):
33+
self._buf[0] = 0
34+
self._buf[1] = 0
35+
self._device.read_mem(reg, buf=self._mv)
36+
return self._buf[0] << 8 | self._buf[1]
37+
38+
def __write_reg(self, reg, value):
39+
self._buf[0] = value >> 8 & 0xFF
40+
self._buf[1] = value & 0xFF
41+
self._device.write_mem(reg, buf=self._mv)
42+
43+
def _set_dir(self, direction):
44+
if direction == self.OUT:
45+
Pin._config_settings &= ~self.__bit
46+
elif direction == self.IN:
47+
Pin._config_settings |= self.__bit
48+
else:
49+
raise ValueError('OPEN_DRAIN is not supported')
50+
51+
self.__write_reg(_CONFIGURATION_REG, Pin._config_settings)
52+
53+
def _set_level(self, level):
54+
if self._mode == self.OUT:
55+
if level:
56+
states = Pin._output_states | self.__bit
57+
else:
58+
states = Pin._output_states & ~self.__bit
59+
60+
# 0nly set if there is an actual change
61+
if states != Pin._output_states:
62+
self.__write_reg(_OUTPUT_PORT_REG, states)
63+
Pin._output_states = states
64+
65+
def _get_level(self):
66+
if self._mode == self.IN:
67+
states = self.__read_reg(_INPUT_PORT_REG)
68+
elif self._mode == self.OUT:
69+
states = Pin._output_states
70+
else:
71+
raise ValueError('Unsupported pin mode')
72+
73+
return int(bool(states & self.__bit))
74+
75+
def _set_irq(self, handler, trigger):
76+
pass
77+
78+
def _set_pull(self, pull):
79+
pass
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
2+
3+
from micropython import const # NOQA
4+
import io_expander_framework
5+
6+
7+
EXIO1 = 0x01
8+
EXIO2 = 0x02
9+
EXIO3 = 0x03
10+
EXIO4 = 0x04
11+
EXIO5 = 0x05
12+
EXIO6 = 0x06
13+
EXIO7 = 0x07
14+
EXIO8 = 0x08
15+
16+
17+
_OUTPUT_PORT_REG = const(0x00)
18+
_INPUT_PORT_REG = const(0x02)
19+
_POLARITY_INVERSION_REG = const(0x02)
20+
_CONFIGURATION_REG = const(0x03)
21+
22+
I2C_ADDR = 0x41
23+
BITS = 8
24+
25+
26+
class Pin(io_expander_framework.Pin):
27+
_config_settings = 0x00
28+
_output_states = 0x00
29+
_reg_int_pins = []
30+
31+
@property
32+
def __bit(self):
33+
return 1 << (self._id - 1)
34+
35+
def __read_reg(self, reg):
36+
self._buf[0] = 0
37+
self._buf[1] = 0
38+
self._device.read_mem(reg, buf=self._mv)
39+
return self._buf[0] << 8 | self._buf[1]
40+
41+
def __write_reg(self, reg, value):
42+
self._buf[0] = value >> 8 & 0xFF
43+
self._buf[1] = value & 0xFF
44+
self._device.write_mem(reg, buf=self._mv)
45+
46+
def _set_dir(self, direction):
47+
if direction == self.OUT:
48+
Pin._config_settings &= ~self.__bit
49+
elif direction == self.IN:
50+
Pin._config_settings |= self.__bit
51+
else:
52+
raise ValueError('OPEN_DRAIN is not supported')
53+
54+
self.__write_reg(_CONFIGURATION_REG, Pin._config_settings)
55+
56+
def _set_level(self, level):
57+
if self._mode == self.OUT:
58+
if level:
59+
states = Pin._output_states | self.__bit
60+
else:
61+
states = Pin._output_states & ~self.__bit
62+
63+
# 0nly set if there is an actual change
64+
if states != Pin._output_states:
65+
self.__write_reg(_OUTPUT_PORT_REG, states)
66+
Pin._output_states = states
67+
68+
def _get_level(self):
69+
if self._mode == self.IN:
70+
states = self.__read_reg(_INPUT_PORT_REG)
71+
elif self._mode == self.OUT:
72+
states = Pin._output_states
73+
else:
74+
raise ValueError('Unsupported pin mode')
75+
76+
return int(bool(states & self.__bit))
77+
78+
def _set_irq(self, handler, trigger):
79+
pass
80+
81+
def _set_pull(self, pull):
82+
pass
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
2+
3+
from micropython import const # NOQA
4+
import io_expander_framework
5+
6+
7+
EXIO1 = 0x01
8+
EXIO2 = 0x02
9+
EXIO3 = 0x03
10+
EXIO4 = 0x04
11+
EXIO5 = 0x05
12+
EXIO6 = 0x06
13+
EXIO7 = 0x07
14+
EXIO8 = 0x08
15+
16+
17+
_OUTPUT_PORT_REG = const(0x00)
18+
_INPUT_PORT_REG = const(0x02)
19+
_POLARITY_INVERSION_REG = const(0x02)
20+
_CONFIGURATION_REG = const(0x03)
21+
22+
I2C_ADDR = 0x49
23+
BITS = 8
24+
25+
26+
class Pin(io_expander_framework.Pin):
27+
_config_settings = 0x00
28+
_output_states = 0x00
29+
_reg_int_pins = []
30+
31+
@property
32+
def __bit(self):
33+
return 1 << (self._id - 1)
34+
35+
def __read_reg(self, reg):
36+
self._buf[0] = 0
37+
self._buf[1] = 0
38+
self._device.read_mem(reg, buf=self._mv)
39+
return self._buf[0] << 8 | self._buf[1]
40+
41+
def __write_reg(self, reg, value):
42+
self._buf[0] = value >> 8 & 0xFF
43+
self._buf[1] = value & 0xFF
44+
self._device.write_mem(reg, buf=self._mv)
45+
46+
def _set_dir(self, direction):
47+
if direction == self.OUT:
48+
Pin._config_settings &= ~self.__bit
49+
elif direction == self.IN:
50+
Pin._config_settings |= self.__bit
51+
else:
52+
raise ValueError('OPEN_DRAIN is not supported')
53+
54+
self.__write_reg(_CONFIGURATION_REG, Pin._config_settings)
55+
56+
def _set_level(self, level):
57+
if self._mode == self.OUT:
58+
if level:
59+
states = Pin._output_states | self.__bit
60+
else:
61+
states = Pin._output_states & ~self.__bit
62+
63+
# 0nly set if there is an actual change
64+
if states != Pin._output_states:
65+
self.__write_reg(_OUTPUT_PORT_REG, states)
66+
Pin._output_states = states
67+
68+
def _get_level(self):
69+
if self._mode == self.IN:
70+
states = self.__read_reg(_INPUT_PORT_REG)
71+
elif self._mode == self.OUT:
72+
states = Pin._output_states
73+
else:
74+
raise ValueError('Unsupported pin mode')
75+
76+
return int(bool(states & self.__bit))
77+
78+
def _set_irq(self, handler, trigger):
79+
pass
80+
81+
def _set_pull(self, pull):
82+
pass
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
2+
3+
from micropython import const # NOQA
4+
import io_expander_framework
5+
6+
7+
EXIO1 = 0x01
8+
EXIO2 = 0x02
9+
EXIO3 = 0x03
10+
EXIO4 = 0x04
11+
EXIO5 = 0x05
12+
EXIO6 = 0x06
13+
EXIO7 = 0x07
14+
EXIO8 = 0x08
15+
16+
17+
_OUTPUT_PORT_REG = const(0x00)
18+
_INPUT_PORT_REG = const(0x02)
19+
_POLARITY_INVERSION_REG = const(0x02)
20+
_CONFIGURATION_REG = const(0x03)
21+
22+
I2C_ADDR = 0x18
23+
BITS = 8
24+
25+
26+
_MODE_OUTPUT = const(0)
27+
_MODE_INPUT = const(1)
28+
29+
30+
class Pin(io_expander_framework.Pin):
31+
_config_settings = 0x00
32+
_output_states = 0x00
33+
_reg_int_pins = []
34+
35+
@property
36+
def __bit(self):
37+
return 1 << (self._id - 1)
38+
39+
def __read_reg(self, reg):
40+
self._buf[0] = 0
41+
self._buf[1] = 0
42+
self._device.read_mem(reg, buf=self._mv)
43+
return self._buf[0] << 8 | self._buf[1]
44+
45+
def __write_reg(self, reg, value):
46+
self._buf[0] = value >> 8 & 0xFF
47+
self._buf[1] = value & 0xFF
48+
self._device.write_mem(reg, buf=self._mv)
49+
50+
def _set_dir(self, direction):
51+
if direction == self.OUT:
52+
Pin._config_settings &= ~self.__bit
53+
elif direction == self.IN:
54+
Pin._config_settings |= self.__bit
55+
else:
56+
raise ValueError('OPEN_DRAIN is not supported')
57+
58+
self.__write_reg(_CONFIGURATION_REG, Pin._config_settings)
59+
60+
def _set_level(self, level):
61+
if self._mode == self.OUT:
62+
if level:
63+
states = Pin._output_states | self.__bit
64+
else:
65+
states = Pin._output_states & ~self.__bit
66+
67+
# 0nly set if there is an actual change
68+
if states != Pin._output_states:
69+
self.__write_reg(_OUTPUT_PORT_REG, states)
70+
Pin._output_states = states
71+
72+
def _get_level(self):
73+
if self._mode == self.IN:
74+
states = self.__read_reg(_INPUT_PORT_REG)
75+
elif self._mode == self.OUT:
76+
states = Pin._output_states
77+
else:
78+
raise ValueError('Unsupported pin mode')
79+
80+
return int(bool(states & self.__bit))
81+
82+
def _set_irq(self, handler, trigger):
83+
pass
84+
85+
def _set_pull(self, pull):
86+
pass

0 commit comments

Comments
 (0)