MySensors Library & Examples
2.3.2-62-ge298769
hal
transport
PJON
driver
interfaces
ARDUINO
PJON_IO.h
1
2
/* Faster digitalWrite, digitalRead, pinMode for Arduino
3
https://codebender.cc/library/digitalWriteFast#bonus%2FdigitalWrite%2Fdigital_write_macros.h
4
- Basic scheme was developed by Paul Stoffregen with digitalWrite.
5
- Extended to pinMode by John Raines
6
- Extended to digitalRead by John Raines with considerable assistance
7
by William Westfield
8
Copyright (c) 2008-2010 PJRC.COM, LLC
9
10
List of supported MCUs:
11
- ATmega8/88/168/328/1280/1284P/2560 (Duemilanove, Uno, Nano, Mini, Pro, Mega)
12
- ATmega16U4/32U4 (Leonardo, Micro)
13
- ATtiny44/84/44A/84A Added by Wilfried Klaas
14
- ATtiny45/85 (Trinket, Digispark)
15
- SAMD21G18A (Arduino Zero) Added by Esben Soeltoft 03/09/2016
16
17
Renamed since v7.0 to avoid naming collisions and so subtle bugs and anomalies
18
if used along with third-party software using older/different versions of
19
digitalWriteFast. All methods are defined in uppercase style to implicitly
20
inform the reader of their definition as macros in the global scope.
21
______________________________________________________________________________
22
23
Permission is hereby granted, free of charge, to any person obtaining a copy
24
of this software and associated documentation files (the "Software"), to deal
25
in the Software without restriction, including without limitation the rights
26
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
copies of the Software, and to permit persons to whom the Software is
28
furnished to do so, subject to the following conditions:
29
30
The above copyright notice and this permission notice shall be included in
31
all copies or substantial portions of the Software.
32
33
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39
THE SOFTWARE. */
40
41
#pragma once
42
43
/* AVR ATmega1280/2560 - Arduino Mega ------------------------------------- */
44
45
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
46
#define PJON_IO_PIN_TO_PORT_REG(P) \
47
((P >= 22 && P <= 29) ? &PORTA : \
48
(((P >= 10 && P <= 13) || (P >= 50 && P <= 53)) ? &PORTB : \
49
((P >= 30 && P <= 37) ? &PORTC : \
50
(((P >= 18 && P <= 21) || P == 38) ? &PORTD : \
51
(((P <= 3) || P == 5) ? &PORTE : \
52
((P >= 54 && P <= 61) ? &PORTF : \
53
(((P >= 39 && P <= 41) || P == 4) ? &PORTG : \
54
(((P >= 6 && P <= 9) || P == 16 || P == 17) ? &PORTH : \
55
((P == 14 || P == 15) ? &PORTJ : \
56
((P >= 62 && P <= 69) ? &PORTK : &PORTL))))))))))
57
58
#define PJON_IO_PIN_TO_DDR_REG(P) \
59
((P >= 22 && P <= 29) ? &DDRA : \
60
(((P >= 10 && P <= 13) || (P >= 50 && P <= 53)) ? &DDRB : \
61
((P >= 30 && P <= 37) ? &DDRC : \
62
(((P >= 18 && P <= 21) || P == 38) ? &DDRD : \
63
(((P <= 3) || P == 5) ? &DDRE : \
64
((P >= 54 && P <= 61) ? &DDRF : \
65
(((P >= 39 && P <= 41) || P == 4) ? &DDRG : \
66
(((P >= 6 && P <= 9) || P == 16 || P == 17) ? &DDRH : \
67
((P == 14 || P == 15) ? &DDRJ : \
68
((P >= 62 && P <= 69) ? &DDRK : &DDRL))))))))))
69
70
#define PJON_IO_PIN_TO_PIN_REG(P) \
71
((P >= 22 && P <= 29) ? &PINA : \
72
(((P >= 10 && P <= 13) || (P >= 50 && P <= 53)) ? &PINB : \
73
((P >= 30 && P <= 37) ? &PINC : \
74
(((P >= 18 && P <= 21) || P == 38) ? &PIND : \
75
(((P <= 3) || P == 5) ? &PINE : \
76
((P >= 54 && P <= 61) ? &PINF : \
77
(((P >= 39 && P <= 41) || P == 4) ? &PING : \
78
(((P >= 6 && P <= 9) || P == 16 || P == 17) ? &PINH : \
79
((P == 14 || P == 15) ? &PINJ : \
80
((P >= 62 && P <= 69) ? &PINK : &PINL))))))))))
81
82
#ifndef PJON_IO_PIN_TO_BIT
83
#define PJON_IO_PIN_TO_BIT(P) \
84
((P >= 7 && P <= 9) ? P - 3 : ((P >= 10 && P <= 13) ? P - 6 : \
85
((P >= 22 && P <= 29) ? P - 22 : ((P >= 30 && P <= 37) ? 37 - P : \
86
((P >= 39 && P <= 41) ? 41 - P : ((P >= 42 && P <= 49) ? 49 - P : \
87
((P >= 50 && P <= 53) ? 53 - P : ((P >= 54 && P <= 61) ? P - 54 : \
88
((P >= 62 && P <= 69) ? P - 62 : ((P == 0 || P == 15 || P == 17 || P == 21) \
89
? 0 : ((P == 1 || P == 14 || P == 16 || P == 20) ? 1 : ((P == 19) ? 2 : \
90
((P == 5 || P == 6 || P == 18) ? 3 : ((P == 2) ? 4 : \
91
((P == 3 || P == 4) ? 5 : 7)))))))))))))))
92
#endif
93
#endif
94
95
/* AVR ATmega88/168/328/328P - Arduino Duemilanove, Uno, Nano, Mini, Pro -- */
96
97
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || \
98
defined(__AVR_ATmega168P__)|| \
99
defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \
100
defined(__AVR_ATmega328PB__)
101
#define PJON_IO_PIN_TO_PORT_REG(P) \
102
((P <= 7) ? &PORTD : ((P >= 8 && P <= 13) ? &PORTB : &PORTC))
103
#define PJON_IO_PIN_TO_DDR_REG(P) \
104
((P <= 7) ? &DDRD : ((P >= 8 && P <= 13) ? &DDRB : &DDRC))
105
#define PJON_IO_PIN_TO_PIN_REG(P) \
106
((P <= 7) ? &PIND : ((P >= 8 && P <= 13) ? &PINB : &PINC))
107
#ifndef PJON_IO_PIN_TO_BIT
108
#define PJON_IO_PIN_TO_BIT(P) \
109
((P <= 7) ? P : ((P >= 8 && P <= 13) ? P - 8 : P - 14))
110
#endif
111
#endif
112
113
/* AVR ATmega16U4/32U4 - Arduino Leonardo, Micro -------------------------- */
114
115
#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
116
#define PJON_IO_PIN_TO_PORT_REG(P) \
117
(((P <= 4) || P == 6 || P == 12 || P == 24 || P == 25 || P == 29) \
118
? &PORTD : ((P == 5 || P == 13) ? &PORTC : ((P >= 18 && P <= 23)) ? &PORTF : \
119
((P == 7) ? &PORTE : &PORTB)))
120
#define PJON_IO_PIN_TO_DDR_REG(P) \
121
(((P <= 4) || P == 6 || P == 12 || P == 24 || P == 25 || P == 29) \
122
? &DDRD : ((P == 5 || P == 13) ? &DDRC : ((P >= 18 && P <= 23)) ? \
123
&DDRF : ((P == 7) ? &DDRE : &DDRB)))
124
#define PJON_IO_PIN_TO_PIN_REG(P) \
125
(((P <= 4) || P == 6 || P == 12 || P == 24 || P == 25 || P == 29) \
126
? &PIND : ((P == 5 || P == 13) ? &PINC : ((P >= 18 && P <= 23)) ? \
127
&PINF : ((P == 7) ? &PINE : &PINB)))
128
#ifndef PJON_IO_PIN_TO_BIT
129
#define PJON_IO_PIN_TO_BIT(P) \
130
((P >= 8 && P <= 11) ? P - 4 : ((P >= 18 && P <= 21) ? 25 - P : \
131
((P == 0) ? 2 : ((P == 1) ? 3 : ((P == 2) ? 1 : ((P == 3) ? 0 : \
132
((P == 4) ? 4 : ((P == 6) ? 7 : ((P == 13) ? 7 : ((P == 14) ? 3 : \
133
((P == 15) ? 1 : ((P == 16) ? 2 : ((P == 17) ? 0 : ((P == 22) ? 1 : \
134
((P == 23) ? 0 : ((P == 24) ? 4 : ((P == 25) ? 7 : ((P == 26) ? 4 : \
135
((P == 27) ? 5 : 6 )))))))))))))))))))
136
#endif
137
#endif
138
139
/* AVR ATtiny45/85 - Trinket, Digispark ----------------------------------- */
140
141
#if defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
142
#define PJON_IO_PIN_TO_PORT_REG(P) &PORTB
143
#define PJON_IO_PIN_TO_DDR_REG(P) &DDRB
144
#define PJON_IO_PIN_TO_PIN_REG(P) &PINB
145
#ifndef PJON_IO_PIN_TO_BIT
146
#define PJON_IO_PIN_TO_BIT(P) P
147
#endif
148
#endif
149
150
/* AVR ATMEGA1284P -------------------------------------------------------- */
151
152
#if defined(__AVR_ATmega1284P__)
153
#define PJON_IO_PIN_TO_PORT_REG(P) \
154
(P >= 24 ? &PORTA : (P <= 7 ? &PORTB : ((P >= 8 && P <=15) ? &PORTD : &PORTC)))
155
#define PJON_IO_PIN_TO_DDR_REG(P) \
156
(P >= 24 ? &DDRA : (P <= 7 ? &DDRB : ((P >= 8 && P <=15) ? &DDRD : &DDRC)))
157
#define PJON_IO_PIN_TO_PIN_REG(P) \
158
(P >= 24 ? &PINA : (P <= 7 ? &PINB : ((P >= 8 && P <=15) ? &PIND : &PINC)))
159
#ifndef PJON_IO_PIN_TO_BIT
160
#define PJON_IO_PIN_TO_BIT(P) \
161
(P >= 24 ? P-24 : (P <= 7 ? P : ((P >= 8 && P <=15) ? P-8 : P-16 ) ) )
162
#endif
163
#endif
164
165
/* AVR ATtiny44/84/44A/84A ------------------------------------------------ */
166
#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || \
167
defined(__AVR_ATtiny44A__) || defined(__AVR_ATtiny84A__)
168
#define PJON_IO_PIN_TO_PORT_REG(P) \
169
((P <= 7) ? &PORTA : &PORTB )
170
#define PJON_IO_PIN_TO_DDR_REG(P) \
171
((P <= 7) ? &DDRA : &DDRB )
172
#define PJON_IO_PIN_TO_PIN_REG(P) \
173
((P <= 7) ? &PINA : &PINB)
174
#ifndef PJON_IO_PIN_TO_BIT
175
#define PJON_IO_PIN_TO_BIT(P) \
176
((P <= 7) ? P : ((P == 8) ? 2 : ( (P == 9) ? 3 : ( (P == 10) ? 1 : 0))))
177
#endif
178
#endif
179
180
/* SAMD21G18A - Arduino Zero ---------------------------------------------- */
181
182
#if defined(__SAMD21G18A__) || defined(ARDUINO_SAM_ZERO) // Arduino Zero pins
183
#define PJON_IO_PIN_TO_PORT_BIT(P) \
184
((P == 0) ? PORT_PA11 : ((P == 1) ? PORT_PA10 : ((P == 2) ? PORT_PA14 : \
185
((P == 3) ? PORT_PA09 : ((P == 4) ? PORT_PA08 : ((P == 5) ? PORT_PA15 : \
186
((P == 6) ? PORT_PA20 : ((P == 7) ? PORT_PA21 : ((P == 8) ? PORT_PA06 : \
187
((P == 9) ? PORT_PA07 : ((P == 10) ? PORT_PA18 : ((P == 11) ? PORT_PA16 : \
188
((P == 12) ? PORT_PA19 : ((P == 13) ? PORT_PA17 : ((P == A0) ? PORT_PA02 : \
189
((P == A1) ? PORT_PB08 : ((P == A2) ? PORT_PB09 : ((P == A3) ? PORT_PA04 : \
190
((P == A4) ? PORT_PA05 : ((P == A5) ? PORT_PB02 : ((P == SCK) ? PORT_PB11 : \
191
((P == MISO) ? PORT_PA12 : ((P == MOSI) ? PORT_PB10 : ((P == PIN_WIRE_SCL) ? \
192
PORT_PA23 : ((P == PIN_WIRE_SDA) ? PORT_PA22 : PORT_PA13 \
193
)))))))))))))))))))))))))
194
195
#define PJON_IO_PIN_TO_PORT_REG(P) \
196
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? PORTB : PORTA )
197
#define PJON_IO_PIN_TO_PORT_REGOUT(P) \
198
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
199
REG_PORT_OUT1 : REG_PORT_OUT0)
200
#define PJON_IO_PIN_TO_PORT_REGOUTSET(P) \
201
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
202
REG_PORT_OUTSET1 : REG_PORT_OUTSET0)
203
#define PJON_IO_PIN_TO_PORT_REGOUTCLR(P) \
204
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
205
REG_PORT_OUTCLR1 : REG_PORT_OUTCLR0)
206
#define PJON_IO_PIN_TO_PORT_REGPINCFG(P) \
207
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
208
REG_PORT_PINCFG1 : REG_PORT_PINCFG0)
209
#define PJON_IO_PIN_TO_PORT_REGDIRSET(P) \
210
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
211
REG_PORT_DIRSET1 : REG_PORT_DIRSET0)
212
#define PJON_IO_PIN_TO_PORT_REGDIRCLR(P) \
213
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
214
REG_PORT_DIRCLR1 : REG_PORT_DIRCLR0)
215
#define PJON_IO_PIN_TO_PORT_IN_REG(P) \
216
((P >= 15 && P <= 16) || (P == 19) || (P >= 23 && P <= 24) ? \
217
REG_PORT_IN1 : REG_PORT_IN0)
218
219
/* functions for read/write/pinmode fast for SAMD chips
220
PWM pins 3, 4, 5, 6, 8, 9, 10, 11, 12, 13 provide 8-bit PWM output with the
221
analogWrite() function analogWrite works on all analog pins and all digital
222
PWM pins. You can supply it any value between 0 and 255. analog pins provide
223
12bits resolution and provide a value between 0-4096.
224
225
INPUT (0x0),
226
OUTPUT (0x1),
227
INPUT_PULLUP (0x2) Set pin to input mode with pull-up resistor enabled,
228
INPUT_PULLDOWN (0x3) */
229
230
#define PJON_IO_MODE(P, V) \
231
do { if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
232
if(V == 0x0) { \
233
PJON_IO_PIN_TO_PORT_REGPINCFG(P) = (uint8_t)(PORT_PINCFG_INEN); \
234
PJON_IO_PIN_TO_PORT_REGDIRCLR(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
235
} else if(V == 0x2) { \
236
PORT->Group[PJON_IO_PIN_TO_PORT_REG(11)].PINCFG[g_APinDescription[11].ulPin].reg = \
237
(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN); \
238
PJON_IO_PIN_TO_PORT_REGDIRCLR(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
239
PJON_IO_PIN_TO_PORT_REGOUTSET(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
240
} else if(V == 0x3) { \
241
PORT->Group[g_APinDescription[11].ulPort].PINCFG[g_APinDescription[11].ulPin].reg = \
242
(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ; \
243
PJON_IO_PIN_TO_PORT_REGDIRCLR(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
244
PJON_IO_PIN_TO_PORT_REGOUTCLR(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
245
} else { \
246
PJON_IO_PIN_TO_PORT_REGPINCFG(P) &= ~(uint8_t)(PORT_PINCFG_INEN); \
247
PJON_IO_PIN_TO_PORT_REGDIRSET(P) = (uint32_t)PJON_IO_PIN_TO_PORT_BIT(P); \
248
} \
249
} else pinMode(P, V); \
250
} while (0)
251
252
#define PJON_IO_READ(P) ( (int) _PJON_IO_READ_(P) )
253
#define _PJON_IO_READ_(P) \
254
(__builtin_constant_p(P)) ? \
255
(PJON_IO_PIN_TO_PORT_IN_REG(P) & PJON_IO_PIN_TO_PORT_BIT(P)) : digitalRead(P)
256
257
#define PJON_IO_WRITE(P, V) \
258
do { if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
259
if(V) PJON_IO_PIN_TO_PORT_REGOUTSET(P) = PJON_IO_PIN_TO_PORT_BIT(P); \
260
else PJON_IO_PIN_TO_PORT_REGOUTCLR(P) = PJON_IO_PIN_TO_PORT_BIT(P); \
261
} else digitalWrite(P, V); \
262
} while(0)
263
264
#define PJON_IO_PULL_DOWN(P) \
265
do { if(__builtin_constant_p(P)) { \
266
PJON_IO_MODE(P, INPUT_PULLDOWN); \
267
} else pinMode(P, INPUT_PULLDOWN); \
268
} while(0)
269
#endif
270
271
/* AVR related ------------------------------------------------------------ */
272
273
#ifdef __AVR__
274
#define PJON_IO_ATOMIC_WRITE(A, P, V) \
275
if ((int)(A) < 0x40) { bitWrite(*(A), PJON_IO_PIN_TO_BIT(P), V); } \
276
else { \
277
uint8_t register saveSreg = SREG; \
278
cli(); \
279
bitWrite(*(A), PJON_IO_PIN_TO_BIT(P), V); \
280
sei(); \
281
SREG = saveSreg; \
282
}
283
284
#ifndef PJON_IO_WRITE
285
#define PJON_IO_WRITE(P, V) \
286
do { \
287
if(__builtin_constant_p(P) && __builtin_constant_p(V)) \
288
PJON_IO_ATOMIC_WRITE((uint8_t*) PJON_IO_PIN_TO_PORT_REG(P), P, V) \
289
else digitalWrite(P, V); \
290
} while(0)
291
#endif
292
293
#ifndef PJON_IO_MODE
294
#define PJON_IO_MODE(P, V) \
295
do { \
296
if(__builtin_constant_p(P) && __builtin_constant_p(V)) \
297
PJON_IO_ATOMIC_WRITE((uint8_t*) PJON_IO_PIN_TO_DDR_REG(P), P, V) \
298
else pinMode(P, V); \
299
} while(0)
300
#endif
301
302
#ifndef PJON_IO_READ
303
#define PJON_IO_READ(P) ((int) _PJON_IO_READ_(P))
304
#define _PJON_IO_READ_(P) \
305
(__builtin_constant_p(P)) ? ( \
306
((((*PJON_IO_PIN_TO_PIN_REG(P)) >> (PJON_IO_PIN_TO_BIT(P))) & 0x01))) : \
307
digitalRead(P)
308
#endif
309
310
#define PJON_IO_PULL_DOWN(P) \
311
do { if(__builtin_constant_p(P)) { \
312
PJON_IO_WRITE(P, LOW); \
313
PJON_IO_MODE(P, INPUT); \
314
} else { \
315
digitalWrite(P, LOW); \
316
pinMode(P, INPUT); \
317
} \
318
} while(0)
319
#endif
Copyright (C) 2013-2019 Sensnology AB. Generated by
doxygen
1.8.17