/* * Copyright (c) 2021-2022 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * */ #ifndef HPM_CRC_DRV_H #define HPM_CRC_DRV_H /** * @brief CRC APIs * @defgroup crc_interface CRC driver APIs * @ingroup crc_interfaces * @{ */ #include "hpm_common.h" #include "hpm_crc_regs.h" /** * @brief CRC preset definitions */ typedef enum crc_preset_enum { crc_preset_none = 0, crc_preset_crc32, /*!< Poly: 0x04C11DB7, Init: 0xFFFFFFFF, Refin: True, Refout: True, Xorout: 0xFFFFFFFF */ crc_preset_crc32_autosar, /*!< Poly: 0xF4ACFB13, Init: 0xFFFFFFFF, Refin: True, Refout: True, Xorout: 0xFFFFFFFF */ crc_preset_crc16_ccitt, /*!< Poly: 0x1021, Init: 0x0000, Refin: True, Refout: True, Xorout: 0x0000 */ crc_preset_crc16_xmodem, /*!< Poly: 0x1021, Init: 0x0000, Refin: False, Refout: False, Xorout: 0x0000 */ crc_preset_crc16_modbus, /*!< Poly: 0x8005, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0x0000 */ crc_preset_crc16_dnp, /*!< Poly: 0x3D65, Init: 0x0000, Refin: True, Refout: True, Xorout: 0xFFFF */ crc_preset_crc16_x25, /*!< Poly: 0x1021, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0xFFFF */ crc_preset_crc16_usb, /*!< Poly: 0x8005, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0xFFFF */ crc_preset_crc16_maxim, /*!< Poly: 0x8005, Init: 0x0000, Refin: True, Refout: True, Xorout: 0xFFFF */ crc_preset_crc16_ibm, /*!< Poly: 0x8005, Init: 0x0000, Refin: True, Refout: True, Xorout: 0x0000 */ crc_preset_crc8_maxim, /*!< Poly: 0x31, Init: 0x00, Refin: True, Refout: True, Xorout: 0x00 */ crc_preset_crc8_rohc, /*!< Poly: 0x07, Init: 0xFF, Refin: True, Refout: True, Xorout: 0x00 */ crc_preset_crc8_itu, /*!< Poly: 0x07, Init: 0x00, Refin: False, Refout: False, Xorout: 0x55 */ crc_preset_crc8, /*!< Poly: 0x07, Init: 0x00, Refin: False, Refout: False, Xorout: 0x00 */ crc_preset_crc5_usb, /*!< Poly: 0x05, Init: 0x1F, Refin: True, Refout: True, Xorout: 0x1F */ } crc_preset_t; /** * @brief CRC Refin definitions. */ typedef enum crc_refin_enum { crc_refin_false = 0, /*!< Do not manipulate input data stream. */ crc_refin_true = 1, /*!< Reflect each byte in the input stream bitwise. */ } crc_refin_t; /** * @brief CRC Refout definitions. */ typedef enum crc_refout_enum { crc_refout_false = 0, /*!< Do not manipulate output data stream. */ crc_refout_true = 1, /*!< Reflect each byte in the output stream bitwise. */ } crc_refout_t; /** * @brief crc input data stream byte order definitions. */ typedef enum crc_in_byte_order_enum { crc_in_byte_order_lsb = 0, /*!< Byte order of the CRC DATA LS Byte first. */ crc_in_byte_order_msb = 1, /*!< Byte order of the CRC DATA MS Byte first. */ } crc_in_byte_order_t; #define CRC_POLY_WIDTH_4 (4U) #define CRC_POLY_WIDTH_5 (5U) #define CRC_POLY_WIDTH_6 (6U) #define CRC_POLY_WIDTH_7 (7U) #define CRC_POLY_WIDTH_8 (8U) #define CRC_POLY_WIDTH_16 (16U) #define CRC_POLY_WIDTH_24 (24U) #define CRC_POLY_WIDTH_32 (32U) /** * @brief Channel config */ typedef struct crc_channel_config { crc_preset_t preset; /*!< Preset CRC. See "crc_preset_t". */ uint32_t init; /*!< Initial value for CRC. */ uint32_t poly; /*!< Poly for CRC. */ uint32_t poly_width; /*!< CRC poly width. See "CRC_POLY_WIDTH_x". */ crc_in_byte_order_t in_byte_order; /*!< CRC intput byte order. See "crc_in_byte_order_t". */ crc_refout_t refout; /*!< CRC reflect output. See "crc_refout_t". */ crc_refin_t refin; /*!< CRC reflect iutput. See "crc_refin_t". */ uint32_t xorout; /*!< XOR mask for CRC result (for no mask, should be 0). */ } crc_channel_config_t; #define CRC_REG_WRITE8(addr, data)\ {\ uint32_t addr32 = (uint32_t)(addr);\ (*(volatile uint8_t *)(addr32) = (data));\ } #define CRC_REG_WRITE16(addr, data)\ {\ uint32_t addr32 = (uint32_t)(addr);\ (*(volatile uint16_t *)(addr32) = (data));\ } #define CRC_REG_WRITE32(addr, data)\ {\ uint32_t addr32 = (uint32_t)(addr);\ (*(volatile uint32_t *)(addr32) = (data));\ } #ifdef __cplusplus extern "C" { #endif /** * @brief Get default channel config * * @param[in] cfg Channel config */ void crc_get_default_channel_config(crc_channel_config_t *cfg); /** * @brief Setup CRC channel * * @param[in] ptr CRC base address * @param[in] ch_index Target channel index to be configured * @param[in] cfg Channel config * * @return status_success if everything is okay */ hpm_stat_t crc_setup_channel_config(CRC_Type *ptr, uint32_t ch_index, crc_channel_config_t *cfg); /** * @brief Calculate one byte data crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] data Data that to be calculate */ static inline void crc_calc_byte(CRC_Type *ptr, uint32_t ch_index, uint8_t data) { CRC_REG_WRITE8(&ptr->CHN[ch_index].DATA, data); } /** * @brief Calculate length bytes data block crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] pbuffer Data to be calculate buffer * @param[in] length Number of pbuffer, unit is byte */ void crc_calc_block_bytes(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length); /** * @brief Calculate half-word data crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] data Data that to be calculate */ static inline void crc_calc_half_word(CRC_Type *ptr, uint32_t ch_index, uint16_t data) { CRC_REG_WRITE16(&ptr->CHN[ch_index].DATA, data); } /** * @brief Calculate length half-words data block crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] pbuffer Data to be calculate buffer * @param[in] length Number of pbuffer, unit is half word(2 bytes) */ void crc_calc_block_half_words(CRC_Type *ptr, uint32_t ch_index, uint16_t *pbuffer, uint32_t length); /** * @brief Calculate word data crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] data Data that to be calculate */ static inline void crc_calc_word(CRC_Type *ptr, uint32_t ch_index, uint32_t data) { CRC_REG_WRITE32(&ptr->CHN[ch_index].DATA, data); } /** * @brief Calculate length words data block crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] pbuffer Data to be calculate buffer * @param[in] length Number of pbuffer, unit is word(4 bytes) */ void crc_calc_block_words(CRC_Type *ptr, uint32_t ch_index, uint32_t *pbuffer, uint32_t length); /** * @brief Fast calculate length bytes large data block crc * * @param[in] ptr CRC base address * @param[in] ch_index CRC channel index * @param[in] pbuffer Data to be calculate buffer * @param[in] length Number of pbuffer, unit is byte */ void crc_calc_large_block_fast(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length); /** * @brief Get CRC result * * @param[in] ptr CRC base address * @param[in] ch_index Index of the channel to be get * @return CRC result */ static inline uint32_t crc_get_result(CRC_Type *ptr, uint32_t ch_index) { return ptr->CHN[ch_index].RESULT; } #ifdef __cplusplus } #endif /** * @} */ #endif /* HPM_CRC_DRV_H */