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

Run time errors with i2c temperature/humidity sensors #828

Closed
pdgilbert opened this issue Dec 27, 2024 · 7 comments
Closed

Run time errors with i2c temperature/humidity sensors #828

pdgilbert opened this issue Dec 27, 2024 · 7 comments

Comments

@pdgilbert
Copy link
Contributor

(Possibly related to #749)

I have examples with some embedded-hal v1 temperature/humidity sensor crates that compile but then fail running. The general symptom is that they do not return from an initial call to the hal.

There are three AHT20 sensor crates and also crates for sensors SHT30 and SHTC3. I have checked the sensor crates with a git version and a release version if it exists. The crates are:

I have tested these with stm32f4xx-hal release v0.22.1 and also with a recent git commit #ed88ea13. For comparison I have also tested with @techmccat 's stm32g4xx-hal from https://github.com/techmccat/stm32g4xx-hal#9462f4cd branch hal-1.
All examples compile with both hals (and also with stm32f1xx-hal).
The three AHT20 crates work with stm32g4xx-hal but fail with stm32f4xx-hal. The SHT30 and SHTC3 crates work with stm32f4xx-hal but fail with stm32g4xx-hal.

I have put the examples in a repository https://github.com/pdgilbert/i2c-test. The action tab shows the compiling results. The README has a few more details from GDB.
The repository also includes some examples with @eldruin 's xca9548a-rs multiplexer crate. These also compile but have run time errors (even in the cases where the sensor crates alone work).

Of course, the most likely problem is that I have something wrong in the setup (src/setup_all_stm32f4xx.rs) but I think it is correct (encouraged by the fact that some examples work). Another possibility is that sensor delays are not sufficiently long, but that would likely affect all examples.

Of course, my hope is that the cross-device abstraction can be made to work, so the device crates will work with different HALs. Suggestions would be appreciated.

@burrbull
Copy link
Member

I'm not an expert in I2C. Maybe someone else can help. There is also #547

I have tested these with stm32f4xx-hal release v0.22.1 and also with a recent git commit #ed88ea13.

If this an old error how can this help?

Another possibility is that sensor delays are not sufficiently long, but that would likely affect all examples.

F1 and F4 I2C peripherals does not have config for timings (except FMPI2c). G4 I2Cs should have.
F1 BlockingI2c tries to workaround this issue with DWT timer. But I do not know the details.

@pdgilbert
Copy link
Contributor Author

I tried commits 88c5843 and 571c3a3 with no success.

I am trying to get a better fix on the location of the problem with gdb. Stepping through the aht20-dr-semi example which uses @anglerud 's aht20-driver v2.0.0 I record this sequence leading to the problem:

Remote target In: aht20_dr_semi::__cortex_m_rt_m* L84   PC: 0x8002802

Remote target In: aht20_driver::AHT20<stm32f4xx_hal::i2c::* L361  PC: 0x8001aa2 

Remote target In: aht20_driver::AHT20<stm32f4xx_hal::i2c::* L389  PC: 0x8001976

Remote target In: stm32f4xx_hal::i2c::I2c<stm32f4_staging:* L443  PC: 0x80011f8 

Remote target In: stm32f4xx_hal::i2c::hal_1::blocking::{im* L11   PC: 0x8001948 

Remote target In: stm32f4xx_hal::i2c::I2c<stm32f4_staging:* L443  PC: 0x80011f8

Remote target In: core::convert::{impl#3}::into<u8, stm32f* L759  PC: 0x8001ed2
Remote target In: core::convert::{impl#3}::into<u8, stm32f* L760  PC: 0x8001edc 

(For the last two lines my gdb src window reports no source. ) When the final line executes the gdb prompt does not return but the semihosting window shows continued stepping through memory:

...
Info : halted: PC: 0x0800123a
Info : halted: PC: 0x0800123c
Info : halted: PC: 0x0800123e
Info : halted: PC: 0x08001240
Info : halted: PC: 0x0800039e
...

If I use ^C to break to gdb then backtrace gives

gdb) bt
#0  0x0800c048 in core::ptr::read_volatile<u32> (src=0x8013c48 <.L__unnamed_4>)
    at /rustc/dff3e7ccd4a18958c938136c4ccdc853fcc86194/library/core/src/ptr/mod.rs:1738
#1  0x080004bc in vcell::VolatileCell<u32>::get<u32> (self=0x40005414)
    at /home/paul/.cargo/registry/src/index.crates.io-6f17d22bba15001f/vcell-0.1.3/src/lib.rs:33
#2  stm32f4_staging::generic::Reg<stm32f4_staging::stm32f401::i2c1::sr1::SR1rs>::read<stm32f4_staging::stm32f401::i2c1::sr1::SR1rs> (self=0x40005414)
    at /home/paul/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stm32f4-staging-0.17.0/src/generic.rs:646
#3  stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>::prepare_read<stm32f4_staging::stm32f401::I2C1> (self=0x2000fe64, addr=..., first_transaction=true)
    at /home/paul/.cargo/git/checkouts/stm32f4xx-hal-fe8350cc04cacf3f/571c3a3/src/i2c.rs:338
#4  0x08001244 in stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>::read_inner<stm32f4_staging::stm32f401::I2C1> (self=0x2000fe64, addr=..., buffer=..., 
    first_transaction=true)
    at /home/paul/.cargo/git/checkouts/stm32f4xx-hal-fe8350cc04cacf3f/571c3a3/src/i2c.rs:457
#5  stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>::read<stm32f4_staging::stm32f401::I2C1, u8> (self=0x2000fe64, addr=56, buffer=...)
    at /home/paul/.cargo/git/checkouts/stm32f4xx-hal-fe8350cc04cacf3f/571c3a3/src/i2c.rs:443
#6  0x0800194c in stm32f4xx_hal::i2c::hal_1::blocking::{impl#0}::read<stm32f4_staging::stm32f401::I2C1> (self=0x2000fe64, addr=56, buffer=...)
    at /home/paul/.cargo/git/checkouts/stm32f4xx-hal-fe8350cc04cacf3f/571c3a3/src/i2c/hal_1.rs:11
#7  0x08001982 in aht20_driver::AHT20<stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>>::check_status<stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>> (
    self=0x2000fe64)
    at /home/paul/.cargo/registry/src/index.crates.io-6f17d22bba15001f/aht20-driver-2.0.0/src/lib.rs:389
#8  0x08001aa8 in aht20_driver::AHT20<stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>>::init<stm32f4xx_hal::i2c::I2c<stm32f4_staging::stm32f401::I2C1>, stm32f4xx_hal::timer::delay::Delay<stm32f4_staging::stm32f401::TIM5, 1000000>> (self=0x2000fe64, 
    delay=0x2000fe0b)
    at /home/paul/.cargo/registry/src/index.crates.io-6f17d22bba15001f/aht20-driver-2.0.0/src/lib.rs:361
