SPIM

Hi everyone,

I am trying to use SPIM for an external DAC. The DAC does not require MISO, only SCK, MOSI, and CS.

I configured SPIM like this:

#define SPI_DAC NRF_SPIM2
SPI_DAC->ENABLE = SPIM_ENABLE_ENABLE_Enabled;
SPI_DAC->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M8 << SPIM_FREQUENCY_FREQUENCY_Pos;
SPI_DAC->PSEL.CSN = NRF_SPIM_PIN_NOT_CONNECTED;
SPI_DAC->PSEL.SCK = NRF_GPIO_PIN_MAP(0, 29);
SPI_DAC->PSEL.MOSI = NRF_GPIO_PIN_MAP(1, 10);
SPI_DAC->PSEL.MISO = NRF_SPIM_PIN_NOT_CONNECTED;

SPI_DAC->TXD.LIST = 0;
SPI_DAC->RXD.LIST = 0;

SPI_DAC->TXD.PTR = (uint32_t)&dac_tx_buf;
SPI_DAC->TXD.MAXCNT = 2;

SPI_DAC->RXD.PTR = (uint32_t)&dac_rx_dummy;
SPI_DAC->RXD.MAXCNT = 2;

SPI_DAC->CONFIG =
    (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
    (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
    (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); // Mode 0

Then I try to start the transfer like this:

SPI_DAC->EVENTS_END = 0;
SPI_DAC->TASKS_START = 1;

while (!SPI_DAC->EVENTS_END) {
    LOG_DBG("in while");
    k_sleep(K_SECONDS(5));
}

SPI_DAC->EVENTS_END = 0;

The problem is that the code stays forever in this while loop, meaning EVENTS_END is never set.

I checked the signals with a logic analyzer. The CS pin goes low, but SCLK and MOSI do not toggle. They just stay in their idle states.

Does anyone know what could prevent SPIM from actually starting the transfer in this case?

  • Maybe try disabling SPIM before setting up the pins:

      // Manual says disable SPI before changing pins, but actually doesn't matter
      NRF_DAC0->ENABLE = 0;               // disable SPI
      
      // Set up pins here
      
      NRF_DAC0->ENABLE = 7;               // enable SPI
    

    Also use an actual pin for CSN (if using SPIM to drive CSN) and be sure to set pin output mode:

    This won't work:
      SPI_DAC->PSEL.CSN = NRF_SPIM_PIN_NOT_CONNECTED;
      
      Maybe try something like:
      NRF_GPIO->PIN_CNF[CSPIN]   = 0x301;  // output, high drive high and low H0H1
      NRF_GPIO->PIN_CNF[SCKPIN]  = 0x301;  // output, high drive high and low H0H1
      NRF_GPIO->PIN_CNF[MOSIPIN] = 1;      // output, standard drive S0S1
      SPI_DAC->PSEL.CSN = CSPIN;
      SPI_DAC->PSEL.SCK = NRF_GPIO_PIN_MAP(0, 29);
      SPI_DAC->PSEL.MOSI = NRF_GPIO_PIN_MAP(1, 10);
    

Related