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

Update for embedded-hal 1.0 #1

Merged
merged 7 commits into from
Feb 24, 2024
Merged
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
13 changes: 7 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [stable, 1.31.0]
rust: [stable, 1.62.0]
TARGET:
- x86_64-unknown-linux-gnu
- x86_64-unknown-linux-musl
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [1.54.0]
rust: [1.63.0]
TARGET:
- x86_64-unknown-linux-gnu

Expand Down Expand Up @@ -139,10 +139,11 @@ jobs:
toolchain: stable
override: true

- name: Run cargo-tarpaulin
uses: actions-rs/[email protected]
with:
args: '--out Lcov -- --test-threads 1'
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Generate code coverage
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info

- name: upload to Coveralls
uses: coverallsapp/github-action@master
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

...
### Changed
- Update to embedded-hal 1.0 (Bumped MSRV to 1.62.0)

## [0.1.1] - 2021-09-10

Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ include = [
edition = "2018"

[dependencies]
embedded-hal = "0.2.6"
embedded-hal = "1.0.0"
nb = "1"

[dev-dependencies]
linux-embedded-hal = "0.3"
embedded-hal-mock = "0.8"
linux-embedded-hal = "0.4.0"
embedded-hal-mock = {version="0.10.0", default-features=false, features=["eh1"]}

[profile.release]
lto = true
111 changes: 64 additions & 47 deletions src/device_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
InterruptPinPolarity, LuxRange, Measurement, ModeChangeError, Opt300x, PhantomData, SlaveAddr,
Status,
};
use embedded_hal::blocking::i2c;
use embedded_hal::i2c;

struct Register;
impl Register {
Expand Down Expand Up @@ -85,17 +85,17 @@ impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE> {
}
}

