embox

Форк
0
/
mikron_gpio.c 
253 строки · 5.0 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @author  Anton Bondarev
6
 * @date    17.07.2024
7
 */
8

9
#include <stdint.h>
10

11
#include <drivers/gpio/gpio_driver.h>
12
#include <hal/reg.h>
13
#include <kernel/irq.h>
14

15
//#include <config/board_config.h>
16
#include <drivers/clk/mikron_pm.h>
17

18
#include <framework/mod/options.h>
19

20
#define GPIO_CHIP_ID                 OPTION_GET(NUMBER, gpio_chip_id)
21
#define GPIO_PINS_NUMBER             16
22

23
#define CONF_GPIO_PORT_0_REGION_BASE 0x00084000
24
#define CONF_GPIO_PORT_1_REGION_BASE 0x00084400
25
#define CONF_GPIO_PORT_2_REGION_BASE 0x00084800
26

27
#define CONF_GPIO_PORT_0_CLK_ENABLE() "CLK_GPIO_PORT0"
28
#define CONF_GPIO_PORT_1_CLK_ENABLE() "CLK_GPIO_PORT1"
29
#define CONF_GPIO_PORT_2_CLK_ENABLE() "CLK_GPIO_PORT2"
30

31
#define GPIOA                        ((volatile struct gpio_reg *)CONF_GPIO_PORT_0_REGION_BASE)
32
#define GPIOB                        ((volatile struct gpio_reg *)CONF_GPIO_PORT_1_REGION_BASE)
33
#define GPIOC                        ((volatile struct gpio_reg *)CONF_GPIO_PORT_2_REGION_BASE)
34

35
extern void mik_pad_cfg_set_func(int port, int pin, int func);
36
extern void mik_pad_cfg_set_ds(int port, int pin, int ds);
37
extern void mik_pad_cfg_set_pupd(int port, int pin, int pupd);
38

39
struct gpio_reg {
40
	union {
41
		volatile uint32_t SET;
42
		volatile uint32_t STATE;
43
	};
44
	volatile uint32_t CLEAR;
45
	volatile uint32_t DIRECTION_OUT;
46
	volatile uint32_t DIRECTION_IN;
47
	volatile uint32_t OUTPUT;
48
	volatile uint32_t CONTROL;
49
};
50

51
static struct gpio_chip mik_gpio_chip;
52

53
static inline
54
void mik_gpio_irq_en(volatile struct gpio_reg *gpio_reg,
55
			uint32_t mask) {
56

57
}
58

59
static inline void mik_gpio_irq_dis(volatile struct gpio_reg *gpio_reg,
60
				uint32_t mask) {
61
}
62

63
static inline uint32_t mik_gpio_irq_get_status(
64
					volatile struct gpio_reg *gpio_reg) {
65
	return 0;
66

67
}
68

69
static inline void mik_gpio_irq_clear_status(
70
		volatile struct gpio_reg *gpio_reg, uint32_t mask) {
71

72
}
73

74
static inline volatile struct gpio_reg *mik_gpio_get_gpio_port(
75
	unsigned char port) {
76
	switch (port) {
77
	case 0:
78
		return GPIOA;
79
	case 1:
80
		return GPIOB;
81
	case 2:
82
		return GPIOC;
83
		break;
84
	default:
85
		return NULL;
86
	}
87

88
	return 0;
89
}
90

91
irq_return_t mik_gpio_irq_handler(unsigned int irq_nr, void *gpio) {
92
	uint32_t mask = 0;
93
	uint8_t port_num = 0;
94
	volatile struct gpio_reg *gpio_reg = gpio;
95

96
	mask = mik_gpio_irq_get_status(gpio_reg);
97

98
	mik_gpio_irq_clear_status(gpio_reg, mask);
99

100
	gpio_handle_irq(&mik_gpio_chip, port_num, mask);
101

102
	return IRQ_HANDLED;
103
}
104

