Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BusError(Nack) for stm32l475 #4

Open
tasosxak opened this issue Jun 4, 2019 · 32 comments
Open

BusError(Nack) for stm32l475 #4

tasosxak opened this issue Jun 4, 2019 · 32 comments

Comments

@tasosxak
Copy link

tasosxak commented Jun 4, 2019

Hi guys,
I tried to use this driver with RTFM for stm32l475 (the Discovery kit for IoT node, stm32l4) and i get BusError(Nack):

let scl = gpiob.pb10.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    let sda = gpiob.pb11.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
       
    let i2c = I2c::i2c2(
           dp.I2C2,
           (scl,sda),
           400.khz(),
           rcc.cfgr.freeze(&mut flash.acr),
          &mut rcc.apb1r1
           );

    let mut dis  = VL53L0x::new(i2c);

    let diss : vl53l0x::VL53L0x<hal::i2c::I2c<hal::stm32::I2C2, 
    (hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF4, 
    hal::gpio::Output<hal::gpio::OpenDrain>>>, 
    hal::gpio::gpiob::PB11<hal::gpio::Alternate<hal::gpio::AF4,
    hal::gpio::Output<hal::gpio::OpenDrain>>>)>>;

    match dis {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(o) => diss = o,
    }

openocd session:

...
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20018000, semihosting
Warn : block write succeeded
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1362). Workaround: increase "set remotetimeout" in GDB
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08017288 msp: 0x20018000, semihosting
BusError(Nack)

Any idea what is wrong?

@bofh
Copy link
Member

bofh commented Jun 4, 2019

Nobody answered on a bus. I've read the documentation and it seems that they configured i2c address differently (from 7.15 I2C addresses of modules used on MB1297). Try to change it here: https://github.com/copterust/vl53l0x/blob/master/src/lib.rs#L21

@hargoniX
Copy link

hargoniX commented Jun 4, 2019

But the manual says that the read address is 0x52 and the write one is 0x53 which comes down to
0b101001x (x for read or write bit) which is exactly the address you are using at the moment inside your code isnt it?

@bofh
Copy link
Member

bofh commented Jun 4, 2019

True, can you use any other device on that i2c?

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

Yes magnetometer , but no hts221 (nack error)

@bofh
Copy link
Member

bofh commented Jun 4, 2019

Another idea -- they have VL53L0X_XSHUT connected, maybe it is pulled to off?

@bofh
Copy link
Member

bofh commented Jun 4, 2019

Xshutdown pin, Active LOW -- so try to output high on the corresponding pin.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

According to this: PC6 -- GPIO_Output -- VL53L0X_XSHUT. So configure it as an output and set to high.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

Also add the delay for 1.2ms after pin rise (it's the boot time of vl.)

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

let mut pin = gpioc.pc6.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper);
    pin.set_high();
    
    
    for i in 1..50000 {}
    
    let scl = gpiob.pb10.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    let sda = gpiob.pb11.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    

    let i2c = I2c::i2c2(
           dp.I2C2,
           (scl,sda),
           400.khz(),
           rcc.cfgr.freeze(&mut flash.acr),
          &mut rcc.apb1r1
           );
  
    //let mut mg = Lis3mdl::new(i2c).unwrap();
    let mut dis  = VL53L0x::new(i2c);

    let diss : vl53l0x::VL53L0x<hal::i2c::I2c<hal::stm32::I2C2, 
    (hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF4, 
    hal::gpio::Output<hal::gpio::OpenDrain>>>, 
    hal::gpio::gpiob::PB11<hal::gpio::Alternate<hal::gpio::AF4,
    hal::gpio::Output<hal::gpio::OpenDrain>>>)>>;
    match dis {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(o) => diss = o,
    }

Because rtfm takes ownership of SySTick , i add a for loop for the delay.
But i get the same message "BussError(Nack)"

@bofh
Copy link
Member

bofh commented Jun 4, 2019

I wonder if it compiles or that loop just got optimized out?

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

the message however does appear after some seconds

@little-arhat
Copy link
Member

@tasosxak you can also use Delay implementation based on cortex-m::asm::delay: http://github.com/copterust/asm-delay.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

@tasosxak Let’s check if it is a driver problem or something else. Can you try something like:

const ADDRESS: u8 = 0x29;
let mut data: [u8; 1] = [0];
i2c.write_read(ADDRESS, &[0xC0], &mut data)?;

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

@tasosxak you can also use Delay implementation based on cortex-m::asm::delay: http://github.com/copterust/asm-delay.

