While learning Rust and embedded programming I have accumulated a set of examples that I am trying to keep working with new HAL releases. I have been using a setup() function to specify pins and parameters for the settings of peripherals. This works but does not scale well as the number of examples grows. I would like to encapsulate parts of the setup in different functions so I can use some pieces for one example and mix those with other pieces in other examples. The code below illustrates the problem. In this example I need both i2c1 and i2c2 while in many other examples I use only i2c1. I have functions setup_i2c1 and setup_i2c2 but I cannot get around the move problem.
The code does not compile:
move occurs because `gpiob` has type `stm32f1xx_hal::gpio::gpiob::Parts`, which does not implement the `Copy` trait
In the function setup_i2c1_i2c2_led_delay_using_dp if I replace calls to setup_i2c1 and setup_i2c2 with the code in those functions (commented out) then it does compile. But then I have to repeat all that code in several examples.
I have also tried passing the whole device peripheral as &mut dp to each setup and then using * de-referencing in the function. This approach I can make work with simpler objects but in the case of dp I only get to
cannot move out of `gpiob.pb8` which is behind a mutable reference
Any suggestions for how to achieve this subdivision of the setup would be appreciated.
Click to expand
#! Example using two i2c buses on bluepill
#![deny(unsafe_code)]
#![no_std]
#![no_main]
use aht10::AHT10;
#[cfg(debug_assertions)]
use panic_semihosting as _;
#[cfg(not(debug_assertions))]
use panic_halt as _;
use cortex_m_rt::entry;
use core::fmt::Write;
//use cortex_m_semihosting::hprintln;
use embedded_graphics::{
mono_font::{ascii::FONT_5X8 as FONT, MonoTextStyleBuilder},
pixelcolor::BinaryColor,
prelude::*,
text::{Baseline, Text},
};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use stm32f1xx_hal::{
timer::Delay,
i2c::{BlockingI2c, DutyCycle, Mode},
pac::{Peripherals, TIM2, I2C1, I2C2},
gpio::{gpiob::{PB8, PB9, PB10, PB11, Parts},
gpioc::{PC13, Parts as PartsC},
Alternate, OpenDrain, Output, PushPull},
afio::Parts as afioParts,
rcc::Clocks,
prelude::*
};
pub type I2c1Type = BlockingI2c>, PB9>)>;
pub type I2c2Type = BlockingI2c>, PB11>)>;
pub type DelayType = Delay;
pub type LedType = PC13
(Somewhat related to #24, #305, and #313.)
While learning Rust and embedded programming I have accumulated a set of examples that I am trying to keep working with new HAL releases. I have been using a
setup()
function to specify pins and parameters for the settings of peripherals. This works but does not scale well as the number of examples grows. I would like to encapsulate parts of the setup in different functions so I can use some pieces for one example and mix those with other pieces in other examples. The code below illustrates the problem. In this example I need bothi2c1
andi2c2
while in many other examples I use onlyi2c1
. I have functionssetup_i2c1
andsetup_i2c2
but I cannot get around the move problem.The code does not compile:
In the function
setup_i2c1_i2c2_led_delay_using_dp
if I replace calls tosetup_i2c1
andsetup_i2c2
with the code in those functions (commented out) then it does compile. But then I have to repeat all that code in several examples.I have also tried passing the whole device peripheral as
&mut dp
to each setup and then using*
de-referencing in the function. This approach I can make work with simpler objects but in the case ofdp
I only get toAny suggestions for how to achieve this subdivision of the setup would be appreciated.
Click to expand
#! Example using two i2c buses on bluepill #![deny(unsafe_code)] #![no_std] #![no_main] use aht10::AHT10; #[cfg(debug_assertions)] use panic_semihosting as _; #[cfg(not(debug_assertions))] use panic_halt as _; use cortex_m_rt::entry; use core::fmt::Write; //use cortex_m_semihosting::hprintln; use embedded_graphics::{ mono_font::{ascii::FONT_5X8 as FONT, MonoTextStyleBuilder}, pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}, }; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; use stm32f1xx_hal::{ timer::Delay, i2c::{BlockingI2c, DutyCycle, Mode}, pac::{Peripherals, TIM2, I2C1, I2C2}, gpio::{gpiob::{PB8, PB9, PB10, PB11, Parts}, gpioc::{PC13, Parts as PartsC}, Alternate, OpenDrain, Output, PushPull}, afio::Parts as afioParts, rcc::Clocks, prelude::* }; pub type I2c1Type = BlockingI2c