embox

Форк
0
/
stm32_gpio_f0.c 
288 строк · 7.5 Кб
1
/**
2
 * @file stm32_gpio_f0.c
3
 * @brief
4
 * @author Vadim Deryabkin
5
 * @version
6
 * @date 29.01.2021
7
 */
8

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

12
#include <embox/unit.h>
13
#include <lib/libds/array.h>
14

15
#include <kernel/irq.h>
16

17
#include <drivers/gpio/gpio_driver.h>
18

19
#include "stm32_gpio_conf_f0.h"
20

21
static gpio_struct *get_gpio (unsigned char port) {
22
    uint8_t *p = (uint8_t *)GPIOA;
23
    p += 1024 * port;
24
    return (gpio_struct *)p;
25
}
26

27
static void set_gpio_mode_output (gpio_struct* GPIO, gpio_mask_t pins) {
28
    uint32_t buf_mode = 0;
29
    uint32_t msk_mode = 0;
30
    for (int i = 0; i < PINS_NUMBER; i++) {
31
        if (pins & (1 << i)) {
32
            buf_mode |= M_PP(i);
33
            msk_mode |= M_MSK(i);
34
        }
35
    }
36

37
    GPIO->MODER &= ~msk_mode;
38
    GPIO->MODER |= buf_mode;
39
}
40

41
static void set_gpio_mode_input (gpio_struct* GPIO, gpio_mask_t pins) {
42
    uint32_t msk_mode = 0;
43
    for (int i = 0; i < PINS_NUMBER; i++) {
44
        if (pins & (1 << i)) {
45
            msk_mode |= M_MSK(i);
46
        }
47
    }
48

49
    GPIO->MODER &= ~msk_mode;
50
}
51

52
static void set_gpio_mode_pull_up (gpio_struct* GPIO, gpio_mask_t pins) {
53
    uint32_t buf_mode = 0;
54
    uint32_t msk_mode = 0;
55
    for (int i = 0; i < PINS_NUMBER; i++) {
56
        if (pins & (1 << i)) {
57
            buf_mode |= P_PU(i);
58
            msk_mode |= P_MSK(i);
59
        }
60
    }
61

62
    GPIO->PUPDR &= ~msk_mode;
63
    GPIO->PUPDR |= buf_mode;
64
}
65

66
static void set_gpio_mode_pull_down (gpio_struct* GPIO, gpio_mask_t pins) {
67
    uint32_t buf_mode = 0;
68
    uint32_t msk_mode = 0;
69
    for (int i = 0; i < PINS_NUMBER; i++) {
70
        if (pins & (1 << i)) {
71
            buf_mode |= P_PD(i);
72
            msk_mode |= P_MSK(i);
73
        }
74
    }
75

76
    GPIO->PUPDR &= ~msk_mode;
77
    GPIO->PUPDR |= buf_mode;
78
}
79

80
static void set_gpio_high_spped (gpio_struct* GPIO, gpio_mask_t pins) {
81
    uint32_t buf_mode = 0;
82
    uint32_t msk_mode = 0;
83
    for (int i = 0; i < PINS_NUMBER; i++) {
84
        if (pins & (1 << i)) {
85
            buf_mode |= S_HS(i);
86
            msk_mode |= S_MSK(i);
87
        }
88
    }
89

90
    GPIO->OSPEEDR &= ~msk_mode;
91
    GPIO->OSPEEDR |= buf_mode;
92
}
93

