CRC.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*!*****************************************************************************
34  * @file CRC.h
35  * @brief CRC driver interface
36  *
37  * @anchor ti_drivers_CRC_Overview
38  * # Overview #
39  *
40  * The CRC driver interface provides device independent APIs, data types,
41  * and macros. The CRC header file should be included in an application as
42  * follows:
43  * @code
44  * #include <ti/drivers/CRC.h>
45  * @endcode
46  *
47  * The Cyclic Redundancy Check (CRC) driver is a generic driver that supports
48  * calculating a variety of standard CRC codes on blocks of input data.
49  *
50  * <hr>
51  * @anchor ti_drivers_CRC_Usage
52  * # Usage #
53  * To calculate the CRC of a block of available data, an application should call:
54  * - CRC_init(): Initialize the CRC driver.
55  * - CRC_Params_init(): Initialize a default #CRC_Params structure.
56  * - CRC_open(): Open an instance of the CRC driver, passing the
57  * initialized parameters, or NULL, and an index (described later).
58  * - CRC_calculateFull(): Calculate the CRC of a data block.
59  * - CRC_close(): De-initialize the CRC instance.
60  *
61  * If the data is only available in noncontiguous memory or is being made
62  * available in blocks (e.g. over UART) then the addData and finalise methods
63  * may be used to calculate the CRC of individual blocks.
64  *
65  * The CRC driver only accepts data lengths that are a multiple of the CRC size.
66  * If asked to CRC 7 bytes with a 4-byte CRC, it will throw an error. Similarly,
67  * if padding bytes are required for a particular application this must be handled
68  * by the caller.
69  *
70  * @anchor ti_drivers_CRC_Synopsis
71  * ## Synopsis
72  * @anchor ti_drivers_CRC_Synopsis_Code
73  * @code
74  * CRC_Handle handle;
75  * CRC_Params params;
76  * int_fast16_t status;
77  * uint32_t result;
78  * uint8_t source[NUM_BYTES];
79  *
80  * CRC_init(); // Initialize the CRC driver
81  *
82  * CRC_Params_init(&params); // Initialize CRC parameters
83  * params.returnBehavior = CRC_RETURN_BEHAVIOR_BLOCKING;
84  *
85  * params.polynomial = CRC_POLYNOMIAL_CRC_16_CCITT;
86  * params.dataSize = CRC_DATA_SIZE_32BIT;
87  * params.seed = 0xFFFF;
88  * params.byteSwapInput = CRC_BYTESWAP_UNCHANGED;
89  *
90  * handle = CRC_open(CONFIG_CRC0, &params);
91  * if (handle == NULL) {
92  * while (1); // CRC_open() failed
93  * }
94  *
95  * // Fill in source
96  *
97  * status = CRC_calculateFull(handle, source, NUM_BYTES, &result);
98  *
99  * if (status != CRC_STATUS_SUCCESS) {
100  * // Error with parameters, or CRC resource was unavailable
101  * while (1);
102  * }
103  * @endcode
104  *
105  * More details on usage are provided in the following sections.
106  *
107  * <hr>
108  * @anchor ti_drivers_CRC_Examples
109  * # Examples
110  *
111  * @li @ref ti_drivers_CRC_Examples_open "Opening a CRC instance"
112  * @li @ref ti_drivers_CRC_Examples_calculateFull "Calculating a full check value"
113  * @li @ref ti_drivers_CRC_Examples_calculatePartial "Partial check calculations"
114  *
115  * @anchor ti_drivers_CRC_Examples_open
116  * ## Opening a CRC instance
117  * After initializing the CRC driver by calling CRC_init(), the application
118  * can open a CRC instance by calling CRC_open(). This function
119  * takes an index into the CRC_config[] array, and a CRC parameters data
120  * structure. The CRC instance is specified by the index of the CRC in
121  * CRC_config[]. Only one CRC index can be used at a time;
122  * calling CRC_open() a second time with the same index previously
123  * passed to CRC_open() will result in an error. You can,
124  * though, re-use the index if the instance is closed via CRC_close().
125  *
126  * If no CRC_Params structure is passed to CRC_open(), default values are
127  * used. If the open call is successful, it returns a non-NULL value.
128  *
129  * @code
130  * CRC_Handle handle;
131  * CRC_Params params;
132  *
133  * // Initialize the CRC driver
134  * CRC_init();
135  *
136  * // Initialize optional CRC parameters for CALLBACK mode
137  * CRC_Params_init(&params);
138  * params.returnBehavior = CRC_RETURN_BEHAVIOR_CALLBACK;
139  * params.callbackFxn = myCallbackFunction;
140  *
141  * handle = CRC_open(CONFIG_CRC0, &params);
142  * if (handle == NULL) {
143  * // CRC_open() failed
144  * while (1);
145  * }
146  * @endcode
147  *
148  * @anchor ti_drivers_CRC_Examples_calculateFull
149  * ## Using the calculateFull API
150  *
151  * ### CRC-8-CCITT without data processing
152  * An 8-bit CRC with no data processing options. Note that the
153  * default POLLING mode uses the CPU to move data so will not
154  * allow the device to enter standby in low-power applications.
155  *
156  * @code
157  * CRC_Handle handle;
158  * int_fast16_t status;
159  * uint8_t source[NUM_BYTES];
160  * uint8_t result;
161  *
162  * // Initialize the CRC driver
163  * CRC_init();
164  *
165  * // The defaults are set to a POLLING mode 8-bit CRC with seed 0xFF
166  * // We can pass NULL instead of a Params struct to make use of this
167  * handle = CRC_open(CONFIG_CRC0, NULL);
168  *
169  * if (handle == NULL) {
170  * while (1); // CRC_open() failed
171  * }
172  *
173  * status = CRC_calculateFull(handle, source, NUM_BYTES, &result);
174  *
175  * if (status != CRC_STATUS_SUCCESS) {
176  * // Error with parameters, or CRC resource was unavailable
177  * while (1);
178  * }
179  * @endcode
180  *
181  * ### CRC-32-IEEE with endianness reversal
182  * A 32-bit CRC with data processing options, in BLOCKING mode.
183  *
184  * @code
185  * CRC_Handle handle;
186  * CRC_Params params;
187  * int_fast16_t status;
188  * uint32_t result;
189  * uint8_t source[NUM_BYTES];
190  *
191  * CRC_init(); // Initialize the CRC driver
192  *
193  * CRC_Params_init(&params); // Initialize CRC parameters
194  * params.returnBehavior = CRC_RETURN_BEHAVIOR_BLOCKING;
195  *
196  * params.byteSwapInput = CRC_BYTESWAP_BYTES_AND_HALF_WORDS;
197  * params.polynomial = CRC_POLYNOMIAL_CRC_32_IEEE;
198  * params.dataSize = CRC_DATA_SIZE_32BIT;
199  * params.seed = 0xFFFFFFFF;
200  *
201  * handle = CRC_open(CONFIG_CRC0, &params);
202  *
203  * if (handle == NULL) {
204  * while (1); // CRC_open() failed
205  * }
206  *
207  * // Obtain data for the source buffer
208  *
209  * status = CRC_calculateFull(handle, source, NUM_BYTES, &result);
210  *
211  * if (status != CRC_STATUS_SUCCESS) {
212  * // Error with parameters, or CRC resource was unavailable
213  * while (1);
214  * }
215  * @endcode
216  *
217  * @anchor ti_drivers_CRC_Examples_calculatePartial
218  * ## Using the addData API
219  *
220  * It may be desirable to use the CRC to calculate over blocks of data that
221  * are available at different times or non-contiguous in memory. A
222  * block-by-block API is available to do this. The following code calculates
223  * the CRC of two separate arrays as though they were concatenated.
224  *
225  * @code
226  * CRC_Handle handle;
227  * CRC_Params params;
228  * int_fast16_t status;
229  * uint32_t result;
230  *
231  * uint32_t sourceA [NUM_BYTES] = { ... };
232  * uint32_t sourceB [NUM_BYTES] = { ... };
233  *
234  * CRC_init();
235  * CRC_Params_init(&params);
236  *
237  * params.byteSwapInput = CRC_BYTESWAP_UNCHANGED;
238  * params.polynomial = CRC_POLYNOMIAL_CRC_32C;
239  * params.dataSize = CRC_DATA_SIZE_32BIT;
240  * params.seed = 0xFFFFFFFF;
241  *
242  * handle = CRC_open(CONFIG_CRC0, &params);
243  *
244  * if (handle == NULL) {
245  * while (1); // CRC_open() failed
246  * }
247  *
248  * status = CRC_addData(handle, sourceA, NUM_BYTES);
249  *
250  * if (status != CRC_STATUS_SUCCESS) {
251  * // CRC resource was unavailable
252  * while (1);
253  * }
254  *
255  * status = CRC_addData(handle, sourceB, NUM_BYTES);
256  *
257  * if (status != CRC_STATUS_SUCCESS) {
258  * // CRC resource was unavailable
259  * while (1);
260  * }
261  *
262  * CRC_finalize(handle, &result);
263  * @endcode
264  *
265  *******************************************************************************
266  */
267 
268 #ifndef ti_drivers_CRC__include
269 #define ti_drivers_CRC__include
270 
271 #include <stddef.h>
272 #include <stdint.h>
273 #include <stdbool.h>
274 
275 #ifdef __cplusplus
276 extern "C" {
277 #endif
278 
279 #define CRC_STATUS_RESERVED (-32)
280 
282 #define CRC_STATUS_SUCCESS (0)
283 
285 #define CRC_STATUS_ERROR (-1)
286 
288 #define CRC_STATUS_RESOURCE_UNAVAILABLE (-2)
289 
291 #define CRC_STATUS_OPERATION_NOT_SUPPORTED (-3)
292 
294 #define CRC_STATUS_LEFTOVER_BYTES_PRESENT (-4)
295 
307 typedef struct {
308  void *object;
309  void const *hwAttrs;
310 } CRC_Config;
311 
316 
329 typedef enum {
341 
342 /* Not all polynomials are supported on all implementations; see the device specific
343  * header files for details. OPERATION_NOT_SUPPORTED will be returned if an
344  * unsupported polynomial is requested.
345  *
346  * Texas Instruments does not provide advice on polynomial suitability. The
347  * availability of polynomials in this driver or on a particular device does
348  * not imply fitness for any particular task. If highly reliable error
349  * detection capabilities are required, please consult a domain expert
350  * before choosing a polynomial.
351  */
352 typedef enum {
365 
369 
375 
384 typedef enum {
385  CRC_BYTESWAP_UNCHANGED, /* A B C D -> A B C D */
386  CRC_BYTESWAP_HALF_WORDS, /* A B C D -> C D A B */
387  CRC_BYTESWAP_BYTES_IN_HALF_WORDS, /* A B C D -> B A D C */
388  CRC_BYTESWAP_BYTES_AND_HALF_WORDS, /* A B C D -> D C B A */
389 } CRC_ByteSwap;
390 
395 typedef enum {
399 } CRC_DataSize;
400 
412 typedef void (*CRC_CallbackFxn) (CRC_Handle handle, int_fast16_t status, void *result);
413 
418 typedef struct {
426  uint32_t timeout;
428  void *custom;
429 
432  uint32_t seed;
435  CRC_Polynomial polynomial;
440 
443  CRC_DataSize dataSize;
446  CRC_ByteSwap byteSwapInput;
447 
455  uint32_t finalXorValue;
456 } CRC_Params;
457 
463 extern const CRC_Params CRC_defaultParams;
464 
473 extern void CRC_init(void);
474 
498 extern void CRC_Params_init(CRC_Params *params);
499 
518 extern CRC_Handle CRC_open(uint_least8_t index, const CRC_Params *params);
519 
542 extern int_fast16_t CRC_calculateFull(CRC_Handle handle, const void *source, size_t sourceBytes, void *result);
543 
567 extern int_fast16_t CRC_addData(CRC_Handle handle, const void *source, size_t sourceBytes);
568 
587 extern void CRC_finalize(CRC_Handle handle, void *result);
588 
600 extern void CRC_reset(CRC_Handle handle);
601 
611 extern void CRC_close(CRC_Handle handle);
612 
613 #ifdef __cplusplus
614 }
615 #endif
616 
617 #endif /* ti_drivers_CRC__include */
uint32_t seed
Definition: CRC.h:432
Definition: CRC.h:338
void CRC_finalize(CRC_Handle handle, void *result)
Completes the CRC calculation and places the final CRC into result.
int_fast16_t CRC_addData(CRC_Handle handle, const void *source, size_t sourceBytes)
Performs the CRC of the provided bytes. Waits for HW access.
Definition: CRC.h:335
Definition: CRC.h:397
CRC_Polynomial
Definition: CRC.h:352
Definition: CRC.h:396
uint32_t timeout
Definition: CRC.h:426
void CRC_Params_init(CRC_Params *params)
Function to initialize the CRC_Params struct to its defaults.
Definition: CRC.h:354
CRC_ReturnBehavior
The way in which CRC function calls return after completing.
Definition: CRC.h:329
Definition: CRC.h:360
void * custom
Definition: CRC.h:428
uint32_t finalXorValue
Definition: CRC.h:455
Definition: CRC.h:385
Definition: CRC.h:386
Definition: CRC.h:364
void CRC_init(void)
This function initializes the CRC module.
CRC_ByteSwap
These byte swapping configurations are primarily for dealing with endianness mismatch. Not all implementations support all configurations.
Definition: CRC.h:384
void CRC_close(CRC_Handle handle)
Function to close a CRC peripheral specified by the CRC handle.
uint8_t reverseInputBits
Definition: CRC.h:449
Definition: CRC.h:358
CRC_DataSize dataSize
Definition: CRC.h:443
CRC_Handle CRC_open(uint_least8_t index, const CRC_Params *params)
This function opens a given CRC peripheral.
CRC_DataSize
The CRC driver will consume data in blocks of this size. Not all implementations support all sizes...
Definition: CRC.h:395
void const * hwAttrs
Definition: CRC.h:309
CRC_Polynomial polynomial
Definition: CRC.h:435
Definition: CRC.h:368
void(* CRC_CallbackFxn)(CRC_Handle handle, int_fast16_t status, void *result)
The definition of a callback function used by the CRC driver when used in CALLBACK mode...
Definition: CRC.h:412
const CRC_Params CRC_defaultParams
Default CRC_Params structure.
Struct containing the parameters required for calculating the CRC of a data block. Default values can be set with CRC_Params_init.
Definition: CRC.h:418
CRC_ReturnBehavior returnBehavior
Definition: CRC.h:420
CRC_ByteSwap byteSwapInput
Definition: CRC.h:446
Definition: CRC.h:362
void CRC_reset(CRC_Handle handle)
Clears any intermediate results such that the next addData call will begin a new CRC.
int_fast16_t CRC_calculateFull(CRC_Handle handle, const void *source, size_t sourceBytes, void *result)
Performs the CRC of the provided bytes, placing the final CRC into result. Waits for HW access...
CRC_Config * CRC_Handle
A handle that is returned from an CRC_open() call.
Definition: CRC.h:315
uint32_t programmablePoly
Definition: CRC.h:437
Definition: CRC.h:356
uint8_t invertOutputBits
Definition: CRC.h:451
Definition: CRC.h:398
uint8_t reverseOutputBits
Definition: CRC.h:453
void * object
Definition: CRC.h:308
uint32_t programmablePolyOrder
Definition: CRC.h:439
Definition: CRC.h:330
CRC_CallbackFxn callbackFxn
Definition: CRC.h:422
CRC Global configuration.
Definition: CRC.h:307
© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale