libraries / Visuino_LiquidCrystal / Visuino_I2CIO.cppon commit Added link to project report (97a3ba0)
   1// ---------------------------------------------------------------------------
   2// Created by Francisco Malpartida on 20/08/11.
   3// Copyright 2011 - Under creative commons license 3.0:
   4//        Attribution-ShareAlike CC BY-SA
   5//
   6// This software is furnished "as is", without technical support, and with no 
   7// warranty, express or implied, as to its usefulness for any purpose.
   8//
   9// Thread Safe: No
  10// Extendable: Yes
  11//
  12// @file I2CIO.h
  13// This file implements a basic IO library using the PCF8574 I2C IO Expander
  14// chip.
  15// 
  16// @brief 
  17// Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
  18// The library implements basic IO general methods to configure IO pin direction
  19// read and write uint8_t operations and basic pin level routines to set or read
  20// a particular IO port.
  21//
  22//
  23// @version API 1.0.0
  24//
  25// @author F. Malpartida - fmalpartida@gmail.com
  26// ---------------------------------------------------------------------------
  27#if (ARDUINO <  100)
  28#include <WProgram.h>
  29#else
  30#include <Arduino.h>
  31#endif
  32
  33#include <inttypes.h>
  34
  35#include <Wire.h>
  36#include "Visuino_I2CIO.h"
  37
  38// CLASS VARIABLES
  39// ---------------------------------------------------------------------------
  40
  41
  42// CONSTRUCTOR
  43// ---------------------------------------------------------------------------
  44I2CIO::I2CIO ( )
  45{
  46   _i2cAddr     = 0x0;
  47   _dirMask     = 0xFF;    // mark all as INPUTs
  48   _shadow      = 0x0;     // no values set
  49   _initialised = false;
  50}
  51
  52// PUBLIC METHODS
  53// ---------------------------------------------------------------------------
  54
  55//
  56// begin
  57int I2CIO::begin (  uint8_t i2cAddr )
  58{
  59   _i2cAddr = i2cAddr;
  60   
  61   Wire.begin ( );
  62      
  63   _initialised = Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
  64
  65#if (ARDUINO <  100)
  66   _shadow = Wire.receive ();
  67#else
  68   _shadow = Wire.read (); // Remove the byte read don't need it.
  69#endif
  70   
  71   return ( _initialised );
  72}
  73
  74//
  75// pinMode
  76void I2CIO::pinMode ( uint8_t pin, uint8_t dir )
  77{
  78   if ( _initialised )
  79   {
  80      if ( OUTPUT == dir )
  81      {
  82         _dirMask &= ~( 1 << pin );
  83      }
  84      else 
  85      {
  86         _dirMask |= ( 1 << pin );
  87      }
  88   }
  89}
  90
  91//
  92// portMode
  93void I2CIO::portMode ( uint8_t dir )
  94{
  95   
  96   if ( _initialised )
  97   {
  98      if ( dir == INPUT )
  99      {
 100         _dirMask = 0xFF;
 101      }
 102      else
 103      {
 104         _dirMask = 0x00;
 105      }
 106   }
 107}
 108
 109//
 110// read
 111uint8_t I2CIO::read ( void )
 112{
 113   uint8_t retVal = 0;
 114   
 115   if ( _initialised )
 116   {
 117      Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
 118#if (ARDUINO <  100)
 119      retVal = ( _dirMask & Wire.receive ( ) );
 120#else
 121      retVal = ( _dirMask & Wire.read ( ) );
 122#endif      
 123      
 124   }
 125   return ( retVal );
 126}
 127
 128//
 129// write
 130int I2CIO::write ( uint8_t value )
 131{
 132   int status = 0;
 133   
 134   if ( _initialised )
 135   {
 136      // Only write HIGH the values of the ports that have been initialised as
 137      // outputs updating the output shadow of the device
 138      _shadow = ( value & ~(_dirMask) );
 139   
 140      Wire.beginTransmission ( _i2cAddr );
 141#if (ARDUINO <  100)
 142      Wire.send ( _shadow );
 143#else
 144      Wire.write ( _shadow );
 145#endif  
 146      status = Wire.endTransmission ();
 147   }
 148   return ( (status == 0) );
 149}
 150
 151//
 152// digitalRead
 153uint8_t I2CIO::digitalRead ( uint8_t pin )
 154{
 155   uint8_t pinVal = 0;
 156   
 157   // Check if initialised and that the pin is within range of the device
 158   // -------------------------------------------------------------------
 159   if ( ( _initialised ) && ( pin <= 7 ) )
 160   {
 161      // Remove the values which are not inputs and get the value of the pin
 162      pinVal = this->read() & _dirMask;
 163      pinVal = ( pinVal >> pin ) & 0x01; // Get the pin value
 164   }
 165   return (pinVal);
 166}
 167
 168//
 169// digitalWrite
 170int I2CIO::digitalWrite ( uint8_t pin, uint8_t level )
 171{
 172   uint8_t writeVal;
 173   int status = 0;
 174   
 175   // Check if initialised and that the pin is within range of the device
 176   // -------------------------------------------------------------------
 177   if ( ( _initialised ) && ( pin <= 7 ) )
 178   {
 179      // Only write to HIGH the port if the port has been configured as
 180      // an OUTPUT pin. Add the new state of the pin to the shadow
 181      writeVal = ( 1 << pin ) & ~_dirMask;
 182      if ( level == HIGH )
 183      {
 184         _shadow |= writeVal;
 185                                                      
 186      }
 187      else 
 188      {
 189         _shadow &= ~writeVal;
 190      }
 191      status = this->write ( _shadow );
 192   }
 193   return ( status );
 194}
 195
 196//
 197// PRIVATE METHODS
 198// ---------------------------------------------------------------------------