1 /*!
2     \file    gd32a50x_crc.c
3     \brief   CRC driver
4 
5     \version 2022-01-30, V1.0.0, firmware for GD32A50x
6 */
7 
8 /*
9     Copyright (c) 2022, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #include "gd32a50x_crc.h"
36 
37 /*!
38     \brief      deinit CRC calculation unit
39     \param[in]  none
40     \param[out] none
41     \retval     none
42 */
crc_deinit(void)43 void crc_deinit(void)
44 {
45     CRC_IDATA = (uint32_t)0xFFFFFFFFU;
46     CRC_DATA  = (uint32_t)0xFFFFFFFFU;
47     CRC_FDATA = (uint32_t)0x00000000U;
48     CRC_POLY  = (uint32_t)0x04C11DB7U;
49     CRC_CTL   = CRC_CTL_RST;
50 }
51 
52 /*!
53     \brief      enable the reverse operation of output data
54     \param[in]  none
55     \param[out] none
56     \retval     none
57 */
crc_reverse_output_data_enable(void)58 void crc_reverse_output_data_enable(void)
59 {
60     CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O);
61     CRC_CTL |= (uint32_t)CRC_CTL_REV_O;
62 }
63 
64 /*!
65     \brief      disable the reverse operation of output data
66     \param[in]  none
67     \param[out] none
68     \retval     none
69 */
crc_reverse_output_data_disable(void)70 void crc_reverse_output_data_disable(void)
71 {
72     CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O);
73 }
74 
75 /*!
76     \brief      reset data register to the value of initialization data register
77     \param[in]  none
78     \param[out] none
79     \retval     none
80 */
crc_data_register_reset(void)81 void crc_data_register_reset(void)
82 {
83     CRC_CTL |= (uint32_t)CRC_CTL_RST;
84 }
85 
86 /*!
87     \brief      read the data register
88     \param[in]  none
89     \param[out] none
90     \retval     32-bit value of the data register
91 */
crc_data_register_read(void)92 uint32_t crc_data_register_read(void)
93 {
94     uint32_t data;
95     data = CRC_DATA;
96     return (data);
97 }
98 
99 /*!
100     \brief      read the free data register
101     \param[in]  none
102     \param[out] none
103     \retval     8-bit value of the free data register
104 */
crc_free_data_register_read(void)105 uint8_t crc_free_data_register_read(void)
106 {
107     uint8_t fdata;
108     fdata = (uint8_t)CRC_FDATA;
109     return (fdata);
110 }
111 
112 /*!
113     \brief      write the free data register
114     \param[in]  free_data: specify 8-bit data
115     \param[out] none
116     \retval     none
117 */
crc_free_data_register_write(uint8_t free_data)118 void crc_free_data_register_write(uint8_t free_data)
119 {
120     CRC_FDATA = (uint32_t)free_data;
121 }
122 
123 /*!
124     \brief      write the initialization data register
125     \param[in]  init_data:specify 32-bit data
126     \param[out] none
127     \retval     none
128 */
crc_init_data_register_write(uint32_t init_data)129 void crc_init_data_register_write(uint32_t init_data)
130 {
131     CRC_IDATA = (uint32_t)init_data;
132 }
133 
134 /*!
135     \brief      configure the CRC input data function
136     \param[in]  data_reverse: specify input data reverse function
137                 only one parameter can be selected which is shown as below:
138       \arg        CRC_INPUT_DATA_NOT: input data is not reversed
139       \arg        CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits
140       \arg        CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits
141       \arg        CRC_INPUT_DATA_WORD: input data is reversed on 32 bits
142     \param[out] none
143     \retval     none
144 */
crc_input_data_reverse_config(uint32_t data_reverse)145 void crc_input_data_reverse_config(uint32_t data_reverse)
146 {
147     CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I);
148     CRC_CTL |= (uint32_t)data_reverse;
149 }
150 
151 /*!
152     \brief      configure the CRC size of polynomial function
153     \param[in]  poly_size: size of polynomial
154                 only one parameter can be selected which is shown as below:
155       \arg        CRC_CTL_PS_32: 32-bit polynomial for CRC calculation
156       \arg        CRC_CTL_PS_16: 16-bit polynomial for CRC calculation
157       \arg        CRC_CTL_PS_8: 8-bit polynomial for CRC calculation
158       \arg        CRC_CTL_PS_7: 7-bit polynomial for CRC calculation
159     \param[out] none
160     \retval     none
161 */
crc_polynomial_size_set(uint32_t poly_size)162 void crc_polynomial_size_set(uint32_t poly_size)
163 {
164     CRC_CTL &= (uint32_t)(~CRC_CTL_PS);
165     CRC_CTL |= (uint32_t)poly_size;
166 }
167 
168 /*!
169     \brief      configure the CRC polynomial value function
170     \param[in]  poly: configurable polynomial value
171     \param[out] none
172     \retval     none
173 */
crc_polynomial_set(uint32_t poly)174 void crc_polynomial_set(uint32_t poly)
175 {
176     CRC_POLY &= (uint32_t)(~CRC_POLY_POLY);
177     CRC_POLY = poly;
178 }
179 
180 /*!
181     \brief      CRC calculate single data
182     \param[in]  sdata: specify input data
183     \param[in]  data_format: input data format
184                 only one parameter can be selected which is shown as below:
185       \arg        INPUT_FORMAT_WORD: input data in word format
186       \arg        INPUT_FORMAT_HALFWORD: input data in half-word format
187       \arg        INPUT_FORMAT_BYTE: input data in byte format
188     \param[out] none
189     \retval     CRC calculate value
190 */
crc_single_data_calculate(uint32_t sdata,uint8_t data_format)191 uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format)
192 {
193     if(INPUT_FORMAT_WORD == data_format) {
194         REG32(CRC) = sdata;
195     } else if(INPUT_FORMAT_HALFWORD == data_format) {
196         REG16(CRC) = (uint16_t)sdata;
197     } else {
198         REG8(CRC) = (uint8_t)sdata;
199     }
200 
201     return(CRC_DATA);
202 }
203 
204 /*!
205     \brief      CRC calculate a data array
206     \param[in]  array: pointer to the input data array
207     \param[in]  size: size of the array
208     \param[in]  data_format: input data format
209                 only one parameter can be selected which is shown as below:
210       \arg        INPUT_FORMAT_WORD: input data in word format
211       \arg        INPUT_FORMAT_HALFWORD: input data in half-word format
212       \arg        INPUT_FORMAT_BYTE: input data in byte format
213     \param[out] none
214     \retval     CRC calculate value
215 */
crc_block_data_calculate(void * array,uint32_t size,uint8_t data_format)216 uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format)
217 {
218     uint8_t *data8;
219     uint16_t *data16;
220     uint32_t *data32;
221     uint32_t index;
222 
223     if(INPUT_FORMAT_WORD == data_format) {
224         data32 = (uint32_t *)array;
225         for(index = 0U; index < size; index++) {
226             REG32(CRC) = data32[index];
227         }
228     } else if(INPUT_FORMAT_HALFWORD == data_format) {
229         data16 = (uint16_t *)array;
230         for(index = 0U; index < size; index++) {
231             REG16(CRC) = data16[index];
232         }
233     } else {
234         data8 = (uint8_t *)array;
235         for(index = 0U; index < size; index++) {
236             REG8(CRC) = data8[index];
237         }
238     }
239 
240     return (CRC_DATA);
241 }
242