Position hold depends on GPS (#14101)
[betaflight.git] / src / main / common / crc.c
blob771cbaeabcd267a4e29d09218326ea6bc9bd8cca
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdint.h>
23 #include "common/crc.h"
25 #include "platform.h"
27 #include "streambuf.h"
29 uint16_t crc16_ccitt(uint16_t crc, unsigned char a)
31 crc ^= (uint16_t)a << 8;
32 for (int ii = 0; ii < 8; ++ii) {
33 if (crc & 0x8000) {
34 crc = (crc << 1) ^ 0x1021;
35 } else {
36 crc = crc << 1;
39 return crc;
42 uint16_t crc16_ccitt_update(uint16_t crc, const void *data, uint32_t length)
44 const uint8_t *p = (const uint8_t *)data;
45 const uint8_t *pend = p + length;
47 for (; p != pend; p++) {
48 crc = crc16_ccitt(crc, *p);
50 return crc;
53 void crc16_ccitt_sbuf_append(sbuf_t *dst, uint8_t *start)
55 uint16_t crc = 0;
56 const uint8_t * const end = sbufPtr(dst);
57 for (const uint8_t *ptr = start; ptr < end; ++ptr) {
58 crc = crc16_ccitt(crc, *ptr);
60 sbufWriteU16(dst, crc);
63 uint8_t crc8_calc(uint8_t crc, unsigned char a, uint8_t poly)
65 crc ^= a;
66 for (int ii = 0; ii < 8; ++ii) {
67 if (crc & 0x80) {
68 crc = (crc << 1) ^ poly;
69 } else {
70 crc = crc << 1;
73 return crc;
76 uint8_t crc8_update(uint8_t crc, const void *data, uint32_t length, uint8_t poly)
78 const uint8_t *p = (const uint8_t *)data;
79 const uint8_t *pend = p + length;
81 for (; p != pend; p++) {
82 crc = crc8_calc(crc, *p, poly);
84 return crc;
87 void crc8_sbuf_append(sbuf_t *dst, uint8_t *start, uint8_t poly)
89 uint8_t crc = 0;
90 const uint8_t * const end = dst->ptr;
91 for (const uint8_t *ptr = start; ptr < end; ++ptr) {
92 crc = crc8_calc(crc, *ptr, poly);
94 sbufWriteU8(dst, crc);
97 uint8_t crc8_xor_update(uint8_t crc, const void *data, uint32_t length)
99 const uint8_t *p = (const uint8_t *)data;
100 const uint8_t *pend = p + length;
102 for (; p != pend; p++) {
103 crc ^= *p;
105 return crc;
108 void crc8_xor_sbuf_append(sbuf_t *dst, uint8_t *start)
110 uint8_t crc = 0;
111 const uint8_t *end = dst->ptr;
112 for (uint8_t *ptr = start; ptr < end; ++ptr) {
113 crc ^= *ptr;
115 sbufWriteU8(dst, crc);
118 // Fowler–Noll–Vo hash function; see https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function
119 uint32_t fnv_update(uint32_t hash, const void *data, uint32_t length)
121 const uint8_t *p = (const uint8_t *)data;
122 const uint8_t *pend = p + length;
124 for (; p != pend; p++) {
125 hash *= FNV_PRIME;
126 hash ^= *p;
129 return hash;