• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_GPIO_DRV_H
9 #define HPM_GPIO_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_gpio_regs.h"
13 #include "hpm_soc_feature.h"
14 
15 #ifndef PORT_PIN_COUNT
16 #define PORT_PIN_COUNT (32U)
17 #endif
18 #define GPIO_GET_PORT_INDEX(x) (x / PORT_PIN_COUNT)
19 #define GPIO_GET_PIN_INDEX(x)  (x % PORT_PIN_COUNT)
20 
21 /**
22  *
23  * @brief GPIO driver APIs
24  * @defgroup gpio_interface GPIO driver APIs
25  * @ingroup io_interfaces
26  * @{
27  */
28 
29 /**
30  * @brief Interrupt trigger type
31  */
32 typedef enum gpio_interrupt_trigger {
33     gpio_interrupt_trigger_level_high = 0,
34     gpio_interrupt_trigger_level_low,
35     gpio_interrupt_trigger_edge_rising,
36     gpio_interrupt_trigger_edge_falling,
37 #if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)
38     gpio_interrupt_trigger_edge_both,
39 #endif
40 } gpio_interrupt_trigger_t;
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /**
47  * @brief   Read target pin level
48  *
49  * @param ptr GPIO base address
50  * @param port Port index
51  * @param pin Pin index
52  *
53  * @return Pin status mask
54  */
gpio_read_pin(GPIO_Type * ptr,uint32_t port,uint8_t pin)55 static inline uint8_t gpio_read_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin)
56 {
57     return (ptr->DI[port].VALUE & (1 << pin)) >> pin;
58 }
59 
60 /**
61  * @brief   Read target pin output state
62  *
63  * @param ptr GPIO base address
64  * @param port Port index
65  * @param pin Pin index
66  *
67  * @return Pin output state
68  */
gpio_get_pin_output_status(GPIO_Type * ptr,uint32_t port,uint8_t pin)69 static inline uint32_t gpio_get_pin_output_status(GPIO_Type *ptr, uint32_t port, uint8_t pin)
70 {
71     return (ptr->DO[port].VALUE & (1 << pin)) >> pin;
72 }
73 
74 /**
75  * @brief   Toggle pin level
76  *
77  * @param ptr GPIO base address
78  * @param port Port index
79  * @param pin Pin index
80  */
gpio_toggle_pin(GPIO_Type * ptr,uint32_t port,uint8_t pin)81 static inline void gpio_toggle_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin)
82 {
83     ptr->DO[port].TOGGLE = 1 << pin;
84 }
85 
86 /**
87  * @brief   Write pin level
88  *
89  * @param ptr GPIO base address
90  * @param port Port index
91  * @param pin Pin index
92  * @param high Pin level set to high when it is set to true
93  */
gpio_write_pin(GPIO_Type * ptr,uint32_t port,uint8_t pin,uint8_t high)94 static inline void gpio_write_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin, uint8_t high)
95 {
96     if (high) {
97         ptr->DO[port].SET = 1 << pin;
98     } else {
99         ptr->DO[port].CLEAR = 1 << pin;
100     }
101 }
102 
103 /**
104  * @brief   Set pin to input mode
105  *
106  * @param ptr GPIO base address
107  * @param port Port index
108  * @param pin Pin index
109  */
gpio_set_pin_input(GPIO_Type * ptr,uint32_t port,uint8_t pin)110 static inline void gpio_set_pin_input(GPIO_Type *ptr, uint32_t port, uint8_t pin)
111 {
112     ptr->OE[port].CLEAR = 1 << pin;
113 }
114 
115 /**
116  * @brief   Set pin to output mode
117  *
118  * @param ptr GPIO base address
119  * @param port Port index
120  * @param pin Pin index
121  */
gpio_set_pin_output(GPIO_Type * ptr,uint32_t port,uint8_t pin)122 static inline void gpio_set_pin_output(GPIO_Type *ptr, uint32_t port, uint8_t pin)
123 {
124     ptr->OE[port].SET = 1 << pin;
125 }
126 
127 /**
128  * @brief   Set pin to output mode with initial value
129  *
130  * @param ptr GPIO base address
131  * @param port Port index
132  * @param pin Pin index
133  * @param initial Initial value
134  */
135 void gpio_set_pin_output_with_initial(GPIO_Type *ptr, uint32_t port, uint8_t pin, uint8_t initial);
136 
137 /**
138  * @brief   Check specific pin interrupt status
139  *
140  * @param ptr GPIO base address
141  * @param port Port index
142  * @param pin Pin index
143  *
144  * @return true if interrupt flag is set
145  */
gpio_check_pin_interrupt_flag(GPIO_Type * ptr,uint32_t port,uint8_t pin)146 static inline bool gpio_check_pin_interrupt_flag(GPIO_Type *ptr, uint32_t port, uint8_t pin)
147 {
148     return ptr->IF[port].VALUE & (1 << pin);
149 }
150 
151 /**
152  * @brief   Clear specific pin interrupt flag
153  *
154  * @param ptr GPIO base address
155  * @param port Port index
156  * @param pin Pin index
157  */
gpio_clear_pin_interrupt_flag(GPIO_Type * ptr,uint32_t port,uint8_t pin)158 static inline void gpio_clear_pin_interrupt_flag(GPIO_Type *ptr, uint32_t port, uint8_t pin)
159 {
160     ptr->IF[port].VALUE = 1 << pin;
161 }
162 
163 /**
164  * @brief   Check if specific pin interrupt is enabled or not
165  *
166  * @param ptr GPIO base address
167  * @param port Port index
168  * @param pin Pin index
169  *
170  * @return true if interrupt is enabled
171  */
gpio_check_pin_interrupt_enabled(GPIO_Type * ptr,uint32_t port,uint8_t pin)172 static inline bool gpio_check_pin_interrupt_enabled(GPIO_Type *ptr, uint32_t port, uint8_t pin)
173 {
174     return (ptr->IE[port].VALUE & (1 << pin)) == (uint32_t) (1 << pin);
175 }
176 
177 /**
178  * @brief  Enable interrupt for specific pin
179  *
180  * @param ptr GPIO base address
181  * @param port Port index
182  * @param pin Pin index
183  */
gpio_enable_pin_interrupt(GPIO_Type * ptr,uint32_t port,uint8_t pin)184 static inline void gpio_enable_pin_interrupt(GPIO_Type *ptr, uint32_t port, uint8_t pin)
185 {
186     ptr->IE[port].SET = 1 << pin;
187 }
188 
189 /**
190  * @brief   Disable interrupt for specific pin
191  *
192  * @param ptr GPIO base address
193  * @param port Port index
194  * @param pin Pin index
195  */
gpio_disable_pin_interrupt(GPIO_Type * ptr,uint32_t port,uint8_t pin)196 static inline void gpio_disable_pin_interrupt(GPIO_Type *ptr, uint32_t port, uint8_t pin)
197 {
198     ptr->IE[port].CLEAR = 1 << pin;
199 }
200 
201 /**
202  * @brief   Check interrupt flag of specific pin and clear if it is set
203  *
204  * @param ptr GPIO base address
205  * @param port Port index
206  * @param pin Pin index
207  *
208  * @return true if the interrupt flag is set and cleared
209  * @return false if the interrupt flag is not set
210  */
gpio_check_clear_interrupt_flag(GPIO_Type * ptr,uint32_t port,uint8_t pin)211 static inline bool gpio_check_clear_interrupt_flag(GPIO_Type *ptr, uint32_t port, uint8_t pin)
212 {
213     if (!gpio_check_pin_interrupt_flag(ptr, port, pin)) {
214         return false;
215     }
216     gpio_clear_pin_interrupt_flag(ptr, port, pin);
217     return true;
218 }
219 
220 
221 /**
222  * @brief   Read all pins level on specific port
223  *
224  * @param ptr GPIO base address
225  * @param port Port index
226  *
227  * @return Port pin level status
228  */
gpio_read_port(GPIO_Type * ptr,uint32_t port)229 static inline uint32_t gpio_read_port(GPIO_Type *ptr, uint32_t port)
230 {
231     return ptr->DI[port].VALUE;
232 }
233 
234 /**
235  * @brief   Toggle port with specific pin mask
236  *
237  * @param ptr GPIO base address
238  * @param port Port index
239  * @param mask Mask pins to be toggled
240  */
gpio_toggle_port_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)241 static inline void gpio_toggle_port_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
242 {
243     ptr->DO[port].TOGGLE = mask;
244 }
245 
246 /**
247  * @brief   Write specific port with value
248  *
249  * @param ptr GPIO base address
250  * @param port Port index
251  * @param value Value to be written
252  */
gpio_write_port(GPIO_Type * ptr,uint32_t port,uint32_t value)253 static inline void gpio_write_port(GPIO_Type *ptr, uint32_t port, uint32_t value)
254 {
255     ptr->DO[port].VALUE = value;
256 }
257 
258 /**
259  * @brief   Set spcific port pin high according to the given mask
260  *
261  * @param ptr GPIO base address
262  * @param port Port index
263  * @param mask Mask of pins to be set to low
264  */
gpio_set_port_low_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)265 static inline void gpio_set_port_low_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
266 {
267     ptr->DO[port].CLEAR = mask;
268 }
269 
270 /**
271  * @brief   Set spcific port pin high according to the given mask
272  *
273  * @param ptr GPIO base address
274  * @param port Port index
275  * @param mask Mask of pins to be set to high
276  */
gpio_set_port_high_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)277 static inline void gpio_set_port_high_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
278 {
279     ptr->DO[port].SET = mask;
280 }
281 
282 /**
283  * @brief   Enable pins output of specific port according to the given mask
284  *
285  * @param ptr GPIO base address
286  * @param port Port index
287  * @param mask Mask of pins to be enabled
288  */
gpio_enable_port_output_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)289 static inline void gpio_enable_port_output_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
290 {
291     ptr->OE[port].SET = mask;
292 }
293 
294 /**
295  * @brief   Disable pins output of specific port according to the given mask
296  *
297  * @param ptr GPIO base address
298  * @param port Port index
299  * @param mask Mask of pins to be disabled
300  */
gpio_disable_port_output_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)301 static inline void gpio_disable_port_output_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
302 {
303     ptr->OE[port].CLEAR = mask;
304 }
305 
306 /**
307  * @brief   Get current interrupt flags on specific port
308  *
309  * @param ptr GPIO base address
310  * @param port Port index
311  *
312  * @return Current interrupt flags on specific port
313  */
gpio_get_port_interrupt_flags(GPIO_Type * ptr,uint32_t port)314 static inline uint32_t gpio_get_port_interrupt_flags(GPIO_Type *ptr, uint32_t port)
315 {
316     return ptr->IF[port].VALUE;
317 }
318 
319 
320 /**
321  * @brief   Clear interrupt flags with given mask on specific port
322  *
323  * @param ptr GPIO base address
324  * @param port Port index
325  * @param mask Mask of interrupts to be cleared
326  */
gpio_clear_port_interrupt_flags_with_mask(GPIO_Type * ptr,uint32_t port,uint32_t mask)327 static inline void gpio_clear_port_interrupt_flags_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask)
328 {
329     ptr->IF[port].VALUE |= mask;
330 }
331 
332 /**
333  * @brief   Enable interrupts with given mask on specific port
334  *
335  * @param ptr GPIO base address
336  * @param port Port index
337  * @param mask Mask of interrupts to be enabled
338  */
gpio_enable_port_interrupt_with_mask(GPIO_Type * ptr,uint32_t port,uint8_t mask)339 static inline void gpio_enable_port_interrupt_with_mask(GPIO_Type *ptr, uint32_t port, uint8_t mask)
340 {
341     ptr->IE[port].SET = mask;
342 }
343 
344 /**
345  * @brief   Disable interrupts with given mask on specific port
346  *
347  * @param ptr GPIO base address
348  * @param port Port index
349  * @param mask Mask of interrupts to be disabled
350  */
gpio_disable_port_interrupt_with_mask(GPIO_Type * ptr,uint32_t port,uint8_t mask)351 static inline void gpio_disable_port_interrupt_with_mask(GPIO_Type *ptr, uint32_t port, uint8_t mask)
352 {
353     ptr->IE[port].CLEAR = mask;
354 }
355 
356 
357 /**
358  * @brief   Config pin interrupt
359  *
360  * @param ptr GPIO base address
361  * @param port Port index
362  * @param pin Pin index
363  * @param trigger Trigger type
364  */
365 void gpio_config_pin_interrupt(GPIO_Type *ptr, uint32_t port, uint8_t pin, gpio_interrupt_trigger_t trigger);
366 
367 
368 /**
369  * @brief   Toggle pin interrupt trigger polarity
370  *
371  * @param ptr GPIO base address
372  * @param port Port index
373  * @param pin Pin index
374  */
375 void gpio_toggle_pin_interrupt_trigger_polarity(GPIO_Type *ptr, uint32_t port, uint8_t pin);
376 
377 /**
378  * @brief   Toggle pin interrupt trigger type
379  *
380  * @param ptr GPIO base address
381  * @param port Port index
382  * @param pin Pin index
383  */
384 void gpio_toggle_pin_interrupt_trigger_type(GPIO_Type *ptr, uint32_t port, uint8_t pin);
385 #ifdef __cplusplus
386 }
387 #endif
388 /**
389  * @}
390  */
391 #endif /* HPM_GPIO_DRV_H */
392