105
static int mik_gpio_setup_irq(int port, uint32_t mask, int mode) {
106
	int res;
107
	volatile struct gpio_reg *gpio_reg;
108
	// int type;
109
	// int edge;
110
	// int pol;
111

112
	gpio_reg = mik_gpio_get_gpio_port(port);
113
	if (gpio_reg == NULL) {
114
		return -1;
115
	}
116

117
	res = irq_attach(0, mik_gpio_irq_handler, 0, (void *)gpio_reg, "GPIO Irq");
118
	if (res < 0) {
119
		return res;
120
	}
121

122
	if ((mode & GPIO_MODE_INT_MODE_LEVEL0)
123
	    || (mode & GPIO_MODE_INT_MODE_LEVEL1)) {
124
	}
125
	else {
126
	}
127

128
	if ((mode & GPIO_MODE_INT_MODE_RISING)
129
	    && (mode & GPIO_MODE_INT_MODE_FALLING)) {
130
	}
131
	else {
132
	}
133

134
	if ((mode & GPIO_MODE_INT_MODE_RISING)
135
	    || (mode & GPIO_MODE_INT_MODE_LEVEL1)) {
136
	}
137
	else {
138
	}
139

140

141
	if (mode & GPIO_MODE_IN_INT_EN) {
142
		mik_gpio_irq_en(gpio_reg, mask);
143
	}
144

145

146
	return res;
147
}
148

149
static int mik_gpio_setup_mode(unsigned char port, gpio_mask_t pins,
150
    int mode) {
151
	volatile struct gpio_reg *gpio_reg;
152
	char *clk_name = NULL;
153
	uint32_t alt = 0;
154
	uint32_t pull = 0;
155

156
	gpio_reg = mik_gpio_get_gpio_port(port);
157
	if (gpio_reg == NULL) {
158
		return -1;
159
	}
160

161
	switch (port) {
162
	case 0:
163
		clk_name = CONF_GPIO_PORT_0_CLK_ENABLE();
164
		break;
165
	case 1:
166
		clk_name = CONF_GPIO_PORT_1_CLK_ENABLE();
167
		break;
168
	case 2:
169
		clk_name = CONF_GPIO_PORT_2_CLK_ENABLE();
170
		break;
171
	default:
172
		return -1;
173
	}
174

175
	/* Enable port */
176
	clk_enable(clk_name);
177

178
	for (int pin = 0; pin < GPIO_PINS_NUMBER; pin++) {
179
		if (!(pins & (1 << pin))) {
180
			continue;
181
		}
182

183
		if (mode & GPIO_MODE_IN) {
184
			gpio_reg->DIRECTION_IN |= 1 << pin;
185
			alt = 0;
186
		}
187

188
		if (mode & GPIO_MODE_OUT) {
189
			gpio_reg->DIRECTION_OUT |= 1 << pin;
190
			alt = 0;
191
		}
192

193
		if (mode & GPIO_MODE_IN_PULL_UP) {
194
			pull = 1;
195
		}
196

197
		if (mode & GPIO_MODE_IN_PULL_DOWN) {
198
			pull = 2;
199
		}
200

201
		if (mode & GPIO_MODE_OUT_ALTERNATE) {
202
			alt = GPIO_GET_ALTERNATE(mode);
203
		}
204

205
		mik_pad_cfg_set_func(port, pin, alt);
206
		mik_pad_cfg_set_ds(port, pin, 0);
207
		mik_pad_cfg_set_pupd(port, pin, pull);
208
	}
209

210
	if (mode & GPIO_MODE_INT_SECTION) {
211
		mik_gpio_setup_irq(port, pins, mode);
212
	}
213

214
	return 0;
215
}
216

217
static void mik_gpio_set(unsigned char port, gpio_mask_t pins, char level) {
218
	volatile struct gpio_reg *gpio_reg;
219

220
	gpio_reg = mik_gpio_get_gpio_port(port);
221
	if (gpio_reg == NULL) {
222
		return;
223
	}
224

225
	if (level) {
226
		gpio_reg->SET |= pins;
227
	}
228
	else {
229
		gpio_reg->CLEAR |= pins;
230
	}
231
}
232

233
static gpio_mask_t mik_gpio_get(unsigned char port, gpio_mask_t pins) {
234
	volatile struct gpio_reg *gpio_reg;
235

236
	gpio_reg = mik_gpio_get_gpio_port(port);
237
	if (gpio_reg == NULL) {
238
		return -1;
239
	}
240

241
	return gpio_reg->SET & pins;
242
}
243

244
static struct gpio_chip mik_gpio_chip = {
245
	.setup_mode = mik_gpio_setup_mode,
246
    .get = mik_gpio_get,
247
    .set = mik_gpio_set,
248
    .nports = 3
249
};
250

251
GPIO_CHIP_DEF(&mik_gpio_chip);
252

253
//STATIC_IRQ_ATTACH(GPIO_IRQ, gpio_irq_handler, NULL);
254

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

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

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

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