embox

Форк
0
/
stm32_gpio_cube.c 
263 строки · 6.6 Кб
1
/**
2
 * @file stm32_gpio_cube.c
3
 * @brief
4
 * @author Denis Deryugin <deryugin.denis@gmail.com>
5
 * @version 0.1
6
 * @date 2016-02-12
7
 */
8

9
#include <assert.h>
10
#include <string.h>
11
#include <stdint.h>
12

13
#include <embox/unit.h>
14
#include <lib/libds/bit.h>
15
#include <lib/libds/array.h>
16

17
#include <kernel/irq.h>
18

19
#include <bsp/stm32cube_hal.h>
20

21
#include <drivers/gpio/gpio_driver.h>
22

23
EMBOX_UNIT_INIT(stm32_gpio_init);
24

25
#define STM32_GPIO_CHIP_ID OPTION_GET(NUMBER,gpio_chip_id)
26

27

28
#define STM32_GPIO_PORTS_COUNT \
29
	sizeof(stm32_gpio_ports) / sizeof(stm32_gpio_ports[0])
30

31
static GPIO_TypeDef *stm32_gpio_ports[] = {
32
	GPIOA,
33
	GPIOB,
34
	GPIOC,
35
#ifdef GPIOD
36
	GPIOD,
37
#ifdef GPIOE
38
	GPIOE,
39
#ifdef GPIOF
40
	GPIOF,
41
#ifdef GPIOG
42
	GPIOG,
43
#ifdef GPIOH
44
	GPIOH,
45
#ifdef GPIOI
46
	GPIOI,
47
#ifdef GPIOJ
48
	GPIOJ,
49
#ifdef GPIOK
50
	GPIOK
51
#endif /* GPIOK */
52
#endif /* GPIOJ */
53
#endif /* GPIOI */
54
#endif /* GPIOH */
55
#endif /* GPIOG */
56
#endif /* GPIOF */
57
#endif /* GPIOE */
58
#endif /* GPIOD */
59
};
60

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;
66
#ifdef GPIOD
67
	case (intptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break;
68
#ifdef GPIOE
69
	case (intptr_t) GPIOE: __HAL_RCC_GPIOE_CLK_ENABLE(); break;
70
#ifdef GPIOF
71
	case (intptr_t) GPIOF: __HAL_RCC_GPIOF_CLK_ENABLE(); break;
72
#ifdef GPIOG
73
	case (intptr_t) GPIOG: __HAL_RCC_GPIOG_CLK_ENABLE(); break;
74
#ifdef GPIOH
75
	case (intptr_t) GPIOH: __HAL_RCC_GPIOH_CLK_ENABLE(); break;
76
#ifdef GPIOI
77
	case (intptr_t) GPIOI: __HAL_RCC_GPIOI_CLK_ENABLE(); break;
78
#ifdef GPIOJ
79
	case (intptr_t) GPIOJ: __HAL_RCC_GPIOJ_CLK_ENABLE(); break;
80
#ifdef GPIOK
81
	case (intptr_t) GPIOK: __HAL_RCC_GPIOK_CLK_ENABLE(); break;
82
#endif /* GPIOK */
83
#endif /* GPIOJ */
84
#endif /* GPIOI */
85
#endif /* GPIOH */
86
#endif /* GPIOG */
87
#endif /* GPIOF */
88
#endif /* GPIOE */
89
#endif /* GPIOD */
90
	default: break;
91
	}
92
}
93

94
#define EXTI0_IRQ          OPTION_GET(NUMBER, exti0_irq)
95
static_assert(EXTI0_IRQ == EXTI0_IRQn, "");
96

97
#define EXTI1_IRQ          OPTION_GET(NUMBER, exti1_irq)
98
static_assert(EXTI1_IRQ == EXTI1_IRQn, "");
99

100
#define EXTI2_IRQ          OPTION_GET(NUMBER, exti2_irq)
101
#if (EXTI2_IRQ != 0)
102
#if defined(STM32F303xC)
103
static_assert(EXTI2_IRQ == EXTI2_TSC_IRQn, "");
104
#else
105
static_assert(EXTI2_IRQ == EXTI2_IRQn, "");
106
#endif
107
#endif /*(EXTI2_IRQ != 0)*/
108

109
#define EXTI3_IRQ          OPTION_GET(NUMBER, exti3_irq)
110
static_assert(EXTI3_IRQ == EXTI3_IRQn, "");
111

112
#define EXTI4_IRQ          OPTION_GET(NUMBER, exti4_irq)
113
static_assert(EXTI4_IRQ == EXTI4_IRQn, "");
114

115
#define EXTI9_5_IRQ        OPTION_GET(NUMBER, exti9_5_irq)
116
static_assert(EXTI9_5_IRQ == EXTI9_5_IRQn, "");
117

118

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, "");
122
#endif
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,
126
};
127

128
static struct gpio_chip stm32_gpio_chip;
129

130
static int stm32_gpio_setup_mode(unsigned char port, gpio_mask_t pins,
131
		int mode) {
132
	GPIO_InitTypeDef GPIO_InitStruct;
133

134
	assert(port < STM32_GPIO_PORTS_COUNT);
135

136
	stm32_gpio_clk_enable(stm32_gpio_ports[port]);
137

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;
142

143
	if (mode & GPIO_MODE_OUT) {
144
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
145

146
		if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {
147
			GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
148
		}
149
		if (mode & GPIO_MODE_OUT_PUSH_PULL) {
150
			GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
151
		}
152
	} else if (mode & GPIO_MODE_IN) {
153
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
154

155
		if (mode & GPIO_MODE_IN_PULL_UP) {
156
			GPIO_InitStruct.Pull = GPIO_PULLUP;
157
		}
158
		if (mode & GPIO_MODE_IN_PULL_DOWN) {
159
			GPIO_InitStruct.Pull = GPIO_PULLDOWN;
160
		}
161
	} else if (mode & GPIO_MODE_OUT_ALTERNATE) {
162
#ifndef STM32F1_CUBE /* There is no Alternate field in GPIO_InitTypeDef */
163
		GPIO_InitStruct.Alternate = GPIO_GET_ALTERNATE(mode);
164
#endif
165
		if (mode & GPIO_MODE_OUT_OPEN_DRAIN) {
166
			GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
167
		}
168
		if (mode & GPIO_MODE_OUT_PUSH_PULL) {
169
			GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
170
		}
171

172
		if (mode & GPIO_MODE_IN_PULL_UP) {
173
			GPIO_InitStruct.Pull = GPIO_PULLUP;
174
		}
175
		if (mode & GPIO_MODE_IN_PULL_DOWN) {
176
			GPIO_InitStruct.Pull = GPIO_PULLDOWN;
177
		}
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;
186
		}
187
	}
188

189
	HAL_GPIO_Init(stm32_gpio_ports[port], &GPIO_InitStruct);
190

191
	return 0;
192
}
193

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);
198
}
199

200
static gpio_mask_t stm32_gpio_get(unsigned char port, gpio_mask_t pins) {
201
	gpio_mask_t res = 0;
202
	int bit;
203

204
	assert(port < STM32_GPIO_PORTS_COUNT);
205

206
	bit_foreach(bit, pins) {
207
		res |= HAL_GPIO_ReadPin(stm32_gpio_ports[port], 1 << bit) << bit;
208
	}
209

210
	return res;
211
}
212

213
irq_return_t stm32_gpio_irq_handler(unsigned int irq_nr, void *data) {
214
	int i;
215
	uint16_t pending;
216

217
	pending = __HAL_GPIO_EXTI_GET_FLAG(0xffff);
218

219
	__HAL_GPIO_EXTI_CLEAR_IT(pending);
220

221
	/* Notify all GPIO ports about interrupt */
222
	for (i = 0; i < STM32_GPIO_PORTS_COUNT; i++) {
223
		gpio_handle_irq(&stm32_gpio_chip, i, pending);
224
	}
225

226
	return IRQ_HANDLED;
227
}
228

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
234
};
235

236
static int stm32_gpio_init(void) {
237
	int res, i;
238

239
	for (i = 0; i < ARRAY_SIZE(exti_irqs); i++) {
240
		if (0 == exti_irqs[i]) {
241
			continue;
242
		}
243
		res = irq_attach(exti_irqs[i], stm32_gpio_irq_handler, 0, NULL,
244
			"STM32 EXTI irq handler");
245
		if (res < 0) {
246
			return -1;
247
		}
248
	}
249

250
	return gpio_register_chip(&stm32_gpio_chip, STM32_GPIO_CHIP_ID);
251
}
252

253
STATIC_IRQ_ATTACH(EXTI0_IRQ, stm32_gpio_irq_handler, NULL);
254
STATIC_IRQ_ATTACH(EXTI1_IRQ, stm32_gpio_irq_handler, NULL);
255
#if (EXTI2_IRQ != 0)
256
STATIC_IRQ_ATTACH(EXTI2_IRQ, stm32_gpio_irq_handler, NULL);
257
#endif /* (EXTI2_IRQ != 0) */
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);
263
#endif
264

265

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.