|
| 1 | +//! I2C Fast Mode Plus example with an AS5600 magnetic angle sensor. |
| 2 | +//! |
| 3 | +//! This example expects the AS5600 to be connected to the I2C bus on PB7 (SDA) and PA15 (SCL), |
| 4 | +//! and a 24MHz HSE oscillator to configure the PLL for 168MHz system clock. |
| 5 | +//! |
| 6 | +//! The I2C bus is configured with Fast Mode Plus (FMP) enabled in SysCfg, and a 1MHz I2C clock rate. |
| 7 | +//! |
| 8 | +//! ```DEFMT_LOG=debug cargo run --release --example rand --features stm32g431,defmt -- --chip STM32G431KBTx``` |
| 9 | +
|
| 10 | +#![deny(warnings)] |
| 11 | +#![deny(unsafe_code)] |
| 12 | +#![no_main] |
| 13 | +#![no_std] |
| 14 | + |
| 15 | +use fugit::HertzU32 as Hertz; |
| 16 | +use hal::prelude::*; |
| 17 | +use hal::rcc::SysClockSrc; |
| 18 | +use hal::stm32; |
| 19 | +use hal::time::RateExtU32; |
| 20 | +use stm32g4xx_hal as hal; |
| 21 | +use stm32g4xx_hal::syscfg::SysCfgExt; |
| 22 | + |
| 23 | +use as5600::As5600; |
| 24 | +use cortex_m_rt::entry; |
| 25 | + |
| 26 | +#[macro_use] |
| 27 | +mod utils; |
| 28 | +use utils::logger::error; |
| 29 | +use utils::logger::info; |
| 30 | + |
| 31 | +#[entry] |
| 32 | +fn main() -> ! { |
| 33 | + utils::logger::init(); |
| 34 | + |
| 35 | + let dp = stm32::Peripherals::take().expect("cannot take peripherals"); |
| 36 | + //let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals"); |
| 37 | + |
| 38 | + let pwr_cfg = dp |
| 39 | + .PWR |
| 40 | + .constrain() |
| 41 | + .vos(stm32g4xx_hal::pwr::VoltageScale::Range1 { enable_boost: true }) |
| 42 | + .freeze(); |
| 43 | + |
| 44 | + let pll_cfg = hal::rcc::PllConfig { |
| 45 | + mux: hal::rcc::PllSrc::HSE(Hertz::MHz(24)), |
| 46 | + m: hal::rcc::PllMDiv::DIV_2, |
| 47 | + n: hal::rcc::PllNMul::MUL_28, |
| 48 | + r: Some(hal::rcc::PllRDiv::DIV_2), |
| 49 | + q: None, |
| 50 | + p: None, |
| 51 | + }; |
| 52 | + |
| 53 | + info!("Configuring PLL"); |
| 54 | + let rcc_cfg = hal::rcc::Config::new(SysClockSrc::PLL) |
| 55 | + .boost(true) |
| 56 | + .pll_cfg(pll_cfg); |
| 57 | + |
| 58 | + let mut rcc = dp.RCC.freeze(rcc_cfg, pwr_cfg); |
| 59 | + info!("System clock frequency: {}", rcc.clocks.sys_clk.to_Hz()); |
| 60 | + |
| 61 | + let gpioa = dp.GPIOA.split(&mut rcc); |
| 62 | + let gpiob = dp.GPIOB.split(&mut rcc); |
| 63 | + |
| 64 | + let sda = gpiob.pb7.into_alternate_open_drain(); |
| 65 | + let scl = gpioa.pa15.into_alternate_open_drain(); |
| 66 | + |
| 67 | + let mut syscfg = dp.SYSCFG.constrain(&mut rcc); |
| 68 | + |
| 69 | + // Enable Fast Mode Plus for I2C1 |
| 70 | + syscfg.i2c_fmp_enable::<1>(true); |
| 71 | + |
| 72 | + // Configure I2C for 1MHz |
| 73 | + let i2c = dp.I2C1.i2c(sda, scl, 1.MHz(), &mut rcc); |
| 74 | + |
| 75 | + let mut as5600 = As5600::new(i2c); |
| 76 | + |
| 77 | + loop { |
| 78 | + match as5600.angle() { |
| 79 | + Ok(angle) => { |
| 80 | + // Convert angle to degrees |
| 81 | + let angle_degrees = angle as f32 * 360.0 / 4096.0; |
| 82 | + info!("Angle: {}°", angle_degrees); |
| 83 | + } |
| 84 | + Err(e) => match e { |
| 85 | + as5600::error::Error::Communication(_) => error!("I2C communication error"), |
| 86 | + as5600::error::Error::Status(_error) => error!("AS5600 status error"), |
| 87 | + as5600::error::Error::Configuration(_error) => error!("AS5600 configuration error"), |
| 88 | + _ => error!("Other AS5600 error"), |
| 89 | + }, |
| 90 | + } |
| 91 | + } |
| 92 | +} |
0 commit comments