Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

383 linhas
13 KiB

  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_gpio.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.gpio"
  12. #endif
  13. /*******************************************************************************
  14. * Variables
  15. ******************************************************************************/
  16. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  17. static PORT_Type *const s_portBases[] = PORT_BASE_PTRS;
  18. static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
  19. #endif
  20. #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
  21. #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
  22. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  23. /*! @brief Array to map FGPIO instance number to clock name. */
  24. static const clock_ip_name_t s_fgpioClockName[] = FGPIO_CLOCKS;
  25. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  26. #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
  27. #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */
  28. /*******************************************************************************
  29. * Prototypes
  30. ******************************************************************************/
  31. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  32. /*!
  33. * @brief Gets the GPIO instance according to the GPIO base
  34. *
  35. * @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
  36. * @retval GPIO instance
  37. */
  38. static uint32_t GPIO_GetInstance(GPIO_Type *base);
  39. #endif
  40. /*******************************************************************************
  41. * Code
  42. ******************************************************************************/
  43. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  44. static uint32_t GPIO_GetInstance(GPIO_Type *base)
  45. {
  46. uint32_t instance;
  47. /* Find the instance index from base address mappings. */
  48. for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
  49. {
  50. if (s_gpioBases[instance] == base)
  51. {
  52. break;
  53. }
  54. }
  55. assert(instance < ARRAY_SIZE(s_gpioBases));
  56. return instance;
  57. }
  58. #endif
  59. /*!
  60. * brief Initializes a GPIO pin used by the board.
  61. *
  62. * To initialize the GPIO, define a pin configuration, as either input or output, in the user file.
  63. * Then, call the GPIO_PinInit() function.
  64. *
  65. * This is an example to define an input pin or an output pin configuration.
  66. * code
  67. * Define a digital input pin configuration,
  68. * gpio_pin_config_t config =
  69. * {
  70. * kGPIO_DigitalInput,
  71. * 0,
  72. * }
  73. * Define a digital output pin configuration,
  74. * gpio_pin_config_t config =
  75. * {
  76. * kGPIO_DigitalOutput,
  77. * 0,
  78. * }
  79. * endcode
  80. *
  81. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
  82. * param pin GPIO port pin number
  83. * param config GPIO pin configuration pointer
  84. */
  85. void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
  86. {
  87. assert(NULL != config);
  88. uint32_t u32flag = 1;
  89. if (config->pinDirection == kGPIO_DigitalInput)
  90. {
  91. base->PDDR &= GPIO_FIT_REG(~(u32flag << pin));
  92. }
  93. else
  94. {
  95. GPIO_PinWrite(base, pin, config->outputLogic);
  96. base->PDDR |= GPIO_FIT_REG((u32flag << pin));
  97. }
  98. }
  99. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  100. /*!
  101. * brief Reads the GPIO port interrupt status flag.
  102. *
  103. * If a pin is configured to generate the DMA request, the corresponding flag
  104. * is cleared automatically at the completion of the requested DMA transfer.
  105. * Otherwise, the flag remains set until a logic one is written to that flag.
  106. * If configured for a level sensitive interrupt that remains asserted, the flag
  107. * is set again immediately.
  108. *
  109. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
  110. * retval The current GPIO port interrupt status flag, for example, 0x00010001 means the
  111. * pin 0 and 17 have the interrupt.
  112. */
  113. uint32_t GPIO_PortGetInterruptFlags(GPIO_Type *base)
  114. {
  115. uint8_t instance;
  116. PORT_Type *portBase;
  117. instance = (uint8_t)GPIO_GetInstance(base);
  118. portBase = s_portBases[instance];
  119. return portBase->ISFR;
  120. }
  121. #else
  122. /*!
  123. * brief Read the GPIO interrupt status flags.
  124. *
  125. * param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on.)
  126. * return The current GPIO's interrupt status flag.
  127. * '1' means the related pin's flag is set, '0' means the related pin's flag not set.
  128. * For example, the return value 0x00010001 means the pin 0 and 17 have the interrupt pending.
  129. */
  130. uint32_t GPIO_GpioGetInterruptFlags(GPIO_Type *base)
  131. {
  132. return base->ISFR[0];
  133. }
  134. /*!
  135. * brief Read individual pin's interrupt status flag.
  136. *
  137. * param base GPIO peripheral base pointer. (GPIOA, GPIOB, GPIOC, and so on)
  138. * param pin GPIO specific pin number.
  139. * return The current selected pin's interrupt status flag.
  140. */
  141. uint8_t GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin)
  142. {
  143. return (uint8_t)((base->ICR[pin] & GPIO_ICR_ISF_MASK) >> GPIO_ICR_ISF_SHIFT);
  144. }
  145. #endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */
  146. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  147. /*!
  148. * brief Clears multiple GPIO pin interrupt status flags.
  149. *
  150. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
  151. * param mask GPIO pin number macro
  152. */
  153. void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t mask)
  154. {
  155. uint8_t instance;
  156. PORT_Type *portBase;
  157. instance = (uint8_t)GPIO_GetInstance(base);
  158. portBase = s_portBases[instance];
  159. portBase->ISFR = mask;
  160. }
  161. #else
  162. /*!
  163. * brief Clears GPIO pin interrupt status flags.
  164. *
  165. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
  166. * param mask GPIO pin number macro
  167. */
  168. void GPIO_GpioClearInterruptFlags(GPIO_Type *base, uint32_t mask)
  169. {
  170. base->ISFR[0] = GPIO_FIT_REG(mask);
  171. }
  172. /*!
  173. * brief Clear GPIO individual pin's interrupt status flag.
  174. *
  175. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on).
  176. * param pin GPIO specific pin number.
  177. */
  178. void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t pin)
  179. {
  180. base->ICR[pin] |= GPIO_FIT_REG(GPIO_ICR_ISF(1U));
  181. }
  182. #endif /* FSL_FEATURE_PORT_HAS_NO_INTERRUPT */
  183. #if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER
  184. /*!
  185. * brief The GPIO module supports a device-specific number of data ports, organized as 32-bit
  186. * words/8-bit Bytes. Each 32-bit/8-bit data port includes a GACR register, which defines the byte-level
  187. * attributes required for a successful access to the GPIO programming model. If the GPIO module's GACR register
  188. * organized as 32-bit words, the attribute controls for the 4 data bytes in the GACR follow a standard little
  189. * endian data convention.
  190. *
  191. * param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
  192. * param attribute GPIO checker attribute
  193. */
  194. void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute)
  195. {
  196. #if defined(FSL_FEATURE_GPIO_REGISTERS_WIDTH) && (FSL_FEATURE_GPIO_REGISTERS_WIDTH == 8U)
  197. base->GACR = ((uint8_t)attribute << GPIO_GACR_ACB_SHIFT);
  198. #else
  199. base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) |
  200. ((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT);
  201. #endif /* FSL_FEATURE_GPIO_REGISTERS_WIDTH */
  202. }
  203. #endif
  204. #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT
  205. /*******************************************************************************
  206. * Variables
  207. ******************************************************************************/
  208. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  209. static FGPIO_Type *const s_fgpioBases[] = FGPIO_BASE_PTRS;
  210. #endif
  211. /*******************************************************************************
  212. * Prototypes
  213. ******************************************************************************/
  214. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  215. /*!
  216. * @brief Gets the FGPIO instance according to the GPIO base
  217. *
  218. * @param base FGPIO peripheral base pointer(PTA, PTB, PTC, etc.)
  219. * @retval FGPIO instance
  220. */
  221. static uint32_t FGPIO_GetInstance(FGPIO_Type *base);
  222. #endif
  223. /*******************************************************************************
  224. * Code
  225. ******************************************************************************/
  226. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  227. static uint32_t FGPIO_GetInstance(FGPIO_Type *base)
  228. {
  229. uint32_t instance;
  230. /* Find the instance index from base address mappings. */
  231. for (instance = 0; instance < ARRAY_SIZE(s_fgpioBases); instance++)
  232. {
  233. if (s_fgpioBases[instance] == base)
  234. {
  235. break;
  236. }
  237. }
  238. assert(instance < ARRAY_SIZE(s_fgpioBases));
  239. return instance;
  240. }
  241. #endif
  242. #if defined(FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL) && FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL
  243. /*!
  244. * brief Initializes the FGPIO peripheral.
  245. *
  246. * This function ungates the FGPIO clock.
  247. *
  248. * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
  249. */
  250. void FGPIO_PortInit(FGPIO_Type *base)
  251. {
  252. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  253. /* Ungate FGPIO periphral clock */
  254. CLOCK_EnableClock(s_fgpioClockName[FGPIO_GetInstance(base)]);
  255. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  256. }
  257. #endif /* FSL_FEATURE_PCC_HAS_FGPIO_CLOCK_GATE_CONTROL */
  258. /*!
  259. * brief Initializes a FGPIO pin used by the board.
  260. *
  261. * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file.
  262. * Then, call the FGPIO_PinInit() function.
  263. *
  264. * This is an example to define an input pin or an output pin configuration:
  265. * code
  266. * Define a digital input pin configuration,
  267. * gpio_pin_config_t config =
  268. * {
  269. * kGPIO_DigitalInput,
  270. * 0,
  271. * }
  272. * Define a digital output pin configuration,
  273. * gpio_pin_config_t config =
  274. * {
  275. * kGPIO_DigitalOutput,
  276. * 0,
  277. * }
  278. * endcode
  279. *
  280. * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
  281. * param pin FGPIO port pin number
  282. * param config FGPIO pin configuration pointer
  283. */
  284. void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config)
  285. {
  286. assert(NULL != config);
  287. uint32_t u32flag = 1;
  288. if (config->pinDirection == kGPIO_DigitalInput)
  289. {
  290. base->PDDR &= ~(u32flag << pin);
  291. }
  292. else
  293. {
  294. FGPIO_PinWrite(base, pin, config->outputLogic);
  295. base->PDDR |= (u32flag << pin);
  296. }
  297. }
  298. #if !(defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT)
  299. /*!
  300. * brief Reads the FGPIO port interrupt status flag.
  301. *
  302. * If a pin is configured to generate the DMA request, the corresponding flag
  303. * is cleared automatically at the completion of the requested DMA transfer.
  304. * Otherwise, the flag remains set until a logic one is written to that flag.
  305. * If configured for a level-sensitive interrupt that remains asserted, the flag
  306. * is set again immediately.
  307. *
  308. * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
  309. * retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the
  310. * pin 0 and 17 have the interrupt.
  311. */
  312. uint32_t FGPIO_PortGetInterruptFlags(FGPIO_Type *base)
  313. {
  314. uint8_t instance;
  315. instance = (uint8_t)FGPIO_GetInstance(base);
  316. PORT_Type *portBase;
  317. portBase = s_portBases[instance];
  318. return portBase->ISFR;
  319. }
  320. /*!
  321. * brief Clears the multiple FGPIO pin interrupt status flag.
  322. *
  323. * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
  324. * param mask FGPIO pin number macro
  325. */
  326. void FGPIO_PortClearInterruptFlags(FGPIO_Type *base, uint32_t mask)
  327. {
  328. uint8_t instance;
  329. instance = (uint8_t)FGPIO_GetInstance(base);
  330. PORT_Type *portBase;
  331. portBase = s_portBases[instance];
  332. portBase->ISFR = mask;
  333. }
  334. #endif
  335. #if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER
  336. /*!
  337. * brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit
  338. * words. Each 32-bit data port includes a GACR register, which defines the byte-level
  339. * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data
  340. * bytes in the GACR follow a standard little endian
  341. * data convention.
  342. *
  343. * param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.)
  344. * param attribute FGPIO checker attribute
  345. */
  346. void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute)
  347. {
  348. base->GACR = ((uint32_t)attribute << FGPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB1_SHIFT) |
  349. ((uint32_t)attribute << FGPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << FGPIO_GACR_ACB3_SHIFT);
  350. }
  351. #endif
  352. #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */