
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                                  Main                                     //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////
// (c) 2021 Miroslav Nemecek, Panda38@seznam.cz, panda38.sweb.cz
// This source code may be used freely without restrictions for any purpose,
// including commercial.

#ifndef _CRC_H
#define _CRC_H

// ============================================================================
//                              CRC tables
// ============================================================================

// CRC-32 table (1 KB)
extern const u32 crc32_tab[256];

// CRC-16 table (512 B)
extern const u16 crc16_tab[256];

// CRC-Kermit table (512 B)
extern const u16 crc_kermit_tab[256];

// CRC-DNP table (512 B)
extern const u16 crc_dnp_tab[256];

// CRC-CCITT table (512 B)
extern const u16 crc_ccitt_tab[256];

// CRC-SHT table (256 B)
extern const u8 crc_sht_tab[256];

// CRC8-Dallas table (256 B)
extern const u8 crc8_dallas_tab[256];

// ============================================================================
//                               Calculate CRC
// ============================================================================

// Calculate CRC-32, 1 byte, inverted result
u32 crc32_1(u32 crc, u8 data);
u32 crc32_slow_1(u32 crc, u8 data);

// Calculate CRC-32 (set flag USEHWCRC32 to use hardware CRC32)
#define CRC32_INIT 0xffffffff
u32 crc32(const void* buf, int len);
u32 crc32_slow(const void* buf, int len);

// Calculate CRC-32 - Raspberry Pico alternative
u32 crc32_Pico(const u8* r0, u32 r1);

// Calculate CRC-16, 1 byte (IBM, Dallas Maxim)
u16 crc16_1(u16 crc, u8 data);
u16 crc16_slow_1(u16 crc, u8 data);

// Calculate CRC-IBM and Dallas Maxim
// used in disk controllers and in Dallas Maxim 1-Wire bus
#define CRCIBM_INIT 0
u16 crc_ibm(const void* buf, int len);
u16 crc_ibm_slow(const void* buf, int len);

// Calculate CRC-Modbus
#define CRCMODBUS_INIT 0xffff
u16 crc_modbus(const void* buf, int len);
u16 crc_modbus_slow(const void* buf, int len);

// Calculate CRC-Kermit, 1 byte, swap bytes of result
u16 crc_kermit_1(u16 crc, u8 data);
u16 crc_kermit_slow_1(u16 crc, u8 data);

// Calculate CRC-Kermit (=original CRC-CCITT)
#define CRCKERMIT_INIT 0
u16 crc_kermit(const void* buf, int len);
u16 crc_kermit_slow(const void* buf, int len);

// Calculate CRC-DNP, 1 byte, invert and swap bytes of result
u16 crc_dnp_1(u16 crc, u8 data);
u16 crc_dnp_slow_1(u16 crc, u8 data);

// Calculate CRC-DNP
#define CRCDNP_INIT 0
u16 crc_dnp(const void* buf, int len);
u16 crc_dnp_slow(const void* buf, int len);

// Calculate CRC-CCITT, 1 byte (XModem, CCITT)
u16 crc_ccitt_1(u16 crc, u8 data);
u16 crc_ccitt_fast_1(u16 crc, u8 data); // without table
u16 crc_ccitt_slow_1(u16 crc, u8 data);

// Calculate CRC-CCITT (XModem)
#define CRCXMODEM_INIT 0
u16 crc_xmodem(const void* buf, int len);
u16 crc_xmodem_fast(const void* buf, int len); // without table
u16 crc_xmodem_slow(const void* buf, int len);

// Calculate CRC-CCITT (0xFFFF)
#define CRCCCITT_INIT 0xffff
u16 crc_ccitt(const void* buf, int len);
u16 crc_ccitt_fast(const void* buf, int len); // without table
u16 crc_ccitt_slow(const void* buf, int len);

// Calculate CRC-CCITT (0x1D0F)
#define CRCCCITTB_INIT 0x1D0F
u16 crc_ccitt_b(const void* buf, int len);
u16 crc_ccitt_b_fast(const void* buf, int len); // without table
u16 crc_ccitt_b_slow(const void* buf, int len);

// Calculate CRC-SICK, 1 byte, swap bytes of result
u16 crc_sick_1(u16 crc, u8 data, u8 prev);

// Calculate CRC-SICK
#define CRCSICK_INIT 0
u16 crc_sick(const void* buf, int len);

// Calculate CRC8-RDallas, 1 byte
u8 crc8_rdallas_1(u8 crc, u8 data);
u8 crc8_rdallas_slow_1(u8 crc, u8 data);

// Calculate CRC8-RDallas
#define CRC8RDALLAS_INIT 0
u8 crc8_rdallas(const void* buf, int len);
u8 crc8_rdallas_slow(const void* buf, int len);

// Calculate CRC8-Dallas, 1 byte
u8 crc8_dallas_1(u8 crc, u8 data);
u8 crc8_dallas_slow_1(u8 crc, u8 data);

// Calculate CRC8-Dallas (Dallas Maxim 1-Wire bus)
#define CRC8DALLAS_INIT 0
u8 crc8_dallas(const void* buf, int len);
u8 crc8_dallas_slow(const void* buf, int len);

// Calculate CRC8-SUM, 1 byte
u8 crc8_sum_1(u8 crc, u8 data);

// Calculate CRC8-SUM
#define CRCSUM8_INIT 0
u8 crc8_sum(const void* buf, int len);

// Calculate CRC16-SUM, 1 byte
u16 crc16_sum_1(u16 crc, u8 data);

// Calculate CRC16-SUM
#define CRCSUM16_INIT 0
u16 crc16_sum(const void* buf, int len);

// Calculate CRC32-SUM, 1 byte
u32 crc32_sum_1(u32 crc, u8 data);

// Calculate CRC32-SUM
#define CRCSUM32_INIT 0
u32 crc32_sum(const void* buf, int len);

// Calculate CRC-SHT, 1 byte
u8 crc_sht_1(u8 crc, u8 data);

// Calculate CRC-SHT (SHT1x and SHT7x series of temperature and humidity sensors)
#define CRCSHT_INIT 0
u8 crc_sht(const void* buf, int len);

// Calculate CRC-XOR, 1 byte
u16 crc_xor_1(u16 crc, u8 data);

// Calculate CRC-XOR
#define CRCXOR_INIT 0
u16 crc_xor(const void* buf, int len);

// ============================================================================
//                               Check CRC tables
// ============================================================================

// Check CRC-32 table (returns False on error)
Bool crc32_check();

// Check CRC-16 table (returns False on error)
Bool crc16_check();

// Check CRC-Kermit table (returns False on error)
Bool crc_kermit_check();

// Check CRC-DNP table (returns False on error)
Bool crc_dnp_check();

// Check CRC-CCITT table (returns False on error)
Bool crc_ccitt_check();

// Check CRC-CCITT fast method (return False on error)
//Bool crc_ccitt_fast_check();

// Check CRC8-Dallas table (returns False on error)
Bool crc8_dallas_check();

// Check all CRC methods (takes few seconds, returns error code or 0 if OK)
int crc_check_all();

#endif // _CRC_H
