Skip to content

Arduino library for (AVR) optimized shiftInOut (simultaneously)

License

Notifications You must be signed in to change notification settings

RobTillaart/FastShiftInOut

Repository files navigation

Arduino CI Arduino-lint JSON check GitHub issues

License: MIT GitHub release PlatformIO Registry

FastShiftInOut

Arduino library for AVR optimized shiftInOut (simultaneously).

Description

Experimental

FastShiftInOut is a class that has optimized code (AVR only) to send and receive bytes simultaneously. In that sense it mimics a SPI bus. It speeds up the shift using low level ports and masks. These are predetermined in the constructor of the FastShiftOut object.

If not an ARDUINO_ARCH_AVR or ARDUINO_ARCH_MEGAAVR the class falls back to a default non optimized 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).

Note: the bitOrder of the byte read and the byte written are the same.

0.2.0 breaking changes

The 0.2.0 version has a flag to unroll the inner loop in writeLSBFIRST() and writeMSBFIRST(). The unrolled loop blocks the interrupts per byte.

Note: this optimization is new and thus experimental. Feedback, including improvements, is welcome.

Performance

Measurements (pre 0.2.0)

Performance of write()

version UNO (us) ESP32 (us)
0.1.0 181.08 4.32
0.1.1 26.84 4.32
0.1.2 26.84 no data
0.1.3 25.52 4.32

Measurements

(0.2.0)
Indicative time in microseconds, Arduino UNO, IDE 1.8.19, measured over 1000 calls.
(delta between 2 calls and 1 call to eliminate overhead)

function 0.1.3 0.2.0 0.2.0L
write() (reference) no data 158.24 no data
write() 25.52 17.61 12.26
writeLSBFIRST() 25.52 17.61 12.26
writeMSBFIRST() 25.52 17.60 12.20
  • Note: 0.1.3 added from old table.
  • Note: reference run on AVR by commenting all optimizations.
  • Note: 0.2.0 measured with loop unroll flag disabled.
  • Note: 0.2.0L measured with loop unrolled flag enabled.

Related

Interface

#include "FastShiftInOut.h"

Functions

bitOrder = { LSBFIRST, MSBFIRST };

  • FastShiftInOut(uint8_t dataIn, uint8_t dataOut, uint8_t clockPin, uint8_t bitOrder = LSBFIRST) Constructor.
  • uint8_t write(uint8_t data) reads and writes simultaneously.
  • uint8_t lastWritten(void) returns last byte written.
  • uint8_t lastRead(void) returns last byte read.
  • uint8_t writeLSBFIRST(uint8_t data) lowest level function, optimized for LSB.
  • uint8_t writeMSBFIRST(uint8_t data) lowest level function, optimized for MSB.

BitOrder

  • bool setBitOrder(uint8_t bitOrder) bitOrder must be LSBFIRST or MSBFIRST.
  • uint8_t getBitOrder(void) idem.

Future

Must

  • Update documentation
  • Follow FastShiftIn and FastShiftOut

Should

Could

Wont

  • void ignoreRead() => would in effect be FastShiftIn()
  • add Print interface?
    • meaning of the return value is not defined.

Support

If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.

Thank you,

About

Arduino library for (AVR) optimized shiftInOut (simultaneously)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages