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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
// package for the GPIO system.
package gpio {
location gpio_a_base = 0x4800_0000;
location gpio_b_base = 0x4800_0400;
location gpio_c_base = 0x4800_0400;
/** IO Data. This is just an expressive boolean. */
bittype data_t : enum(1) {
low = 0,
high = 1,
}
/**
* Structure of the GPIO port on an stm32l432
*/
objtype gpio_t {
assert_pos(0);
reg (32) : {
/** The mode for each pin. */
mode_r : enum(2) {
/** The GPIO pin is used for input. */
input = 0b0,
/** The GPIO pin is used for general output. */
general_output = 0b1,
/**
* The GPIO pin is used for whatever the altername function
* is defined as (refer to manual).
*/
alternate_function = 0b10,
/**
* The GPIO pin is set to analog.
*/
analog = 0b11,
} [16];
};
/**
* The output type.
*/
assert_pos(0x04);
reg (32) : {
otype_r : enum(1) {
/**
* The GPIO pin is capable of sinking to ground (for LOW) or providing
* power (for HIGH).
*/
push_pull = 0,
/**
* The GPIO pin is only able to sink current (for LOW), or nothing (for
* HIGH).
*/
open_drain = 1,
}[16];
reserved(16); // Have to pad out the remaining 16 bits.
};
/**
* Sets the speed of the provided GPIO pin.
*/
assert_pos(0x08);
reg (32) : {
ospeed_r : enum(2) {
low = 0,
medium = 1,
high = 2,
very_high = 3,
} [16];
};
/**
* Pullup/Pulldown type
*/
assert_pos(0x0c);
wo reg (32) : {
pupd_r : enum(2) {
none = 0b0,
// Compiles to Gpio::PupdR::PullUp
pull_up = 0b1,
// Compiles to Gpio::PupdR::PullDown
pull_down = 0b10,
// Not used, but has to be included to fill out the enum.
reserved = 0b11,
} [16];
};
/**
* Input data register.
*
* Reading form the provided pin will yield high if the pin is on, or low if
* the pin is low.
*/
assert_pos(0x10);
ro reg (32) : {
id_r : data_t[16];
reserved(16);
};
/**
* Output data register.
*
* Writing to this register sets the appropriate register to low/high.
*/
assert_pos(0x14);
wo reg (32) : {
rw od_r : data_t[16];
reserved(16);
};
/**
* The GPIO port bit set/reset register.
*/
assert_pos(0x18);
reg bsr_r(32) : {
/**
* Sets the pins associated with the bits. Like od_r, but can be used to
* turn on multiple pins at once.
*/
wo set : (16);
/**
* Resets the pins written to this register.
*/
wo reset : (16);
};
assert_pos(0x1c);
reg(32) : {
lock : enum(1) {
unlocked = 0
locked = 1;
} [16];
lockk : (1);
reserved(15);
};
/**
* Alternate function registers (both low/high).
* Each nybble refers to a pin.
*/
assert_pos(0x20);
reg(64) : {
afn : (4)[16];
}
/**
* The bit reset register.
*/
assert_pos(0x28);
reg(32) : {
wo br_r : (16);
reserved (16);
}
/**
* Analog switch control for the pin.
*/
reg(32) : {
asc_r : (16);
reserved (16);
}
}
object gpio_a at gpio_a_base : gpio_t;
object gpio_b at gpio_b_base : gpio_t;
object gpio_c at gpio_c_base : gpio_t;
}
|