Skip to content

Commit 2f9124a

Browse files
authored
Merge pull request #10 from I-Connect/EndTransmissionResult
Return result of I2C write and readmethods
2 parents 32bc8e7 + 0b3d4ce commit 2f9124a

File tree

2 files changed

+171
-95
lines changed

2 files changed

+171
-95
lines changed

src/SparkFunSX1509.cpp

Lines changed: 118 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,28 @@ void SX1509::reset(bool hardware)
107107
}
108108
}
109109

110-
void SX1509::pinDir(byte pin, byte inOut)
110+
void SX1509::pinDir(byte pin, byte inOut, byte initialLevel)
111111
{
112112
// The SX1509 RegDir registers: REG_DIR_B, REG_DIR_A
113113
// 0: IO is configured as an output
114114
// 1: IO is configured as an input
115115
byte modeBit;
116116
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+
}
117124
modeBit = 0;
125+
}
118126
else
127+
{
119128
modeBit = 1;
129+
}
120130

121-
unsigned int tempRegDir = readWord(REG_DIR_B);
131+
uint16_t tempRegDir = readWord(REG_DIR_B);
122132
if (modeBit)
123133
tempRegDir |= (1 << pin);
124134
else
@@ -136,73 +146,104 @@ void SX1509::pinDir(byte pin, byte inOut)
136146
}
137147
}
138148

139-
void SX1509::pinMode(byte pin, byte inOut)
149+
void SX1509::pinMode(byte pin, byte inOut, byte initialLevel)
140150
{
141-
pinDir(pin, inOut);
151+
pinDir(pin, inOut, initialLevel);
142152
}
143153

144-
void SX1509::writePin(byte pin, byte highLow)
154+
bool SX1509::writePin(byte pin, byte highLow)
145155
{
146-
unsigned int tempRegDir = readWord(REG_DIR_B);
156+
157+
uint16_t tempRegDir = readWord(REG_DIR_B);
147158

148159
if ((0xFFFF ^ tempRegDir) & (1 << pin)) // If the pin is an output, write high/low
149160
{
150-
unsigned int tempRegData = readWord(REG_DATA_B);
161+
uint16_t tempRegData = readWord(REG_DATA_B);
151162
if (highLow)
152163
tempRegData |= (1 << pin);
153164
else
154165
tempRegData &= ~(1 << pin);
155-
writeWord(REG_DATA_B, tempRegData);
166+
return writeWord(REG_DATA_B, tempRegData);
156167
}
157168
else // Otherwise the pin is an input, pull-up/down
158169
{
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);
161172

162173
if (highLow) // if HIGH, do pull-up, disable pull-down
163174
{
164175
tempPullUp |= (1 << pin);
165176
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);
168178
}
169179
else // If LOW do pull-down, disable pull-up
170180
{
171181
tempPullDown |= (1 << pin);
172182
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);
175184
}
176185
}
177186
}
178187

179-
void SX1509::digitalWrite(byte pin, byte highLow)
188+
bool SX1509::digitalWrite(byte pin, byte highLow)
180189
{
181-
writePin(pin, highLow);
190+
return writePin(pin, highLow);
182191
}
183192

184193
byte SX1509::readPin(byte pin)
185194
{
186-
unsigned int tempRegDir = readWord(REG_DIR_B);
195+
uint16_t tempRegDir = readWord(REG_DIR_B);
187196

188197
if (tempRegDir & (1 << pin)) // If the pin is an input
189198
{
190-
unsigned int tempRegData = readWord(REG_DATA_B);
199+
uint16_t tempRegData = readWord(REG_DATA_B);
191200
if (tempRegData & (1 << pin))
192201
return 1;
193202
}
203+
else
204+
{
205+
// log_d("Pin %d not INPUT, REG_DIR_B: %d", pin, tempRegDir);
206+
}
194207

195208
return 0;
196209
}
197210

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+
198234
byte SX1509::digitalRead(byte pin)
199235
{
200236
return readPin(pin);
201237
}
202238

