Skip to content

Commit 60d5ebd

Browse files
authored
add read(array, size), experimental (#16)
- add **void read(uint8_t \*array, uint8_t size)** (experimental) - update readme.md - reorder functions in .cpp - minor edits
1 parent 912bb85 commit 60d5ebd

File tree

6 files changed

+125
-64
lines changed

6 files changed

+125
-64
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9-
## [0.3.3] - 2023-10-31
9+
## [0.3.4] - 2024-07-22
10+
- add **void read(uint8_t \*array, uint8_t size)** (experimental)
1011
- update readme.md
12+
- reorder functions in .cpp
13+
- minor edits
1114

15+
## [0.3.3] - 2023-10-31
16+
- update readme.md
1217

1318
## [0.3.2] - 2023-02-20
1419
- add (experimental) read16(), read24(), read32() functions.

FastShiftIn.cpp

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
//
22
// FILE: FastShiftIn.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.3.3
4+
// VERSION: 0.3.4
55
// PURPOSE: Fast ShiftIn for 74HC165 register, AVR optimized
66
// DATE: 2013-09-29
77
// URL: https://github.com/RobTillaart/FastShiftIn
8-
//
9-
// HISTORY: see changelog.md
108

119

1210
#include "FastShiftIn.h"
@@ -19,7 +17,7 @@ FastShiftIn::FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder)
1917
pinMode(dataIn, INPUT);
2018
pinMode(clockPin, OUTPUT);
2119
// https://www.arduino.cc/reference/en/language/functions/advanced-io/shiftin/
22-
digitalWrite(clockPin, LOW); // assume rising pulses from clock
20+
digitalWrite(clockPin, LOW); // assume rising pulses from clock
2321

2422
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
2523

@@ -53,14 +51,13 @@ uint16_t FastShiftIn::read()
5351

