-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
Describe the bug
Occasionally a call to spi_transceive() doesn't return. When this happens the system has to be reset to function again. Sometimes when this occurs the Bluetooth submodule (which is also used in this project) and the shell continues to operate and other times they have both stopped working.
What have you tried to diagnose or workaround this issue?
I've looked at the each thread stack usage and there doesn't seem to be an issue there. I've got the CONFIG_STACK_SENTINEL=y and CONFIG_STACK_CANARIES=y and neither of these detect failures while running. I've tried increasing and decreasing the priority of the thread that contains the spi_transceive call to above and below the Bluetooth threads but that didn't help.
After searching through Zephyr issues I noticed issue #12342 and PR #12400 and wondered if this is related so I tried to cherry pick those commits to the 1.13.0 release, I got as far as the first 2 commits but the third (845e383) had too many changes since 1.13.0 to be easy to apply. The two commits I could apply plus configuring CONFIG_SWAP_NONATOMIC=y didn't fix the issue.
To Reproduce
CONFIG_SPI=y
CONFIG_SPI_INIT_PRIORITY=70
CONFIG_SPI_0=y
CONFIG_SPI_0_NAME="SPI_0"
CONFIG_SPI_0_OP_MODES=1
CONFIG_SPI_0_IRQ_PRI=7
CONFIG_SPI_NRFX=y
CONFIG_SPI_0_NRF_SPIM=y
CONFIG_SPI_0_NRF_SCK_PIN=14
CONFIG_SPI_0_NRF_MOSI_PIN=16
CONFIG_SPI_0_NRF_MISO_PIN=11
CONFIG_SPI_0_NRF_ORC=0x00
`
static struct spi_buf stSpi_tx_buffs[3];
static struct spi_buf stSpi_rx_buffs[3];
static const struct spi_buf_set stSpi_tx_buff_array = {
.buffers = stSpi_tx_buffs,
.count = 3
};
static const struct spi_buf_set stSpi_rx_buff_array = {
.buffers = stSpi_rx_buffs,
.count = 3
};
void app_spi_init(void)
{
stSpim_dma = device_get_binding(SPIM_DRV_NAME);
stConfig_chipSelect.gpio_dev = stGpio_dev;
stConfig_chipSelect.gpio_pin = SPI_CS_PIN;
stConfig_chipSelect.delay = 0;
stConfig_Spim.frequency = 1000000;
stConfig_Spim.operation = (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB
| SPI_WORD_SET(8));
stConfig_Spim.slave = 0;
stConfig_Spim.cs = &stConfig_chipSelect;
uint8_t *au8_tx_data;
uint8_t *au8_rx_data;
au8_tx_data = (uint8_t*)&SPIS_stuMData;
au8_rx_data = (uint8_t*)&SPIS_stuSData;
stSpi_tx_buffs[0].buf = &au8_tx_data[0];
stSpi_tx_buffs[0].len = 200;
stSpi_tx_buffs[1].buf = &au8_tx_data[200];
stSpi_tx_buffs[1].len = 200;
stSpi_tx_buffs[2].buf = &au8_tx_data[2 * 200];
stSpi_tx_buffs[2].len = 200;
stSpi_rx_buffs[0].buf = &au8_rx_data[0];
stSpi_rx_buffs[0].len = 200;
stSpi_rx_buffs[1].buf = &au8_rx_data[200];
stSpi_rx_buffs[1].len = 200;
stSpi_rx_buffs[2].buf = &au8_rx_data[2 * 200];
stSpi_rx_buffs[2].len = 200;
}
`
The spi_transceive() call is happening at 20ms intervals.
spi_transceive(stSpim_dma, &stConfig_Spim, &stSpi_tx_buff_array, &stSpi_rx_buff_array);
Expected behavior
I've observed it on the CRO and can see that the SPIM operation completes (SS pin goes high, SPI clk signal stops) but a pin (used for debugging) that is set to high before the transfer and low after the transfer completes goes high and normally low afterwards but when the issue occurs it never goes low.
After up to an hour of operation the code stops working.
Impact
Showstopper
Screenshots or console output

In the above screenshot the blue falling pulse on the left shows a successful call to spi_transceive() and the one in the middle shows a successful transfer but no return to the calling thread. The blue trace shows the SS line. The green shows some post processing after the transfer is complete. The yellow shows the debug pin described above going high just before the transfer and low afterwards. Note the yellow trace also goes high and low again immediately after the transfer in the pulse on the left (redundantly showing the same information as the green trace).
Environment (please complete the following information):
- OS: Windows 7
- Toolchain: gcc-arm-none-eabi-7-2018-q2-update-win32-sha2.exe
- Zephyr 1.13.0
Additional context
We're using the nrf52832 SoC.
Bluetooth is configured as a peripheral and observer. It is configured to always be passively scanning.