159 lines
5.4 KiB
Markdown
Raw Normal View History

2021-01-29 12:31:58 +01:00
[![Arduino CI](https://github.com/RobTillaart/bitHelpers/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
2021-10-19 16:59:51 +02:00
[![Arduino-lint](https://github.com/RobTillaart/bitHelpers/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/bitHelpers/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/bitHelpers/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/bitHelpers/actions/workflows/jsoncheck.yml)
2021-01-29 12:31:58 +01:00
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/bitHelpers/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/bitHelpers.svg?maxAge=3600)](https://github.com/RobTillaart/bitHelpers/releases)
# bitHelpers
2021-12-14 11:51:15 +01:00
Arduino library with functions on bit level.
2021-01-29 12:31:58 +01:00
2021-10-19 16:59:51 +02:00
2021-01-29 12:31:58 +01:00
## Description
2021-08-09 21:39:09 +02:00
This library contains functions to manipulate bits and bit patterns in an
2021-01-29 12:31:58 +01:00
efficient way.
For most functions a 8 - 64 bit optimized version exist.
The library is tested on ESP32 and Arduino UNO but not for all possible values.
other platforms are expected to work without modification.
2021-12-14 11:51:15 +01:00
If they don't please file an issue on GitHub.
2021-01-29 12:31:58 +01:00
2021-12-14 11:51:15 +01:00
New bit functions can be added or investigated, please file an issue on GitHub.
2021-01-29 12:31:58 +01:00
## Interface
2021-08-10 22:16:36 +02:00
2021-01-29 12:31:58 +01:00
### 0.1.0
2021-08-10 22:16:36 +02:00
2021-01-29 12:31:58 +01:00
BitCount, several implementations to compare performance.
2021-12-14 11:51:15 +01:00
- **uint8_t bitCountReference(uint32_t value)** returns number of bits set in a value.
- **uint8_t bitCountKR(uint32_t value)** Kerningham Ritchie bitCount.
- **uint8_t bitCountArray(uint32_t value)** count per nybble with lookup table.
- **uint8_t bitCountF1(uint32_t value)** SWAG algorithm variant.
- **uint8_t bitCountF2(uint32_t value)** SWAG algorithm variant.
2021-01-29 12:31:58 +01:00
2021-08-09 21:39:09 +02:00
BitCount - fastest version, SWAG algorithm
2021-12-14 11:51:15 +01:00
- **uint8_t bitCount(uint8_t value)** available for 16, 32 and 64 bit.
2021-01-29 12:31:58 +01:00
Reverse: uint8_t .. uint64_t
2021-12-14 11:51:15 +01:00
- **T bitReverse(T value)** reverses bits in a uint8_t .. uint64_t.
- **T nybbleReverse(T value)** reverses nibbles (4 bit) in a uint8_t .. uint64_t.
- **T byteReverse(T value)** reverses bytes (8 bit) in a uint16_t .. uint64_t.
- **T wordReverse(T value)** reverses words (16 bit) in uint32_t and uint64_t.
Swap upper and lower half: uint8_t .. uint64_t.
- **T swap(T value)** 0x12345678 ==> 0x56781234.
2021-01-29 12:31:58 +01:00
Rotate Left / Right: uint8_t .. uint64_t
2021-08-09 21:39:09 +02:00
if pos larger than # bits original value is returned.
2021-12-14 11:51:15 +01:00
2021-08-09 21:39:09 +02:00
- **T bitRotateLeft(T value, uint8_t pos)**
- **T bitRotateRight(T value, uint8_t pos)**
2021-01-29 12:31:58 +01:00
BitFlip: uint8_t .. uint64_t a.k.a toggle
2021-08-09 21:39:09 +02:00
if pos larger than # bits original value is returned.
2021-12-14 11:51:15 +01:00
2021-08-09 21:39:09 +02:00
- **T bitFlip(T value, uint8_t pos)** flips a single bit at pos
2021-01-29 12:31:58 +01:00
BitRot: uint8_t .. uint64_t
2021-12-14 11:51:15 +01:00
2021-08-09 21:39:09 +02:00
- **T bitRot(T value, float chance = 0.5)** random damage to a single bit of a value,
chance = float 0.0 .. 1.0 that one random bit is toggled.
2021-01-29 12:31:58 +01:00
**bitRot()** is a function that can be used to mimic single bit errors in communication protocols.
*Note: a chance of 50% for 2 uint8_t is not equal to 50% chance for 1 uint16_t.*
2021-08-10 22:16:36 +02:00
2021-01-29 12:31:58 +01:00
### 0.1.1 added
How many bits are needed to store / transmit a number?
2021-12-14 11:51:15 +01:00
- **bitsNeededReference(n)** reference implementation for uint8_t to uint64_t.
2021-01-29 12:31:58 +01:00
- **bitsNeeded(n)** A 'recursive strategy' for uint8_t .. uint64_t provides a fast answer.
2021-12-14 11:51:15 +01:00
The following functions are made as the normal **bitset()** etcetera do not work for 64 bit.
2021-01-29 12:31:58 +01:00
These functions are optimized for speed for **AVR**, **ESP32** and **ESP8266**.
2021-12-14 11:51:15 +01:00
- **void bitSet64(uint64_t & x, uint8_t bit)** set bit of uint64_t
- **void bitClear64(uint64_t & x, uint8_t bit)** clear bit of uint64_t
- **void bitToggle64(uint64_t & x, uint8_t bit)** toggle bit of uint64_t
- **void bitWrite64(uint64_t & x, uint8_t bit, uint8_t value)** set bit of uint64_t to 0 or 1
- **void bitRead64(uint64_t & x, uint8_t bit)** reads bit from uint64_t
2021-01-29 12:31:58 +01:00
Also added are macro versions of these five functions.
2021-12-14 11:51:15 +01:00
2021-01-29 12:31:58 +01:00
- **mbitSet64(x, bit)** set bit of uint64_t
- **mbitClear64(x, bit)** clear bit of uint64_t
- **mbitToggle64(x, bit)** toggle bit of uint64_t
- **mbitWrite64(x, bit, value)** set bit of uint64_t to 0 or 1
- **mbitRead64(x, bit)** reads bit from uint64_t
2021-08-10 22:16:36 +02:00
2021-01-29 12:31:58 +01:00
### 0.1.2 added
2021-08-09 21:39:09 +02:00
Added Arduino-CI and unit tests
### 0.1.3 added
- update readme.md
- update unit tests
2021-01-29 12:31:58 +01:00
2021-10-19 16:59:51 +02:00
### 0.1.4
- update build-CI (e.g. ESP32 compilation of tests)
- update readme.md with badges
2021-12-14 11:51:15 +01:00
### 0.1.5
- update library.json, minor edits
2021-08-10 22:16:36 +02:00
## BitReverse n bit number
Trick to reverse a number of n bits ( 0 < n < 32 ).
2021-12-14 11:51:15 +01:00
Could also be done similar with 64 bit and or byte / nibble reverse.
2021-08-10 22:16:36 +02:00
not as fast as a dedicated version.
```cpp
uint32_t bitReverse(uint32_t x, uint8_t n)
{
uint32_t r = bitReverse(x);
return r >> (32 - n);
}
```
Could be added in next release...
2021-01-29 12:31:58 +01:00
## Future
2021-12-14 11:51:15 +01:00
- improve documentation
- improve readability of code (val => value and pos => position)
2021-01-29 12:31:58 +01:00
- besides **bitRot()** one can also have timing issues when clocking in bits.
A function could be created to mimic such timing error, by shifting bits from a
specific position. e.g.
- parShiftLeft(00001010, 4) ==> 00011010
- bitBurst(00000000, 3) ==> 00111000 any group of 3 bits will toggle.
2021-10-19 16:59:51 +02:00
- bitRot(value, chance = 50%, times = 1) extension...
2021-01-29 12:31:58 +01:00
- bitNoggle(value, bit) - toggle all but one bit. (why?)
- bitSort(value) ==> 00101001 ==> 00000111
- many more :)
2021-08-10 22:16:36 +02:00
- add **bitReverse(uint32_t x, uint8_t n)**
- add **byteReverse24(uint32_t x)** dedicated 24 bit = 3 bytes e.g RGB
- add **byteInverse(uint32_t x)** (a,b,c,d) => (255-a, 255-b, 255-c, 255-d)
2021-10-19 16:59:51 +02:00
- performance tests
2021-01-29 12:31:58 +01:00
2021-12-14 11:51:15 +01:00
2021-01-29 12:31:58 +01:00
## Operations
See examples.