danielgallagher0 / hts221

Rust crate to interface with the STMicro HTS221 sensor
Apache License 2.0
9 stars 3 forks source link

Temperature values from HTS221 sensor for stm32l475 #4

Closed tasosxak closed 4 years ago

tasosxak commented 5 years ago
#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate stm32l4xx_hal;
extern crate hts221;

extern crate cortex_m;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
#[macro_use(block)]
extern crate nb;
extern crate panic_semihosting;

use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
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 stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::serial::Serial;

const PERIOD: u32 = 5_000_000;

#[entry]
fn main() -> ! {
    //hprintln!("Hello, world!").unwrap();

        let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
        let mut flash = peripherals.FLASH.constrain();
        let mut rcc = peripherals.RCC.constrain();
        let mut gpiob = peripherals.GPIOB.split(&mut rcc.ahb2);
        let clocks = rcc.cfgr.freeze(&mut flash.acr);
        let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl);
        let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl);

        let serial = Serial::usart1( peripherals.USART1, (tx, rx), 115_200.bps(), clocks, &mut rcc.apb2);
        let (mut tx, mut rx) = serial.split();
        let sent = b'A';
        block!(tx.write(sent)).ok();

        //let p = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
block!(tx.write(b'h')).ok();
        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);
         block!(tx.write(b'k')).ok();
        let i2c = I2c::i2c2(
            peripherals.I2C2,
            (scl,sda),
            1.mhz(),
            rcc.cfgr.freeze(&mut flash.acr),
           &mut rcc.apb1r1
            );
         block!(tx.write(b'z')).ok();
       let mut hts = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build()
        .unwrap();

        let x  = 4;//hts.temperature_x8().unwrap() / 8;
        block!(tx.write(b'Y')).ok();
        block!(tx.write(x as u8)).ok();

      //hprintln!("temperature: {}",hts.temperature_x8().unwrap() / 8);

    loop {}
}

I get runtime error, after this command block!(tx.write(b'k')).ok();

openocd :

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 500 kHz
adapter_nsrst_delay: 100
none separate
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : clock speed 480 kHz
Info : STLINK v2 JTAG v28 API v2 SWIM v18 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.242300
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'gdb' connection on tcp/3333
Info : device id = 0x10076415
Info : flash size = 1024kbytes
undefined debug reason 7 - target needs reset
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: 0x080097ca msp: 0x20018000
adapter speed: 4000 kHz
Info : Padding image section 0 with 20 bytes
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20018000
Warn : block write succeeded
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: 0x080097ca msp: 0x20018000 

gdb session:

tasosxak@tasosxak:~/Documents/RustProjects/app$ cargo run --example hello
    Finished dev [unoptimized + debuginfo] target(s) in 8.11s
     Running `gdb-multiarch -q -x openocd.gdb target/thumbv7em-none-eabi/debug/examples/hello`
Reading symbols from target/thumbv7em-none-eabi/debug/examples/hello...done.
0x00000000 in ?? ()
Breakpoint 1 at 0x8009810: file /home/tasosxak/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.7/src/lib.rs,line 553.
Breakpoint 2 at 0x8009a1c: file /home/tasosxak/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.7/src/lib.rs,line 543.
Breakpoint 3 at 0x8008c2e: file /home/tasosxak/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.1/src/lib.rs, line 78.
Loading section .vector_table, size 0x188 lma 0x8000000
Loading section .text, size 0x98a4 lma 0x8000188
Loading section .rodata, size 0x1248 lma 0x8009a40
Start address 0x80097ca, load size 44148
Transfer rate: 33 KB/sec, 8829 bytes/write.
(gdb) break main
Breakpoint 4 at 0x800268e: file examples/hello.rs, line 39.
(gdb) continue
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 4, main () at examples/hello.rs:39
39              let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
(gdb) continue
Continuing.

Breakpoint 3, rust_begin_unwind (info=0x20017dd4)
    at /home/tasosxak/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.1/src/lib.rs:78
78          interrupt::disable();
(gdb)

minicom:

Welcome to minicom 2.7.1

