1 /*
2 * Copyright (c) 2021-2022 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_CRC_DRV_H
9 #define HPM_CRC_DRV_H
10
11 /**
12 * @brief CRC APIs
13 * @defgroup crc_interface CRC driver APIs
14 * @ingroup crc_interfaces
15 * @{
16 */
17
18
19 #include "hpm_common.h"
20 #include "hpm_crc_regs.h"
21
22 /**
23 * @brief CRC preset definitions
24 */
25 typedef enum crc_preset_enum {
26 crc_preset_none = 0,
27 crc_preset_crc32, /*!< Poly: 0x04C11DB7, Init: 0xFFFFFFFF, Refin: True, Refout: True, Xorout: 0xFFFFFFFF */
28 crc_preset_crc32_autosar, /*!< Poly: 0xF4ACFB13, Init: 0xFFFFFFFF, Refin: True, Refout: True, Xorout: 0xFFFFFFFF */
29 crc_preset_crc16_ccitt, /*!< Poly: 0x1021, Init: 0x0000, Refin: True, Refout: True, Xorout: 0x0000 */
30 crc_preset_crc16_xmodem, /*!< Poly: 0x1021, Init: 0x0000, Refin: False, Refout: False, Xorout: 0x0000 */
31 crc_preset_crc16_modbus, /*!< Poly: 0x8005, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0x0000 */
32 crc_preset_crc16_dnp, /*!< Poly: 0x3D65, Init: 0x0000, Refin: True, Refout: True, Xorout: 0xFFFF */
33 crc_preset_crc16_x25, /*!< Poly: 0x1021, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0xFFFF */
34 crc_preset_crc16_usb, /*!< Poly: 0x8005, Init: 0xFFFF, Refin: True, Refout: True, Xorout: 0xFFFF */
35 crc_preset_crc16_maxim, /*!< Poly: 0x8005, Init: 0x0000, Refin: True, Refout: True, Xorout: 0xFFFF */
36 crc_preset_crc16_ibm, /*!< Poly: 0x8005, Init: 0x0000, Refin: True, Refout: True, Xorout: 0x0000 */
37 crc_preset_crc8_maxim, /*!< Poly: 0x31, Init: 0x00, Refin: True, Refout: True, Xorout: 0x00 */
38 crc_preset_crc8_rohc, /*!< Poly: 0x07, Init: 0xFF, Refin: True, Refout: True, Xorout: 0x00 */
39 crc_preset_crc8_itu, /*!< Poly: 0x07, Init: 0x00, Refin: False, Refout: False, Xorout: 0x55 */
40 crc_preset_crc8, /*!< Poly: 0x07, Init: 0x00, Refin: False, Refout: False, Xorout: 0x00 */
41 crc_preset_crc5_usb, /*!< Poly: 0x05, Init: 0x1F, Refin: True, Refout: True, Xorout: 0x1F */
42 } crc_preset_t;
43
44 /**
45 * @brief CRC Refin definitions.
46 */
47 typedef enum crc_refin_enum {
48 crc_refin_false = 0, /*!< Do not manipulate input data stream. */
49 crc_refin_true = 1, /*!< Reflect each byte in the input stream bitwise. */
50 } crc_refin_t;
51
52 /**
53 * @brief CRC Refout definitions.
54 */
55 typedef enum crc_refout_enum {
56 crc_refout_false = 0, /*!< Do not manipulate output data stream. */
57 crc_refout_true = 1, /*!< Reflect each byte in the output stream bitwise. */
58 } crc_refout_t;
59
60 /**
61 * @brief crc input data stream byte order definitions.
62 */
63 typedef enum crc_in_byte_order_enum {
64 crc_in_byte_order_lsb = 0, /*!< Byte order of the CRC DATA LS Byte first. */
65 crc_in_byte_order_msb = 1, /*!< Byte order of the CRC DATA MS Byte first. */
66 } crc_in_byte_order_t;
67
68 #define CRC_POLY_WIDTH_4 (4U)
69 #define CRC_POLY_WIDTH_5 (5U)
70 #define CRC_POLY_WIDTH_6 (6U)
71 #define CRC_POLY_WIDTH_7 (7U)
72 #define CRC_POLY_WIDTH_8 (8U)
73 #define CRC_POLY_WIDTH_16 (16U)
74 #define CRC_POLY_WIDTH_24 (24U)
75 #define CRC_POLY_WIDTH_32 (32U)
76
77 /**
78 * @brief Channel config
79 */
80 typedef struct crc_channel_config {
81 crc_preset_t preset; /*!< Preset CRC. See "crc_preset_t". */
82 uint32_t init; /*!< Initial value for CRC. */
83 uint32_t poly; /*!< Poly for CRC. */
84 uint32_t poly_width; /*!< CRC poly width. See "CRC_POLY_WIDTH_x". */
85 crc_in_byte_order_t in_byte_order; /*!< CRC intput byte order. See "crc_in_byte_order_t". */
86 crc_refout_t refout; /*!< CRC reflect output. See "crc_refout_t". */
87 crc_refin_t refin; /*!< CRC reflect iutput. See "crc_refin_t". */
88 uint32_t xorout; /*!< XOR mask for CRC result (for no mask, should be 0). */
89 } crc_channel_config_t;
90
91 #define CRC_REG_WRITE8(addr, data)\
92 {\
93 uint32_t addr32 = (uint32_t)(addr);\
94 (*(volatile uint8_t *)(addr32) = (data));\
95 }
96
97 #define CRC_REG_WRITE16(addr, data)\
98 {\
99 uint32_t addr32 = (uint32_t)(addr);\
100 (*(volatile uint16_t *)(addr32) = (data));\
101 }
102
103 #define CRC_REG_WRITE32(addr, data)\
104 {\
105 uint32_t addr32 = (uint32_t)(addr);\
106 (*(volatile uint32_t *)(addr32) = (data));\
107 }
108
109 #ifdef __cplusplus
110 extern "C" {
111 #endif
112
113 /**
114 * @brief Reset CRC channel
115 *
116 * @param[in] ptr CRC base address
117 * @param[in] ch_index Index of the channel to be reset
118 *
119 */
crc_reset(CRC_Type * ptr,uint32_t ch_index)120 static inline void crc_reset(CRC_Type *ptr, uint32_t ch_index)
121 {
122 ptr->CHN[ch_index].CLR |= CRC_CHN_CLR_CLR_MASK;
123 }
124
125 /**
126 * @brief Get default channel config
127 *
128 * @param[in] ptr CRC base address
129 * @param[in] cfg Channel config
130 */
131 void crc_get_default_channel_config(crc_channel_config_t *cfg);
132
133 /**
134 * @brief Setup CRC channel
135 *
136 * @param[in] ptr CRC base address
137 * @param[in] ch_index Target channel index to be configured
138 * @param[in] cfg Channel config
139 *
140 * @return status_success if everything is okay
141 */
142 hpm_stat_t crc_setup_channel_config(CRC_Type *ptr, uint32_t ch_index,
143 crc_channel_config_t *cfg);
144
145 /**
146 * @brief Calculate one byte data crc
147 *
148 * @param[in] ptr CRC base address
149 * @param[in] ch_index CRC channel index
150 * @param[in] data Data that to be calculate
151 */
crc_calc_byte(CRC_Type * ptr,uint32_t ch_index,uint8_t data)152 static inline void crc_calc_byte(CRC_Type *ptr, uint32_t ch_index, uint8_t data)
153 {
154 CRC_REG_WRITE8(&ptr->CHN[ch_index].DATA, data);
155 }
156
157 /**
158 * @brief Calculate length bytes data block crc
159 *
160 * @param[in] ptr CRC base address
161 * @param[in] ch_index CRC channel index
162 * @param[in] pbuffer Data to be calculate buffer
163 * @param[in] length Number of pbuffer, unit is byte
164 */
165 void crc_calc_block_bytes(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length);
166
167 /**
168 * @brief Calculate half-word data crc
169 *
170 * @param[in] ptr CRC base address
171 * @param[in] ch_index CRC channel index
172 * @param[in] data Data that to be calculate
173 */
crc_calc_half_word(CRC_Type * ptr,uint32_t ch_index,uint16_t data)174 static inline void crc_calc_half_word(CRC_Type *ptr, uint32_t ch_index, uint16_t data)
175 {
176 CRC_REG_WRITE16(&ptr->CHN[ch_index].DATA, data);
177 }
178
179 /**
180 * @brief Calculate length half-words data block crc
181 *
182 * @param[in] ptr CRC base address
183 * @param[in] ch_index CRC channel index
184 * @param[in] pbuffer Data to be calculate buffer
185 * @param[in] length Number of pbuffer, unit is half word(2 bytes)
186 */
187 void crc_calc_block_half_words(CRC_Type *ptr, uint32_t ch_index, uint16_t *pbuffer, uint32_t length);
188
189 /**
190 * @brief Calculate word data crc
191 *
192 * @param[in] ptr CRC base address
193 * @param[in] ch_index CRC channel index
194 * @param[in] data Data that to be calculate
195 */
crc_calc_word(CRC_Type * ptr,uint32_t ch_index,uint32_t data)196 static inline void crc_calc_word(CRC_Type *ptr, uint32_t ch_index, uint32_t data)
197 {
198 CRC_REG_WRITE32(&ptr->CHN[ch_index].DATA, data);
199 }
200
201 /**
202 * @brief Calculate length words data block crc
203 *
204 * @param[in] ptr CRC base address
205 * @param[in] ch_index CRC channel index
206 * @param[in] pbuffer Data to be calculate buffer
207 * @param[in] length Number of pbuffer, unit is word(4 bytes)
208 */
209 void crc_calc_block_words(CRC_Type *ptr, uint32_t ch_index, uint32_t *pbuffer, uint32_t length);
210
211 /**
212 * @brief Fast calculate length bytes large data block crc
213 *
214 * @param[in] ptr CRC base address
215 * @param[in] ch_index CRC channel index
216 * @param[in] pbuffer Data to be calculate buffer
217 * @param[in] length Number of pbuffer, unit is byte
218 */
219 void crc_calc_large_block_fast(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length);
220
221 /**
222 * @brief Get CRC result
223 *
224 * @param[in] ptr CRC base address
225 * @param[in] ch_index Index of the channel to be get
226 * @return CRC result
227 */
crc_get_result(CRC_Type * ptr,uint32_t ch_index)228 static inline uint32_t crc_get_result(CRC_Type *ptr, uint32_t ch_index)
229 {
230 return ptr->CHN[ch_index].RESULT;
231 }
232 #ifdef __cplusplus
233 }
234 #endif
235
236 /**
237 * @}
238 */
239
240 #endif /* HPM_CRC_DRV_H */
241