mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
134 lines
3.4 KiB
C
134 lines
3.4 KiB
C
#pragma once
|
|
/*
|
|
Author: Daniel Mohr
|
|
Date: 2022-09-12
|
|
|
|
Here are implementations, which were used in release '0.1.6'.
|
|
|
|
Fletcher16.cpp
|
|
Fletcher16.h
|
|
Fletcher32.cpp
|
|
Fletcher32.h
|
|
Fletcher64.cpp
|
|
Fletcher64.h
|
|
*/
|
|
|
|
#define FLETCHER_16_v0_1_6 255
|
|
#define FLETCHER_32_v0_1_6 65535UL
|
|
#define FLETCHER_64_v0_1_6 4294967295ULL
|
|
|
|
uint16_t fletcher16_v0_1_6(uint8_t *data, const uint16_t length)
|
|
{
|
|
#ifdef ARDUINO_ARCH_AVR
|
|
uint8_t _s1 = 0;
|
|
uint8_t _s2 = 0;
|
|
#else
|
|
uint16_t _s1 = 0;
|
|
uint16_t _s2 = 0;
|
|
#endif
|
|
for (uint16_t i = 0; i < length; i++)
|
|
{
|
|
#if defined(ARDUINO_ARCH_AVR)
|
|
uint8_t t = 0xFF - data[i];
|
|
if (t >= _s1) _s1 += data[i];
|
|
else _s1 = _s1 + data[i] + 1;
|
|
|
|
t = 0xFF - _s1;
|
|
if (t >= _s2) _s2 += _s1;
|
|
else _s2 = _s2 + _s1 + 1;
|
|
|
|
#elif defined(ARDUINO_ARCH_SAMD) || defined(ESP32) || defined(ESP8266)
|
|
_s1 += data[i];
|
|
_s1 = (_s1 & 255) + (_s1 >> 8);
|
|
_s2 += _s1;
|
|
_s2 = (_s2 & 255) + (_s2 >> 8);
|
|
|
|
#else
|
|
// REFERENCE
|
|
_s1 += data[i];
|
|
if (_s1 >= FLETCHER_16_v0_1_6) _s1 -= FLETCHER_16_v0_1_6;
|
|
_s2 += _s1;
|
|
if (_s2 >= FLETCHER_16_v0_1_6) _s2 -= FLETCHER_16_v0_1_6;
|
|
#endif
|
|
}
|
|
if (_s1 >= FLETCHER_16_v0_1_6) _s1 -= FLETCHER_16_v0_1_6;
|
|
if (_s2 >= FLETCHER_16_v0_1_6) _s2 -= FLETCHER_16_v0_1_6;
|
|
return (((uint16_t)_s2) << 8) | _s1;
|
|
}
|
|
|
|
uint32_t fletcher32_v0_1_6(uint16_t *data, const uint16_t length)
|
|
{
|
|
#ifdef ARDUINO_ARCH_AVR
|
|
uint16_t _s1 = 0;
|
|
uint16_t _s2 = 0;
|
|
#else
|
|
uint32_t _s1 = 0;
|
|
uint32_t _s2 = 0;
|
|
#endif
|
|
for (uint16_t i = 0; i < length; i++)
|
|
{
|
|
#ifdef ARDUINO_ARCH_AVR
|
|
unsigned int t = _s1;
|
|
// Serial.println("__builtin_uadd_overflow");
|
|
if (__builtin_uadd_overflow(t, data[i], &t)) {
|
|
t++;
|
|
}
|
|
_s1 = t;
|
|
t = _s2;
|
|
if (__builtin_uadd_overflow(t, _s1, &t)) {
|
|
t++;
|
|
}
|
|
_s2 = t;
|
|
#elif defined(ARDUINO_ARCH_SAMD) || defined(ESP32) || defined(ESP8266)
|
|
_s1 += data[i];
|
|
_s1 = (_s1 & 65535UL) + (_s1 >> 16);
|
|
_s2 += _s1;
|
|
_s2 = (_s2 & 65535UL) + (_s2 >> 16);
|
|
#else
|
|
_s1 += data[i];
|
|
if (_s1 >= FLETCHER_32_v0_1_6) _s1 -= FLETCHER_32_v0_1_6;
|
|
_s2 += _s1;
|
|
if (_s2 >= FLETCHER_32_v0_1_6) _s2 -= FLETCHER_32_v0_1_6;
|
|
#endif
|
|
}
|
|
if (_s1 >= FLETCHER_32_v0_1_6) _s1 -= FLETCHER_32_v0_1_6;
|
|
if (_s2 >= FLETCHER_32_v0_1_6) _s2 -= FLETCHER_32_v0_1_6;
|
|
return (((uint32_t)_s2) << 16) | _s1;
|
|
}
|
|
|
|
uint64_t fletcher64_v0_1_6(uint32_t *data, const uint16_t length)
|
|
{
|
|
#if defined(ARDUINO_ARCH_AVR) || defined(ESP32) || defined(ESP8266)
|
|
uint32_t _s1 = 0;
|
|
uint32_t _s2 = 0;
|
|
#else
|
|
uint64_t _s1 = 0;
|
|
uint64_t _s2 = 0;
|
|
#endif
|
|
for (uint16_t i = 0; i < length; i++)
|
|
{
|
|
#if defined(ARDUINO_ARCH_AVR) || defined(ESP32) || defined(ESP8266)
|
|
uint32_t t = 0xFFFFFFFF - data[i];
|
|
if (t >= _s1) _s1 += data[i];
|
|
else _s1 = _s1 + data[i] + 1;
|
|
|
|
t = 0xFFFFFFFF - _s1;
|
|
if (t >= _s2) _s2 += _s1;
|
|
else _s2 = _s2 + _s1 + 1;
|
|
#elif defined(ARDUINO_ARCH_SAMD)
|
|
_s1 += data[i];
|
|
_s1 = (_s1 & ((((uint64_t) 1) << 32) - 1)) + (_s1 >> 32);
|
|
_s2 += _s1;
|
|
_s2 = (_s2 & ((((uint64_t) 1) << 32) - 1)) + (_s2 >> 32);
|
|
#else
|
|
_s1 += data[i];
|
|
if (_s1 >= FLETCHER_64_v0_1_6) _s1 -= FLETCHER_64_v0_1_6;
|
|
_s2 += _s1;
|
|
if (_s2 >= FLETCHER_64_v0_1_6) _s2 -= FLETCHER_64_v0_1_6;
|
|
#endif
|
|
}
|
|
if (_s1 >= FLETCHER_64_v0_1_6) _s1 -= FLETCHER_64_v0_1_6;
|
|
if (_s2 >= FLETCHER_64_v0_1_6) _s2 -= FLETCHER_64_v0_1_6;
|
|
return (((uint64_t)_s2) << 32) | _s1;
|
|
}
|