#9  0x080023e0 in aht20_dr_semi::__cortex_m_rt_main () at examples/aht20-dr-semi.rs:84
#10 0x080022c2 in aht20_dr_semi::__cortex_m_rt_main_trampoline ()
    at examples/aht20-dr-semi.rs:61
(gdb) 

Let me know if there is something else I should check. (I'm a novice with gdb and not familiar with the hal or sensor crate code.)

@burrbull
Copy link
Member

just a thought. But could it be related to device addresses?

@pdgilbert
Copy link
Contributor Author

I don't think so. The device address is hard coded in some of the crates because it cannot be change. Were it is not hard coded it is set in the generic part of my code, so it works with stm32f4xx_hal and not with stm32g4xx_hal or vice versa.

@burrbull
Copy link
Member

burrbull commented Dec 30, 2024

If I use ^C to break to gdb then backtrace gives

It looks like it halts on reading SR1 register.

For the last two lines my gdb src window reports no source.

This could be https://doc.rust-lang.org/src/core/convert/mod.rs.html#759
It is strange. Why it is not optimized out? Do yo u compile with --release and what compilation flags?
I do no see profile section in your Cargo.toml:

stm32f4xx-hal/Cargo.toml

Lines 568 to 575 in 585dd0f

[profile.dev]
debug = true
lto = true
[profile.release]
debug = true
lto = true
opt-level = "s"

@pdgilbert
Copy link
Contributor Author

Thanks @burrbull , this seems to be the problem. (I'm a novice with gdb, so tips and explanations appreciated.)

I was using default profiles. Thus no debug info for release, so I have been using mostly dev. And it looks like the default opt-level for dev is 0, which seems to be the source of the problem. Using default profiles the problem is fixed by using release (subject to reboot below). Using profiles as above, gives some debug info with release so I will use it more. Adding opt-level = 1 in [profile.dev] fixes the problem when using the dev profile. (Subject to more testing.)

I have been exiting and restarting gdb sessions as I test different code, but I have been leaving my openocd session running with my st-link probe connected to the test board. I have now discovered that if I run a gdb session that fails (eg. dev profile with opt-level = 0) then something in the st-link, mcu&board, or sensor, gets left in a state that causes the next session to have problems initializing the sensor. Thus I have been having some failures for code that works if I re-boot the probe, mcu and sensor.

@pdgilbert
Copy link
Contributor Author

I have done more testing and some fixing of examples at the above repository (https://github.com/pdgilbert/i2c-test). All the semihost examples now work with stm32f4xx-hal (tested adding opt-level = 1 to profile.dev and lto = true to profile.release).

Many of the xca9548a-* examples with @eldruin 's xca9548a-rs multiplexer crate and various sensors are also now working. Remaining problems are not with stm32f4xx-hal. (Testing in progress on bluepill is mostly going well too.) Thanks @burrbull .

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

2 participants