rust-embedded / discovery

Discover the world of microcontrollers through Rust!
https://docs.rust-embedded.org/discovery/
Apache License 2.0
1.47k stars 511 forks source link

[15-led-compass] LSM303AGR board version aux15::init() not working? #334

Open dcabanis opened 3 years ago

dcabanis commented 3 years ago

Hi all,

I am running the lab 15 with a DISCOVERY board bought in 2021. it has the LSM303AGR eCompass chip on it as opposed to the original board's LSM303DLHC.

As I am building the starter code and the solution code, all passes without any errors but when I try to run the examples the X, Y, Z are always set to 0.

I have the feeling that the aux15::init() function isn't properly initializing the device. Is anyone encountering the same issue with the latest board?

Cheers.

eisnstein commented 3 years ago

As it states in 14.2, you have to check out this issue regarding the LSM303AGR #274. I also just started with 15 and so far I got the very first example running.

  1. add lsm303agr = "0.1" to the dependencies in your 15-led-compass/auxiliary/Cargo.toml so that it looks like this:
    
    [package]
    authors = ["Jorge Aparicio <jorge@japaric.io>"]
    edition = "2018"
    name = "aux15"
    version = "0.1.0"

[dependencies] cortex-m = "=0.5.6" cortex-m-rt = "0.6.3" panic-itm = "=0.4.0" lsm303agr = "0.1"

[dependencies.f3] features = ["rt"] version = "0.6.1"


2. Change the `15-led-compass/auxiliary/src/lib.rs` to use the lsm303agr instead of the lsm303dlhc:

//! Initialization code

![no_std]

[allow(unused_extern_crates)] // NOTE(allow) bug rust-lang/rust#53964

extern crate panic_itm; // panic handler

pub use cortex_m::{asm::bkpt, iprint, iprintln, peripheral::ITM}; pub use cortex_m_rt::entry; pub use f3::{ hal::{ delay::Delay, gpio::gpiob::PB6, gpio::gpiob::PB7, gpio::AF4, prelude, stm32f30x::i2c1, stm32f30x::I2C1, }, led::{Direction, Leds}, lsm303dlhc::I16x3, }; pub use lsm303agr::{ UnscaledMeasurement };

use f3::{ hal::{i2c::I2c, prelude::*, stm32f30x}, Lsm303dlhc, };

use lsm303agr::{interface::I2cInterface, mode, Lsm303agr, MagOutputDataRate};

pub fn init() -> (Leds, Lsm303agr<I2cInterface<I2c<I2C1, (PB6, PB7)>>, mode::MagContinuous>, Delay, ITM) { let cp = cortex_m::Peripherals::take().unwrap(); let dp = stm32f30x::Peripherals::take().unwrap();

let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();

let clocks = rcc.cfgr.freeze(&mut flash.acr);

let gpioe = dp.GPIOE.split(&mut rcc.ahb);
let leds = Leds::new(gpioe);

let mut gpiob = dp.GPIOB.split(&mut rcc.ahb);
let scl = gpiob.pb6.into_af4(&mut gpiob.moder, &mut gpiob.afrl);
let sda = gpiob.pb7.into_af4(&mut gpiob.moder, &mut gpiob.afrl);

let i2c = I2c::i2c1(dp.I2C1, (scl, sda), 400.khz(), clocks, &mut rcc.apb1);

let mut lsm = Lsm303agr::new_with_i2c(i2c);
lsm.init().unwrap();
lsm.set_mag_odr(MagOutputDataRate::Hz10).unwrap();
let lsm303agr = lsm.into_mag_continuous().ok().unwrap();

let delay = Delay::new(cp.SYST, clocks);

(leds, lsm303agr, delay, cp.ITM)

}


3. Use the lsm303agr in the `15-led-compass/src/main.rs` like this:

![deny(unsafe_code)]

![no_main]

![no_std]

[allow(unused_imports)]

use aux15::{entry, iprint, iprintln, prelude::*, UnscaledMeasurement}; use aux15::Direction;

[entry]

fn main() -> ! { let (mut leds, mut lsm303agr, mut delay, mut itm) = aux15::init();

loop {
    let status = lsm303agr.mag_status().unwrap();
    if status.xyz_new_data {
        let data = lsm303agr.mag_data().unwrap();
        iprintln!(&mut itm.stim[0], "{:?}", data);
    }

    delay.delay_ms(1_000_u16);
}

}



Hope this helps.
NitinSaxenait commented 3 years ago

Hi, @eisnstein I am also working on the same Chapter of Discovery Book. I was too stuck because of this lsm303dlhc & lsm303agr but your solution really helped me. I have successfully completed the Take 1. I have one doubt in the src/main.rs if status.xyz_new_data { let data = lsm303agr.mag_data().unwrap(); iprintln!(&mut itm.stim[0], "{:?}", data); } I know we are reading the data from the Magnetometer's register using let status = lsm303agr.mag_status().unwrap(); but what we are doing with the if block here? what is this status.xyz_newdata is doing here?? Thanks.