![]() |
LCD Library 1.3.0
LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library.
|
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 // ---------------------------------------------------------------------------