forked from M-Labs/zynq-rs
i2c: implement EEPROM operations; add CountDown waiting indication
This commit is contained in:
parent
c60230af25
commit
f7d3135ec7
|
@ -0,0 +1,84 @@
|
||||||
|
use super::I2C;
|
||||||
|
use crate::time::Microseconds;
|
||||||
|
use embedded_hal::timer::CountDown;
|
||||||
|
|
||||||
|
pub struct EEPROM<'a> {
|
||||||
|
i2c: &'a mut I2C,
|
||||||
|
port: u8,
|
||||||
|
address: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EEPROM<'a> {
|
||||||
|
#[cfg(feature = "target_zc706")]
|
||||||
|
pub fn new(i2c: &'a mut I2C) -> Self {
|
||||||
|
EEPROM {
|
||||||
|
i2c: i2c,
|
||||||
|
port: 2,
|
||||||
|
address: 0b1010100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "target_zc706")]
|
||||||
|
fn select(&mut self) -> Result<(), &'static str> {
|
||||||
|
let mask: u16 = 1 << self.port;
|
||||||
|
self.i2c.pca9548_select(0b1110100, mask as u8)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Random read
|
||||||
|
pub fn read<'r>(&mut self, addr: u8, buf: &'r mut [u8]) -> Result<(), &'static str> {
|
||||||
|
self.select()?;
|
||||||
|
|
||||||
|
self.i2c.start()?;
|
||||||
|
self.i2c.write(self.address << 1)?;
|
||||||
|
self.i2c.write(addr)?;
|
||||||
|
|
||||||
|
self.i2c.restart()?;
|
||||||
|
self.i2c.write((self.address << 1) | 1)?;
|
||||||
|
let buf_len = buf.len();
|
||||||
|
for (i, byte) in buf.iter_mut().enumerate() {
|
||||||
|
*byte = self.i2c.read(i < buf_len - 1)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.i2c.stop()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Page write
|
||||||
|
pub fn write(&mut self, addr: u8, buf: &[u8]) -> Result<(), &'static str> {
|
||||||
|
self.select()?;
|
||||||
|
|
||||||
|
self.i2c.start()?;
|
||||||
|
self.i2c.write(self.address << 1)?;
|
||||||
|
self.i2c.write(addr)?;
|
||||||
|
for (i, byte) in buf.iter().enumerate() {
|
||||||
|
self.i2c.write(*byte)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.i2c.stop()?;
|
||||||
|
self.poll(1_000_000_000)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Poll
|
||||||
|
pub fn poll(&mut self, timeout_us: u64) -> Result<(), &'static str> {
|
||||||
|
self.select()?;
|
||||||
|
|
||||||
|
self.i2c.count_down.start(Microseconds(timeout_us));
|
||||||
|
while !self.i2c.write((self.address << 1) | 1)? {
|
||||||
|
if !self.i2c.count_down.waiting() {
|
||||||
|
return Err("I2C polling timeout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_eui48<'r>(&mut self) -> Result<[u8; 6], &'static str> {
|
||||||
|
let mut buffer = [0u8; 6];
|
||||||
|
self.read(0xFA, &mut buffer)?;
|
||||||
|
Ok(buffer)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
//! I2C Bit-banging Controller
|
//! I2C Bit-banging Controller
|
||||||
|
|
||||||
mod regs;
|
mod regs;
|
||||||
use log::{error, info, warn};
|
pub mod eeprom;
|
||||||
use crate::{print, println};
|
|
||||||
use super::clocks::Clocks;
|
use super::clocks::Clocks;
|
||||||
use super::slcr;
|
use super::slcr;
|
||||||
use super::time::Microseconds;
|
use super::time::Microseconds;
|
||||||
|
|
|
@ -138,6 +138,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<U: PartialOrd> CountDown<U>
|
||||||
|
where
|
||||||
|
GlobalTimer: TimeSource<U>,
|
||||||
|
{
|
||||||
|
pub fn waiting(&self) -> bool {
|
||||||
|
self.timer.now() <= self.timeout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// embedded-hal sync API
|
/// embedded-hal sync API
|
||||||
impl embedded_hal::blocking::delay::DelayMs<u64> for GlobalTimer {
|
impl embedded_hal::blocking::delay::DelayMs<u64> for GlobalTimer {
|
||||||
fn delay_ms(&mut self, ms: u64) {
|
fn delay_ms(&mut self, ms: u64) {
|
||||||
|
|
Loading…
Reference in New Issue