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

Dependents:   SoftwareI2C_Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SoftwareI2C.h Source File

SoftwareI2C.h

00001 /* 
00002  * mbed Library to use a software master i2c interface on any GPIO pins
00003  * Copyright (c) 2012 Christopher Pepper
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 #ifndef _SOFTWARE_I2C_H_
00008 #define _SOFTWARE_I2C_H_
00009 
00010 #include "mbed.h"
00011 
00012 /**
00013   * @brief SoftwareI2C class
00014   */
00015 
00016 class SoftwareI2C {
00017 public:
00018     SoftwareI2C(PinName sda, PinName scl);
00019     ~SoftwareI2C();
00020 
00021     void read(uint8_t device_address, uint8_t* data, uint8_t data_bytes);
00022     void write(uint8_t device_address, uint8_t* data,  uint8_t data_bytes);
00023     void write(uint8_t device_address, uint8_t byte);
00024     void randomRead(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes);
00025     void randomWrite(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes);
00026     void randomWrite(uint8_t device_address, uint8_t start_address, uint8_t byte);
00027     
00028     uint8_t read8(uint8_t device_address, uint8_t start_address);
00029     uint16_t read16(uint8_t device_address, uint8_t start_address);
00030     uint32_t read24(uint8_t device_address, uint8_t start_address);
00031     uint32_t read32(uint8_t device_address, uint8_t start_address);
00032     
00033     void setDeviceAddress(uint8_t address){
00034         _device_address = address;
00035     }
00036     
00037     void setFrequency(uint32_t frequency){
00038         _frequency_delay = 1000000 / frequency;
00039     }
00040 
00041     inline void initialise() {
00042         _scl.output();
00043         _sda.output();
00044         
00045         _sda = 1;
00046         _scl = 0;
00047         wait_us(_frequency_delay);
00048 
00049         for ( int n = 0; n <= 3; ++n ) {
00050             stop();
00051         }
00052     }
00053 
00054 private:
00055     inline void start() {
00056         _sda.output();
00057         wait_us(_frequency_delay);
00058         _scl = 1;
00059         _sda = 1;
00060         wait_us(_frequency_delay);
00061         _sda = 0;
00062         wait_us(_frequency_delay);
00063         _scl = 0;
00064         wait_us(_frequency_delay);
00065     }
00066 
00067     inline void stop() {
00068         _sda.output();
00069         wait_us(_frequency_delay);
00070         _sda = 0;
00071         wait_us(_frequency_delay);
00072         _scl = 1;
00073         wait_us(_frequency_delay);
00074         _sda = 1;
00075     }
00076 
00077     inline void putByte(uint8_t byte) {
00078         _sda.output();
00079         for ( int n = 8; n > 0; --n) {
00080             wait_us(_frequency_delay);
00081             _sda = byte & (1 << (n-1));
00082             _scl = 1;
00083             wait_us(_frequency_delay);
00084             _scl = 0;
00085         }
00086         _sda = 1;
00087     }
00088 
00089     inline uint8_t getByte() {
00090         uint8_t byte = 0;
00091 
00092         _sda.input();          //release the data line
00093         _sda.mode(OpenDrain);
00094         
00095         wait_us(_frequency_delay);
00096 
00097         for ( int n = 8; n > 0; --n ) {
00098             _scl=1;            //set clock high
00099             wait_us(_frequency_delay);
00100             byte |= _sda << (n-1); //read the bit
00101             wait_us(_frequency_delay);
00102             _scl=0;            //set clock low
00103             wait_us(_frequency_delay);
00104         }
00105 
00106         _sda.output();         //take data line back
00107 
00108         return byte;
00109     }
00110 
00111     inline void giveAck() {
00112         _sda.output();
00113         wait_us(_frequency_delay);
00114         _sda = 0;
00115         _scl = 1;
00116         wait_us(_frequency_delay);
00117         _scl = 0;
00118         _sda = 1;
00119 
00120     }
00121 
00122     inline bool getAck() {
00123         _sda.output();
00124         _sda = 1;
00125         _scl = 1;
00126         _sda.input();
00127         _sda.mode(OpenDrain);
00128         wait_us(_frequency_delay);
00129         _scl = 0;
00130 
00131         if(_sda != 0){return false;}
00132 
00133         wait_us(_frequency_delay);
00134         return true;
00135     }
00136 
00137     DigitalInOut _sda;
00138     DigitalInOut _scl;
00139     
00140     uint8_t _device_address;
00141     uint32_t _frequency_delay;
00142 };
00143 
00144 #endif