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 // @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    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00110    {
00111       for(i = 0; i < 8; i++)
00112       {
00113          if (bitOrder == LSBFIRST)
00114          {
00115             fio_digitalWrite(dataRegister, dataBit, !!(value & (1 << i)));
00116          }
00117          else
00118          {
00119             fio_digitalWrite(dataRegister, dataBit, !!(value & (1 << (7 - i))));
00120          }
00121          fio_digitalWrite_HIGH (clockRegister, clockBit);
00122          
00123          // Switching is a little bit faster
00124          fio_digitalWrite_SWITCH (clockRegister,clockBit);
00125       }
00126    } // end critical section
00127 }
00128 
00129 void fio_shiftOut(fio_register dataRegister, uint8_t dataBit, 
00130                   fio_register clockRegister, uint8_t clockBit)
00131 {
00132    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00133    {
00134       // shift out 0x0 (B00000000) fast, byte order is irrelevant
00135       fio_digitalWrite_LOW (dataRegister, dataBit);
00136 
00137       for(uint8_t i = 0; i<8; ++i)
00138       {
00139          fio_digitalWrite_HIGH (clockRegister, clockBit);
00140          fio_digitalWrite_SWITCH (clockRegister, clockBit);
00141       }
00142    }
00143 }
00144 void fio_shiftOut1_init(uint8_t pin)
00145 {
00146         fio_shiftOut1_init(fio_pinToOutputRegister(pin,HIGH),fio_pinToBit(pin));
00147 }
00148 
00149 void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit)
00150 {
00151         // Make sure that capacitors are charged
00152         // 300us is an educated guess...
00153         fio_digitalWrite(shift1Register,shift1Bit,HIGH);
00154         delayMicroseconds(300);
00155 }
00156 void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, 
00157                    boolean noLatch)
00158 {
00159         /*
00160          * this function are based on Shif1 protocol developed by Roman Black 
00161     *    (http://www.romanblack.com/shift1.htm)
00162          *
00163          * test sketches:
00164          *      http://pastebin.com/raw.php?i=2hnC9v2Z
00165          *      http://pastebin.com/raw.php?i=bGg4DhXQ
00166          *      http://pastebin.com/raw.php?i=tg1ZFiM5
00167          *    http://pastebin.com/raw.php?i=93ExPDD3 - cascading
00168          * tested with:
00169          *      TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
00170     *                   arduino-one-wire-shift-register-prototype)
00171          *      7HC595N
00172          */
00173 
00174         // iterate but ignore last bit (is it correct now?)
00175         for(int8_t i = 7; i>=0; --i)
00176    {
00177 
00178                 // assume that pin is HIGH (smokin' pot all day... :) - requires 
00179       // initialization
00180                 if(value & _BV(i))
00181       {
00182          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00183          {
00184             // HIGH = 1 Bit
00185             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00186             //hold pin LOW for 1us - done! :)
00187             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00188             //hold pin HIGH for 15us
00189          } // end critical section
00190          delayMicroseconds(15);
00191                 }
00192       else
00193       {
00194          ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00195          {
00196             // LOW = 0 Bit
00197             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00198             // hold pin LOW for 15us
00199             delayMicroseconds(15);
00200             fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
00201          } // end critical section
00202          // hold pin HIGH for 30us
00203          delayMicroseconds(30);         
00204                 }
00205                 if(!noLatch && i==1)
00206       {
00207          break;
00208       }
00209         }
00210    
00211         if(!noLatch)
00212    {
00213       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00214       {
00215          // send last bit (=LOW) and Latch command
00216          fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
00217       } // end critical section
00218       delayMicroseconds(199);           // Hold pin low for 200us
00219 
00220       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
00221       {
00222          fio_digitalWrite_HIGH(shift1Register,shift1Bit);
00223       } // end critical section
00224                 delayMicroseconds(299);   // Hold pin high for 300us and leave it that 
00225                                 // way - using explicit HIGH here, just in case.
00226         }
00227 }
00228 
00229 void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch)
00230 {
00231         fio_shiftOut1(fio_pinToOutputRegister(pin, SKIP),fio_pinToBit(pin),value, noLatch);
00232 }
 All Classes Files Functions Variables Typedefs Defines