drv_gpio.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-11-06 balanceTWK first version
  9. * 2020-06-16 thread-liu add stm32mp1
  10. * 2020-09-01 thread-liu add GPIOZ
  11. * 2020-09-18 geniusgogo optimization design pin-index algorithm
  12. */
  13. #ifndef __DRV_GPIO_H__
  14. #define __DRV_GPIO_H__
  15. #include <rtdevice.h>
  16. #include <board.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. #define __STM32_PORT(port) GPIO##port##_BASE
  21. /**
  22. * @brief Calculates the RT-Thread global pin number from an STM32-specific port and pin.
  23. *
  24. * @details
  25. * This macro provides a vendor-specific way to map a human-readable GPIO port
  26. * (e.g., 'A', 'B') and pin number (0-15) to a single integer value that RT-Thread's
  27. * pin device driver uses to identify a pin globally.
  28. *
  29. * The calculation is based on the memory address offset of the target GPIO port's
  30. * base register relative to GPIOA. It assumes a linear memory map for GPIO ports.
  31. *
  32. * It includes special compile-time handling for different STM32 series, such as the
  33. * STM32MP1, which have a different GPIO memory layout (e.g., 4KB stride between
  34. * port registers) and may include special ports like GPIOZ.
  35. *
  36. * @param[in] PORTx The GPIO port letter (e.g., A, B, C, D). Pass the letter without
  37. * quotes (e.g., A, not 'A').
  38. * @param[in] PIN The pin number within the port (an integer from 0 to 15).
  39. *
  40. * @return
  41. * An `rt_base_t` integer representing the unique pin index for use with RT-Thread
  42. * pin device driver functions (e.g., rt_pin_mode(), rt_pin_write()).
  43. *
  44. * @note
  45. * - **STM32 & RT-Thread Specific:** This macro is highly dependent on the STM32 HAL
  46. * and RT-Thread's pin numbering convention. It relies on underlying HAL macros like
  47. * `__STM32_PORT()` and base address definitions like `GPIOA_BASE`.
  48. * - **Not Portable:** Do not use this macro in code intended to be portable across
  49. * different microcontroller vendors.
  50. * - **Compile-Time Evaluation:** The macro is evaluated entirely at compile time. The
  51. * correct implementation for the target STM32 series is selected via preprocessor
  52. * directives (e.g., `SOC_SERIES_STM32MP1`).
  53. * - **Argument Evaluation:** As this is a preprocessor macro, its arguments are
  54. * substituted directly. Avoid passing expressions with side effects (e.g., `i++`)
  55. * as arguments, as they may be evaluated multiple times.
  56. *
  57. * @see rt_pin_mode()
  58. * @see rt_pin_write()
  59. * @see rt_pin_read()
  60. *
  61. * @code
  62. * // Usage Example 1: Configure pin PD11 as a push-pull output.
  63. * rt_pin_mode(GET_PIN(D, 11), PIN_MODE_OUTPUT);
  64. *
  65. * // Usage Example 2: Write a high logic level to pin PA5.
  66. * rt_pin_write(GET_PIN(A, 5), PIN_HIGH);
  67. *
  68. * // Usage Example 3: Read the logic level from pin PC13.
  69. * int level = rt_pin_read(GET_PIN(C, 13));
  70. * @endcode
  71. */
  72. #if defined(SOC_SERIES_STM32MP1)
  73. #define GET_PIN(PORTx,PIN) (GPIO##PORTx == GPIOZ) ? (176 + PIN) : ((rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x1000UL) )) + PIN))
  74. #else
  75. #define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)
  76. #endif
  77. struct pin_irq_map
  78. {
  79. rt_uint16_t pinbit;
  80. IRQn_Type irqno;
  81. };
  82. int rt_hw_pin_init(void);
  83. #ifdef __cplusplus
  84. }
  85. #endif
  86. #endif /* __DRV_GPIO_H__ */