OPTIONS: I18n
Compiled on Aug 13 2017, 15:25:34.
Port /dev/ttyACM0, 15:28:48

Press CTRL-A Z for help on special keys

Ahkz
danielgallagher0 commented 5 years ago

The minicom output makes it Look like the error happens after it writes the "z", correct?

So the error is likely that the Builder is failing to build, and so the unwrap panics. Looks like the Error type implements Debug. Can you see if the error is NACK or OVERRUN?

Finally, is this on a custom board, or something like the Nucleo?

tasosxak commented 5 years ago

its a discovery kit of stm32l475VGT6 by stm. [https://www.st.com/content/ccc/resource/technical/document/reference_manual/02/35/09/0c/4f/f7/40/03/DM00083560.pdf/files/DM00083560.pdf/jcr:content/translations/en.DM00083560.pdf]

How I can find out the error type?

danielgallagher0 commented 5 years ago

Instead of "unwrap"ing the result of build, you can print the error:

let mut hts_result = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build();
if hts_result.is_err() {
    hprintln!("{:?}", hts_result.err().unwrap());
}
let mut hts = hts_result.unwrap();

I was developing using a similar board, and I did not have to set the I2C pins to open drain outputs first. Does it behave differently if you do this instead:

let scl = gpiob.pb10.into_af4(&mut gpiob.moder, &mut gpiob.afrh);
let sda = gpiob.pb11.into_af4(&mut gpiob.moder, &mut gpiob.afrh);
tasosxak commented 5 years ago
#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate stm32l4xx_hal;
extern crate hts221;

extern crate cortex_m;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
#[macro_use(block)]
extern crate nb;
extern crate panic_semihosting;

use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
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 stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::serial::Serial;

const PERIOD: u32 = 5_000_000;

#[entry]
fn main() -> ! {
    //hprintln!("Hello, world!").unwrap();

        let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
        let mut flash = peripherals.FLASH.constrain();
        let mut rcc = peripherals.RCC.constrain();
        let mut gpiob = peripherals.GPIOB.split(&mut rcc.ahb2);
        let clocks = rcc.cfgr.freeze(&mut flash.acr);
        let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl);
        let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl);

        let serial = Serial::usart1( peripherals.USART1, (tx, rx), 115_200.bps(), clocks, &mut rcc.apb2);
        let (mut tx, mut rx) = serial.split();
        let sent = b'A';
        block!(tx.write(sent)).ok();

        //let p = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
block!(tx.write(b'h')).ok();
        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);
         block!(tx.write(b'k')).ok();
        let i2c = I2c::i2c2(
            peripherals.I2C2,
            (scl,sda),
            1.mhz(),
            rcc.cfgr.freeze(&mut flash.acr),
           &mut rcc.apb1r1
            );
         block!(tx.write(b'z')).ok();
        let mut hts_result = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build();

       if hts_result.is_err() {
          hprintln!("{:?}", hts_result.err().unwrap());
        }

       //let mut hts = hts_result.unwrap();
       let x  = 4;//hts.temperature_x8().unwrap() / 8;
        block!(tx.write(b'Y')).ok();
        block!(tx.write(x as u8)).ok();

      //hprintln!("temperature: {}",hts.temperature_x8().unwrap() / 8);

    loop {}
}

minicom:

Welcome to minicom 2.7.1

OPTIONS: I18n 
Compiled on Aug 13 2017, 15:25:34.
Port /dev/ttyACM0, 03:53:44

Press CTRL-A Z for help on special keys

Ahkz
tasosxak commented 5 years ago

If I remove into_open_drain_output calls i get compiler error:

#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate stm32l4xx_hal;
extern crate hts221;

extern crate cortex_m;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
#[macro_use(block)]
extern crate nb;
extern crate panic_semihosting;

use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
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 stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::serial::Serial;

const PERIOD: u32 = 5_000_000;

