hpm_gpio_drv.h 8.9 KB

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