nRF Connect SDKによるnRF54L15のI2Cペリフェラル初期化ガイド

カーネルコンフィギュレーションの設定

Zephyr RTOS上でI2C機能を有効化するには、プロジェクトの設定ファイル(通常はprj.confまたはKconfig)にて、以下のオプションを追加する必要があります。これにより、I2Cドライバがカーネルに組み込まれます。

CONFIG_I2C=y

デバイスツリーオーバーレイの定義

ハードウェア設定を定義するため、プロジェクトのルートディレクトリにボード名に対応したオーバーレイファイル(例: nrf54l15dk_nrf54l15app.overlay)を作成します。このファイル内でピン機能(ピンコンフィグレーション)とI2Cノードの有効化を行います。

以下の設定例では、TWIM(Two-wire Interface Master)ペリフェラルを使用し、ポート1のピン11(SCL)とピン12(SDA)を割り当てています。また、スリープ時の低消費電力設定も併せて定義しています。

/ {
    pinctrl {
        /* アクティブ状態のピン設定 */
        i2c_cfg_default: i2c_cfg_default {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                bias-pull-up;
            };
        };

        /* スリープ状態のピン設定 */
        i2c_cfg_sleep: i2c_cfg_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                low-power-enable;
            };
        };
    };
};

&i2c22 {
    status = "okay";
    clock-frequency = <I2C_BITRATE_STANDARD>;
    
    /* ピン状態の割り当て */
    pinctrl-0 = <&i2c_cfg_default>;
    pinctrl-1 = <&i2c_cfg_sleep>;
    pinctrl-names = "default", "sleep";

    /* 接続するI2Cデバイスの定義 (アドレス 0x58) */
    my_peripheral: my_peripheral@58 {
        compatible = "i2c-device";
        status = "okay";
        reg = <0x58>;
    };
};

アプリケーションコードの実装

メインアプリケーションコードにて、デバイスツリーで定義したノードを取得し、I2Cバスの準備状況を確認した後、データの送受信を行います。ここでは、ZephyrのI2CデバイスツリーAPI(i2c_dt_spec)を使用して実装します。

以下のコードは、デバイスへの書き込み処理と、レジスタ指定による読み出し処理の例です。

#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/printk.h>

/* デバイスツリーのノードラベルを指定 */
#define SENSOR_NODE_ID DT_NODELABEL(my_peripheral)

int main(void)
{
    printk("Starting I2C sample on %s\n", CONFIG_BOARD_TARGET);

    /* デバイスツリーからI2Cデバイス情報を取得 */
    static const struct i2c_dt_spec bus_spec = I2C_DT_SPEC_GET(SENSOR_NODE_ID);

    /* I2Cバスの準備完了を確認 */
    if (!device_is_ready(bus_spec.bus)) {
        printk("Error: I2C bus %s is not ready!\n", bus_spec.bus->name);
        return 0;
    }
    printk("I2C bus %s is ready.\n", bus_spec.bus->name);

    /* レジスタ 0x01 にデータ 0xA5 を書き込む */
    uint8_t tx_packet[2] = {0x01, 0xA5};
    int ret = i2c_write_dt(&bus_spec, tx_packet, sizeof(tx_packet));
    
    if (ret != 0) {
        printk("Write failed: addr 0x%x, reg 0x%02x\n", bus_spec.addr, tx_packet[0]);
    }

    /* レジスタ 0x01 からデータを読み出す */
    uint8_t target_reg = 0x01;
    uint8_t rx_buffer = 0;

    ret = i2c_write_read_dt(&bus_spec, &target_reg, 1, &rx_buffer, 1);
    if (ret != 0) {
        printk("Read failed: addr 0x%x, reg 0x%02x\n", bus_spec.addr, target_reg);
    } else {
        printk("Read success: value 0x%02x\n", rx_buffer);
    }

    return 0;
}

タグ: nRF54L15 nRF-Connect-SDK Zephyr I2C DeviceTree

5月23日 12:30 投稿