#[entry]
fn main() -> ! {
    //hprintln!("Hello, world!").unwrap();

        let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
        let mut flash = peripherals.FLASH.constrain();
        let mut rcc = peripherals.RCC.constrain();
        let mut gpiob = peripherals.GPIOB.split(&mut rcc.ahb2);
        let clocks = rcc.cfgr.freeze(&mut flash.acr);
        let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl);
        let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl);

        let serial = Serial::usart1( peripherals.USART1, (tx, rx), 115_200.bps(), clocks, &mut rcc.apb2);
        let (mut tx, mut rx) = serial.split();
        let sent = b'A';
        block!(tx.write(sent)).ok();

        //let p = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
block!(tx.write(b'h')).ok();
        let scl = gpiob.pb10.into_af4(&mut gpiob.moder, &mut gpiob.afrh);
        let sda = gpiob.pb11.into_af4(&mut gpiob.moder, &mut gpiob.afrh);
         block!(tx.write(b'k')).ok();
        let i2c = I2c::i2c2(
            peripherals.I2C2,
            (scl,sda),
            1.mhz(),
            rcc.cfgr.freeze(&mut flash.acr),
           &mut rcc.apb1r1
            );
         block!(tx.write(b'z')).ok();
        let mut hts_result = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build();

       if hts_result.is_err() {
          hprintln!("{:?}", hts_result.err().unwrap());
        }

       //let mut hts = hts_result.unwrap();
       let x  = 4;//hts.temperature_x8().unwrap() / 8;
        block!(tx.write(b'Y')).ok();
        block!(tx.write(x as u8)).ok();

      //hprintln!("temperature: {}",hts.temperature_x8().unwrap() / 8);

    loop {}
}
error[E0277]: the trait bound `stm32l4xx_hal::gpio::gpiob::PB10<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Input<stm32l4xx_hal::gpio::Floating>>>: stm32l4xx_hal::i2c::SclPin<stm32l4xx_hal::stm32::I2C2>` is not satisfied
  --> examples/hello.rs:57:19
   |
57 |         let i2c = I2c::i2c2(
   |                   ^^^^^^^^^ the trait `stm32l4xx_hal::i2c::SclPin<stm32l4xx_hal::stm32::I2C2>` is not implemented for `stm32l4xx_hal::gpio::gpiob::PB10<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Input<stm32l4xx_hal::gpio::Floating>>>`
   |
   = help: the following implementations were found:
             <stm32l4xx_hal::gpio::gpiob::PB10<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Output<stm32l4xx_hal::gpio::OpenDrain>>> as stm32l4xx_hal::i2c::SclPin<stm32l4xx_hal::stm32::I2C2>>
   = note: required by `<stm32l4xx_hal::i2c::I2c<stm32l4xx_hal::stm32::I2C2, (SCL, SDA)>>::i2c2`

error[E0277]: the trait bound `stm32l4xx_hal::gpio::gpiob::PB11<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Input<stm32l4xx_hal::gpio::Floating>>>: stm32l4xx_hal::i2c::SdaPin<stm32l4xx_hal::stm32::I2C2>` is not satisfied
  --> examples/hello.rs:57:19
   |
57 |         let i2c = I2c::i2c2(
   |                   ^^^^^^^^^ the trait `stm32l4xx_hal::i2c::SdaPin<stm32l4xx_hal::stm32::I2C2>` is not implemented for `stm32l4xx_hal::gpio::gpiob::PB11<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Input<stm32l4xx_hal::gpio::Floating>>>`
   |
   = help: the following implementations were found:
             <stm32l4xx_hal::gpio::gpiob::PB11<stm32l4xx_hal::gpio::Alternate<stm32l4xx_hal::gpio::AF4, stm32l4xx_hal::gpio::Output<stm32l4xx_hal::gpio::OpenDrain>>> as stm32l4xx_hal::i2c::SdaPin<stm32l4xx_hal::stm32::I2C2>>
   = note: required by `<stm32l4xx_hal::i2c::I2c<stm32l4xx_hal::stm32::I2C2, (SCL, SDA)>>::i2c2`
danielgallagher0 commented 5 years ago

Looks like the hprintln didn't do anything useful. Try replacing hprintln!("{:?}", hts_result.err().unwrap()); with

match hts_result.err().unwrap() {
stm32f4xx_hal::i2c::Error::NACK => block!(tx.write(b'n')),
stm32f4xx_hal::i2c::Error::OVERRUN => block!(tx.write(b'o')),
}

That will at least provide a bit more information, but I'm not really sure what to do in either case. You may need to step through the hts221 build function to see which call is failing. That may provide more insight.

tasosxak commented 5 years ago
#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate stm32l4xx_hal;
extern crate hts221;

extern crate cortex_m;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
#[macro_use(block)]
extern crate nb;
extern crate panic_semihosting;

use cortex_m_rt::entry;
use cortex_m_semihosting::{debug, hprintln};
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 stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::serial::Serial;

const PERIOD: u32 = 5_000_000;

#[entry]
fn main() -> ! {
    //hprintln!("Hello, world!").unwrap();

        let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
        let mut flash = peripherals.FLASH.constrain();
        let mut rcc = peripherals.RCC.constrain();
        let mut gpiob = peripherals.GPIOB.split(&mut rcc.ahb2);
        let clocks = rcc.cfgr.freeze(&mut flash.acr);
        let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl);
        let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl);

        let serial = Serial::usart1( peripherals.USART1, (tx, rx), 115_200.bps(), clocks, &mut rcc.apb2);
        let (mut tx, mut rx) = serial.split();
        let sent = b'A';
        block!(tx.write(sent)).ok();

        //let p = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
block!(tx.write(b'h')).ok();
        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);
         block!(tx.write(b'k')).ok();
        let i2c = I2c::i2c2(
            peripherals.I2C2,
            (scl,sda),
            1.mhz(),
            rcc.cfgr.freeze(&mut flash.acr),
           &mut rcc.apb1r1
            );
         block!(tx.write(b'z')).ok();
        let mut hts_result = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build();

       match hts_result.err().unwrap() {
stm32l4xx_hal::i2c::Error::NACK => block!(tx.write(b'n')).ok(),
stm32l4xx_hal::i2c::Error::OVERRUN => block!(tx.write(b'o')).ok(),
}

       //let mut hts = hts_result.unwrap();
       let x  = 4;//hts.temperature_x8().unwrap() / 8;
        block!(tx.write(b'Y')).ok();
        block!(tx.write(x as u8)).ok();

      //hprintln!("temperature: {}",hts.temperature_x8().unwrap() / 8);

    loop {}
}

