959
|
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
|
|
46 typedef uint8_t fio_bit;
|
|
47 typedef volatile uint8_t *fio_register;
|
|
48
|
|
49
|
|
50 #elif defined(__PIC32MX__)
|
|
51 typedef uint32_t fio_bit;
|
|
52 typedef volatile uint32_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
|
|
60 typedef uint8_t fio_bit;
|
|
61 typedef uint8_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
|
|
75 static __inline__ uint8_t __iCliRetVal(void)
|
|
76 {
|
|
77 noInterrupts();
|
|
78 return(1);
|
|
79 }
|
|
80 static __inline__ void __iSeiParam(const uint8_t *__s)
|
|
81 {
|
|
82 interrupts();
|
|
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 */
|
|
97 fio_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 */
|
|
106 fio_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 */
|
|
115 fio_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 */
|
|
128 void fio_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 */
|
|
158 int fio_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 */
|
|
171 void fio_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 */
|
|
184 void fio_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 */
|
|
194 void fio_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 */
|
|
202 void fio_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 */
|
|
210 void fio_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 */
|
|
217 void fio_shiftOut1_init(uint8_t pin);
|
|
218
|
|
219 #endif // FAST_IO_H
|