I would like to initialize a basic output GPIO pin on my blue pill board. I am using Rust and the stm32f1xx_hal crate. I want to create a struct Peripherals which holds the handle to the output in the following way:
use cortex_m_rt;
use stm32f1xx_hal::{
pac,
prelude::*,
gpio,
afio,
serial::{Serial, Config},
};
use crate::pac::{USART1};
type GpioOutput = gpio::gpioc::PC13<gpio::Output<gpio::PushPull>>;
pub struct Peripherals{
led: Option<GpioOutput>
}
impl Peripherals {
fn init() -> Peripherals {
let dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::Peripherals::take().unwrap();
// set clock frequency to internal 8mhz oscillator
let mut rcc = dp.RCC.constrain();
let mut flash = dp.FLASH.constrain();
let clocks = rcc.cfgr.sysclk(8.mhz()).freeze(&mut flash.acr);
// access PGIOC registers
let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
return Peripherals{
led: Peripherals::init_led(&mut gpioc)
}
}
fn init_led(gpioc: &mut gpio::gpioc::Parts) -> Option<GpioOutput> {
let led = &gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
return Some(led);
}
}
This code does not work, since init_led returns Option<&GpioOutput>. Now I am wondering if it makes sense to use a lifetime parameter in the Peripherals struct and store a reference to the GpioOutput within the struct. Or is it more sensible to store the unreferenced value - and how would I implement either of these options?
The only solution which seems to work is moving the init_led code to the scope of the init function:
return Peripherals{
led: Some(gpioc.pc13.into_push_pull_output(&mut gpioc.crh))
}
But i would like to seperate that code within its own function. How can i do that?
Ok, i figured out a way in case someone else is having the same problem:
I am just wondering if this is the correct way to do it or will it create extra overhead, because i am passing gpioc by value instead of by reference in the init_led function?