Line data Source code
1 1 : /*
2 : * Copyright (c) 2024 Brill Power Ltd.
3 : * Copyright (c) 2025 Renesas Electronics Corporation
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /**
9 : * @file
10 : * @brief CRC public API header file.
11 : * @ingroup crc_interface
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_DRIVERS_CRC_H
15 : #define ZEPHYR_INCLUDE_DRIVERS_CRC_H
16 :
17 : #include <zephyr/device.h>
18 : #include <zephyr/kernel.h>
19 : #include <zephyr/sys/crc.h>
20 :
21 : #ifdef __cplusplus
22 : extern "C" {
23 : #endif
24 :
25 : /**
26 : * @brief Interfaces for Cyclic Redundancy Check (CRC) devices.
27 : * @defgroup crc_interface CRC driver APIs
28 : * @ingroup io_interfaces
29 : * @{
30 : */
31 :
32 : /**
33 : * @name CRC input/output string flags
34 : * @anchor CRC_FLAGS
35 : *
36 : * @{
37 : */
38 :
39 : /**
40 : * @brief Reverse input string
41 : */
42 1 : #define CRC_FLAG_REVERSE_INPUT BIT(0)
43 :
44 : /**
45 : * @brief Reverse output string
46 : */
47 1 : #define CRC_FLAG_REVERSE_OUTPUT BIT(1)
48 :
49 : /** @} */
50 :
51 : /**
52 : * @cond INTERNAL_HIDDEN
53 : * Internally seed values for CRC algorithms are defined.
54 : * These values are used to initialize the CRC calculation.
55 : */
56 :
57 : /** CRC4 initial value */
58 : #define CRC4_INIT_VAL 0x0
59 :
60 : /** CRC4_TI initial value */
61 : #define CRC4_TI_INIT_VAL 0x0
62 :
63 : /** CRC7_BE initial value */
64 : #define CRC7_BE_INIT_VAL 0x0
65 :
66 : /** CRC8 initial value */
67 : #define CRC8_INIT_VAL 0x0
68 :
69 : /** CRC8_CCITT initial value */
70 : #define CRC8_CCITT_INIT_VAL 0xFF
71 :
72 : /** CRC8_ROHC initial value */
73 : #define CRC8_ROHC_INIT_VAL 0xFF
74 :
75 : /** CRC16 initial value */
76 : #define CRC16_INIT_VAL 0x0
77 :
78 : /** CRC16_ANSI initial value */
79 : #define CRC16_ANSI_INIT_VAL 0x0
80 :
81 : /** CRC16_CCITT initial value */
82 : #define CRC16_CCITT_INIT_VAL 0x0000
83 :
84 : /** CRC16_ITU_T initial value */
85 : #define CRC16_ITU_T_INIT_VAL 0x0000
86 :
87 : /** CRC24_PGP initial value */
88 : #define CRC24_PGP_INIT_VALUE 0x00B704CEU
89 :
90 : /** CRC32_C initial value */
91 : #define CRC32_IEEE_INIT_VAL 0xFFFFFFFFU
92 :
93 : /** CRC32_K_4_2 initial value */
94 : #define CRC32_C_INIT_VAL 0xFFFFFFFFU
95 :
96 : /** @endcond */
97 :
98 : /**
99 : * @brief CRC state enumeration
100 : */
101 :
102 1 : enum crc_state {
103 : /** CRC device is in IDLE state. */
104 : CRC_STATE_IDLE = 0,
105 : /** CRC calculation is in-progress. */
106 : CRC_STATE_IN_PROGRESS
107 : };
108 :
109 : /**
110 : * @brief Provides a type to hold CRC initial seed value
111 : */
112 1 : typedef uint32_t crc_init_val_t;
113 :
114 : /**
115 : * @brief Provides a type to hold CRC polynomial value.
116 : * See @a CRC_POLYNOMIAL for predefined polynomial values.
117 : */
118 1 : typedef uint32_t crc_poly_t;
119 :
120 : /**
121 : * @brief Provides a type to hold CRC result value
122 : */
123 1 : typedef uint32_t crc_result_t;
124 :
125 : /**
126 : * @brief CRC context structure
127 : *
128 : * This structure holds the state of the CRC calculation, including
129 : * the type of CRC being calculated, the current state, the polynomial,
130 : * the initial seed value, and the result of the CRC calculation.
131 : */
132 :
133 1 : struct crc_ctx {
134 : /** CRC calculation type */
135 1 : enum crc_type type;
136 : /** Current CRC device state */
137 1 : enum crc_state state;
138 : /** CRC input/output reverse flags */
139 1 : uint32_t reversed;
140 : /** CRC polynomial */
141 1 : crc_poly_t polynomial;
142 : /** CRC initial seed value */
143 1 : crc_init_val_t seed;
144 : /** CRC result */
145 1 : crc_result_t result;
146 : };
147 :
148 : /**
149 : * @brief Callback API upon CRC calculation begin
150 : * See @a crc_begin() for argument description
151 : */
152 1 : typedef int (*crc_api_begin)(const struct device *dev, struct crc_ctx *ctx);
153 :
154 : /**
155 : * @brief Callback API upon CRC calculation stream update
156 : * See @a crc_update() for argument description
157 : */
158 1 : typedef int (*crc_api_update)(const struct device *dev, struct crc_ctx *ctx, const void *buffer,
159 : size_t bufsize);
160 :
161 : /**
162 : * @brief Callback API upon CRC calculation finish
163 : * See @a crc_finish() for argument description
164 : */
165 1 : typedef int (*crc_api_finish)(const struct device *dev, struct crc_ctx *ctx);
166 :
167 0 : __subsystem struct crc_driver_api {
168 0 : crc_api_begin begin;
169 0 : crc_api_update update;
170 0 : crc_api_finish finish;
171 : };
172 :
173 : /**
174 : * @brief Configure CRC unit for calculation
175 : *
176 : * @param dev Pointer to the device structure
177 : * @param ctx Pointer to the CRC context structure
178 : *
179 : * @retval 0 if successful
180 : * @retval -ENOSYS if function is not implemented
181 : * @retval errno code on failure
182 : */
183 1 : __syscall int crc_begin(const struct device *dev, struct crc_ctx *ctx);
184 :
185 : static inline int z_impl_crc_begin(const struct device *dev, struct crc_ctx *ctx)
186 : {
187 : const struct crc_driver_api *api = (const struct crc_driver_api *)dev->api;
188 :
189 : if (api->begin == NULL) {
190 : return -ENOSYS;
191 : }
192 :
193 : return api->begin(dev, ctx);
194 : }
195 :
196 : /**
197 : * @brief Perform CRC calculation on the provided data buffer and retrieve result
198 : *
199 : * @param dev Pointer to the device structure
200 : * @param ctx Pointer to the CRC context structure
201 : * @param buffer Pointer to input data buffer
202 : * @param bufsize Number of bytes in *buffer
203 : *
204 : * @retval 0 if successful
205 : * @retval -ENOSYS if function is not implemented
206 : * @retval errno code on failure
207 : */
208 1 : __syscall int crc_update(const struct device *dev, struct crc_ctx *ctx, const void *buffer,
209 : size_t bufsize);
210 :
211 : static inline int z_impl_crc_update(const struct device *dev, struct crc_ctx *ctx,
212 : const void *buffer, size_t bufsize)
213 : {
214 : const struct crc_driver_api *api = (const struct crc_driver_api *)dev->api;
215 :
216 : if (api->update == NULL) {
217 : return -ENOSYS;
218 : }
219 :
220 : return api->update(dev, ctx, buffer, bufsize);
221 : }
222 :
223 : /**
224 : * @brief Finalize CRC calculation
225 : *
226 : * @param dev Pointer to the device structure
227 : * @param ctx Pointer to the CRC context structure
228 : *
229 : * @retval 0 if successful
230 : * @retval -ENOSYS if function is not implemented
231 : * @retval errno code on failure
232 : */
233 1 : __syscall int crc_finish(const struct device *dev, struct crc_ctx *ctx);
234 :
235 : static inline int z_impl_crc_finish(const struct device *dev, struct crc_ctx *ctx)
236 : {
237 : const struct crc_driver_api *api = (const struct crc_driver_api *)dev->api;
238 :
239 : if (api->finish == NULL) {
240 : return -ENOSYS;
241 : }
242 :
243 : return api->finish(dev, ctx);
244 : }
245 :
246 : /**
247 : * @brief Verify CRC result
248 : *
249 : * @param ctx Pointer to the CRC context structure
250 : * @param expected Expected CRC result
251 : *
252 : * @retval 0 if successful
253 : * @retval -EBUSY if CRC calculation is not completed
254 : * @retval -EPERM if CRC verification failed
255 : */
256 1 : static inline int crc_verify(struct crc_ctx *ctx, crc_result_t expected)
257 : {
258 : if (ctx == NULL) {
259 : return -EINVAL;
260 : }
261 :
262 : if (ctx->state == CRC_STATE_IN_PROGRESS) {
263 : return -EBUSY;
264 : }
265 :
266 : if (expected != ctx->result) {
267 : return -EPERM;
268 : }
269 :
270 : return 0;
271 : }
272 :
273 : /**
274 : * @}
275 : */
276 :
277 : #ifdef __cplusplus
278 : }
279 : #endif
280 :
281 : #include <zephyr/syscalls/crc.h>
282 :
283 : #endif /* ZEPHYR_INCLUDE_DRIVERS_CRC_H */
|