Implement conversion from Clock to Hertz using reference

Implementing `impl From<SystemClock> for Hertz` is a footgun, as
SystemClock is not Copy, so the automatic conversion consumes the
owned clock.

This is visible in the example i2c.rs:

```
    let mut i2c = hal::I2C::i2c1(
        pac.I2C1,
        sda_pin,
        scl_pin, // Try `not_an_scl_pin` here
        400.kHz(),
        &mut pac.RESETS,
        clocks.peripheral_clock,
    );
```

If the user wants to use both `i2c0` and `i2c1` at the same time,
copying from this example won't work:

```
error[E0382]: use of moved value: `clocks.peripheral_clock`
   --> rp2040-hal/examples/i2c.rs:106:9
    |
97  |         clocks.peripheral_clock,
    |         ----------------------- value moved here
...
106 |         clocks.peripheral_clock,
    |         ^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
    |
    = note: move occurs because `clocks.peripheral_clock` has type
`PeripheralClock`, which does not implement the `Copy` trait
```

As getting the frequency from a clock doesn't really need ownership,
changing it to `impl From<&SystemClock> for Hertz` is both more
logical and provides better usability.

This is, however, a breaking change: Code relying on this trait
implementation needs to be changed by adding a `&`.
This commit is contained in:
Jan Niehusmann 2022-07-22 19:31:10 +00:00
parent 69c2dd2c2b
commit f8984a9eac
10 changed files with 14 additions and 11 deletions

View file

@ -134,7 +134,7 @@ fn main() -> ! {
scl_pin, scl_pin,
400.kHz(), 400.kHz(),
&mut pac.RESETS, &mut pac.RESETS,
clocks.peripheral_clock, &clocks.peripheral_clock,
); );
// Create the I²C display interface: // Create the I²C display interface:

View file

@ -98,7 +98,7 @@ fn main() -> ! {
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable( .enable(
hal::uart::common_configs::_115200_8_N_1, hal::uart::common_configs::_115200_8_N_1,
clocks.peripheral_clock.into(), clocks.peripheral_clock.freq(),
) )
.unwrap(); .unwrap();

View file

@ -138,7 +138,7 @@ fn main() -> ! {
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable( .enable(
hal::uart::common_configs::_9600_8_N_1, hal::uart::common_configs::_9600_8_N_1,
clocks.peripheral_clock.into(), clocks.peripheral_clock.freq(),
) )
.unwrap(); .unwrap();

View file

@ -122,7 +122,7 @@ fn main() -> ! {
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable( .enable(
hal::uart::common_configs::_9600_8_N_1, hal::uart::common_configs::_9600_8_N_1,
clocks.peripheral_clock.into(), clocks.peripheral_clock.freq(),
) )
.unwrap(); .unwrap();

View file

@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Update embedded-hal alpha support to version 1.0.0-alpha.8 - Update embedded-hal alpha support to version 1.0.0-alpha.8
- Implement `From<&SomeClock> for Hertz` instead of `From<SomeClock> for Hertz`
for the clocks in `rp2040_hal::clocks`.
## [0.5.0] - 2022-06-13 ## [0.5.0] - 2022-06-13

View file

@ -94,7 +94,7 @@ fn main() -> ! {
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable( .enable(
hal::uart::common_configs::_9600_8_N_1, hal::uart::common_configs::_9600_8_N_1,
clocks.peripheral_clock.into(), clocks.peripheral_clock.freq(),
) )
.unwrap(); .unwrap();

View file

@ -89,7 +89,7 @@ fn main() -> ! {
scl_pin, // Try `not_an_scl_pin` here scl_pin, // Try `not_an_scl_pin` here
400.kHz(), 400.kHz(),
&mut pac.RESETS, &mut pac.RESETS,
clocks.peripheral_clock, &clocks.peripheral_clock,
); );
// Write three bytes to the I²C device with 7-bit address 0x2C // Write three bytes to the I²C device with 7-bit address 0x2C

View file

@ -25,6 +25,7 @@ use hal::pac;
// Some traits we need // Some traits we need
use core::fmt::Write; use core::fmt::Write;
use hal::Clock;
/// The linker will place this boot block at the start of our program image. We /// The linker will place this boot block at the start of our program image. We
/// need this to help the ROM bootloader get our code up and running. /// need this to help the ROM bootloader get our code up and running.
@ -89,7 +90,7 @@ fn main() -> ! {
let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS) let mut uart = hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable( .enable(
hal::uart::common_configs::_9600_8_N_1, hal::uart::common_configs::_9600_8_N_1,
clocks.peripheral_clock.into(), clocks.peripheral_clock.freq(),
) )
.unwrap(); .unwrap();

View file

@ -417,9 +417,9 @@ macro_rules! base_clock {
impl Sealed for $name {} impl Sealed for $name {}
impl From<$name> for Hertz impl From<&$name> for Hertz
{ {
fn from(value: $name) -> Hertz { fn from(value: &$name) -> Hertz {
value.frequency value.frequency
} }
} }

View file

@ -6,7 +6,7 @@
//! //!
//! See [examples/uart.rs](https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal/examples/uart.rs) for a more complete example //! See [examples/uart.rs](https://github.com/rp-rs/rp-hal/tree/main/rp2040-hal/examples/uart.rs) for a more complete example
//! ```no_run //! ```no_run
//! use rp2040_hal::{clocks::init_clocks_and_plls, gpio::{Pins, FunctionUart}, pac, sio::Sio, uart::{self, UartPeripheral}, watchdog::Watchdog}; //! use rp2040_hal::{Clock, clocks::init_clocks_and_plls, gpio::{Pins, FunctionUart}, pac, sio::Sio, uart::{self, UartPeripheral}, watchdog::Watchdog};
//! //!
//! const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // Typically found in BSP crates //! const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // Typically found in BSP crates
//! //!
@ -25,7 +25,7 @@
//! let uart = UartPeripheral::new(peripherals.UART0, pins, &mut peripherals.RESETS) //! let uart = UartPeripheral::new(peripherals.UART0, pins, &mut peripherals.RESETS)
//! .enable( //! .enable(
//! uart::common_configs::_9600_8_N_1, //! uart::common_configs::_9600_8_N_1,
//! clocks.peripheral_clock.into(), //! clocks.peripheral_clock.freq(),
//! ).unwrap(); //! ).unwrap();
//! //!
//! uart.write_full_blocking(b"Hello World!\r\n"); //! uart.write_full_blocking(b"Hello World!\r\n");