1 /***************************************************************************//**
2 * \file cyhal_crc.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the CRC hardware accelerator.
6 * This interface abstracts out the chip specific details. If any chip specific
7 * functionality is necessary, or performance is critical the low level functions
8 * can be used directly.
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
13 * an affiliate of Cypress Semiconductor Corporation
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *******************************************************************************/
29 
30 /**
31 * \addtogroup group_hal_crc CRC (Cyclic Redundancy Check)
32 * \ingroup group_hal
33 * \{
34 * High level interface for interacting with the CRC, which provides hardware
35 * accelerated CRC computations.
36 * The CRC APIs are structured to enable usage in situations where the entire input data
37 * set is not available in memory at the same time. Therefore, each conversion consists of three steps:
38 * * A single call to \ref cyhal_crc_start, to initialize data structures used to compute CRC
39 * * One or more calls to \ref cyhal_crc_compute, to provide chunks of data
40 * * A single call to \ref cyhal_crc_finish, to finalize the computation and retrieve the result
41 *
42 * The table below provides CRC parameters for some common CRC algorithms.
43 * \note The Expected CRC column shows the computed CRC when the value "123456789" is passed to \ref cyhal_crc_compute.
44 *
45 * | CRC algorithm Name  | Len | Polynomial |Initial seed| Data REV | Data XOR | Rem REV | Remainder XOR | Expected CRC |
46 * | ------------------- | --- | ---------- |----------- | -------- | -------- | ------- | ------------- | ------------ |
47 * | CRC-6  / CDMA2000-A |  6  |    0x27    |    0x3F    |   false  |     0    |  false  |      0x00     |     0x0D     |
48 * | CRC-6  / CDMA2000-B |  6  |    0x07    |    0x3F    |   false  |     0    |  false  |      0x00     |     0x3B     |
49 * | CRC-6  / DARC       |  6  |    0x19    |    0x00    |   true   |     0    |  true   |      0x00     |     0x26     |
50 * | CRC-6  / ITU        |  6  |    0x03    |    0x00    |   true   |     0    |  true   |      0x00     |     0x06     |
51 * | CRC-8  / ITU        |  8  |    0x07    |    0x00    |   false  |     0    |  false  |      0x55     |     0xA1     |
52 * | CRC-8  / MAXIM      |  8  |    0x31    |    0x00    |   true   |     0    |  true   |      0x00     |     0xA1     |
53 * | CRC-8  / ROHC       |  8  |    0x07    |    0xFF    |   true   |     0    |  true   |      0x00     |     0xD0     |
54 * | CRC-8  / WCDMA      |  8  |    0x9B    |    0x00    |   true   |     0    |  true   |      0x00     |     0x25     |
55 * | CRC-16 / CCITT-0    | 16  |   0x1021   |   0xFFFF   |   false  |     0    |  false  |     0x0000    |    0x29B1    |
56 * | CRC-16 / CDMA2000   | 16  |   0xC867   |   0xFFFF   |   false  |     0    |  false  |     0x0000    |    0x4C06    |
57 * | CRC-32              | 32  | 0x04C11DB7 | 0xFFFFFFFF |   true   |     0    |  true   |   0xFFFFFFFF  |  0xCBF43926  |
58 * | CRC-32 / BZIP2      | 32  | 0x04C11DB7 | 0xFFFFFFFF |   false  |     0    |  false  |   0xFFFFFFFF  |  0xFC891918  |
59 *
60 * \note Algorithms that have less than 8 bits, like CRC-6, populate the lower bits and leave the high order bits 0.
61 *
62 * \note Many of the algorithm parameters can be customized.
63 *
64 * See \ref crc_algorithm_t and \ref subsection_crc_snippet_1 for more details.
65 *
66 * \section subsection_crc_quickstart Quick Start
67 *
68 * \ref cyhal_crc_init initializes the CRC generator and passes the pointer to the CRC block through the **obj** object of type \ref cyhal_crc_t.
69 *
70 * \subsection subsection_crc_snippet_1 Snippet1: CRC Generation
71 * The following snippet initializes a CRC generator and computes the CRC for a sample message.
72 *
73 * \snippet hal_crc.c snippet_cyhal_crc_simple_init
74 */
75 
76 #pragma once
77 
78 #include <stdint.h>
79 #include <stdbool.h>
80 #include "cy_result.h"
81 #include "cyhal_hw_types.h"
82 
83 #if defined(__cplusplus)
84 extern "C" {
85 #endif
86 
87 /** \addtogroup group_hal_results_crc CRC HAL Results
88  *  CRC specific return codes
89  *  \ingroup group_hal_results
90  *  \{ *//**
91  */
92 
93 /** Invalid argument */
94 #define CYHAL_CRC_RSLT_ERR_BAD_ARGUMENT                 \
95     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_CRC, 0))
96 
97 /**
98  * \}
99  */
100 
101 /** @brief CRC algorithm parameters */
102 typedef struct
103 {
104     uint32_t width; //!< Bit width of the CRC
105     uint32_t polynomial; //!< The polynomial to use
106     uint32_t lfsrInitState; //!< Initial state of the LFSR
107     uint32_t dataXor; //!< Byte mask to xor with the data
108     uint32_t remXor; //!< Mask to xor with the remainder.
109     /**
110      * The order in which data should be processed.
111      * If 0, data is processed MSB first.
112      * If 1, data is processed LSB first.
113      */
114     bool dataReverse;
115     bool remReverse; //!< If 1, the remainder is reversed. If 0, it is not.
116 } crc_algorithm_t;
117 
118 /** Initialize the CRC generator. This function reserves the CRYPTO block for CRC calculations.
119  *
120  * @param[out] obj  Pointer to a CRC generator object. The caller must allocate the memory
121  *  for this object but the init function will initialize its contents.
122  * @return          The status of the init request.
123  *
124  * Returns \ref CY_RSLT_SUCCESS if the operation was successful. Refer \ref subsection_crc_snippet_1 for more information.
125  */
126 cy_rslt_t cyhal_crc_init(cyhal_crc_t *obj);
127 
128 /** Release the CRC generator.
129  *
130  * @param[in,out] obj The CRC generator object
131  */
132 void cyhal_crc_free(cyhal_crc_t *obj);
133 
134 /** The CRC block is setup to perform CRC computation
135  *
136  * @param[in,out] obj       The CRC generator object
137  * @param[in] algorithm     The CRC algorithm to use for computations Refer \ref crc_algorithm_t.
138  * @return The status of the compute request
139  *
140  * \note The state of the CRC Block will be reset to the state provided by in the argument algorithm.
141  *
142  * Returns \ref CY_RSLT_SUCCESS if the operation was successful.
143  */
144 cy_rslt_t cyhal_crc_start(cyhal_crc_t *obj, const crc_algorithm_t *algorithm);
145 
146 /** Computes the CRC for the given data and accumulates the CRC with the CRC generated from previous calls.
147  * This function can be called multiple times to provide additional data.
148  * \note Input data must be 4-byte aligned. Refer \ref subsection_crc_snippet_1 for more details.
149  * @param[in] obj    The CRC generator object
150  * @param[in] data   The input data
151  * @param[in] length The number of bytes in the data
152  * @return The status of the compute request
153  *
154  * Returns \ref CY_RSLT_SUCCESS if the operation was successful.
155  */
156 cy_rslt_t cyhal_crc_compute(const cyhal_crc_t *obj, const uint8_t *data, size_t length);
157 
158 /** Finalizes the CRC computation and returns the CRC for the complete set of data passed through a
159  * single call or multiple calls to \ref cyhal_crc_compute.
160  * \note The computed CRC pointer provided must be 4 byte aligned. Refer to
161  * \ref subsection_crc_snippet_1 for more details.
162  *
163  * \note If the length of the CRC is less than a full word, the result will be in the lower bits
164  * allowing the result to be downcast if desired.
165  *
166  * @param[in]  obj The CRC generator object
167  * @param[out] crc The computed CRC
168  * @return The status of the compute request
169  *
170  * Returns \ref CY_RSLT_SUCCESS if the operation was successful.
171  */
172 cy_rslt_t cyhal_crc_finish(const cyhal_crc_t *obj, uint32_t *crc);
173 
174 #if defined(__cplusplus)
175 }
176 #endif
177 
178 #ifdef CYHAL_CRC_IMPL_HEADER
179 #include CYHAL_CRC_IMPL_HEADER
180 #endif /* CYHAL_CRC_IMPL_HEADER */
181 
182 /** \} group_hal_crc */
183