@@ -49,19 +49,12 @@ static constexpr uint8_t REG_PWM3_DUTY_H = 0x20;
4949static constexpr uint8_t REG_PWM4_DUTY_L = 0x21 ;
5050static constexpr uint8_t REG_PWM4_DUTY_H = 0x22 ;
5151
52- void PY32IOExpander_Class::_writeBit (uint8_t reg_l, uint8_t reg_h, uint8_t pin, bool value)
52+ bool PY32IOExpander_Class::_writeBit (uint8_t reg_l, uint8_t reg_h, uint8_t pin, bool value)
5353{
5454 if (pin < 8 ) {
55- if (value)
56- bitOn (reg_l, 1 << pin);
57- else
58- bitOff (reg_l, 1 << pin);
59- } else {
60- if (value)
61- bitOn (reg_h, 1 << (pin - 8 ));
62- else
63- bitOff (reg_h, 1 << (pin - 8 ));
55+ return value ? bitOn (reg_l, 1 << pin) : bitOff (reg_l, 1 << pin);
6456 }
57+ return value ? bitOn (reg_h, 1 << (pin - 8 )) : bitOff (reg_h, 1 << (pin - 8 ));
6558}
6659
6760bool PY32IOExpander_Class::_readBit (uint8_t reg_l, uint8_t reg_h, uint8_t pin)
@@ -80,95 +73,133 @@ bool PY32IOExpander_Class::begin()
8073 return true ;
8174}
8275
83- void PY32IOExpander_Class::setDirection (uint8_t pin, bool direction)
76+ bool PY32IOExpander_Class::_setDirection (uint8_t pin, bool direction)
8477{
8578 // direction: false=input (0), true=output (1)
86- _writeBit (REG_GPIO_M_L , REG_GPIO_M_H , pin, direction);
79+ if (!_isValidPin (pin)) return false ;
80+ return _writeBit (REG_GPIO_M_L , REG_GPIO_M_H , pin, direction);
8781}
8882
89- void PY32IOExpander_Class::enablePull (uint8_t pin, bool enablePull )
83+ bool PY32IOExpander_Class::_setPullMode (uint8_t pin, gpio_pull_t mode )
9084{
91- if (enablePull) {
92- // Enable Pull Up by default if neither is set
93- bool pu = _readBit ( REG_GPIO_PU_L , REG_GPIO_PU_H , pin);
94- bool pd = _readBit ( REG_GPIO_PD_L , REG_GPIO_PD_H , pin);
95- if (!pu && !pd) {
96- _writeBit ( REG_GPIO_PU_L , REG_GPIO_PU_H , pin, true ) ;
85+ if (! _isValidPin (pin)) return false ;
86+ switch (mode) {
87+ case pull_none: {
88+ bool pu_ok = _writeBit ( REG_GPIO_PU_L , REG_GPIO_PU_H , pin, false );
89+ bool pd_ok = _writeBit ( REG_GPIO_PD_L , REG_GPIO_PD_H , pin, false );
90+ return pu_ok && pd_ok ;
9791 }
98- // If one is already set, leave it.
99- } else {
100- // Disable both
101- _writeBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin, false );
102- _writeBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin, false );
103- }
104- }
105-
106- void PY32IOExpander_Class::setPullMode (uint8_t pin, bool mode)
107- {
108- // mode: false=down, true=up
109- if (mode) {
110- // Pull Up
111- _writeBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin, false );
112- _writeBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin, true );
113- } else {
114- // Pull Down
115- _writeBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin, false );
116- _writeBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin, true );
92+ case pull_up: {
93+ bool pd_ok = _writeBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin, false );
94+ bool pu_ok = _writeBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin, true );
95+ return pd_ok && pu_ok;
96+ }
97+ case pull_down: {
98+ bool pu_ok = _writeBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin, false );
99+ bool pd_ok = _writeBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin, true );
100+ return pu_ok && pd_ok;
101+ }
102+ default :
103+ return false ;
117104 }
118105}
119106
120107void PY32IOExpander_Class::setDriveMode (uint8_t pin, bool openDrain)
121108{
122109 // openDrain: false=push-pull (0), true=open-drain (1)
110+ if (!_isValidPin (pin)) return ;
123111 _writeBit (REG_GPIO_DRV_L , REG_GPIO_DRV_H , pin, openDrain);
124112}
125113
126- void PY32IOExpander_Class::setHighImpedance (uint8_t pin, bool enable)
114+ bool PY32IOExpander_Class::_setHighImpedance (uint8_t pin, bool enable)
127115{
128- if (enable) {
129- // Input mode
130- setDirection (pin, false );
131- // Disable pulls
132- enablePull (pin, false );
133- }
116+ if (! _isValidPin (pin)) return false ;
117+ if (!enable) return true ;
118+ // Input mode with the pulls disabled
119+ bool dir_ok = _setDirection (pin, false );
120+ bool pull_ok = _setPullMode (pin, pull_none );
121+ return dir_ok && pull_ok;
134122}
135123
136124bool PY32IOExpander_Class::getWriteValue (uint8_t pin)
137125{
126+ if (!_isValidPin (pin)) return false ;
138127 return _readBit (REG_GPIO_O_L , REG_GPIO_O_H , pin);
139128}
140129
141- void PY32IOExpander_Class::digitalWrite (uint8_t pin, bool level)
130+ bool PY32IOExpander_Class::_digitalWrite (uint8_t pin, bool level)
142131{
143- _writeBit (REG_GPIO_O_L , REG_GPIO_O_H , pin, level);
132+ if (!_isValidPin (pin)) return false ;
133+ return _writeBit (REG_GPIO_O_L , REG_GPIO_O_H , pin, level);
144134}
145135
146136bool PY32IOExpander_Class::digitalRead (uint8_t pin)
147137{
138+ if (!_isValidPin (pin)) return false ;
148139 return _readBit (REG_GPIO_I_L , REG_GPIO_I_H , pin);
149140}
150141
151- void PY32IOExpander_Class::resetIrq ()
142+ bool PY32IOExpander_Class::_resetIrq ()
152143{
153144 // Clear all interrupts by writing 1s to IS registers
154- writeRegister8 (REG_GPIO_IS_L , 0xFF );
155- writeRegister8 (REG_GPIO_IS_H , 0xFF ); // Only bits 0-5 used for high byte (pins 8-13)
145+ bool l_ok = writeRegister8 (REG_GPIO_IS_L , 0xFF );
146+ bool h_ok = writeRegister8 (REG_GPIO_IS_H , 0xFF ); // Only bits 0-5 used for high byte (pins 8-13)
147+ return l_ok && h_ok;
156148}
157149
158- void PY32IOExpander_Class::disableIrq ()
150+ bool PY32IOExpander_Class::_disableIrq ()
159151{
160152 // Disable all interrupts
161- writeRegister8 (REG_GPIO_IE_L , 0x00 );
162- writeRegister8 (REG_GPIO_IE_H , 0x00 );
153+ bool l_ok = writeRegister8 (REG_GPIO_IE_L , 0x00 );
154+ bool h_ok = writeRegister8 (REG_GPIO_IE_H , 0x00 );
155+ return l_ok && h_ok;
163156}
164157
165- void PY32IOExpander_Class::enableIrq ()
158+ bool PY32IOExpander_Class::_enableIrq ()
166159{
167160 // Enable all interrupts
168- writeRegister8 (REG_GPIO_IE_L , 0xFF );
169- writeRegister8 (REG_GPIO_IE_H , 0x3F ); // Pins 8-13
161+ bool l_ok = writeRegister8 (REG_GPIO_IE_L , 0xFF );
162+ bool h_ok = writeRegister8 (REG_GPIO_IE_H , 0x3F ); // Pins 8-13
163+ return l_ok && h_ok;
170164}
171165
166+ void PY32IOExpander_Class::enablePull (uint8_t pin, bool enablePull)
167+ {
168+ if (!_isValidPin (pin)) return ;
169+ if (enablePull) {
170+ // Enable Pull Up by default if neither is set
171+ bool pu = _readBit (REG_GPIO_PU_L , REG_GPIO_PU_H , pin);
172+ bool pd = _readBit (REG_GPIO_PD_L , REG_GPIO_PD_H , pin);
173+ if (!pu && !pd) {
174+ _setPullMode (pin, pull_up);
175+ }
176+ // If one is already set, leave it.
177+ } else {
178+ _setPullMode (pin, pull_none);
179+ }
180+ }
181+
182+ #if PY32IOEXPANDER_STATUS_API
183+ bool PY32IOExpander_Class::setDirection (uint8_t pin, bool direction) { return _setDirection (pin, direction); }
184+ bool PY32IOExpander_Class::setPullMode (uint8_t pin, gpio_pull_t mode) { return _setPullMode (pin, mode); }
185+ bool PY32IOExpander_Class::setPullMode (uint8_t pin, bool mode) { return _setPullMode (pin, mode ? pull_up : pull_down); }
186+ bool PY32IOExpander_Class::setHighImpedance (uint8_t pin, bool enable) { return _setHighImpedance (pin, enable); }
187+ bool PY32IOExpander_Class::digitalWrite (uint8_t pin, bool level) { return _digitalWrite (pin, level); }
188+ bool PY32IOExpander_Class::resetIrq () { return _resetIrq (); }
189+ bool PY32IOExpander_Class::disableIrq () { return _disableIrq (); }
190+ bool PY32IOExpander_Class::enableIrq () { return _enableIrq (); }
191+ #else
192+ void PY32IOExpander_Class::setDirection (uint8_t pin, bool direction) { _setDirection (pin, direction); }
193+ // mode: false=down, true=up
194+ void PY32IOExpander_Class::setPullMode (uint8_t pin, bool mode) { _setPullMode (pin, mode ? pull_up : pull_down); }
195+ bool PY32IOExpander_Class::setPullMode (uint8_t pin, gpio_pull_t mode) { return _setPullMode (pin, mode); }
196+ void PY32IOExpander_Class::setHighImpedance (uint8_t pin, bool enable) { _setHighImpedance (pin, enable); }
197+ void PY32IOExpander_Class::digitalWrite (uint8_t pin, bool level) { _digitalWrite (pin, level); }
198+ void PY32IOExpander_Class::resetIrq () { _resetIrq (); }
199+ void PY32IOExpander_Class::disableIrq () { _disableIrq (); }
200+ void PY32IOExpander_Class::enableIrq () { _enableIrq (); }
201+ #endif
202+
172203uint16_t PY32IOExpander_Class::readDeviceUID ()
173204{
174205 uint8_t l = readRegister8 (REG_UID_L );
0 commit comments