1
1
//
2
2
// FILE: FastShiftInOut.cpp
3
3
// AUTHOR: Rob Tillaart
4
- // VERSION: 0.2.0
4
+ // VERSION: 0.2.1
5
5
// PURPOSE: Arduino library for (AVR) optimized shiftInOut (simultaneously)
6
6
// URL: https://github.com/RobTillaart/FastShiftInOut
7
7
@@ -109,8 +109,12 @@ uint8_t FastShiftInOut::writeLSBFIRST(uint8_t data)
109
109
uint8_t oldSREG = SREG;
110
110
noInterrupts ();
111
111
112
- if ((value & 0x01 ) == 0 ) *localDataOutRegister &= outmask2;
113
- else *localDataOutRegister |= outmask1;
112
+ // See discussion #17 FastShiftOut
113
+ uint8_t d0 = *localDataOutRegister & outmask2; // cache 0
114
+ uint8_t d1 = d0 | outmask1; // cache 1
115
+
116
+ if ((value & 0x01 ) == 0 ) *localDataOutRegister = d0;
117
+ else *localDataOutRegister = d1;
114
118
// *localClockRegister |= cbmask1;
115
119
// if ((*localDataInRegister & inmask1) > 0) rv |= 0x01;
116
120
// *localClockRegister &= cbmask2; // ~_clockBit;
@@ -121,50 +125,50 @@ uint8_t FastShiftInOut::writeLSBFIRST(uint8_t data)
121
125
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x01 ;
122
126
*localClockRegister = r; // reset it
123
127
124
- if ((value & 0x02 ) == 0 ) *localDataOutRegister &= outmask2 ;
125
- else *localDataOutRegister |= outmask1 ;
128
+ if ((value & 0x02 ) == 0 ) *localDataOutRegister = d0 ;
129
+ else *localDataOutRegister = d1 ;
126
130
r = *localClockRegister;
127
131
*localClockRegister = r | cbmask1; // set one bit
128
132
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x02 ;
129
133
*localClockRegister = r; // reset it
130
134
131
- if ((value & 0x04 ) == 0 ) *localDataOutRegister &= outmask2 ;
132
- else *localDataOutRegister |= outmask1 ;
135
+ if ((value & 0x04 ) == 0 ) *localDataOutRegister = d0 ;
136
+ else *localDataOutRegister = d1 ;
133
137
r = *localClockRegister;
134
138
*localClockRegister = r | cbmask1; // set one bit
135
139
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x04 ;
136
140
*localClockRegister = r; // reset it
137
141
138
- if ((value & 0x08 ) == 0 ) *localDataOutRegister &= outmask2 ;
139
- else *localDataOutRegister |= outmask1 ;
142
+ if ((value & 0x08 ) == 0 ) *localDataOutRegister = d0 ;
143
+ else *localDataOutRegister = d1 ;
140
144
r = *localClockRegister;
141
145
*localClockRegister = r | cbmask1; // set one bit
142
146
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x08 ;
143
147
*localClockRegister = r; // reset it
144
148
145
- if ((value & 0x10 ) == 0 ) *localDataOutRegister &= outmask2 ;
146
- else *localDataOutRegister |= outmask1 ;
149
+ if ((value & 0x10 ) == 0 ) *localDataOutRegister = d0 ;
150
+ else *localDataOutRegister = d1 ;
147
151
r = *localClockRegister;
148
152
*localClockRegister = r | cbmask1; // set one bit
149
153
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x10 ;
150
154
*localClockRegister = r; // reset it
151
155
152
- if ((value & 0x20 ) == 0 ) *localDataOutRegister &= outmask2 ;
153
- else *localDataOutRegister |= outmask1 ;
156
+ if ((value & 0x20 ) == 0 ) *localDataOutRegister = d0 ;
157
+ else *localDataOutRegister = d1 ;
154
158
r = *localClockRegister;
155
159
*localClockRegister = r | cbmask1; // set one bit
156
160
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x20 ;
157
161
*localClockRegister = r; // reset it
158
162
159
- if ((value & 0x40 ) == 0 ) *localDataOutRegister &= outmask2 ;
160
- else *localDataOutRegister |= outmask1 ;
163
+ if ((value & 0x40 ) == 0 ) *localDataOutRegister = d0 ;
164
+ else *localDataOutRegister = d1 ;
161
165
r = *localClockRegister;
162
166
*localClockRegister = r | cbmask1; // set one bit
163
167
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x40 ;
164
168
*localClockRegister = r; // reset it
165
169
166
- if ((value & 0x80 ) == 0 ) *localDataOutRegister &= outmask2 ;
167
- else *localDataOutRegister |= outmask1 ;
170
+ if ((value & 0x80 ) == 0 ) *localDataOutRegister = d0 ;
171
+ else *localDataOutRegister = d1 ;
168
172
r = *localClockRegister;
169
173
*localClockRegister = r | cbmask1; // set one bit
170
174
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x80 ;
@@ -185,16 +189,19 @@ uint8_t FastShiftInOut::writeLSBFIRST(uint8_t data)
185
189
186
190
uint8_t oldSREG = SREG;
187
191
noInterrupts ();
188
-
189
- uint8_t r = *localClockRegister;
190
-
192
+
193
+ uint8_t d0 = *localDataOutRegister & outmask2; // cache 0
194
+ uint8_t d1 = d0 | outmask1; // cache 1
195
+
191
196
for (uint8_t m = 1 ; m > 0 ; m <<= 1 )
192
197
{
193
198
// write one bit
194
- if ((value & m) == 0 ) *localDataOutRegister &= outmask2;
195
- else *localDataOutRegister |= outmask1;
199
+ if ((value & m) == 0 ) *localDataOutRegister = d0;
200
+ else *localDataOutRegister = d1;
201
+ uint8_t r = *localClockRegister;
202
+
196
203
// clock pulse HIGH
197
- *localClockRegister |= cbmask1;
204
+ *localClockRegister = r | cbmask1;
198
205
// read one bit
199
206
if ((*localDataInRegister & inmask1) > 0 ) rv |= m;
200
207
// clock pulse LOW
@@ -249,8 +256,12 @@ uint8_t FastShiftInOut::writeMSBFIRST(uint8_t data)
249
256
uint8_t oldSREG = SREG;
250
257
noInterrupts ();
251
258
252
- if ((value & 0x80 ) == 0 ) *localDataOutRegister &= outmask2;
253
- else *localDataOutRegister |= outmask1;
259
+ // See discussion #17 FastShiftOut
260
+ uint8_t d0 = *localDataOutRegister & outmask2; // cache 0
261
+ uint8_t d1 = d0 | outmask1; // cache 1
262
+
263
+ if ((value & 0x80 ) == 0 ) *localDataOutRegister = d0;
264
+ else *localDataOutRegister = d1;
254
265
// *localClockRegister |= cbmask1;
255
266
// if ((*localDataInRegister & inmask1) > 0) rv |= 0x80;
256
267
// *localClockRegister &= cbmask2; // ~_clockBit;
@@ -261,50 +272,50 @@ uint8_t FastShiftInOut::writeMSBFIRST(uint8_t data)
261
272
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x80 ;
262
273
*localClockRegister = r; // reset it
263
274
264
- if ((value & 0x40 ) == 0 ) *localDataOutRegister &= outmask2 ;
265
- else *localDataOutRegister |= outmask1 ;
275
+ if ((value & 0x40 ) == 0 ) *localDataOutRegister = d0 ;
276
+ else *localDataOutRegister = d1 ;
266
277
r = *localClockRegister;
267
278
*localClockRegister = r | cbmask1; // set one bit
268
279
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x40 ;
269
280
*localClockRegister = r; // reset it
270
281
271
- if ((value & 0x20 ) == 0 ) *localDataOutRegister &= outmask2 ;
272
- else *localDataOutRegister |= outmask1 ;
282
+ if ((value & 0x20 ) == 0 ) *localDataOutRegister = d0 ;
283
+ else *localDataOutRegister = d1 ;
273
284
r = *localClockRegister;
274
285
*localClockRegister = r | cbmask1; // set one bit
275
286
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x20 ;
276
287
*localClockRegister = r; // reset it
277
288
278
- if ((value & 0x10 ) == 0 ) *localDataOutRegister &= outmask2 ;
279
- else *localDataOutRegister |= outmask1 ;
289
+ if ((value & 0x10 ) == 0 ) *localDataOutRegister = d0 ;
290
+ else *localDataOutRegister = d1 ;
280
291
r = *localClockRegister;
281
292
*localClockRegister = r | cbmask1; // set one bit
282
293
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x10 ;
283
294
*localClockRegister = r; // reset it
284
295
285
- if ((value & 0x08 ) == 0 ) *localDataOutRegister &= outmask2 ;
286
- else *localDataOutRegister |= outmask1 ;
296
+ if ((value & 0x08 ) == 0 ) *localDataOutRegister = d0 ;
297
+ else *localDataOutRegister = d1 ;
287
298
r = *localClockRegister;
288
299
*localClockRegister = r | cbmask1; // set one bit
289
300
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x08 ;
290
301
*localClockRegister = r; // reset it
291
302
292
- if ((value & 0x04 ) == 0 ) *localDataOutRegister &= outmask2 ;
293
- else *localDataOutRegister |= outmask1 ;
303
+ if ((value & 0x04 ) == 0 ) *localDataOutRegister = d0 ;
304
+ else *localDataOutRegister = d1 ;
294
305
r = *localClockRegister;
295
306
*localClockRegister = r | cbmask1; // set one bit
296
307
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x04 ;
297
308
*localClockRegister = r; // reset it
298
309
299
- if ((value & 0x02 ) == 0 ) *localDataOutRegister &= outmask2 ;
300
- else *localDataOutRegister |= outmask1 ;
310
+ if ((value & 0x02 ) == 0 ) *localDataOutRegister = d0 ;
311
+ else *localDataOutRegister = d1 ;
301
312
r = *localClockRegister;
302
313
*localClockRegister = r | cbmask1; // set one bit
303
314
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x02 ;
304
315
*localClockRegister = r; // reset it
305
316
306
- if ((value & 0x01 ) == 0 ) *localDataOutRegister &= outmask2 ;
307
- else *localDataOutRegister |= outmask1 ;
317
+ if ((value & 0x01 ) == 0 ) *localDataOutRegister = d0 ;
318
+ else *localDataOutRegister = d1 ;
308
319
r = *localClockRegister;
309
320
*localClockRegister = r | cbmask1; // set one bit
310
321
if ((*localDataInRegister & inmask1) > 0 ) rv |= 0x01 ;
@@ -326,14 +337,18 @@ uint8_t FastShiftInOut::writeMSBFIRST(uint8_t data)
326
337
uint8_t oldSREG = SREG;
327
338
noInterrupts ();
328
339
329
- uint8_t r = *localClockRegister;
340
+ // See discussion #17 FastShiftOut
341
+ uint8_t d0 = *localDataOutRegister & outmask2; // cache 0
342
+ uint8_t d1 = d0 | outmask1; // cache 1
343
+
330
344
for (uint8_t m = 0x80 ; m > 0 ; m >>= 1 )
331
345
{
332
346
// write one bit
333
- if ((value & m) == 0 ) *localDataOutRegister &= outmask2;
334
- else *localDataOutRegister |= outmask1;
347
+ if ((value & m) == 0 ) *localDataOutRegister = d0;
348
+ else *localDataOutRegister = d1;
349
+ uint8_t r = *localClockRegister;
335
350
// clock pulse HIGH
336
- *localClockRegister |= cbmask1;
351
+ *localClockRegister = r | cbmask1;
337
352
// read one bit
338
353
if ((*localDataInRegister & inmask1) > 0 ) rv |= m;
339
354
// clock pulse LOW
0 commit comments