Skip to content

Commit

Permalink
CRC8/16: 16 elements table support added
Browse files Browse the repository at this point in the history
  • Loading branch information
pstolarz committed Sep 1, 2024
1 parent 880fa42 commit b7b1f25
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
4 changes: 4 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ choice CRC8_ALGO
bool "Basic; no memory tables"
config CRC8_ALGO_TAB_16LH
bool "2x16 elements table"
config CRC8_ALGO_TAB_16
bool "16 elements table"
endchoice

config CRC16_ENABLED
Expand All @@ -48,6 +50,8 @@ choice CRC16_ALGO
bool "Basic; no memory tables"
config CRC16_ALGO_TAB_16LH
bool "2x16 elements table"
config CRC16_ALGO_TAB_16
bool "16 elements table"
endchoice
endif

Expand Down
4 changes: 3 additions & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ CONFIG_PWR_CTRL_REV_POLARITY LITERAL1
CONFIG_SEARCH_ENABLED LITERAL1
CONFIG_MAX_SEARCH_FILTERS LITERAL1
CONFIG_OVERDRIVE_ENABLED LITERAL1
CONFIG_CRC8_ALGO CRC8_TAB_16LH LITERAL1
CONFIG_CRC8_ALGO LITERAL1
CONFIG_CRC16_ENABLED LITERAL1
CONFIG_CRC16_ALGO LITERAL1
CONFIG_FLASH_CRC_TAB LITERAL1
Expand All @@ -170,8 +170,10 @@ CONFIG_RP2040_PIOSM_NUM_USED LITERAL1

CRC8_BASIC LITERAL1
CRC8_TAB_16LH LITERAL1
CRC8_TAB_16 LITERAL1
CRC16_BASIC LITERAL1
CRC16_TAB_16LH LITERAL1
CRC16_TAB_16 LITERAL1

TIMING_STRICT LITERAL1
TIMING_RELAXED LITERAL1
Expand Down
39 changes: 29 additions & 10 deletions src/OneWireNg.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023 Piotr Stolarz
* Copyright (c) 2019-2024 Piotr Stolarz
* OneWireNg: Arduino 1-wire service library
*
* Distributed under the 2-clause BSD License (the License)
Expand All @@ -15,17 +15,23 @@

#define CRC8_BASIC 1
#define CRC8_TAB_16LH 2
#define CRC8_TAB_16 3

#define CRC16_BASIC 1
#define CRC16_TAB_16LH 2
#define CRC16_TAB_16 3

#if defined(CONFIG_CRC8_ALGO) && \
!(CONFIG_CRC8_ALGO == CRC8_BASIC || CONFIG_CRC8_ALGO == CRC8_TAB_16LH)
!(CONFIG_CRC8_ALGO == CRC8_BASIC || \
CONFIG_CRC8_ALGO == CRC8_TAB_16LH || \
CONFIG_CRC8_ALGO == CRC8_TAB_16)
# error "Invalid CONFIG_CRC8_ALGO"
#endif

#if defined(CONFIG_CRC16_ALGO) && \
!(CONFIG_CRC16_ALGO == CRC16_BASIC || CONFIG_CRC16_ALGO == CRC16_TAB_16LH)
!(CONFIG_CRC16_ALGO == CRC16_BASIC || \
CONFIG_CRC16_ALGO == CRC16_TAB_16LH || \
CONFIG_CRC16_ALGO == CRC16_TAB_16)
# error "Invalid CONFIG_CRC16_ALGO"
#endif

