Issue with SPI4 RX buffer - always 0xFF data

Hi,

I got strange behavior of the SPI4 nrfx driver on nRF5340 (using nRF SDK v2.6.1 non-secure build with BLE enabled on NET core). Namely, every time I try to receive bytes from external MEMS, the RX buffer contain a 0xFF value. The external device response correctly, I checked it with logic analyzer.

My devicetree configuration looks like this:

spi4_default: spi4_default {
    group1 {
        psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,
                <NRF_PSEL(SPIM_MOSI, 0, 9)>,
                <NRF_PSEL(SPIM_MISO, 0, 10)>;
        nordic,drive-mode = <NRF_DRIVE_H0H1>;
    };
};

spi4_sleep: spi4_sleep {
    group1 {
        psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,
                <NRF_PSEL(SPIM_MOSI, 0, 9)>,
                <NRF_PSEL(SPIM_MISO, 0, 10)>;
        low-power-enable;
    };
};

&spi4 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    pinctrl-0 = <&spi4_default>;
    pinctrl-1 = <&spi4_sleep>;
    pinctrl-names = "default", "sleep";
    cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
};

I'm using nrfx driver with the following initialization and receive:

int spi_Init(void)
{
   int ret = 0;
   nrfx_err_t err_code;

   if (_isSpiInit)
   {
      return NRFX_ERROR_ALREADY_INITIALIZED;
   }

   nrfx_spim_uninit(&spiInst);

#if defined(__ZEPHYR__)
   IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SPIM_INST_GET(SPI_INST)), IRQ_PRIO_LOWEST,
               NRFX_SPIM_INST_HANDLER_GET(SPI_INST), 0, 0);
#endif

#if USE_SPI_HARDWARE_CS == 1
   nrfx_spim_config_t spiConfig = NRFX_SPIM_DEFAULT_CONFIG(SPI_SCK_PIN, SPI_MOSI_PIN, SPI_MISO_PIN, SPI_CS_PIN);
   spiConfig.use_hw_ss = true;
#else
   nrfx_gpiote_output_config_t config = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;

   err_code = nrfx_gpiote_output_configure(&gpioteInst, SPI_CS_PIN, &config, NULL);
   if (err_code != NRFX_SUCCESS)
   {
      LOG_ERR("Output configure failed: %d", err_code);
      return -1;
   }

   nrfx_gpiote_out_set(&gpioteInst, SPI_CS_PIN);
   spiConfig.use_hw_ss = false;
#endif
   spiConfig.mode = NRF_SPIM_MODE_0;
   spiConfig.ss_duration = 0x01;
   spiConfig.miso_pin = SPI_MISO_PIN;
   // spiConfig.frequency = NRFX_MHZ_TO_HZ(8);

   err_code = nrfx_spim_init(&spiInst, &spiConfig, NULL, NULL);
   if (err_code != NRFX_SUCCESS)
   {
      LOG_ERR("Init MEMS SPI failed: %d", err_code);
      return -1;
   }
   else
   {
      LOG_INF("MEMS SPIM configured");
      _isSpiInit = true;
   }

   return ret;
}

int spi_Read(uint8_t *data, uint16_t bytes_number)
{
   int err_code;
   uint8_t tx = *data;
   uint8_t rx[1 + 3] = {0}; // test

   // nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(&tx, 1, rx, bytes_number + 1);
   nrfx_spim_xfer_desc_t xfer_desc_tx = NRFX_SPIM_XFER_TX(&tx, 1);
   nrfx_spim_xfer_desc_t xfer_desc_rx = NRFX_SPIM_XFER_RX(rx, 1);

   spimXferDesc.rx_length = 0;
   spimXferDesc.tx_length = 1;
   txBuff[0] = 0x01;
#if USE_SPI_HARDWARE_CS == 0
   nrfx_gpiote_out_clear(&gpioteInst, SPI_CS_PIN);
#endif
   err_code = nrfx_spim_xfer(&spiInst, &spimXferDesc, 0);
   if (err_code != NRFX_SUCCESS)
   {
      LOG_ERR("MEMS SPI transfer failed: %d", err_code);
      return -1;
   }
   
   spimXferDesc.rx_length = 1;
   spimXferDesc.tx_length = 0;

   err_code = nrfx_spim_xfer(&spiInst, &spimXferDesc, 0);
   if (err_code != NRFX_SUCCESS)
   {
      LOG_ERR("MEMS SPI transfer failed: %d", err_code);
      return -1;
   }

#if USE_SPI_HARDWARE_CS == 0
   nrfx_gpiote_out_set(&gpioteInst, SPI_CS_PIN);
#endif
   memcpy(&data[1], &rx[0], 1);

   return 0;
}

I tried different compilation, with static RX buffer, single TX/RX buffer, single TRX transfer, TX and RX transfer, CS drived by hardware, changing MISO pin, using IRQs, blocking mode but nothing helped. I was wondering, if the NET core can do something with the P0.10, but I deleted node with gpio_forwarder, changed it's gpios, but it also did nothing better.

I found related ticket (devzone.nordicsemi.com/.../spi-communication-issue-zephyr-driver-works-nrfx-driver-returns-0xff), but it was solved by fixing MISO gpio configuration.

I had added a devicetree overlay for hci_ipc project for NET core with different UART0 RTS pin than P0.10, also didn't help.
 In my case, the pinout is correct. In prj.conf I have CONFIG_NRFX_SPIM4=y, CONFIG_NFCT_PINS_AS_GPIOS=y

What else can I do to receive a correct value and what is a source of that issue? 

Parents Reply Children
No Data
Related