bit_lib.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #pragma once
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. #define TOPBIT(X) (1 << (X - 1))
  9. typedef enum {
  10. BitLibParityEven,
  11. BitLibParityOdd,
  12. BitLibParityAlways0,
  13. BitLibParityAlways1,
  14. } BitLibParity;
  15. /** @brief Increment and wrap around a value.
  16. * @param index value to increment
  17. * @param length wrap-around range
  18. */
  19. #define bit_lib_increment_index(index, length) (index = (((index) + 1) % (length)))
  20. /** @brief Test if a bit is set.
  21. * @param data value to test
  22. * @param index bit index to test
  23. */
  24. #define bit_lib_bit_is_set(data, index) ((data & (1 << (index))) != 0)
  25. /** @brief Test if a bit is not set.
  26. * @param data value to test
  27. * @param index bit index to test
  28. */
  29. #define bit_lib_bit_is_not_set(data, index) ((data & (1 << (index))) == 0)
  30. /** @brief Push a bit into a byte array.
  31. * @param data array to push bit into
  32. * @param data_size array size
  33. * @param bit bit to push
  34. */
  35. void bit_lib_push_bit(uint8_t* data, size_t data_size, bool bit);
  36. /** @brief Set a bit in a byte array.
  37. * @param data array to set bit in
  38. * @param position The position of the bit to set.
  39. * @param bit bit value to set
  40. */
  41. void bit_lib_set_bit(uint8_t* data, size_t position, bool bit);
  42. /** @brief Set the bit at the given position to the given value.
  43. * @param data The data to set the bit in.
  44. * @param position The position of the bit to set.
  45. * @param byte The data to set the bit to.
  46. * @param length The length of the data.
  47. */
  48. void bit_lib_set_bits(uint8_t* data, size_t position, uint8_t byte, uint8_t length);
  49. /** @brief Get the bit of a byte.
  50. * @param data The byte to get the bits from.
  51. * @param position The position of the bit.
  52. * @return The bit.
  53. */
  54. bool bit_lib_get_bit(const uint8_t* data, size_t position);
  55. /**
  56. * @brief Get the bits of a data, as uint8_t.
  57. * @param data The data to get the bits from.
  58. * @param position The position of the first bit.
  59. * @param length The length of the bits.
  60. * @return The bits.
  61. */
  62. uint8_t bit_lib_get_bits(const uint8_t* data, size_t position, uint8_t length);
  63. /**
  64. * @brief Get the bits of a data, as uint16_t.
  65. * @param data The data to get the bits from.
  66. * @param position The position of the first bit.
  67. * @param length The length of the bits.
  68. * @return The bits.
  69. */
  70. uint16_t bit_lib_get_bits_16(const uint8_t* data, size_t position, uint8_t length);
  71. /**
  72. * @brief Get the bits of a data, as uint32_t.
  73. * @param data The data to get the bits from.
  74. * @param position The position of the first bit.
  75. * @param length The length of the bits.
  76. * @return The bits.
  77. */
  78. uint32_t bit_lib_get_bits_32(const uint8_t* data, size_t position, uint8_t length);
  79. /**
  80. * @brief Test parity of given bits
  81. * @param bits Bits to test parity of
  82. * @param parity Parity to test against
  83. * @return true if parity is correct, false otherwise
  84. */
  85. bool bit_lib_test_parity_32(uint32_t bits, BitLibParity parity);
  86. /**
  87. * @brief Test parity of bit array, check parity for every parity_length block from start
  88. *
  89. * @param data Bit array
  90. * @param position Start position
  91. * @param length Bit count
  92. * @param parity Parity to test against
  93. * @param parity_length Parity block length
  94. * @return true
  95. * @return false
  96. */
  97. bool bit_lib_test_parity(
  98. const uint8_t* data,
  99. size_t position,
  100. uint8_t length,
  101. BitLibParity parity,
  102. uint8_t parity_length);
  103. /**
  104. * @brief Add parity to bit array
  105. *
  106. * @param data Source bit array
  107. * @param position Start position
  108. * @param dest Destination bit array
  109. * @param dest_position Destination position
  110. * @param source_length Source bit count
  111. * @param parity_length Parity block length
  112. * @param parity Parity to test against
  113. * @return size_t
  114. */
  115. size_t bit_lib_add_parity(
  116. const uint8_t* data,
  117. size_t position,
  118. uint8_t* dest,
  119. size_t dest_position,
  120. uint8_t source_length,
  121. uint8_t parity_length,
  122. BitLibParity parity);
  123. /**
  124. * @brief Remove bit every n in array and shift array left. Useful to remove parity.
  125. *
  126. * @param data Bit array
  127. * @param position Start position
  128. * @param length Bit count
  129. * @param n every n bit will be removed
  130. * @return size_t
  131. */
  132. size_t bit_lib_remove_bit_every_nth(uint8_t* data, size_t position, uint8_t length, uint8_t n);
  133. /**
  134. * @brief Copy bits from source to destination.
  135. *
  136. * @param data destination array
  137. * @param position position in destination array
  138. * @param length length of bits to copy
  139. * @param source source array
  140. * @param source_position position in source array
  141. */
  142. void bit_lib_copy_bits(
  143. uint8_t* data,
  144. size_t position,
  145. size_t length,
  146. const uint8_t* source,
  147. size_t source_position);
  148. /**
  149. * @brief Reverse bits in bit array
  150. *
  151. * @param data Bit array
  152. * @param position start position
  153. * @param length length of bits to reverse
  154. */
  155. void bit_lib_reverse_bits(uint8_t* data, size_t position, uint8_t length);
  156. /**
  157. * @brief Count 1 bits in data
  158. *
  159. * @param data
  160. * @return uint8_t set bit count
  161. */
  162. uint8_t bit_lib_get_bit_count(uint32_t data);
  163. /**
  164. * @brief Print data as bit array
  165. *
  166. * @param data
  167. * @param length
  168. */
  169. void bit_lib_print_bits(const uint8_t* data, size_t length);
  170. typedef struct {
  171. const char mark;
  172. const size_t start;
  173. const size_t length;
  174. } BitLibRegion;
  175. /**
  176. * @brief Print data as bit array and mark regions. Regions needs to be sorted by start position.
  177. *
  178. * @param regions
  179. * @param region_count
  180. * @param data
  181. * @param length
  182. */
  183. void bit_lib_print_regions(
  184. const BitLibRegion* regions,
  185. size_t region_count,
  186. const uint8_t* data,
  187. size_t length);
  188. /**
  189. * @brief Reverse bits in uint16_t, faster than generic bit_lib_reverse_bits.
  190. *
  191. * @param data
  192. * @return uint16_t
  193. */
  194. uint16_t bit_lib_reverse_16_fast(uint16_t data);
  195. /**
  196. * @brief Reverse bits in uint8_t, faster than generic bit_lib_reverse_bits.
  197. *
  198. * @param byte Byte
  199. * @return uint8_t the reversed byte
  200. */
  201. uint8_t bit_lib_reverse_8_fast(uint8_t byte);
  202. /**
  203. * @brief Slow, but generic CRC8 implementation
  204. *
  205. * @param data
  206. * @param data_size
  207. * @param polynom CRC polynom
  208. * @param init init value
  209. * @param ref_in true if the right bit is older
  210. * @param ref_out true to reverse output
  211. * @param xor_out xor output with this value
  212. * @return uint8_t
  213. */
  214. uint16_t bit_lib_crc8(
  215. uint8_t const* data,
  216. size_t data_size,
  217. uint8_t polynom,
  218. uint8_t init,
  219. bool ref_in,
  220. bool ref_out,
  221. uint8_t xor_out);
  222. /**
  223. * @brief Slow, but generic CRC16 implementation
  224. *
  225. * @param data
  226. * @param data_size
  227. * @param polynom CRC polynom
  228. * @param init init value
  229. * @param ref_in true if the right bit is older
  230. * @param ref_out true to reverse output
  231. * @param xor_out xor output with this value
  232. * @return uint16_t
  233. */
  234. uint16_t bit_lib_crc16(
  235. uint8_t const* data,
  236. size_t data_size,
  237. uint16_t polynom,
  238. uint16_t init,
  239. bool ref_in,
  240. bool ref_out,
  241. uint16_t xor_out);
  242. #ifdef __cplusplus
  243. }
  244. #endif