2021.11.15現在 → nRF9160 feather にて、Ethernet Sheild(W5500 と SDCard ) を 使う際の注意点

追記：overlay ファイルにて、 spim3 の
compatible = "nordic,nrf-spim";
を
compatible = "wiznet,w5500";
に変更したら、下記の症状はなくなり、
irq_connect_dynamicを利用したり、nrfx_spimライブラリの修正する必要はなくなった。

よって、この記事の対処は不要になった。


<del>

以前の記事の補足。

https://qiita.com/KiKUiCHi_R1R/items/b89abb6464eaabcf1207


W5500 と SPI 通信を行う際、以下のファイルに関数を追加したことを忘れていた。

・ nrfx_spim.h (ncs/modules/hal/nordic/nrfx/drivers/include/nrfx_spim.h)
・ nrfx_spim.c (ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_spim.c)

```nrfx_spim.h(追加分のみ)


nrfx_err_t nrfx_spim_update(nrfx_spim_t const *        p_instance,
                            nrfx_spim_config_t const * p_config,
                            nrfx_spim_evt_handler_t    handler,
                            void *                     p_context);

```


```nrfx_spim.c(追加分のみ)
nrfx_err_t nrfx_spim_update(nrfx_spim_t const *        p_instance,
                            nrfx_spim_config_t const * p_config,
                            nrfx_spim_evt_handler_t    handler,
                            void *                     p_context)
{
    NRFX_ASSERT(p_config);
    spim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
    nrfx_err_t err_code;


    NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_reg;

    p_cb->handler = handler;
    p_cb->p_context = p_context;

    uint32_t mosi_pin;
    uint32_t miso_pin;
    // Configure pins used by the peripheral:
    // - SCK - output with initial value corresponding with the SPI mode used:
    //   0 - for modes 0 and 1 (CPOL = 0), 1 - for modes 2 and 3 (CPOL = 1);
    //   according to the reference manual guidelines this pin and its input
    //   buffer must always be connected for the SPI to work.
    if (p_config->mode <= NRF_SPIM_MODE_1)
    {
        nrf_gpio_pin_clear(p_config->sck_pin);
    }
    else
    {
        nrf_gpio_pin_set(p_config->sck_pin);
    }

    nrf_gpio_pin_drive_t pin_drive;
    pin_drive = NRF_GPIO_PIN_S0S1;

    nrf_gpio_cfg(p_config->sck_pin,
                 NRF_GPIO_PIN_DIR_OUTPUT,
                 NRF_GPIO_PIN_INPUT_CONNECT,
                 NRF_GPIO_PIN_NOPULL,
                 pin_drive,
                 NRF_GPIO_PIN_NOSENSE);
    // - MOSI (optional) - output with initial value 0,
    if (p_config->mosi_pin != NRFX_SPIM_PIN_NOT_USED)
    {
        mosi_pin = p_config->mosi_pin;
        nrf_gpio_pin_clear(mosi_pin);
        nrf_gpio_cfg(mosi_pin,
                     NRF_GPIO_PIN_DIR_OUTPUT,
                     NRF_GPIO_PIN_INPUT_DISCONNECT,
                     NRF_GPIO_PIN_NOPULL,
                     pin_drive,
                     NRF_GPIO_PIN_NOSENSE);
    }
    else
    {
        mosi_pin = NRF_SPIM_PIN_NOT_CONNECTED;
    }
    // - MISO (optional) - input,
    if (p_config->miso_pin != NRFX_SPIM_PIN_NOT_USED)
    {
        miso_pin = p_config->miso_pin;
        nrf_gpio_cfg(miso_pin,
                     NRF_GPIO_PIN_DIR_INPUT,
                     NRF_GPIO_PIN_INPUT_CONNECT,
                     p_config->miso_pull,
                     pin_drive,
                     NRF_GPIO_PIN_NOSENSE);
    }
    else
    {
        miso_pin = NRF_SPIM_PIN_NOT_CONNECTED;
    }
    // - Slave Select (optional) - output with initial value 1 (inactive).

    // 'p_cb->ss_pin' variable is used during transfers to check if SS pin should be toggled,
    // so this field needs to be initialized even if the pin is not used.
    p_cb->ss_pin = p_config->ss_pin;

    if (p_config->ss_pin != NRFX_SPIM_PIN_NOT_USED)
    {
        if (p_config->ss_active_high)
        {
            nrf_gpio_pin_clear(p_config->ss_pin);
        }
        else
        {
            nrf_gpio_pin_set(p_config->ss_pin);
        }
        nrf_gpio_cfg(p_config->ss_pin,
                     NRF_GPIO_PIN_DIR_OUTPUT,
                     NRF_GPIO_PIN_INPUT_DISCONNECT,
                     NRF_GPIO_PIN_NOPULL,
                     pin_drive,
                     NRF_GPIO_PIN_NOSENSE);
        p_cb->ss_active_high = p_config->ss_active_high;
    }

    nrf_spim_pins_set(p_spim, p_config->sck_pin, mosi_pin, miso_pin);
    nrf_spim_frequency_set(p_spim, p_config->frequency);
    nrf_spim_configure(p_spim, p_config->mode, p_config->bit_order);

    nrf_spim_orc_set(p_spim, p_config->orc);

    nrf_spim_enable(p_spim);

    if (p_cb->handler)
    {
        NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_reg),p_config->irq_priority);
        NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_reg));
    }

    p_cb->transfer_in_progress = false;
    p_cb->state = NRFX_DRV_STATE_INITIALIZED;

    err_code = NRFX_SUCCESS;
    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}

```


SDカードのSPIライブラリにて、Ethernet側のSPIまで初期化されてしまうので、
従来の nrfx_spim_init() 関数を使用するとエラーになる。

そのため、nrfx_spim_initから、必要部分だけを抜き出し上書きだけすることで W5500 と SDカードライブラリを無理やり共存させている。

以前に記事にも書いたが、割り込みの初期化処理において、
```IRQ_CONNECT()```
がエラーになるので、
```irq_connect_dynamic()```
に変更する必要があるのことにも注意が必要。
</del>

* * *
以上。
* * *