impl<I2C, E, IC> Opt300x<I2C, IC, mode::OneShot>
impl<I2C, IC> Opt300x<I2C, IC, mode::OneShot>
where
I2C: i2c::Write<Error = E>,
I2C: i2c::I2c,
{
/// Change into continuous measurement mode
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn into_continuous(
mut self,
) -> Result<Opt300x<I2C, IC, mode::Continuous>, ModeChangeError<E, Self>> {
) -> Result<Opt300x<I2C, IC, mode::Continuous>, ModeChangeError<I2C::Error, Self>> {
if let Err(Error::I2C(e)) = self.set_config(
self.config
.with_high(BitFlags::MODE0)
Expand All @@ -115,16 +115,16 @@ where
}
}

impl<I2C, E, IC> Opt300x<I2C, IC, mode::Continuous>
impl<I2C, IC> Opt300x<I2C, IC, mode::Continuous>
where
I2C: i2c::Write<Error = E>,
I2C: i2c::I2c,
{
/// Change into one-shot mode
///
/// This will actually shut down the device until a measurement is requested.
pub fn into_one_shot(
mut self,
) -> Result<Opt300x<I2C, IC, mode::OneShot>, ModeChangeError<E, Self>> {
) -> Result<Opt300x<I2C, IC, mode::OneShot>, ModeChangeError<I2C::Error, Self>> {
if let Err(Error::I2C(e)) = self.set_config(
self.config
.with_low(BitFlags::MODE0)
Expand All @@ -144,19 +144,19 @@ where
}
}

impl<I2C, E, IC> Opt300x<I2C, IC, mode::Continuous>
impl<I2C, IC> Opt300x<I2C, IC, mode::Continuous>
where
I2C: i2c::WriteRead<Error = E>,
I2C: i2c::I2c,
{
/// Read the result of the most recent light to digital conversion in lux
pub fn read_lux(&mut self) -> Result<f32, Error<E>> {
pub fn read_lux(&mut self) -> Result<f32, Error<I2C::Error>> {
let result = self.read_raw()?;
Ok(raw_to_lux(result))
}

/// Read the result of the most recent light to digital conversion in
/// raw format: (exponent, mantissa)
pub fn read_raw(&mut self) -> Result<(u8, u16), Error<E>> {
pub fn read_raw(&mut self) -> Result<(u8, u16), Error<I2C::Error>> {
let result = self.read_register(Register::RESULT)?;
Ok(((result >> 12) as u8, result & 0xFFF))
}
Expand All @@ -166,12 +166,12 @@ fn raw_to_lux(result: (u8, u16)) -> f32 {
(f64::from(1 << result.0) * 0.01 * f64::from(result.1)) as f32
}

impl<I2C, E, IC> Opt300x<I2C, IC, mode::OneShot>
impl<I2C, IC> Opt300x<I2C, IC, mode::OneShot>
where
I2C: i2c::WriteRead<Error = E> + i2c::Write<Error = E>,
I2C: i2c::I2c,
{
/// Read the result of the most recent light to digital conversion in lux
pub fn read_lux(&mut self) -> nb::Result<Measurement<f32>, Error<E>> {
pub fn read_lux(&mut self) -> nb::Result<Measurement<f32>, Error<I2C::Error>> {
let measurement = self.read_raw()?;
Ok(Measurement {
result: raw_to_lux(measurement.result),
Expand All @@ -181,7 +181,7 @@ where

/// Read the result of the most recent light to digital conversion in
/// raw format: (exponent, mantissa)
pub fn read_raw(&mut self) -> nb::Result<Measurement<(u8, u16)>, Error<E>> {
pub fn read_raw(&mut self) -> nb::Result<Measurement<(u8, u16)>, Error<I2C::Error>> {
if self.was_conversion_started {
let status = self.read_status().map_err(nb::Error::Other)?;
if status.conversion_ready {
Expand All @@ -206,15 +206,15 @@ where
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::WriteRead<Error = E>,
I2C: i2c::I2c,
{
/// Read the status of the conversion.
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn read_status(&mut self) -> Result<Status, Error<E>> {
pub fn read_status(&mut self) -> Result<Status, Error<I2C::Error>> {
let config = self.read_register(Register::CONFIG)?;
Ok(Status {
has_overflown: (config & BitFlags::OVF) != 0,
Expand All @@ -225,15 +225,15 @@ where
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::Write<Error = E>,
I2C: i2c::I2c,
{
/// Set the fault count
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn set_fault_count(&mut self, count: FaultCount) -> Result<(), Error<E>> {
pub fn set_fault_count(&mut self, count: FaultCount) -> Result<(), Error<I2C::Error>> {
let config = self.config.bits & !0b11;
let config = match count {
FaultCount::One => config,
Expand All @@ -251,7 +251,7 @@ where
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn set_lux_range(&mut self, range: LuxRange) -> Result<(), Error<E>> {
pub fn set_lux_range(&mut self, range: LuxRange) -> Result<(), Error<I2C::Error>> {
let value = match range {
LuxRange::Auto => Ok(0b1100),
LuxRange::Manual(rn) if rn >= 0b1100 => Err(Error::InvalidInputData),
Expand All @@ -267,7 +267,7 @@ where
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn set_integration_time(&mut self, time: IntegrationTime) -> Result<(), Error<E>> {
pub fn set_integration_time(&mut self, time: IntegrationTime) -> Result<(), Error<I2C::Error>> {
let config = match time {
IntegrationTime::Ms100 => self.config.with_low(BitFlags::CT),
IntegrationTime::Ms800 => self.config.with_high(BitFlags::CT),
Expand All @@ -282,7 +282,7 @@ where
pub fn set_interrupt_pin_polarity(
&mut self,
polarity: InterruptPinPolarity,
) -> Result<(), Error<E>> {
) -> Result<(), Error<I2C::Error>> {
let config = match polarity {
InterruptPinPolarity::Low => self.config.with_low(BitFlags::POL),
InterruptPinPolarity::High => self.config.with_high(BitFlags::POL),
Expand All @@ -294,23 +294,23 @@ where
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn enable_exponent_masking(&mut self) -> Result<(), Error<E>> {
pub fn enable_exponent_masking(&mut self) -> Result<(), Error<I2C::Error>> {
self.set_config(self.config.with_high(BitFlags::ME))
}

/// Disable exponent masking (default).
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn disable_exponent_masking(&mut self) -> Result<(), Error<E>> {
pub fn disable_exponent_masking(&mut self) -> Result<(), Error<I2C::Error>> {
self.set_config(self.config.with_low(BitFlags::ME))
}

/// Set result comparison mode for interrupt reporting
///
/// Note that the conversion ready flag is cleared automatically
/// after calling this method.
pub fn set_comparison_mode(&mut self, mode: ComparisonMode) -> Result<(), Error<E>> {
pub fn set_comparison_mode(&mut self, mode: ComparisonMode) -> Result<(), Error<I2C::Error>> {
let config = match mode {
ComparisonMode::LatchedWindow => self.config.with_high(BitFlags::L),
ComparisonMode::TransparentHysteresis => self.config.with_low(BitFlags::L),
Expand All @@ -324,7 +324,11 @@ where
/// 11 or a mantissa value greater than 4095.
///
/// Note that this disables the end-of-conversion mode.
pub fn set_low_limit_raw(&mut self, exponent: u8, mantissa: u16) -> Result<(), Error<E>> {
pub fn set_low_limit_raw(
&mut self,
exponent: u8,
mantissa: u16,
) -> Result<(), Error<I2C::Error>> {
if exponent > 0b1011 || mantissa > 0xFFF {
return Err(Error::InvalidInputData);
}
Expand All @@ -338,7 +342,11 @@ where
///
/// Returns `Error::InvalidInputData` for an exponent value greater than
/// 11 or a mantissa value greater than 4095.
pub fn set_high_limit_raw(&mut self, exponent: u8, mantissa: u16) -> Result<(), Error<E>> {
pub fn set_high_limit_raw(
&mut self,
exponent: u8,
mantissa: u16,
) -> Result<(), Error<I2C::Error>> {
if exponent > 0b1011 || mantissa > 0xFFF {
return Err(Error::InvalidInputData);
}
Expand All @@ -350,7 +358,7 @@ where
///
/// Note that this changes the two highest bits of the lux low limit exponent.
/// Please see the device datasheet for further details.
pub fn enable_end_of_conversion_mode(&mut self) -> Result<(), Error<E>> {
pub fn enable_end_of_conversion_mode(&mut self) -> Result<(), Error<I2C::Error>> {
let limit = self.low_limit | 0b1100 << 12;
self.write_register(Register::LOW_LIMIT, limit)
}
Expand All @@ -360,28 +368,28 @@ where
/// Note that this restores the two highest bits of the lux low limit
/// exponent to the last value set before enabling the end-of-conversion
/// mode (0b00 by default).
pub fn disable_end_of_conversion_mode(&mut self) -> Result<(), Error<E>> {
pub fn disable_end_of_conversion_mode(&mut self) -> Result<(), Error<I2C::Error>> {
self.write_register(Register::LOW_LIMIT, self.low_limit)
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::WriteRead<Error = E>,
I2C: i2c::I2c,
{
/// Read the manifacturer ID
pub fn get_manufacturer_id(&mut self) -> Result<u16, Error<E>> {
pub fn get_manufacturer_id(&mut self) -> Result<u16, Error<I2C::Error>> {
self.read_register(Register::MANUFACTURER_ID)
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::WriteRead<Error = E>,
I2C: i2c::I2c,
IC: marker::WithDeviceId,
{
/// Read the device ID
pub fn get_device_id(&mut self) -> Result<u16, Error<E>> {
pub fn get_device_id(&mut self) -> Result<u16, Error<I2C::Error>> {
self.read_register(Register::DEVICE_ID)
}
}
Expand All @@ -405,11 +413,11 @@ impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE> {
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::WriteRead<Error = E>,
I2C: i2c::I2c,
{
fn read_register(&mut self, register: u8) -> Result<u16, Error<E>> {
fn read_register(&mut self, register: u8) -> Result<u16, Error<I2C::Error>> {
let mut data = [0, 0];
self.i2c
.write_read(self.address, &[register], &mut data)
Expand All @@ -418,30 +426,39 @@ where
}
}

impl<I2C, E, IC, MODE> Opt300x<I2C, IC, MODE>
impl<I2C, IC, MODE> Opt300x<I2C, IC, MODE>
where
I2C: i2c::Write<Error = E>,
I2C: i2c::I2c,
{
fn set_config(&mut self, config: Config) -> Result<(), Error<E>> {
fn set_config(&mut self, config: Config) -> Result<(), Error<I2C::Error>> {
self.write_register(Register::CONFIG, config.bits)?;
self.config = config;
Ok(())
}

fn write_register(&mut self, register: u8, value: u16) -> Result<(), Error<E>> {
fn write_register(&mut self, register: u8, value: u16) -> Result<(), Error<I2C::Error>> {
let data = [register, (value >> 8) as u8, value as u8];
self.i2c.write(self.address, &data).map_err(Error::I2C)
}
}

#[cfg(test)]
mod tests {
use core::convert::Infallible;

use super::*;

impl embedded_hal::i2c::ErrorType for I2cMock {
type Error = Infallible;
}

struct I2cMock;
impl i2c::Write for I2cMock {
type Error = ();
fn write(&mut self, _addr: u8, _bytes: &[u8]) -> Result<(), Self::Error> {
impl i2c::I2c for I2cMock {
fn transaction(
&mut self,
_address: u8,
_operations: &mut [i2c::Operation<'_>],
) -> Result<(), Self::Error> {
Ok(())
}
}
Expand Down
Loading
Loading