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 19:21:03 2012 +0000
Revision:
0:6f6cfcdfe3d8
Child:
2:8670e78c4b63
Initial Public Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3p 0:6f6cfcdfe3d8 1 /*
p3p 0:6f6cfcdfe3d8 2 * mbed Library to use a software master i2c interface on any GPIO pins
p3p 0:6f6cfcdfe3d8 3 * Copyright (c) 2012 Christopher Pepper
p3p 0:6f6cfcdfe3d8 4 * Released under the MIT License: http://mbed.org/license/mit
p3p 0:6f6cfcdfe3d8 5 */
p3p 0:6f6cfcdfe3d8 6
p3p 0:6f6cfcdfe3d8 7 #ifndef _SOFTWARE_I2C_H_
p3p 0:6f6cfcdfe3d8 8 #define _SOFTWARE_I2C_H_
p3p 0:6f6cfcdfe3d8 9
p3p 0:6f6cfcdfe3d8 10 #include "mbed.h"
p3p 0:6f6cfcdfe3d8 11
p3p 0:6f6cfcdfe3d8 12 /**
p3p 0:6f6cfcdfe3d8 13 * @brief SoftwareI2C class
p3p 0:6f6cfcdfe3d8 14 */
p3p 0:6f6cfcdfe3d8 15
p3p 0:6f6cfcdfe3d8 16 class SoftwareI2C {
p3p 0:6f6cfcdfe3d8 17 public:
p3p 0:6f6cfcdfe3d8 18 SoftwareI2C(PinName sda, PinName scl);
p3p 0:6f6cfcdfe3d8 19 ~SoftwareI2C();
p3p 0:6f6cfcdfe3d8 20
p3p 0:6f6cfcdfe3d8 21 void read(uint8_t device_address, uint8_t* data, uint8_t data_bytes);
p3p 0:6f6cfcdfe3d8 22 void write(uint8_t device_address, uint8_t* data, uint8_t data_bytes);
p3p 0:6f6cfcdfe3d8 23 void write(uint8_t device_address, uint8_t byte);
p3p 0:6f6cfcdfe3d8 24 void randomRead(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes);
p3p 0:6f6cfcdfe3d8 25 void randomWrite(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes);
p3p 0:6f6cfcdfe3d8 26 void randomWrite(uint8_t device_address, uint8_t start_address, uint8_t byte);
p3p 0:6f6cfcdfe3d8 27
p3p 0:6f6cfcdfe3d8 28 uint8_t read8(uint8_t device_address, uint8_t start_address);
p3p 0:6f6cfcdfe3d8 29 uint16_t read16(uint8_t device_address, uint8_t start_address);
p3p 0:6f6cfcdfe3d8 30 uint32_t read24(uint8_t device_address, uint8_t start_address);
p3p 0:6f6cfcdfe3d8 31 uint32_t read32(uint8_t device_address, uint8_t start_address);
p3p 0:6f6cfcdfe3d8 32
p3p 0:6f6cfcdfe3d8 33 void setDeviceAddress(uint8_t address){
p3p 0:6f6cfcdfe3d8 34 _device_address = address;
p3p 0:6f6cfcdfe3d8 35 }
p3p 0:6f6cfcdfe3d8 36
p3p 0:6f6cfcdfe3d8 37 inline void initialise() {
p3p 0:6f6cfcdfe3d8 38 _scl.output();
p3p 0:6f6cfcdfe3d8 39 _sda.output();
p3p 0:6f6cfcdfe3d8 40
p3p 0:6f6cfcdfe3d8 41 _sda = 1;
p3p 0:6f6cfcdfe3d8 42 _scl = 0;
p3p 0:6f6cfcdfe3d8 43 wait_us(10);
p3p 0:6f6cfcdfe3d8 44
p3p 0:6f6cfcdfe3d8 45 for ( int n = 0; n <= 3; ++n ) {
p3p 0:6f6cfcdfe3d8 46 stop();
p3p 0:6f6cfcdfe3d8 47 }
p3p 0:6f6cfcdfe3d8 48 }
p3p 0:6f6cfcdfe3d8 49
p3p 0:6f6cfcdfe3d8 50 private:
p3p 0:6f6cfcdfe3d8 51 inline void start() {
p3p 0:6f6cfcdfe3d8 52 _sda.output();
p3p 0:6f6cfcdfe3d8 53 wait_us(1);
p3p 0:6f6cfcdfe3d8 54 _scl = 1;
p3p 0:6f6cfcdfe3d8 55 _sda = 1;
p3p 0:6f6cfcdfe3d8 56 wait_us(1);
p3p 0:6f6cfcdfe3d8 57 _sda = 0;
p3p 0:6f6cfcdfe3d8 58 wait_us(1);
p3p 0:6f6cfcdfe3d8 59 _scl = 0;
p3p 0:6f6cfcdfe3d8 60 wait_us(1);
p3p 0:6f6cfcdfe3d8 61 }
p3p 0:6f6cfcdfe3d8 62
p3p 0:6f6cfcdfe3d8 63 inline void stop() {
p3p 0:6f6cfcdfe3d8 64 _sda.output();
p3p 0:6f6cfcdfe3d8 65 wait_us(1);
p3p 0:6f6cfcdfe3d8 66 _sda = 0;
p3p 0:6f6cfcdfe3d8 67 wait_us(1);
p3p 0:6f6cfcdfe3d8 68 _scl = 1;
p3p 0:6f6cfcdfe3d8 69 wait_us(1);
p3p 0:6f6cfcdfe3d8 70 _sda = 1;
p3p 0:6f6cfcdfe3d8 71 }
p3p 0:6f6cfcdfe3d8 72
p3p 0:6f6cfcdfe3d8 73 inline void putByte(uint8_t byte) {
p3p 0:6f6cfcdfe3d8 74 _sda.output();
p3p 0:6f6cfcdfe3d8 75 for ( int n = 8; n > 0; --n) {
p3p 0:6f6cfcdfe3d8 76 wait_us(1);
p3p 0:6f6cfcdfe3d8 77 _sda = byte & (1 << (n-1));
p3p 0:6f6cfcdfe3d8 78 _scl = 1;
p3p 0:6f6cfcdfe3d8 79 wait_us(1);
p3p 0:6f6cfcdfe3d8 80 _scl = 0;
p3p 0:6f6cfcdfe3d8 81 }
p3p 0:6f6cfcdfe3d8 82 _sda = 1;
p3p 0:6f6cfcdfe3d8 83 }
p3p 0:6f6cfcdfe3d8 84
p3p 0:6f6cfcdfe3d8 85 inline uint8_t getByte() {
p3p 0:6f6cfcdfe3d8 86 uint8_t byte = 0;
p3p 0:6f6cfcdfe3d8 87
p3p 0:6f6cfcdfe3d8 88 _sda.input(); //release the data line
p3p 0:6f6cfcdfe3d8 89 _sda.mode(OpenDrain);
p3p 0:6f6cfcdfe3d8 90
p3p 0:6f6cfcdfe3d8 91 wait_us(1);
p3p 0:6f6cfcdfe3d8 92
p3p 0:6f6cfcdfe3d8 93 for ( int n = 8; n > 0; --n ) {
p3p 0:6f6cfcdfe3d8 94 _scl=1; //set clock high
p3p 0:6f6cfcdfe3d8 95 wait_us(1);
p3p 0:6f6cfcdfe3d8 96 byte |= _sda << (n-1); //read the bit
p3p 0:6f6cfcdfe3d8 97 wait_us(1);
p3p 0:6f6cfcdfe3d8 98 _scl=0; //set clock low
p3p 0:6f6cfcdfe3d8 99 wait_us(1);
p3p 0:6f6cfcdfe3d8 100 }
p3p 0:6f6cfcdfe3d8 101
p3p 0:6f6cfcdfe3d8 102 _sda.output(); //take data line back
p3p 0:6f6cfcdfe3d8 103
p3p 0:6f6cfcdfe3d8 104 return byte;
p3p 0:6f6cfcdfe3d8 105 }
p3p 0:6f6cfcdfe3d8 106
p3p 0:6f6cfcdfe3d8 107 inline void giveAck() {
p3p 0:6f6cfcdfe3d8 108 _sda.output();
p3p 0:6f6cfcdfe3d8 109 wait_us(1);
p3p 0:6f6cfcdfe3d8 110 _sda = 0;
p3p 0:6f6cfcdfe3d8 111 _scl = 1;
p3p 0:6f6cfcdfe3d8 112 wait_us(1);
p3p 0:6f6cfcdfe3d8 113 _scl = 0;
p3p 0:6f6cfcdfe3d8 114 _sda = 1;
p3p 0:6f6cfcdfe3d8 115
p3p 0:6f6cfcdfe3d8 116 }
p3p 0:6f6cfcdfe3d8 117
p3p 0:6f6cfcdfe3d8 118 inline bool getAck() {
p3p 0:6f6cfcdfe3d8 119 _sda.output();
p3p 0:6f6cfcdfe3d8 120 _sda = 1;
p3p 0:6f6cfcdfe3d8 121 _scl = 1;
p3p 0:6f6cfcdfe3d8 122 _sda.input();
p3p 0:6f6cfcdfe3d8 123 _sda.mode(OpenDrain);
p3p 0:6f6cfcdfe3d8 124 wait_us(1);
p3p 0:6f6cfcdfe3d8 125 _scl = 0;
p3p 0:6f6cfcdfe3d8 126
p3p 0:6f6cfcdfe3d8 127 if(_sda != 0){return false;}
p3p 0:6f6cfcdfe3d8 128
p3p 0:6f6cfcdfe3d8 129 wait_us(1);
p3p 0:6f6cfcdfe3d8 130 return true;
p3p 0:6f6cfcdfe3d8 131 }
p3p 0:6f6cfcdfe3d8 132
p3p 0:6f6cfcdfe3d8 133 DigitalInOut _sda;
p3p 0:6f6cfcdfe3d8 134 DigitalInOut _scl;
p3p 0:6f6cfcdfe3d8 135
p3p 0:6f6cfcdfe3d8 136 uint8_t _device_address;
p3p 0:6f6cfcdfe3d8 137 };
p3p 0:6f6cfcdfe3d8 138
p3p 0:6f6cfcdfe3d8 139 #endif