First release of a Software I2C implementation, Tested and confirmed to work with the BMP085 Barometric Pressure Sensor

Dependents:   SoftwareI2C_Test

mbed Library to use a software master i2c interface on any GPIO pins
Copyright (c) 2012 Christopher Pepper
Released under the MIT License: http://mbed.org/license/mit

Committer:
p3p
Date:
Sun Apr 01 22:52:47 2012 +0000
Revision:
2:8670e78c4b63
Parent:
1:6966eacc5914
Added the option to change the frequency (delay between GPIO toggles so blocking)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3p 2:8670e78c4b63 1 /*
p3p 2:8670e78c4b63 2 * mbed Library to use a software master i2c interface on any GPIO pins
p3p 2:8670e78c4b63 3 * Copyright (c) 2012 Christopher Pepper
p3p 2:8670e78c4b63 4 * Released under the MIT License: http://mbed.org/license/mit
p3p 2:8670e78c4b63 5 */
p3p 2:8670e78c4b63 6
p3p 2:8670e78c4b63 7 #include "SoftwareI2C.h"
p3p 2:8670e78c4b63 8
p3p 2:8670e78c4b63 9 /**
p3p 2:8670e78c4b63 10 * @brief Initializes interface
p3p 2:8670e78c4b63 11 * @param sda GPIO pin to use as I2C SDA
p3p 2:8670e78c4b63 12 * @param scl GPIO pin to use as I2C SCL
p3p 2:8670e78c4b63 13 */
p3p 2:8670e78c4b63 14
p3p 2:8670e78c4b63 15 SoftwareI2C::SoftwareI2C(PinName sda, PinName scl) : _sda(sda) , _scl(scl) {
p3p 2:8670e78c4b63 16 _scl.output();
p3p 2:8670e78c4b63 17 _scl.mode(OpenDrain);
p3p 2:8670e78c4b63 18 _sda.output();
p3p 2:8670e78c4b63 19 _sda.mode(OpenDrain);
p3p 2:8670e78c4b63 20
p3p 2:8670e78c4b63 21 _device_address = 0;
p3p 2:8670e78c4b63 22 _frequency_delay = 1;
p3p 2:8670e78c4b63 23
p3p 2:8670e78c4b63 24 initialise();
p3p 2:8670e78c4b63 25 }
p3p 2:8670e78c4b63 26
p3p 2:8670e78c4b63 27 SoftwareI2C::~SoftwareI2C() {
p3p 2:8670e78c4b63 28
p3p 2:8670e78c4b63 29 }
p3p 2:8670e78c4b63 30
p3p 2:8670e78c4b63 31 /**
p3p 2:8670e78c4b63 32 * @brief Read 1 or more bytes from the I2C slave
p3p 2:8670e78c4b63 33 * @param device_address The address of the device to read from
p3p 2:8670e78c4b63 34 * @param data An allocated array to read the data into
p3p 2:8670e78c4b63 35 * @param data_bytes Number of bytes to read (must be equal to or less then the allocated memory in data)
p3p 2:8670e78c4b63 36 */
p3p 2:8670e78c4b63 37 void SoftwareI2C::read(uint8_t device_address, uint8_t* data, uint8_t data_bytes) {
p3p 2:8670e78c4b63 38 if (data == 0 || data_bytes == 0) return;
p3p 2:8670e78c4b63 39
p3p 2:8670e78c4b63 40 device_address = device_address | 0x01;
p3p 2:8670e78c4b63 41 start();
p3p 2:8670e78c4b63 42 putByte(device_address);
p3p 2:8670e78c4b63 43 getAck();
p3p 2:8670e78c4b63 44 for (int x = 0; x < data_bytes; ++x) {
p3p 2:8670e78c4b63 45 data[x] = getByte();
p3p 2:8670e78c4b63 46 if ( x < (data_bytes -1)) { //ack all but the final byte
p3p 2:8670e78c4b63 47 giveAck();
p3p 2:8670e78c4b63 48 }
p3p 2:8670e78c4b63 49 }
p3p 2:8670e78c4b63 50 stop();
p3p 2:8670e78c4b63 51 }
p3p 2:8670e78c4b63 52
p3p 2:8670e78c4b63 53 /**
p3p 2:8670e78c4b63 54 * @brief Write 1 or more bytes to the I2C slave
p3p 2:8670e78c4b63 55 * @param device_address The address of the device to write to
p3p 2:8670e78c4b63 56 * @param data An array to write the data from
p3p 2:8670e78c4b63 57 * @param data_bytes Number of bytes to write from array
p3p 2:8670e78c4b63 58 */
p3p 2:8670e78c4b63 59 void SoftwareI2C::write(uint8_t device_address, uint8_t* data, uint8_t data_bytes) {
p3p 2:8670e78c4b63 60 if (data == 0 || data_bytes == 0) return;
p3p 2:8670e78c4b63 61
p3p 2:8670e78c4b63 62 device_address = device_address & 0xFE;
p3p 2:8670e78c4b63 63 start();
p3p 2:8670e78c4b63 64 putByte(device_address);
p3p 2:8670e78c4b63 65 getAck();
p3p 2:8670e78c4b63 66 for ( int x = 0; x < data_bytes; ++x ) {
p3p 2:8670e78c4b63 67 putByte(data[x]);
p3p 2:8670e78c4b63 68 getAck();
p3p 2:8670e78c4b63 69 }
p3p 2:8670e78c4b63 70 stop();
p3p 2:8670e78c4b63 71 }
p3p 2:8670e78c4b63 72
p3p 2:8670e78c4b63 73 /**
p3p 2:8670e78c4b63 74 * @brief Write 1 byte to the I2C slave
p3p 2:8670e78c4b63 75 * @param device_address The address of the device to write to
p3p 2:8670e78c4b63 76 * @param byte The data to write
p3p 2:8670e78c4b63 77 */
p3p 2:8670e78c4b63 78 void SoftwareI2C::write(uint8_t device_address, uint8_t byte) {
p3p 2:8670e78c4b63 79 device_address = device_address & 0xFE;
p3p 2:8670e78c4b63 80 start();
p3p 2:8670e78c4b63 81 putByte(device_address);
p3p 2:8670e78c4b63 82 getAck();
p3p 2:8670e78c4b63 83 putByte(byte);
p3p 2:8670e78c4b63 84 getAck();
p3p 2:8670e78c4b63 85 stop();
p3p 2:8670e78c4b63 86 }
p3p 2:8670e78c4b63 87
p3p 2:8670e78c4b63 88 /**
p3p 2:8670e78c4b63 89 * @brief Read 1 or more bytes from the I2C slave at the specified memory address
p3p 2:8670e78c4b63 90 * @param device_address The address of the device to read from
p3p 2:8670e78c4b63 91 * @param start_address The memory address to read from
p3p 2:8670e78c4b63 92 * @param data The allocated array to read into
p3p 2:8670e78c4b63 93 * @param data_bytes The number of bytes to read
p3p 2:8670e78c4b63 94 */
p3p 2:8670e78c4b63 95 void SoftwareI2C::randomRead(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes) {
p3p 2:8670e78c4b63 96 if (data == 0 || data_bytes == 0) return;
p3p 2:8670e78c4b63 97
p3p 2:8670e78c4b63 98 device_address = device_address & 0xFE;
p3p 2:8670e78c4b63 99 start();
p3p 2:8670e78c4b63 100 putByte(device_address);
p3p 2:8670e78c4b63 101 if (!getAck()) {
p3p 2:8670e78c4b63 102 return;
p3p 2:8670e78c4b63 103 }
p3p 2:8670e78c4b63 104 putByte(start_address);
p3p 2:8670e78c4b63 105 if (!getAck()) {
p3p 2:8670e78c4b63 106 return;
p3p 2:8670e78c4b63 107 }
p3p 2:8670e78c4b63 108
p3p 2:8670e78c4b63 109 device_address=device_address | 0x01;
p3p 2:8670e78c4b63 110 start();
p3p 2:8670e78c4b63 111 putByte(device_address);
p3p 2:8670e78c4b63 112 if (!getAck()) {
p3p 2:8670e78c4b63 113 return;
p3p 2:8670e78c4b63 114 }
p3p 2:8670e78c4b63 115 for ( int x = 0; x < data_bytes; ++x) {
p3p 2:8670e78c4b63 116 data[x] = getByte();
p3p 2:8670e78c4b63 117 if (x != (data_bytes - 1)) giveAck();
p3p 2:8670e78c4b63 118 }
p3p 2:8670e78c4b63 119 stop();
p3p 2:8670e78c4b63 120 }
p3p 2:8670e78c4b63 121
p3p 2:8670e78c4b63 122 /**
p3p 2:8670e78c4b63 123 * @brief Write 1 byte to the I2C slave at the specified memory address
p3p 2:8670e78c4b63 124 * @param device_address The address of the device to write to
p3p 2:8670e78c4b63 125 * @param start_address The memory address to write to
p3p 2:8670e78c4b63 126 * @param byte The data to write
p3p 2:8670e78c4b63 127 */
p3p 2:8670e78c4b63 128 void SoftwareI2C::randomWrite(uint8_t device_address, uint8_t start_address, uint8_t byte) {
p3p 2:8670e78c4b63 129 device_address = device_address & 0xFE;
p3p 2:8670e78c4b63 130 start();
p3p 2:8670e78c4b63 131 putByte(device_address);
p3p 2:8670e78c4b63 132 getAck();
p3p 2:8670e78c4b63 133 putByte(start_address);
p3p 2:8670e78c4b63 134 getAck();
p3p 2:8670e78c4b63 135 putByte(byte);
p3p 2:8670e78c4b63 136 getAck();
p3p 2:8670e78c4b63 137 stop();
p3p 2:8670e78c4b63 138 }
p3p 2:8670e78c4b63 139
p3p 2:8670e78c4b63 140 /**
p3p 2:8670e78c4b63 141 * @brief Write 1 or more bytes to the I2C slave at the specified memory address
p3p 2:8670e78c4b63 142 * @param device_address The address of the device to write to
p3p 2:8670e78c4b63 143 * @param start_address The memory address to write to
p3p 2:8670e78c4b63 144 * @param data The data to write
p3p 2:8670e78c4b63 145 * @param data_bytes The number of bytes to write
p3p 2:8670e78c4b63 146 */
p3p 2:8670e78c4b63 147 void SoftwareI2C::randomWrite(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes) {
p3p 2:8670e78c4b63 148 if (data == 0 || data_bytes == 0) return;
p3p 2:8670e78c4b63 149
p3p 2:8670e78c4b63 150 device_address = device_address & 0xFE;
p3p 2:8670e78c4b63 151 start();
p3p 2:8670e78c4b63 152 putByte(device_address);
p3p 2:8670e78c4b63 153 getAck();
p3p 2:8670e78c4b63 154 putByte(start_address);
p3p 2:8670e78c4b63 155 getAck();
p3p 2:8670e78c4b63 156 for ( int x = 0; x <= data_bytes; ++x ) {
p3p 2:8670e78c4b63 157 putByte(data[x]);
p3p 2:8670e78c4b63 158 getAck();
p3p 2:8670e78c4b63 159 }
p3p 2:8670e78c4b63 160 stop();
p3p 2:8670e78c4b63 161 }
p3p 2:8670e78c4b63 162
p3p 2:8670e78c4b63 163 /**
p3p 2:8670e78c4b63 164 * @brief Read 2 bytes from the I2C slave at the specified memory address and return them as an 16bit unsigned integer
p3p 2:8670e78c4b63 165 * @param device_address The address of the device to read from
p3p 2:8670e78c4b63 166 * @param start_address The memory address to read from
p3p 2:8670e78c4b63 167 * @return MSB 16bit unsigned integer
p3p 2:8670e78c4b63 168 */
p3p 2:8670e78c4b63 169 uint16_t SoftwareI2C::read16(uint8_t device_address, uint8_t start_address) {
p3p 2:8670e78c4b63 170 uint8_t short_array[2] = {0, 0};
p3p 2:8670e78c4b63 171 randomRead(device_address, start_address, short_array, 2 );
p3p 2:8670e78c4b63 172 uint16_t value = 0;
p3p 2:8670e78c4b63 173 value = short_array[0] << 8;
p3p 2:8670e78c4b63 174 value |= short_array[1];
p3p 2:8670e78c4b63 175
p3p 2:8670e78c4b63 176 return value;
p3p 2:8670e78c4b63 177 }
p3p 2:8670e78c4b63 178
p3p 2:8670e78c4b63 179 /**
p3p 2:8670e78c4b63 180 * @brief Read 3 bytes from the I2C slave at the specified memory address and return them as an 32bit unsigned integer
p3p 2:8670e78c4b63 181 * @param device_address The address of the device to read from
p3p 2:8670e78c4b63 182 * @param start_address The memory address to read from
p3p 2:8670e78c4b63 183 * @return MSB 32bit unsigned integer
p3p 2:8670e78c4b63 184 */
p3p 2:8670e78c4b63 185 uint32_t SoftwareI2C::read24(uint8_t device_address, uint8_t start_address) {
p3p 2:8670e78c4b63 186 uint8_t value_array[4] = {0, 0, 0};
p3p 2:8670e78c4b63 187 randomRead(device_address, start_address, value_array, 3 );
p3p 2:8670e78c4b63 188 uint32_t value = 0;
p3p 2:8670e78c4b63 189 value = value_array[0] << 16;
p3p 2:8670e78c4b63 190 value |= value_array[1] << 8;
p3p 2:8670e78c4b63 191 value |= value_array[2];
p3p 2:8670e78c4b63 192
p3p 2:8670e78c4b63 193 return value;
p3p 2:8670e78c4b63 194 }
p3p 2:8670e78c4b63 195
p3p 2:8670e78c4b63 196 /**
p3p 2:8670e78c4b63 197 * @brief Read 4 bytes from the I2C slave at the specified memory address and return them as an 32bit unsigned integer
p3p 2:8670e78c4b63 198 * @param device_address The address of the device to read from
p3p 2:8670e78c4b63 199 * @param start_address The memory address to read from
p3p 2:8670e78c4b63 200 * @return MSB 32bit unsigned integer
p3p 2:8670e78c4b63 201 */
p3p 2:8670e78c4b63 202 uint32_t SoftwareI2C::read32(uint8_t device_address, uint8_t start_address) {
p3p 2:8670e78c4b63 203 uint8_t value_array[4] = {0, 0, 0, 0};
p3p 2:8670e78c4b63 204 randomRead(device_address, start_address, value_array, 4 );
p3p 2:8670e78c4b63 205 uint32_t value = 0;
p3p 2:8670e78c4b63 206 value = value_array[0] << 24;
p3p 2:8670e78c4b63 207 value |= value_array[1] << 16;
p3p 2:8670e78c4b63 208 value |= value_array[2] << 8;
p3p 2:8670e78c4b63 209 value |= value_array[3];
p3p 2:8670e78c4b63 210
p3p 2:8670e78c4b63 211 return value;
p3p 0:6f6cfcdfe3d8 212 }