diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index b3558a71cf..fefb6e45f6 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -45,6 +45,7 @@ PSEUDOMODULES += cortexm_fpu PSEUDOMODULES += cortexm_svc PSEUDOMODULES += cpp PSEUDOMODULES += cpu_check_address +PSEUDOMODULES += crc16_fast PSEUDOMODULES += crc32_fast PSEUDOMODULES += credman_load PSEUDOMODULES += dbgpin diff --git a/sys/Makefile.dep b/sys/Makefile.dep index f3e9837772..270b3816a5 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -49,6 +49,10 @@ ifneq (,$(filter congure_reno_methods,$(USEMODULE))) USEMODULE += seq endif +ifneq (,$(filter crc16_fast,$(USEMODULE))) + USEMODULE += checksum +endif + ifneq (,$(filter crc32_fast,$(USEMODULE))) USEMODULE += checksum endif diff --git a/sys/checksum/crc16_ccitt.c b/sys/checksum/crc16_ccitt.c index 5f8f30b9ce..d6b3cdb6a7 100644 --- a/sys/checksum/crc16_ccitt.c +++ b/sys/checksum/crc16_ccitt.c @@ -21,6 +21,8 @@ #include #include +#include "byteorder.h" +#include "kernel_defines.h" #include "checksum/crc16_ccitt.h" static const uint16_t crc_ccitt_lookuptable[256] = { @@ -96,7 +98,16 @@ static const uint16_t _crc16_ccitt_false_lookuptable[256] = { uint16_t crc16_ccitt_kermit_update(uint16_t crc, const unsigned char *buf, size_t len) { while (len--) { - crc = (crc >> 8) ^ crc_ccitt_lookuptable[(crc ^ (*buf++)) & 0xff]; + uint8_t e = crc ^= *buf++; + if (IS_USED(MODULE_CRC16_FAST)) { + crc = (crc >> 8) ^ crc_ccitt_lookuptable[e]; + } else { + uint8_t f = e ^ (e << 4); + crc = (crc >> 8) + ^ ((uint16_t)f << 8) + ^ ((uint16_t)f << 3) + ^ ((uint16_t)f >> 4); + } } return crc; @@ -115,7 +126,14 @@ uint16_t crc16_ccitt_mcrf4xx_calc(const unsigned char *buf, size_t len) uint16_t crc16_ccitt_false_update(uint16_t crc, const unsigned char *buf, size_t len) { while (len--) { - crc = ((crc << 8) ^ _crc16_ccitt_false_lookuptable[((crc >> 8) ^ ((*buf++) & 0x00FF))]); + crc = byteorder_swaps(crc) ^ *buf++; + if (IS_USED(MODULE_CRC16_FAST)) { + crc = (crc & 0xFF00) ^ _crc16_ccitt_false_lookuptable[crc & 0xFF]; + } else { + crc ^= (uint8_t)(crc & 0xff) >> 4; + crc ^= (crc << 8) << 4; + crc ^= ((crc & 0xff) << 4) << 1; + } } return crc; diff --git a/sys/include/checksum/crc16_ccitt.h b/sys/include/checksum/crc16_ccitt.h index b884ed2bfa..14ad802b2e 100644 --- a/sys/include/checksum/crc16_ccitt.h +++ b/sys/include/checksum/crc16_ccitt.h @@ -18,6 +18,9 @@ * do (and is thus also far more memory efficient). Its caveat * however is that it is slower by about factor 8 than these versions. * + * @note enable the `crc32_fast` module for a look-up table based + * implementation that trades code size for speed. + * * @{ * @file * @author Ludwig Knüpfer