LCD Library 1.2.1
LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library.
/Users/fmalpartida/development/ardWorkspace/LiquidCrystal_I2C/LiquiCrystal_I2C/FastIO.cpp
Go to the documentation of this file.
00001 // ---------------------------------------------------------------------------
00002 // Created by Florian Fida on 20/01/12
00003 // Copyright 2012 - Under creative commons license 3.0:
00004 //        Attribution-ShareAlike CC BY-SA
00005 //        http://creativecommons.org/licenses/by-sa/3.0/
00006 //
00007 // This software is furnished "as is", without technical support, and with no
00008 // warranty, express or implied, as to its usefulness for any purpose.
00009 // ---------------------------------------------------------------------------
00010 // fio_shiftOut1 functions are based on Shif1 protocol developed by Roman Black 
00011 // (http://www.romanblack.com/shift1.htm)
00012 //
00013 // Thread Safe: No
00014 // Extendable: Yes
00015 //
00016 // @file FastIO.h
00017 // This file implements basic fast IO routines.
00018 // 
00019 // @brief 
00020 //
00021 // @version API 1.0.0
00022 //
00023 // @author Florian Fida -
00024 //
00025 // 2012-03-16 bperrybap updated fio_shiftout() to be smaller & faster
00026 //
00027 // @todo:
00028 //  support chipkit:
00029 // (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/
00030 //   cores/pic32/wiring_digital.c)
00031 // ---------------------------------------------------------------------------
00032 #include "FastIO.h"
00033 
00034 
00035 fio_register fio_pinToOutputRegister(uint8_t pin, uint8_t initial_state)
00036 {
00037         pinMode(pin, OUTPUT);
00038    
00039         if(initial_state != SKIP) 
00040    {
00041       digitalWrite(pin, initial_state); // also turns off pwm timer
00042    }
00043 #ifdef FIO_FALLBACK
00044          //  just wasting memory if not using fast io...
00045         return 0;
00046 #else
00047          return portOutputRegister(digitalPinToPort(pin));
00048 #endif
00049  }
00050 
00051 
00052 fio_register fio_pinToInputRegister(uint8_t pin)
00053 {
00054         pinMode(pin, INPUT);
00055         digitalWrite(pin, LOW); // also turns off pwm timer and pullup
00056 #ifdef FIO_FALLBACK
00057          //  just wasting memory if not using fast io...
00058         return 0;
00059 #else
00060          return portInputRegister(digitalPinToPort(pin));
00061 #endif
00062  }
00063 
00064 
00065 fio_bit fio_pinToBit(uint8_t pin)
00066 {
00067 #ifdef FIO_FALLBACK
00068          // (ab)use the bit variable to store the pin
00069         return pin;
00070 #else
00071          return digitalPinToBitMask(pin);
00072 #endif
00073  }
00074 
00075 
00076 void fio_digitalWrite(fio_register pinRegister, fio_bit pinBit, uint8_t value) 
00077 {
00078 #ifdef FIO_FALLBACK
00079          digitalWrite(pinBit, value);
00080 #else
00081     ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00082    {
00083       if(value == LOW)
00084       {
00085          fio_digitalWrite_LOW(pinRegister,pinBit);
00086       }
00087       else
00088       {
00089          fio_digitalWrite_HIGH(pinRegister,pinBit);
00090       }
00091    }
00092 #endif
00093  }
00094 
00095 int fio_digitalRead(fio_register pinRegister, uint8_t pinBit)
00096 {
00097 #ifdef FIO_FALLBACK
00098          return digitalRead (pinBit);
00099 #else
00100          if (*pinRegister & pinBit)
00101    {
00102       return HIGH;
00103    }
00104         return LOW;
00105 #endif
00106  }
00107 
00108 void fio_shiftOut (fio_register dataRegister, fio_bit dataBit, 
00109                    fio_register clockRegister, fio_bit clockBit, 
00110                    uint8_t value, uint8_t bitOrder)
00111 {
00112         // # disable interrupts
00113         int8_t i;
00114    
00115         if(bitOrder == LSBFIRST)
00116         {
00117                 for(i = 0; i < 8; i++)
00118                 {
00119                         ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00120                         {
00121                                 if(value & 1)
00122             {
00123                fio_digitalWrite_HIGH(dataRegister, dataBit);
00124                                 }
00125             else
00126             {
00127                fio_digitalWrite_LOW(dataRegister, dataBit);
00128             }
00129             value >>= 1;
00130                                 fio_digitalWrite_HIGH (clockRegister, clockBit);
00131                                 fio_digitalWrite_LOW (clockRegister,clockBit);
00132                         }
00133                 }
00134       
00135         }
00136         else
00137         {
00138                 for(i = 0; i < 8; i++)
00139                 {
00140                         ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00141                         {
00142                                 if(value & 0x80)
00143             {
00144                fio_digitalWrite_HIGH(dataRegister, dataBit);
00145                                 }
00146             else
00147             {
00148                fio_digitalWrite_LOW(dataRegister, dataBit);
00149             }
00150                                 value <<= 1;
00151                                 fio_digitalWrite_HIGH (clockRegister, clockBit);
00152                                 fio_digitalWrite_LOW (clockRegister,clockBit);
00153                         }
00154                 }
00155         }
00156 }
00157 
00158 
00159 void fio_shiftOut(fio_register dataRegister, fio_bit dataBit, 
00160                   fio_register clockRegister, fio_bit clockBit)
00161 {
00162    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00163    {
00164       // shift out 0x0 (B00000000) fast, byte order is irrelevant
00165       fio_digitalWrite_LOW (dataRegister, dataBit);
00166       
00167       for(uint8_t i = 0; i<8; ++i)
00168       {
00169          fio_digitalWrite_HIGH (clockRegister, clockBit);
00170          fio_digitalWrite_SWITCH (clockRegister, clockBit);
00171       }
00172    }
00173 }
00174 
00175 
00176 void fio_shiftOut1_init(uint8_t pin)
00177 {
00178         fio_shiftOut1_init(fio_pinToOutputRegister(pin,HIGH),fio_pinToBit(pin));
00179 }
00180 
00181 void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit)
00182 {
00183         // Make sure that capacitors are charged
00184         // 300us is an educated guess...
00185         fio_digitalWrite(shift1Register,shift1Bit,HIGH);
00186         delayMicroseconds(300);
00187 }
00188 
00189 
00190 void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, 
00191                    boolean noLatch)
00192 {
00193         /*
00194          * this function are based on Shif1 protocol developed by Roman Black 
00195     *    (http://www.romanblack.com/shift1.htm)
00196          *
00197          * test sketches:
00198          *      http://pastebin.com/raw.php?i=2hnC9v2Z
00199          *      http://pastebin.com/raw.php?i=bGg4DhXQ
00200          *      http://pastebin.com/raw.php?i=tg1ZFiM5
00201          *    http://pastebin.com/raw.php?i=93ExPDD3 - cascading
00202          * tested with:
00203          *      TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
00204     *                   arduino-one-wire-shift-register-prototype)
00205          *      7HC595N
00206          */
00207    
00208         // iterate but ignore last bit (is it correct now?)
00209         for(int8_t i = 7; i>=0; --i)
00210    {
00211       
00212                 // assume that pin is HIGH (smokin' pot all day... :) - requires 
00213       // initialization
00214                 if(value & _BV(i))
00215       {
00216          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00217          {
00218             // HIGH = 1 Bit
00219             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00220             //hold pin LOW for 1us - done! :)
00221             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00222          } // end critical section
00223          //hold pin HIGH for 15us
00224          delayMicroseconds(15);
00225                 }
00226       else
00227       {
00228          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00229          {
00230             // LOW = 0 Bit
00231             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00232             // hold pin LOW for 15us
00233             delayMicroseconds(15);
00234             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00235          } // end critical section
00236          
00237          // hold pin HIGH for 30us
00238          delayMicroseconds(30);         
00239                 }
00240                 if(!noLatch && i==1)
00241       {
00242          break;
00243       }
00244         }
00245    
00246         if(!noLatch)
00247    {
00248       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00249       {
00250          // send last bit (=LOW) and Latch command
00251          fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00252       } // end critical section
00253       delayMicroseconds(199);           // Hold pin low for 200us
00254       
00255       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00256       {
00257          fio_digitalWrite_HIGH(shift1Register,shift1Bit);
00258       } // end critical section
00259                 delayMicroseconds(299);   // Hold pin high for 300us and leave it that 
00260       // way - using explicit HIGH here, just in case.
00261         }
00262 }
00263 
00264 void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch)
00265 {
00266         fio_shiftOut1(fio_pinToOutputRegister(pin, SKIP),fio_pinToBit(pin),value, noLatch);
00267 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines