@@ -107,18 +107,28 @@ void SX1509::reset(bool hardware)
107
107
}
108
108
}
109
109
110
- void SX1509::pinDir (byte pin, byte inOut)
110
+ void SX1509::pinDir (byte pin, byte inOut, byte initialLevel )
111
111
{
112
112
// The SX1509 RegDir registers: REG_DIR_B, REG_DIR_A
113
113
// 0: IO is configured as an output
114
114
// 1: IO is configured as an input
115
115
byte modeBit;
116
116
if ((inOut == OUTPUT) || (inOut == ANALOG_OUTPUT))
117
+ {
118
+ uint16_t tempRegData = readWord (REG_DATA_B);
119
+ if (initialLevel == LOW)
120
+ {
121
+ tempRegData &= ~(1 << pin);
122
+ writeWord (REG_DATA_B, tempRegData);
123
+ }
117
124
modeBit = 0 ;
125
+ }
118
126
else
127
+ {
119
128
modeBit = 1 ;
129
+ }
120
130
121
- unsigned int tempRegDir = readWord (REG_DIR_B);
131
+ uint16_t tempRegDir = readWord (REG_DIR_B);
122
132
if (modeBit)
123
133
tempRegDir |= (1 << pin);
124
134
else
@@ -136,73 +146,104 @@ void SX1509::pinDir(byte pin, byte inOut)
136
146
}
137
147
}
138
148
139
- void SX1509::pinMode (byte pin, byte inOut)
149
+ void SX1509::pinMode (byte pin, byte inOut, byte initialLevel )
140
150
{
141
- pinDir (pin, inOut);
151
+ pinDir (pin, inOut, initialLevel );
142
152
}
143
153
144
- void SX1509::writePin (byte pin, byte highLow)
154
+ bool SX1509::writePin (byte pin, byte highLow)
145
155
{
146
- unsigned int tempRegDir = readWord (REG_DIR_B);
156
+
157
+ uint16_t tempRegDir = readWord (REG_DIR_B);
147
158
148
159
if ((0xFFFF ^ tempRegDir) & (1 << pin)) // If the pin is an output, write high/low
149
160
{
150
- unsigned int tempRegData = readWord (REG_DATA_B);
161
+ uint16_t tempRegData = readWord (REG_DATA_B);
151
162
if (highLow)
152
163
tempRegData |= (1 << pin);
153
164
else
154
165
tempRegData &= ~(1 << pin);
155
- writeWord (REG_DATA_B, tempRegData);
166
+ return writeWord (REG_DATA_B, tempRegData);
156
167
}
157
168
else // Otherwise the pin is an input, pull-up/down
158
169
{
159
- unsigned int tempPullUp = readWord (REG_PULL_UP_B);
160
- unsigned int tempPullDown = readWord (REG_PULL_DOWN_B);
170
+ uint16_t tempPullUp = readWord (REG_PULL_UP_B);
171
+ uint16_t tempPullDown = readWord (REG_PULL_DOWN_B);
161
172
162
173
if (highLow) // if HIGH, do pull-up, disable pull-down
163
174
{
164
175
tempPullUp |= (1 << pin);
165
176
tempPullDown &= ~(1 << pin);
166
- writeWord (REG_PULL_UP_B, tempPullUp);
167
- writeWord (REG_PULL_DOWN_B, tempPullDown);
177
+ return writeWord (REG_PULL_UP_B, tempPullUp) && writeWord (REG_PULL_DOWN_B, tempPullDown);
168
178
}
169
179
else // If LOW do pull-down, disable pull-up
170
180
{
171
181
tempPullDown |= (1 << pin);
172
182
tempPullUp &= ~(1 << pin);
173
- writeWord (REG_PULL_UP_B, tempPullUp);
174
- writeWord (REG_PULL_DOWN_B, tempPullDown);
183
+ return writeWord (REG_PULL_UP_B, tempPullUp) && writeWord (REG_PULL_DOWN_B, tempPullDown);
175
184
}
176
185
}
177
186
}
178
187
179
- void SX1509::digitalWrite (byte pin, byte highLow)
188
+ bool SX1509::digitalWrite (byte pin, byte highLow)
180
189
{
181
- writePin (pin, highLow);
190
+ return writePin (pin, highLow);
182
191
}
183
192
184
193
byte SX1509::readPin (byte pin)
185
194
{
186
- unsigned int tempRegDir = readWord (REG_DIR_B);
195
+ uint16_t tempRegDir = readWord (REG_DIR_B);
187
196
188
197
if (tempRegDir & (1 << pin)) // If the pin is an input
189
198
{
190
- unsigned int tempRegData = readWord (REG_DATA_B);
199
+ uint16_t tempRegData = readWord (REG_DATA_B);
191
200
if (tempRegData & (1 << pin))
192
201
return 1 ;
193
202
}
203
+ else
204
+ {
205
+ // log_d("Pin %d not INPUT, REG_DIR_B: %d", pin, tempRegDir);
206
+ }
194
207
195
208
return 0 ;
196
209
}
197
210
211
+ bool SX1509::readPin (const byte pin, bool *value)
212
+ {
213
+ uint16_t tempRegDir;
214
+ if (readWord (REG_DIR_B, &tempRegDir))
215
+ {
216
+ if (tempRegDir & (1 << pin))
217
+ { // If the pin is an input
218
+ uint16_t tempRegData;
219
+ if (readWord (REG_DATA_B, &tempRegData))
220
+ {
221
+ *value = (tempRegData & (1 << pin)) != 0 ;
222
+ return true ;
223
+ };
224
+ }
225
+ else
226
+ {
227
+ *value = false ;
228
+ return true ;
229
+ }
230
+ }
231
+ return false ;
232
+ }
233
+
198
234
byte SX1509::digitalRead (byte pin)
199
235
{
200
236
return readPin (pin);
201
237
}
202
238
239
+ bool SX1509::digitalRead (byte pin, bool *value)
240
+ {
241
+ return readPin (pin, value);
242
+ }
243
+
203
244
void SX1509::ledDriverInit (byte pin, byte freq /* = 1*/ , bool log /* = false*/ )
204
245
{
205
- unsigned int tempWord;
246
+ uint16_t tempWord;
206
247
byte tempByte;
207
248
208
249
// Disable input buffer
@@ -339,7 +380,7 @@ void SX1509::setupBlink(byte pin, byte tOn, byte tOff, byte onIntensity, byte of
339
380
340
381
void SX1509::keypad (byte rows, byte columns, unsigned int sleepTime, byte scanTime, byte debounceTime)
341
382
{
342
- unsigned int tempWord;
383
+ uint16_t tempWord;
343
384
byte tempByte;
344
385
345
386
// If clock hasn't been set up, set it to internal 2MHz
@@ -544,7 +585,7 @@ void SX1509::debounceKeypad(byte time, byte numRows, byte numCols)
544
585
void SX1509::enableInterrupt (byte pin, byte riseFall)
545
586
{
546
587
// Set REG_INTERRUPT_MASK
547
- unsigned int tempWord = readWord (REG_INTERRUPT_MASK_B);
588
+ uint16_t tempWord = readWord (REG_INTERRUPT_MASK_B);
548
589
tempWord &= ~(1 << pin); // 0 = event on IO will trigger interrupt
549
590
writeWord (REG_INTERRUPT_MASK_B, tempWord);
550
591
@@ -694,7 +735,7 @@ byte SX1509::readByte(byte registerAddress)
694
735
_i2cPort->endTransmission ();
695
736
_i2cPort->requestFrom (deviceAddress, (byte)1 );
696
737
697
- readValue = Wire. read ();
738
+ readValue = _i2cPort-> read ();
698
739
699
740
return readValue;
700
741
}
@@ -704,10 +745,10 @@ byte SX1509::readByte(byte registerAddress)
704
745
// - A 16-bit unsigned int will be returned.
705
746
// - The msb of the return value will contain the value read from registerAddress
706
747
// - The lsb of the return value will contain the value read from registerAddress + 1
707
- unsigned int SX1509::readWord (byte registerAddress)
748
+ uint16_t SX1509::readWord (byte registerAddress)
708
749
{
709
- unsigned int readValue;
710
- unsigned int msb, lsb;
750
+ uint16_t readValue;
751
+ uint16_t msb, lsb;
711
752
unsigned int timeout = RECEIVE_TIMEOUT_VALUE * 2 ;
712
753
713
754
_i2cPort->beginTransmission (deviceAddress);
@@ -722,53 +763,79 @@ unsigned int SX1509::readWord(byte registerAddress)
722
763
return readValue;
723
764
}
724
765
766
+ bool SX1509::readByte (byte registerAddress, byte *value)
767
+ {
768
+ return readBytes (registerAddress, value, 1 );
769
+ }
770
+
771
+ // readWord(byte registerAddress)
772
+ // This function will read a two-byte word beginning at registerAddress
773
+ // - A 16-bit unsigned int will be set in value.
774
+ // - The msb of the return value will contain the value read from registerAddress
775
+ // - The lsb of the return value will contain the value read from registerAddress + 1
776
+ // - Return boolean true if succesfull
777
+ bool SX1509::readWord (byte registerAddress, uint16_t *value)
778
+ {
779
+ byte dest[2 ];
780
+ if (readBytes (registerAddress, dest, 2 ))
781
+ {
782
+ value[0 ] = dest[1 ];
783
+ value[1 ] = dest[0 ];
784
+ return true ;
785
+ }
786
+ return false ;
787
+ }
788
+
725
789
// readBytes(byte firstRegisterAddress, byte * destination, byte length)
726
790
// This function reads a series of bytes incrementing from a given address
727
- // - firstRegsiterAddress is the first address to be read
791
+ // - firstRegisterAddress is the first address to be read
728
792
// - destination is an array of bytes where the read values will be stored into
729
793
// - length is the number of bytes to be read
730
- // - No return value.
731
- void SX1509::readBytes (byte firstRegisterAddress, byte *destination, byte length)
794
+ // - Return boolean true if succesfull
795
+ bool SX1509::readBytes (byte firstRegisterAddress, byte *destination, byte length)
732
796
{
733
797
_i2cPort->beginTransmission (deviceAddress);
734
798
_i2cPort->write (firstRegisterAddress);
735
- _i2cPort->endTransmission ();
736
- _i2cPort->requestFrom (deviceAddress, length);
799
+ uint8_t endResult = _i2cPort->endTransmission ();
800
+ bool result = (endResult == I2C_ERROR_OK) && ( _i2cPort->requestFrom (deviceAddress, length) == length);
737
801
738
- for ( int i = 0 ; i < length; i++ )
802
+ if (result )
739
803
{
740
- destination[i] = _i2cPort->read ();
804
+ for (int i = 0 ; i < length; i++)
805
+ {
806
+ destination[i] = _i2cPort->read ();
807
+ }
741
808
}
809
+ return result;
742
810
}
743
811
744
812
// writeByte(byte registerAddress, byte writeValue)
745
813
// This function writes a single byte to a single register on the SX509.
746
814
// - writeValue is written to registerAddress
747
815
// - deviceAddres should already be set from the constructor
748
- // - No return value.
749
- void SX1509::writeByte (byte registerAddress, byte writeValue)
816
+ // - Return value: true if succeeded, false if failed
817
+ bool SX1509::writeByte (byte registerAddress, byte writeValue)
750
818
{
751
819
_i2cPort->beginTransmission (deviceAddress);
752
- _i2cPort->write (registerAddress);
753
- _i2cPort->write (writeValue );
754
- _i2cPort-> endTransmission ( );
820
+ bool result = _i2cPort->write (registerAddress) && _i2cPort-> write (writeValue );
821
+ uint8_t endResult = _i2cPort->endTransmission ( );
822
+ return result && (endResult == I2C_ERROR_OK );
755
823
}
756
824
757
825
// writeWord(byte registerAddress, ungisnged int writeValue)
758
826
// This function writes a two-byte word to registerAddress and registerAddress + 1
759
827
// - the upper byte of writeValue is written to registerAddress
760
828
// - the lower byte of writeValue is written to registerAddress + 1
761
- // - No return value.
762
- void SX1509::writeWord (byte registerAddress, unsigned int writeValue)
829
+ // - Return value: true if succeeded, false if failed
830
+ bool SX1509::writeWord (byte registerAddress, uint16_t writeValue)
763
831
{
764
832
byte msb, lsb;
765
833
msb = ((writeValue & 0xFF00 ) >> 8 );
766
834
lsb = (writeValue & 0x00FF );
767
835
_i2cPort->beginTransmission (deviceAddress);
768
- _i2cPort->write (registerAddress);
769
- _i2cPort->write (msb);
770
- _i2cPort->write (lsb);
771
- _i2cPort->endTransmission ();
836
+ bool result = _i2cPort->write (registerAddress) && _i2cPort->write (msb) && _i2cPort->write (lsb);
837
+ uint8_t endResult = _i2cPort->endTransmission ();
838
+ return result && (endResult == I2C_ERROR_OK);
772
839
}
773
840
774
841
// writeBytes(byte firstRegisterAddress, byte * writeArray, byte length)
@@ -777,14 +844,16 @@ void SX1509::writeWord(byte registerAddress, unsigned int writeValue)
777
844
// - All writes following will be at incremental register addresses.
778
845
// - writeArray should be an array of byte values to be written.
779
846
// - length should be the number of bytes to be written.
780
- // - no return value.
781
- void SX1509::writeBytes (byte firstRegisterAddress, byte *writeArray, byte length)
847
+ // - Return value: true if succeeded, false if failed
848
+ bool SX1509::writeBytes (byte firstRegisterAddress, byte *writeArray, byte length)
782
849
{
783
850
_i2cPort->beginTransmission (deviceAddress);
784
- _i2cPort->write (firstRegisterAddress);
785
- for (int i = 0 ; i < length; i++)
851
+ bool result = _i2cPort->write (firstRegisterAddress);
852
+ int i = 0 ;
853
+ while (result && i < length)
786
854
{
787
- _i2cPort->write (writeArray[i]);
855
+ result = _i2cPort->write (writeArray[i++ ]);
788
856
}
789
- _i2cPort->endTransmission ();
857
+ uint8_t endResult = _i2cPort->endTransmission ();
858
+ return result && (endResult == I2C_ERROR_OK);
790
859
}
0 commit comments