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// 2012-03-16 bperrybap mods for chipkit32 (pic32) Arduino 25// support chipkit: 26// (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/ 27// cores/pic32/wiring_digital.c) 28// --------------------------------------------------------------------------- 29#ifndef _FAST_IO_H_ 30#define _FAST_IO_H_ 31 32#if (ARDUINO < 100) 33#include <WProgram.h> 34#else 35#include <Arduino.h> 36#endif 37 38#include <pins_arduino.h>// pleasing sanguino core 39#include <inttypes.h> 40 41 42#define SKIP 0x23 43 44#if defined (__AVR__) 45#include <util/atomic.h>// for critical section management 46typedefuint8_t fio_bit; 47typedef volatileuint8_t*fio_register; 48 49 50#elif defined(__PIC32MX__) 51typedefuint32_t fio_bit; 52typedef volatileuint32_t*fio_register; 53 54 55#else 56// fallback to Arduino standard digital i/o routines 57#define FIO_FALLBACK 58#define ATOMIC_BLOCK(dummy) if(true) 59#define ATOMIC_RESTORESTATE 60typedefuint8_t fio_bit; 61typedefuint8_t fio_register; 62#endif 63 64 65 66#if !defined(FIO_FALLBACK) && !defined(ATOMIC_BLOCK) 67/* 68 * Define an ATOMIC_BLOCK that implements ATOMIC_FORCEON type 69 * Using the portable Arduino interrupts() and noInterrupts() 70 */ 71#define ATOMIC_RESTORESTATE ATOMIC_FORCEON// sorry, no support for save/restore yet. 72#define ATOMIC_FORCEON uint8_t sreg_save \ 73 __attribute__((__cleanup__(__iSeiParam))) = 0 74 75static __inline__ uint8_t__iCliRetVal(void) 76{ 77noInterrupts(); 78return(1); 79} 80static __inline__ void__iSeiParam(const uint8_t*__s) 81{ 82interrupts(); 83} 84#define ATOMIC_BLOCK(type) for(type, __Todo = __iCliRetVal(); __Todo; __Todo = 0) 85 86#endif// end of block to create compatible ATOMIC_BLOCK() 87 88 89 90/*! 91 @function 92 @abstract Get the output register for specified pin. 93 @discussion if fast digital IO is disabled this function returns NULL 94 @param pin[in] Number of a digital pin 95 @result Register 96 */ 97fio_register fio_pinToOutputRegister(uint8_t pin,uint8_t initial_state = LOW); 98 99/*! 100 @function 101 @abstract Get the input register for specified pin. 102 @discussion if fast digital IO is disabled this function returns NULL 103 @param pin[in] Number of a digital pin 104 @result Register 105 */ 106fio_register fio_pinToInputRegister(uint8_t pin); 107 108/*! 109 @function 110 @abstract Find the bit which belongs to specified pin 111 @discussion if fast digitalWrite is disabled this function returns the pin 112 @param pin[in] Number of a digital pin 113 @result Bit 114 */ 115fio_bit fio_pinToBit(uint8_t pin); 116 117 118/*! 119 @method 120 @abstract direct digital write 121 @discussion without any checks 122 @discussion falls back to normal digitalWrite if fast io is disabled 123 @param pinRegister[in] Register - ignored if fast digital write is disabled 124 @param pinBit[in] Bit - Pin if fast digital write is disabled 125 @param value[in] desired output 126 */ 127// __attribute__ ((always_inline)) /* let the optimizer decide that for now */ 128voidfio_digitalWrite( fio_register pinRegister, fio_bit pinBit,uint8_t value ); 129 130/** 131 * This is where the magic happens that makes things fast. 132 * Implemented as preprocessor directives to force inlining 133 * SWITCH is fast for FIO but probably slow for FIO_FALLBACK so SWITCHTO is recommended if the value is known. 134 */ 135 136#ifndef FIO_FALLBACK 137#define fio_digitalWrite_LOW(reg,bit) *reg &= ~bit 138#define fio_digitalWrite_HIGH(reg,bit) *reg |= bit 139#define fio_digitalWrite_SWITCH(reg,bit) *reg ^= bit 140#define fio_digitalWrite_SWITCHTO(reg,bit,val) fio_digitalWrite_SWITCH(reg,bit) 141#else 142// reg -> dummy NULL, bit -> pin 143#define fio_digitalWrite_HIGH(reg,bit) digitalWrite(bit,HIGH) 144#define fio_digitalWrite_LOW(reg,bit) digitalWrite(bit,LOW) 145#define fio_digitalWrite_SWITCH(reg,bit) digitalWrite(bit, !digitalRead(bit)) 146#define fio_digitalWrite_SWITCHTO(reg,bit,val) digitalWrite(bit,val); 147#endif 148 149/*! 150 @function 151 @abstract direct digital read 152 @discussion without any checks 153 @discussion falls back to normal digitalRead if fast io is disabled 154 @param pinRegister[in] Register - ignored if fast io is disabled 155 @param pinBit[in] Bit - Pin if fast io is disabled 156 @result Value read from pin 157 */ 158intfio_digitalRead( fio_register pinRegister, fio_bit pinBit ); 159 160/*! 161 @method 162 @abstract faster shift out 163 @discussion using fast digital write 164 @discussion falls back to normal digitalWrite if fastio is disabled 165 @param dataRegister[in] Register of data pin - ignored if fast digital write is disabled 166 @param dataBit[in] Bit of data pin - Pin if fast digital write is disabled 167 @param clockRegister[in] Register of data pin - ignored if fast digital write is disabled 168 @param clockBit[in] Bit of data pin - Pin if fast digital write is disabled 169 @param bitOrder[in] bit order 170 */ 171voidfio_shiftOut( fio_register dataRegister, fio_bit dataBit, fio_register clockRegister, 172 fio_bit clockBit,uint8_t value,uint8_t bitOrder ); 173 174/*! 175 @method 176 @abstract faster shift out clear 177 @discussion using fast digital write 178 @discussion falls back to normal digitalWrite if fastio is disabled 179 @param dataRegister[in] Register of data pin - ignored if fast digital write is disabled 180 @param dataBit[in] Bit of data pin - Pin if fast digital write is disabled 181 @param clockRegister[in] Register of data pin - ignored if fast digital write is disabled 182 @param clockBit[in] Bit of data pin - Pin if fast digital write is disabled 183 */ 184voidfio_shiftOut(fio_register dataRegister, fio_bit dataBit, fio_register clockRegister, fio_bit clockBit); 185 186/*! 187 * @method 188 * @abstract one wire shift out 189 * @discussion protocol needs initialisation (fio_shiftOut1_init) 190 * @param shift1Register[in] pins register 191 * @param shift1Bit[in] pins bit 192 * @param value[in] value to shift out, last byte is ignored and always shifted out LOW 193 */ 194voidfio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit,uint8_t value, boolean noLatch =false); 195/*! 196 * @method 197 * @abstract one wire shift out 198 * @discussion protocol needs initialisation (fio_shiftOut1_init) 199 * @param pin[in] digital pin 200 * @param value[in] value to shift out, last byte is ignored and always shifted out LOW 201 */ 202voidfio_shiftOut1(uint8_t pin,uint8_t value, boolean noLatch =false); 203/*! 204 * @method 205 * @abstract initializes one wire shift out protocol 206 * @discussion Puts pin to HIGH state and delays until Capacitors are charged. 207 * @param shift1Register[in] pins register 208 * @param shift1Bit[in] pins bit 209 */ 210voidfio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit); 211/*! 212 * @method 213 * @abstract initializes one wire shift out protocol 214 * @discussion Puts pin to HIGH state and delays until Capacitors are charged. 215 * @param pin[in] digital pin 216 */ 217voidfio_shiftOut1_init(uint8_t pin); 218 219#endif// FAST_IO_H