239+
bool SX1509::digitalRead(byte pin, bool *value)
240+
{
241+
return readPin(pin, value);
242+
}
243+
203244
void SX1509::ledDriverInit(byte pin, byte freq /*= 1*/, bool log /*= false*/)
204245
{
205-
unsigned int tempWord;
246+
uint16_t tempWord;
206247
byte tempByte;
207248

208249
// Disable input buffer
@@ -339,7 +380,7 @@ void SX1509::setupBlink(byte pin, byte tOn, byte tOff, byte onIntensity, byte of
339380

340381
void SX1509::keypad(byte rows, byte columns, unsigned int sleepTime, byte scanTime, byte debounceTime)
341382
{
342-
unsigned int tempWord;
383+
uint16_t tempWord;
343384
byte tempByte;
344385

345386
// 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)
544585
void SX1509::enableInterrupt(byte pin, byte riseFall)
545586
{
546587
// Set REG_INTERRUPT_MASK
547-
unsigned int tempWord = readWord(REG_INTERRUPT_MASK_B);
588+
uint16_t tempWord = readWord(REG_INTERRUPT_MASK_B);
548589
tempWord &= ~(1 << pin); // 0 = event on IO will trigger interrupt
549590
writeWord(REG_INTERRUPT_MASK_B, tempWord);
550591

@@ -694,7 +735,7 @@ byte SX1509::readByte(byte registerAddress)
694735
_i2cPort->endTransmission();
695736
_i2cPort->requestFrom(deviceAddress, (byte)1);
696737

697-
readValue = Wire.read();
738+
readValue = _i2cPort->read();
698739

699740
return readValue;
700741
}
@@ -704,10 +745,10 @@ byte SX1509::readByte(byte registerAddress)
704745
// - A 16-bit unsigned int will be returned.
705746
// - The msb of the return value will contain the value read from registerAddress
706747
// - 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)
708749
{
709-
unsigned int readValue;
710-
unsigned int msb, lsb;
750+
uint16_t readValue;
751+
uint16_t msb, lsb;
711752
unsigned int timeout = RECEIVE_TIMEOUT_VALUE * 2;
712753

713754
_i2cPort->beginTransmission(deviceAddress);
@@ -722,53 +763,79 @@ unsigned int SX1509::readWord(byte registerAddress)
722763
return readValue;
723764
}
724765

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+
725789
// readBytes(byte firstRegisterAddress, byte * destination, byte length)
726790
// 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
728792
// - destination is an array of bytes where the read values will be stored into
729793
// - 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)
732796
{
733797
_i2cPort->beginTransmission(deviceAddress);
734798
_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);
737801

738-
for (int i = 0; i < length; i++)
802+
if (result)
739803
{
740-
destination[i] = _i2cPort->read();
804+
for (int i = 0; i < length; i++)
805+
{
806+
destination[i] = _i2cPort->read();
807+
}
741808
}
809+
return result;
742810
}
743811

744812
// writeByte(byte registerAddress, byte writeValue)
745813
// This function writes a single byte to a single register on the SX509.
746814
// - writeValue is written to registerAddress
747815
// - 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)
750818
{
751819
_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);
755823
}
756824

757825
// writeWord(byte registerAddress, ungisnged int writeValue)
758826
// This function writes a two-byte word to registerAddress and registerAddress + 1
759827
// - the upper byte of writeValue is written to registerAddress
760828
// - 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)
763831
{
764832
byte msb, lsb;
765833
msb = ((writeValue & 0xFF00) >> 8);
766834
lsb = (writeValue & 0x00FF);
767835
_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);
772839
}
773840

774841
// writeBytes(byte firstRegisterAddress, byte * writeArray, byte length)
@@ -777,14 +844,16 @@ void SX1509::writeWord(byte registerAddress, unsigned int writeValue)
777844
// - All writes following will be at incremental register addresses.
778845
// - writeArray should be an array of byte values to be written.
779846
// - 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)
782849
{
783850
_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)
786854
{
787-
_i2cPort->write(writeArray[i]);
855+
result = _i2cPort->write(writeArray[i++]);
788856
}
789-
_i2cPort->endTransmission();
857+
uint8_t endResult = _i2cPort->endTransmission();
858+
return result && (endResult == I2C_ERROR_OK);
790859
}

0 commit comments

Comments
 (0)