From d4e0d6142da973c6dad9422c462b691484775459 Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 10 Jan 2024 12:03:38 +0100 Subject: [PATCH] feat(firmware): implement FUSB302 reset --- firmware/Cargo.toml | 1 + firmware/src/fusb302.rs | 60 +++++++++++++++++++++++++++++++++++++++++ firmware/src/main.rs | 14 ++++++++-- 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 firmware/src/fusb302.rs diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index e1c5ff2..89500e6 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" [dependencies] ch32v00x-hal = { git = "https://github.com/lujoga/ch32v00x-hal.git", branch = "qingke-rt", features = ["ch32v003", "rt"] } +embedded-hal = "0.2.7" panic-halt = "0.2.0" qingke-rt = "0.1.7" diff --git a/firmware/src/fusb302.rs b/firmware/src/fusb302.rs new file mode 100644 index 0000000..76b81aa --- /dev/null +++ b/firmware/src/fusb302.rs @@ -0,0 +1,60 @@ +use embedded_hal::blocking::i2c::{Write, WriteRead}; + +#[derive(Debug)] +pub enum Error { + ReadError(RE), + WriteError(WE), +} + +pub trait ErrorType { + type Error; +} + +pub enum Variant { + B, + B01, + B10, + B11, +} + +impl Variant { + fn address(&self) -> u8 { + match self { + Variant::B => 0b0100_010, + Variant::B01 => 0b0100_011, + Variant::B10 => 0b0100_100, + Variant::B11 => 0b0100_101, + } + } +} + +pub struct Fusb302 { + i2c: I2C, + variant: Variant, +} + +impl ErrorType for Fusb302 +where + I2C: Write + WriteRead, +{ + type Error = Error<::Error, ::Error>; +} + +impl Fusb302 +where + I2C: Write + WriteRead, +{ + pub fn new(i2c: I2C, variant: Variant) -> Self { + Self { i2c, variant } + } + + pub fn release(self) -> I2C { + self.i2c + } + + pub fn reset(&mut self) -> Result<(), ::Error> { + self.i2c + .write(self.variant.address(), &[0x0c, 0b1]) + .map_err(|err| Error::WriteError(err)) + } +} diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 617a03f..bd5ce5a 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -1,8 +1,14 @@ #![no_std] #![no_main] +mod fusb302; + use ch32v00x_hal as hal; +use core::cell::Cell; + +use fusb302::{Fusb302, Variant}; + use hal::debug::SDIPrint; use hal::gpio::PinState; use hal::i2c::{I2c, I2cConfig}; @@ -25,14 +31,14 @@ fn main() -> ! { let mut _fan = gpioa.pa2.into_push_pull_output_in_state(PinState::High); let gpioc = p.GPIOC.split(&mut rcc); - let _i2c = I2c::i2c1( + let i2c = Cell::new(Some(I2c::i2c1( p.I2C1, gpioc.pc2.into_alternate_open_drain(), gpioc.pc1.into_alternate_open_drain(), I2cConfig::fast_mode(), &mut rcc, &clocks, - ); + ))); let mut _tec = gpioc.pc4.into_push_pull_output(); let gpiod = p.GPIOD.split(&mut rcc); @@ -44,5 +50,9 @@ fn main() -> ! { &clocks, ); + let mut fusb302 = Fusb302::new(i2c.replace(None).unwrap(), Variant::B); + fusb302.reset().unwrap(); + let _ = i2c.replace(Some(fusb302.release())); + loop {} }