1 /***************************************************************************//**
2 * @file
3 * @brief General Purpose Cyclic Redundancy Check (GPCRC) API.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #include "sl_common.h"
32 #include "em_gpcrc.h"
33 #include "sl_assert.h"
34
35 #if defined(GPCRC_PRESENT) && (GPCRC_COUNT > 0)
36
37 /***************************************************************************//**
38 * @addtogroup gpcrc
39 * @{
40 ******************************************************************************/
41
42 /*******************************************************************************
43 *************************** GLOBAL FUNCTIONS ******************************
44 ******************************************************************************/
45
46 /***************************************************************************//**
47 * @brief
48 * Initialize the General Purpose Cyclic Redundancy Check (GPCRC) module.
49 *
50 * @details
51 * Use this function to configure the operational parameters of the GPCRC,
52 * such as the polynomial to use and how the input should be preprocessed
53 * before entering the CRC calculation.
54 *
55 * @note
56 * This function will not copy the initialization value to the data register
57 * to prepare for a new CRC calculation. Either call
58 * @ref GPCRC_Start before each calculation or by use the
59 * autoInit functionality.
60 *
61 * @param[in] gpcrc
62 * A pointer to the GPCRC peripheral register block.
63 *
64 * @param[in] init
65 * A pointer to the initialization structure used to configure the GPCRC.
66 ******************************************************************************/
GPCRC_Init(GPCRC_TypeDef * gpcrc,const GPCRC_Init_TypeDef * init)67 void GPCRC_Init(GPCRC_TypeDef * gpcrc, const GPCRC_Init_TypeDef * init)
68 {
69 uint32_t polySelect;
70 uint32_t revPoly = 0;
71
72 if (init->crcPoly == 0x04C11DB7) {
73 polySelect = GPCRC_CTRL_POLYSEL_CRC32;
74 } else {
75 // If not using the fixed CRC-32 polynomial, use 16-bit.
76 EFM_ASSERT((init->crcPoly & 0xFFFF0000UL) == 0U);
77 #if defined(GPCRC_CTRL_POLYSEL_CRC16)
78 polySelect = GPCRC_CTRL_POLYSEL_CRC16;
79 #else
80 polySelect = GPCRC_CTRL_POLYSEL_16;
81 #endif
82 revPoly = SL_RBIT16(init->crcPoly);
83 }
84
85 #if defined(GPCRC_EN_EN)
86 if (init->enable) {
87 gpcrc->EN_SET = GPCRC_EN_EN;
88 } else {
89 gpcrc->EN_CLR = GPCRC_EN_EN;
90 }
91
92 gpcrc->CTRL = (((uint32_t)init->autoInit << _GPCRC_CTRL_AUTOINIT_SHIFT)
93 | ((uint32_t)init->reverseByteOrder << _GPCRC_CTRL_BYTEREVERSE_SHIFT)
94 | ((uint32_t)init->reverseBits << _GPCRC_CTRL_BITREVERSE_SHIFT)
95 | ((uint32_t)init->enableByteMode << _GPCRC_CTRL_BYTEMODE_SHIFT)
96 | polySelect);
97 #else
98 gpcrc->CTRL = (((uint32_t)init->autoInit << _GPCRC_CTRL_AUTOINIT_SHIFT)
99 | ((uint32_t)init->reverseByteOrder << _GPCRC_CTRL_BYTEREVERSE_SHIFT)
100 | ((uint32_t)init->reverseBits << _GPCRC_CTRL_BITREVERSE_SHIFT)
101 | ((uint32_t)init->enableByteMode << _GPCRC_CTRL_BYTEMODE_SHIFT)
102 | polySelect
103 | ((uint32_t)init->enable << _GPCRC_CTRL_EN_SHIFT));
104 #endif
105
106 #if defined(GPCRC_CTRL_POLYSEL_CRC16)
107 if (polySelect == GPCRC_CTRL_POLYSEL_CRC16) {
108 #else
109 if (polySelect == GPCRC_CTRL_POLYSEL_16) {
110 #endif
111 // Set the CRC polynomial value.
112 gpcrc->POLY = revPoly & _GPCRC_POLY_POLY_MASK;
113 }
114
115 // Load the CRC initialization value to GPCRC_INIT.
116 gpcrc->INIT = init->initValue;
117 }
118
119 /***************************************************************************//**
120 * @brief
121 * Reset GPCRC registers to the hardware reset state.
122 *
123 * @note
124 * The data registers are not reset by this function.
125 *
126 * @param[in] gpcrc
127 * A pointer to the GPCRC peripheral register block.
128 ******************************************************************************/
129 void GPCRC_Reset(GPCRC_TypeDef * gpcrc)
130 {
131 gpcrc->CTRL = _GPCRC_CTRL_RESETVALUE;
132 gpcrc->POLY = _GPCRC_POLY_RESETVALUE;
133 gpcrc->INIT = _GPCRC_INIT_RESETVALUE;
134 }
135
136 /** @} (end addtogroup gpcrc) */
137
138 #endif /* defined(GPCRC_COUNT) && (GPCRC_COUNT > 0) */
139