• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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