2015-12-18 12:56:46 +01:00

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