STM32 Rust halでI2C (halを0.9から0.13にバージョンアップしてみた )

  • 2022.04.10
  • I2C
STM32 Rust halでI2C (halを0.9から0.13にバージョンアップしてみた )

前回halを使ってI2Cを操作しました。
少し前にhal(stm32f4xx-hal)のバージョンが 0.13 に上がったので、今回は 0.13 で動作確認を行いました。
内容は前回(バージョン0.9)の記事と同じですから、必要な情報のみ記述しておきます。

I2C、接続するデバイス、接続方法などについては 前々回の記事 を参照してください。

開発環境は以下の通りです。

PC:Windows10 OS
Board:STM32Nucleo-F401RE
デバイス:STM32F401RE
エディタ:VSCode
言語:Rust
stm32f4xx-hal:Version 0.13

ボードの情報は こちら からご覧いただけます。
環境構築については こちら をご覧になってください。

Rustのバージョンアップ

こちらの環境では今まで、rustc のバージョンが 1.57 でした。
halのバージョンを上げた後にビルドしたところ「バージョンアップせよ」と怒られました。

コマンドプロンプトを起動し、以下のコマンドを入力します。

rustup update

rustup update

Cargo.toml

ドキュメントに習って、以下のように記述します。

[dependencies]
embedded-hal = "0.2"
nb = "1"
cortex-m = "0.7"
cortex-m-rt = "0.7"
panic-halt = "0.2"
[dependencies.stm32f4xx-hal]
features = ["stm32f401", "rt"]
version = "0.13"

ソースコード

#![no_std]
#![no_main]

use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics
use cortex_m_rt::entry;
use stm32f4xx_hal::prelude::*; // Hz()
use stm32f4xx_hal::i2c::*;

const DEVICE_ADRS_FOR_WRITE: u8 = 0xa0;

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

    let dp = stm32f4xx_hal::pac::Peripherals::take().unwrap();
    let gpiob = dp.GPIOB.split();   // GPIOBのclockも有効にしてくれる (AHBENRレジスタ)

    let rcc = dp.RCC.constrain();       // RCCの取得
    let clks = rcc.cfgr.freeze();   // 各clockの設定
    let mode = Mode::Standard { frequency: 100_000_u32.Hz() };

    let mut i2c = I2c::new(
        dp.I2C1,
        (gpiob.pb8, gpiob.pb9),
        mode,
        &clks,
    );  // I2Cの生成

    let wbuf = [0, 1, 18, 52, 86];
    // 0, 1 : 書き込むメモリーの先頭アドレス (0x0001 番地)
    // 18, 52, 86 はメモリーに書く値(数値に意味はない)

    let adrs = DEVICE_ADRS_FOR_WRITE >> 1;  // 中で左シフトされるので右シフトしておく
    let _ = i2c.write(adrs, &wbuf);

    let mut rbuf = [0; 3];

    let _ = i2c.write_read(adrs, &wbuf[..2], &mut rbuf);    // 第2引数はスライスを使って最初の2バイトのみ書くように指示する

    loop {
    }
}

コード概要

要所にコメントを入れたので参考にしてください。
メモリーの1番地から3バイト適当な値を書いて、読み出してみました。
rbufの配列に読んだ値が入ります。

I2C::new()の第2引数は split()した値を加工することなく渡すことができるようになっています。

(0.9で使っていた into_alternate_af4_open_drain() の処理が不要になった)

不要になったというよりは、GPIOのモードをオルタネート afx (xは数字)に設定するメソッド自体がなくなりました。
その代わりI2Cペリフェラルを生成するnew()メソッドではモード設定をしないままの型を受け付けてくれるようになったようで、その分コードを書く手間が省けました。

その他、列挙型のModeが追加される等いくつかの変更があります。
コード量はわずかですから、0.9のものと比べて頂くと違いがわかると思います。

動作させてみる

それでは F5キーでプログラムを起動した後、entry で停止したらもう一度F5キーを押してプログラムを動作させてみます。

デバッグモードは OpenOCD に設定する必要があるので、エラーが出る場合には確認してみてください。

こちらでは書いた値3バイトを正しく読むことができました。

いかがでしたか?
皆さんの環境では、うまく動作しましたか?

今回のプロジェクトを stm32f401-i2c3 におきましたので、よろしければ参考になさってください。

お疲れさまでした。

I2Cカテゴリの最新記事