let mut pin = gpioc.pc6.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper);
    pin.set_high();
    
    
    let d = AsmDelay::new(64_000_000); // 64Mhz
    d.delay_ms(2);
    
    let scl = gpiob.pb10.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    let sda = gpiob.pb11.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    

    let i2c = I2c::i2c2(
           dp.I2C2,
           (scl,sda),
           400.khz(),
           rcc.cfgr.freeze(&mut flash.acr),
          &mut rcc.apb1r1
           );
  
    //let mut mg = Lis3mdl::new(i2c).unwrap();
    let mut dis  = VL53L0x::new(i2c);

    let diss : vl53l0x::VL53L0x<hal::i2c::I2c<hal::stm32::I2C2, 
    (hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF4, 
    hal::gpio::Output<hal::gpio::OpenDrain>>>, 
    hal::gpio::gpiob::PB11<hal::gpio::Alternate<hal::gpio::AF4,
    hal::gpio::Output<hal::gpio::OpenDrain>>>)>>;
    match dis {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(o) => diss = o,
    }

Compiler error:

error[E0277]: the trait bound `bitrate::Hertz<u32>: core::convert::From<u32>` is not satisfied
  --> src/main.rs:92:13
   |
92 |     let d = AsmDelay::new(64_000_000u32); // 64Mhz
   |             ^^^^^^^^^^^^^ the trait `core::convert::From<u32>` is not implemented for `bitrate::Hertz<u32>`
   |
   = note: required because of the requirements on the impl of `core::convert::Into<bitrate::Hertz<u32>>` for `u32`
   = note: required by `asm_delay::AsmDelay::new

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

@tasosxak Let’s check if it is a driver problem or something else. Can you try something like:

const ADDRESS: u8 = 0x29;
let mut data: [u8; 1] = [0];
i2c.write_read(ADDRESS, &[0xC0], &mut data)?;
 let mut pin = gpioc.pc6.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper);
    pin.set_high();
    
    for i in 1..5000 {}
   // let d = AsmDelay::new(64_000_000u32); // 64Mhz
   // d.delay_ms(2);
    
    let scl = gpiob.pb10.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    let sda = gpiob.pb11.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    

    let mut i2c = I2c::i2c2(
           dp.I2C2,
           (scl,sda),
           400.khz(),
           rcc.cfgr.freeze(&mut flash.acr),
          &mut rcc.apb1r1
           );
    
    const ADDRESS: u8 = 0x29; 
    let mut data: [u8; 1] = [0]; 
    let mut x = i2c.write_read(ADDRESS, &[0xC0], &mut data);
    match x {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(_) => hprintln!("its ok").unwrap(),
    }
  
    //let mut mg = Lis3mdl::new(i2c).unwrap();
    let mut dis  = VL53L0x::new(i2c);

    let diss : vl53l0x::VL53L0x<hal::i2c::I2c<hal::stm32::I2C2, 
    (hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF4, 
    hal::gpio::Output<hal::gpio::OpenDrain>>>, 
    hal::gpio::gpiob::PB11<hal::gpio::Alternate<hal::gpio::AF4,
    hal::gpio::Output<hal::gpio::OpenDrain>>>)>>;
    match dis {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(o) => diss = o,
    }

openocd output:

Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1402). Workaround: increase "set remotetimeout" in GDB
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08017a58 msp: 0x20018000, semihosting
Nack
BusError(Nack)

@little-arhat
Copy link
Member

Docs of asmdelay should be updated, I guess.

AsmDelay uses bitrate crate, so you should do use bitrate::* and then AsmDelay::new(65.mhz()).

Alternatevely, you could use just cortex-m::asm::delay, but that one accepts cycle count.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

@tasosxak so it looks like a problem on a bus. I'm still 98% sure that an empty for loop will be removed by the compiler so please try reading who_am_i register after the delay implemented via AsmDelay, or cortex_m::asm::delay.

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

extern crate panic_semihosting;
extern crate stm32l4xx_hal as hal;
extern crate hts221;
extern crate lis3mdl;
extern crate vl53l0x;
extern crate embedded_hal;

use cortex_m_semihosting::hprintln;
use rtfm::{app, Instant};
use hts221::Builder;
//use stm32l4xx_hal::rcc::RccExt;
//use stm32l4xx_hal::gpio::GpioExt;
//use stm32l4::stm32l4x5::interrupt;
use stm32l4xx_hal::i2c::SdaPin;
use stm32l4xx_hal::i2c::SclPin;
use stm32l4xx_hal::i2c::Error;
use stm32l4xx_hal::i2c::I2c;
use stm32l4xx_hal::stm32::I2C2;
//use stm32l4xx_hal::flash::FlashExt;
//use stm32l4xx_hal::time::U32Ext;
//use hal::delay::Delay;
//use hal::prelude::*;
use lis3mdl::Lis3mdl;
use vl53l0x::VL53L0x;
//use embedded_hal::prelude::*;
//use asm_delay::AsmDelay;
use bitrate::*;
error[E0034]: multiple applicable items in scope
  --> src/main.rs:94:30
   |
94 |     let d = AsmDelay::new(65.mhz()); // 64Mhz
   |                              ^^^ multiple `mhz` found

I really i dont know why i get this error

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

I tried "cortex_m::asm::delay;" so now :

let mut pin = gpioc.pc6.into_push_pull_output(&mut gpioc.moder, &mut gpioc.otyper);
    pin.set_high();
    
    //for i in 1..5000 {}
    //let d = AsmDelay::new(65.mhz()); // 64Mhz
    //d.delay_ms(2);
    delay(80000) ;
    
    let scl = gpiob.pb10.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    let sda = gpiob.pb11.into_open_drain_output(&mut gpiob.moder, &mut gpiob.otyper).into_af4(&mut gpiob.moder, &mut gpiob.afrh);
    

    let mut i2c = I2c::i2c2(
           dp.I2C2,
           (scl,sda),
           400.khz(),
           rcc.cfgr.freeze(&mut flash.acr),
          &mut rcc.apb1r1
           );
    
    const ADDRESS: u8 = 0x29; 
    let mut data: [u8; 1] = [0]; 
    let mut x = i2c.write_read(ADDRESS, &[0xC0], &mut data);
    match x {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(_) => hprintln!("its ok").unwrap(),
    }
  
    //let mut mg = Lis3mdl::new(i2c).unwrap();
    let mut dis  = VL53L0x::new(i2c);

    let diss : vl53l0x::VL53L0x<hal::i2c::I2c<hal::stm32::I2C2, 
    (hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF4, 
    hal::gpio::Output<hal::gpio::OpenDrain>>>, 
    hal::gpio::gpiob::PB11<hal::gpio::Alternate<hal::gpio::AF4,
    hal::gpio::Output<hal::gpio::OpenDrain>>>)>>;
    match dis {
      Err(e) => hprintln!("{:?}",e).unwrap(),
      Ok(o) => diss = o,
    }

openocd:

Warn : Padding 4 bytes to keep 8-byte write size
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20018000, semihosting
Warn : block write succeeded
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1373). Workaround: increase "set remotetimeout" in GDB
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
adapter speed: 480 kHz
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08017790 msp: 0x20018000, semihosting
Nack
BusError(Nack)


@bofh
Copy link
Member

bofh commented Jun 4, 2019

Are C examples for vl53 work on your board?

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

I didn't try with C. As I said magnetometer which uses i2c works fine.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

To sum up:

  • magnetometer works fine;
  • reading who_am_i from the vl directly via i2c w/o a driver is not working.

So it is either:

  • hardware problem;
  • bug in i2c implementation;
  • some corner case.

Running official C VL53 example for this board would either confirm, or disprove hardware problem.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

BTW: I’ve found the schematics of your board, they do have a pull-up resistor on a xshut pin of vl, so you could remove that code, it seems that it does nothing at all.

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

I didn't call who_am_i function if is important i can try.
Also hts221 sensor doesnt work ,here i get "Nack" error.

@bofh
Copy link
Member

bofh commented Jun 4, 2019

Who am I is the register inside vl and you are reading it directly without a driver with a line let mut x = i2c.write_read(ADDRESS, &[0xC0], &mut data); and it does not work.

@tasosxak
Copy link
Author

tasosxak commented Jun 4, 2019

So if who_am_i register doesnt work it should not work magnetometer right?

@bofh
Copy link
Member

bofh commented Jun 5, 2019

Something is wrong before the driver. You need to debug it a bit. To understand what exactly try C example (if there is one that comes with this board.) Or maybe ask the embedded_hal team.

@tasosxak
Copy link
Author

tasosxak commented Jun 6, 2019

I checked it on another stm32l475 board and I get the same error.

@bofh
Copy link
Member

bofh commented Jun 6, 2019

@tasosxak
Copy link
Author

tasosxak commented Jun 6, 2019

Yes

@tasosxak
Copy link
Author

tasosxak commented Jun 6, 2019

Also the link of issue for hts221 sensor:
danielgallagher0/hts221#4

@lucazulian
Copy link

I've the same problem for STM32L432 board

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants