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 Get default channel config
115 *
116 * @param[in] cfg Channel config
117 */
118 void crc_get_default_channel_config(crc_channel_config_t *cfg);
119
120 /**
121 * @brief Setup CRC channel
122 *
123 * @param[in] ptr CRC base address
124 * @param[in] ch_index Target channel index to be configured
125 * @param[in] cfg Channel config
126 *
127 * @return status_success if everything is okay
128 */
129 hpm_stat_t crc_setup_channel_config(CRC_Type *ptr, uint32_t ch_index,
130 crc_channel_config_t *cfg);
131
132 /**
133 * @brief Calculate one byte data crc
134 *
135 * @param[in] ptr CRC base address
136 * @param[in] ch_index CRC channel index
137 * @param[in] data Data that to be calculate
138 */
crc_calc_byte(CRC_Type * ptr,uint32_t ch_index,uint8_t data)139 static inline void crc_calc_byte(CRC_Type *ptr, uint32_t ch_index, uint8_t data)
140 {
141 CRC_REG_WRITE8(&ptr->CHN[ch_index].DATA, data);
142 }
143
144 /**
145 * @brief Calculate length bytes data block crc
146 *
147 * @param[in] ptr CRC base address
148 * @param[in] ch_index CRC channel index
149 * @param[in] pbuffer Data to be calculate buffer
150 * @param[in] length Number of pbuffer, unit is byte
151 */
152 void crc_calc_block_bytes(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length);
153
154 /**
155 * @brief Calculate half-word data crc
156 *
157 * @param[in] ptr CRC base address
158 * @param[in] ch_index CRC channel index
159 * @param[in] data Data that to be calculate
160 */
crc_calc_half_word(CRC_Type * ptr,uint32_t ch_index,uint16_t data)161 static inline void crc_calc_half_word(CRC_Type *ptr, uint32_t ch_index, uint16_t data)
162 {
163 CRC_REG_WRITE16(&ptr->CHN[ch_index].DATA, data);
164 }
165
166 /**
167 * @brief Calculate length half-words data block crc
168 *
169 * @param[in] ptr CRC base address
170 * @param[in] ch_index CRC channel index
171 * @param[in] pbuffer Data to be calculate buffer
172 * @param[in] length Number of pbuffer, unit is half word(2 bytes)
173 */
174 void crc_calc_block_half_words(CRC_Type *ptr, uint32_t ch_index, uint16_t *pbuffer, uint32_t length);
175
176 /**
177 * @brief Calculate word data crc
178 *
179 * @param[in] ptr CRC base address
180 * @param[in] ch_index CRC channel index
181 * @param[in] data Data that to be calculate
182 */
crc_calc_word(CRC_Type * ptr,uint32_t ch_index,uint32_t data)183 static inline void crc_calc_word(CRC_Type *ptr, uint32_t ch_index, uint32_t data)
184 {
185 CRC_REG_WRITE32(&ptr->CHN[ch_index].DATA, data);
186 }
187
188 /**
189 * @brief Calculate length words data block crc
190 *
191 * @param[in] ptr CRC base address
192 * @param[in] ch_index CRC channel index
193 * @param[in] pbuffer Data to be calculate buffer
194 * @param[in] length Number of pbuffer, unit is word(4 bytes)
195 */
196 void crc_calc_block_words(CRC_Type *ptr, uint32_t ch_index, uint32_t *pbuffer, uint32_t length);
197
198 /**
199 * @brief Fast calculate length bytes large data block crc
200 *
201 * @param[in] ptr CRC base address
202 * @param[in] ch_index CRC channel index
203 * @param[in] pbuffer Data to be calculate buffer
204 * @param[in] length Number of pbuffer, unit is byte
205 */
206 void crc_calc_large_block_fast(CRC_Type *ptr, uint32_t ch_index, uint8_t *pbuffer, uint32_t length);
207
208 /**
209 * @brief Get CRC result
210 *
211 * @param[in] ptr CRC base address
212 * @param[in] ch_index Index of the channel to be get
213 * @return CRC result
214 */
crc_get_result(CRC_Type * ptr,uint32_t ch_index)215 static inline uint32_t crc_get_result(CRC_Type *ptr, uint32_t ch_index)
216 {
217 return ptr->CHN[ch_index].RESULT;
218 }
219 #ifdef __cplusplus
220 }
221 #endif
222
223 /**
224 * @}
225 */
226
227 #endif /* HPM_CRC_DRV_H */
228