238: Pwm: allow get_duty to return the old value for some time r=therealprof a=eldruin
This is #140 applied to the `Pwm` trait as well, since the same concerns apply. Follows up on #236.
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
PWM is often implemented in a buffered way to allow glitch-free
operation; as a result, implementing a strict "you get what you last
set" is not feasible for some implementations.
236: PwmPin: allow get_duty to return the old value for some time r=therealprof a=eldruin
This is #140 rebased to master.
However, I suppose the same thing applies to the `Pwm::try_get_duty()` method. Shouldn't the same note be added to that method as well?
Closes#140
Co-authored-by: chrysn <chrysn@fsfe.org>
PWM is often implemented in a buffered way to allow glitch-free
operation; as a result, implementing a strict "you get what you last
set" is not feasible for some implementations.
230: Make I2C compatible with multiple address sizes r=ryankurte a=eldruin
This adds I2C 7-bit and 10-bit address mode compatibility as roughly described [here](https://github.com/rust-embedded/embedded-hal/issues/147#issuecomment-511703503).
Discussion issue: #147
I have also added the `SevenBitAddress` as the default address mode to the traits so this is not even a breaking change.
Usage broken down per use case:
* **Device driver which only supports 7-bit addressing mode:**
The driver looks exactly the same as now since the default address mode is 7-bit.
```rust
impl<I2C, E> MyDriver<I2C>
where I2C: i2c::Write<Error = E> {
pub fn do_cool_stuff(&mut self) // ...
}
```
* **Device driver which only supports 10-bit addressing mode:**
The only difference to a 7-bit-address-only driver is one additional parameter in the I2C trait bound.
```rust
impl<I2C, E> MyDriver<I2C>
where I2C: i2c::Write<TenBitAddress, Error = E> {
pub fn do_cool_stuff(&mut self) // ...
}
```
* **Driver for device supporting both addressing modes:**
Complexity can be abstracted away into additional internal traits which can handle the addressing stuff. Driver code stays clean.
**This is nothing new**. We already do this on drivers for devices compatible with both I2C and SPI. No need for duplicated code.
Here a real example: [usage](3af5637f1d/src/device_impl.rs (L43)), [traits](https://github.com/eldruin/bmi160-rs/blob/master/src/interface.rs)
```rust
impl<DI, E> MyDriver<DI>
where DI: WriteData<Error = E> {
pub fn do_cool_stuff(&mut self) {} // ...
}
pub trait WriteData {
// ...
}
// it is also possible to just leave the `SevenBitAddress` type out here,
// since it is the default.
impl<I2C, E> WriteData for I2cInterface<I2C, SevenBitAddress>
where
I2C: i2c::Write<SevenBitAddress, Error = E>,
{
// ...
}
impl<I2C, E> WriteData for I2cInterface<I2C, TenBitAddress>
where
I2C: i2c::Write<TenBitAddress, Error = E>,
{
// ...
}
```
* **Bus controller impl supporting only 7-bit addressing mode:**
Code stays almost the same, just adding one addressing mode parameter. Additionally, _if desired_:
* 10-bit addressing can be software-emulated:
Emulate by extending and copying payload in separate `TenBitAddress` implementation. Total flexibility to do whatever is necessary in this case since the code is independent.
* 10-bit addressing cannot be software-emulated:
Implementation does not offer implementation for `TenBitAddress` variant. The user gets a compilation error and everything is clear.
* **Bus controller impl supporting both addressing modes:**
No problem. Two separate implementations guarantee as much flexibility as necessary. At the same time, sharing generic code is possible.
Additional benefits:
* No runtime performance cost
* No runtime switching, duplicated code or panics for unsupported modes.
* Consistent with what we do for code paths that can be determined statically by the compiler.
* To my taste elegant, simple and very descriptive.
See [here](https://github.com/rust-embedded/embedded-hal/issues/147#issuecomment-647157906) for a comparison to other alternatives.
I have also sealed the trait.
## Proof
* A HAL implementation of both modes: [bitbang-hal](https://github.com/eldruin/bitbang-hal/tree/i2c-multi-address-mode). [code changes](https://github.com/eldruin/bitbang-hal/compare/embedded-hal-1.0.0-alpha.1...eldruin:i2c-multi-address-mode)
* Drivers supporting only 7-bit addresses need **no changes**.
For demonstration purposes, explicitly including the `SevenBitAddress` would look like this: [OPT300x](https://github.com/eldruin/opt300x-rs/tree/i2c-multi-address-mode). [code changes](https://github.com/eldruin/opt300x-rs/compare/i2c-multi-address-mode).
This would be similar to the case of a 10-bit-only device driver.
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
222: Improve watchdog API design using move semantics r=therealprof a=luojia65
This pull request improved watchdog API design. When starting watchdog, we may convert it into another type. We may implement different functions for this type. Or downstream developers can implement `Watchdog` for only an enabled type, to prevent feed to disabled watchdogs or forget to enable before feeding. If we are able to stop this watchdog, it can be converted into the former type.
If current design still need a same type after the watchdog is enabled, they may use `Target = Self`. In this way we create a fallback for earlier designs.
A simple proof of concept: [here](https://github.com/gd32v-rust/gd32vf103-hal/blob/new-watchdog-design/src/wdog.rs#L155-L169) (L120-L153 for its `Enable` implementation, and there is `Disable` implementation)
Related issue: https://github.com/rust-embedded/embedded-hal/issues/98
Earlier discussion: https://github.com/rust-embedded/embedded-hal/pull/76#issuecomment-417413406
Co-authored-by: luojia65 <me@luojia.cc>
Co-authored-by: Luo Jia <account@luojia.cc>
228: Standardize address wording r=therealprof a=eldruin
For consistency.
Credit goes to @BroderickCarlin for noticing in #147.
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
219: v1.0.0 alpha release r=therealprof a=ryankurte
🎉🎊🥳
See #177 for progress on blocking issues
Co-authored-by: ryan kurte <ryankurte@gmail.com>
Co-authored-by: Daniel Egger <daniel@eggers-club.de>
221: Enable doctests and fix them r=therealprof a=eldruin
I discovered that due to a typo some doctests were not being run.
A couple small fixes were also necessary for them to compile.
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
216: Switch from Travis to GitHub actions r=ryankurte a=therealprof
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
Co-authored-by: Daniel Egger <daniel@eggers-club.de>
217: Restrict ADC ID type to Copy types r=ryankurte a=therealprof
This fixes a deny-by-default clippy lint:
```
error: a `const` item should never be interior mutable
--> src/adc.rs:47:5
|
47 | const CHANNEL: Self::ID;
| ^^^^^^^^^^^^^^^--------^
| |
| consider requiring `<Self as adc::Channel<ADC>>::ID` to be `Copy`
|
= note: `#[deny(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
```
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
Co-authored-by: Daniel Egger <daniel@eggers-club.de>
This fixes a deny-by-default clippy lint:
```
error: a `const` item should never be interior mutable
--> src/adc.rs:47:5
|
47 | const CHANNEL: Self::ID;
| ^^^^^^^^^^^^^^^--------^
| |
| consider requiring `<Self as adc::Channel<ADC>>::ID` to be `Copy`
|
= note: `#[deny(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
```
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
198: Add MSRV configuration to CI r=therealprof a=eldruin
The compatibility with the MSRV should be checked by the CI. At the moment that is Rust 1.35.0 due to [this issue](https://github.com/rust-lang/rust/issues/54973).
The MSRV and its update process should probably also be documented in the README.
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
195: Separate Capture, Pwm and Qei traits into modules r=ryankurte a=eldruin
The `lib.rs` file is already _very_ long. I propose separating these traits which are just at the end of the file into their own modules.
I have kept the modules private and reexported the traits and types to maintain the same interface.
However, for consistency with the other traits maybe it would be worth it to expose these new modules as well and not reexport the traits in `lib.rs`.
What do you think?
Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>