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

Commit

Permalink
Merge pull request #55 from hanhossain/feat_i2c
Browse files Browse the repository at this point in the history
Blocking I2C
  • Loading branch information
MabezDev authored Apr 17, 2021
2 parents e8dd426 + 6ac5caf commit 94dc49f
Show file tree
Hide file tree
Showing 6 changed files with 805 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ void = { version = "1.0.2", default-features = false }
[dev-dependencies]
panic-halt = "0.2.0"
ili9341 = { version = "0.3.0", features = ["graphics"] }
ssd1306 = "0.3.1"
embedded-graphics = "0.6.2"
mpu6050 = "0.1.3"

[[example]]
name = "alloc"
Expand Down
150 changes: 150 additions & 0 deletions examples/i2c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#![no_std]
#![no_main]

use core::panic::PanicInfo;
use embedded_graphics::{
fonts::{Font8x16, Text},
pixelcolor::BinaryColor,
prelude::*,
style::TextStyle,
};
use embedded_hal::blocking::i2c::{Write, WriteRead};
use esp32_hal::{
clock_control::{self, sleep, CPUSource, ClockControl},
delay::Delay,
dport::Split,
dprintln,
i2c::{self, Error, I2C},
prelude::*,
target::{I2C0, Peripherals},
timer::Timer,
};
use mpu6050::Mpu6050;
use ssd1306::{prelude::*, Builder};
use xtensa_lx::mutex::SpinLockMutex;

#[entry]
fn main() -> ! {
let dp = Peripherals::take().unwrap();

let (mut dport, dport_clock_control) = dp.DPORT.split();

// setup clocks & watchdog
let mut clkcntrl = ClockControl::new(
dp.RTCCNTL,
dp.APB_CTRL,
dport_clock_control,
clock_control::XTAL_FREQUENCY_AUTO,
)
.unwrap();

// set desired clock frequencies
clkcntrl
.set_cpu_frequencies(
CPUSource::PLL,
80.MHz(),
CPUSource::PLL,
240.MHz(),
CPUSource::PLL,
80.MHz(),
)
.unwrap();

// disable RTC watchdog
let (clkcntrl_config, mut watchdog) = clkcntrl.freeze().unwrap();
watchdog.disable();

// disable MST watchdogs
let (.., mut watchdog0) = Timer::new(dp.TIMG0, clkcntrl_config);
let (.., mut watchdog1) = Timer::new(dp.TIMG1, clkcntrl_config);
watchdog0.disable();
watchdog1.disable();

let pins = dp.GPIO.split();
let i2c0 = i2c::I2C::new(
dp.I2C0,
i2c::Pins {
sda: pins.gpio4,
scl: pins.gpio15,
},
400_000,
&mut dport,
);
let i2c0 = SpinLockMutex::new(i2c0);

// Display
let mut display = {
let i2c_wrapper = I2CWrapper::new(&i2c0);
let mut display: GraphicsMode<_> = Builder::new().connect_i2c(i2c_wrapper).into();

let mut rst = pins.gpio16.into_push_pull_output();
rst.set_low().unwrap();
sleep(10.ms());
rst.set_high().unwrap();

display.init().unwrap();
display.clear();
display.flush().unwrap();

display
};

// IMU
let mut imu = {
let i2c_wrapper = I2CWrapper::new(&i2c0);
let mut imu = Mpu6050::new(i2c_wrapper);

let mut delay = Delay::new();
imu.init(&mut delay).unwrap();
imu
};

Text::new("Hello world!", Point::new(2, 28))
.into_styled(TextStyle::new(Font8x16, BinaryColor::On))
.draw(&mut display)
.unwrap();
display.flush().unwrap();

sleep(3.s());

loop {
let temp = imu.get_temp().unwrap();
let gyro = imu.get_gyro().unwrap();
let acc = imu.get_acc().unwrap();
dprintln!("temp: {}, gyro: {:?}, acc: {:?}", temp, gyro, acc);
sleep(1.s());
}
}

struct I2CWrapper<'a> {
i2c: &'a SpinLockMutex<I2C<I2C0>>,
}

impl<'a> I2CWrapper<'a> {
fn new(i2c: &'a SpinLockMutex<I2C<I2C0>>) -> Self {
Self { i2c }
}
}

impl<'a> Write for I2CWrapper<'a> {
type Error = Error;

fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.i2c.lock(|x| x.write(addr, bytes))
}
}

impl<'a> WriteRead for I2CWrapper<'a> {
type Error = Error;

fn write_read(&mut self, address: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
self.i2c.lock(|x| x.write_read(address, bytes, buffer))
}
}

#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
dprintln!("----- PANIC -----");
dprintln!("{:?}", info);
loop {}
}
1 change: 1 addition & 0 deletions src/gpio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ macro_rules! impl_input {
}

fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self {
// NOTE(unsafe) atomic read to a stateless register
unsafe { &*IO_MUX::ptr() }
.$iomux
.modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) });
Expand Down
20 changes: 10 additions & 10 deletions src/gpio/mux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ pub enum InputSignal {
PCMFSYNC = 204,
PCMCLK = 205,
PCMDIN = 206,
SIGNAL_224 = 224,
SIGNAL_225 = 225,
SIGNAL_226 = 226,
SIGNAL_227 = 227,
SIGNAL_228 = 228,
SIG_IN_FUNC224 = 224,
SIG_IN_FUNC225 = 225,
SIG_IN_FUNC226 = 226,
SIG_IN_FUNC227 = 227,
SIG_IN_FUNC228 = 228,

SD_DATA0 = 512,
SD_DATA1,
Expand Down Expand Up @@ -443,11 +443,11 @@ pub enum OutputSignal {
ANT_SEL5 = 221,
ANT_SEL6 = 222,
ANT_SEL7 = 223,
SIG_IN_FUNC224 = 224,
SIG_IN_FUNC225 = 225,
SIG_IN_FUNC226 = 226,
SIG_IN_FUNC227 = 227,
SIG_IN_FUNC228 = 228,
SIGNAL_224 = 224,
SIGNAL_225 = 225,
SIGNAL_226 = 226,
SIGNAL_227 = 227,
SIGNAL_228 = 228,
GPIO = 256,

CLK_OUT1 = 512,
Expand Down
Loading

0 comments on commit 94dc49f

Please sign in to comment.