libraries / Visuino_LiquidCrystal / Visuino_FastIO.cppon commit Added link to project report (97a3ba0)
   1// ---------------------------------------------------------------------------
   2// Created by Florian Fida on 20/01/12
   3// Copyright 2012 - Under creative commons license 3.0:
   4//        Attribution-ShareAlike CC BY-SA
   5//        http://creativecommons.org/licenses/by-sa/3.0/
   6//
   7// This software is furnished "as is", without technical support, and with no
   8// warranty, express or implied, as to its usefulness for any purpose.
   9// ---------------------------------------------------------------------------
  10// fio_shiftOut1 functions are based on Shif1 protocol developed by Roman Black 
  11// (http://www.romanblack.com/shift1.htm)
  12//
  13// Thread Safe: No
  14// Extendable: Yes
  15//
  16// @file FastIO.h
  17// This file implements basic fast IO routines.
  18// 
  19// @brief 
  20//
  21// @version API 1.0.0
  22//
  23// @author Florian Fida -
  24//
  25// 2012-03-16 bperrybap updated fio_shiftout() to be smaller & faster
  26//
  27// @todo:
  28//  support chipkit:
  29// (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/
  30//   cores/pic32/wiring_digital.c)
  31// ---------------------------------------------------------------------------
  32#include "Visuino_FastIO.h"
  33
  34
  35fio_register fio_pinToOutputRegister(uint8_t pin, uint8_t initial_state)
  36{
  37        pinMode(pin, OUTPUT);
  38   
  39        if(initial_state != SKIP) 
  40   {
  41      digitalWrite(pin, initial_state); // also turns off pwm timer
  42   }
  43#ifdef FIO_FALLBACK
  44        //  just wasting memory if not using fast io...
  45        return 0;
  46#else
  47        return portOutputRegister(digitalPinToPort(pin));
  48#endif
  49}
  50
  51
  52fio_register fio_pinToInputRegister(uint8_t pin)
  53{
  54        pinMode(pin, INPUT);
  55        digitalWrite(pin, LOW); // also turns off pwm timer and pullup
  56#ifdef FIO_FALLBACK
  57        //  just wasting memory if not using fast io...
  58        return 0;
  59#else
  60        return portInputRegister(digitalPinToPort(pin));
  61#endif
  62}
  63
  64
  65fio_bit fio_pinToBit(uint8_t pin)
  66{
  67#ifdef FIO_FALLBACK
  68        // (ab)use the bit variable to store the pin
  69        return pin;
  70#else
  71        return digitalPinToBitMask(pin);
  72#endif
  73}
  74
  75
  76void fio_digitalWrite(fio_register pinRegister, fio_bit pinBit, uint8_t value) 
  77{
  78#ifdef FIO_FALLBACK
  79        digitalWrite(pinBit, value);
  80#else
  81   ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
  82   {
  83      if(value == LOW)
  84      {
  85         fio_digitalWrite_LOW(pinRegister,pinBit);
  86      }
  87      else
  88      {
  89         fio_digitalWrite_HIGH(pinRegister,pinBit);
  90      }
  91   }
  92#endif
  93}
  94
  95int fio_digitalRead(fio_register pinRegister, uint8_t pinBit)
  96{
  97#ifdef FIO_FALLBACK
  98        return digitalRead (pinBit);
  99#else
 100        if (*pinRegister & pinBit)
 101   {
 102      return HIGH;
 103   }
 104        return LOW;
 105#endif
 106}
 107
 108void fio_shiftOut (fio_register dataRegister, fio_bit dataBit, 
 109                   fio_register clockRegister, fio_bit clockBit, 
 110                   uint8_t value, uint8_t bitOrder)
 111{
 112        // # disable interrupts
 113        int8_t i;
 114   
 115        if(bitOrder == LSBFIRST)
 116        {
 117                for(i = 0; i < 8; i++)
 118                {
 119                        ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 120                        {
 121                                if(value & 1)
 122            {
 123               fio_digitalWrite_HIGH(dataRegister, dataBit);
 124                                }
 125            else
 126            {
 127               fio_digitalWrite_LOW(dataRegister, dataBit);
 128            }
 129            value >>= 1;
 130                                fio_digitalWrite_HIGH (clockRegister, clockBit);
 131                                fio_digitalWrite_LOW (clockRegister,clockBit);
 132                        }
 133                }
 134      
 135        }
 136        else
 137        {
 138                for(i = 0; i < 8; i++)
 139                {
 140                        ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 141                        {
 142                                if(value & 0x80)
 143            {
 144               fio_digitalWrite_HIGH(dataRegister, dataBit);
 145                                }
 146            else
 147            {
 148               fio_digitalWrite_LOW(dataRegister, dataBit);
 149            }
 150                                value <<= 1;
 151                                fio_digitalWrite_HIGH (clockRegister, clockBit);
 152                                fio_digitalWrite_LOW (clockRegister,clockBit);
 153                        }
 154                }
 155        }
 156}
 157
 158
 159void fio_shiftOut(fio_register dataRegister, fio_bit dataBit, 
 160                  fio_register clockRegister, fio_bit clockBit)
 161{
 162   ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 163   {
 164      // shift out 0x0 (B00000000) fast, byte order is irrelevant
 165      fio_digitalWrite_LOW (dataRegister, dataBit);
 166      
 167      for(uint8_t i = 0; i<8; ++i)
 168      {
 169         fio_digitalWrite_HIGH (clockRegister, clockBit);
 170         fio_digitalWrite_SWITCH (clockRegister, clockBit);
 171      }
 172   }
 173}
 174
 175
 176void fio_shiftOut1_init(uint8_t pin)
 177{
 178        fio_shiftOut1_init(fio_pinToOutputRegister(pin,HIGH),fio_pinToBit(pin));
 179}
 180
 181void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit)
 182{
 183        // Make sure that capacitors are charged
 184        // 300us is an educated guess...
 185        fio_digitalWrite(shift1Register,shift1Bit,HIGH);
 186        delayMicroseconds(300);
 187}
 188
 189
 190void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, 
 191                   boolean noLatch)
 192{
 193        /*
 194         * this function are based on Shif1 protocol developed by Roman Black 
 195    *    (http://www.romanblack.com/shift1.htm)
 196         *
 197         * test sketches:
 198         *      http://pastebin.com/raw.php?i=2hnC9v2Z
 199         *      http://pastebin.com/raw.php?i=bGg4DhXQ
 200         *      http://pastebin.com/raw.php?i=tg1ZFiM5
 201         *    http://pastebin.com/raw.php?i=93ExPDD3 - cascading
 202         * tested with:
 203         *      TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
 204    *                   arduino-one-wire-shift-register-prototype)
 205         *      7HC595N
 206         */
 207   
 208        // iterate but ignore last bit (is it correct now?)
 209        for(int8_t i = 7; i>=0; --i)
 210   {
 211      
 212                // assume that pin is HIGH (smokin' pot all day... :) - requires 
 213      // initialization
 214                if(value & _BV(i))
 215      {
 216         ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 217         {
 218            // HIGH = 1 Bit
 219            fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
 220            //hold pin LOW for 1us - done! :)
 221            fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
 222         } // end critical section
 223         //hold pin HIGH for 15us
 224         delayMicroseconds(15);
 225                }
 226      else
 227      {
 228         ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 229         {
 230            // LOW = 0 Bit
 231            fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
 232            // hold pin LOW for 15us
 233            delayMicroseconds(15);
 234            fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
 235         } // end critical section
 236         
 237         // hold pin HIGH for 30us
 238         delayMicroseconds(30);         
 239                }
 240                if(!noLatch && i==1)
 241      {
 242         break;
 243      }
 244        }
 245   
 246        if(!noLatch)
 247   {
 248      ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 249      {
 250         // send last bit (=LOW) and Latch command
 251         fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
 252      } // end critical section
 253      delayMicroseconds(199);           // Hold pin low for 200us
 254      
 255      ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
 256      {
 257         fio_digitalWrite_HIGH(shift1Register,shift1Bit);
 258      } // end critical section
 259                delayMicroseconds(299);   // Hold pin high for 300us and leave it that 
 260      // way - using explicit HIGH here, just in case.
 261        }
 262}
 263
 264void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch)
 265{
 266        fio_shiftOut1(fio_pinToOutputRegister(pin, SKIP),fio_pinToBit(pin),value, noLatch);
 267}