mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
295 lines
11 KiB
C
295 lines
11 KiB
C
/***************************************************************************//**
|
|
* @file
|
|
* @brief Cyclic Redundancy Check (CRC) API.
|
|
* @version 4.2.1
|
|
*******************************************************************************
|
|
* @section License
|
|
* <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
|
|
*******************************************************************************
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
*
|
|
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
|
* obligation to support this Software. Silicon Labs is providing the
|
|
* Software "AS IS", with no express or implied warranties of any kind,
|
|
* including, but not limited to, any implied warranties of merchantability
|
|
* or fitness for any particular purpose or warranties against infringement
|
|
* of any proprietary rights of a third party.
|
|
*
|
|
* Silicon Labs will not be liable for any consequential, incidental, or
|
|
* special damages, or any other relief, or for any claim by any third party,
|
|
* arising from your use of this Software.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef __SILICON_LABS_EM_CRC_H__
|
|
#define __SILICON_LABS_EM_CRC_H__
|
|
|
|
#include "em_device.h"
|
|
#if defined(CRC_COUNT) && (CRC_COUNT > 0)
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/***************************************************************************//**
|
|
* @addtogroup EM_Library
|
|
* @{
|
|
******************************************************************************/
|
|
|
|
/***************************************************************************//**
|
|
* @addtogroup CRC
|
|
* @{
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
******************************** ENUMS ************************************
|
|
******************************************************************************/
|
|
|
|
/** CRC width values. */
|
|
typedef enum
|
|
{
|
|
/** 8 bit (1 byte) CRC code. */
|
|
crcWidth8 = CRC_CTRL_CRCWIDTH_CRCWIDTH8,
|
|
|
|
/** 16 bit (2 byte) CRC code. */
|
|
crcWidth16 = CRC_CTRL_CRCWIDTH_CRCWIDTH16,
|
|
|
|
/** 24 bit (3 byte) CRC code. */
|
|
crcWidth24 = CRC_CTRL_CRCWIDTH_CRCWIDTH24,
|
|
|
|
/** 32 bit (4 byte) CRC code. */
|
|
crcWidth32 = CRC_CTRL_CRCWIDTH_CRCWIDTH32
|
|
} CRC_Width_TypeDef;
|
|
|
|
|
|
/** CRC byte reverse values. */
|
|
typedef enum
|
|
{
|
|
/** Most significant CRC bytes are transferred first over air via the Frame
|
|
* Controller (FRC). */
|
|
crcByteOrderNormal = CRC_CTRL_BYTEREVERSE_NORMAL,
|
|
|
|
/** Least significant CRC bytes are transferred first over air via the Frame
|
|
* Controller (FRC). */
|
|
crcByteOrderReversed = CRC_CTRL_BYTEREVERSE_REVERSED
|
|
} CRC_ByteOrder_TypeDef;
|
|
|
|
|
|
/** CRC bit order values. */
|
|
typedef enum
|
|
{
|
|
/** Least significant data bit (LSB) is fed first to the CRC generator. */
|
|
crcBitOrderLSBFirst = CRC_CTRL_INPUTBITORDER_LSBFIRST,
|
|
|
|
/** Most significant data bit (MSB) is fed first to the CRC generator. */
|
|
crcBitOrderMSBFirst = CRC_CTRL_INPUTBITORDER_MSBFIRST
|
|
} CRC_BitOrder_TypeDef;
|
|
|
|
|
|
/** CRC bit reverse values. */
|
|
typedef enum
|
|
{
|
|
/** The bit ordering of CRC data is the same as defined by the BITORDER field
|
|
* in the Frame Controller. */
|
|
crcBitReverseNormal = CRC_CTRL_BITREVERSE_NORMAL,
|
|
|
|
/** The bit ordering of CRC data is the opposite as defined by the BITORDER
|
|
* field in the Frame Controller. */
|
|
crcBitReverseReversed = CRC_CTRL_BITREVERSE_REVERSED
|
|
} CRC_BitReverse_TypeDef;
|
|
|
|
|
|
/*******************************************************************************
|
|
******************************* STRUCTS ***********************************
|
|
******************************************************************************/
|
|
|
|
/** CRC initialization structure. */
|
|
typedef struct
|
|
{
|
|
/** Width of the CRC code. */
|
|
CRC_Width_TypeDef crcWidth;
|
|
|
|
/** CRC polynomial value. This value defines POLY[31:0], which is used as the
|
|
* polynomial (in reversed order) during the CRC calculation. If the CRC
|
|
* width is less than 32 bits, the most significant part of this register
|
|
* remains unused.
|
|
* - Set the bit to 1 in the register to get the corresponding degree term
|
|
* appear in the polynomial with a coefficient of 1.
|
|
* - Set the bit to 0 in the register to get the corresponding degree term
|
|
* appear in the polynomial with a coefficient of 0.
|
|
* Note: If a CRC polynomial of size less than 32 bits is to be used, the
|
|
* polynomial value must be shifted so that the highest degree term is
|
|
* located in DATA[0]!
|
|
* Please refer to the CRC sub-chapter "CRC Polynomial" in the documentation
|
|
* for more details! */
|
|
uint32_t crcPoly;
|
|
|
|
/** CRC initialization value. Loaded into the CRC_DATA register upon issuing
|
|
* the INIT command by calling CRC_InitCommand(), or when the Frame
|
|
* Controller (FRC) uses the CRC for automatic CRC calculation and
|
|
* verification. */
|
|
uint32_t initValue;
|
|
|
|
/** Number of bits per input word. This value defines the number of valid
|
|
* input bits in the CRC_INPUTDATA register, or in data coming from the Frame
|
|
* Controller (FRC). The number of bits in each word equals to
|
|
* (BITSPERWORD + EXTRABITSPERWORD + 1), where EXTRABITSPERWORD is taken from
|
|
* the currently active Frame Control Descriptor (FCD). */
|
|
uint8_t bitsPerWord;
|
|
|
|
/** If true, the byte order is reversed and the least significant CRC bytes
|
|
* are transferred first over the air. (description TBD) */
|
|
CRC_ByteOrder_TypeDef byteReverse;
|
|
|
|
/** Bit order. Defines the order in which bits are fed to the CRC generator.
|
|
* This setting applies both to data written to the CRC_INPUTDATA register,
|
|
* and data coming from the Frame Controller (FRC). */
|
|
CRC_BitOrder_TypeDef inputBitOrder;
|
|
|
|
/** Output bit reverse. In most cases, the bit ordering of the CRC value
|
|
* corresponds to the bit ordering of other data transmitted over air. When
|
|
* set, the BITREVERSE field has the possibility to reverse this bit ordering
|
|
* to comply with some protocols. Note that this field does not affect the
|
|
* way the CRC value is calculated, only how it is transmitted over air. */
|
|
CRC_BitReverse_TypeDef bitReverse;
|
|
|
|
/** Enable/disable CRC input data padding. When set, CRC input data is zero-
|
|
* padded, such that the number of bytes over which the CRC value is
|
|
* calculated at least equals the length of the calculated CRC value. If not
|
|
* set, no zero-padding of CRC input data is applied. */
|
|
bool inputPadding;
|
|
|
|
/** If true, CRC input is inverted. */
|
|
bool invInput;
|
|
|
|
/** If true, CRC output to the Frame Controller (FRC) is inverted. */
|
|
bool invOutput;
|
|
} CRC_Init_TypeDef;
|
|
|
|
/** Default configuration for CRC_Init_TypeDef structure. */
|
|
#define CRC_INIT_DEFAULT \
|
|
{ \
|
|
crcWidth16, /* CRC width is 16 bits. */ \
|
|
0x00008408UL, /* Polynomial value of IEEE 802.15.4-2006. */ \
|
|
0x00000000UL, /* Initialization value. */ \
|
|
8U, /* 8 bits per word. */ \
|
|
crcByteOrderNormal, /* Byte order is normal. */ \
|
|
crcBitOrderLSBFirst, /* Bit order (TBD). */ \
|
|
crcBitReverseNormal, /* Bit order is not reversed on output. */ \
|
|
false, /* No zero-padding. */ \
|
|
false, /* Input is not inverted. */ \
|
|
false /* Output is not inverted. */ \
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
****************************** PROTOTYPES *********************************
|
|
******************************************************************************/
|
|
|
|
void CRC_Init(CRC_Init_TypeDef const *init);
|
|
void CRC_Reset(void);
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Issues a command to initialize the CRC calculation.
|
|
*
|
|
* @details
|
|
* This function issues the command INITIALIZE in CRC_CMD that initializes the
|
|
* CRC calculation by writing the initial values to the DATA register.
|
|
*
|
|
* @note
|
|
* Internal notes:
|
|
* Initialize in CRC_CMD
|
|
* Conclude on reference of parameters. Register names or config struct members?
|
|
******************************************************************************/
|
|
__STATIC_INLINE void CRC_InitCommand(void)
|
|
{
|
|
CRC->CMD = CRC_CMD_INITIALIZE;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Set the initialization value of the CRC.
|
|
******************************************************************************/
|
|
__STATIC_INLINE void CRC_InitValueSet(uint32_t initValue)
|
|
{
|
|
CRC->INIT = initValue;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Writes data to the input data register of the CRC.
|
|
*
|
|
* @details
|
|
* Use this function to write input data to the CRC when the FRC is not being
|
|
* used for automatic handling of the CRC. The CRC calculation is based on
|
|
* the provided input data using the configured CRC polynomial.
|
|
*
|
|
* @param[in] data
|
|
* Data to be written to the input data register.
|
|
******************************************************************************/
|
|
__STATIC_INLINE void CRC_InputDataWrite(uint16_t data)
|
|
{
|
|
CRC->INPUTDATA = (uint32_t)data;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Reads the data register of the CRC.
|
|
*
|
|
* @details
|
|
* Use this function to read the calculated CRC value.
|
|
*
|
|
* @return
|
|
* Content of the CRC data register.
|
|
******************************************************************************/
|
|
__STATIC_INLINE uint32_t CRC_DataRead(void)
|
|
{
|
|
return CRC->DATA;
|
|
}
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief
|
|
* Gets if the CRC is busy.
|
|
*
|
|
* @details
|
|
* Returns true when the CRC module is busy, false otherwise.
|
|
*
|
|
* @return
|
|
* CRC busy flag.
|
|
* @li true - CRC module is busy.
|
|
* @li false - CRC module is not busy.
|
|
******************************************************************************/
|
|
__STATIC_INLINE bool CRC_BusyGet(void)
|
|
{
|
|
return (bool)((CRC->STATUS & _CRC_STATUS_BUSY_MASK)
|
|
>> _CRC_STATUS_BUSY_SHIFT);
|
|
}
|
|
|
|
|
|
/** @} (end addtogroup CRC) */
|
|
/** @} (end addtogroup EM_Library) */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* defined(CRC_COUNT) && (CRC_COUNT > 0) */
|
|
#endif /* __SILICON_LABS_EM_CRC_H__ */
|