use embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::mutex::Mutex;
use embassy_sync::once_lock::OnceLock;
use esp_hal::Async;
use esp_hal::i2c::master::{Config, I2c};
use esp_hal::peripherals::{GPIO8, GPIO9, I2C0};
use esp_hal::time::Rate;
pub type SysI2cBus = Mutex<CriticalSectionRawMutex, I2c<'static, Async>>;
pub type SysI2cDevice = I2cDevice<'static, CriticalSectionRawMutex, I2c<'static, Async>>;
pub const FREQUENCY: Rate = Rate::from_khz(400);
#[allow(missing_docs)]
pub struct SysI2cResources<'d> {
pub i2c: I2C0<'d>,
pub sda: GPIO8<'d>,
pub scl: GPIO9<'d>,
}
reborrow_group!(SysI2cResources { i2c, sda, scl });
struct SharedBus(SysI2cBus);
unsafe impl Sync for SharedBus {}
static BUS: OnceLock<SharedBus> = OnceLock::new();
impl SysI2cResources<'static> {
pub fn into_bus(self) -> &'static SysI2cBus {
let i2c = I2c::new(self.i2c, Config::default().with_frequency(FREQUENCY))
.expect("400 kHz is a valid I2C configuration")
.with_sda(self.sda)
.with_scl(self.scl)
.into_async();
if BUS.init(SharedBus(Mutex::new(i2c))).is_err() {
panic!("the system I2C bus was already created");
}
bus().expect("just initialised")
}
}
pub fn bus() -> Option<&'static SysI2cBus> {
BUS.try_get().map(|b| &b.0)
}
pub fn device(bus: &'static SysI2cBus) -> SysI2cDevice {
I2cDevice::new(bus)
}