94
static void set_gpio_mode_alt_func (gpio_struct* GPIO, gpio_mask_t pins,
95
                                    uint32_t func) {
96
    uint32_t buf_mode = 0;
97
    uint32_t msk_mode = 0;
98
    for (int i = 0; i < PINS_NUMBER / 2; i++) {
99
        if (pins & (1 << i)) {
100
            buf_mode |= L_AF(i, func);
101
            msk_mode |= L_AF_MSK(i);
102
        }
103
    }
104

105
    GPIO->AFRL &= ~msk_mode;
106
    GPIO->AFRL |= buf_mode;
107

108
    buf_mode = 0;
109
    msk_mode = 0;
110
    for (int i = PINS_NUMBER / 2; i < PINS_NUMBER; i++) {
111
        if (pins & (1 << i)) {
112
            buf_mode |= H_AF(i, func);
113
            msk_mode |= H_AF_MSK(i);
114
        }
115
    }
116

117
    GPIO->AFRH &= ~msk_mode;
118
    GPIO->AFRH |= buf_mode;
119

120
    buf_mode = 0;
121
    msk_mode = 0;
122
    for (int i = 0; i < PINS_NUMBER; i++) {
123
        if (pins & (1 << i)) {
124
            buf_mode |= M_ALT(i);
125
            msk_mode |= M_MSK(i);
126
        }
127
    }
128

129
    GPIO->MODER &= ~msk_mode;
130
    GPIO->MODER |= buf_mode;
131
}
132

133
static void set_gpio_mode_open_drain (gpio_struct* GPIO, gpio_mask_t pins) {
134
    GPIO->OTYPER |= pins;
135
}
136

137
static void set_gpio_mode_push_pull (gpio_struct* GPIO, gpio_mask_t pins) {
138
    GPIO->OTYPER &= ~pins;
139
}
140

141
static void set_gpio_it_rising (gpio_mask_t pins) {
142
    EXTI->RTSR |= pins;
143
}
144

145
static void reset_gpio_it_rising (gpio_mask_t pins) {
146
    EXTI->RTSR &= ~pins;
147
}
148

149
static void set_gpio_it_falling (gpio_mask_t pins) {
150
    EXTI->FTSR |= pins;
151
}
152

153
static void reset_gpio_it_falling (gpio_mask_t pins) {
154
    EXTI->FTSR &= ~pins;
155
}
156

157
static void set_exti_interrupt (unsigned char port, gpio_mask_t pins) {
158
    for (int i = 0; i < PINS_NUMBER; i++) {
159
        if (pins & (1 << i)) {
160
            SYSCFG->EXTICR[i / 4] &= ~(0xF << 4 * (i % 4)); // DocID025023 Rev 4, 147/779.
161
            SYSCFG->EXTICR[i / 4] |= port << 4 * (i % 4);
162
        }
163
    }
164

165
    EXTI->PR = pins;
166
    EXTI->EMR |= pins;
167
    EXTI->IMR |= pins;
168
}
169

170
static void reset_exti_interrupt (unsigned char port, gpio_mask_t pins) {
171
    EXTI->EMR &= ~pins;
172
    EXTI->IMR &= ~pins;
173
    EXTI->PR = pins;
174
}
175

176
static int stm32_gpio_setup_mode(unsigned char port, gpio_mask_t pins, int mode) {
177
    assert(!((port == GPIO_PORT_E) || (port > GPIO_PORT_F)));
178

179
    set_gpio_pwr(port);
180

181
    gpio_struct* GPIO = get_gpio(port);
182

183
    set_gpio_high_spped(GPIO, pins);
184

185
    if (mode & GPIO_MODE_OUT) {
186
        set_gpio_mode_output(GPIO, pins);
187

188
        if (mode & GPIO_MODE_OUT_OPEN_DRAIN)    set_gpio_mode_open_drain(GPIO, pins);
189
        if (mode & GPIO_MODE_OUT_PUSH_PULL)        set_gpio_mode_push_pull(GPIO, pins);
190
        reset_exti_interrupt(port, pins);
191
    } else if (mode & GPIO_MODE_IN) {
192
        set_gpio_mode_input(GPIO, pins);
193

194
        if (mode & GPIO_MODE_IN_PULL_UP)         set_gpio_mode_pull_up(GPIO, pins);
195
        if (mode & GPIO_MODE_IN_PULL_DOWN)        set_gpio_mode_pull_down(GPIO, pins);
196
        reset_exti_interrupt(port, pins);
197
    } else if (mode & GPIO_MODE_OUT_ALTERNATE) {
198
        uint32_t func = GPIO_GET_ALTERNATE(mode);
199
        set_gpio_mode_alt_func(GPIO, pins, func);
200

201
        if (mode & GPIO_MODE_IN_PULL_UP)         set_gpio_mode_pull_up(GPIO, pins);
202
        if (mode & GPIO_MODE_IN_PULL_DOWN)        set_gpio_mode_pull_down(GPIO, pins);
203
        if (mode & GPIO_MODE_OUT_PUSH_PULL)        set_gpio_mode_push_pull(GPIO, pins);
204
        if (mode & GPIO_MODE_OUT_OPEN_DRAIN)    set_gpio_mode_open_drain(GPIO, pins);
205

206
        reset_exti_interrupt(port, pins);
207
    } else if (mode & GPIO_MODE_INT_MODE_RISING_FALLING) {
208
        if ((mode & GPIO_MODE_INT_MODE_RISING_FALLING) ==
209
                GPIO_MODE_INT_MODE_RISING_FALLING) {
210
            set_gpio_it_rising(pins);
211
            set_gpio_it_falling(pins);
212
        } else if (mode & GPIO_MODE_INT_MODE_RISING) {
213
            set_gpio_it_rising(pins);
214
            reset_gpio_it_falling(pins);
215
        } else if (mode & GPIO_MODE_INT_MODE_FALLING) {
216
            reset_gpio_it_rising(pins);
217
            set_gpio_it_falling(pins);
218
        }
219

220
        set_exti_interrupt(port, pins);
221
    }
222

223
    return 0;
224
}
225

