1 /**
2 *********************************************************************************
3 *
4 * @file ald_crc.c
5 * @brief CRC module driver.
6 *
7 * @version V1.0
8 * @date 6 Dec 2017
9 * @author AE Team
10 * @note
11 *
12 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 *
28 *********************************************************************************
29 */
30
31 #include "ald_crc.h"
32
33 /** @addtogroup ES32FXXX_ALD
34 * @{
35 */
36
37 /** @defgroup CRC CRC
38 * @brief CRC module driver
39 * @{
40 */
41 #ifdef ALD_CRC
42
43 /** @addtogroup CRC_Private_Functions CRC Private Functions
44 * @{
45 */
46 void ald_crc_reset(crc_handle_t *hperh);
47 #ifdef ALD_DMA
48 static void crc_dma_calculate_cplt(void *arg);
49 static void crc_dma_error(void *arg);
50 #endif
51 /**
52 * @}
53 */
54
55
56 /** @defgroup CRC_Public_Functions CRC Public Functions
57 * @{
58 */
59
60 /** @defgroup CRC_Public_Functions_Group1 Initialization functions
61 * @brief Initialization and Configuration functions
62 * @{
63 */
64
65 /**
66 * @brief Initializes the CRC mode according to the specified parameters in
67 * the crc_handle_t and create the associated handle.
68 * @param hperh: Pointer to a crc_handle_t structure that contains
69 * the configuration information for the specified CRC module.
70 * @retval Status, see @ref ald_status_t.
71 */
ald_crc_init(crc_handle_t * hperh)72 ald_status_t ald_crc_init(crc_handle_t *hperh)
73 {
74 uint32_t tmp = 0;
75
76 if (hperh == NULL)
77 return ERROR;
78
79 assert_param(IS_CRC(hperh->perh));
80 assert_param(IS_CRC_MODE(hperh->init.mode));
81 assert_param(IS_FUNC_STATE(hperh->init.chs_rev));
82 assert_param(IS_FUNC_STATE(hperh->init.data_inv));
83 assert_param(IS_FUNC_STATE(hperh->init.data_rev));
84 assert_param(IS_FUNC_STATE(hperh->init.chs_inv));
85
86 ald_crc_reset(hperh);
87 __LOCK(hperh);
88
89 CRC_ENABLE(hperh);
90
91 tmp = hperh->perh->CR;
92
93 tmp |= ((hperh->init.chs_rev << CRC_CR_CHSREV_POS) | (hperh->init.data_inv << CRC_CR_DATREV_POS) |
94 (hperh->init.chs_inv << CRC_CR_CHSINV_POS) | (hperh->init.mode << CRC_CR_MODE_POSS) |
95 (CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS) | (hperh->init.data_rev << CRC_CR_DATREV_POS) |
96 (0 << CRC_CR_BYTORD_POS));
97
98 hperh->perh->CR = tmp;
99 hperh->perh->SEED = hperh->init.seed;
100 CRC_RESET(hperh);
101
102 hperh->state = CRC_STATE_READY;
103
104 __UNLOCK(hperh);
105 return OK;
106 }
107
108 /**
109 * @}
110 */
111
112 /** @defgroup CRC_Public_Functions_Group2 Calculate functions
113 * @brief Calculate functions
114 * @{
115 */
116
117 /**
118 * @brief Calculate the crc value of data by byte.
119 * @param hperh: Pointer to a crc_handle_t structure that contains
120 * the configuration information for the specified CRC module.
121 * @param buf: Pointer to data buffer
122 * @param size: The size of data to be calculate
123 * @retval result, the result of a amount data
124 */
ald_crc_calculate(crc_handle_t * hperh,uint8_t * buf,uint32_t size)125 uint32_t ald_crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size)
126 {
127 uint32_t i;
128 uint32_t ret;
129
130 assert_param(IS_CRC(hperh->perh));
131
132 if (buf == NULL || size == 0)
133 return 0;
134
135 __LOCK(hperh);
136 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS);
137 hperh->state = CRC_STATE_BUSY;
138
139 for (i = 0; i < size; i++)
140 *((volatile uint8_t *)&(hperh->perh->DATA)) = buf[i];
141
142 ret = CRC->CHECKSUM;
143 hperh->state = CRC_STATE_READY;
144 __UNLOCK(hperh);
145
146 return ret;
147 }
148
149 /**
150 * @brief Calculate the crc value of data by halfword.
151 * @param hperh: Pointer to a crc_handle_t structure that contains
152 * the configuration information for the specified CRC module.
153 * @param buf: Pointer to data buffer
154 * @param size: The size of data to be calculate,width is 2 bytes.
155 * @retval result, the result of a amount data
156 */
ald_crc_calculate_halfword(crc_handle_t * hperh,uint16_t * buf,uint32_t size)157 uint32_t ald_crc_calculate_halfword(crc_handle_t *hperh, uint16_t *buf, uint32_t size)
158 {
159 uint32_t i;
160 uint32_t ret;
161
162 assert_param(IS_CRC(hperh->perh));
163
164 if (buf == NULL || size == 0)
165 return 0;
166
167 __LOCK(hperh);
168 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS);
169 hperh->state = CRC_STATE_BUSY;
170
171 for (i = 0; i < size; i++)
172 *((volatile uint16_t *)&(hperh->perh->DATA)) = buf[i];
173
174 ret = CRC->CHECKSUM;
175 hperh->state = CRC_STATE_READY;
176 __UNLOCK(hperh);
177
178 return ret;
179 }
180
181 /**
182 * @brief Calculate the crc value of data by word.
183 * @param hperh: Pointer to a crc_handle_t structure that contains
184 * the configuration information for the specified CRC module.
185 * @param buf: Pointer to data buffer
186 * @param size: The size of data to be calculate,width is 4 bytes
187 * @retval result, the result of a amount data
188 */
ald_crc_calculate_word(crc_handle_t * hperh,uint32_t * buf,uint32_t size)189 uint32_t ald_crc_calculate_word(crc_handle_t *hperh, uint32_t *buf, uint32_t size)
190 {
191 uint32_t i;
192 uint32_t ret;
193
194 assert_param(IS_CRC(hperh->perh));
195
196 if (buf == NULL || size == 0)
197 return 0;
198
199 __LOCK(hperh);
200 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS);
201 hperh->state = CRC_STATE_BUSY;
202
203 for (i = 0; i < size; i++)
204 CRC->DATA = buf[i];
205
206 ret = CRC->CHECKSUM;
207 hperh->state = CRC_STATE_READY;
208 __UNLOCK(hperh);
209
210 return ret;
211 }
212
213 /**
214 * @}
215 */
216
217 #ifdef ALD_DMA
218 /** @defgroup CRC_Public_Functions_Group3 DMA operation functions
219 * @brief DMA operation functions
220 * @{
221 */
222
223 /**
224 * @brief Calculate an amount of data used dma channel
225 * @param hperh: Pointer to a crc_handle_t structure that contains
226 * the configuration information for the specified CRC module.
227 * @param buf: Pointer to data buffer
228 * @param res: Pointer to result
229 * @param size: Amount of data to be Calculate
230 * @param channel: DMA channel as CRC transmit
231 * @retval Status, see @ref ald_status_t.
232 */
ald_crc_calculate_by_dma(crc_handle_t * hperh,uint8_t * buf,uint32_t * res,uint16_t size,uint8_t channel)233 ald_status_t ald_crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
234 {
235 if (hperh->state != CRC_STATE_READY)
236 return BUSY;
237
238 if (buf == NULL || size == 0)
239 return ERROR;
240
241 __LOCK(hperh);
242 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS);
243
244 hperh->state = CRC_STATE_BUSY;
245
246 hperh->cal_buf = buf;
247 hperh->cal_res = res;
248
249 if (hperh->hdma.perh == NULL)
250 hperh->hdma.perh = DMA0;
251
252 hperh->hdma.cplt_arg = (void *)hperh;
253 hperh->hdma.cplt_cbk = &crc_dma_calculate_cplt;
254 hperh->hdma.err_arg = (void *)hperh;
255 hperh->hdma.err_cbk = &crc_dma_error;
256
257 ald_dma_config_struct(&(hperh->hdma.config));
258 hperh->hdma.config.data_width = DMA_DATA_SIZE_BYTE;
259 hperh->hdma.config.src = (void *)buf;
260 hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
261 hperh->hdma.config.size = size;
262 hperh->hdma.config.src_inc = DMA_DATA_INC_BYTE;
263 hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE;
264 hperh->hdma.config.msel = DMA_MSEL_CRC;
265 hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE;
266 hperh->hdma.config.channel = channel;
267 ald_dma_config_basic(&(hperh->hdma));
268
269 __UNLOCK(hperh);
270 CRC_DMA_ENABLE(hperh);
271
272 return OK;
273 }
274
275 /**
276 * @brief Calculate an amount of data used dma channel,data width is half-word.
277 * @param hperh: Pointer to a crc_handle_t structure that contains
278 * the configuration information for the specified CRC module.
279 * @param buf: Pointer to half_word data buffer
280 * @param res: Pointer to result
281 * @param size: Amount of half_word data to be Calculate
282 * @param channel: DMA channel as CRC transmit
283 * @retval Status, see @ref ald_status_t.
284 */
ald_crc_calculate_halfword_by_dma(crc_handle_t * hperh,uint16_t * buf,uint32_t * res,uint16_t size,uint8_t channel)285 ald_status_t ald_crc_calculate_halfword_by_dma(crc_handle_t *hperh, uint16_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
286 {
287 if (hperh->state != CRC_STATE_READY)
288 return BUSY;
289
290 if (buf == NULL || size == 0)
291 return ERROR;
292
293 __LOCK(hperh);
294 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS);
295
296 hperh->state = CRC_STATE_BUSY;
297
298 hperh->cal_buf = (uint8_t *)buf;
299 hperh->cal_res = res;
300
301 if (hperh->hdma.perh == NULL)
302 hperh->hdma.perh = DMA0;
303
304 hperh->hdma.cplt_arg = (void *)hperh;
305 hperh->hdma.cplt_cbk = &crc_dma_calculate_cplt;
306 hperh->hdma.err_arg = (void *)hperh;
307 hperh->hdma.err_cbk = &crc_dma_error;
308
309 ald_dma_config_struct(&(hperh->hdma.config));
310 hperh->hdma.config.data_width = DMA_DATA_SIZE_HALFWORD;
311 hperh->hdma.config.src = (void *)buf;
312 hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
313 hperh->hdma.config.size = size;
314 hperh->hdma.config.src_inc = DMA_DATA_INC_HALFWORD;
315 hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE;
316 hperh->hdma.config.msel = DMA_MSEL_CRC;
317 hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE;
318 hperh->hdma.config.channel = channel;
319 ald_dma_config_basic(&(hperh->hdma));
320
321 __UNLOCK(hperh);
322 CRC_DMA_ENABLE(hperh);
323
324 return OK;
325 }
326
327 /**
328 * @brief Calculate an amount of data used dma channel,data width is word.
329 * @param hperh: Pointer to a crc_handle_t structure that contains
330 * the configuration information for the specified CRC module.
331 * @param buf: Pointer to word data buffer
332 * @param res: Pointer to result
333 * @param size: Amount of word data to be Calculate
334 * @param channel: DMA channel as CRC transmit
335 * @retval Status, see @ref ald_status_t.
336 */
ald_crc_calculate_word_by_dma(crc_handle_t * hperh,uint32_t * buf,uint32_t * res,uint16_t size,uint8_t channel)337 ald_status_t ald_crc_calculate_word_by_dma(crc_handle_t *hperh, uint32_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
338 {
339 if (hperh->state != CRC_STATE_READY)
340 return BUSY;
341
342 if (buf == NULL || size == 0)
343 return ERROR;
344
345 __LOCK(hperh);
346 MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS);
347
348 hperh->state = CRC_STATE_BUSY;
349
350 hperh->cal_buf = (uint8_t *)buf;
351 hperh->cal_res = res;
352
353 if (hperh->hdma.perh == NULL)
354 hperh->hdma.perh = DMA0;
355
356 hperh->hdma.cplt_arg = (void *)hperh;
357 hperh->hdma.cplt_cbk = &crc_dma_calculate_cplt;
358 hperh->hdma.err_arg = (void *)hperh;
359 hperh->hdma.err_cbk = &crc_dma_error;
360
361 ald_dma_config_struct(&(hperh->hdma.config));
362 hperh->hdma.config.data_width = DMA_DATA_SIZE_WORD;
363 hperh->hdma.config.src = (void *)buf;
364 hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
365 hperh->hdma.config.size = size;
366 hperh->hdma.config.src_inc = DMA_DATA_INC_WORD;
367 hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE;
368 hperh->hdma.config.msel = DMA_MSEL_CRC;
369 hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE;
370 hperh->hdma.config.channel = channel;
371 ald_dma_config_basic(&(hperh->hdma));
372
373 __UNLOCK(hperh);
374 CRC_DMA_ENABLE(hperh);
375
376 return OK;
377 }
378
379
380 /**
381 * @brief Pauses the DMA Transfer.
382 * @param hperh: Pointer to a crc_handle_t structure that contains
383 * the configuration information for the specified CRC module.
384 * @retval Status, see @ref ald_status_t.
385 */
ald_crc_dma_pause(crc_handle_t * hperh)386 ald_status_t ald_crc_dma_pause(crc_handle_t *hperh)
387 {
388 __LOCK(hperh);
389 CRC_DMA_DISABLE(hperh);
390 __UNLOCK(hperh);
391
392 return OK;
393 }
394
395 /**
396 * @brief Resumes the DMA Transfer.
397 * @param hperh: Pointer to a crc_handle_t structure that contains
398 * the configuration information for the specified CRC module.
399 * @retval Status, see @ref ald_status_t.
400 */
ald_crc_dma_resume(crc_handle_t * hperh)401 ald_status_t ald_crc_dma_resume(crc_handle_t *hperh)
402 {
403 __LOCK(hperh);
404 CRC_DMA_ENABLE(hperh);
405 __UNLOCK(hperh);
406
407 return OK;
408 }
409
410 /**
411 * @brief Stops the DMA Transfer.
412 * @param hperh: Pointer to a crc_handle_t structure that contains
413 * the configuration information for the specified CRC module.
414 * @retval Status, see @ref ald_status_t.
415 */
ald_crc_dma_stop(crc_handle_t * hperh)416 ald_status_t ald_crc_dma_stop(crc_handle_t *hperh)
417 {
418 __LOCK(hperh);
419 CRC_DMA_DISABLE(hperh);
420 __UNLOCK(hperh);
421
422 hperh->state = CRC_STATE_READY;
423 return OK;
424 }
425
426 /**
427 * @}
428 */
429 #endif
430
431 /** @defgroup CRC_Public_Functions_Group4 Peripheral State and Errors functions
432 * @brief CRC State and Errors functions
433 * @{
434 */
435
436 /**
437 * @brief Returns the CRC state.
438 * @param hperh: Pointer to a crc_handle_t structure that contains
439 * the configuration information for the specified CRC module.
440 * @retval CRC state
441 */
ald_crc_get_state(crc_handle_t * hperh)442 crc_state_t ald_crc_get_state(crc_handle_t *hperh)
443 {
444 assert_param(IS_CRC(hperh->perh));
445
446 return hperh->state;
447 }
448 /**
449 * @}
450 */
451
452 /**
453 * @}
454 */
455
456 /** @defgroup CRC_Private_Functions CRC Private Functions
457 * @brief CRC Private functions
458 * @{
459 */
460
461 /**
462 * @brief Reset the CRC peripheral.
463 * @param hperh: Pointer to a crc_handle_t structure that contains
464 * the configuration information for the specified CRC module.
465 * @retval None
466 */
ald_crc_reset(crc_handle_t * hperh)467 void ald_crc_reset(crc_handle_t *hperh)
468 {
469 hperh->perh->DATA = 0x0;
470 hperh->perh->CR = 0x2;
471 hperh->perh->SEED = 0xFFFFFFFF;
472
473 hperh->state = CRC_STATE_READY;
474 __UNLOCK(hperh);
475 return;
476 }
477
478 #ifdef ALD_DMA
479 /**
480 * @brief DMA CRC calculate process complete callback.
481 * @param arg: Pointer to a crc_handle_t structure that contains
482 * the configuration information for the specified CRC module.
483 * @retval None
484 */
crc_dma_calculate_cplt(void * arg)485 static void crc_dma_calculate_cplt(void *arg)
486 {
487 crc_handle_t *hperh = (crc_handle_t *)arg;
488
489 *(hperh->cal_res) = CRC->CHECKSUM;
490 CRC_DMA_DISABLE(hperh);
491
492 hperh->state = CRC_STATE_READY;
493
494 if (hperh->cal_cplt_cbk)
495 hperh->cal_cplt_cbk(hperh);
496 }
497
498 /**
499 * @brief DMA CRC communication error callback.
500 * @param arg: Pointer to a crc_handle_t structure that contains
501 * the configuration information for the specified CRC module.
502 * @retval None
503 */
crc_dma_error(void * arg)504 static void crc_dma_error(void *arg)
505 {
506 crc_handle_t *hperh = (crc_handle_t *)arg;
507
508 CRC_CLEAR_ERROR_FLAG(hperh);
509 CRC_DMA_DISABLE(hperh);
510
511 hperh->state = CRC_STATE_READY;
512
513 if (hperh->err_cplt_cbk)
514 hperh->err_cplt_cbk(hperh);
515 }
516 #endif
517 /**
518 * @}
519 */
520 #endif /* ALD_CRC */
521
522 /**
523 * @}
524 */
525
526 /**
527 * @}
528 */
529