/*
 * crc_core.h
 *
 *  Created on: 27/04/2021
 *      Author: alexrayne <alexraynepe196@gmail.com>
 * ------------------------------------------------------------------------------------
 *  RA CRC-core support
 */

#ifndef BSP_CPU_DEV_CRC_CORE_H_
#define BSP_CPU_DEV_CRC_CORE_H_

#include <stdint.h>
#include "mcu_crc.h"


/// @brief power on/off crc core
#define crc_core_enable()   CRC_enable()
#define crc_core_disable()  CRC_disable()


/**
 * \brief      Calculate the CRC16 over a data area
 * \param data Pointer to the data
 * \param datalen The length of the data
 * \param acc  The accumulated CRC that is to be updated (or zero).
 * \return     The CRC16 checksum.
 *
 *             This function calculates the CRC16 checksum of a data area.
 *
 *             \note The algorithm used in this implementation is
 *             tailored for a running checksum and does not perform as
 *             well as a table-driven algorithm when checksumming an
 *             entire data block.
 */
// Poly  : 0x1021    x^16 + x^12 + x^5 + 1
unsigned short crc_core_16ccitt_lsb(const void* data, int datalen,  unsigned short acc);
unsigned short crc_core_16ccitt_msb(const void* data, int datalen,  unsigned short acc);

// Poly  : 0x8005    x^16 + x^15 + x^2 + 1
unsigned short crc_core_16ansi_lsb(const void* data, int datalen,   unsigned short acc);
unsigned short crc_core_16ansi_msb(const void* data, int datalen,   unsigned short acc);

/// @brief celc crc32 CCITT checksum
enum { CRC32CCITT_INIT = 0, };
unsigned long crc_core_32ccitt_lsb(const void* data, unsigned datalen, unsigned long acc);
unsigned long crc_core_32ccitt_msb(const void* data, unsigned datalen, unsigned long acc);


/// @brief continue CRC calculation after crc_core_16XXX_data
unsigned short crc_core_append16(const void* data, unsigned datalen);
unsigned long  crc_core_append32(const void* data, unsigned datalen);

unsigned char crc_core8(const void* data, unsigned datalen, unsigned char acc);

unsigned long crc_core32_msb(const void* data, unsigned datalen, unsigned long acc);
unsigned long crc_core32_lsb(const void* data, unsigned datalen, unsigned long acc);

#define crc_core32(...) crc_core32_msb(__VA_ARGS__)


#endif /* BSP_CPU_DEV_CRC_CORE_H_ */
