1 /**
2 *
3 * \file
4 *
5 * \brief SAM DSU CRC32 driver.
6 *
7 * This file defines a useful set of functions for DSU CRC32 on SAM devices.
8 *
9 * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
10 *
11 * \asf_license_start
12 *
13 * \page License
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright notice,
19 * this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 * this list of conditions and the following disclaimer in the documentation
23 * and/or other materials provided with the distribution.
24 *
25 * 3. The name of Atmel may not be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * 4. This software may only be redistributed and used in connection with an
29 * Atmel microcontroller product.
30 *
31 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
32 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
34 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
35 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 *
43 * \asf_license_stop
44 *
45 */
46 /*
47 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
48 */
49
50 #include <system_interrupt.h>
51 #include <pac.h>
52 #include <crc32.h>
53
54 /**
55 * \brief Calculate CRC32 value of the input memory
56 *
57 * Calculate CRC32 value of the input memory.
58 *
59 * The read value must be complemented to match standard CRC32 implementations
60 * or kept non-inverted if used as starting point for subsequent CRC32 calculations.
61 *
62 * \param[in] addr Memory address to calculate CRC32
63 * \param[in] len Memory length to calculate CRC32
64 * \param[in,out] pcrc32 Initial value used for the CRC32 calculation, and CRC32 result after calculation
65 *
66 * \return Status of the configuration procedure.
67 *
68 * \retval STATUS_OK If CRC32 calculation OK
69 * \retval STATUS_ERR_BAD_ADDRESS The address was not aligned with 4 bytes.
70
71 * \retval STATUS_ERR_IO A bus error is detected
72 */
dsu_crc32_cal(const uint32_t addr,const uint32_t len,uint32_t * pcrc32)73 enum status_code dsu_crc32_cal(const uint32_t addr, const uint32_t len, uint32_t *pcrc32)
74 {
75 if (addr & 0x00000003) {
76 return STATUS_ERR_BAD_ADDRESS;
77 }
78
79 system_interrupt_disable_global();
80 system_peripheral_unlock(SYSTEM_PERIPHERAL_ID(DSU), ~SYSTEM_PERIPHERAL_ID(DSU));
81
82 DSU->DATA.reg = *pcrc32;
83 DSU->ADDR.reg = addr;
84 DSU->LENGTH.reg = len;
85
86 DSU->CTRL.bit.CRC = 1;
87 while ((DSU->STATUSA.reg & DSU_STATUSA_DONE) != 1) {
88 }
89
90 if (DSU->STATUSA.reg & DSU_STATUSA_BERR) {
91 system_peripheral_lock(SYSTEM_PERIPHERAL_ID(DSU), ~SYSTEM_PERIPHERAL_ID(DSU));
92 system_interrupt_enable_global();
93 return STATUS_ERR_IO;
94 }
95
96 *pcrc32 = DSU->DATA.reg;
97 DSU->STATUSA.reg = DSU_STATUSA_DONE;
98
99 system_peripheral_lock(SYSTEM_PERIPHERAL_ID(DSU), ~SYSTEM_PERIPHERAL_ID(DSU));
100 system_interrupt_enable_global();
101 return STATUS_OK;
102 }