0.3.2 FastSHiftIn

This commit is contained in:
rob tillaart 2023-02-20 17:23:35 +01:00
parent f5b52a4ba2
commit d3cb255b01
14 changed files with 317 additions and 64 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:

View File

@ -6,14 +6,24 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.2] - 2023-02-20
- add (experimental) read16(), read24(), read32() functions.
- changed return types of some functions.
- update keywords.txt
- update readme.md
- update GitHub actions
- update license 2023
- minor edits
## [0.3.1] - 2022-11-06
- redo clock pulse
## [0.3.0] - 2022-11-05
- fix inputRegister bug
- refactor for code size
----
## [0.2.4] - 2022-11-05
- add changelog.md
@ -27,10 +37,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.2] - 2020-12-22
----
## No history ...
## [0.1.0 - 2013-09-29
- initial version

View File

@ -1,7 +1,7 @@
//
// FILE: FastShiftIn.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// VERSION: 0.3.2
// PURPOSE: Fast ShiftIn for 74HC165 register, AVR optimized
// DATE: 2013-09-29
// URL: https://github.com/RobTillaart/FastShiftIn
@ -14,8 +14,8 @@
FastShiftIn::FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder)
{
_bitOrder = bitOrder;
_value = 0;
_bitOrder = bitOrder;
_lastValue = 0;
pinMode(dataIn, INPUT);
pinMode(clockPin, OUTPUT);
// https://www.arduino.cc/reference/en/language/functions/advanced-io/shiftin/
@ -41,8 +41,7 @@ FastShiftIn::FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder)
}
int FastShiftIn::read()
uint16_t FastShiftIn::read()
{
if (_bitOrder == LSBFIRST)
{
@ -52,8 +51,65 @@ int FastShiftIn::read()
}
uint16_t FastShiftIn::read16()
{
uint16_t rv;
if (_bitOrder == LSBFIRST)
{
rv = readLSBFIRST();
rv += uint16_t(readLSBFIRST()) << 8;
return rv;
}
rv = readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
return rv;
}
int FastShiftIn::readLSBFIRST()
uint32_t FastShiftIn::read24()
{
uint32_t rv;
if (_bitOrder == LSBFIRST)
{
rv = readLSBFIRST();
rv += uint32_t(readLSBFIRST()) << 8;
rv += uint32_t(readLSBFIRST()) << 16;
return rv;
}
rv = readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
return rv;
}
uint32_t FastShiftIn::read32()
{
uint32_t rv;
if (_bitOrder == LSBFIRST)
{
rv = readLSBFIRST();
rv += uint32_t(readLSBFIRST()) << 8;
rv += uint32_t(readLSBFIRST()) << 16;
rv += uint32_t(readLSBFIRST()) << 24;
return rv;
}
rv = readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
rv <<= 8;
rv += readMSBFIRST();
return rv;
}
uint8_t FastShiftIn::readLSBFIRST()
{
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
@ -74,20 +130,20 @@ int FastShiftIn::readLSBFIRST()
*_clockRegister &= cbmask2;
SREG = oldSREG;
}
_value = rv;
_lastValue = rv;
return rv;
#else
// reference implementation
_value = shiftIn(_dataPinIn, _clockPin, LSBFIRST);
return _value;
// reference implementation
_lastValue = shiftIn(_dataPinIn, _clockPin, LSBFIRST);
return _lastValue;
#endif
}
int FastShiftIn::readMSBFIRST()
uint8_t FastShiftIn::readMSBFIRST()
{
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
@ -108,23 +164,23 @@ int FastShiftIn::readMSBFIRST()
*_clockRegister &= cbmask2;
SREG = oldSREG;
}
_value = rv;
_lastValue = rv;
return rv;
#else
// reference implementation
_value = shiftIn(_dataPinIn, _clockPin, MSBFIRST);
return _value;
// reference implementation
_lastValue = shiftIn(_dataPinIn, _clockPin, MSBFIRST);
return _lastValue;
#endif
}
int FastShiftIn::lastRead(void)
uint32_t FastShiftIn::lastRead(void)
{
return _value;
return _lastValue;
};
@ -145,5 +201,5 @@ uint8_t FastShiftIn::getBitOrder(void)
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
//
// FILE: FastShiftIn.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.1
// VERSION: 0.3.2
// PURPOSE: Fast ShiftIn for 74HC165 register, AVR optimized
// DATE: 2013-09-29
// URL: https://github.com/RobTillaart/FastShiftIn
@ -11,7 +11,7 @@
#include "Arduino.h"
#define FASTSHIFTIN_LIB_VERSION (F("0.3.1"))
#define FASTSHIFTIN_LIB_VERSION (F("0.3.2"))
class FastShiftIn
@ -20,36 +20,40 @@ public:
// bitOrder = { LSBFIRST, MSBFIRST };
FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder = LSBFIRST);
int read(void);
int lastRead(void);
uint16_t read(void);
uint16_t read16(void);
uint32_t read24(void);
uint32_t read32(void);
uint32_t lastRead(void);
bool setBitOrder(uint8_t bitOrder);
uint8_t getBitOrder(void);
// returns false if bitOrder out of range.
bool setBitOrder(uint8_t bitOrder);
uint8_t getBitOrder(void);
// overrule bitOrder (most optimized).
int readLSBFIRST(void);
int readMSBFIRST(void);
uint8_t readLSBFIRST(void);
uint8_t readMSBFIRST(void);
private:
uint8_t _bitOrder;
int _value;
uint8_t _bitOrder;
uint32_t _lastValue;
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
volatile uint8_t *_dataInRegister;
uint8_t _dataInBit;
uint8_t _dataInBit;
volatile uint8_t *_clockRegister;
uint8_t _clockBit;
uint8_t _clockBit;
#else
uint8_t _dataPinIn;
uint8_t _clockPin;
uint8_t _dataPinIn;
uint8_t _clockPin;
#endif
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2013-2022 Rob Tillaart
Copyright (c) 2013-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,4 +1,3 @@
//
// FILE: fastShiftIn_test.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test sketch
@ -9,7 +8,7 @@
FastShiftIn FSI(12, 13);
volatile int x = 0;
volatile uint32_t x = 0;
uint32_t start, duration1, duration2;
@ -20,12 +19,23 @@ void setup()
Serial.println(__FILE__);
Serial.println(FASTSHIFTIN_LIB_VERSION);
FSI.setBitOrder(LSBFIRST);
digitalWrite(12, HIGH);
Serial.println("\n 8 bits HIGH\n");
Serial.println("\nPerformance - time in us : read()");
test_read();
Serial.println("\nPerformance - time in us : read16()");
test_read16();
Serial.println("\nPerformance - time in us : read24()");
test_read24();
Serial.println("\nPerformance - time in us : read32()");
test_read32();
Serial.println("\nPerformance - time in us : readLSBFIRST()");
test_readLSBFIRST();
@ -66,6 +76,87 @@ void test_read()
}
void test_read16()
{
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read16();
}
duration1 = micros() - start;
Serial.print("FastShiftIn1: ");
Serial.println(duration1 * 0.001);
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read16();
x = FSI.read16();
}
duration2 = micros() - start;
Serial.print("FastShiftIn2: ");
Serial.println(duration2 * 0.001);
Serial.print(" Delta: ");
Serial.println((duration2 - duration1) * 0.001);
Serial.println();
delay(100);
}
void test_read24()
{
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read24();
}
duration1 = micros() - start;
Serial.print("FastShiftIn1: ");
Serial.println(duration1 * 0.001);
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read24();
x = FSI.read24();
}
duration2 = micros() - start;
Serial.print("FastShiftIn2: ");
Serial.println(duration2 * 0.001);
Serial.print(" Delta: ");
Serial.println((duration2 - duration1) * 0.001);
Serial.println();
delay(100);
}
void test_read32()
{
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read32();
}
duration1 = micros() - start;
Serial.print("FastShiftIn1: ");
Serial.println(duration1 * 0.001);
start = micros();
for (int i = 0; i < 1000; i++)
{
x = FSI.read32();
x = FSI.read32();
}
duration2 = micros() - start;
Serial.print("FastShiftIn2: ");
Serial.println(duration2 * 0.001);
Serial.print(" Delta: ");
Serial.println((duration2 - duration1) * 0.001);
Serial.println();
delay(100);
}
void test_readLSBFIRST()
{
start = micros();

View File

@ -0,0 +1,49 @@
Arduino UNO
IDE 1.8.19
fastShiftIn_test.ino
0.3.2
8 bits HIGH
Performance - time in us : read()
FastShiftIn1: 21.62
FastShiftIn2: 42.11
Delta: 20.49
Performance - time in us : read16()
FastShiftIn1: 41.70
FastShiftIn2: 82.73
Delta: 41.04
Performance - time in us : read24()
FastShiftIn1: 63.58
FastShiftIn2: 126.49
Delta: 62.91
Performance - time in us : read32()
FastShiftIn1: 83.95
FastShiftIn2: 167.24
Delta: 83.29
Performance - time in us : readLSBFIRST()
FastShiftIn1: 20.68
FastShiftIn2: 40.61
Delta: 19.93
Performance - time in us : readMSBFIRST()
FastShiftIn1: 20.68
FastShiftIn2: 40.60
Delta: 19.92
Performance - time in us : reference shiftIn()
Standard shiftIn1: 108.99
Standard shiftIn2: 217.19
Delta: 108.20

View File

@ -6,9 +6,15 @@ FastShiftIn KEYWORD1
# Methods and Functions (KEYWORD2)
read KEYWORD2
read16 KEYWORD2
read24 KEYWORD2
read32 KEYWORD2
lastRead KEYWORD2
setBitOrder KEYWORD2
getBitOrder KEYWORD2
readLSBFIRST KEYWORD2
readMSBFIRST KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/FastShiftIn.git"
},
"version": "0.3.1",
"version": "0.3.2",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=FastShiftIn
version=0.3.1
version=0.3.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for (AVR) optimized shiftIn - e.g. for 74HC165

