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