/** ****************************************************************************** * @file xl_crc.c * @author xu.wang * @version 4.5.2 * @date Fri Mar 26 17:29:12 2021 * @brief This file provide function about CRC firmware program ****************************************************************************** * @attention * * 2019 by Chipways Communications,Inc. All Rights Reserved. * This software is supplied under the terms of a license * agreement or non-disclosure agreement with Chipways. * Passing on and copying of this document,and communication * of its contents is not permitted without prior written * authorization. * *

© COPYRIGHT 2019 Chipways

****************************************************************************** */ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /* Includes ---------------------------------------------------------------*/ #include "xl_crc.h" /** @addtogroup XL6600_StdPeriph_Driver * @{ */ /** @defgroup CRC CRC Module * @brief CRC Driver Modules Library * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** @defgroup CRC_Private_Functions * @{ */ /** * @brief CRC»Ö¸´³õʼ״̬ * @return ·µ»ØÖ´ÐÐ״̬. */ void CRC_Deinit(void) { /* De-initialize the PMC module return to the default state. */ CRC->CTRL = 0x00000000u; CRC->GPOLY = 0x00000000u; CRC->INIT = 0xFFFFFFFFu; } /** * @brief CRC³õʼ»¯ * @param CRC_InitStruct: CRC³õʼ»¯ÅäÖýṹÌå * @retval None */ void CRC_Init(const CRC_InitTypeDef *CRC_InitStruct) { uint32_t tmpreg; /* configure the register. */ /* Get the CTRL Register. */ tmpreg = CRC->CTRL; /* clear the CTRL bit*/ tmpreg &= ~(CRC_CTRL_TOT_MASK | CRC_CTRL_TCRC_MASK | CRC_CTRL_T16_MASK | CRC_CTRL_INV_MASK); /* set CRC control register */ tmpreg |= ((((uint32_t)CRC_InitStruct->CRC_WriteTranspose << CRC_CTRL_TOT_SHIFT) & CRC_CTRL_TOT_MASK) |\ (((uint32_t)CRC_InitStruct->CRC_DataWidth << CRC_CTRL_TCRC_SHIFT) & CRC_CTRL_TCRC_MASK)|\ (((uint32_t)CRC_InitStruct->CRC_Transpose16Only << CRC_CTRL_T16_SHIFT) & CRC_CTRL_T16_MASK) |\ (((uint32_t)CRC_InitStruct->CRC_DataOutInvert << CRC_CTRL_INV_SHIFT) & CRC_CTRL_INV_MASK)); /* Write to CRC CTRL */ CRC->CTRL = tmpreg ; if(CRC_InitStruct->CRC_DataWidth == CRC_Width32Bits) { /* set 32-bit CRC Polynomial register */ CRC->GPOLY = (uint32_t)(CRC_InitStruct->CRC_PolyData); } else { /* set 16-bit CRC Polynomial register */ CRC->GPOLY=(uint16_t)(CRC_InitStruct->CRC_PolyData); } } /** * @brief CRC 16λ켯Ëã. * @param InitValue: ³õʼֵ * @param *msg: ¼ÆËãµÄÊý¾Ý * @param SizeBytes: ¼ÆËãµÄ³¤¶È * @return ·µ»ØCRC16λÊý¾Ý¼ÆËã½á¹û. */ uint16_t CRC_Cal16(uint32_t InitValue, const uint8_t *msg, uint32_t SizeBytes) { uint16_t data_out; uint32_t i; /* init value set */ CRC->INIT = InitValue; CRC->CTRL |= CRC_CTRL_INIT_MASK; /* Wait for calculation completion */ for(i=0; iDATAIN = msg[i]; CRC->CTRL |= CRC_CTRL_CALC_MASK; } if((CRC->CTRL & CRC_CTRL_T16_MASK) == CRC_CTRL_T16_MASK) { /* read DATAOUT low 16 bits */ data_out=(uint16_t)(CRC->DATAOUT); } else if((CRC->CTRL & 0x00000100u) != 0x00000100u) { /* read DATAOUT low 16 bits */ data_out=(uint16_t)(CRC->DATAOUT); } else { /* read DATAOUT high 16 bits */ data_out=(uint16_t)(CRC->DATAOUT >> 16u); } return(data_out); } /** * @brief CRC 16λģ¿ìËÙ¼ÆËã. * @param InitValue: ³õʼֵ * @param *msg: ¼ÆËãµÄÊý¾Ý * @param SizeBytes: ¼ÆËãµÄ³¤¶È * @return ·µ»ØCRC16λÊý¾Ý¼ÆËã½á¹û. */ uint16_t CRC_Cal16_Fast(uint32_t InitValue, const uint8_t *msg, uint32_t SizeBytes) { uint16_t data_out; uint32_t i; uint32_t temp; uint16_t integer4=0; uint16_t integer8=0; uint16_t integer16=0; uint16_t integer32=0; uint16_t integer4_1=0; uint16_t integer8_1=0; uint16_t integer16_1=0; uint16_t integer32_1=0; uint8_t remainder32=0; temp = CRC->CTRL; temp |= CRC_CTRL_INIT_MASK; /* init value set */ CRC->INIT = InitValue; CRC->CTRL |= CRC_CTRL_INIT_MASK; integer32 = SizeBytes>>5; integer32_1 = integer32<<5; remainder32 = SizeBytes-integer32_1; integer16 = remainder32>>4; integer16_1 = integer16<<4; remainder32 = remainder32-integer16_1; integer8 = remainder32>>3; integer8_1 = integer8<<3; remainder32 = remainder32-integer8_1; integer4 = remainder32>>2; integer4_1 = integer4<<2; remainder32 = integer32_1 + integer16_1 + integer8_1 + integer4_1; temp = CRC->CTRL; temp |= CRC_CTRL_CALC_MASK; for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=remainder32;iDATAIN = msg[i++]; CRC->CTRL = temp; } if((CRC->CTRL & CRC_CTRL_T16_MASK) == CRC_CTRL_T16_MASK) { /* read DATAOUT low 16 bits */ data_out=(uint16_t)(CRC->DATAOUT); } else if((CRC->CTRL & 0x00000100u) != 0x00000100u) { /* read DATAOUT low 16 bits */ data_out=(uint16_t)(CRC->DATAOUT); } else { /* read DATAOUT high 16 bits */ data_out=(uint16_t)(CRC->DATAOUT >> 16u); } return(data_out); } /** * @brief CRC 32λ켯Ëã. * @param InitValue: ³õʼֵ * @param *msg: ¼ÆËãµÄÊý¾Ý * @param SizeBytes: ¼ÆËãµÄ³¤¶È * @return ·µ»ØCRC32λÊý¾Ý¼ÆËã½á¹û. */ uint32_t CRC_Cal32(uint32_t InitValue, const uint8_t *msg, uint32_t SizeBytes) { uint32_t data_out; uint32_t i; /* init value set */ CRC->INIT = InitValue; CRC->CTRL |= CRC_CTRL_INIT_MASK; /*Wait for calculation completion*/ for(i=0; iDATAIN = msg[i]; CRC->CTRL |= CRC_CTRL_CALC_MASK; } data_out=CRC->DATAOUT; return(data_out); } /** * @brief CRC 32λģ¿ìËÙ¼ÆËã. * @param InitValue: ³õʼֵ * @param *msg: ¼ÆËãµÄÊý¾Ý * @param SizeBytes: ¼ÆËãµÄ³¤¶È * @return ·µ»ØCRC32λÊý¾Ý¼ÆËã½á¹û. */ uint32_t CRC_Cal32Fast(uint32_t InitValue, const uint8_t *msg, uint32_t SizeBytes) { uint32_t data_out; uint32_t i; uint32_t temp; uint16_t integer4=0; uint16_t integer8=0; uint16_t integer16=0; uint16_t integer32=0; uint16_t integer4_1=0; uint16_t integer8_1=0; uint16_t integer16_1=0; uint16_t integer32_1=0; uint8_t remainder32=0; /* init value set */ CRC->INIT = InitValue; CRC->CTRL |= CRC_CTRL_INIT_MASK; integer32 = SizeBytes>>5; integer32_1 = integer32<<5; remainder32 = SizeBytes-integer32_1; integer16 = remainder32>>4; integer16_1 = integer16<<4; remainder32 = remainder32-integer16_1; integer8 = remainder32>>3; integer8_1 = integer8<<3; remainder32 = remainder32-integer8_1; integer4 = remainder32>>2; integer4_1 = integer4<<2; remainder32 = integer32_1 + integer16_1 + integer8_1 + integer4_1; temp = CRC->CTRL; temp |= CRC_CTRL_CALC_MASK; for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=0;iDATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; CRC->DATAIN = msg[i++]; CRC->CTRL = temp; } for(i=remainder32;iDATAIN = msg[i++]; CRC->CTRL = temp; } data_out=CRC->DATAOUT; return(data_out); } /** * @} */ /** * @} */ /** * @} */ #ifdef __cplusplus } #endif /* __cplusplus */ /******************************************************************************* * EOF ******************************************************************************/