A software I2C interface which is a drop-in replacement for the regular mbed I2C interface in case you run out of I2C ports
Dependents: Luminocity laser-tag
This is a first version. Doesn't mean more versions will come, mainly means it may be a bit buggy. If it does not work for you: first try exactly the same code with the regular hardware I2C. If that does work, well then I made an error somewhere :D. You can send me a message if you can't figure it out, although without your hardware it generally is hard for me to reproduce.
While basic I2C should work, advanced things like clock stretching and multi-master I2C busses are not supported.
If you find an error and solve it: Send a pull request and I generally will accept it :).
Revision 1:05473196d133, committed 2016-11-28
- Comitter:
- Sissors
- Date:
- Mon Nov 28 19:55:30 2016 +0000
- Parent:
- 0:fee70b6fe0e9
- Commit message:
- Changed scl to push pull during transactions
; More efficient and we don't support clock stretching anyway
; Using OpenDrain mode maybe for future, however is device dependent
Changed in this revision
SoftI2C.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r fee70b6fe0e9 -r 05473196d133 SoftI2C.cpp --- a/SoftI2C.cpp Tue Nov 22 20:45:35 2016 +0000 +++ b/SoftI2C.cpp Mon Nov 28 19:55:30 2016 +0000 @@ -59,11 +59,11 @@ int SoftI2C::read(int ack) { int retval = 0; + _scl.output(); // Shift the bits out, msb first for (int i = 7; i>=0; i--) { //SCL low - _scl.output(); _scl.write(0); _sda.input(); wait_us(delay_us); @@ -73,12 +73,11 @@ wait_us(delay_us); //SCL high again - _scl.input(); + _scl.write(1); wait_us(delay_us << 1); //wait two delays } // Last cycle to set the ACK - _scl.output(); _scl.write(0); if ( ack ) { _sda.output(); @@ -88,7 +87,7 @@ } wait_us(delay_us << 1); - _scl.input(); + _scl.write(1); wait_us(delay_us << 1); @@ -96,10 +95,11 @@ } int SoftI2C::write(int data) { + _scl.output(); + // Shift the bits out, msb first for (int i = 7; i>=0; i--) { //SCL low - _scl.output(); _scl.write(0); wait_us(delay_us); @@ -113,19 +113,18 @@ wait_us(delay_us); //SCL high again - _scl.input(); + _scl.write(1); wait_us(delay_us << 1); //wait two delays } // Last cycle to get the ACK - _scl.output(); _scl.write(0); wait_us(delay_us); _sda.input(); wait_us(delay_us); - _scl.input(); + _scl.write(1); wait_us(delay_us); int retval = ~_sda.read(); //Read the ack wait_us(delay_us); @@ -140,7 +139,7 @@ _scl.output(); _scl.write(0); wait_us(delay_us << 1); - _scl.input(); + _scl.write(1); wait_us(delay_us << 1); } // Pull SDA low