From 1c7312d470fa18556900672a32d31d8bf2b1606e Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 22:27:45 +0200 Subject: [PATCH 01/12] Extract i2c into separate module --- src/i2c.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 110 ++----------------------------------------------- 2 files changed, 120 insertions(+), 107 deletions(-) create mode 100644 src/i2c.rs diff --git a/src/i2c.rs b/src/i2c.rs new file mode 100644 index 0000000..27c9ca4 --- /dev/null +++ b/src/i2c.rs @@ -0,0 +1,117 @@ +//! `embedded-hal` I2C traits implementation + +use std::ops; +use std::path::{Path, PathBuf}; + +/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits +/// +/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html +pub struct I2cdev { + inner: i2cdev::linux::LinuxI2CDevice, + path: PathBuf, + address: Option, +} + +impl I2cdev { + /// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details. + /// + /// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new + pub fn new

(path: P) -> Result + where + P: AsRef, + { + let dev = I2cdev { + path: path.as_ref().to_path_buf(), + inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?, + address: None, + }; + Ok(dev) + } + + fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> { + if self.address != Some(address) { + self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?; + self.address = Some(address); + } + Ok(()) + } +} + +impl ops::Deref for I2cdev { + type Target = i2cdev::linux::LinuxI2CDevice; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl ops::DerefMut for I2cdev { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +mod embedded_hal_impl { + use super::*; + use embedded_hal::blocking::i2c::{ + Operation as I2cOperation, Read, Transactional, Write, WriteRead, + }; + use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer}; + use i2cdev::linux::LinuxI2CMessage; + + impl Read for I2cdev { + type Error = i2cdev::linux::LinuxI2CError; + + fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.set_address(address)?; + self.inner.read(buffer) + } + } + + impl Write for I2cdev { + type Error = i2cdev::linux::LinuxI2CError; + + fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.set_address(address)?; + self.inner.write(bytes) + } + } + + impl WriteRead for I2cdev { + type Error = i2cdev::linux::LinuxI2CError; + + fn try_write_read( + &mut self, + address: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Self::Error> { + self.set_address(address)?; + let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)]; + self.inner.transfer(&mut messages).map(drop) + } + } + + impl Transactional for I2cdev { + type Error = i2cdev::linux::LinuxI2CError; + + fn try_exec( + &mut self, + address: u8, + operations: &mut [I2cOperation], + ) -> Result<(), Self::Error> { + // Map operations from generic to linux objects + let mut messages: Vec<_> = operations + .as_mut() + .iter_mut() + .map(|a| match a { + I2cOperation::Write(w) => LinuxI2CMessage::write(w), + I2cOperation::Read(r) => LinuxI2CMessage::read(r), + }) + .collect(); + + self.set_address(address)?; + self.inner.transfer(&mut messages).map(drop) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index f03c925..bc76f3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,14 +27,11 @@ pub use gpio_cdev; use core::convert::Infallible; use std::io::{self, Write}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::time::Duration; use std::{ops, thread}; use cast::{u32, u64}; -use embedded_hal::blocking::i2c::Operation as I2cOperation; -use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer}; -use i2cdev::linux::LinuxI2CMessage; use spidev::SpidevTransfer; mod serial; @@ -139,109 +136,8 @@ impl embedded_hal::blocking::delay::DelayMs for Delay { } } -/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits -/// -/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html -pub struct I2cdev { - inner: i2cdev::linux::LinuxI2CDevice, - path: PathBuf, - address: Option, -} - -impl I2cdev { - /// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details. - /// - /// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new - pub fn new

(path: P) -> Result - where - P: AsRef, - { - let dev = I2cdev { - path: path.as_ref().to_path_buf(), - inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?, - address: None, - }; - Ok(dev) - } - - fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> { - if self.address != Some(address) { - self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?; - self.address = Some(address); - } - Ok(()) - } -} - -impl embedded_hal::blocking::i2c::Read for I2cdev { - type Error = i2cdev::linux::LinuxI2CError; - - fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.set_address(address)?; - self.inner.read(buffer) - } -} - -impl embedded_hal::blocking::i2c::Write for I2cdev { - type Error = i2cdev::linux::LinuxI2CError; - - fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { - self.set_address(address)?; - self.inner.write(bytes) - } -} - -impl embedded_hal::blocking::i2c::WriteRead for I2cdev { - type Error = i2cdev::linux::LinuxI2CError; - - fn try_write_read( - &mut self, - address: u8, - bytes: &[u8], - buffer: &mut [u8], - ) -> Result<(), Self::Error> { - self.set_address(address)?; - let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)]; - self.inner.transfer(&mut messages).map(drop) - } -} - -impl embedded_hal::blocking::i2c::Transactional for I2cdev { - type Error = i2cdev::linux::LinuxI2CError; - - fn try_exec( - &mut self, - address: u8, - operations: &mut [I2cOperation], - ) -> Result<(), Self::Error> { - // Map operations from generic to linux objects - let mut messages: Vec<_> = operations - .as_mut() - .iter_mut() - .map(|a| match a { - I2cOperation::Write(w) => LinuxI2CMessage::write(w), - I2cOperation::Read(r) => LinuxI2CMessage::read(r), - }) - .collect(); - - self.set_address(address)?; - self.inner.transfer(&mut messages).map(drop) - } -} - -impl ops::Deref for I2cdev { - type Target = i2cdev::linux::LinuxI2CDevice; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl ops::DerefMut for I2cdev { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} +mod i2c; +pub use crate::i2c::I2cdev; /// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits /// From 96c712ee1e4c67af359fa607b6c150f78bce3ab5 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 22:37:45 +0200 Subject: [PATCH 02/12] Extract delay into separate module --- src/delay.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 88 ++------------------------------------------------ 2 files changed, 93 insertions(+), 85 deletions(-) create mode 100644 src/delay.rs diff --git a/src/delay.rs b/src/delay.rs new file mode 100644 index 0000000..741bd08 --- /dev/null +++ b/src/delay.rs @@ -0,0 +1,90 @@ +//! Implementation of [`embedded-hal`] delay traits +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal + +use cast::{u32, u64}; +use core::convert::Infallible; +use embedded_hal::blocking::delay::{DelayMs, DelayUs}; +use std::thread; +use std::time::Duration; + +/// Empty struct that provides delay functionality on top of `thread::sleep` +pub struct Delay; + +impl DelayUs for Delay { + type Error = Infallible; + + fn try_delay_us(&mut self, n: u8) -> Result<(), Self::Error> { + thread::sleep(Duration::new(0, u32(n) * 1000)); + Ok(()) + } +} + +impl DelayUs for Delay { + type Error = Infallible; + + fn try_delay_us(&mut self, n: u16) -> Result<(), Self::Error> { + thread::sleep(Duration::new(0, u32(n) * 1000)); + Ok(()) + } +} + +impl DelayUs for Delay { + type Error = Infallible; + + fn try_delay_us(&mut self, n: u32) -> Result<(), Self::Error> { + let secs = n / 1_000_000; + let nsecs = (n % 1_000_000) * 1_000; + + thread::sleep(Duration::new(u64(secs), nsecs)); + Ok(()) + } +} + +impl DelayUs for Delay { + type Error = Infallible; + + fn try_delay_us(&mut self, n: u64) -> Result<(), Self::Error> { + let secs = n / 1_000_000; + let nsecs = ((n % 1_000_000) * 1_000) as u32; + + thread::sleep(Duration::new(secs, nsecs)); + Ok(()) + } +} + +impl DelayMs for Delay { + type Error = Infallible; + + fn try_delay_ms(&mut self, n: u8) -> Result<(), Self::Error> { + thread::sleep(Duration::from_millis(u64(n))); + Ok(()) + } +} + +impl DelayMs for Delay { + type Error = Infallible; + + fn try_delay_ms(&mut self, n: u16) -> Result<(), Self::Error> { + thread::sleep(Duration::from_millis(u64(n))); + Ok(()) + } +} + +impl DelayMs for Delay { + type Error = Infallible; + + fn try_delay_ms(&mut self, n: u32) -> Result<(), Self::Error> { + thread::sleep(Duration::from_millis(u64(n))); + Ok(()) + } +} + +impl DelayMs for Delay { + type Error = Infallible; + + fn try_delay_ms(&mut self, n: u64) -> Result<(), Self::Error> { + thread::sleep(Duration::from_millis(n)); + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index bc76f3a..0a0ace2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,6 @@ #![deny(missing_docs)] -use cast; pub use i2cdev; pub use nb; pub use serial_core; @@ -25,13 +24,10 @@ pub use sysfs_gpio; #[cfg(feature = "gpio_cdev")] pub use gpio_cdev; -use core::convert::Infallible; use std::io::{self, Write}; +use std::ops; use std::path::Path; -use std::time::Duration; -use std::{ops, thread}; -use cast::{u32, u64}; use spidev::SpidevTransfer; mod serial; @@ -55,86 +51,8 @@ pub use cdev_pin::CdevPin; /// Sysfs pin re-export pub use sysfs_pin::SysfsPin; -/// Empty struct that provides delay functionality on top of `thread::sleep` -pub struct Delay; - -impl embedded_hal::blocking::delay::DelayUs for Delay { - type Error = Infallible; - - fn try_delay_us(&mut self, n: u8) -> Result<(), Self::Error> { - thread::sleep(Duration::new(0, u32(n) * 1000)); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayUs for Delay { - type Error = Infallible; - - fn try_delay_us(&mut self, n: u16) -> Result<(), Self::Error> { - thread::sleep(Duration::new(0, u32(n) * 1000)); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayUs for Delay { - type Error = Infallible; - - fn try_delay_us(&mut self, n: u32) -> Result<(), Self::Error> { - let secs = n / 1_000_000; - let nsecs = (n % 1_000_000) * 1_000; - - thread::sleep(Duration::new(u64(secs), nsecs)); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayUs for Delay { - type Error = Infallible; - - fn try_delay_us(&mut self, n: u64) -> Result<(), Self::Error> { - let secs = n / 1_000_000; - let nsecs = ((n % 1_000_000) * 1_000) as u32; - - thread::sleep(Duration::new(secs, nsecs)); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayMs for Delay { - type Error = Infallible; - - fn try_delay_ms(&mut self, n: u8) -> Result<(), Self::Error> { - thread::sleep(Duration::from_millis(u64(n))); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayMs for Delay { - type Error = Infallible; - - fn try_delay_ms(&mut self, n: u16) -> Result<(), Self::Error> { - thread::sleep(Duration::from_millis(u64(n))); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayMs for Delay { - type Error = Infallible; - - fn try_delay_ms(&mut self, n: u32) -> Result<(), Self::Error> { - thread::sleep(Duration::from_millis(u64(n))); - Ok(()) - } -} - -impl embedded_hal::blocking::delay::DelayMs for Delay { - type Error = Infallible; - - fn try_delay_ms(&mut self, n: u64) -> Result<(), Self::Error> { - thread::sleep(Duration::from_millis(n)); - Ok(()) - } -} +mod delay; +pub use crate::delay::Delay; mod i2c; pub use crate::i2c::I2cdev; From c586d646cf04778e09042bbf5f39f3795b6817b7 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 22:50:30 +0200 Subject: [PATCH 03/12] Extract SPI into separate module --- src/lib.rs | 106 +++++--------------------------------------------- src/serial.rs | 6 +-- src/spi.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 101 deletions(-) create mode 100644 src/spi.rs diff --git a/src/lib.rs b/src/lib.rs index 0a0ace2..91acea1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,19 +23,6 @@ pub use sysfs_gpio; #[cfg(feature = "gpio_cdev")] pub use gpio_cdev; - -use std::io::{self, Write}; -use std::ops; -use std::path::Path; - -use spidev::SpidevTransfer; - -mod serial; -mod timer; - -pub use serial::Serial; -pub use timer::SysTimer; - #[cfg(feature = "gpio_sysfs")] /// Sysfs Pin wrapper module mod sysfs_pin; @@ -47,94 +34,19 @@ mod cdev_pin; #[cfg(feature = "gpio_cdev")] /// Cdev pin re-export pub use cdev_pin::CdevPin; + #[cfg(feature = "gpio_sysfs")] /// Sysfs pin re-export pub use sysfs_pin::SysfsPin; mod delay; -pub use crate::delay::Delay; - mod i2c; -pub use crate::i2c::I2cdev; - -/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits -/// -/// [`spidev::Spidev`]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html -pub struct Spidev(pub spidev::Spidev); - -impl Spidev { - /// See [`spidev::Spidev::open`][0] for details. - /// - /// [0]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html#method.open - pub fn open

(path: P) -> io::Result - where - P: AsRef, - { - spidev::Spidev::open(path).map(Spidev) - } -} - -impl embedded_hal::blocking::spi::Transfer for Spidev { - type Error = io::Error; - - fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> { - let tx = buffer.to_owned(); - self.0 - .transfer(&mut SpidevTransfer::read_write(&tx, buffer))?; - Ok(buffer) - } -} - -impl embedded_hal::blocking::spi::Write for Spidev { - type Error = io::Error; - - fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> { - self.0.write_all(buffer) - } -} - -pub use embedded_hal::blocking::spi::Operation as SpiOperation; - -/// Transactional implementation batches SPI operations into a single transaction -impl embedded_hal::blocking::spi::Transactional for Spidev { - type Error = io::Error; - - fn try_exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> { - // Map types from generic to linux objects - let mut messages: Vec<_> = operations - .iter_mut() - .map(|a| { - match a { - SpiOperation::Write(w) => SpidevTransfer::write(w), - SpiOperation::Transfer(r) => { - // Clone read to write pointer - // SPIdev is okay with having w == r but this is tricky to achieve in safe rust - let w = unsafe { - let p = r.as_ptr(); - std::slice::from_raw_parts(p, r.len()) - }; - - SpidevTransfer::read_write(w, r) - } - } - }) - .collect(); - - // Execute transfer - self.0.transfer_multiple(&mut messages) - } -} - -impl ops::Deref for Spidev { - type Target = spidev::Spidev; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} +mod serial; +mod spi; +mod timer; -impl ops::DerefMut for Spidev { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} +pub use crate::delay::Delay; +pub use crate::i2c::I2cdev; +pub use crate::serial::Serial; +pub use crate::spi::{SpiOperation, Spidev}; +pub use crate::timer::SysTimer; diff --git a/src/serial.rs b/src/serial.rs index 102849c..39e05ee 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,12 +1,10 @@ //! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html) -use std::io::{ErrorKind as IoErrorKind, Read, Write}; -use std::path::Path; - use nb; - use serial_core; use serial_unix::TTYPort; +use std::io::{ErrorKind as IoErrorKind, Read, Write}; +use std::path::Path; /// Newtype around [`serial_unix::TTYPort`] that implements /// the `embedded-hal` traits. diff --git a/src/spi.rs b/src/spi.rs new file mode 100644 index 0000000..19dc3a0 --- /dev/null +++ b/src/spi.rs @@ -0,0 +1,99 @@ +//! Implementation of [`embedded-hal`] SPI traits +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal +//! + +pub use embedded_hal::blocking::spi::Operation as SpiOperation; +use std::io; +use std::ops; +use std::path::Path; + +/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits +/// +/// [`spidev::Spidev`]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html +pub struct Spidev(pub spidev::Spidev); + +impl Spidev { + /// See [`spidev::Spidev::open`][0] for details. + /// + /// [0]: https://docs.rs/spidev/0.4.0/spidev/struct.Spidev.html#method.open + pub fn open

(path: P) -> io::Result + where + P: AsRef, + { + spidev::Spidev::open(path).map(Spidev) + } +} + +impl ops::Deref for Spidev { + type Target = spidev::Spidev; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ops::DerefMut for Spidev { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +mod embedded_hal_impl { + use super::*; + use embedded_hal::blocking::spi::{Transactional, Transfer, Write}; + use spidev::SpidevTransfer; + use std::io::Write as _; + + impl Transfer for Spidev { + type Error = io::Error; + + fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> { + let tx = buffer.to_owned(); + self.0 + .transfer(&mut SpidevTransfer::read_write(&tx, buffer))?; + Ok(buffer) + } + } + + impl Write for Spidev { + type Error = io::Error; + + fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> { + self.0.write_all(buffer) + } + } + + /// Transactional implementation batches SPI operations into a single transaction + impl Transactional for Spidev { + type Error = io::Error; + + fn try_exec<'a>( + &mut self, + operations: &mut [SpiOperation<'a, u8>], + ) -> Result<(), Self::Error> { + // Map types from generic to linux objects + let mut messages: Vec<_> = operations + .iter_mut() + .map(|a| { + match a { + SpiOperation::Write(w) => SpidevTransfer::write(w), + SpiOperation::Transfer(r) => { + // Clone read to write pointer + // SPIdev is okay with having w == r but this is tricky to achieve in safe rust + let w = unsafe { + let p = r.as_ptr(); + std::slice::from_raw_parts(p, r.len()) + }; + + SpidevTransfer::read_write(w, r) + } + } + }) + .collect(); + + // Execute transfer + self.0.transfer_multiple(&mut messages) + } + } +} From c52ce6619bcf7aed0170e26cc5d72f55f71f6f94 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 22:53:33 +0200 Subject: [PATCH 04/12] Improve documentation --- src/cdev_pin.rs | 4 +++- src/i2c.rs | 4 +++- src/serial.rs | 4 +++- src/sysfs_pin.rs | 4 +++- src/timer.rs | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cdev_pin.rs b/src/cdev_pin.rs index b35e50e..ea6fcf6 100644 --- a/src/cdev_pin.rs +++ b/src/cdev_pin.rs @@ -1,4 +1,6 @@ -//! Linux CDev pin type +//! Implementation of [`embedded-hal`] digital input/output traits using a Linux CDev pin +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal /// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits /// diff --git a/src/i2c.rs b/src/i2c.rs index 27c9ca4..6aece27 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -1,4 +1,6 @@ -//! `embedded-hal` I2C traits implementation +//! Implementation of [`embedded-hal`] I2C traits +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal use std::ops; use std::path::{Path, PathBuf}; diff --git a/src/serial.rs b/src/serial.rs index 39e05ee..70a125d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,4 +1,6 @@ -//! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html) +//! Implementation of [`embedded-hal`] serial traits +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal use nb; use serial_core; diff --git a/src/sysfs_pin.rs b/src/sysfs_pin.rs index b585912..fe2e672 100644 --- a/src/sysfs_pin.rs +++ b/src/sysfs_pin.rs @@ -1,4 +1,6 @@ -//! Linux Sysfs pin type +//! Implementation of [`embedded-hal`] digital input/output traits using a Linux Sysfs pin +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal use std::path::Path; diff --git a/src/timer.rs b/src/timer.rs index 0b26b19..b3ce737 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,4 +1,6 @@ -//! Timers. +//! Implementation of [`embedded-hal`] timer traits +//! +//! [`embedded-hal`]: https://docs.rs/embedded-hal use core::convert::Infallible; use std::time::{Duration, Instant}; From 8857740cc9c1279d642271b9cdc934bc9160a04b Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 23:03:27 +0200 Subject: [PATCH 05/12] Do not reexport renamed type --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 91acea1..ffb3e87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,5 +48,5 @@ mod timer; pub use crate::delay::Delay; pub use crate::i2c::I2cdev; pub use crate::serial::Serial; -pub use crate::spi::{SpiOperation, Spidev}; +pub use crate::spi::Spidev; pub use crate::timer::SysTimer; From a47723f5281893e9c988b9acb1dc85f09c3d7a70 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 23:08:19 +0200 Subject: [PATCH 06/12] Make import more local --- src/spi.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/spi.rs b/src/spi.rs index 19dc3a0..c864e82 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -3,7 +3,6 @@ //! [`embedded-hal`]: https://docs.rs/embedded-hal //! -pub use embedded_hal::blocking::spi::Operation as SpiOperation; use std::io; use std::ops; use std::path::Path; @@ -41,7 +40,7 @@ impl ops::DerefMut for Spidev { mod embedded_hal_impl { use super::*; - use embedded_hal::blocking::spi::{Transactional, Transfer, Write}; + use embedded_hal::blocking::spi::{Operation as SpiOperation, Transactional, Transfer, Write}; use spidev::SpidevTransfer; use std::io::Write as _; From 4c331ece3d1c19276affba5daf9d221ecc665835 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 23:08:25 +0200 Subject: [PATCH 07/12] Use 2018 import syntax in example --- examples/transactional-i2c.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/transactional-i2c.rs b/examples/transactional-i2c.rs index 451ae43..43d2156 100644 --- a/examples/transactional-i2c.rs +++ b/examples/transactional-i2c.rs @@ -1,5 +1,3 @@ -extern crate embedded_hal; -extern crate linux_embedded_hal; use embedded_hal::blocking::i2c::{Operation as I2cOperation, Transactional}; use linux_embedded_hal::I2cdev; From 18d704d362db5dc5f8a70761c3f99557ab4b25b3 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 11 Sep 2021 23:59:33 +0200 Subject: [PATCH 08/12] Update to embedded-hal-1.0.0-alpha.5 --- Cargo.toml | 2 +- examples/transactional-i2c.rs | 4 ++-- src/cdev_pin.rs | 14 +++++++------- src/delay.rs | 18 +++++++++--------- src/i2c.rs | 10 +++++----- src/serial.rs | 18 +++++++++--------- src/spi.rs | 14 +++++--------- src/sysfs_pin.rs | 14 +++++++------- src/timer.rs | 16 ++++++++-------- 9 files changed, 53 insertions(+), 57 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ae62c40..b80cc6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ async-tokio = ["gpio-cdev/async-tokio"] default = [ "gpio_cdev", "gpio_sysfs" ] [dependencies] -embedded-hal = "=1.0.0-alpha.4" +embedded-hal = "=1.0.0-alpha.5" gpio-cdev = { version = "0.4", optional = true } sysfs_gpio = { version = "0.5", optional = true } diff --git a/examples/transactional-i2c.rs b/examples/transactional-i2c.rs index 43d2156..a8697e1 100644 --- a/examples/transactional-i2c.rs +++ b/examples/transactional-i2c.rs @@ -1,4 +1,4 @@ -use embedded_hal::blocking::i2c::{Operation as I2cOperation, Transactional}; +use embedded_hal::i2c::blocking::{Operation as I2cOperation, Transactional}; use linux_embedded_hal::I2cdev; const ADDR: u8 = 0x12; @@ -21,7 +21,7 @@ where I2cOperation::Write(&[0xAB]), I2cOperation::Read(&mut read_buffer), ]; - self.i2c.try_exec(ADDR, &mut ops).and(Ok(read_buffer[0])) + self.i2c.exec(ADDR, &mut ops).and(Ok(read_buffer[0])) } } diff --git a/src/cdev_pin.rs b/src/cdev_pin.rs index ea6fcf6..6af3031 100644 --- a/src/cdev_pin.rs +++ b/src/cdev_pin.rs @@ -17,10 +17,10 @@ impl CdevPin { } } -impl embedded_hal::digital::OutputPin for CdevPin { +impl embedded_hal::digital::blocking::OutputPin for CdevPin { type Error = gpio_cdev::errors::Error; - fn try_set_low(&mut self) -> Result<(), Self::Error> { + fn set_low(&mut self) -> Result<(), Self::Error> { if self.1 { self.0.set_value(1) } else { @@ -28,7 +28,7 @@ impl embedded_hal::digital::OutputPin for CdevPin { } } - fn try_set_high(&mut self) -> Result<(), Self::Error> { + fn set_high(&mut self) -> Result<(), Self::Error> { if self.1 { self.0.set_value(0) } else { @@ -37,10 +37,10 @@ impl embedded_hal::digital::OutputPin for CdevPin { } } -impl embedded_hal::digital::InputPin for CdevPin { +impl embedded_hal::digital::blocking::InputPin for CdevPin { type Error = gpio_cdev::errors::Error; - fn try_is_high(&self) -> Result { + fn is_high(&self) -> Result { if !self.1 { self.0.get_value().map(|val| val != 0) } else { @@ -48,8 +48,8 @@ impl embedded_hal::digital::InputPin for CdevPin { } } - fn try_is_low(&self) -> Result { - self.try_is_high().map(|val| !val) + fn is_low(&self) -> Result { + self.is_high().map(|val| !val) } } diff --git a/src/delay.rs b/src/delay.rs index 741bd08..878d062 100644 --- a/src/delay.rs +++ b/src/delay.rs @@ -4,7 +4,7 @@ use cast::{u32, u64}; use core::convert::Infallible; -use embedded_hal::blocking::delay::{DelayMs, DelayUs}; +use embedded_hal::delay::blocking::{DelayMs, DelayUs}; use std::thread; use std::time::Duration; @@ -14,7 +14,7 @@ pub struct Delay; impl DelayUs for Delay { type Error = Infallible; - fn try_delay_us(&mut self, n: u8) -> Result<(), Self::Error> { + fn delay_us(&mut self, n: u8) -> Result<(), Self::Error> { thread::sleep(Duration::new(0, u32(n) * 1000)); Ok(()) } @@ -23,7 +23,7 @@ impl DelayUs for Delay { impl DelayUs for Delay { type Error = Infallible; - fn try_delay_us(&mut self, n: u16) -> Result<(), Self::Error> { + fn delay_us(&mut self, n: u16) -> Result<(), Self::Error> { thread::sleep(Duration::new(0, u32(n) * 1000)); Ok(()) } @@ -32,7 +32,7 @@ impl DelayUs for Delay { impl DelayUs for Delay { type Error = Infallible; - fn try_delay_us(&mut self, n: u32) -> Result<(), Self::Error> { + fn delay_us(&mut self, n: u32) -> Result<(), Self::Error> { let secs = n / 1_000_000; let nsecs = (n % 1_000_000) * 1_000; @@ -44,7 +44,7 @@ impl DelayUs for Delay { impl DelayUs for Delay { type Error = Infallible; - fn try_delay_us(&mut self, n: u64) -> Result<(), Self::Error> { + fn delay_us(&mut self, n: u64) -> Result<(), Self::Error> { let secs = n / 1_000_000; let nsecs = ((n % 1_000_000) * 1_000) as u32; @@ -56,7 +56,7 @@ impl DelayUs for Delay { impl DelayMs for Delay { type Error = Infallible; - fn try_delay_ms(&mut self, n: u8) -> Result<(), Self::Error> { + fn delay_ms(&mut self, n: u8) -> Result<(), Self::Error> { thread::sleep(Duration::from_millis(u64(n))); Ok(()) } @@ -65,7 +65,7 @@ impl DelayMs for Delay { impl DelayMs for Delay { type Error = Infallible; - fn try_delay_ms(&mut self, n: u16) -> Result<(), Self::Error> { + fn delay_ms(&mut self, n: u16) -> Result<(), Self::Error> { thread::sleep(Duration::from_millis(u64(n))); Ok(()) } @@ -74,7 +74,7 @@ impl DelayMs for Delay { impl DelayMs for Delay { type Error = Infallible; - fn try_delay_ms(&mut self, n: u32) -> Result<(), Self::Error> { + fn delay_ms(&mut self, n: u32) -> Result<(), Self::Error> { thread::sleep(Duration::from_millis(u64(n))); Ok(()) } @@ -83,7 +83,7 @@ impl DelayMs for Delay { impl DelayMs for Delay { type Error = Infallible; - fn try_delay_ms(&mut self, n: u64) -> Result<(), Self::Error> { + fn delay_ms(&mut self, n: u64) -> Result<(), Self::Error> { thread::sleep(Duration::from_millis(n)); Ok(()) } diff --git a/src/i2c.rs b/src/i2c.rs index 6aece27..c93e794 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -55,7 +55,7 @@ impl ops::DerefMut for I2cdev { mod embedded_hal_impl { use super::*; - use embedded_hal::blocking::i2c::{ + use embedded_hal::i2c::blocking::{ Operation as I2cOperation, Read, Transactional, Write, WriteRead, }; use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer}; @@ -64,7 +64,7 @@ mod embedded_hal_impl { impl Read for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { self.set_address(address)?; self.inner.read(buffer) } @@ -73,7 +73,7 @@ mod embedded_hal_impl { impl Write for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { + fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { self.set_address(address)?; self.inner.write(bytes) } @@ -82,7 +82,7 @@ mod embedded_hal_impl { impl WriteRead for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn try_write_read( + fn write_read( &mut self, address: u8, bytes: &[u8], @@ -97,7 +97,7 @@ mod embedded_hal_impl { impl Transactional for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn try_exec( + fn exec( &mut self, address: u8, operations: &mut [I2cOperation], diff --git a/src/serial.rs b/src/serial.rs index 70a125d..46bb61d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -29,10 +29,10 @@ fn translate_io_errors(err: std::io::Error) -> nb::Error { } } -impl embedded_hal::serial::Read for Serial { +impl embedded_hal::serial::nb::Read for Serial { type Error = IoErrorKind; - fn try_read(&mut self) -> nb::Result { + fn read(&mut self) -> nb::Result { let mut buffer = [0; 1]; let bytes_read = self.0.read(&mut buffer).map_err(translate_io_errors)?; if bytes_read == 1 { @@ -43,15 +43,15 @@ impl embedded_hal::serial::Read for Serial { } } -impl embedded_hal::serial::Write for Serial { +impl embedded_hal::serial::nb::Write for Serial { type Error = IoErrorKind; - fn try_write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { self.0.write(&[word]).map_err(translate_io_errors)?; Ok(()) } - fn try_flush(&mut self) -> nb::Result<(), Self::Error> { + fn flush(&mut self) -> nb::Result<(), Self::Error> { self.0.flush().map_err(translate_io_errors) } } @@ -60,7 +60,7 @@ impl embedded_hal::serial::Write for Serial { mod test { use std::path::Path; - use embedded_hal::serial::{Read, Write}; + use embedded_hal::serial::nb::{Read, Write}; use std::io::{Read as IoRead, Write as IoWrite}; use super::*; @@ -75,20 +75,20 @@ mod test { #[test] fn test_empty_read() { let (mut _master, mut serial) = create_pty_and_serial(); - assert_eq!(Err(nb::Error::WouldBlock), serial.try_read()); + assert_eq!(Err(nb::Error::WouldBlock), serial.read()); } #[test] fn test_read() { let (mut master, mut serial) = create_pty_and_serial(); master.write(&[1]).expect("Write failed"); - assert_eq!(Ok(1), serial.try_read()); + assert_eq!(Ok(1), serial.read()); } #[test] fn test_write() { let (mut master, mut serial) = create_pty_and_serial(); - serial.try_write(2).expect("Write failed"); + serial.write(2).expect("Write failed"); let mut buf = [0; 2]; assert_eq!(1, master.read(&mut buf).unwrap()); assert_eq!(buf, [2, 0]); diff --git a/src/spi.rs b/src/spi.rs index c864e82..2306a53 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -40,25 +40,24 @@ impl ops::DerefMut for Spidev { mod embedded_hal_impl { use super::*; - use embedded_hal::blocking::spi::{Operation as SpiOperation, Transactional, Transfer, Write}; + use embedded_hal::spi::blocking::{Operation as SpiOperation, Transactional, Transfer, Write}; use spidev::SpidevTransfer; use std::io::Write as _; impl Transfer for Spidev { type Error = io::Error; - fn try_transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<&'b [u8]> { + fn transfer<'b>(&mut self, buffer: &'b mut [u8]) -> io::Result<()> { let tx = buffer.to_owned(); self.0 - .transfer(&mut SpidevTransfer::read_write(&tx, buffer))?; - Ok(buffer) + .transfer(&mut SpidevTransfer::read_write(&tx, buffer)) } } impl Write for Spidev { type Error = io::Error; - fn try_write(&mut self, buffer: &[u8]) -> io::Result<()> { + fn write(&mut self, buffer: &[u8]) -> io::Result<()> { self.0.write_all(buffer) } } @@ -67,10 +66,7 @@ mod embedded_hal_impl { impl Transactional for Spidev { type Error = io::Error; - fn try_exec<'a>( - &mut self, - operations: &mut [SpiOperation<'a, u8>], - ) -> Result<(), Self::Error> { + fn exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> { // Map types from generic to linux objects let mut messages: Vec<_> = operations .iter_mut() diff --git a/src/sysfs_pin.rs b/src/sysfs_pin.rs index fe2e672..5734f22 100644 --- a/src/sysfs_pin.rs +++ b/src/sysfs_pin.rs @@ -28,10 +28,10 @@ impl SysfsPin { } } -impl embedded_hal::digital::OutputPin for SysfsPin { +impl embedded_hal::digital::blocking::OutputPin for SysfsPin { type Error = sysfs_gpio::Error; - fn try_set_low(&mut self) -> Result<(), Self::Error> { + fn set_low(&mut self) -> Result<(), Self::Error> { if self.0.get_active_low()? { self.0.set_value(1) } else { @@ -39,7 +39,7 @@ impl embedded_hal::digital::OutputPin for SysfsPin { } } - fn try_set_high(&mut self) -> Result<(), Self::Error> { + fn set_high(&mut self) -> Result<(), Self::Error> { if self.0.get_active_low()? { self.0.set_value(0) } else { @@ -48,10 +48,10 @@ impl embedded_hal::digital::OutputPin for SysfsPin { } } -impl embedded_hal::digital::InputPin for SysfsPin { +impl embedded_hal::digital::blocking::InputPin for SysfsPin { type Error = sysfs_gpio::Error; - fn try_is_high(&self) -> Result { + fn is_high(&self) -> Result { if !self.0.get_active_low()? { self.0.get_value().map(|val| val != 0) } else { @@ -59,8 +59,8 @@ impl embedded_hal::digital::InputPin for SysfsPin { } } - fn try_is_low(&self) -> Result { - self.try_is_high().map(|val| !val) + fn is_low(&self) -> Result { + self.is_high().map(|val| !val) } } diff --git a/src/timer.rs b/src/timer.rs index b3ce737..6235f72 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -5,7 +5,7 @@ use core::convert::Infallible; use std::time::{Duration, Instant}; -use embedded_hal::timer::{CountDown, Periodic}; +use embedded_hal::timer::{nb::CountDown, Periodic}; /// A periodic timer based on [`std::time::Instant`][instant], which is a /// monotonically nondecreasing clock. @@ -33,7 +33,7 @@ impl CountDown for SysTimer { type Error = Infallible; type Time = Duration; - fn try_start(&mut self, count: T) -> Result<(), Self::Error> + fn start(&mut self, count: T) -> Result<(), Self::Error> where T: Into, { @@ -42,7 +42,7 @@ impl CountDown for SysTimer { Ok(()) } - fn try_wait(&mut self) -> nb::Result<(), Self::Error> { + fn wait(&mut self) -> nb::Result<(), Self::Error> { if (Instant::now() - self.start) >= self.duration { // Restart the timer to fulfill the contract by `Periodic` self.start = Instant::now(); @@ -65,8 +65,8 @@ mod tests { fn test_delay() { let mut timer = SysTimer::new(); let before = Instant::now(); - timer.try_start(Duration::from_millis(100)).unwrap(); - nb::block!(timer.try_wait()).unwrap(); + timer.start(Duration::from_millis(100)).unwrap(); + nb::block!(timer.wait()).unwrap(); let after = Instant::now(); let duration_ms = (after - before).as_millis(); assert!(duration_ms >= 100); @@ -78,13 +78,13 @@ mod tests { fn test_periodic() { let mut timer = SysTimer::new(); let before = Instant::now(); - timer.try_start(Duration::from_millis(100)).unwrap(); - nb::block!(timer.try_wait()).unwrap(); + timer.start(Duration::from_millis(100)).unwrap(); + nb::block!(timer.wait()).unwrap(); let after1 = Instant::now(); let duration_ms_1 = (after1 - before).as_millis(); assert!(duration_ms_1 >= 100); assert!(duration_ms_1 < 500); - nb::block!(timer.try_wait()).unwrap(); + nb::block!(timer.wait()).unwrap(); let after2 = Instant::now(); let duration_ms_2 = (after2 - after1).as_millis(); assert!(duration_ms_2 >= 100); From 07754c2bb6cd73a04432bec315b72efad5bd3514 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 18 Sep 2021 12:54:21 +0200 Subject: [PATCH 09/12] Update changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2270baf..c9fe0d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Modified `OutputPin` behavior for active-low pins to match `InputPin` behavior. - Set default features to build both sysfs and cdev pin types. - Removed `Pin` export, use `CdevPin` or `SysfsPin`. -- Increased the Minimum Supported Rust Version to `1.36.0` due to an update of `gpio_cdev`. -- Adapted to `embedded-hal` `1.0.0-alpha.3` release. +- Adapted to `embedded-hal` `1.0.0-alpha.5` release. - Updated `nb` to version `1`. ## [v0.3.0] - 2019-11-25 From 0cd3fb098bfb3935127abcca77efa5d00c5111fd Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 18 Sep 2021 12:54:35 +0200 Subject: [PATCH 10/12] Raise MSRV to version 1.46.0 due to dependencies --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 1 + README.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a84d4fd..ba91b86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: include: # Test MSRV - - rust: 1.36.0 + - rust: 1.46.0 TARGET: x86_64-unknown-linux-gnu # Test nightly but don't fail diff --git a/CHANGELOG.md b/CHANGELOG.md index c9fe0d9..566dc86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Modified `OutputPin` behavior for active-low pins to match `InputPin` behavior. - Set default features to build both sysfs and cdev pin types. - Removed `Pin` export, use `CdevPin` or `SysfsPin`. +- Increased the Minimum Supported Rust Version to `1.46.0` due to an update of `bitflags`. - Adapted to `embedded-hal` `1.0.0-alpha.5` release. - Updated `nb` to version `1`. diff --git a/README.md b/README.md index 4a7c42b..949e3c3 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] } ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.36.0 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.46.0 and up. It *might* compile with older versions but that may change in any new patch release. ## License From e43b25447cf8bae1918bc1b8c0ffca24867c5113 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 25 Sep 2021 14:46:30 +0200 Subject: [PATCH 11/12] Update dependencies --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b80cc6b..7ff56ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,14 +21,14 @@ default = [ "gpio_cdev", "gpio_sysfs" ] [dependencies] embedded-hal = "=1.0.0-alpha.5" -gpio-cdev = { version = "0.4", optional = true } -sysfs_gpio = { version = "0.5", optional = true } +gpio-cdev = { version = "0.5", optional = true } +sysfs_gpio = { version = "0.6", optional = true } -i2cdev = "0.4.3" +i2cdev = "0.5" nb = "1" serial-core = "0.4.0" serial-unix = "0.4.0" -spidev = "0.4" +spidev = "0.5" [dev-dependencies] openpty = "0.1.0" @@ -36,4 +36,4 @@ openpty = "0.1.0" [dependencies.cast] # we don't need the `Error` implementation default-features = false -version = "0.2.2" +version = "0.3" From c4abaf22bed464dc6fb49a8ac61522e8fcc1b3e9 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sat, 25 Sep 2021 21:13:31 +0200 Subject: [PATCH 12/12] Update MSRV in bors --- .github/bors.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/bors.toml b/.github/bors.toml index 183d1f0..64eb89c 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -4,5 +4,5 @@ required_approvals = 1 status = [ "CI (stable, x86_64-unknown-linux-gnu)", "CI (stable, armv7-unknown-linux-gnueabihf)", - "CI (1.36.0, x86_64-unknown-linux-gnu)", + "CI (1.46.0, x86_64-unknown-linux-gnu)", ]