GY-63_MS5611/libraries/bitHelpers/README.md

189 lines
6.3 KiB
Markdown
Raw Normal View History

2021-01-29 06:31:58 -05:00
[![Arduino CI](https://github.com/RobTillaart/bitHelpers/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
2021-10-19 10:59:51 -04: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 06:31:58 -05: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 05:51:15 -05:00
Arduino library with functions on bit level.
2021-01-29 06:31:58 -05:00
2021-10-19 10:59:51 -04:00
2021-01-29 06:31:58 -05:00
## Description
2021-08-09 15:39:09 -04:00
This library contains functions to manipulate bits and bit patterns in an
2021-01-29 06:31:58 -05: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 05:51:15 -05:00
If they don't please file an issue on GitHub.
2021-01-29 06:31:58 -05:00
2021-12-14 05:51:15 -05:00
New bit functions can be added or investigated, please file an issue on GitHub.
2021-01-29 06:31:58 -05:00
## Interface
2021-08-10 16:16:36 -04:00
2021-01-29 06:31:58 -05:00
### 0.1.0
2021-08-10 16:16:36 -04:00
2021-01-29 06:31:58 -05:00
BitCount, several implementations to compare performance.
2021-12-14 05:51:15 -05: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 06:31:58 -05:00
2021-08-09 15:39:09 -04:00
BitCount - fastest version, SWAG algorithm
2021-12-14 05:51:15 -05:00
- **uint8_t bitCount(uint8_t value)** available for 16, 32 and 64 bit.
2021-01-29 06:31:58 -05:00
Reverse: uint8_t .. uint64_t
2021-12-14 05:51:15 -05: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 06:31:58 -05:00
Rotate Left / Right: uint8_t .. uint64_t
2021-08-09 15:39:09 -04:00
if pos larger than # bits original value is returned.
2021-12-14 05:51:15 -05:00
2021-08-09 15:39:09 -04:00
- **T bitRotateLeft(T value, uint8_t pos)**
- **T bitRotateRight(T value, uint8_t pos)**
2021-01-29 06:31:58 -05:00
BitFlip: uint8_t .. uint64_t a.k.a toggle
2021-08-09 15:39:09 -04:00
if pos larger than # bits original value is returned.
2021-12-14 05:51:15 -05:00
2021-08-09 15:39:09 -04:00
- **T bitFlip(T value, uint8_t pos)** flips a single bit at pos
2021-01-29 06:31:58 -05:00
BitRot: uint8_t .. uint64_t
2021-12-14 05:51:15 -05:00
2022-04-13 13:33:48 -04:00
- **T bitRot(T value, float chance = 0.5, uint8_t times = 1)** random damage to a single bit of a value,
2021-08-09 15:39:09 -04:00
chance = float 0.0 .. 1.0 that one random bit is toggled.
2022-04-13 13:33:48 -04:00
The times parameter allows to apply this n times.
2021-01-29 06:31:58 -05: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 16:16:36 -04:00
2021-01-29 06:31:58 -05:00
### 0.1.1 added
How many bits are needed to store / transmit a number?
2021-12-14 05:51:15 -05:00
- **bitsNeededReference(n)** reference implementation for uint8_t to uint64_t.
2021-01-29 06:31:58 -05:00
- **bitsNeeded(n)** A 'recursive strategy' for uint8_t .. uint64_t provides a fast answer.
2021-12-14 05:51:15 -05:00
The following functions are made as the normal **bitset()** etcetera do not work for 64 bit.
2021-01-29 06:31:58 -05:00
These functions are optimized for speed for **AVR**, **ESP32** and **ESP8266**.
2021-12-14 05:51:15 -05: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 06:31:58 -05:00
Also added are macro versions of these five functions.
2021-12-14 05:51:15 -05:00
2021-01-29 06:31:58 -05: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 16:16:36 -04:00
2022-04-12 09:50:42 -04:00
### 0.1.2 and beyond
2021-01-29 06:31:58 -05:00
2022-04-12 09:50:42 -04:00
See CHANGELOG.md
2021-08-09 15:39:09 -04:00
2022-04-12 09:50:42 -04:00
## Operations
See examples.
2021-08-09 15:39:09 -04:00
2022-04-12 09:50:42 -04:00
## Future
- improve documentation
- improve readability of code
- add performance tests
2021-01-29 06:31:58 -05:00
2022-04-12 09:50:42 -04:00
#### Functions add
2021-10-19 10:59:51 -04:00
2022-04-12 09:50:42 -04: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, 3)** ==> 00011010
- **bitBurst(00000000, 3)** ==> 00111000 any group of 3 bits will toggle. edges?
- **bitNoggle(value, bit)** - toggle all but one bit. (why?)
- **bitSort(value)** 00101001 ==> 00000111
or with minimal # toggles?
- **bitReverse(uint32_t x, uint8_t n)**
- **byteReverse24(uint32_t x)** dedicated 24 bit = 3 bytes e.g RGB
2022-04-13 13:33:48 -04:00
- **byteInverse(uint32_t x)** (a,b,c,d) => (255-a, 255-b, 255-c, 255-d) = rather simple ~?
2022-04-12 09:50:42 -04:00
- **isBitPalindrome()** byte, word ...
2022-04-13 13:33:48 -04:00
- **bitSwap(value, p, q)**
2021-10-19 10:59:51 -04:00
2022-04-12 09:50:42 -04:00
#### Functions fix
2021-12-14 05:51:15 -05:00
2022-04-12 09:50:42 -04:00
- **bitRotateLeftRight()** should it do modulo pos?
- **bitsNeededRef()** correct for value 0?
2021-12-14 05:51:15 -05:00
2022-04-12 09:50:42 -04:00
#### BitReverse n bit number
2021-08-10 16:16:36 -04:00
Trick to reverse a number of n bits ( 0 < n < 32 ).
2021-12-14 05:51:15 -05:00
Could also be done similar with 64 bit and or byte / nibble reverse.
2021-08-10 16:16:36 -04: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...
2022-04-12 09:50:42 -04:00
Q: what to do with the first (32-n) bits?
Just reverse the last 24 bits and clear bit 24-31 is different than
reversing the last 24 bits and keel bit 24-31 as is.
```cpp
uint32_t bitReverse(uint32_t x, uint8_t n)
{
uint32_t y = (x >> n) << n;
uint32_t r = bitReverse(x);
r >>= (32 - n);
return y | r;
}
```
2021-08-10 16:16:36 -04:00
2022-10-29 09:51:15 -04:00
## Future
#### Must
- redo documentation
- logical groups
#### Should
#### Could
- 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.
- bitRot(value, chance = 50%, times = 1) extention...
- bitNoggle(value, bit) - toggle all but one bit. (why?)
- bitSort(value) ==> 00101001 ==> 00000111
- many more :)