NCSメモ:SPIマスターとSPIスレーブのサンプル追加

SPIマスター用デバイスツリーoverlayの例

&pinctrl {
    spi21_default: spi21_default {
        group2 {
            psels = <NRF_PSEL(SPIM_MOSI, 1, 12)>,
                    <NRF_PSEL(SPIM_SCK, 1, 8)>,
                    <NRF_PSEL(SPIM_MISO, 1, 11)>;
            nordic,drive-mode = <NRF_DRIVE_H0H1>;
        };
    };
};

&spi21 {
    status = "okay";
    pinctrl-0 = <&spi21_default>;
    pinctrl-names = "default";
    cs-gpios = <&gpio2 10 (GPIO_ACTIVE_LOW)>;
};

この設定により、SPI21がマスターとして動作し、SCK/MOSI/MISO/CSはそれぞれP1.8/P1.12/P1.11/P2.10に対応します。

SPIマスターのコード例

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>

#define SPI_DEV_NODE DT_NODELABEL(spi21)

void main(void)
{
    const struct device *spi_dev = DEVICE_DT_GET(SPI_DEV_NODE);
    if (!device_is_ready(spi_dev)) {
        printk("SPI device not ready!\n");
        return;
    }

    struct spi_cs_control cs_ctrl = {
        .gpio = GPIO_DT_SPEC_GET(SPI_DEV_NODE, cs_gpios),
        .delay = 0,
    };

    struct spi_config spi_cfg = {
        .frequency = 1000000,
        .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_MASTER,
        .slave = 0,
        .cs = &cs_ctrl,
    };

    uint8_t tx_data[5] = { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E };
    uint8_t rx_data[5] = {0};

    struct spi_buf tx_spi_buf = { .buf = tx_data, .len = sizeof(tx_data) };
    struct spi_buf rx_spi_buf = { .buf = rx_data, .len = sizeof(rx_data) };
    struct spi_buf_set tx = { .buffers = &tx_spi_buf, .count = 1 };
    struct spi_buf_set rx = { .buffers = &rx_spi_buf, .count = 1 };

    int result = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
    printk("SPI transceive result: %d\n", result);
    printk("TX: %02x %02x %02x %02x %02x\n", tx_data[0], tx_data[1], tx_data[2], tx_data[3], tx_data[4]);
    printk("RX: %02x %02x %02x %02x %02x\n", rx_data[0], rx_data[1], rx_data[2], rx_data[3], rx_data[4]);
}

このコードはSPIMを使用して5バイトのデータを送信し、送信および受信結果を出力します。

SPIスレーブ(SPIS)の例が必要な場合は、以下のoverlayとコードを参照してください:

SPIスレーブ用overlayの例

&pinctrl {
    spis22_default: spis22_default {
        group1 {
            psels = <NRF_PSEL(SPIS_SCK, 2, 6)>,
                    <NRF_PSEL(SPIS_MOSI, 2, 9)>,
                    <NRF_PSEL(SPIS_MISO, 2, 8)>,
                    <NRF_PSEL(SPIS_CSN, 2, 10)>;
        };
    };
};

&spi22 {
    compatible = "nordic,nrf-spis";
    status = "okay";
    pinctrl-0 = <&spis22_default>;
    pinctrl-names = "default";
    def-char = <0x00>;
};

SPIスレーブのC言語コード断片

static const struct spi_config spi_config = {
    .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_SLAVE,
    .frequency = 1000000,
    .slave = 1,
};

const struct device *spi_device = DEVICE_DT_GET(DT_NODELABEL(spi22));

void main(void)
{
    uint8_t send_buffer[32] = { 's', 'p', 'i', 's', 'l', 'a', 'v', 'e', '\n' };
    uint8_t recv_buffer[32] = {0};

    struct spi_buf tx_buf = { .buf = send_buffer, .len = sizeof(send_buffer) };
    struct spi_buf rx_buf = { .buf = recv_buffer, .len = sizeof(recv_buffer) };
    struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 };
    struct spi_buf_set rx = { .buffers = &rx_buf, .count = 1 };

    while (1) {
        int error = spi_transceive(spi_device, &spi_config, &tx, &rx);
        printk("SPI error: %d\n", error);
        printk("TX buffer [0]: %x\n", send_buffer[0]);
        printk("RX buffer [0]: %x\n", recv_buffer[0]);
        k_sleep(K_MSEC(1000));
    }
}

タグ: Zephyr SPI Nordic NCS embedded

5月15日 15:00 投稿