stm32_gpio.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Copyright (C) 2010 by Ulrich Prinz (uprinz2@netscape.net)
  3. * Copyright (C) 2011-2013 by Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. /*
  36. * \verbatim
  37. * $Id$
  38. * \endverbatim
  39. */
  40. /* GPIO Configuration for the GPIO of L1/F2/F4 */
  41. #include <cfg/os.h>
  42. #include <cfg/arch.h>
  43. #include <cfg/arch/gpio.h>
  44. #include <sys/nutdebug.h>
  45. #include <arch/cm3.h>
  46. #include <dev/gpio.h>
  47. #include <arch/cm3/stm/stm32_gpio.h>
  48. #if defined (MCU_STM32L1)
  49. #define GPIO_RCC_ENR AHBENR
  50. #elif defined (MCU_STM32F0)
  51. #define GPIO_RCC_ENR AHBENR
  52. #elif defined (MCU_STM32F2)
  53. #define GPIO_RCC_ENR AHB1ENR
  54. #elif defined (MCU_STM32F3)
  55. #define GPIO_RCC_ENR AHBENR
  56. #elif defined (MCU_STM32F4)
  57. #define GPIO_RCC_ENR AHB1ENR
  58. #else
  59. #warning "Unknown STM32 family"
  60. #endif
  61. /*!
  62. * \brief Get pin configuration.
  63. *
  64. * Trying to set undefined ports must be avoided.
  65. * If NUTDEBUG is enabled an assertion will be rised.
  66. *
  67. * \param bank GPIO bank/port number.
  68. * \param bit Bit number of the specified bank/port.
  69. *
  70. * \return Attribute flags of the pin.
  71. */
  72. uint32_t GpioPinConfigGet(int bank, int bit)
  73. {
  74. uint32_t rc = 0;
  75. GPIO_TypeDef *gpio = (GPIO_TypeDef *)bank;
  76. uint8_t mode = ((gpio->MODER) >> (bit *2)) & 0x3;
  77. uint8_t pull = ((gpio->PUPDR) >> (bit *2)) & 0x3;
  78. uint8_t dr_oc = ((gpio->OTYPER) >> bit ) & 0x1;
  79. uint8_t speed = ((gpio->OSPEEDR) >> (bit *2)) & 0x3;
  80. if (mode == GPIO_Mode_OUT)
  81. {
  82. rc = GPIO_CFG_OUTPUT;
  83. rc |= (dr_oc)? GPIO_CFG_MULTIDRIVE: 0;
  84. rc |= (pull == GPIO_PuPd_UP)?GPIO_CFG_PULLUP : 0;
  85. }
  86. else if (mode == GPIO_Mode_AF)
  87. {
  88. rc = GPIO_CFG_PERIPHAL;
  89. rc |= (dr_oc)? GPIO_CFG_MULTIDRIVE: 0;
  90. rc |= (pull == GPIO_PuPd_UP)?GPIO_CFG_PULLUP : 0;
  91. }
  92. else if (mode == GPIO_Mode_AN)
  93. {
  94. rc = GPIO_CFG_OUTPUT| GPIO_CFG_DISABLED;
  95. }
  96. else if(mode == GPIO_Mode_IN)
  97. {
  98. rc |= (pull == GPIO_PuPd_UP)?GPIO_CFG_PULLUP : 0;
  99. }
  100. switch (speed)
  101. {
  102. case 0: rc |= GPIO_CFG_SPEED_SLOW; break;
  103. case 2: rc |= GPIO_CFG_SPEED_HIGH; break;
  104. case 3: rc |= GPIO_CFG_SPEED_FAST; break;
  105. }
  106. return rc;
  107. }
  108. /*!
  109. * \brief Set port wide pin configuration.
  110. *
  111. * \note This function does not check for undefined ports and pins or
  112. * invalid attributes. If this is required, use GpioPinConfigSet().
  113. * If NUTDEBUG is enabled accessing an undefined port will rise
  114. * an assertion.
  115. *
  116. * \param bank GPIO bank/port number.
  117. * \param mask The given attributes are set for a specific pin, if the
  118. * corresponding bit in this mask is 1.
  119. * \param flags Attribute flags to set.
  120. *
  121. * \return Always 0.
  122. */
  123. int GpioPortConfigSet(int bank, uint32_t mask, uint32_t flags)
  124. {
  125. int i;
  126. for( i=0; i<16; i++)
  127. {
  128. if (mask & 1)
  129. GpioPinConfigSet(bank, i, flags);
  130. mask >>= 1;
  131. }
  132. return 0;
  133. }
  134. int GpioPinConfigSet(int bank, int bit, uint32_t flags)
  135. {
  136. NUTASSERT(IS_GPIO_ALL_PERIPH(bank));
  137. GPIO_TypeDef *gpio = (GPIO_TypeDef *) bank;
  138. GpioClkEnable(bank);
  139. /* Set the inital value, if given
  140. *
  141. * Otherwise we may introduce unwanted transistions on the port
  142. */
  143. if (flags & GPIO_CFG_INIT_HIGH)
  144. {
  145. if (flags & GPIO_CFG_INIT_LOW)
  146. return -1;
  147. else
  148. GpioPinSetHigh(bank, bit);
  149. }
  150. if (flags & GPIO_CFG_INIT_LOW)
  151. GpioPinSetLow(bank, bit);
  152. /* we can't check for these flags, so clear them */
  153. flags &= ~(GPIO_CFG_INIT_LOW |GPIO_CFG_INIT_HIGH);
  154. /* Reset all two bit entries */
  155. gpio->MODER &= ~(0x3 <<(bit << 1));
  156. gpio->OSPEEDR &= ~(0x3 <<(bit << 1));
  157. gpio->PUPDR &= ~(0x3 <<(bit << 1));
  158. /* For non-output, multidrive is don't care*/
  159. if (flags & GPIO_CFG_MULTIDRIVE )
  160. gpio->OTYPER |= 1<<bit;
  161. else
  162. gpio->OTYPER &= ~(1<<bit);
  163. /* For non-output, ospeedr is don't care*/
  164. switch(flags & GPIO_CFG_SPEED_FAST)
  165. {
  166. case GPIO_CFG_SPEED_FAST:
  167. gpio->OSPEEDR |= (3 <<(bit << 1));
  168. break;
  169. case GPIO_CFG_SPEED_MED:
  170. gpio->OSPEEDR |= (0x1 <<(bit << 1));
  171. break;
  172. }
  173. /* Pull Up/Pull Down applies to all configurations*/
  174. if (flags & GPIO_CFG_PULLUP )
  175. gpio->PUPDR |= (1<<((bit << 1)));
  176. if (flags & GPIO_CFG_PULLDOWN )
  177. gpio->PUPDR |= (2<<((bit << 1)));
  178. if (flags & GPIO_CFG_PERIPHAL)
  179. {
  180. gpio->MODER |= 2<<((bit << 1));
  181. }
  182. else if (flags & GPIO_CFG_OUTPUT)
  183. {
  184. gpio->MODER |= 1<<((bit << 1));
  185. }
  186. #if defined(SYSCFG_CMPCR_CMP_PD)
  187. if ((flags & GPIO_CFG_SPEED_HIGH) == GPIO_CFG_SPEED_HIGH) {
  188. /* On F4, if even one pin needs fastest (high) speed, we need to enable the SYSCFG clock
  189. and the IO compensation cell (whatever this compensation cell is ?)*/
  190. CM3BBSET(RCC_BASE, RCC_TypeDef, APB2ENR, _BI32(RCC_APB2ENR_SYSCFGEN));
  191. CM3BBSET(SYSCFG_BASE, SYSCFG_TypeDef, CMPCR, _BI32(SYSCFG_CMPCR_CMP_PD));
  192. /* FIXME: Do we need to check SYSCFG_CMPCR_READY ? */
  193. }
  194. #endif
  195. /* Check the result. */
  196. if( GpioPinConfigGet( bank, bit ) != flags ) {
  197. return -1;
  198. }
  199. return 0;
  200. }
  201. /*!
  202. * \brief Register a GPIO pin interrupt handler.
  203. *
  204. * Generating interrupts on GPIO pin changes is not supported on all
  205. * platforms. In this case dedicated external interrupt pins may
  206. * be used with NutRegisterIrqHandler().
  207. *
  208. * Interrupts are triggered on rising and falling edges. Level triggering
  209. * or triggering on specific edges is not supported.
  210. *
  211. * After registering, interrupts are disabled. Calling GpioIrqEnable()
  212. * is required to activate the interrupt.
  213. *
  214. * The following code fragment registers an interrupt handler which is
  215. * called on each change of bit 4 of the first GPIO port:
  216. * \code
  217. * #include <dev/gpio.h>
  218. *
  219. * static void PinChange(void *arg)
  220. * {
  221. * ...
  222. * }
  223. *
  224. * {
  225. * ...
  226. * GpioPinConfigSet(0, 4, GPIO_CFG_PULLUP);
  227. * GpioRegisterIrqHandler(&sig_GPIO, 4, PinChange, NULL);
  228. * GpioIrqEnable(&sig_GPIO, 4);
  229. * ...
  230. * }
  231. * \endcode
  232. *
  233. * \param sig Bank/port interrupt to be associated with this handler.
  234. * \param bit Bit number of the specified bank/port.
  235. * \param handler This routine will be called by Nut/OS, when the specified
  236. * pin changes its state.
  237. * \param arg Argument to be passed to the interrupt handler routine.
  238. *
  239. * \return 0 on success, -1 otherwise.
  240. */
  241. extern int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, uint8_t bit, void (*handler) (void *), void *arg)
  242. {
  243. int rc = 0;
  244. #if 0
  245. if (bit<5) {
  246. NutRegisterIrqHandler( &sig_INTERRUPT0, void(* handler)(void *), void * arg)
  247. uint32_t afiob = bit/4;
  248. /* Select bank in AFIO_EXTIn */
  249. AFIO->EXTICR[afiob] |= bank<<(afiob*4);
  250. EXTI->
  251. #endif
  252. return rc;
  253. }
  254. /*!
  255. * \brief Enable a specified GPIO interrupt.
  256. *
  257. * A related interrupt handler must have been registered before calling
  258. * this function. See GpioRegisterIrqHandler().
  259. *
  260. * \param sig Interrupt to enable.
  261. * \param bit Bit number of the specified bank/port.
  262. *
  263. * \return 0 on success, -1 otherwise.
  264. */
  265. int GpioIrqEnable(GPIO_SIGNAL * sig, uint8_t bit)
  266. {
  267. return -1;
  268. }
  269. /*!
  270. * \brief Disable a specified GPIO interrupt.
  271. *
  272. * \param sig Interrupt to disable.
  273. * \param bit Bit number of the specified bank/port.
  274. *
  275. * \return 0 on success, -1 otherwise.
  276. */
  277. int GpioIrqDisable(GPIO_SIGNAL * sig, uint8_t bit)
  278. {
  279. return 0;
  280. }
  281. /* Copied from STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c*/
  282. /**
  283. * @}
  284. */
  285. /** @defgroup GPIO_Group3 GPIO Alternate functions configuration function
  286. * @brief GPIO Alternate functions configuration function
  287. *
  288. ===============================================================================
  289. GPIO Alternate functions configuration function
  290. ===============================================================================
  291. @endverbatim
  292. * @{
  293. */
  294. /**
  295. * @brief Changes the mapping of the specified pin.
  296. * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
  297. * @param GPIO_PinSource: specifies the pin for the Alternate function.
  298. * This parameter can be GPIO_PinSourcex where x can be (0..15).
  299. * @param GPIO_AFSelection: selects the pin to used as Alternate function.
  300. * This parameter can be one of the following values:
  301. * @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
  302. * @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
  303. * @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
  304. * @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
  305. * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
  306. * @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1
  307. * @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1
  308. * @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2
  309. * @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2
  310. * @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2
  311. * @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3
  312. * @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3
  313. * @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3
  314. * @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3
  315. * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
  316. * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
  317. * @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
  318. * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
  319. * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
  320. * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
  321. * @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7
  322. * @arg GPIO_AF_USART1: Connect USART1 pins to AF7
  323. * @arg GPIO_AF_USART2: Connect USART2 pins to AF7
  324. * @arg GPIO_AF_USART3: Connect USART3 pins to AF7
  325. * @arg GPIO_AF_UART4: Connect UART4 pins to AF8
  326. * @arg GPIO_AF_UART5: Connect UART5 pins to AF8
  327. * @arg GPIO_AF_USART6: Connect USART6 pins to AF8
  328. * @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
  329. * @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
  330. * @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9
  331. * @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9
  332. * @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9
  333. * @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
  334. * @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
  335. * @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
  336. * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
  337. * @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
  338. * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
  339. * @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
  340. * @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
  341. * @retval None
  342. */
  343. void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, nutgpio_pin_t GPIO_PinSource, uint8_t GPIO_AF)
  344. {
  345. uint32_t temp = 0x00;
  346. uint32_t temp_2 = 0x00;
  347. /* Check the parameters */
  348. NUTASSERT(IS_GPIO_ALL_PERIPH(GPIOx));
  349. NUTASSERT(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  350. NUTASSERT(IS_GPIO_AF(GPIO_AF));
  351. temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
  352. GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
  353. temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
  354. GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
  355. }