View File

@ -27,6 +27,9 @@ in the constructor of the FastShiftIn object.
If not an **ARDUINO_ARCH_AVR** or **ARDUINO_ARCH_MEGAAVR** the class falls back
to the default shiftIn() implementation.
Since 0.3.2 read16(), read24() and read32() are added.
These are experimental and not fully tested yet.
## Performance
@ -35,26 +38,50 @@ The performance of **read()** is substantially faster than the default Arduino
Exact how big the performance gain is can be seen with the example sketch.
It does a comparison and shows how the class is to be used.
test 0.2.3 Arduino UNO
Time in microseconds, Arduino UNO
| function | 0.2.3 | 0.3.2 |
|:---------------------|---------:|---------:|
| read() | 19.30 | 20.49 |
| read16() | | 41.04 |
| read24() | | 62.91 |
| read32() | | 83.95 |
| readLSBFIRST() | 19.04 | 19.92 |
| readMSBFIRST() | 19.04 | 19.92 |
| reference shiftIn() | 107.82 | 108.20 |
0.3.2 is a bit slower (incl. reference) than 0.2.3 but still much
faster than the reference.
| function | time (us) |
|:---------------------|----------:|
| read() | 19.30 |
| readLSBFIRST() | 19.04 |
| readMSBFIRST() | 19.04 |
| reference shiftIn() | 107.82 |
## Interface
The interface exists of the following functions:
```cpp
#include "FastShiftIn.h"
```
- **int read(void)** reads a new value.
- **int lastRead()** returns last value read.
- **bool setBitOrder(uint8_t bitOrder)** set LSBFIRST or MSBFIRST. Returns false for other values.
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST
- **int readLSBFIRST(void)** optimized LSB read().
- **int readMSBFIRST(void)** optimized MSB read().
#### Functions
- **FastShiftIn(uint8_t dataIn, uint8_t clockPin, uint8_t bitOrder = LSBFIRST)** Constructor
- **uint16_t read(void)** reads a new value, 8 bit.
- **uint16_t read16(void)** reads a new value, 16 bit.
- **uint32_t read24(void)** reads a new value, 24 bit.
- **uint32_t read32(void)** reads a new value, 32 bit.
- **uint32_t lastRead()** returns last value read.
- **bool setBitOrder(uint8_t bitOrder)** set LSBFIRST or MSBFIRST.
Returns false for other values.
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST.
- **uint16_t readLSBFIRST(void)** optimized LSB read(), 8 bit.
- **uint16_t readMSBFIRST(void)** optimized MSB read(), 8 bit.
#### Byte order
It might be that **read16/24/32** has bytes not in the right order.
Then you should use multiple calls to **read()** and merge these
bytes in the order you want them.
## Notes
@ -64,15 +91,22 @@ The interface exists of the following functions:
pull up resistors, especially if wires are exceeding 10 cm (4").
## Operation
See examples
## Future
#### Must
#### Should
- extend unit tests
#### Could
- esp32 optimization readLSBFIRST readMSBFIRST
- read8() read16(), read24(), read32()
- **read(uint8_t \* arr, uint8_t nr)** ??
- example schema
- would it be interesting to make a fastShiftIn16() etc?
- squeeze performance but more maintenance.?
#### Wont

View File

@ -40,6 +40,7 @@ unittest_setup()
fprintf(stderr, "FASTSHIFTIN_LIB_VERSION: %s\n", (char *) FASTSHIFTIN_LIB_VERSION);
}
unittest_teardown()
{
}
@ -104,4 +105,6 @@ unittest(test_read)
unittest_main()
// --------
// -- END OF FILE --