Error:

error[E0599]: no variant named `NACK` found for type `stm32l4xx_hal::i2c::Error` in the current scope
  --> examples/hello.rs:71:28
   |
71 | stm32l4xx_hal::i2c::Error::NACK => block!(tx.write(b'n')).ok(),
   | ---------------------------^^^^
   | |
   | variant not found in `stm32l4xx_hal::i2c::Error`

error[E0599]: no variant named `OVERRUN` found for type `stm32l4xx_hal::i2c::Error` in the current scope
  --> examples/hello.rs:72:28
   |
72 | stm32l4xx_hal::i2c::Error::OVERRUN => block!(tx.write(b'o')).ok(),
   | ---------------------------^^^^^^^
   | |
   | variant not found in `stm32l4xx_hal::i2c::Error`

error[E0308]: mismatched types
  --> examples/hello.rs:70:8
   |
70 | /        match hts_result.err().unwrap() {
71 | | stm32l4xx_hal::i2c::Error::NACK => block!(tx.write(b'n')).ok(),
72 | | stm32l4xx_hal::i2c::Error::OVERRUN => block!(tx.write(b'o')).ok(),
73 | | }
   | |_^ expected (), found enum `core::option::Option`
   |
   = note: expected type `()`
              found type `core::option::Option<()>`

error: aborting due to 3 previous errors

Some errors occurred: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.
error: Could not compile `app`.

To learn more, run the command again with --verbose.
tasosxak commented 5 years ago
#![deny(unsafe_code)]
#![no_main]
#![no_std]
extern crate stm32l4xx_hal;
extern crate hts221;

extern crate cortex_m;
#[macro_use(entry, exception)]
extern crate cortex_m_rt as rt;
extern crate stm32l4xx_hal as hal;
extern crate cortex_m_semihosting as sh;
extern crate nb;
extern crate panic_semihosting;