5452
uint16_t FastShiftIn::read16()
5553
{
56-
uint16_t rv;
5754
if (_bitOrder == LSBFIRST)
5855
{
59-
rv = readLSBFIRST();
56+
uint16_t rv = readLSBFIRST();
6057
rv += uint16_t(readLSBFIRST()) << 8;
6158
return rv;
6259
}
63-
rv = readMSBFIRST();
60+
uint16_t rv = readMSBFIRST();
6461
rv <<= 8;
6562
rv += readMSBFIRST();
6663
return rv;
@@ -69,15 +66,14 @@ uint16_t FastShiftIn::read16()
6966

7067
uint32_t FastShiftIn::read24()
7168
{
72-
uint32_t rv;
7369
if (_bitOrder == LSBFIRST)
7470
{
75-
rv = readLSBFIRST();
71+
uint32_t rv = readLSBFIRST();
7672
rv += uint32_t(readLSBFIRST()) << 8;
7773
rv += uint32_t(readLSBFIRST()) << 16;
7874
return rv;
7975
}
80-
rv = readMSBFIRST();
76+
uint32_t rv = readMSBFIRST();
8177
rv <<= 8;
8278
rv += readMSBFIRST();
8379
rv <<= 8;
@@ -88,16 +84,15 @@ uint32_t FastShiftIn::read24()
8884

8985
uint32_t FastShiftIn::read32()
9086
{
91-
uint32_t rv;
9287
if (_bitOrder == LSBFIRST)
9388
{
94-
rv = readLSBFIRST();
89+
uint32_t rv = readLSBFIRST();
9590
rv += uint32_t(readLSBFIRST()) << 8;
9691
rv += uint32_t(readLSBFIRST()) << 16;
9792
rv += uint32_t(readLSBFIRST()) << 24;
9893
return rv;
9994
}
100-
rv = readMSBFIRST();
95+
uint32_t rv = readMSBFIRST();
10196
rv <<= 8;
10297
rv += readMSBFIRST();
10398
rv <<= 8;
@@ -108,6 +103,46 @@ uint32_t FastShiftIn::read32()
108103
}
109104

110105

106+
uint32_t FastShiftIn::lastRead(void)
107+
{
108+
return _lastValue;
109+
}
110+
111+
112+
void FastShiftIn::read(uint8_t * array, uint8_t size)
113+
{
114+
if (_bitOrder == LSBFIRST)
115+
{
116+
for (uint8_t i = 0; i < size; i++)
117+
{
118+
array[size - i - 1] = readLSBFIRST();
119+
}
120+
return;
121+
}
122+
for (uint8_t i = 0; i < size; i++)
123+
{
124+
array[i] = readMSBFIRST();
125+
}
126+
return;
127+
}
128+
129+
130+
bool FastShiftIn::setBitOrder(const uint8_t bitOrder)
131+
{
132+
if ((bitOrder == LSBFIRST) || (bitOrder == MSBFIRST))
133+
{
134+
_bitOrder = bitOrder;
135+
return true;
136+
};
137+
return false;
138+
}
139+
140+
141+
uint8_t FastShiftIn::getBitOrder(void)
142+
{
143+
return _bitOrder;
144+
}
145+
111146

112147
uint8_t FastShiftIn::readLSBFIRST()
113148
{
@@ -118,16 +153,19 @@ uint8_t FastShiftIn::readLSBFIRST()
118153
uint8_t cbmask2 = ~_clockBit;
119154
uint8_t inmask1 = _dataInBit;
120155

121-
for (uint8_t m = 1; m > 0; m <<= 1)
156+
for (uint8_t m = 0x01; m > 0; m <<= 1)
122157
{
158+
// remember state register
123159
uint8_t oldSREG = SREG;
160+
// disable interrupts
124161
noInterrupts();
125162
// clock pulse HIGH
126163
*_clockRegister |= cbmask1;
127164
// read one bit
128165
if ((*_dataInRegister & inmask1) > 0) rv |= m;
129166
// clock pulse LOW
130167
*_clockRegister &= cbmask2;
168+
// reset interrupts flag to previous state
131169
SREG = oldSREG;
132170
}
133171
_lastValue = rv;
@@ -154,14 +192,17 @@ uint8_t FastShiftIn::readMSBFIRST()
154192

155193
for (uint8_t m = 0x80; m > 0; m >>= 1)
156194
{
195+
// remember state register
157196
uint8_t oldSREG = SREG;
197+
// disable interrupts
158198
noInterrupts();
159199
// clock pulse HIGH
160200
*_clockRegister |= cbmask1;
161201
// read one bit
162202
if ((*_dataInRegister & inmask1) > 0) rv |= m;
163203
// clock pulse LOW
164204
*_clockRegister &= cbmask2;
205+
// reset interrupts flag to previous state
165206
SREG = oldSREG;
166207
}
167208
_lastValue = rv;
@@ -178,28 +219,5 @@ uint8_t FastShiftIn::readMSBFIRST()
178219
}
179220

180221

181-
uint32_t FastShiftIn::lastRead(void)
182-
{
183-
return _lastValue;
184-
};
185-
186-
187-
bool FastShiftIn::setBitOrder(const uint8_t bitOrder)
188-
{
189-
if ((bitOrder == LSBFIRST) || (bitOrder == MSBFIRST))
190-
{
191-
_bitOrder = bitOrder;
192-
return true;
193-
};
194-
return false;
195-
}
196-
197-
198-
uint8_t FastShiftIn::getBitOrder(void)
199-
{
200-
return _bitOrder;
201-
};
202-
203-
204222
// -- END OF FILE --
205223

FastShiftIn.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: FastShiftIn.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.3.3
5+
// VERSION: 0.3.4
66
// PURPOSE: Fast ShiftIn for 74HC165 register, AVR optimized
77
// DATE: 2013-09-29
88
// URL: https://github.com/RobTillaart/FastShiftIn
@@ -11,7 +11,7 @@
1111
#include "Arduino.h"
1212

1313

14-
#define FASTSHIFTIN_LIB_VERSION (F("0.3.3"))
14+
#define FASTSHIFTIN_LIB_VERSION (F("0.3.4"))
1515

1616

1717
class FastShiftIn
@@ -26,6 +26,9 @@ class FastShiftIn
2626
uint32_t read32(void);
2727
uint32_t lastRead(void);
2828

29+
// Experimental 0.3.4
30+
void read(uint8_t * array, uint8_t size);
31+
2932
// returns false if bitOrder out of range.
3033
bool setBitOrder(uint8_t bitOrder);
3134
uint8_t getBitOrder(void);
@@ -37,7 +40,7 @@ class FastShiftIn
3740
private:
3841
uint8_t _bitOrder;
3942
uint32_t _lastValue;
40-
43+
4144
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
4245

4346
volatile uint8_t *_dataInRegister;

README.md

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313

1414
Arduino library for **AVR** optimized shiftIn - e.g. for 74HC165.
1515

16-
Related libraries
17-
- https://github.com/RobTillaart/FastShiftOut
18-
- https://github.com/RobTillaart/FastShiftInOut
19-
- https://github.com/RobTillaart/ShiftInSlow
20-
- https://github.com/RobTillaart/ShiftOutSlow
21-
2216

2317
## Description
2418

@@ -28,17 +22,22 @@ It speeds up the shift using low level ports and masks. These are predetermined
2822
in the constructor of the FastShiftIn object.
2923

3024
If not an **ARDUINO_ARCH_AVR** or **ARDUINO_ARCH_MEGAAVR** the class falls back
31-
to the default shiftIn() implementation.
25+
to the default **shiftIn()** implementation.
26+
27+
The library allows to set (and get) the bitOrder and apply this to multiple read()
28+
calls. It also provide access to **readLSBFIRST()** and **readMSBFIRST()** which
29+
are the low level workers and most optimized code (so far).
3230

33-
Since 0.3.2 read16(), read24() and read32() are added.
34-
These are experimental and not fully tested yet.
31+
The library provides wrapper functions to read multi-byte variables.
32+
These are read16(), read24(), read32() and read(array, size).
33+
The latter is used to shift in any size object.
3534

3635

37-
## Performance
36+
### Performance
3837

39-
The performance of **read()** is substantially faster than the default Arduino
40-
**shiftIn()**, but not as fast as HW SPI.
41-
Exact how big the performance gain is can be seen with the example sketch.
38+
The performance of **read()** is substantially faster for **AVR** than the default
39+
Arduino **shiftIn()**, but not as fast as HW SPI.
40+
Exact how large the performance gain is can be seen with the example sketch.
4241
It does a comparison and shows how the class is to be used.
4342

4443
Time in microseconds, Arduino UNO
@@ -58,33 +57,64 @@ Time in microseconds, Arduino UNO
5857
faster than the reference.
5958

6059

60+
### Related libraries
61+
62+
- https://github.com/RobTillaart/FastShiftIn
63+
- https://github.com/RobTillaart/FastShiftOut
64+
- https://github.com/RobTillaart/FastShiftInOut
65+
- https://github.com/RobTillaart/ShiftInSlow
66+
- https://github.com/RobTillaart/ShiftOutSlow
67+
6168

6269
## Interface
6370

6471
```cpp
6572
#include "FastShiftIn.h"
6673
```
6774

68-
#### Functions
75+
### Constructor
6976

7077
- **FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder = LSBFIRST)** Constructor
78+
79+
### Functions
80+
7181
- **uint16_t read(void)** reads a new value, 8 bit.
7282
- **uint16_t read16(void)** reads a new value, 16 bit.
7383
- **uint32_t read24(void)** reads a new value, 24 bit.
7484
- **uint32_t read32(void)** reads a new value, 32 bit.
7585
- **uint32_t lastRead()** returns last value read.
86+
87+
### Meta
88+
7689
- **bool setBitOrder(uint8_t bitOrder)** set LSBFIRST or MSBFIRST.
7790
Returns false for other values.
7891
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST.
7992
- **uint16_t readLSBFIRST(void)** optimized LSB read(), 8 bit.
8093
- **uint16_t readMSBFIRST(void)** optimized MSB read(), 8 bit.
8194

8295

83-
#### Byte order
96+
### Experimental
97+
98+
- **void read(uint8_t \*array, uint8_t size)** read an array of values.
99+
The order in the array follows as BYTE order MSB / LSB, that is why this function
100+
is made experimental. This might change in the future, and fill the array
101+
in arrival order.
84102

85-
It might be that **read16/24/32** has bytes not in the right order.
86-
Then you should use multiple calls to **read()** and merge these
87-
bytes in the order you want them.
103+
104+
### Byte order
105+
106+
The functions **read16()**, **read24()** and **read32()** of this library assume
107+
that the BIT-order is also the BYTE-order.
108+
This is not always the case as an n-byte element can have n! == factorial(n)
109+
distinct byte orders.
110+
111+
So **read16()** can have two, **read24()** can have six and **read32()** can even have
112+
(in theory) 24 distinct byte orders. Although LSB and MSB are the most common,
113+
other byte orders exist, and sometimes one explicitly wants to reorder the bytes.
114+
115+
If the BIT-order is not the BYTE-order, the user has two options
116+
- call **read()** multiple times and merge the bytes in the order needed.
117+
- call **read32()** (a.o) and reorder the bytes in a separate function.
88118

89119

90120
## Notes
@@ -98,15 +128,20 @@ pull up resistors, especially if wires are exceeding 10 cm (4").
98128

99129
#### Must
100130

131+
101132
#### Should
102133

103134
- extend unit tests
104135

105136
#### Could
106137

107-
- esp32 optimization readLSBFIRST readMSBFIRST
108-
- **read(uint8_t \* arr, uint8_t nr)** ??
109-
- example schema
138+
- investigate separate **BYTE**-order,
139+
- only MSBFirst and LSBFirst
140+
- **void setByteOrder()** + **uint8_t getByteOrder()**
141+
- other option is add parameters / overload to make byte order explicit
142+
- **read32(1,0,3,2)** performance penalty + invalid combination.
143+
- investigate ESP32 optimization readLSBFIRST readMSBFIRST
144+
- example schemas
110145
- would it be interesting to make a fastShiftIn16() etc?
111146
- squeeze performance but more maintenance.?
112147

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"type": "git",
1616
"url": "https://github.com/RobTillaart/FastShiftIn.git"
1717
},
18-
"version": "0.3.3",
18+
"version": "0.3.4",
1919
"license": "MIT",
2020
"frameworks": "*",
2121
"platforms": "*",

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=FastShiftIn
2-
version=0.3.3
2+
version=0.3.4
33
author=Rob Tillaart <[email protected]>
44
maintainer=Rob Tillaart <[email protected]>
55
sentence=Arduino library for (AVR) optimized shiftIn - e.g. for 74HC165

0 commit comments

Comments
 (0)