From a6f9a7ae1d240d52430aa8e8ea31aed0dbe2e003 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Tue, 2 Jul 2024 11:01:21 +0200 Subject: [PATCH 01/12] run `cargo update` on example --- .../stm32f4-single-motor-example/Cargo.lock | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/stm32f4-single-motor-example/Cargo.lock b/examples/stm32f4-single-motor-example/Cargo.lock index b561241..a114dfd 100644 --- a/examples/stm32f4-single-motor-example/Cargo.lock +++ b/examples/stm32f4-single-motor-example/Cargo.lock @@ -113,9 +113,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" [[package]] name = "defmt" @@ -137,7 +137,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.77", ] [[package]] @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" dependencies = [ "litrs", ] @@ -220,22 +220,22 @@ checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.77", ] [[package]] @@ -286,7 +286,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.0", + "rustc_version 0.4.1", "spin", "stable_deref_trait", ] @@ -380,18 +380,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -437,9 +437,9 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver 1.0.23", ] @@ -553,9 +553,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -582,22 +582,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.77", ] [[package]] @@ -632,9 +632,9 @@ checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" From 33965bbeb6512d3b36c39f7647b58d0d874f150c Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Tue, 2 Jul 2024 11:04:04 +0200 Subject: [PATCH 02/12] rename `defmt` feature to `defmt-03` this follows the pattern from other crates (e.g. `heapless`) which allows to add e.g. an upcoming `defmt` v1.0 support as a non-breaking feature. --- Cargo.toml | 3 +++ README.md | 2 +- src/lib.rs | 16 ++++++++-------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index db7258c..b848245 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ categories = ["embedded", "hardware-support", "no-std", "no-std::no-alloc"] keywords = ["tb6612fng", "driver", "motor", "controller", "embedded-hal-driver"] license = "MIT OR Apache-2.0" +[features] +defmt-03 = ["dep:defmt"] + [dependencies] embedded-hal = "1.0" diff --git a/README.md b/README.md index 24b0b2d..b3a19bd 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ See the documentation for usage examples. * You plan on using a single motor without the standby feature: use `Motor` ## Optional features -* `defmt`: you can enable the [`defmt`](https://defmt.ferrous-systems.com/) feature to get a `defmt::debug!` call for every speed change. +* `defmt-03`: you can enable this feature to get a `defmt::Format` implementation for all structs & enums in this crate and a `defmt::debug` call for every speed change. ## Examples A simple example for the STM32F4 microcontrollers is [available](examples/stm32f4-single-motor-example/README.md). diff --git a/src/lib.rs b/src/lib.rs index 2f2ae9d..eaf90fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ //! * You plan on using a single motor without the standby feature: use [`Motor`] //! //! ## Optional features -//! * `defmt`: you can enable the `defmt` feature to get a `defmt::Format` implementation for all structs & enums in this crate and a `defmt::debug` call for every speed change. +//! * `defmt-03`: you can enable this feature to get a `defmt::Format` implementation for all structs & enums in this crate and a `defmt::debug` call for every speed change. #![forbid(unsafe_code)] #![deny(warnings)] @@ -20,14 +20,14 @@ #![deny(unused)] #![no_std] -#[cfg(feature = "defmt")] +#[cfg(feature = "defmt-03")] use defmt::Format; use embedded_hal::digital::{OutputPin, StatefulOutputPin}; use embedded_hal::pwm::SetDutyCycle; /// Defines errors which can happen when calling [`Motor::drive()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(Format))] +#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum MotorError { /// An invalid speed has been defined. The speed must be given as a percentage value between 0 and 100 to be valid. InvalidSpeed, @@ -41,7 +41,7 @@ pub enum MotorError { /// Defines errors which can happen when calling [`Tb6612fng::new()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(Format))] +#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum Tb6612fngError< MAIN1Error, MAIN2Error, @@ -61,7 +61,7 @@ pub enum Tb6612fngError< /// Defines the possible drive commands. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt", derive(Format))] +#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum DriveCommand { /// Drive forward with the defined speed (in percentage) Forward(u8), @@ -78,7 +78,7 @@ pub enum DriveCommand { /// Use the [`Motor`] struct directly if you only have one motor. /// See the crate-level comment for further details on when to use what. #[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(Format))] +#[cfg_attr(feature = "defmt-03", derive(Format))] pub struct Tb6612fng { /// The first motor, labelled as 'A' on the chip pub motor_a: Motor, @@ -213,7 +213,7 @@ where /// This is unaware of the standby pin. If you plan on using both motors and the standby feature then use the [`Tb6612fng`] struct instead. /// See the crate-level comment for further details on when to use what. #[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(Format))] +#[cfg_attr(feature = "defmt-03", derive(Format))] pub struct Motor { in1: IN1, in2: IN2, @@ -308,7 +308,7 @@ where } } - #[cfg(feature = "defmt")] + #[cfg(feature = "defmt-03")] defmt::debug!("driving {} with speed {}", drive_command, speed); self.pwm From b688be8d9c83e77ceebfa87a6f0f2e0d6344c8ae Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Tue, 2 Jul 2024 11:38:16 +0200 Subject: [PATCH 03/12] document errors for all methods this fulfils the [C-FAILURE] guideline. [C-FAILURE]: https://rust-lang.github.io/api-guidelines/documentation.html#function-docs-include-error-panic-and-safety-considerations-c-failure --- src/lib.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index eaf90fc..5d40bf4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,7 +104,11 @@ where /// The initial state of the motors will be set to [stopped](DriveCommand::Stop). /// The initial state of standby will be *disabled*. /// - /// Usage example: + /// # Errors + /// If any of the underlying pin interactions fail these errors will be propagated up. + /// The errors are specific to your HAL. + /// + /// # Usage example /// ``` /// # use embedded_hal_mock::eh1::digital::Mock as PinMock; /// # use embedded_hal_mock::eh1::pwm::Mock as PwmMock; @@ -189,11 +193,19 @@ where /// /// Note that this does not change any commands on the motors, i.e. the PWM signal will continue /// and once [`Tb6612fng::disable_standby`] is called the motor will pick up where it left off (unless the command was changed in-between). + /// + /// # Errors + /// If the underlying pin interaction fails this error will be propagated up. + /// The error is specific to your HAL. pub fn enable_standby(&mut self) -> Result<(), STBY::Error> { self.standby.set_low() } /// Disable standby. Note that the last active commands on the motors will resume. + /// + /// # Errors + /// If the underlying pin interaction fails this error will be propagated up. + /// The error is specific to your HAL. pub fn disable_standby(&mut self) -> Result<(), STBY::Error> { self.standby.set_high() } @@ -201,6 +213,10 @@ where /// Returns whether the standby mode is enabled. /// /// *NOTE* this does *not* read the electrical state of the pin, see [`StatefulOutputPin`] + /// + /// # Errors + /// If the underlying pin interaction fails this error will be propagated up. + /// The error is specific to your HAL. pub fn current_standby(&mut self) -> Result where STBY: StatefulOutputPin, @@ -210,6 +226,7 @@ where } /// Represents a single motor (either motor A or motor B) hooked up to a TB6612FNG controller. +/// /// This is unaware of the standby pin. If you plan on using both motors and the standby feature then use the [`Tb6612fng`] struct instead. /// See the crate-level comment for further details on when to use what. #[derive(Debug)] @@ -231,7 +248,11 @@ where /// This also automatically enables the PWM pin. /// The initial state of the motor will be set to [stopped](DriveCommand::Stop). /// - /// Usage example: + /// # Errors + /// If any of the underlying pin interactions fail these errors will be propagated up. + /// The errors are specific to your HAL. + /// + /// # Usage example /// ``` /// # use embedded_hal_mock::eh1::digital::Mock as PinMock; /// # use embedded_hal_mock::eh1::pwm::Mock as PwmMock; @@ -275,6 +296,13 @@ where } /// Drive with the defined speed (or brake or stop the motor). + /// + /// # Errors + /// If the underlying pin interaction fails this error will be propagated up. + /// The error is specific to your HAL. + /// + /// The specified speed must be between 0 and 100 (inclusive), otherwise you will get a + /// [`MotorError::InvalidSpeed`] error. #[allow(clippy::type_complexity)] pub fn drive( &mut self, @@ -330,7 +358,7 @@ where /// Return the current speed of the motor (in percentage). Note that driving forward returns a positive number /// while driving backward returns a negative number and both [`DriveCommand::Brake`] and [`DriveCommand::Stop`] return 0. /// - /// If you need to know in more details what the current status is consider calling [`Motor::current_drive_command`] instead. + /// If you need to know in more details what the current status is, consider calling [`Motor::current_drive_command`] instead. pub fn current_speed(&self) -> i8 { match self.current_drive_command() { DriveCommand::Forward(s) => *s as i8, From 35b07de5425734e86c777d6bc1eb80f2ae54c151 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Tue, 2 Jul 2024 11:55:49 +0200 Subject: [PATCH 04/12] add `authors` to `Cargo.toml` this is required by [C-METADATA]. [C-METADATA]: https://rust-lang.github.io/api-guidelines/documentation.html#c-metadata --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index b848245..ef1a482 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/rust-embedded-community/tb6612fng-rs" categories = ["embedded", "hardware-support", "no-std", "no-std::no-alloc"] keywords = ["tb6612fng", "driver", "motor", "controller", "embedded-hal-driver"] license = "MIT OR Apache-2.0" +authors = ["Ralph Ursprung ", "ripytide "] [features] defmt-03 = ["dep:defmt"] From 57d86a100289bdaedb0446f118854e78389dec4e Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Tue, 2 Jul 2024 11:07:36 +0200 Subject: [PATCH 05/12] update README & changelog in preparation of v1.0 the license & contribution part is taken 1:1 from [C-PERMISSIVE]. [C-PERMISSIVE]: https://rust-lang.github.io/api-guidelines/necessities.html#crate-and-its-dependencies-have-a-permissive-license-c-permissive --- CHANGELOG.md | 7 ++++--- README.md | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24f6097..bca6b57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate ### Added + * Add a `current_standby()` method to check if the driver is currently in standby mode. ### Changed @@ -15,9 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 initialisation to the documented defaults. * `Motor::new()` and `Driver::new()` methods now also return errors if they fail to set their outputs upon initialisation. -* Breaking: update to `embedded-hal` 1.0 -* Renamed error types to their struct names -* Renamed `DriveCommand::Backwards` to `DriveCommand::Backward` to match +* **Breaking**: update to `embedded-hal` 1.0 +* **Breaking**: Renamed error types to their struct names +* **Breaking**: Renamed `DriveCommand::Backwards` to `DriveCommand::Backward` to match `DriveCommand::Forward` ### Removed diff --git a/README.md b/README.md index b3a19bd..2cec911 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,19 @@ A simple example for the STM32F4 microcontrollers is [available](examples/stm32f ## Changelog For the changelog please see the dedicated [CHANGELOG.md](CHANGELOG.md). -## Roadmap to v1.0.0 -This crate is already stable, however it's based on a release candidate version of [`embedded-hal`](https://github.com/rust-embedded/embedded-hal/), -making the API unstable (the change from 1.0.0-rc.1 to 1.0.0 of e-h will be breaking from a dependency management point of view). - -See [the tracking issue](https://github.com/rust-embedded-community/tb6612fng-rs/issues/4) for the roadmap to v1.0.0. - ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.62 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.63 and up. It *might* compile with older versions but that may change in any new patch release. + +## License +Licensed under either of + +* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Contribution +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. From 973c337828fb6d85eb2443aa93414653137afba0 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Sun, 8 Sep 2024 20:19:39 +0200 Subject: [PATCH 06/12] simplify `Tb6612fng::new`: take `Motor`s instead of pins this lets the caller construct the `Motor` and hand it over to `Tb6612fng` instead of having to pass all the pins. this reduces the risk fo mixing up the pins as the old API wuold take 7 pins as an input. --- src/lib.rs | 48 +++++++++--------------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5d40bf4..3718aa3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,19 +42,7 @@ pub enum MotorError { /// Defines errors which can happen when calling [`Tb6612fng::new()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] #[cfg_attr(feature = "defmt-03", derive(Format))] -pub enum Tb6612fngError< - MAIN1Error, - MAIN2Error, - MAPWMError, - MBIN1Error, - MBIN2Error, - MBPWMError, - STBYError, -> { - /// An error in setting the initial `drive()` of `motor_a` - MotorA(MotorError), - /// An error in setting the initial `drive()` of `motor_b` - MotorB(MotorError), +pub enum Tb6612fngError { /// An error in setting the initial output of the standby pin Standby(STBYError), } @@ -133,15 +121,11 @@ where /// # let standby = PinMock::new(&[PinTransaction::set(High)]); /// # let mut standby_ = standby.clone(); /// - /// use tb6612fng::Tb6612fng; + /// use tb6612fng::{Motor, Tb6612fng}; /// /// let controller = Tb6612fng::new( - /// motor_a_in1, - /// motor_a_in2, - /// motor_a_pwm, - /// motor_b_in1, - /// motor_b_in2, - /// motor_b_pwm, + /// Motor::new(motor_a_in1, motor_a_in2, motor_a_pwm).unwrap(), + /// Motor::new(motor_b_in1, motor_b_in2, motor_b_pwm).unwrap(), /// standby, /// ); /// @@ -155,30 +139,16 @@ where /// ``` #[allow(clippy::type_complexity)] pub fn new( - motor_a_in1: MAIN1, - motor_a_in2: MAIN2, - motor_a_pwm: MAPWM, - motor_b_in1: MBIN1, - motor_b_in2: MBIN2, - motor_b_pwm: MBPWM, + motor_a: Motor, + motor_b: Motor, standby: STBY, ) -> Result< Tb6612fng, - Tb6612fngError< - MAIN1::Error, - MAIN2::Error, - MAPWM::Error, - MBIN1::Error, - MBIN2::Error, - MBPWM::Error, - STBY::Error, - >, + Tb6612fngError, > { let mut controller = Tb6612fng { - motor_a: Motor::new(motor_a_in1, motor_a_in2, motor_a_pwm) - .map_err(Tb6612fngError::MotorA)?, - motor_b: Motor::new(motor_b_in1, motor_b_in2, motor_b_pwm) - .map_err(Tb6612fngError::MotorB)?, + motor_a, + motor_b, standby, }; From bbdd9b4d04da1db3cbac94de20bb9c947546066e Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sun, 8 Sep 2024 20:23:18 +0200 Subject: [PATCH 07/12] exclude e-h 0.2 dependency coming from mock --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ef1a482..177c41f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,4 @@ embedded-hal = "1.0" defmt = { version = "0.3", optional = true } [dev-dependencies] -embedded-hal-mock = "0.11" +embedded-hal-mock = { version = "0.11", default-features = false, features = ["eh1"] } From d9da807701c366dac882c9c4e1c6ae3f3f0cf353 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Mon, 9 Sep 2024 10:48:17 +0200 Subject: [PATCH 08/12] remove `defmt` dependency & feature based on the discussion on GitHub we don't need this dependency. it's the only 0.x dependency currently present in the crate and doesn't provide a lot of value since consuming code can use `defmt::Debug2Format` when needed. the single `defmt::debug!` statement in `Motor::drive` was not very helpful anyway if two motors were connected as it did not differentiate between the motors in the message. since this was the only optional feature there's no need anymore to test with `--all-features` in the CI. this has been removed from the build matrix (but the possibility to add it later has been kept as it doesn't make the build script unnecessarily complicated). --- .github/workflows/CI.yml | 5 +---- CHANGELOG.md | 3 +++ Cargo.toml | 1 - README.md | 3 --- src/lib.rs | 13 ------------- 5 files changed, 4 insertions(+), 21 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f1874f5..3ce54cd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,10 +14,7 @@ jobs: fail-fast: false matrix: rust: [1.63.0, stable] - features: ['', '--all-features'] - exclude: - - rust: 1.63.0 - features: '--all-features' + features: [''] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index bca6b57..ea042e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Removed the `drive_forward`, `drive_backward`, `stop` and `brake` functions as they are duplicates to the `drive` function with the different enum variants and make the API surface larger +* Removed the `defmt` feature: it was only used for debugging and since the `enum`s & `struct`s implement `Debug` + consuming code can use `defmt::Debug2Format` when needed. The single `defmt::debug!` statement in `Motor::drive` was + not very helpful anyway if two motors were connected ## [0.2.0] - 2023-11-28 diff --git a/Cargo.toml b/Cargo.toml index 177c41f..3ffcf9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ license = "MIT OR Apache-2.0" authors = ["Ralph Ursprung ", "ripytide "] [features] -defmt-03 = ["dep:defmt"] [dependencies] embedded-hal = "1.0" diff --git a/README.md b/README.md index 2cec911..e022faf 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,6 @@ See the documentation for usage examples. * You plan on using a single motor with the standby feature: use `Motor` and control the standby pin manually * You plan on using a single motor without the standby feature: use `Motor` -## Optional features -* `defmt-03`: you can enable this feature to get a `defmt::Format` implementation for all structs & enums in this crate and a `defmt::debug` call for every speed change. - ## Examples A simple example for the STM32F4 microcontrollers is [available](examples/stm32f4-single-motor-example/README.md). diff --git a/src/lib.rs b/src/lib.rs index 3718aa3..2ed3b77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,9 +9,6 @@ //! * You plan on using both motors without the standby feature: use two separate [`Motor`]s //! * You plan on using a single motor with the standby feature: use [`Motor`] and control the standby pin manually //! * You plan on using a single motor without the standby feature: use [`Motor`] -//! -//! ## Optional features -//! * `defmt-03`: you can enable this feature to get a `defmt::Format` implementation for all structs & enums in this crate and a `defmt::debug` call for every speed change. #![forbid(unsafe_code)] #![deny(warnings)] @@ -20,14 +17,11 @@ #![deny(unused)] #![no_std] -#[cfg(feature = "defmt-03")] -use defmt::Format; use embedded_hal::digital::{OutputPin, StatefulOutputPin}; use embedded_hal::pwm::SetDutyCycle; /// Defines errors which can happen when calling [`Motor::drive()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum MotorError { /// An invalid speed has been defined. The speed must be given as a percentage value between 0 and 100 to be valid. InvalidSpeed, @@ -41,7 +35,6 @@ pub enum MotorError { /// Defines errors which can happen when calling [`Tb6612fng::new()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum Tb6612fngError { /// An error in setting the initial output of the standby pin Standby(STBYError), @@ -49,7 +42,6 @@ pub enum Tb6612fngError { /// Defines the possible drive commands. #[derive(PartialEq, Eq, Debug, Copy, Clone)] -#[cfg_attr(feature = "defmt-03", derive(Format))] pub enum DriveCommand { /// Drive forward with the defined speed (in percentage) Forward(u8), @@ -66,7 +58,6 @@ pub enum DriveCommand { /// Use the [`Motor`] struct directly if you only have one motor. /// See the crate-level comment for further details on when to use what. #[derive(Debug)] -#[cfg_attr(feature = "defmt-03", derive(Format))] pub struct Tb6612fng { /// The first motor, labelled as 'A' on the chip pub motor_a: Motor, @@ -200,7 +191,6 @@ where /// This is unaware of the standby pin. If you plan on using both motors and the standby feature then use the [`Tb6612fng`] struct instead. /// See the crate-level comment for further details on when to use what. #[derive(Debug)] -#[cfg_attr(feature = "defmt-03", derive(Format))] pub struct Motor { in1: IN1, in2: IN2, @@ -306,9 +296,6 @@ where } } - #[cfg(feature = "defmt-03")] - defmt::debug!("driving {} with speed {}", drive_command, speed); - self.pwm .set_duty_cycle_percent(speed) .map_err(MotorError::PwmError)?; From 1e4680dc8f8b15b4aa86bbe1528c47a196e7ff1b Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Mon, 9 Sep 2024 11:22:05 +0200 Subject: [PATCH 09/12] fix markdown license links in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e022faf..76088b3 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,8 @@ compile with older versions but that may change in any new patch release. ## License Licensed under either of -* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) -* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option. From b383c5dd677813169fbd580a8d6d056e2075bb96 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Mon, 9 Sep 2024 12:08:16 +0200 Subject: [PATCH 10/12] implement `core::error::Error` this API has been stabilised with Rust 1.81.0. accordingly the MSRV has been raised. in order to implement `cause` the underlying error from the HAL must also implement `core::error::Error`. otherwise the trait bound will not be satisfied. as the trait has only just been stabilisied it is not yet implemented by any HAL (except for `embedded-hal-mock` since it's `std`). however, for GPIO operations most HALs will anyway just use `core::convert::Infallible` which in turn already implements `core::error::Error`, thus this should work out of the box. --- .github/workflows/CI.yml | 2 +- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- README.md | 2 +- src/lib.rs | 60 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3ce54cd..2187aed 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [1.63.0, stable] + rust: [1.81.0, stable] features: [''] runs-on: ubuntu-latest steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index ea042e1..a8b544b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added * Add a `current_standby()` method to check if the driver is currently in standby mode. +* `MotorError` and `Tb6612fngError` now implement `core::error::Error` (newly stabilised in Rust 1.81) ### Changed @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **Breaking**: Renamed error types to their struct names * **Breaking**: Renamed `DriveCommand::Backwards` to `DriveCommand::Backward` to match `DriveCommand::Forward` +* The MSRV has been updated to 1.81.0 due to `core::error::Error` being implemented ### Removed diff --git a/Cargo.toml b/Cargo.toml index 3ffcf9a..b15b089 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "tb6612fng" version = "0.2.0" edition = "2021" -rust-version = "1.63" +rust-version = "1.81" description = "A `no_std` driver for the TB6612FNG motor driver." repository = "https://github.com/rust-embedded-community/tb6612fng-rs" diff --git a/README.md b/README.md index 76088b3..08a8acd 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ A simple example for the STM32F4 microcontrollers is [available](examples/stm32f For the changelog please see the dedicated [CHANGELOG.md](CHANGELOG.md). ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.63 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.81 and up. It *might* compile with older versions but that may change in any new patch release. ## License diff --git a/src/lib.rs b/src/lib.rs index 2ed3b77..4097271 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,8 @@ #![deny(unused)] #![no_std] +use core::error::Error; +use core::fmt::{Debug, Formatter}; use embedded_hal::digital::{OutputPin, StatefulOutputPin}; use embedded_hal::pwm::SetDutyCycle; @@ -33,6 +35,37 @@ pub enum MotorError { PwmError(PWMError), } +impl core::fmt::Display + for MotorError +{ + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + use MotorError::*; + match self { + InvalidSpeed => write!(f, "an invalid speed has been specified"), + In1Error(_) => write!(f, "failed to set the output of the IN1 pin"), + In2Error(_) => write!(f, "failed to set the output of the IN2 pin"), + PwmError(_) => write!(f, "failed to set the output of the PWM pin"), + } + } +} + +impl< + IN1Error: Debug + Error + 'static, + IN2Error: Debug + Error + 'static, + PWMError: Debug + Error + 'static, + > Error for MotorError +{ + fn source(&self) -> Option<&(dyn Error + 'static)> { + use MotorError::*; + match self { + InvalidSpeed => None, + In1Error(e) => Some(e), + In2Error(e) => Some(e), + PwmError(e) => Some(e), + } + } +} + /// Defines errors which can happen when calling [`Tb6612fng::new()`]. #[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum Tb6612fngError { @@ -40,6 +73,24 @@ pub enum Tb6612fngError { Standby(STBYError), } +impl core::fmt::Display for Tb6612fngError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + use Tb6612fngError::*; + match self { + Standby(_) => write!(f, "failed to set the output of the standby pin"), + } + } +} + +impl Error for Tb6612fngError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + use Tb6612fngError::*; + match self { + Standby(e) => Some(e), + } + } +} + /// Defines the possible drive commands. #[derive(PartialEq, Eq, Debug, Copy, Clone)] pub enum DriveCommand { @@ -89,6 +140,8 @@ where /// /// # Usage example /// ``` + /// + /// # fn main() -> Result<(), Box> { /// # use embedded_hal_mock::eh1::digital::Mock as PinMock; /// # use embedded_hal_mock::eh1::pwm::Mock as PwmMock; /// # use embedded_hal_mock::eh1::pwm::Transaction as PwmTransaction; @@ -113,10 +166,9 @@ where /// # let mut standby_ = standby.clone(); /// /// use tb6612fng::{Motor, Tb6612fng}; - /// /// let controller = Tb6612fng::new( - /// Motor::new(motor_a_in1, motor_a_in2, motor_a_pwm).unwrap(), - /// Motor::new(motor_b_in1, motor_b_in2, motor_b_pwm).unwrap(), + /// Motor::new(motor_a_in1, motor_a_in2, motor_a_pwm)?, + /// Motor::new(motor_b_in1, motor_b_in2, motor_b_pwm)?, /// standby, /// ); /// @@ -127,6 +179,8 @@ where /// # motor_b_in2_.done(); /// # motor_b_pwm_.done(); /// # standby_.done(); + /// # Ok(()) + /// # } /// ``` #[allow(clippy::type_complexity)] pub fn new( From 8ff6c184c5136e90367f1b10bb007a33c24e9a41 Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Mon, 23 Sep 2024 19:04:51 +0200 Subject: [PATCH 11/12] simplify GHA required build settings by adding a single `build-results` job which depends on all other jobs we can simplify the setting of required builds in the repository. currently, all builds - including all variations of the build matrix! - need to be manually specified. once this has been merged the settings can be changed to require only this one job (which will fail if any of the other jobs failed). this way it's also easier to add/remove jobs or change the build matrix as it no longer requires changing the settings on the repository. this is inspired by [this discussion on GH][discussion]. [discussion]: https://github.com/orgs/community/discussions/26822 --- .github/workflows/CI.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2187aed..e38c585 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -92,3 +92,20 @@ jobs: with: sarif_file: rust-clippy-results.sarif wait-for-processing: true + + # simplify GH settings: have one single build to be required + build-results: + name: Final Results + if: ${{ always() }} + runs-on: ubuntu-latest + needs: [lib, stm32f4-single-motor-example, clippy] + steps: + - name: check for failed builds of the library + if: ${{ needs.lib.result != 'success' }} + run: exit 1 + - name: check for failed builds of the example + if: ${{ needs.stm32f4-single-motor-example.result != 'success' }} + run: exit 1 + - name: check for failed clippy builds + if: ${{ needs.clippy.result != 'success' }} + run: exit 1 From 06323a428998414c153cd04359f8035f4671ebff Mon Sep 17 00:00:00 2001 From: Ralph Ursprung Date: Mon, 23 Sep 2024 21:11:31 +0200 Subject: [PATCH 12/12] chore: Release tb6612fng version 1.0.0 --- CHANGELOG.md | 5 ++++- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b544b..ab7294d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate + +## [1.0.0] - 2024-09-23 ### Added * Add a `current_standby()` method to check if the driver is currently in standby mode. @@ -43,5 +45,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 If your HAL does not yet implement this, then please use the previous release of the library. -[Unreleased]: https://github.com/rust-embedded-community/tb6612fng-rs/compare/v0.2.0...HEAD +[Unreleased]: https://github.com/rust-embedded-community/tb6612fng-rs/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/rust-embedded-community/tb6612fng-rs/compare/v0.2.0...v1.0.0 [0.2.0]: https://github.com/rust-embedded-community/tb6612fng-rs/compare/v0.1.1...v0.2.0 diff --git a/Cargo.toml b/Cargo.toml index b15b089..f474c79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tb6612fng" -version = "0.2.0" +version = "1.0.0" edition = "2021" rust-version = "1.81"