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

Commit 94dc49f

Browse files
authored
Merge pull request #55 from hanhossain/feat_i2c
Blocking I2C
2 parents e8dd426 + 6ac5caf commit 94dc49f

File tree

6 files changed

+805
-10
lines changed

6 files changed

+805
-10
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ void = { version = "1.0.2", default-features = false }
5050
[dev-dependencies]
5151
panic-halt = "0.2.0"
5252
ili9341 = { version = "0.3.0", features = ["graphics"] }
53+
ssd1306 = "0.3.1"
5354
embedded-graphics = "0.6.2"
55+
mpu6050 = "0.1.3"
5456

5557
[[example]]
5658
name = "alloc"

examples/i2c.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use core::panic::PanicInfo;
5+
use embedded_graphics::{
6+
fonts::{Font8x16, Text},
7+
pixelcolor::BinaryColor,
8+
prelude::*,
9+
style::TextStyle,
10+
};
11+
use embedded_hal::blocking::i2c::{Write, WriteRead};
12+
use esp32_hal::{
13+
clock_control::{self, sleep, CPUSource, ClockControl},
14+
delay::Delay,
15+
dport::Split,
16+
dprintln,
17+
i2c::{self, Error, I2C},
18+
prelude::*,
19+
target::{I2C0, Peripherals},
20+
timer::Timer,
21+
};
22+
use mpu6050::Mpu6050;
23+
use ssd1306::{prelude::*, Builder};
24+
use xtensa_lx::mutex::SpinLockMutex;
25+
26+
#[entry]
27+
fn main() -> ! {
28+
let dp = Peripherals::take().unwrap();
29+
30+
let (mut dport, dport_clock_control) = dp.DPORT.split();
31+
32+
// setup clocks & watchdog
33+
let mut clkcntrl = ClockControl::new(
34+
dp.RTCCNTL,
35+
dp.APB_CTRL,
36+
dport_clock_control,
37+
clock_control::XTAL_FREQUENCY_AUTO,
38+
)
39+
.unwrap();
40+
41+
// set desired clock frequencies
42+
clkcntrl
43+
.set_cpu_frequencies(
44+
CPUSource::PLL,
45+
80.MHz(),
46+
CPUSource::PLL,
47+
240.MHz(),
48+
CPUSource::PLL,
49+
80.MHz(),
50+
)
51+
.unwrap();
52+
53+
// disable RTC watchdog
54+
let (clkcntrl_config, mut watchdog) = clkcntrl.freeze().unwrap();
55+
watchdog.disable();
56+
57+
// disable MST watchdogs
58+
let (.., mut watchdog0) = Timer::new(dp.TIMG0, clkcntrl_config);
59+
let (.., mut watchdog1) = Timer::new(dp.TIMG1, clkcntrl_config);
60+
watchdog0.disable();
61+
watchdog1.disable();
62+
63+
let pins = dp.GPIO.split();
64+
let i2c0 = i2c::I2C::new(
65+
dp.I2C0,
66+
i2c::Pins {
67+
sda: pins.gpio4,
68+
scl: pins.gpio15,
69+
},
70+
400_000,
71+
&mut dport,
72+
);
73+
let i2c0 = SpinLockMutex::new(i2c0);
74+
75+
// Display
76+
let mut display = {
77+
let i2c_wrapper = I2CWrapper::new(&i2c0);
78+
let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c_wrapper).into();
79+
80+
let mut rst = pins.gpio16.into_push_pull_output();
81+
rst.set_low().unwrap();
82+
sleep(10.ms());
83+
rst.set_high().unwrap();
84+
85+
display.init().unwrap();
86+
display.clear();
87+
display.flush().unwrap();
88+
89+
display
90+
};
91+
92+
// IMU
93+
let mut imu = {
94+
let i2c_wrapper = I2CWrapper::new(&i2c0);
95+
let mut imu = Mpu6050::new(i2c_wrapper);
96+
97+
let mut delay = Delay::new();
98+
imu.init(&mut delay).unwrap();
99+
imu
100+
};
101+
102+
Text::new("Hello world!", Point::new(2, 28))
103+
.into_styled(TextStyle::new(Font8x16, BinaryColor::On))
104+
.draw(&mut display)
105+
.unwrap();
106+
display.flush().unwrap();
107+
108+
sleep(3.s());
109+
110+
loop {
111+
let temp = imu.get_temp().unwrap();
112+
let gyro = imu.get_gyro().unwrap();
113+
let acc = imu.get_acc().unwrap();
114+
dprintln!("temp: {}, gyro: {:?}, acc: {:?}", temp, gyro, acc);
115+
sleep(1.s());
116+
}
117+
}
118+
119+
struct I2CWrapper<'a> {
120+
i2c: &'a SpinLockMutex<I2C<I2C0>>,
121+
}
122+
123+
impl<'a> I2CWrapper<'a> {
124+
fn new(i2c: &'a SpinLockMutex<I2C<I2C0>>) -> Self {
125+
Self { i2c }
126+
}
127+
}
128+
129+
impl<'a> Write for I2CWrapper<'a> {
130+
type Error = Error;
131+
132+
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
133+
self.i2c.lock(|x| x.write(addr, bytes))
134+
}
135+
}
136+
137+
impl<'a> WriteRead for I2CWrapper<'a> {
138+
type Error = Error;
139+
140+
fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
141+
self.i2c.lock(|x| x.write_read(address, bytes, buffer))
142+
}
143+
}
144+
145+
#[panic_handler]
146+
fn panic(info: &PanicInfo) -> ! {
147+
dprintln!("----- PANIC -----");
148+
dprintln!("{:?}", info);
149+
loop {}
150+
}

src/gpio/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ macro_rules! impl_input {
741741
}
742742

743743
fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self {
744+
// NOTE(unsafe) atomic read to a stateless register
744745
unsafe { &*IO_MUX::ptr() }
745746
.$iomux
746747
.modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) });

src/gpio/mux.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ pub enum InputSignal {
183183
PCMFSYNC = 204,
184184
PCMCLK = 205,
185185
PCMDIN = 206,
186-
SIGNAL_224 = 224,
187-
SIGNAL_225 = 225,
188-
SIGNAL_226 = 226,
189-
SIGNAL_227 = 227,
190-
SIGNAL_228 = 228,
186+
SIG_IN_FUNC224 = 224,
187+
SIG_IN_FUNC225 = 225,
188+
SIG_IN_FUNC226 = 226,
189+
SIG_IN_FUNC227 = 227,
190+
SIG_IN_FUNC228 = 228,
191191

192192
SD_DATA0 = 512,
193193
SD_DATA1,
@@ -443,11 +443,11 @@ pub enum OutputSignal {
443443
ANT_SEL5 = 221,
444444
ANT_SEL6 = 222,
445445
ANT_SEL7 = 223,
446-
SIG_IN_FUNC224 = 224,
447-
SIG_IN_FUNC225 = 225,
448-
SIG_IN_FUNC226 = 226,
449-
SIG_IN_FUNC227 = 227,
450-
SIG_IN_FUNC228 = 228,
446+
SIGNAL_224 = 224,
447+
SIGNAL_225 = 225,
448+
SIGNAL_226 = 226,
449+
SIGNAL_227 = 227,
450+
SIGNAL_228 = 228,
451451
GPIO = 256,
452452

453453
CLK_OUT1 = 512,

0 commit comments

Comments
 (0)