1 /*
2 * Copyright (c) 2024 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_PPI_DRV_H
9 #define HPM_PPI_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_soc_ip_feature.h"
13 #include "hpm_ppi_regs.h"
14
15 /**
16 * @brief PPI driver APIs
17 * @defgroup ppi_interface PPI driver APIs
18 * @ingroup ppi_interfaces
19 * @{
20 */
21
22 /**
23 * @brief cs pin idle polarity
24 *
25 */
26 typedef enum {
27 ppi_cs_idle_pol_low = 0,
28 ppi_cs_idle_pol_high
29 } ppi_cs_idle_polarity_t; /**< ppi_cs_idle_polarity_t */
30
31 /**
32 * @brief dm pin valid polarity
33 *
34 */
35 typedef enum {
36 ppi_dm_valid_pol_high = 0,
37 ppi_dm_valid_pol_low
38 } ppi_dm_valid_polarity_t; /**< ppi_dm_valid_polarity_t */
39
40 /**
41 * @brief ctrl pin polarity
42 *
43 */
44 typedef enum {
45 ppi_ctrl_pol_low = 0,
46 ppi_ctrl_pol_high
47 } ppi_ctrl_polarity_t; /**< ppi_ctrl_polarity_t */
48
49 /**
50 * @brief ctrl pin direction
51 *
52 */
53 typedef enum {
54 ppi_ctrl_pin_dir_input = 0,
55 ppi_ctrl_pin_dir_output,
56 } ppi_ctrl_pin_dir_t; /**< ppi_ctrl_pin_dir_t */
57
58 /**
59 * @brief clock pin output mode
60 *
61 */
62 typedef enum {
63 ppi_clk_output_by_cmd_clk_output = 0,
64 ppi_clk_always_output
65 } ppi_clk_output_mode_t; /**< ppi_clk_output_mode_t */
66
67 /**
68 * @brief irq mask
69 *
70 */
71 typedef enum {
72 ppi_irq_tm_out_mask = PPI_IRQ_EN_IRQ_TMOUT_EN_MASK,
73 } ppi_irq_mask_t; /**< ppi_irq_mask_t */
74
75 /**
76 * @brief port size
77 *
78 */
79 typedef enum {
80 ppi_port_size_8bits = 0,
81 ppi_port_size_16bits,
82 ppi_port_size_32bits,
83 } ppi_port_size_t; /**< ppi_port_size_t */
84
85 /**
86 * @brief cmd byte select
87 *
88 */
89 typedef enum {
90 ppi_byte_sel_0_7_bits = 0,
91 ppi_byte_sel_8_15_bits,
92 ppi_byte_sel_16_23_bits,
93 ppi_byte_sel_24_31_bits
94 } ppi_byte_sel_t; /**< ppi_byte_sel_t */
95
96 /**
97 * @brief cmd address and data function
98 *
99 */
100 typedef enum {
101 ppi_ad_func_data = 0,
102 ppi_ad_func_addr
103 } ppi_ad_func_t; /**< ppi_ad_func_t */
104
105 /**
106 * @brief cmd address and data pins direction
107 *
108 */
109 typedef enum {
110 ppi_ad_pin_dir_output = 0,
111 ppi_ad_pin_dir_input
112 } ppi_ad_pin_dir_t; /**< ppi_ad_pin_dir_t */
113
114 /**
115 * @brief clock pin config structure
116 *
117 */
118 typedef struct {
119 uint8_t cycle_num;
120 uint8_t high_num;
121 uint8_t low_num;
122 ppi_clk_output_mode_t mode;
123 bool revert;
124 } ppi_clk_pin_config_t; /**< ppi_clk_pin_config_t */
125
126 /**
127 * @brief cs pin config structure
128 *
129 */
130 typedef struct {
131 ppi_port_size_t port_size;
132 uint16_t addr_start_high_12bits; /* address space: 0xF8000000 ~ 0xFFFFFFFF */
133 uint16_t addr_end_high_12bits; /* address space: 0xF8000000 ~ 0xFFFFFFFF */
134 uint16_t addr_mask;
135 bool sync_clk_en;
136 uint8_t sync_clk_sel;
137 uint8_t interval_cycle;
138 uint8_t rcmd_start0;
139 uint8_t rcmd_end0;
140 uint8_t rcmd_start1;
141 uint8_t rcmd_end1;
142 uint8_t wcmd_start0;
143 uint8_t wcmd_end0;
144 uint8_t wcmd_start1;
145 uint8_t wcmd_end1;
146 #if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
147 ppi_dm_valid_polarity_t dm_polarity;
148 #endif
149 } ppi_cs_pin_config_t; /**< ppi_cs_pin_config_t */
150
151 /**
152 * @brief cmd config structure
153 *
154 */
155 typedef struct {
156 bool cs_pin_value;
157 bool clk_output;
158 uint8_t cmd_cycle;
159 ppi_ad_func_t ad_func_sel[4];
160 ppi_ad_pin_dir_t ad_pin_dir[4];
161 ppi_byte_sel_t byte_sel[4];
162 bool ctrl_pin_value[8];
163 } ppi_cmd_config_t; /**< ppi_cmd_config_t */
164
165 #ifdef __cplusplus
166 extern "C" {
167 #endif
168
169 /**
170 * @brief set ppi software reset
171 *
172 * @param[in] ppi PPI base address
173 * @param[in] reset true - software reset; false - normal work.
174 */
ppi_set_reset(PPI_Type * ppi,bool reset)175 static inline void ppi_set_reset(PPI_Type *ppi, bool reset)
176 {
177 if (reset) {
178 ppi->GLB_CFG |= PPI_GLB_CFG_SOFT_RESET_MASK;
179 } else {
180 ppi->GLB_CFG &= ~PPI_GLB_CFG_SOFT_RESET_MASK;
181 }
182 }
183
184 /**
185 * @brief config cs pin work valid polarity
186 *
187 * @param[in] ppi PPI base address
188 * @param[in] index cs pin index, value: 0 - 3
189 * @param[in] pol @ref ppi_cs_idle_polarity_t
190 */
ppi_config_cs_pin_polarity(PPI_Type * ppi,uint8_t index,ppi_cs_idle_polarity_t pol)191 static inline void ppi_config_cs_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_cs_idle_polarity_t pol)
192 {
193 assert(index < 4);
194 ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CS_IDLE_ST_SHIFT) << index))) | (((pol << PPI_PAD_CFG_CS_IDLE_ST_SHIFT) << index));
195 }
196
197 /**
198 * @brief config dm pin work polarity
199 *
200 * @param[in] ppi PPI base address
201 * @param[in] index If has HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS feature, this is cs pin index, value: 0 - 3. Else, not use.
202 * @param[in] pol @ref ppi_dm_valid_polarity_t
203 */
ppi_config_dm_pin_polarity(PPI_Type * ppi,uint8_t index,ppi_dm_valid_polarity_t pol)204 static inline void ppi_config_dm_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_dm_valid_polarity_t pol)
205 {
206 #if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
207 assert(index < 4);
208 ppi->CS[index].CFG2 = (ppi->CS[index].CFG2 & ~PPI_CS_CFG2_DM_POLARITY_MASK) | PPI_CS_CFG2_DM_POLARITY_SET(pol);
209 #else
210 (void)index;
211 if (pol == ppi_dm_valid_pol_high) {
212 ppi->PAD_CFG &= ~PPI_PAD_CFG_DM_PAD_POL_MASK;
213 } else {
214 ppi->PAD_CFG |= PPI_PAD_CFG_DM_PAD_POL_MASK;
215 }
216 #endif
217 }
218
219 /**
220 * @brief config ctrl pin work polarity, output and input ctrl pin polarity has different meaning
221 *
222 * @param[in] ppi PPI base address
223 * @param[in] index Ctrl pin index, value: 0 - 7
224 * @param[in] pol @ref ppi_ctrl_polarity_t
225 * [1] Output: ppi_ctrl_pol_low is output the value in cmd; ppi_ctrl_pol_high is output reversed value in cmd.
226 * [2] Input: ppi_ctrl_pol_low is input low valid; ppi_ctrl_pol_high is input high valid.
227 */
ppi_config_ctrl_pin_polarity(PPI_Type * ppi,uint8_t index,ppi_ctrl_polarity_t pol)228 static inline void ppi_config_ctrl_pin_polarity(PPI_Type *ppi, uint8_t index, ppi_ctrl_polarity_t pol)
229 {
230 assert(index < 8);
231 ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CTRL_PAD_POL_SHIFT) << index))) | (((pol << PPI_PAD_CFG_CTRL_PAD_POL_SHIFT) << index));
232 }
233
234 /**
235 * @brief set ctrl pin direction
236 *
237 * @param[in] ppi PPI base address
238 * @param[in] index Ctrl pin index, value: 0 - 7
239 * @param[in] dir Ctrl pin direction, @ref ppi_ctrl_pin_dir_t
240 */
ppi_set_ctrl_pin_dir(PPI_Type * ppi,uint8_t index,ppi_ctrl_pin_dir_t dir)241 static inline void ppi_set_ctrl_pin_dir(PPI_Type *ppi, uint8_t index, ppi_ctrl_pin_dir_t dir)
242 {
243 assert(index < 8);
244 ppi->PAD_CFG = (ppi->PAD_CFG & ~(((1u << PPI_PAD_CFG_CTRL_PAD_OE_SHIFT) << index))) | (((dir << PPI_PAD_CFG_CTRL_PAD_OE_SHIFT) << index));
245 }
246
247 /**
248 * @brief config timeout
249 *
250 * @param[in] ppi PPI base address
251 * @param[in] timeout_cnt timeout counter
252 * @param[in] enable true - enable; false - disable
253 */
ppi_config_timeout(PPI_Type * ppi,uint16_t timeout_cnt,bool enable)254 static inline void ppi_config_timeout(PPI_Type *ppi, uint16_t timeout_cnt, bool enable)
255 {
256 ppi->TM_CFG = PPI_TM_CFG_TM_CFG_SET(timeout_cnt) | PPI_TM_CFG_TM_EN_SET(enable);
257 }
258
259 /**
260 * @brief set irq enable
261 *
262 * @param[in] ppi PPI base address
263 * @param[in] mask irq mask, @ref ppi_irq_mask_t
264 */
ppi_set_irq_enable(PPI_Type * ppi,uint32_t mask)265 static inline void ppi_set_irq_enable(PPI_Type *ppi, uint32_t mask)
266 {
267 ppi->IRQ_EN |= mask;
268 }
269
270 /**
271 * @brief set irq disable
272 *
273 * @param[in] ppi PPI base address
274 * @param[in] mask irq mask, @ref ppi_irq_mask_t
275 */
ppi_set_irq_disable(PPI_Type * ppi,uint32_t mask)276 static inline void ppi_set_irq_disable(PPI_Type *ppi, uint32_t mask)
277 {
278 ppi->IRQ_EN &= ~mask;
279 }
280
281 /**
282 * @brief get irq enable status
283 *
284 * @param[in] ppi PPI base address
285 * @retval irq enable status, @ref ppi_irq_mask_t
286 */
ppi_get_irq_enable_status(PPI_Type * ppi)287 static inline uint32_t ppi_get_irq_enable_status(PPI_Type *ppi)
288 {
289 return ppi->IRQ_EN;
290 }
291
292 /**
293 * @brief get irq status
294 *
295 * @param[in] ppi PPI base address
296 * @retval irq status, @ref ppi_irq_mask_t
297 */
ppi_get_irq_status(PPI_Type * ppi)298 static inline uint32_t ppi_get_irq_status(PPI_Type *ppi)
299 {
300 return ppi->IRQ_STS;
301 }
302
303 /**
304 * @brief clear irq flag
305 *
306 * @param[in] ppi PPI base address
307 * @param[in] mask irq mask, @ref ppi_irq_mask_t
308 */
ppi_clear_irq_flag(PPI_Type * ppi,uint32_t mask)309 static inline void ppi_clear_irq_flag(PPI_Type *ppi, uint32_t mask)
310 {
311 ppi->IRQ_STS = mask;
312 }
313
314 /**
315 * @brief set clk pin enable
316 *
317 * @param[in] ppi PPI base address
318 */
ppi_set_clk_pin_enable(PPI_Type * ppi)319 static inline void ppi_set_clk_pin_enable(PPI_Type *ppi)
320 {
321 ppi->CLKPIN_CFG |= PPI_CLKPIN_CFG_EN_MASK;
322 }
323
324 /**
325 * @brief set clk pin disable
326 *
327 * @param[in] ppi PPI base address
328 */
ppi_set_clk_pin_disable(PPI_Type * ppi)329 static inline void ppi_set_clk_pin_disable(PPI_Type *ppi)
330 {
331 ppi->CLKPIN_CFG &= ~PPI_CLKPIN_CFG_EN_MASK;
332 }
333
334 /**
335 * @brief config clock pin output
336 *
337 * @param[in] ppi PPI base address
338 * @param[in] config clock pin config structure pointer, @ref ppi_clk_pin_config_t
339 */
340 void ppi_config_clk_pin(PPI_Type *ppi, ppi_clk_pin_config_t *config);
341
342 /**
343 * @brief config cs pin
344 *
345 * @param[in] ppi PPI base address
346 * @param[in] index cs pin index, value: 0 - 3
347 * @param[in] config cs pin config structure pointer, @ref ppi_cs_pin_config_t
348 */
349 void ppi_config_cs_pin(PPI_Type *ppi, uint8_t index, ppi_cs_pin_config_t *config);
350
351 /**
352 * @brief config cmd
353 *
354 * @param[in] ppi PPI base address
355 * @param[in] index cmd index, value: 0 - 63
356 * @param[in] config cmd config structure pointer, @ref ppi_cmd_config_t
357 */
358 void ppi_config_cmd(PPI_Type *ppi, uint8_t index, ppi_cmd_config_t *config);
359
360 #ifdef __cplusplus
361 }
362 #endif
363 /**
364 * @}
365 */
366 #endif /* HPM_PPI_DRV_H */
367