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:
0:6f6cfcdfe3d8
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 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 2:8670e78c4b63 36
p3p 2:8670e78c4b63 37 void setFrequency(uint32_t frequency){
p3p 2:8670e78c4b63 38 _frequency_delay = 1000000 / frequency;
p3p 2:8670e78c4b63 39 }
p3p 0:6f6cfcdfe3d8 40
p3p 0:6f6cfcdfe3d8 41 inline void initialise() {
p3p 0:6f6cfcdfe3d8 42 _scl.output();
p3p 0:6f6cfcdfe3d8 43 _sda.output();
p3p 0:6f6cfcdfe3d8 44
p3p 0:6f6cfcdfe3d8 45 _sda = 1;
p3p 0:6f6cfcdfe3d8 46 _scl = 0;
p3p 2:8670e78c4b63 47 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 48
p3p 0:6f6cfcdfe3d8 49 for ( int n = 0; n <= 3; ++n ) {
p3p 0:6f6cfcdfe3d8 50 stop();
p3p 0:6f6cfcdfe3d8 51 }
p3p 0:6f6cfcdfe3d8 52 }
p3p 0:6f6cfcdfe3d8 53
p3p 0:6f6cfcdfe3d8 54 private:
p3p 0:6f6cfcdfe3d8 55 inline void start() {
p3p 0:6f6cfcdfe3d8 56 _sda.output();
p3p 2:8670e78c4b63 57 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 58 _scl = 1;
p3p 0:6f6cfcdfe3d8 59 _sda = 1;
p3p 2:8670e78c4b63 60 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 61 _sda = 0;
p3p 2:8670e78c4b63 62 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 63 _scl = 0;
p3p 2:8670e78c4b63 64 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 65 }
p3p 0:6f6cfcdfe3d8 66
p3p 0:6f6cfcdfe3d8 67 inline void stop() {
p3p 0:6f6cfcdfe3d8 68 _sda.output();
p3p 2:8670e78c4b63 69 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 70 _sda = 0;
p3p 2:8670e78c4b63 71 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 72 _scl = 1;
p3p 2:8670e78c4b63 73 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 74 _sda = 1;
p3p 0:6f6cfcdfe3d8 75 }
p3p 0:6f6cfcdfe3d8 76
p3p 0:6f6cfcdfe3d8 77 inline void putByte(uint8_t byte) {
p3p 0:6f6cfcdfe3d8 78 _sda.output();
p3p 0:6f6cfcdfe3d8 79 for ( int n = 8; n > 0; --n) {
p3p 2:8670e78c4b63 80 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 81 _sda = byte & (1 << (n-1));
p3p 0:6f6cfcdfe3d8 82 _scl = 1;
p3p 2:8670e78c4b63 83 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 84 _scl = 0;
p3p 0:6f6cfcdfe3d8 85 }
p3p 0:6f6cfcdfe3d8 86 _sda = 1;
p3p 0:6f6cfcdfe3d8 87 }
p3p 0:6f6cfcdfe3d8 88
p3p 0:6f6cfcdfe3d8 89 inline uint8_t getByte() {
p3p 0:6f6cfcdfe3d8 90 uint8_t byte = 0;
p3p 0:6f6cfcdfe3d8 91
p3p 0:6f6cfcdfe3d8 92 _sda.input(); //release the data line
p3p 0:6f6cfcdfe3d8 93 _sda.mode(OpenDrain);
p3p 0:6f6cfcdfe3d8 94
p3p 2:8670e78c4b63 95 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 96
p3p 0:6f6cfcdfe3d8 97 for ( int n = 8; n > 0; --n ) {
p3p 0:6f6cfcdfe3d8 98 _scl=1; //set clock high
p3p 2:8670e78c4b63 99 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 100 byte |= _sda << (n-1); //read the bit
p3p 2:8670e78c4b63 101 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 102 _scl=0; //set clock low
p3p 2:8670e78c4b63 103 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 104 }
p3p 0:6f6cfcdfe3d8 105
p3p 0:6f6cfcdfe3d8 106 _sda.output(); //take data line back
p3p 0:6f6cfcdfe3d8 107
p3p 0:6f6cfcdfe3d8 108 return byte;
p3p 0:6f6cfcdfe3d8 109 }
p3p 0:6f6cfcdfe3d8 110
p3p 0:6f6cfcdfe3d8 111 inline void giveAck() {
p3p 0:6f6cfcdfe3d8 112 _sda.output();
p3p 2:8670e78c4b63 113 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 114 _sda = 0;
p3p 0:6f6cfcdfe3d8 115 _scl = 1;
p3p 2:8670e78c4b63 116 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 117 _scl = 0;
p3p 0:6f6cfcdfe3d8 118 _sda = 1;
p3p 0:6f6cfcdfe3d8 119
p3p 0:6f6cfcdfe3d8 120 }
p3p 0:6f6cfcdfe3d8 121
p3p 0:6f6cfcdfe3d8 122 inline bool getAck() {
p3p 0:6f6cfcdfe3d8 123 _sda.output();
p3p 0:6f6cfcdfe3d8 124 _sda = 1;
p3p 0:6f6cfcdfe3d8 125 _scl = 1;
p3p 0:6f6cfcdfe3d8 126 _sda.input();
p3p 0:6f6cfcdfe3d8 127 _sda.mode(OpenDrain);
p3p 2:8670e78c4b63 128 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 129 _scl = 0;
p3p 0:6f6cfcdfe3d8 130
p3p 0:6f6cfcdfe3d8 131 if(_sda != 0){return false;}
p3p 0:6f6cfcdfe3d8 132
p3p 2:8670e78c4b63 133 wait_us(_frequency_delay);
p3p 0:6f6cfcdfe3d8 134 return true;
p3p 0:6f6cfcdfe3d8 135 }
p3p 0:6f6cfcdfe3d8 136
p3p 0:6f6cfcdfe3d8 137 DigitalInOut _sda;
p3p 0:6f6cfcdfe3d8 138 DigitalInOut _scl;
p3p 0:6f6cfcdfe3d8 139
p3p 0:6f6cfcdfe3d8 140 uint8_t _device_address;
p3p 2:8670e78c4b63 141 uint32_t _frequency_delay;
p3p 0:6f6cfcdfe3d8 142 };
p3p 0:6f6cfcdfe3d8 143
p3p 0:6f6cfcdfe3d8 144 #endif