nrf-rs / microbit

A Rust crate for BBC micro:bit development
BSD Zero Clause License
276 stars 61 forks source link

Magnetometer examples broken #9

Closed droogmic closed 3 years ago

droogmic commented 6 years ago

All 3 mag3110 examples appear to block before being able to get and print data.

#0  0x00004180 in <nrf51_hal::i2c::I2c<nrf51::TWI1>>::send_byte (self=0x20003e9c, byte=0x20003d7c "\020\000")
    at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/nrf51-hal-0.5.1/src/i2c.rs:88
#1  0x00004ae2 in <nrf51_hal::i2c::I2c<nrf51::TWI1> as embedded_hal::blocking::i2c::Write>::write (self=0x20003e9c, addr=14, bytes=...)
    at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/nrf51-hal-0.5.1/src/i2c.rs:213
#2  0x0000091a in <mag3110::Mag3110<I2C>>::write_register (self=0x20003e9c, reg=mag3110::CTRL_REG1, byte=0)
    at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/mag3110-0.1.3/src/lib.rs:154
#3  0x000007ac in <mag3110::Mag3110<I2C>>::stop_sampling (self=0x20003e9c) at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/mag3110-0.1.3/src/lib.rs:140
#4  0x00000946 in <mag3110::Mag3110<I2C>>::set_sampling_mode (self=0x20003e9c, dr=mag3110::HZ80, ov=mag3110::OV16)
    at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/mag3110-0.1.3/src/lib.rs:110
#5  0x00000bda in <mag3110::Mag3110<I2C>>::new (i2c=...) at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/mag3110-0.1.3/src/lib.rs:103
#6  0x00001706 in i2c_haldriver_printmagserial::main::{{closure}} (cs=0x20003fcc) at examples/i2c_haldriver_printmagserial.rs:80
#7  0x0000285c in cortex_m::interrupt::free (f=...) at /home/droogmic/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.5.2/src/interrupt.rs:69
#8  0x00001242 in i2c_haldriver_printmagserial::main () at examples/i2c_haldriver_printmagserial.rs:47
therealprof commented 6 years ago

Can't confirm. They all work "fine"(*) for me.

(*) The only one that kind of makes sense is the: i2c_hal_printmagserial, the i2c_haldriver_printmagserial waits for an interrupt which never occurs while i2c_direct_printmagserialdelivers exactly one (wonky) result.

droogmic commented 6 years ago

Interesting, I wonder what is different.

droogmic commented 6 years ago

FYI, still occurring, still not sure why:

cargo run --example i2c_hal_printmagserial
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s                                                                                                                
     Running `arm-none-eabi-gdb target/thumbv6m-none-eabi/debug/examples/i2c_hal_printmagserial`
GNU gdb (GDB) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from target/thumbv6m-none-eabi/debug/examples/i2c_hal_printmagserial...done.
Reset () at /home/xxx/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.4/src/lib.rs:494
494     __pre_init();
semihosting is enabled
Loading section .vector_table, size 0xa8 lma 0x0
Loading section .text, size 0x6c20 lma 0xa8
Loading section .rodata, size 0x844 lma 0x6cd0
Start address 0x5ca4, load size 29964
Transfer rate: 9 KB/sec, 7491 bytes/write.
(gdb) break i2c_hal_printmagserial.rs:30
Breakpoint 1 at 0x4c8: file examples/i2c_hal_printmagserial.rs, line 30.
(gdb) continue
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, main () at examples/i2c_hal_printmagserial.rs:30
30      if let Some(p) = microbit::Peripherals::take() {
(gdb) next
31          p.CLOCK.tasks_lfclkstart.write(|w| unsafe { w.bits(1) });
(gdb) 
32          while p.CLOCK.events_lfclkstarted.read().bits() == 0 {}
(gdb) 
32          while p.CLOCK.events_lfclkstarted.read().bits() == 0 {}
(gdb) 
33          p.CLOCK.events_lfclkstarted.write(|w| unsafe { w.bits(0) });
(gdb) 
33          p.CLOCK.events_lfclkstarted.write(|w| unsafe { w.bits(0) });
(gdb) 
35          p.RTC0.prescaler.write(|w| unsafe { w.bits(4095) });
(gdb) 
36          p.RTC0.evtenset.write(|w| w.tick().set_bit());
(gdb) 
37          p.RTC0.intenset.write(|w| w.tick().set_bit());
(gdb) 
38          p.RTC0.tasks_start.write(|w| unsafe { w.bits(1) });
(gdb) 
40          cortex_m::interrupt::free(move |cs| {
(gdb)

# Blocks here
therealprof commented 6 years ago

Guess we'll need to revisit then to make it more reliable.

bodagovsky commented 4 years ago

I have the same problem. First time I ran i2c_hal_printmagserial got only Welcome to the magnetometer reader! Then I tried to play with I2C addresses, and I started to get some values, but all of them were the same and never changed despite of moving the board for example, if i change this let _ = i2c.write(0x19, &[0x33, 0x32]); // let _ = i2c.write(0xE, &[0x11, 0x7f]); and this if i2c.write_read(0x19, &[0x32], &mut data).is_ok() {

I get this


x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107                                                    
x: 13107, y: 13107, z: 13107       ```
therealprof commented 4 years ago

I find it rather likely that this is caused by different sensors used in different revisions of the board. Rev 1.3 (and below) use MAG3110 (cf. https://tech.microbit.org/hardware/previous-revision/), while Rev 1.5 uses LSM303AGR and potentially in the future FXOS8700CQ, cf. https://tech.microbit.org/hardware/

bodagovsky commented 4 years ago

I still can’t get, why I have always the same values? Am I doing something wrong? I am using addresses from here https://tech.microbit.org/hardware/i2c/

therealprof commented 4 years ago

The driver you're using is MAG3110 only, I don't know how much the LSM303AGR register interface differs but it's highly likely to not work with the unmodified MAG3110 driver.

robyoung commented 3 years ago

there is now a magnetometer example that runs on V1.5 and V2