Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add crude MAX5970 bounce detection #1564

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/gimlet/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ notifications = ["timer"]
name = "task-power"
features = ["gimlet"]
priority = 6
max-sizes = {flash = 32768, ram = 8192 }
stacksize = 1504
max-sizes = {flash = 65536, ram = 8192 }
stacksize = 2504
start = true
task-slots = ["i2c_driver", "sensor", "gimlet_seq"]
notifications = ["timer"]
Expand Down
63 changes: 55 additions & 8 deletions drv/i2c-devices/src/max5970.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ impl Max5970 {
self.device.read_reg::<u8, u8>(reg as u8)
}

fn write_reg(&self, reg: Register, value: u8) -> Result<(), ResponseCode> {
self.device.write(&[reg as u8, value])
}

pub fn i2c_device(&self) -> &I2cDevice {
&self.device
}
Expand Down Expand Up @@ -327,37 +331,80 @@ impl Max5970 {
Ok(Amperes(delta / self.rsense as f32))
}

fn peak_vout(
&self,
msb_reg: Register,
lsb_reg: Register,
) -> Result<Volts, ResponseCode> {
Ok(self.convert_volts(
MonRange(self.read_reg(Register::mon_range)?),
self.read_reg(msb_reg)?,
self.read_reg(lsb_reg)?,
))
}

pub fn max_vout(&self) -> Result<Volts, ResponseCode> {
let (msb_reg, lsb_reg) = if self.rail == 0 {
(Register::max_chx_mon_msb_ch1, Register::max_chx_mon_lsb_ch1)
} else {
(Register::max_chx_mon_msb_ch2, Register::max_chx_mon_lsb_ch2)
};

Ok(self.convert_volts(
MonRange(self.read_reg(Register::mon_range)?),
self.read_reg(msb_reg)?,
self.read_reg(lsb_reg)?,
))
self.peak_vout(msb_reg, lsb_reg)
}

pub fn max_iout(&self) -> Result<Amperes, ResponseCode> {
pub fn min_vout(&self) -> Result<Volts, ResponseCode> {
let (msb_reg, lsb_reg) = if self.rail == 0 {
(Register::max_chx_cs_msb_ch1, Register::max_chx_cs_lsb_ch1)
(Register::min_chx_mon_msb_ch1, Register::min_chx_mon_lsb_ch1)
} else {
(Register::max_chx_cs_msb_ch2, Register::max_chx_cs_lsb_ch2)
(Register::min_chx_mon_msb_ch2, Register::min_chx_mon_lsb_ch2)
};

self.peak_vout(msb_reg, lsb_reg)
}

fn peak_iout(
&self,
msb_reg: Register,
lsb_reg: Register,
) -> Result<Amperes, ResponseCode> {
self.convert_current(
Status2(self.read_reg(Register::status2)?),
self.read_reg(msb_reg)?,
self.read_reg(lsb_reg)?,
)
}

pub fn max_iout(&self) -> Result<Amperes, ResponseCode> {
let (msb_reg, lsb_reg) = if self.rail == 0 {
(Register::max_chx_cs_msb_ch1, Register::max_chx_cs_lsb_ch1)
} else {
(Register::max_chx_cs_msb_ch2, Register::max_chx_cs_lsb_ch2)
};

self.peak_iout(msb_reg, lsb_reg)
}

pub fn min_iout(&self) -> Result<Amperes, ResponseCode> {
let (msb_reg, lsb_reg) = if self.rail == 0 {
(Register::min_chx_cs_msb_ch1, Register::min_chx_cs_lsb_ch1)
} else {
(Register::min_chx_cs_msb_ch2, Register::min_chx_cs_lsb_ch2)
};

self.peak_iout(msb_reg, lsb_reg)
}

pub fn status0(&self) -> Result<u8, ResponseCode> {
self.read_reg(Register::status0)
}

pub fn clear_peaks(&self) -> Result<(), ResponseCode> {
let rst = if self.rail == 0 { 0b00_11 } else { 0b11_00 };

self.write_reg(Register::peak_log_rst, rst)?;
self.write_reg(Register::peak_log_rst, 0)
}
}

impl Validate<ResponseCode> for Max5970 {
Expand Down
2 changes: 2 additions & 0 deletions drv/i2c-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub enum ResponseCode {
OperationNotSupported,
/// Illegal number of leases
IllegalLeaseCount,
/// Too much data -- or not enough buffer
TooMuchData,
}

///
Expand Down
24 changes: 22 additions & 2 deletions drv/stm32xx-i2c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ enum Trace {
KonamiISR(u32),
Konami(I2cKonamiCode),
ResetISR(u32),
ResetCR2(u32),
AddrISR(u32),
AddrMatch,
AddrNack(u8),
Expand Down Expand Up @@ -434,6 +435,8 @@ impl I2cController<'_> {

// And then finally set it
i2c.cr1.modify(|_, w| w.pe().set_bit());

ringbuf_entry!(Trace::ResetCR2(i2c.cr2.read().bits()));
}

///
Expand Down Expand Up @@ -555,6 +558,7 @@ impl I2cController<'_> {
i2c.cr2.modify(|_, w| { w
.nbytes().bits(wlen as u8)
.autoend().clear_bit()
.reload().clear_bit()
.add10().clear_bit()
.sadd().bits((addr << 1).into())
.rd_wrn().clear_bit()
Expand Down Expand Up @@ -614,6 +618,8 @@ impl I2cController<'_> {
}
}

let mut overrun = false;

if rlen != ReadLength::Fixed(0) {
//
// If we have both a write and a read, we deliberately do not send
Expand All @@ -626,6 +632,7 @@ impl I2cController<'_> {
i2c.cr2.modify(|_, w| { w
.nbytes().bits(rlen as u8)
.autoend().clear_bit()
.reload().clear_bit()
.add10().clear_bit()
.sadd().bits((addr << 1).into())
.rd_wrn().set_bit()
Expand Down Expand Up @@ -686,7 +693,15 @@ impl I2cController<'_> {
continue;
}

putbyte(pos, byte).ok_or(drv_i2c_api::ResponseCode::BadArg)?;
if !overrun && putbyte(pos, byte).is_none() {
//
// If we're unable to accept what we just read, we need to
// keep reading to complete the transfer -- but we will
// not call putbyte again and we will return failure.
//
overrun = true;
}

pos += 1;
}

Expand All @@ -712,7 +727,11 @@ impl I2cController<'_> {
//
i2c.cr2.modify(|_, w| w.stop().set_bit());

Ok(())
if overrun {
Err(drv_i2c_api::ResponseCode::TooMuchData)
} else {
Ok(())
}
}

///
Expand Down Expand Up @@ -751,6 +770,7 @@ impl I2cController<'_> {
i2c.cr2.modify(|_, w| { w
.nbytes().bits(0u8)
.autoend().clear_bit()
.reload().clear_bit()
.add10().clear_bit()
.sadd().bits((addr << 1).into())
.rd_wrn().bit(opval)
Expand Down
10 changes: 9 additions & 1 deletion idl/power.idol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Interface(
err: CLike("ResponseCode"),
),
idempotent: true,
),
),
"bmr491_event_log_read": (
doc: "reads an event from the BMR491's combined fault and lifecycle event log",
args: {
Expand All @@ -58,6 +58,14 @@ Interface(
),
idempotent: true,
),
"bmr491_fault_log_clear": (
doc: "clears the BMR491's persistent fault log",
reply: Result(
ok: "()",
err: CLike("ResponseCode"),
),
idempotent: true,
),
"bmr491_max_fault_event_index": (
doc: "returns the index of the most recent fault event in the BMR491's event log",
reply: Result(
Expand Down
4 changes: 3 additions & 1 deletion task/power-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ pub enum Operation {
MfrMaxTemp3,
}

pub const MAX_BLOCK_LEN: usize = 17;
// This is a bit of an arbitrary number, but is set to the maximum read block
// size that we expect given the devices that we interact with.
pub const MAX_BLOCK_LEN: usize = 32;

// We use a `u8` for the actual block length; ensure `MAX_BLOCK_LEN` fits.
static_assertions::const_assert!(MAX_BLOCK_LEN <= u8::MAX as usize);
Expand Down
Loading
Loading