use cortex_m_semihosting::{debug, hprintln};
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 stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::serial::Serial;
use crate::stm32l4xx_hal::prelude::*;
use crate::stm32l4xx_hal::delay::Delay;
use crate::rt::ExceptionFrame;
use crate::rt::entry;

use core::fmt::Write;
use crate::sh::hio;

const PERIOD: u32 = 5_000_000;

#[entry]
fn main() -> ! {

        let mut hstdout = hio::hstdout().unwrap();
        let peripherals = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
        let mut flash = peripherals.FLASH.constrain();
        let mut rcc = peripherals.RCC.constrain();
        let mut gpiob = peripherals.GPIOB.split(&mut rcc.ahb2);
        let clocks = rcc.cfgr.freeze(&mut flash.acr);
        //let tx = gpiob.pb6.into_af7(&mut gpiob.moder, &mut gpiob.afrl);
       // let rx = gpiob.pb7.into_af7(&mut gpiob.moder, &mut gpiob.afrl);

       // let serial = Serial::usart1( peripherals.USART1, (tx, rx), 115_200.bps(), clocks, &mut rcc.apb2);
        //let (mut tx, mut rx) = serial.split();
        //let sent = b'A';
        //block!(tx.write(sent)).ok();

        //let p = stm32l4xx_hal::stm32l4::stm32l4x5::Peripherals::take().unwrap();
//block!(tx.write(b'h')).ok();
        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);
        //block!(tx.write(b'k')).ok();

        let i2c = I2c::i2c2(
            peripherals.I2C2,
            (scl,sda),
            1.mhz(),
            rcc.cfgr.freeze(&mut flash.acr),
           &mut rcc.apb1r1
            );

        //block!(tx.write(b'z')).ok();

        let mut hts_result = hts221::Builder::new(i2c)
        .with_avg_t(hts221::AvgT::Avg256)
        .with_avg_h(hts221::AvgH::Avg512)
        .build();

      if hts_result.is_err() {
          writeln!(hstdout,"{:?}", hts_result.err().unwrap()).unwrap();

        }

       //let mut hts = hts_result.unwrap();
       let x  = 4;//hts.temperature_x8().unwrap() / 8;
        //block!(tx.write(b'Y')).ok();
       // block!(tx.write(x as u8)).ok();

      //hprintln!("temperature: {}",hts.temperature_x8().unwrap() / 8);

    loop {}
}

openocd session:

xPSR: 0x01000000 pc: 0x08008a66 msp: 0x20018000, semihosting
Nack
danielgallagher0 commented 5 years ago

I went out and got the same board, and can confirm this issue. I suspect there's something specific to this board that is not enabling either the I2C2 bus or this specific sensor by default, but I haven't had any luck narrowing it down.

I doubt the underlying issue is with the driver, but I'll keep the issue open until I can get it fixed, since I'd like to use the sensor on this board.

danielgallagher0 commented 5 years ago

I tried out the X-Cube-Watson demo software from STMicro, and it can talk to the HTS221 just fine. Now to replicate all of the initialization in Rust...

bofh commented 5 years ago

Hi @danielgallagher0 have you managed to find what’s wrong?

danielgallagher0 commented 5 years ago

No, I haven't had time in the evenings to work on this for the last couple of months. I should be able to get back to it mid-August or September.

bofh commented 4 years ago

Hi, any news on this?

bofh commented 4 years ago

Probably the reason is 10 bit addressing: https://github.com/copterust/vl53l0x/issues/5

danielgallagher0 commented 4 years ago

Finally got back to this, and found it. The issue that @bofh linked is correct, though it's 8-bit addressing, not 10-bit. stm32f30x-hal (which is the first HAL I developed against) uses 7-bit addresses for its I2C devices, and appends the 1-bit R/W value in the least significant place to make the full 8-bit address. stm32l4xx-hal expects the address to be 8-bit.

I confirmed by updating the I2C_ID for the HTS221 to 0xBE (i.e., 0x5F << 1), and it works. Will update the crate appropriately and close when released.