226
static void stm32_gpio_set(unsigned char port, gpio_mask_t pins, char level) {
227
    assert(!((port == GPIO_PORT_E) || (port > GPIO_PORT_F)));
228

229
    gpio_struct* GPIO = get_gpio(port);
230

231
    if (level) {
232
        GPIO->BSRR = pins;
233
    } else {
234
        GPIO->BRR = pins;
235
    }
236
}
237

238
static gpio_mask_t stm32_gpio_get(unsigned char port, gpio_mask_t pins) {
239
    assert(!((port == GPIO_PORT_E) || (port > GPIO_PORT_F)));
240

241
    gpio_struct* GPIO = get_gpio(port);
242

243
    return GPIO->IDR & pins;
244
}
245

246

247
static struct gpio_chip stm32_gpio_chip = {
248
    .setup_mode = stm32_gpio_setup_mode,
249
    .get = stm32_gpio_get,
250
    .set = stm32_gpio_set,
251
    .nports = STM32_GPIO_PORTS_COUNT
252
};
253

254
irq_return_t stm32_gpio_irq_handler(unsigned int irq_nr, void *data) {
255
    uint16_t pending = EXTI->PR;
256
    EXTI->PR = 0xFFFF;
257

258
    /* Notify all GPIO ports about interrupt */
259
    for (int i = 0; i < STM32_GPIO_PORTS_COUNT; i++) {
260
        gpio_handle_irq(&stm32_gpio_chip, i, pending);
261
    }
262

263
    return IRQ_HANDLED;
264
}
265

266
static const unsigned char exti_irqs[] = {
267
    EXTI0_1_IRQ, EXTI2_3_IRQ, EXTI4_15_IRQ
268
};
269

270
static int stm32_gpio_init(void) {
271
    int res, i;
272

273
    for (i = 0; i < ARRAY_SIZE(exti_irqs); i++) {
274
        res = irq_attach(exti_irqs[i], stm32_gpio_irq_handler, 0, NULL,
275
            "STM32 EXTI irq handler");
276
        if (res < 0) {
277
            return -1;
278
        }
279
    }
280

281
    return gpio_register_chip(&stm32_gpio_chip, STM32_GPIO_CHIP_ID);
282
}
283

284
EMBOX_UNIT_INIT(stm32_gpio_init);
285

286
STATIC_IRQ_ATTACH(EXTI0_1_IRQ, stm32_gpio_irq_handler, NULL);
287
STATIC_IRQ_ATTACH(EXTI2_3_IRQ, stm32_gpio_irq_handler, NULL);
288
STATIC_IRQ_ATTACH(EXTI4_15_IRQ, stm32_gpio_irq_handler, NULL);
289

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

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

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

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