/**
******************************************************************************
* @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
******************************************************************************/