mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.3.3 FastShiftOut
This commit is contained in:
parent
bfc61cdb0e
commit
da2e9fe077
@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.3.3] - 2024-07-23
|
||||
- Fix #13, add wrapper functions
|
||||
- write16/24/32, write(array, size)
|
||||
- improved timing measurement in FastShiftOut_test.ino
|
||||
- update readme.md
|
||||
- minor edits
|
||||
|
||||
## [0.3.2] - 2023-10-31
|
||||
- update readme.md
|
||||
|
||||
|
||||
## [0.3.1] - 2023-02-20
|
||||
- update readme.md
|
||||
- update GitHub actions
|
||||
|
@ -39,6 +39,7 @@ void test1()
|
||||
duration1 = micros() - start;
|
||||
Serial.print(" write: ");
|
||||
Serial.println(duration1 * 0.001);
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@ -66,6 +67,7 @@ void test2()
|
||||
duration1 = micros() - start;
|
||||
Serial.print("writeLSBFIRST: ");
|
||||
Serial.println(duration1 * 0.001);
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@ -93,6 +95,7 @@ void test3()
|
||||
duration1 = micros() - start;
|
||||
Serial.print("writeMSBFIRST: ");
|
||||
Serial.println(duration1 * 0.001);
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@ -120,6 +123,7 @@ void test4()
|
||||
duration1 = micros() - start;
|
||||
Serial.print("Standard shiftOut1: ");
|
||||
Serial.println(duration1 * 0.001);
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@ -148,6 +152,7 @@ void test5()
|
||||
duration1 = micros() - start;
|
||||
Serial.print("println(\"Hello world\"): \t");
|
||||
Serial.println(duration1 * 0.01);
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
@ -157,7 +162,7 @@ void test5()
|
||||
duration1 = micros() - start;
|
||||
Serial.print("println(1357): \t\t\t");
|
||||
Serial.println(duration1 * 0.01);
|
||||
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
@ -176,4 +181,4 @@ void loop()
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
// -- END OF FILE --
|
||||
|
@ -47,8 +47,70 @@ size_t FastShiftOut::write(uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
/* experimental
|
||||
size_t write(const uint8_t \*buffer, size_t size)
|
||||
// EXPERIMENTAL 0.3.3
|
||||
size_t FastShiftOut::write16(uint16_t data)
|
||||
{
|
||||
if (_bitOrder == LSBFIRST)
|
||||
{
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
writeLSBFIRST(data >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeMSBFIRST(data >> 8);
|
||||
writeMSBFIRST(data & 0xFF);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
// EXPERIMENTAL 0.3.3
|
||||
size_t FastShiftOut::write24(uint32_t data)
|
||||
{
|
||||
if (_bitOrder == LSBFIRST)
|
||||
{
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
data >>= 8;
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
data >>= 8;
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeMSBFIRST((data >> 16) & 0xFF);
|
||||
writeMSBFIRST((data >> 8) & 0xFF);
|
||||
writeMSBFIRST(data & 0xFF);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
// EXPERIMENTAL 0.3.3
|
||||
size_t FastShiftOut::write32(uint32_t data)
|
||||
{
|
||||
if (_bitOrder == LSBFIRST)
|
||||
{
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
data >>= 8;
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
data >>= 8;
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
data >>= 8;
|
||||
writeLSBFIRST(data & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeMSBFIRST((data >> 24) & 0xFF);
|
||||
writeMSBFIRST((data >> 16) & 0xFF);
|
||||
writeMSBFIRST((data >> 8) & 0xFF);
|
||||
writeMSBFIRST(data & 0xFF);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
// EXPERIMENTAL 0.3.3
|
||||
size_t FastShiftOut::write(uint8_t * array, size_t size)
|
||||
{
|
||||
size_t n = 0;
|
||||
if (_bitOrder == LSBFIRST)
|
||||
@ -56,19 +118,42 @@ size_t write(const uint8_t \*buffer, size_t size)
|
||||
for (size_t i = size; i > 0; ) // from end to begin ????
|
||||
{
|
||||
i--;
|
||||
n += writeLSBFIRST(buffer[i]);
|
||||
writeLSBFIRST(array[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < size; i++) // from begin to end..
|
||||
{
|
||||
n += writeMSBFIRST(buffer[i]);
|
||||
writeMSBFIRST(array[i]);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
return size;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
uint8_t FastShiftOut::lastWritten(void)
|
||||
{
|
||||
return _lastValue;
|
||||
}
|
||||
|
||||
|
||||
bool FastShiftOut::setBitOrder(const uint8_t bitOrder)
|
||||
{
|
||||
if ((bitOrder == LSBFIRST) || (bitOrder == MSBFIRST))
|
||||
{
|
||||
_bitOrder = bitOrder;
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t FastShiftOut::getBitOrder(void)
|
||||
{
|
||||
return _bitOrder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t FastShiftOut::writeLSBFIRST(uint8_t data)
|
||||
@ -137,28 +222,5 @@ size_t FastShiftOut::writeMSBFIRST(uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
uint8_t FastShiftOut::lastWritten(void)
|
||||
{
|
||||
return _lastValue;
|
||||
}
|
||||
|
||||
|
||||
bool FastShiftOut::setBitOrder(const uint8_t bitOrder)
|
||||
{
|
||||
if ((bitOrder == LSBFIRST) || (bitOrder == MSBFIRST))
|
||||
{
|
||||
_bitOrder = bitOrder;
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t FastShiftOut::getBitOrder(void)
|
||||
{
|
||||
return _bitOrder;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: FastShiftOut.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.3.2
|
||||
// VERSION: 0.3.3
|
||||
// PURPOSE: shiftOut class that implements the Print interface
|
||||
// DATE: 2013-08-22
|
||||
// URL: https://github.com/RobTillaart/FastShiftOut
|
||||
@ -11,7 +11,7 @@
|
||||
#include "Arduino.h"
|
||||
#include "Print.h"
|
||||
|
||||
#define FASTSHIFTOUT_LIB_VERSION (F("0.3.2"))
|
||||
#define FASTSHIFTOUT_LIB_VERSION (F("0.3.3"))
|
||||
|
||||
|
||||
class FastShiftOut : public Print
|
||||
@ -21,14 +21,19 @@ public:
|
||||
FastShiftOut(uint8_t dataOut, uint8_t clockPin, uint8_t bitOrder = LSBFIRST);
|
||||
|
||||
size_t write(uint8_t data);
|
||||
// experimental
|
||||
// size_t write(const uint8_t \*buffer, size_t size);
|
||||
uint8_t lastWritten(void);
|
||||
|
||||
// EXPERIMENTAL (wrappers)
|
||||
size_t write16(uint16_t data);
|
||||
size_t write24(uint32_t data);
|
||||
size_t write32(uint32_t data);
|
||||
size_t write(uint8_t * array, size_t size);
|
||||
|
||||
// META
|
||||
bool setBitOrder(uint8_t bitOrder);
|
||||
uint8_t getBitOrder(void);
|
||||
|
||||
// overrule bitOrder (most optimized).
|
||||
// overrule bitOrder, most optimized.
|
||||
size_t writeLSBFIRST(uint8_t data);
|
||||
size_t writeMSBFIRST(uint8_t data);
|
||||
|
||||
|
@ -13,16 +13,10 @@
|
||||
|
||||
Arduino library for **AVR** optimized shiftOut - e.g. 74HC595.
|
||||
|
||||
Related libraries
|
||||
- https://github.com/RobTillaart/FastShiftIn
|
||||
- https://github.com/RobTillaart/FastShiftInOut
|
||||
- https://github.com/RobTillaart/ShiftInSlow
|
||||
- https://github.com/RobTillaart/ShiftOutSlow
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
FastShiftOut is a class that has optimized code for AVR to shift out data faster
|
||||
FastShiftOut is a class that has optimized code (AVR only) to shift out data faster
|
||||
than the normal **shiftOut()** function.
|
||||
It speeds up the shift using low level ports and masks. These are predetermined
|
||||
in the constructor of the FastShiftOut object.
|
||||
@ -30,25 +24,45 @@ in the constructor of the FastShiftOut object.
|
||||
If not an **ARDUINO_ARCH_AVR** or **ARDUINO_ARCH_MEGAAVR** the class falls back
|
||||
to the default shiftOut() implementation.
|
||||
|
||||
The library allows to set (and get) the bitOrder and apply this to multiple write()
|
||||
calls. It also provide access to **writeLSBFIRST()** and **writeMSBFIRST()** which
|
||||
are the low level workers and most optimized code (so far).
|
||||
|
||||
## Performance
|
||||
The library provides wrapper functions to write multi-byte variables.
|
||||
These are write16(), write24(), write32() and write(array, size).
|
||||
The latter is used to shift out any size object.
|
||||
|
||||
The performance of **write()** is substantially faster than the default Arduino
|
||||
**shiftOut()**, but not as fast as HW SPI.
|
||||
Exact how big the performance gain is can be seen with the example sketch.
|
||||
|
||||
### Performance
|
||||
|
||||
The performance of **write()** is substantially faster for **AVR** than the default
|
||||
Arduino **shiftOut()**, but not as fast as HW SPI.
|
||||
Exact how large the performance gain is can be seen with the example sketch.
|
||||
It does a comparison and shows how the class is to be used.
|
||||
|
||||
Time in microseconds, Arduino UNO
|
||||
|
||||
| function | 0.2.4 | 0.3.1 |
|
||||
|:-------------------------|--------:|---------:|
|
||||
| write() | 21.66 | 22.48 |
|
||||
| writeLSBFIRST() | 22.94 | 23.37 |
|
||||
| writeMSBFIRST() | 20.30 | 21.86 |
|
||||
| reference shiftOut() | 89.74 | 89.74 |
|
||||
| println("Hello world") | | 328.92 |
|
||||
| println(1357) | | 313.56 |
|
||||
| println(3.14159265, 4) | | 717.36 |
|
||||
| function | 0.2.4 | 0.3.1 | 0.3.3 |
|
||||
|:-------------------------|--------:|---------:|---------:|
|
||||
| write() | 21.66 | 22.48 | 22.37 |
|
||||
| writeLSBFIRST() | 22.94 | 23.37 | 23.26 |
|
||||
| writeMSBFIRST() | 20.30 | 21.86 | 21.75 |
|
||||
| reference shiftOut() | 89.74 | 89.74 | 89.60 |
|
||||
| println("Hello world") | | 328.92 | 328.92 |
|
||||
| println(1357) | | 313.56 | 311.68 |
|
||||
| println(3.14159265, 4) | | 717.36 | 716.04 |
|
||||
|
||||
|
||||
Note: 0.3.3 has improved the measurement, not the code sec.
|
||||
|
||||
|
||||
### Related
|
||||
|
||||
- https://github.com/RobTillaart/FastShiftIn
|
||||
- https://github.com/RobTillaart/FastShiftInOut
|
||||
- https://github.com/RobTillaart/FastShiftOut
|
||||
- https://github.com/RobTillaart/ShiftInSlow
|
||||
- https://github.com/RobTillaart/ShiftOutSlow
|
||||
|
||||
|
||||
## Interface
|
||||
@ -57,27 +71,53 @@ Time in microseconds, Arduino UNO
|
||||
#include "FastShiftOut.h"
|
||||
```
|
||||
|
||||
#### Functions
|
||||
### Constructor
|
||||
|
||||
- **FastShiftOut(uint8_t dataOut, uint8_t clockPin, uint8_t bitOrder = LSBFIRST)** Constructor.
|
||||
- **size_t write(const uint8_t data)** send a byte, also the workhorse of the **Print** interface.
|
||||
|
||||
### Functions
|
||||
|
||||
- **size_t write(uint8_t data)** send a byte, also the workhorse of the **Print** interface.
|
||||
- **size_t write16(uint16_t data)** send 2 bytes.
|
||||
- **size_t write24(uint32_t data)** send 3 bytes.
|
||||
- **size_t write32(uint32_t data)** send 4 bytes.
|
||||
- **size_t write(uint8_t \*array, size_t size)** send size bytes.
|
||||
- **uint8_t lastWritten()** returns last byte written.
|
||||
|
||||
### Meta
|
||||
|
||||
- **bool setBitOrder(uint8_t bitOrder)** set LSBFIRST or MSBFIRST. Returns false for other values.
|
||||
- **uint8_t getBitOrder(void)** returns LSBFIRST or MSBFIRST.
|
||||
- **size_t writeLSBFIRST(const uint8_t data);** most optimized.
|
||||
- **size_t writeMSBFIRST(const uint8_t data);** most optimized.
|
||||
- **size_t writeLSBFIRST(uint8_t data)** most optimized.
|
||||
- **size_t writeMSBFIRST(uint8_t data)** most optimized.
|
||||
|
||||
|
||||
As a FastShiftOut object implements the Print interface, one can also call
|
||||
|
||||
- **FSO.print(any type);** or
|
||||
- **FSO.println(any type);**
|
||||
- **FSO.print(any type)** or
|
||||
- **FSO.println(any type)**
|
||||
|
||||
to send e.g. a float with 4 digits over the line, or some text string.
|
||||
|
||||
Note: **FSO.print()** returns the number of characters printed, including an optional \\r or \\n.
|
||||
|
||||
|
||||
### Byte order
|
||||
|
||||
The functions **write16()**, **write24()** and **write32()** of this library assume
|
||||
that the BIT-order is also the BYTE-order.
|
||||
This is not always the case as an n-byte element can have n! == factorial(n)
|
||||
distinct byte orders.
|
||||
|
||||
So **write16()** can have two, **write24()** can have six and **write32()** can even have
|
||||
(in theory) 24 distinct byte orders. Although LSB and MSB are the most common,
|
||||
other byte orders exist, and sometimes one explicitly wants to reorder the bytes.
|
||||
|
||||
If the BIT-order is not the BYTE-order, the user has two options
|
||||
- call **write()** multiple times and merge the bytes in the order needed.
|
||||
- call **write32()** (a.o) and reorder the bytes in a separate function.
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
- The optimizations are AVR only for now, other platforms may follow.
|
||||
@ -90,15 +130,19 @@ pull up resistors, especially if wires are exceeding 10 cm (4").
|
||||
|
||||
#### Must
|
||||
|
||||
- keep in sync with FastShiftIn()
|
||||
|
||||
#### Should
|
||||
|
||||
- extend unit tests
|
||||
|
||||
#### Could
|
||||
|
||||
- investigate separate **BYTE**-order,
|
||||
- only MSBFirst and LSBFirst
|
||||
- **void setByteOrder()** + **uint8_t getByteOrder()**
|
||||
- investigate ESP32 optimization readLSBFIRST readMSBFIRST
|
||||
- performance ESP32
|
||||
- check optimized ESP32
|
||||
- add **size_t write(const uint8_t \*buffer, size_t size)**
|
||||
- example schema
|
||||
|
||||
#### Wont
|
||||
|
@ -6,6 +6,9 @@ FastShiftOut KEYWORD1
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
write KEYWORD2
|
||||
write16 KEYWORD2
|
||||
write24 KEYWORD2
|
||||
write32 KEYWORD2
|
||||
|
||||
lastWritten KEYWORD2
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/FastShiftOut.git"
|
||||
},
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=FastShiftOut
|
||||
version=0.3.2
|
||||
version=0.3.3
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for (AVR) optimized shiftOut - e.g. 74HC595
|
||||
|
Loading…
Reference in New Issue
Block a user