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
|
/** Base addresses for the Gpio ports. */
static GPIOA_BASE: u32 = 0x48000000;
static GPIOB_BASE: u32 = 0x48000400;
static GPIOC_BASE: u32 = 0x48000800;
static GPIOH_BASE: u32 = 0x48001C00;
use crate::hal::common::{regget, regset};
use crate::hal::rcc::{get_rcc, GpioPortN};
#[derive(Clone, Copy)]
pub enum GpioMode {
Input = 0,
Output = 1,
Alternate = 2,
Analog = 3,
}
#[derive(Clone, Copy)]
pub enum GpioOutputType {
PushPull = 0,
OpenDrain = 1,
}
pub enum GpioSpeed {
Low = 0,
Medium = 1,
High = 2,
VeryHigh = 3,
}
pub enum GpioPullDir {
None = 0,
Up = 1,
Down = 2,
}
/* Struct representation of a GPIO Port. */
#[repr(C)]
struct GpioPortMem {
/* Mode of each GPIO pin for this GPIO port. */
mode_r: u32,
/* Output type for each gpio pin in this port. */
otype_r: u32,
/* GPIO port output speed. */
ospeed_r: u32,
/* GPIO port pull-up/pull-down register */
pupd_r: u32,
/* GPIO port input data register. */
id_r: u32,
/* GPIO port output data register. */
od_r: u32,
/* GPIO port bit set/reset register. */
bsr_r: u32,
/* GPIO port configuration lock register. */
lck_r: u32,
/* Alternate function low-register. */
af_rl: u32,
/* Alternate function high-register. */
af_rh: u32,
/* GPIO port bit register. */
br_r: u32,
/* Analog switch control register. */
asc_r: u32,
}
#[derive(Clone, Copy)]
pub struct GpioPort {
mem: *mut GpioPortMem,
}
pub struct GpioPin {
port: GpioPort,
pin_number: u8,
}
impl GpioPort {
pub fn pin(self: &mut GpioPort, n: u8) -> GpioPin {
return GpioPin {
port: *self,
pin_number: n,
};
}
}
impl GpioPin {
pub unsafe fn set_mode(self: &mut GpioPin, mode: GpioMode) -> () {
let mode_ptr: *mut u32 = &mut (*self.port.mem).mode_r;
regset(mode_ptr, 3 << self.pin_number * 2, mode as u32);
}
pub unsafe fn set_pull_dir(self: &mut GpioPin, pull_dir: GpioPullDir) {
let pull_dir_ptr: *mut u32 = &mut (*self.port.mem).pupd_r;
regset(pull_dir_ptr, 3 << self.pin_number * 2, pull_dir_ptr as u32);
}
pub unsafe fn set_output_type(self: &mut GpioPin, otype: GpioOutputType) -> () {
let otype_ptr: *mut u32 = &mut (*self.port.mem).otype_r;
regset(otype_ptr, 1 << self.pin_number, otype as u32);
}
pub unsafe fn set_output_speed(self: &mut GpioPin, ospeed: GpioSpeed) -> () {
let ospeed_ptr: *mut u32 = &mut (*self.port.mem).ospeed_r;
regset(ospeed_ptr, 3 << self.pin_number * 2, ospeed as u32);
}
pub unsafe fn get(self: &mut GpioPin) -> bool {
let id_r: *mut u32 = &mut (*self.port.mem).id_r;
regget(id_r, 1 << self.pin_number) != 0
}
pub unsafe fn set_high(self: &mut GpioPin) {
self.set(true);
}
pub unsafe fn set_low(self: &mut GpioPin) {
self.set(false);
}
pub unsafe fn set(self: &mut GpioPin, on: bool) -> () {
let od_r: *mut u32 = &mut (*self.port.mem).od_r;
regset(od_r, 1 << self.pin_number, on as u32);
}
}
pub fn get_gpio_port_a() -> GpioPort {
get_rcc().enable_gpio_port(GpioPortN::A);
return GpioPort {
mem: GPIOA_BASE as *mut GpioPortMem,
};
}
pub fn get_gpio_port_b() -> GpioPort {
get_rcc().enable_gpio_port(GpioPortN::B);
return GpioPort {
mem: GPIOB_BASE as *mut GpioPortMem,
};
}
|