Skip to content
This repository was archived by the owner on Aug 9, 2022. It is now read-only.

Commit 8a3f2e7

Browse files
committed
PoC gpio driver for all output enabled pins using the embedded-hal traits
1 parent 584cf1f commit 8a3f2e7

File tree

3 files changed

+215
-0
lines changed

3 files changed

+215
-0
lines changed

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ edition = "2018"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10+
# esp32 = { version = "0.2.1" }
11+
esp32 = { path = "../../hal/esp32-pac"}
12+
13+
[dependencies.embedded-hal]
14+
features = ["unproven"]
15+
version = "0.2.3"

src/gpio.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
2+
use core::marker::PhantomData;
3+
use core::convert::Infallible;
4+
5+
use esp32::{GPIO, IO_MUX};
6+
use embedded_hal::digital::v2::OutputPin;
7+
8+
/// Extension trait to split a GPIO peripheral in independent pins and registers
9+
pub trait GpioExt {
10+
/// The to split the GPIO into
11+
type Parts;
12+
13+
/// Splits the GPIO block into independent pins and registers
14+
fn split(self) -> Self::Parts;
15+
}
16+
17+
/// Input mode (type state)
18+
pub struct Input<MODE> {
19+
_mode: PhantomData<MODE>,
20+
}
21+
22+
/// Floating input (type state)
23+
pub struct Floating;
24+
25+
/// Pulled down input (type state)
26+
pub struct PullDown;
27+
28+
/// Pulled up input (type state)
29+
pub struct PullUp;
30+
31+
/// Open drain input or output (type state)
32+
pub struct OpenDrain;
33+
34+
/// Push pull output (type state)
35+
pub struct PushPull;
36+
37+
/// Analog mode (type state)
38+
pub struct Analog;
39+
40+
/// Output mode (type state)
41+
pub struct Output<MODE> {
42+
_mode: PhantomData<MODE>,
43+
}
44+
45+
macro_rules! gpio {
46+
($GPIO:ident: [
47+
$($pxi:ident: ($pname:ident, $MODE:ty),)+
48+
]) => {
49+
50+
impl GpioExt for $GPIO {
51+
type Parts = Parts;
52+
53+
fn split(self) -> Self::Parts {
54+
Parts {
55+
$(
56+
$pname: $pxi { _mode: PhantomData },
57+
)+
58+
}
59+
}
60+
}
61+
62+
pub struct Parts {
63+
$(
64+
/// Pin
65+
pub $pname: $pxi<$MODE>,
66+
)+
67+
}
68+
69+
// create all the pins, we can also add functionality
70+
// applicable to all pin states here
71+
$(
72+
/// Pin
73+
pub struct $pxi<MODE> {
74+
_mode: PhantomData<MODE>,
75+
}
76+
)+
77+
78+
};
79+
}
80+
81+
// All info on reset state pulled from 4.10 IO_MUX Pad List in the reference manual
82+
gpio! {
83+
GPIO: [
84+
Gpio0: (gpio0, Input<PullUp>),
85+
Gpio1: (gpio1, Input<PullUp>),
86+
Gpio2: (gpio2, Input<PullDown>),
87+
Gpio3: (gpio3, Input<PullUp>),
88+
Gpio4: (gpio4, Input<PullDown>),
89+
Gpio5: (gpio5, Input<PullUp>),
90+
Gpio6: (gpio6, Input<PullUp>),
91+
Gpio7: (gpio7, Input<PullUp>),
92+
Gpio8: (gpio8, Input<PullUp>),
93+
Gpio9: (gpio9, Input<PullUp>),
94+
Gpio10: (gpio10, Input<PullUp>),
95+
Gpio11: (gpio11, Input<PullUp>),
96+
Gpio12: (gpio12, Input<PullDown>),
97+
Gpio13: (gpio13, Input<Floating>),
98+
Gpio14: (gpio14, Input<Floating>),
99+
Gpio15: (gpio15, Input<PullUp>),
100+
Gpio16: (gpio16, Input<Floating>),
101+
Gpio17: (gpio17, Input<Floating>),
102+
Gpio18: (gpio18, Input<Floating>),
103+
Gpio19: (gpio19, Input<Floating>),
104+
Gpio20: (gpio20, Input<Floating>),
105+
Gpio21: (gpio21, Input<Floating>),
106+
Gpio22: (gpio22, Input<Floating>),
107+
Gpio23: (gpio23, Input<Floating>),
108+
// TODO these pins have a reset mode of 0 (apart from Gpio27),
109+
// input disable, does that mean they are actually in output mode on reset?
110+
Gpio25: (gpio25, Input<Floating>),
111+
Gpio26: (gpio26, Input<Floating>),
112+
Gpio27: (gpio27, Input<Floating>),
113+
// TODO all these really missing?
114+
// Gpio24: (gpio24, Input<Floating>),
115+
// Gpio28: (gpio28, Input<Floating>),
116+
// Gpio29: (gpio29, Input<Floating>),
117+
// Gpio30: (gpio30, Input<Floating>),
118+
// Gpio31: (gpio31, Input<Floating>),
119+
Gpio32: (gpio32, Input<Floating>),
120+
Gpio33: (gpio33, Input<Floating>),
121+
Gpio34: (gpio34, Input<Floating>),
122+
Gpio35: (gpio35, Input<Floating>),
123+
Gpio36: (gpio36, Input<Floating>),
124+
Gpio37: (gpio37, Input<Floating>),
125+
Gpio38: (gpio38, Input<Floating>),
126+
Gpio39: (gpio39, Input<Floating>),
127+
]
128+
}
129+
130+
macro_rules! impl_output {
131+
($en:ident, $outs:ident, $outc:ident, [
132+
// index, gpio pin name, funcX name, iomux pin name, iomux mcu_sel bits
133+
$($pxi:ident: ($i:expr, $pin:ident, $funcXout:ident, $iomux:ident, $mcu_sel_bits:expr),)+
134+
]) => {
135+
$(
136+
impl<MODE> OutputPin for $pxi<Output<MODE>> {
137+
type Error = Infallible;
138+
139+
fn set_high(&mut self) -> Result<(), Self::Error> {
140+
// NOTE(unsafe) atomic write to a stateless register
141+
unsafe { (*GPIO::ptr()).$outs.write(|w| w.bits(1 << $i)) };
142+
Ok(())
143+
}
144+
145+
fn set_low(&mut self) -> Result<(), Self::Error> {
146+
// NOTE(unsafe) atomic write to a stateless register
147+
unsafe { (*GPIO::ptr()).$outc.write(|w| w.bits(1 << $i)) };
148+
Ok(())
149+
}
150+
}
151+
152+
impl<MODE> $pxi<MODE> {
153+
pub fn into_push_pull_output(self) -> $pxi<Output<PushPull>> {
154+
let gpio = unsafe{ &*GPIO::ptr() };
155+
let iomux = unsafe{ &*IO_MUX::ptr() };
156+
gpio.$en.modify(|_, w| unsafe { w.bits(0x1 << $i) });
157+
gpio.$funcXout.modify(|_, w| unsafe { w.bits(0x100) });
158+
159+
iomux.$iomux.modify(|_, w| unsafe { w.mcu_sel().bits($mcu_sel_bits) });
160+
$pxi { _mode: PhantomData }
161+
}
162+
}
163+
)+
164+
};
165+
}
166+
167+
impl_output! {
168+
enable_w1ts, out_w1ts, out_w1tc, [
169+
Gpio0: (0, pin0, func0_out_sel_cfg, gpio0, 0b00),
170+
Gpio1: (1, pin1, func1_out_sel_cfg, u0txd, 0b10),
171+
Gpio2: (2, pin2, func2_out_sel_cfg, gpio2, 0b00),
172+
Gpio3: (3, pin3, func3_out_sel_cfg, u0rxd, 0b10),
173+
Gpio4: (4, pin4, func4_out_sel_cfg, gpio4, 0b10),
174+
Gpio5: (5, pin5, func5_out_sel_cfg, gpio5, 0b10),
175+
Gpio6: (6, pin6, func6_out_sel_cfg, sd_clk, 0b10),
176+
Gpio7: (7, pin7, func7_out_sel_cfg, sd_data0, 0b10),
177+
Gpio8: (8, pin8, func8_out_sel_cfg, sd_data1, 0b10),
178+
Gpio9: (9, pin9, func9_out_sel_cfg, sd_data2, 0b10),
179+
Gpio10: (10, pin10, func10_out_sel_cfg, sd_data3, 0b10),
180+
Gpio11: (11, pin11, func11_out_sel_cfg, sd_cmd, 0b10),
181+
Gpio12: (12, pin12, func12_out_sel_cfg, mtdi, 0b10),
182+
Gpio13: (13, pin13, func13_out_sel_cfg, mtck, 0b10),
183+
Gpio14: (14, pin14, func14_out_sel_cfg, mtms, 0b10),
184+
Gpio15: (15, pin15, func15_out_sel_cfg, mtdo, 0b10),
185+
Gpio16: (16, pin16, func16_out_sel_cfg, gpio16, 0b10),
186+
Gpio17: (17, pin17, func17_out_sel_cfg, gpio17, 0b10),
187+
Gpio18: (18, pin18, func18_out_sel_cfg, gpio18, 0b10),
188+
Gpio19: (19, pin19, func19_out_sel_cfg, gpio19, 0b10),
189+
Gpio20: (20, pin20, func20_out_sel_cfg, gpio20, 0b10),
190+
Gpio21: (21, pin21, func21_out_sel_cfg, gpio21, 0b10),
191+
Gpio22: (22, pin22, func22_out_sel_cfg, gpio22, 0b10),
192+
Gpio23: (23, pin23, func23_out_sel_cfg, gpio23, 0b10),
193+
Gpio25: (25, pin25, func25_out_sel_cfg, gpio25, 0b10),
194+
Gpio26: (26, pin26, func26_out_sel_cfg, gpio26, 0b10),
195+
Gpio27: (27, pin27, func27_out_sel_cfg, gpio27, 0b10),
196+
]
197+
}
198+
199+
impl_output! {
200+
enable1_w1ts, out1_w1ts, out1_w1tc, [
201+
Gpio32: (0, pin32, func32_out_sel_cfg, gpio32, 0b00),
202+
Gpio33: (1, pin33, func33_out_sel_cfg, gpio33, 0b00),
203+
/* Deliberately omitting 34-39 as these can *only* be inputs */
204+
]
205+
}

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![no_std]
2+
3+
pub use embedded_hal as ehal;
4+
pub mod gpio;

0 commit comments

Comments
 (0)