summaryrefslogtreecommitdiff
path: root/bsp/stm32/libraries/HAL_Drivers/drivers/drv_gpio.h
blob: d69e34ec52dd47b29fe390e1b660ef60ecd7dfd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2018-11-06     balanceTWK        first version
 * 2020-06-16     thread-liu        add stm32mp1
 * 2020-09-01     thread-liu        add GPIOZ
 * 2020-09-18     geniusgogo        optimization design pin-index algorithm
 */

#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__

#include <rtdevice.h>
#include <board.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef RT_USING_DM

#define __STM32_PORT(port)  GPIO##port##_BASE

/**
 * @brief  Calculates the RT-Thread global pin number from an STM32-specific port and pin.
 *
 * @details
 * This macro provides a vendor-specific way to map a human-readable GPIO port
 * (e.g., 'A', 'B') and pin number (0-15) to a single integer value that RT-Thread's
 * pin device driver uses to identify a pin globally.
 *
 * The calculation is based on the memory address offset of the target GPIO port's
 * base register relative to GPIOA. It assumes a linear memory map for GPIO ports.
 *
 * It includes special compile-time handling for different STM32 series, such as the
 * STM32MP1, which have a different GPIO memory layout (e.g., 4KB stride between
 * port registers) and may include special ports like GPIOZ.
 *
 * @param[in]  PORTx The GPIO port letter (e.g., A, B, C, D). Pass the letter without
 * quotes (e.g., A, not 'A').
 * @param[in]  PIN   The pin number within the port (an integer from 0 to 15).
 *
 * @return
 * An `rt_base_t` integer representing the unique pin index for use with RT-Thread
 * pin device driver functions (e.g., rt_pin_mode(), rt_pin_write()).
 *
 * @note
 * - **STM32 & RT-Thread Specific:** This macro is highly dependent on the STM32 HAL
 *   and RT-Thread's pin numbering convention. It relies on underlying HAL macros like
 *   `__STM32_PORT()` and base address definitions like `GPIOA_BASE`.
 * - **Not Portable:** Do not use this macro in code intended to be portable across
 *   different microcontroller vendors.
 * - **Compile-Time Evaluation:** The macro is evaluated entirely at compile time. The
 *   correct implementation for the target STM32 series is selected via preprocessor
 *   directives (e.g., `SOC_SERIES_STM32MP1`).
 * - **Argument Evaluation:** As this is a preprocessor macro, its arguments are
 *   substituted directly. Avoid passing expressions with side effects (e.g., `i++`)
 *   as arguments, as they may be evaluated multiple times.
 *
 * @see rt_pin_mode()
 * @see rt_pin_write()
 * @see rt_pin_read()
 *
 * @code
 * // Usage Example 1: Configure pin PD11 as a push-pull output.
 * rt_pin_mode(GET_PIN(D, 11), PIN_MODE_OUTPUT);
 *
 * // Usage Example 2: Write a high logic level to pin PA5.
 * rt_pin_write(GET_PIN(A, 5), PIN_HIGH);
 *
 * // Usage Example 3: Read the logic level from pin PC13.
 * int level = rt_pin_read(GET_PIN(C, 13));
 * @endcode
 */
#if defined(SOC_SERIES_STM32MP1)
#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))
#else
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)
#endif

#endif /* !RT_USING_DM */

struct pin_irq_map
{
    rt_uint16_t pinbit;
    IRQn_Type irqno;
};

int rt_hw_pin_init(void);

#ifdef __cplusplus
}
#endif

#endif /* __DRV_GPIO_H__ */