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