1 /***************************************************************************//**
\r
3 * @brief Cyclic Redundancy Check (CRC) API.
\r
5 *******************************************************************************
\r
7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
\r
8 *******************************************************************************
\r
10 * Permission is granted to anyone to use this software for any purpose,
\r
11 * including commercial applications, and to alter it and redistribute it
\r
12 * freely, subject to the following restrictions:
\r
14 * 1. The origin of this software must not be misrepresented; you must not
\r
15 * claim that you wrote the original software.
\r
16 * 2. Altered source versions must be plainly marked as such, and must not be
\r
17 * misrepresented as being the original software.
\r
18 * 3. This notice may not be removed or altered from any source distribution.
\r
20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
\r
21 * obligation to support this Software. Silicon Labs is providing the
\r
22 * Software "AS IS", with no express or implied warranties of any kind,
\r
23 * including, but not limited to, any implied warranties of merchantability
\r
24 * or fitness for any particular purpose or warranties against infringement
\r
25 * of any proprietary rights of a third party.
\r
27 * Silicon Labs will not be liable for any consequential, incidental, or
\r
28 * special damages, or any other relief, or for any claim by any third party,
\r
29 * arising from your use of this Software.
\r
31 ******************************************************************************/
\r
33 #ifndef __SILICON_LABS_EM_CRC_H__
\r
34 #define __SILICON_LABS_EM_CRC_H__
\r
36 #include "em_device.h"
\r
37 #if defined(CRC_COUNT) && (CRC_COUNT > 0)
\r
40 #include <stdbool.h>
\r
46 /***************************************************************************//**
\r
47 * @addtogroup EM_Library
\r
49 ******************************************************************************/
\r
51 /***************************************************************************//**
\r
54 ******************************************************************************/
\r
56 /*******************************************************************************
\r
57 ******************************** ENUMS ************************************
\r
58 ******************************************************************************/
\r
60 /** CRC width values. */
\r
63 /** 8 bit (1 byte) CRC code. */
\r
64 crcWidth8 = CRC_CTRL_CRCWIDTH_CRCWIDTH8,
\r
66 /** 16 bit (2 byte) CRC code. */
\r
67 crcWidth16 = CRC_CTRL_CRCWIDTH_CRCWIDTH16,
\r
69 /** 24 bit (3 byte) CRC code. */
\r
70 crcWidth24 = CRC_CTRL_CRCWIDTH_CRCWIDTH24,
\r
72 /** 32 bit (4 byte) CRC code. */
\r
73 crcWidth32 = CRC_CTRL_CRCWIDTH_CRCWIDTH32
\r
74 } CRC_Width_TypeDef;
\r
77 /** CRC byte reverse values. */
\r
80 /** Most significant CRC bytes are transferred first over air via the Frame
\r
81 * Controller (FRC). */
\r
82 crcByteOrderNormal = CRC_CTRL_BYTEREVERSE_NORMAL,
\r
84 /** Least significant CRC bytes are transferred first over air via the Frame
\r
85 * Controller (FRC). */
\r
86 crcByteOrderReversed = CRC_CTRL_BYTEREVERSE_REVERSED
\r
87 } CRC_ByteOrder_TypeDef;
\r
90 /** CRC bit order values. */
\r
93 /** Least significant data bit (LSB) is fed first to the CRC generator. */
\r
94 crcBitOrderLSBFirst = CRC_CTRL_INPUTBITORDER_LSBFIRST,
\r
96 /** Most significant data bit (MSB) is fed first to the CRC generator. */
\r
97 crcBitOrderMSBFirst = CRC_CTRL_INPUTBITORDER_MSBFIRST
\r
98 } CRC_BitOrder_TypeDef;
\r
101 /** CRC bit reverse values. */
\r
104 /** The bit ordering of CRC data is the same as defined by the BITORDER field
\r
105 * in the Frame Controller. */
\r
106 crcBitReverseNormal = CRC_CTRL_BITREVERSE_NORMAL,
\r
108 /** The bit ordering of CRC data is the opposite as defined by the BITORDER
\r
109 * field in the Frame Controller. */
\r
110 crcBitReverseReversed = CRC_CTRL_BITREVERSE_REVERSED
\r
111 } CRC_BitReverse_TypeDef;
\r
114 /*******************************************************************************
\r
115 ******************************* STRUCTS ***********************************
\r
116 ******************************************************************************/
\r
118 /** CRC initialization structure. */
\r
121 /** Width of the CRC code. */
\r
122 CRC_Width_TypeDef crcWidth;
\r
124 /** CRC polynomial value. This value defines POLY[31:0], which is used as the
\r
125 * polynomial (in reversed order) during the CRC calculation. If the CRC
\r
126 * width is less than 32 bits, the most significant part of this register
\r
128 * - Set the bit to 1 in the register to get the corresponding degree term
\r
129 * appear in the polynomial with a coefficient of 1.
\r
130 * - Set the bit to 0 in the register to get the corresponding degree term
\r
131 * appear in the polynomial with a coefficient of 0.
\r
132 * Note: If a CRC polynomial of size less than 32 bits is to be used, the
\r
133 * polynomial value must be shifted so that the highest degree term is
\r
134 * located in DATA[0]!
\r
135 * Please refer to the CRC sub-chapter "CRC Polynomial" in the documentation
\r
136 * for more details! */
\r
139 /** CRC initialization value. Loaded into the CRC_DATA register upon issuing
\r
140 * the INIT command by calling CRC_InitCommand(), or when the Frame
\r
141 * Controller (FRC) uses the CRC for automatic CRC calculation and
\r
143 uint32_t initValue;
\r
145 /** Number of bits per input word. This value defines the number of valid
\r
146 * input bits in the CRC_INPUTDATA register, or in data coming from the Frame
\r
147 * Controller (FRC). The number of bits in each word equals to
\r
148 * (BITSPERWORD + EXTRABITSPERWORD + 1), where EXTRABITSPERWORD is taken from
\r
149 * the currently active Frame Control Descriptor (FCD). */
\r
150 uint8_t bitsPerWord;
\r
152 /** If true, the byte order is reversed and the least significant CRC bytes
\r
153 * are transferred first over the air. (description TBD) */
\r
154 CRC_ByteOrder_TypeDef byteReverse;
\r
156 /** Bit order. Defines the order in which bits are fed to the CRC generator.
\r
157 * This setting applies both to data written to the CRC_INPUTDATA register,
\r
158 * and data coming from the Frame Controller (FRC). */
\r
159 CRC_BitOrder_TypeDef inputBitOrder;
\r
161 /** Output bit reverse. In most cases, the bit ordering of the CRC value
\r
162 * corresponds to the bit ordering of other data transmitted over air. When
\r
163 * set, the BITREVERSE field has the possibility to reverse this bit ordering
\r
164 * to comply with some protocols. Note that this field does not affect the
\r
165 * way the CRC value is calculated, only how it is transmitted over air. */
\r
166 CRC_BitReverse_TypeDef bitReverse;
\r
168 /** Enable/disable CRC input data padding. When set, CRC input data is zero-
\r
169 * padded, such that the number of bytes over which the CRC value is
\r
170 * calculated at least equals the length of the calculated CRC value. If not
\r
171 * set, no zero-padding of CRC input data is applied. */
\r
174 /** If true, CRC input is inverted. */
\r
177 /** If true, CRC output to the Frame Controller (FRC) is inverted. */
\r
179 } CRC_Init_TypeDef;
\r
181 /** Default configuration for CRC_Init_TypeDef structure. */
\r
182 #define CRC_INIT_DEFAULT \
\r
184 crcWidth16, /* CRC width is 16 bits. */ \
\r
185 0x00008408UL, /* Polynomial value of IEEE 802.15.4-2006. */ \
\r
186 0x00000000UL, /* Initialization value. */ \
\r
187 8U, /* 8 bits per word. */ \
\r
188 crcByteOrderNormal, /* Byte order is normal. */ \
\r
189 crcBitOrderLSBFirst, /* Bit order (TBD). */ \
\r
190 crcBitReverseNormal, /* Bit order is not reversed on output. */ \
\r
191 false, /* No zero-padding. */ \
\r
192 false, /* Input is not inverted. */ \
\r
193 false /* Output is not inverted. */ \
\r
197 /*******************************************************************************
\r
198 ****************************** PROTOTYPES *********************************
\r
199 ******************************************************************************/
\r
201 void CRC_Init(CRC_Init_TypeDef const *init);
\r
202 void CRC_Reset(void);
\r
204 /***************************************************************************//**
\r
206 * Issues a command to initialize the CRC calculation.
\r
209 * This function issues the command INITIALIZE in CRC_CMD that initializes the
\r
210 * CRC calculation by writing the initial values to the DATA register.
\r
214 * Initialize in CRC_CMD
\r
215 * Conclude on reference of parameters. Register names or config struct members?
\r
216 ******************************************************************************/
\r
217 __STATIC_INLINE void CRC_InitCommand(void)
\r
219 CRC->CMD = CRC_CMD_INITIALIZE;
\r
223 /***************************************************************************//**
\r
225 * Set the initialization value of the CRC.
\r
226 ******************************************************************************/
\r
227 __STATIC_INLINE void CRC_InitValueSet(uint32_t initValue)
\r
229 CRC->INIT = initValue;
\r
233 /***************************************************************************//**
\r
235 * Writes data to the input data register of the CRC.
\r
238 * Use this function to write input data to the CRC when the FRC is not being
\r
239 * used for automatic handling of the CRC. The CRC calculation is based on
\r
240 * the provided input data using the configured CRC polynomial.
\r
243 * Data to be written to the input data register.
\r
244 ******************************************************************************/
\r
245 __STATIC_INLINE void CRC_InputDataWrite(uint16_t data)
\r
247 CRC->INPUTDATA = (uint32_t)data;
\r
251 /***************************************************************************//**
\r
253 * Reads the data register of the CRC.
\r
256 * Use this function to read the calculated CRC value.
\r
259 * Content of the CRC data register.
\r
260 ******************************************************************************/
\r
261 __STATIC_INLINE uint32_t CRC_DataRead(void)
\r
267 /***************************************************************************//**
\r
269 * Gets if the CRC is busy.
\r
272 * Returns true when the CRC module is busy, false otherwise.
\r
276 * @li true - CRC module is busy.
\r
277 * @li false - CRC module is not busy.
\r
278 ******************************************************************************/
\r
279 __STATIC_INLINE bool CRC_BusyGet(void)
\r
281 return (bool)((CRC->STATUS & _CRC_STATUS_BUSY_MASK)
\r
282 >> _CRC_STATUS_BUSY_SHIFT);
\r
286 /** @} (end addtogroup CRC) */
\r
287 /** @} (end addtogroup EM_Library) */
\r
293 #endif /* defined(CRC_COUNT) && (CRC_COUNT > 0) */
\r
294 #endif /* __SILICON_LABS_EM_CRC_H__ */
\r