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