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

How to use i2c_external with microbit-v2? #121

Open
felipebalbi opened this issue Oct 31, 2023 · 2 comments
Open

How to use i2c_external with microbit-v2? #121

felipebalbi opened this issue Oct 31, 2023 · 2 comments

Comments

@felipebalbi
Copy link

Hi,

I'm attempting to read from shtc3 sensor connected to microbit-v2 via i2c external pins. For testing, I'm using a minimal RTIC app with one task which received a local context containing the Twim:<TWIM0> instance which it uses to instantiate shtc3. When attempting to build the application, it results in unsatisfied trait bounds:

error[E0599]: the method `device_identifier` exists for struct `ShtCx<Sht2Gen, &mut Twim<TWIM0>>`, but its trait bounds were not satisfied
   --> app\src\main.rs:157:29
    |
157 |         let device_id = sht.device_identifier().unwrap();
    |                             ^^^^^^^^^^^^^^^^^ method cannot be called on `ShtCx<Sht2Gen, &mut Twim<TWIM0>>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `<&mut microbit::nrf52833_hal::Twim<microbit::nrf52833_pac::TWIM0> as _embedded_hal_blocking_i2c_Read>::Error = _`
            `<&mut microbit::nrf52833_hal::Twim<microbit::nrf52833_pac::TWIM0> as _embedded_hal_blocking_i2c_Write>::Error = _`
            `&mut microbit::nrf52833_hal::Twim<microbit::nrf52833_pac::TWIM0>: _embedded_hal_blocking_i2c_Read`
            `&mut microbit::nrf52833_hal::Twim<microbit::nrf52833_pac::TWIM0>: _embedded_hal_blocking_i2c_Write`

If I move the code to init(), then it compiles fine, but there is no activity on the i2c external pins (checked with an oscilloscope) and every transaction results in a Nack.

Is there anything else I need to do to get i2c_external to work? Here's a minimal version of my code:

#[app(device = microbit::hal::pac)]
mod app {
    use super::*;

    #[shared]
    struct Shared {}

    #[local]
    struct Local {
        led: P0_21<Output<PushPull>>,
        // i2c: Twim<TWIM0>,
        gpiote: Gpiote,
        state: bool,
    }

    #[init]
    fn init(cx: init::Context) -> (Shared, Local) {
        info!("Hello from RTIC on micro:bit v2");

        let mut board = Board::new(cx.device, cx.core);
        let i2c = Twim::new(board.TWIM0, board.i2c_external.into(), FREQUENCY_A::K100);
        let mut sht = shtcx::shtc3(i2c);
        let device_id = sht.device_identifier().unwrap(); // Fails here with Nack

        (
            Shared {},
            Local {},
        )
    }
@BartMassey
Copy link
Member

You'll probably want to put the sht in your locals, not i2c. The shtc3 driver takes ownership of the i2c.

This sounds like maybe an shtcx issue. I've driven external i2c devices in roughly the way you describe before, but have never used this crate.

It's weird that you're not seeing any activity on the external pins with a scope: especially since you're getting a NACK, which I think should only happen when a bus transaction was tried and failed.

Not sure how to help further without an SHTC device, I'm afraid.

@felipebalbi
Copy link
Author

You'll probably want to put the sht in your locals, not i2c. The shtc3 driver takes ownership of the i2c.

I'll give that a go when I have some free time on a weekend.

This sounds like maybe an shtcx issue. I've driven external i2c devices in roughly the way you describe before, but have never used this crate.

It's weird that you're not seeing any activity on the external pins with a scope: especially since you're getting a NACK, which I think should only happen when a bus transaction was tried and failed.

If we have bogus pin-muxing, the I2C controller thinks it has driven the correct signals, but they have not propagated to external balls on the die. When waiting for an ACK, there was also no activity, then it signals a NAK and asserts interrupt signal. It can happen :)

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