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 :).

Committer:
Sissors
Date:
Mon Nov 28 19:55:30 2016 +0000
Revision:
1:05473196d133
Parent:
0:fee70b6fe0e9
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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:fee70b6fe0e9 1 #include "mbed.h"
Sissors 0:fee70b6fe0e9 2
Sissors 0:fee70b6fe0e9 3 #ifndef SOFTI2C_H
Sissors 0:fee70b6fe0e9 4 #define SOFTI2C_H
Sissors 0:fee70b6fe0e9 5
Sissors 0:fee70b6fe0e9 6 /**
Sissors 0:fee70b6fe0e9 7 * A software I2C class in case you run out of hardware I2C pins or cannot use
Sissors 0:fee70b6fe0e9 8 * those for another reason.
Sissors 0:fee70b6fe0e9 9 *
Sissors 0:fee70b6fe0e9 10 * The class is a drop-in replacement of the classic mbed I2C class: include
Sissors 0:fee70b6fe0e9 11 * this file in your program, replace I2C with SoftI2C when creating the object
Sissors 0:fee70b6fe0e9 12 * and it should work properly without other modifications.
Sissors 0:fee70b6fe0e9 13 */
Sissors 0:fee70b6fe0e9 14 class SoftI2C {
Sissors 0:fee70b6fe0e9 15 public:
Sissors 0:fee70b6fe0e9 16 /**
Sissors 0:fee70b6fe0e9 17 * Create an software I2C Master interface, connected to the specified pins
Sissors 0:fee70b6fe0e9 18 *
Sissors 0:fee70b6fe0e9 19 * @param sda I2C data pin
Sissors 0:fee70b6fe0e9 20 * @param scl I2C clock pin
Sissors 0:fee70b6fe0e9 21 */
Sissors 0:fee70b6fe0e9 22 SoftI2C(PinName sda, PinName scl);
Sissors 0:fee70b6fe0e9 23
Sissors 0:fee70b6fe0e9 24 /**
Sissors 0:fee70b6fe0e9 25 * Set the frequency of the I2C interface.
Sissors 0:fee70b6fe0e9 26 *
Sissors 0:fee70b6fe0e9 27 * Note that the delay of the DigitalInOuts is not compensated: the real
Sissors 0:fee70b6fe0e9 28 * frequency will be lower than the one set. However since I2C is a
Sissors 0:fee70b6fe0e9 29 * synchronous protocol this shouldn't affect functionality
Sissors 0:fee70b6fe0e9 30 *
Sissors 0:fee70b6fe0e9 31 * @param hz The bus frequency in hertz
Sissors 0:fee70b6fe0e9 32 */
Sissors 0:fee70b6fe0e9 33 void frequency(int hz);
Sissors 0:fee70b6fe0e9 34
Sissors 0:fee70b6fe0e9 35 /**
Sissors 0:fee70b6fe0e9 36 * Read from an I2C slave.
Sissors 0:fee70b6fe0e9 37 *
Sissors 0:fee70b6fe0e9 38 * Performs a complete read transaction. The bottom bit of the address is forced to 1 to indicate a read.
Sissors 0:fee70b6fe0e9 39 *
Sissors 0:fee70b6fe0e9 40 * @param address 8-bit I2C slave address [ addr | 1 ]
Sissors 0:fee70b6fe0e9 41 * @param Pointer to the byte-array data to read to
Sissors 0:fee70b6fe0e9 42 * @param length Number of bytes to read
Sissors 0:fee70b6fe0e9 43 * @param repeated Repeated start, true - do not send stop at end
Sissors 0:fee70b6fe0e9 44 * @return 0 on success (ack), non-0 on failure (nack)
Sissors 0:fee70b6fe0e9 45 */
Sissors 0:fee70b6fe0e9 46 int read(int address, char *data, int length, bool repeated=false);
Sissors 0:fee70b6fe0e9 47
Sissors 0:fee70b6fe0e9 48 /**
Sissors 0:fee70b6fe0e9 49 * Read a single byte from the I2C bus
Sissors 0:fee70b6fe0e9 50 *
Sissors 0:fee70b6fe0e9 51 * @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
Sissors 0:fee70b6fe0e9 52 * @return the byte read
Sissors 0:fee70b6fe0e9 53 */
Sissors 0:fee70b6fe0e9 54 int read(int ack);
Sissors 0:fee70b6fe0e9 55
Sissors 0:fee70b6fe0e9 56 /**
Sissors 0:fee70b6fe0e9 57 * Write to an I2C slave.
Sissors 0:fee70b6fe0e9 58 *
Sissors 0:fee70b6fe0e9 59 * Performs a complete write transaction. The bottom bit of the address is forced to 0 to indicate a write.
Sissors 0:fee70b6fe0e9 60 *
Sissors 0:fee70b6fe0e9 61 * @param address 8-bit I2C slave address [ addr | 0 ]
Sissors 0:fee70b6fe0e9 62 * @param Pointer to the byte-array data to send
Sissors 0:fee70b6fe0e9 63 * @param length Number of bytes to send
Sissors 0:fee70b6fe0e9 64 * @param repeated Repeated start, true - do not send stop at end
Sissors 0:fee70b6fe0e9 65 * @return 0 on success (ack), non-0 on failure (nack)
Sissors 0:fee70b6fe0e9 66 */
Sissors 0:fee70b6fe0e9 67 int write(int address, const char *data, int length, bool repeated=false);
Sissors 0:fee70b6fe0e9 68
Sissors 0:fee70b6fe0e9 69 /**
Sissors 0:fee70b6fe0e9 70 * Write single byte out on the I2C bus
Sissors 0:fee70b6fe0e9 71 *
Sissors 0:fee70b6fe0e9 72 * @param data data to write on the bus
Sissors 0:fee70b6fe0e9 73 * @return '1' if an ACK is received, '0' otherwise
Sissors 0:fee70b6fe0e9 74 */
Sissors 0:fee70b6fe0e9 75 int write(int data);
Sissors 0:fee70b6fe0e9 76
Sissors 0:fee70b6fe0e9 77 /**
Sissors 0:fee70b6fe0e9 78 * Create a (re-)start condition on the I2C bus
Sissors 0:fee70b6fe0e9 79 */
Sissors 0:fee70b6fe0e9 80 void start(void);
Sissors 0:fee70b6fe0e9 81
Sissors 0:fee70b6fe0e9 82 /**
Sissors 0:fee70b6fe0e9 83 * Create a stop condition on the I2C bus
Sissors 0:fee70b6fe0e9 84 */
Sissors 0:fee70b6fe0e9 85 void stop(void);
Sissors 0:fee70b6fe0e9 86
Sissors 0:fee70b6fe0e9 87 protected:
Sissors 0:fee70b6fe0e9 88 DigitalInOut _sda;
Sissors 0:fee70b6fe0e9 89 DigitalInOut _scl;
Sissors 0:fee70b6fe0e9 90 int delay_us;
Sissors 0:fee70b6fe0e9 91 bool active;
Sissors 0:fee70b6fe0e9 92 };
Sissors 0:fee70b6fe0e9 93
Sissors 0:fee70b6fe0e9 94
Sissors 0:fee70b6fe0e9 95 #endif