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