Expand Down Expand Up @@ -292,22 +298,29 @@ uint8_t OneWireNg::crc8(const void *in, size_t len, uint8_t crc_in)
{
uint8_t crc = crc_in;

#if (CONFIG_CRC8_ALGO == CRC8_TAB_16LH)
#if (CONFIG_CRC8_ALGO == CRC8_TAB_16LH || CONFIG_CRC8_ALGO == CRC8_TAB_16)
const uint8_t *in_bts = (const uint8_t*)in;

# if (CONFIG_CRC8_ALGO == CRC8_TAB_16LH)
CRCTAB_STORAGE static uint8_t CRC8_16L[] = {
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41
};
# endif
CRCTAB_STORAGE static uint8_t CRC8_16H[] = {
0x00, 0x9d, 0x23, 0xbe, 0x46, 0xdb, 0x65, 0xf8,
0x8c, 0x11, 0xaf, 0x32, 0xca, 0x57, 0xe9, 0x74
};

while (len--) {
crc ^= *in_bts++;
crc = tabRead_u8(CRC8_16L + (crc & 0x0f)) ^
tabRead_u8(CRC8_16H + (crc >> 4));
# if (CONFIG_CRC8_ALGO == CRC8_TAB_16LH)
uint8_t tl = tabRead_u8(CRC8_16L + (crc & 0xf));
# else
uint8_t tl = tabRead_u8(CRC8_16H + (crc & 0xf));
tl = tabRead_u8(CRC8_16H + (tl & 0xf)) ^ (tl >> 4);
# endif
crc = tl ^ tabRead_u8(CRC8_16H + (crc >> 4));
}
#else
crc = OneWireNg::crc<uint8_t, 0x8c>(in, len, crc);
Expand All @@ -320,23 +333,29 @@ uint16_t OneWireNg::crc16(const void *in, size_t len, uint16_t crc_in)
{
uint16_t crc = crc_in;

# if (CONFIG_CRC16_ALGO == CRC16_TAB_16LH)
# if (CONFIG_CRC16_ALGO == CRC16_TAB_16LH || CONFIG_CRC16_ALGO == CRC16_TAB_16)
const uint8_t *in_bts = (const uint8_t*)in;

# if (CONFIG_CRC16_ALGO == CRC16_TAB_16LH)
CRCTAB_STORAGE static uint16_t CRC16_16L[] = {
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440
};
#endif
CRCTAB_STORAGE static uint16_t CRC16_16H[] = {
0x0000, 0xcc01, 0xd801, 0x1400, 0xf001, 0x3c00, 0x2800, 0xe401,
0xa001, 0x6c00, 0x7800, 0xb401, 0x5000, 0x9c01, 0x8801, 0x4400
};

while (len--) {
crc ^= *in_bts++;
crc = (crc >> 8) ^
tabRead_u16(CRC16_16L + (crc & 0x0f)) ^
tabRead_u16(CRC16_16H + ((crc >> 4) & 0x0f));
# if (CONFIG_CRC16_ALGO == CRC16_TAB_16LH)
uint16_t tl = tabRead_u16(CRC16_16L + (crc & 0xf));
# else
uint16_t tl = tabRead_u16(CRC16_16H + (crc & 0xf));
tl = tabRead_u16(CRC16_16H + (tl & 0xf)) ^ (tl >> 4);
# endif
crc = (crc >> 8) ^ tl ^ tabRead_u16(CRC16_16H + ((crc >> 4) & 0xf));
}
# else
crc = OneWireNg::crc<uint16_t, 0xa001>(in, len, crc_in);
Expand Down
16 changes: 12 additions & 4 deletions src/OneWireNg_Config.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023 Piotr Stolarz
* Copyright (c) 2019-2024 Piotr Stolarz
* OneWireNg: Arduino 1-wire service library
*
* Distributed under the 2-clause BSD License (the License)
Expand Down Expand Up @@ -42,12 +42,16 @@
# define CONFIG_CRC8_ALGO CRC8_BASIC
# elif CONFIG_CRC8_ALGO_TAB_16LH
# define CONFIG_CRC8_ALGO CRC8_TAB_16LH
# elif CONFIG_CRC8_ALGO_TAB_16
# define CONFIG_CRC8_ALGO CRC8_TAB_16
# endif

# if CONFIG_CRC16_ALGO_BASIC
# define CONFIG_CRC16_ALGO CRC16_BASIC
# elif CONFIG_CRC16_ALGO_TAB_16LH
# define CONFIG_CRC16_ALGO CRC16_TAB_16LH
# elif CONFIG_CRC16_ALGO_TAB_16
# define CONFIG_CRC16_ALGO CRC16_TAB_16
# endif

# if CONFIG_BITBANG_TIMING_STRICT
Expand Down Expand Up @@ -137,9 +141,11 @@
* Type of algorithm used for CRC-8/MAXIM calculation.
*
* The macro may be defined as:
* - @c CRC8_BASIC: Basic method. No memory tables used. This method is
* about 8 times slower than the tabled method but no extra memory is used.
* - @c CRC8_BASIC: Basic method. No memory tables used. This method is about
* 8 times slower than the table based methods but no extra memory is used.
* - @c CRC8_TAB_16LH: 2x16 elements table, 1 byte each.
* - @c CRC8_TAB_16: 16 elements table, 1 byte each. This method is about 20%
* slower than 2x16 elements table based method.
*/
# ifndef CONFIG_CRC8_ALGO
# define CONFIG_CRC8_ALGO CRC8_TAB_16LH
Expand All @@ -158,8 +164,10 @@
*
* The macro may be defined as:
* - @c CRC16_BASIC: Basic method. No memory tables used. This method is about
* 8 times slower than the tabled method but no extra memory is used.
* 8 times slower than the table based methods but no extra memory is used.
* - @c CRC16_TAB_16LH: 2x16 elements table, 2 bytes each.
* - @c CRC16_TAB_16: 16 elements table, 2 bytes each. This method is about 20%
* slower than 2x16 elements table based method.
*/
# ifndef CONFIG_CRC16_ALGO
# define CONFIG_CRC16_ALGO CRC16_TAB_16LH
Expand Down

0 comments on commit b7b1f25

Please sign in to comment.