-
Notifications
You must be signed in to change notification settings - Fork 3
/
gpio2.c
72 lines (55 loc) · 1.68 KB
/
gpio2.c
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
#include "gpio2.h"
static uint32_t maskn(uint16_t pins, uint8_t bits, uint32_t val) {
uint32_t mask = 0;
while (pins) {
if (pins & 1) mask |= val;
pins >>= 1;
val <<= bits;
}
return mask;
}
void gpioConfig(enum GPIO_Pin pins, enum GPIO_Conf conf) {
//assert(!((pins>>24) & ((pins>>24)-1)));
while ((pins>>24) & ((pins>>24)-1)); // hang if mixed gpios
struct GPIOA_Type* gpio = &GPIO_ALL[(pins >> 16) & 7].gpio;
pins &= Pin_All;
if ((conf & 0x3000) == GPIO_ANALOG) {
conf = GPIO_ANALOG; // clear all other flags
}
if ((conf & 0x0030) == 0x0030) {
conf &= ~0x0030; // both PU and PD -> both off (reserved according to manual)
}
uint32_t mode = (conf & 0x3000) >> 12;
uint32_t af = (conf & 0x0f00) >> 8;
uint32_t od = (conf & 0x0080) >> 7;
uint32_t pupd = (conf & 0x0030) >> 4;
uint32_t spd = (conf & 0x0003);
uint32_t msk2 = maskn(pins, 2, 0x3);
gpio->MODER &= ~msk2;
gpio->PUPDR &= ~msk2;
gpio->OSPEEDR &= ~msk2;
if (od) {
gpio->OTYPER |= pins;
} else {
gpio->OTYPER &= ~pins;
}
gpio->OSPEEDR |= maskn(pins, 2, spd);
gpio->PUPDR |= maskn(pins, 2, pupd);
gpio->MODER |= maskn(pins, 2, mode);
if (mode == 2) { // AF OUTPUT
gpio->AFRL &= ~maskn(pins & 0xff, 4, 0xf);
gpio->AFRL |= maskn(pins & 0xff, 4, af);
gpio->AFRH &= ~maskn((pins>>8) & 0xff, 4, 0xf);
gpio->AFRH |= maskn((pins>>8) & 0xff, 4, af);
}
}
uint32_t gpioLock(enum GPIO_Pin pins) {
//assert(!((pins>>24) & ((pins>>24)-1)));
while ((pins>>24) & ((pins>>24)-1)); // hang if mixed gpios
struct GPIOA_Type* gpio = &GPIO_ALL[(pins >> 16) & 7].gpio;
pins &= Pin_All;
gpio->LCKR = pins | (1<<16);
gpio->LCKR = pins ;
gpio->LCKR = pins | (1<<16);
return gpio->LCKR;
}