Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Add CRC8 calculation subsystem to quantum #12641

Merged
merged 1 commit into from
Jun 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ endif
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
OPT_DEFS += -DSPLIT_KEYBOARD
CRC_ENABLE := yes

# Include files used by all split keyboards
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_util.c
Expand Down Expand Up @@ -546,6 +547,11 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
COMMON_VPATH += $(QUANTUM_PATH)/split_common
endif

ifeq ($(strip $(CRC_ENABLE)), yes)
OPT_DEFS += -DCRC_ENABLE
QUANTUM_LIB_SRC += crc.c
endif

HAPTIC_ENABLE ?= no
ifneq ($(strip $(HAPTIC_ENABLE)),no)
COMMON_VPATH += $(DRIVER_PATH)/haptic
Expand Down
59 changes: 59 additions & 0 deletions quantum/crc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* Copyright 2021 QMK
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "crc.h"

__attribute__((weak)) void crc_init(void){
/* Software implementation nothing todo here. */
};

#if defined(CRC8_USE_TABLE)
/**
* Static table used for the table_driven implementation.
*/
static const crc_t crc_table[256] = {0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3};

__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) {
const uint8_t *d = (const uint8_t *)data;
crc_t crc = 0xff;
size_t tbl_idx;

while (data_len--) {
tbl_idx = crc ^ *d;
crc = crc_table[tbl_idx] & 0xff;
d++;
}
return crc & 0xff;
}
#else
__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) {
const uint8_t *d = (const uint8_t *)data;
crc_t crc = 0xff;
size_t i, j;

for (i = 0; i < data_len; i++) {
crc ^= d[i];
for (j = 0; j < 8; j++) {
if ((crc & 0x80) != 0)
crc = (crc_t)((crc << 1) ^ 0x31);
else
crc <<= 1;
}
}
return crc;
}
#endif
44 changes: 44 additions & 0 deletions quantum/crc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Copyright 2021 QMK
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "quantum.h"

/**
* The type of the CRC values.
*
* This type must be big enough to contain at least 8 bits.
*/
#if defined(CRC8_OPTIMIZE_SPEED)
typedef uint_fast8_t crc_t;
#else
typedef uint_least8_t crc_t;
#endif

/**
* Initialize crc subsystem.
*/
__attribute__((weak)) void crc_init(void);

/**
* Generate CRC8 value from given data.
*
* \param[in] data Pointer to a buffer of \a data_len bytes.
* \param[in] data_len Number of bytes in the \a data buffer.
* \return The calculated crc value.
*/
__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len);
6 changes: 6 additions & 0 deletions tmk_core/common/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef EEPROM_DRIVER
# include "eeprom_driver.h"
#endif
#if defined(CRC_ENABLE)
# include "crc.h"
#endif

static uint32_t last_input_modification_time = 0;
uint32_t last_input_activity_time(void) { return last_input_modification_time; }
Expand Down Expand Up @@ -288,6 +291,9 @@ void keyboard_init(void) {
timer_init();
sync_timer_init();
matrix_init();
#if defined(CRC_ENABLE)
crc_init();
#endif
#ifdef VIA_ENABLE
via_init();
#endif
Expand Down