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