13
#include <embox/unit.h>
14
#include <lib/libds/bit.h>
15
#include <lib/libds/array.h>
17
#include <kernel/irq.h>
19
#include <bsp/stm32cube_hal.h>
21
#include <drivers/gpio/gpio_driver.h>
23
EMBOX_UNIT_INIT(stm32_gpio_init);
25
#define STM32_GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
28
#define STM32_GPIO_PORTS_COUNT \
29
sizeof(stm32_gpio_ports) / sizeof(stm32_gpio_ports[0])
31
static GPIO_TypeDef *stm32_gpio_ports[] = {
61
static inline void stm32_gpio_clk_enable(void *gpio_base) {
62
switch ((intptr_t) gpio_base) {
63
case (intptr_t) GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break;
64
case (intptr_t) GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break;
65
case (intptr_t) GPIOC: __HAL_RCC_GPIOC_CLK_ENABLE(); break;
67
case (intptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break;
69
case (intptr_t) GPIOE: __HAL_RCC_GPIOE_CLK_ENABLE(); break;
71
case (intptr_t) GPIOF: __HAL_RCC_GPIOF_CLK_ENABLE(); break;
73
case (intptr_t) GPIOG: __HAL_RCC_GPIOG_CLK_ENABLE(); break;
75
case (intptr_t) GPIOH: __HAL_RCC_GPIOH_CLK_ENABLE(); break;
77
case (intptr_t) GPIOI: __HAL_RCC_GPIOI_CLK_ENABLE(); break;
79
case (intptr_t) GPIOJ: __HAL_RCC_GPIOJ_CLK_ENABLE(); break;
81
case (intptr_t) GPIOK: __HAL_RCC_GPIOK_CLK_ENABLE(); break;
94
#define EXTI0_IRQ OPTION_GET(NUMBER, exti0_irq)
95
static_assert(EXTI0_IRQ == EXTI0_IRQn, "");
97
#define EXTI1_IRQ OPTION_GET(NUMBER, exti1_irq)
98
static_assert(EXTI1_IRQ == EXTI1_IRQn, "");
100
#define EXTI2_IRQ OPTION_GET(NUMBER, exti2_irq)
102
#if defined(STM32F303xC)
103
static_assert(EXTI2_IRQ == EXTI2_TSC_IRQn, "");
105
static_assert(EXTI2_IRQ == EXTI2_IRQn, "");
109
#define EXTI3_IRQ OPTION_GET(NUMBER, exti3_irq)
110
static_assert(EXTI3_IRQ == EXTI3_IRQn, "");
112
#define EXTI4_IRQ OPTION_GET(NUMBER, exti4_irq)
113
static_assert(EXTI4_IRQ == EXTI4_IRQn, "");
115
#define EXTI9_5_IRQ OPTION_GET(NUMBER, exti9_5_irq)
116
static_assert(EXTI9_5_IRQ == EXTI9_5_IRQn, "");
119
#define EXTI15_10_IRQ OPTION_GET(NUMBER, exti15_10_irq)
120
#if (EXTI15_10_IRQ != 0)
121
static_assert(EXTI15_10_IRQ == EXTI15_10_IRQn, "");
123
static const unsigned char exti_irqs[] = {
124
EXTI0_IRQ, EXTI1_IRQ, EXTI2_IRQ, EXTI3_IRQ, EXTI4_IRQ,
125
EXTI9_5_IRQ, EXTI15_10_IRQ,
128
static struct gpio_chip stm32_gpio_chip;
130
static int stm32_gpio_setup_mode(unsigned char port, gpio_mask_t pins,
132
GPIO_InitTypeDef GPIO_InitStruct;
134
assert(port < STM32_GPIO_PORTS_COUNT);
136
stm32_gpio_clk_enable(stm32_gpio_ports[port]);
138
memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
139
GPIO_InitStruct.Pin = pins;
140
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
141
GPIO_InitStruct.Pull = GPIO_NOPULL;
143
if (mode & GPIO_MODE_OUT) {
144
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
146
if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {
147
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
149
if (mode & GPIO_MODE_OUT_PUSH_PULL) {
150
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
152
} else if (mode & GPIO_MODE_IN) {
153
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
155
if (mode & GPIO_MODE_IN_PULL_UP) {
156
GPIO_InitStruct.Pull = GPIO_PULLUP;
158
if (mode & GPIO_MODE_IN_PULL_DOWN) {
159
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
161
} else if (mode & GPIO_MODE_OUT_ALTERNATE) {
163
GPIO_InitStruct.Alternate = GPIO_GET_ALTERNATE(mode);
165
if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {
166
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
168
if (mode & GPIO_MODE_OUT_PUSH_PULL) {
169
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
172
if (mode & GPIO_MODE_IN_PULL_UP) {
173
GPIO_InitStruct.Pull = GPIO_PULLUP;
175
if (mode & GPIO_MODE_IN_PULL_DOWN) {
176
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
178
} else if (mode & GPIO_MODE_INT_MODE_RISING_FALLING) {
179
if ((mode & GPIO_MODE_INT_MODE_RISING_FALLING)
180
== GPIO_MODE_INT_MODE_RISING_FALLING) {
181
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
182
} else if (mode & GPIO_MODE_INT_MODE_RISING) {
183
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
184
} else if (mode & GPIO_MODE_INT_MODE_FALLING) {
185
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
189
HAL_GPIO_Init(stm32_gpio_ports[port], &GPIO_InitStruct);
194
static void stm32_gpio_set(unsigned char port, gpio_mask_t pins, char level) {
195
assert(port < STM32_GPIO_PORTS_COUNT);
196
HAL_GPIO_WritePin(stm32_gpio_ports[port], pins,
197
level ? GPIO_PIN_SET : GPIO_PIN_RESET);
200
static gpio_mask_t stm32_gpio_get(unsigned char port, gpio_mask_t pins) {
204
assert(port < STM32_GPIO_PORTS_COUNT);
206
bit_foreach(bit, pins) {
207
res |= HAL_GPIO_ReadPin(stm32_gpio_ports[port], 1 << bit) << bit;
213
irq_return_t stm32_gpio_irq_handler(unsigned int irq_nr, void *data) {
217
pending = __HAL_GPIO_EXTI_GET_FLAG(0xffff);
219
__HAL_GPIO_EXTI_CLEAR_IT(pending);
222
for (i = 0; i < STM32_GPIO_PORTS_COUNT; i++) {
223
gpio_handle_irq(&stm32_gpio_chip, i, pending);
229
static struct gpio_chip stm32_gpio_chip = {
230
.setup_mode = stm32_gpio_setup_mode,
231
.get = stm32_gpio_get,
232
.set = stm32_gpio_set,
233
.nports = STM32_GPIO_PORTS_COUNT
236
static int stm32_gpio_init(void) {
239
for (i = 0; i < ARRAY_SIZE(exti_irqs); i++) {
240
if (0 == exti_irqs[i]) {
243
res = irq_attach(exti_irqs[i], stm32_gpio_irq_handler, 0, NULL,
244
"STM32 EXTI irq handler");
250
return gpio_register_chip(&stm32_gpio_chip, STM32_GPIO_CHIP_ID);
253
STATIC_IRQ_ATTACH(EXTI0_IRQ, stm32_gpio_irq_handler, NULL);
254
STATIC_IRQ_ATTACH(EXTI1_IRQ, stm32_gpio_irq_handler, NULL);
256
STATIC_IRQ_ATTACH(EXTI2_IRQ, stm32_gpio_irq_handler, NULL);
258
STATIC_IRQ_ATTACH(EXTI3_IRQ, stm32_gpio_irq_handler, NULL);
259
STATIC_IRQ_ATTACH(EXTI4_IRQ, stm32_gpio_irq_handler, NULL);
260
STATIC_IRQ_ATTACH(EXTI9_5_IRQ, stm32_gpio_irq_handler, NULL);
261
#if (EXTI15_10_IRQ != 0)
262
STATIC_IRQ_ATTACH(EXTI15_10_IRQ, stm32_gpio_irq_handler, NULL);