LCD Library 1.2.0
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 // @todo:
00026 //  support chipkit:
00027 // (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/
00028 //   cores/pic32/wiring_digital.c)
00029 // ---------------------------------------------------------------------------
00030 #include "FastIO.h"
00031 
00032 fio_register fio_pinToOutputRegister(uint8_t pin, uint8_t initial_state)
00033 {
00034         pinMode(pin, OUTPUT);
00035    
00036         if(initial_state != SKIP) 
00037    {
00038       digitalWrite(pin, initial_state); // also turns off pwm timer
00039    }
00040 #ifdef FIO_FALLBACK
00041         //  just wasting memory if not using fast io...
00042         return 0;
00043 #else
00044         return portOutputRegister(digitalPinToPort(pin));
00045 #endif
00046 }
00047 
00048 fio_register fio_pinToInputRegister(uint8_t pin)
00049 {
00050         pinMode(pin, INPUT);
00051         digitalWrite(pin, LOW); // also turns off pwm timer and pullup
00052 #ifdef FIO_FALLBACK
00053         //  just wasting memory if not using fast io...
00054         return 0;
00055 #else
00056         return portInputRegister(digitalPinToPort(pin));
00057 #endif
00058 }
00059 
00060 uint8_t fio_pinToBit(uint8_t pin)
00061 {
00062 #ifdef FIO_FALLBACK
00063         // (ab)use the bit variable to store the pin
00064         return pin;
00065 #else
00066         return digitalPinToBitMask(pin);
00067 #endif
00068 }
00069 
00070 void fio_digitalWrite(fio_register pinRegister, uint8_t pinBit, uint8_t value) 
00071 {
00072 #ifdef FIO_FALLBACK
00073         digitalWrite(pinBit, value);
00074 #else
00075    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00076    {
00077       if(value == LOW)
00078       {
00079          fio_digitalWrite_LOW(pinRegister,pinBit);
00080       }
00081       else
00082       {
00083          fio_digitalWrite_HIGH(pinRegister,pinBit);
00084       }
00085    }
00086 #endif
00087 }
00088 
00089 int fio_digitalRead(fio_register pinRegister, uint8_t pinBit)
00090 {
00091 #ifdef FIO_FALLBACK
00092         return digitalRead (pinBit);
00093 #else
00094         if (*pinRegister & pinBit)
00095    {
00096       return HIGH;
00097    }
00098         return LOW;
00099 #endif
00100 }
00101 
00102 void fio_shiftOut (fio_register dataRegister, fio_bit dataBit, 
00103                    fio_register clockRegister, fio_bit clockBit, 
00104                    uint8_t value, uint8_t bitOrder)
00105 {
00106         // # disable interrupts
00107         int8_t i;
00108    
00109    
00110    for(i = 0; i < 8; i++)
00111    {
00112       if (bitOrder == LSBFIRST)
00113       {
00114          fio_digitalWrite(dataRegister, dataBit, !!(value & (1 << i)));
00115       }
00116       else
00117       {
00118          fio_digitalWrite(dataRegister, dataBit, !!(value & (1 << (7 - i))));
00119       }
00120       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00121       {
00122          fio_digitalWrite_HIGH (clockRegister, clockBit);
00123          
00124          // Switching is a little bit faster
00125          fio_digitalWrite_SWITCH (clockRegister,clockBit);
00126       } // end critical section
00127       
00128    } 
00129 }
00130 
00131 void fio_shiftOut(fio_register dataRegister, uint8_t dataBit, 
00132                   fio_register clockRegister, uint8_t clockBit)
00133 {
00134    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00135    {
00136       // shift out 0x0 (B00000000) fast, byte order is irrelevant
00137       fio_digitalWrite_LOW (dataRegister, dataBit);
00138       
00139       for(uint8_t i = 0; i<8; ++i)
00140       {
00141          fio_digitalWrite_HIGH (clockRegister, clockBit);
00142          fio_digitalWrite_SWITCH (clockRegister, clockBit);
00143       }
00144    }
00145 }
00146 void fio_shiftOut1_init(uint8_t pin)
00147 {
00148         fio_shiftOut1_init(fio_pinToOutputRegister(pin,HIGH),fio_pinToBit(pin));
00149 }
00150 
00151 void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit)
00152 {
00153         // Make sure that capacitors are charged
00154         // 300us is an educated guess...
00155         fio_digitalWrite(shift1Register,shift1Bit,HIGH);
00156         delayMicroseconds(300);
00157 }
00158 void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, 
00159                    boolean noLatch)
00160 {
00161         /*
00162          * this function are based on Shif1 protocol developed by Roman Black 
00163     *    (http://www.romanblack.com/shift1.htm)
00164          *
00165          * test sketches:
00166          *      http://pastebin.com/raw.php?i=2hnC9v2Z
00167          *      http://pastebin.com/raw.php?i=bGg4DhXQ
00168          *      http://pastebin.com/raw.php?i=tg1ZFiM5
00169          *    http://pastebin.com/raw.php?i=93ExPDD3 - cascading
00170          * tested with:
00171          *      TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
00172     *                   arduino-one-wire-shift-register-prototype)
00173          *      7HC595N
00174          */
00175    
00176         // iterate but ignore last bit (is it correct now?)
00177         for(int8_t i = 7; i>=0; --i)
00178    {
00179       
00180                 // assume that pin is HIGH (smokin' pot all day... :) - requires 
00181       // initialization
00182                 if(value & _BV(i))
00183       {
00184          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00185          {
00186             // HIGH = 1 Bit
00187             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00188             //hold pin LOW for 1us - done! :)
00189             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00190          } // end critical section
00191          //hold pin HIGH for 15us
00192          delayMicroseconds(15);
00193                 }
00194       else
00195       {
00196          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00197          {
00198             // LOW = 0 Bit
00199             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00200             // hold pin LOW for 15us
00201             delayMicroseconds(15);
00202             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00203          } // end critical section
00204          
00205          // hold pin HIGH for 30us
00206          delayMicroseconds(30);         
00207                 }
00208                 if(!noLatch && i==1)
00209       {
00210          break;
00211       }
00212         }
00213    
00214         if(!noLatch)
00215    {
00216       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00217       {
00218          // send last bit (=LOW) and Latch command
00219          fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00220       } // end critical section
00221       delayMicroseconds(199);           // Hold pin low for 200us
00222       
00223       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00224       {
00225          fio_digitalWrite_HIGH(shift1Register,shift1Bit);
00226       } // end critical section
00227                 delayMicroseconds(299);   // Hold pin high for 300us and leave it that 
00228       // way - using explicit HIGH here, just in case.
00229         }
00230 }
00231 
00232 void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch)
00233 {
00234         fio_shiftOut1(fio_pinToOutputRegister(pin, SKIP),fio_pinToBit(pin),value, noLatch);
00235 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines