This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPI Master stops working after S132 softdevice enabled

Initialization:

The softdevice is initialized as in the BLE UART example. The body of the ble_stack_init() function is identical to the BLE UART example.

SPI is initialized as in the SPI peripheral example, but I have gone over to writing the registers directly, just to verify that there is nothing weird happening with the spi driver. I get the exact same behavior both when using the nrf spi driver and when working with the registers directly.

SPI configuration is as follows:

#define IMU_SCK_PIN 0
#define IMU_MOSI_PIN 1
#define IMU_MISO_PIN 5

NRF_P0->PIN_CNF[IMU_SCK_PIN] = 0b11;
NRF_SPIM0->PSEL.SCK = IMU_SCK_PIN;

NRF_P0->PIN_CNF[IMU_MOSI_PIN] = 0b11;
NRF_SPIM0->PSEL.MOSI = IMU_MOSI_PIN;

NRF_P0->PIN_CNF[IMU_MISO] = 0b00;
NRF_SPIM0->PSEL.MISO = IMU_MISO_PIN;

NRF_SPIM0->FREQUENCY = 0x10000000; // 1Mhz
NRF_SPIM0->CONFIG = 0b000;
NRF_SPIM0->ENABLE = 7;

The transfer is then done as follows:

uint8_t tx_buffer[2] = { 0x80, 0x08 };
uint8_t rx_buffer[2];

NRF_SPIM0->TXD.PTR = (uint32_t) tx_buffer;
NRF_SPIM0->TXD.MAXCNT = 2;
NRF_SPIM0->TXD.LIST = 0;

NRF_SPIM0->RXD.PTR = (uint32_t) rx_buffer;
NRF_SPIM0->RXD.MAXCNT = 2;
NRF_SPIM0->RXD.LIST = 0;

SEGGER_RTT_WriteString(0, "xfer start\r\n");

NRF_SPIM0->EVENTS_END = 0;
NRF_SPIM0->TASKS_START = 1;
while (!NRF_SPIM0->EVENTS_END);
NRF_SPIM0->EVENTS_END = 0;

SEGGER_RTT_WriteString(0, "xfer done\r\n");

Case 1:

Everything works as expected when I try to do a SPI transfer before the ble_stack_init(); function has been called called, xfer start prints, and shortly after xfer done prints.

EVENTS_START is asserted immediately when TASKS_START is written to. EVENTS_ENDRX and EVENTS_ENDTX are both asserted when the transfer is done, and EVENTS_END is asserted shortly afterwards. EVENTS_STOPPED is never asserted, as expected.

Case 2:

However, after ble_stack_init(); has been called, the the EVENTS_END flag is never asserted, and the while loop never finishes. xfer start prints, but xfer done is never printed.

EVENTS_START is asserted immediately when TASKS_START is written to, but no other events are asserted. I validate that the interrupt enable register is set to 0 before I start, so I don't think any interrupt could reset the register before the loop checks it.

Additional information:

  • My chip is marked N52832 QFAAB0 1701FH
  • The board is the NRF52 DK, PCA10040
  • Softdevice S132 v5.0.0
  • SDK v14
  • GCC

Does anyone have any ideas what the problem might be? Hope I didn't do anything way too stupid. I have been struggling with this for a little bit, and it would be really nice to get it sorted out.

Related