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?