Jack Hansdampf / SoftwareI2C
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         warte(_frequency_delay);
00048 
00049         for ( int n = 0; n <= 3; ++n ) {
00050             stop();
00051         }
00052     }
00053 
00054 private:
00055     void warte(int zeit)
00056     {
00057      for (int i=0;i<zeit*5;i++)
00058      {
00059       asm(
00060         "nop\n\t"
00061       );   
00062      }   
00063     }
00064     inline void start() {
00065         _sda.output();
00066         warte(_frequency_delay);
00067         _scl = 1;
00068         _sda = 1;
00069         warte(_frequency_delay);
00070         _sda = 0;
00071         warte(_frequency_delay);
00072         _scl = 0;
00073         warte(_frequency_delay);
00074     }
00075 
00076     inline void stop() {
00077         _sda.output();
00078         warte(_frequency_delay);
00079         _sda = 0;
00080         warte(_frequency_delay);
00081         _scl = 1;
00082         warte(_frequency_delay);
00083         _sda = 1;
00084     }
00085 
00086     inline void putByte(uint8_t byte) {
00087         _sda.output();
00088         for ( int n = 8; n > 0; --n) {
00089             warte(_frequency_delay);
00090             _sda = byte & (1 << (n-1));
00091             _scl = 1;
00092             warte(_frequency_delay);
00093             _scl = 0;
00094         }
00095         _sda = 1;
00096     }
00097 
00098     inline uint8_t getByte() {
00099         uint8_t byte = 0;
00100 
00101         _sda.input();          //release the data line
00102         _sda.mode(OpenDrain);
00103         
00104         warte(_frequency_delay);
00105 
00106         for ( int n = 8; n > 0; --n ) {
00107             _scl=1;            //set clock high
00108             warte(_frequency_delay);
00109             byte |= _sda << (n-1); //read the bit
00110             warte(_frequency_delay);
00111             _scl=0;            //set clock low
00112             warte(_frequency_delay);
00113         }
00114 
00115         _sda.output();         //take data line back
00116 
00117         return byte;
00118     }
00119 
00120     inline void giveAck() {
00121         _sda.output();
00122         warte(_frequency_delay);
00123         _sda = 0;
00124         _scl = 1;
00125         warte(_frequency_delay);
00126         _scl = 0;
00127         _sda = 1;
00128 
00129     }
00130 
00131     inline bool getAck() {
00132         _sda.output();
00133         _sda = 1;
00134         _scl = 1;
00135         _sda.input();
00136         _sda.mode(OpenDrain);
00137         warte(_frequency_delay);
00138         _scl = 0;
00139 
00140         if(_sda != 0){return false;}
00141 
00142         warte(_frequency_delay);
00143         return true;
00144     }
00145 
00146     DigitalInOut _sda;
00147     DigitalInOut _scl;
00148     
00149     uint8_t _device_address;
00150     uint32_t _frequency_delay;
00151 };
00152 
00153 #endif