LCD Library 1.3.0
LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library.
I2CIO.cpp
Go to the documentation of this file.
00001 // ---------------------------------------------------------------------------
00002 // Created by Francisco Malpartida on 20/08/11.
00003 // Copyright 2011 - Under creative commons license 3.0:
00004 //        Attribution-ShareAlike CC BY-SA
00005 //
00006 // This software is furnished "as is", without technical support, and with no 
00007 // warranty, express or implied, as to its usefulness for any purpose.
00008 //
00009 // Thread Safe: No
00010 // Extendable: Yes
00011 //
00012 // @file I2CIO.h
00013 // This file implements a basic IO library using the PCF8574 I2C IO Expander
00014 // chip.
00015 // 
00016 // @brief 
00017 // Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
00018 // The library implements basic IO general methods to configure IO pin direction
00019 // read and write uint8_t operations and basic pin level routines to set or read
00020 // a particular IO port.
00021 //
00022 //
00023 // @version API 1.0.0
00024 //
00025 // @author F. Malpartida - fmalpartida@gmail.com
00026 // ---------------------------------------------------------------------------
00027 #if (ARDUINO <  100)
00028 #include <WProgram.h>
00029 #else
00030 #include <Arduino.h>
00031 #endif
00032 
00033 #include <inttypes.h>
00034 
00035 #include <../Wire/Wire.h>
00036 #include "I2CIO.h"
00037 
00038 // CLASS VARIABLES
00039 // ---------------------------------------------------------------------------
00040 
00041 
00042 // CONSTRUCTOR
00043 // ---------------------------------------------------------------------------
00044 I2CIO::I2CIO ( )
00045 {
00046    _i2cAddr     = 0x0;
00047    _dirMask     = 0xFF;    // mark all as INPUTs
00048    _shadow      = 0x0;     // no values set
00049    _initialised = false;
00050 }
00051 
00052 // PUBLIC METHODS
00053 // ---------------------------------------------------------------------------
00054 
00055 //
00056 // begin
00057 int I2CIO::begin (  uint8_t i2cAddr )
00058 {
00059    _i2cAddr = i2cAddr;
00060    
00061    Wire.begin ( );
00062       
00063    _initialised = Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
00064 
00065 #if (ARDUINO <  100)
00066    _shadow = Wire.receive ();
00067 #else
00068    _shadow = Wire.read (); // Remove the byte read don't need it.
00069 #endif
00070    
00071    return ( _initialised );
00072 }
00073 
00074 //
00075 // pinMode
00076 void I2CIO::pinMode ( uint8_t pin, uint8_t dir )
00077 {
00078    if ( _initialised )
00079    {
00080       if ( OUTPUT == dir )
00081       {
00082          _dirMask &= ~( 1 << pin );
00083       }
00084       else 
00085       {
00086          _dirMask |= ( 1 << pin );
00087       }
00088    }
00089 }
00090 
00091 //
00092 // portMode
00093 void I2CIO::portMode ( uint8_t dir )
00094 {
00095    
00096    if ( _initialised )
00097    {
00098       if ( dir == INPUT )
00099       {
00100          _dirMask = 0xFF;
00101       }
00102       else
00103       {
00104          _dirMask = 0x00;
00105       }
00106    }
00107 }
00108 
00109 //
00110 // read
00111 uint8_t I2CIO::read ( void )
00112 {
00113    uint8_t retVal = 0;
00114    
00115    if ( _initialised )
00116    {
00117       Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
00118 #if (ARDUINO <  100)
00119       retVal = ( _dirMask & Wire.receive ( ) );
00120 #else
00121       retVal = ( _dirMask & Wire.read ( ) );
00122 #endif      
00123       
00124    }
00125    return ( retVal );
00126 }
00127 
00128 //
00129 // write
00130 int I2CIO::write ( uint8_t value )
00131 {
00132    int status = 0;
00133    
00134    if ( _initialised )
00135    {
00136       // Only write HIGH the values of the ports that have been initialised as
00137       // outputs updating the output shadow of the device
00138       _shadow = ( value & ~(_dirMask) );
00139    
00140       Wire.beginTransmission ( _i2cAddr );
00141 #if (ARDUINO <  100)
00142       Wire.send ( _shadow );
00143 #else
00144       Wire.write ( _shadow );
00145 #endif  
00146       status = Wire.endTransmission ();
00147    }
00148    return ( (status == 0) );
00149 }
00150 
00151 //
00152 // digitalRead
00153 uint8_t I2CIO::digitalRead ( uint8_t pin )
00154 {
00155    uint8_t pinVal = 0;
00156    
00157    // Check if initialised and that the pin is within range of the device
00158    // -------------------------------------------------------------------
00159    if ( ( _initialised ) && ( pin <= 7 ) )
00160    {
00161       // Remove the values which are not inputs and get the value of the pin
00162       pinVal = this->read() & _dirMask;
00163       pinVal = ( pinVal >> pin ) & 0x01; // Get the pin value
00164    }
00165    return (pinVal);
00166 }
00167 
00168 //
00169 // digitalWrite
00170 int I2CIO::digitalWrite ( uint8_t pin, uint8_t level )
00171 {
00172    uint8_t writeVal;
00173    int status = 0;
00174    
00175    // Check if initialised and that the pin is within range of the device
00176    // -------------------------------------------------------------------
00177    if ( ( _initialised ) && ( pin <= 7 ) )
00178    {
00179       // Only write to HIGH the port if the port has been configured as
00180       // an OUTPUT pin. Add the new state of the pin to the shadow
00181       writeVal = ( 1 << pin ) & ~_dirMask;
00182       if ( level == HIGH )
00183       {
00184          _shadow |= writeVal;
00185                                                       
00186       }
00187       else 
00188       {
00189          _shadow &= ~writeVal;
00190       }
00191       status = this->write ( _shadow );
00192    }
00193    return ( status );
00194 }
00195 
00196 //
00197 // PRIVATE METHODS
00198 // ---------------------------------------------------------------------------
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines