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

SPI configuration for nrf52832

I've configured the SPI with DMA module as in the code below.

I've loaded the tx buffer with sample data and start the transaction; however, I'm not reading anything either on the MOSI pin or the MISO pin. The SCK pin also stays low. The tx and rx end events do go from 0 to 1 correctly.

Any ideas what I'm doing wrong?

Thanksspi code.rtf

  • I made the changes you suggested. Actually the chip select pin is separate from the spi module. It shouldn't have any effect on the clock and data signals. I still don't get anything on the mosi line after the start task is initiated.

  • Here's the amended code with your changes. I also put in a loop for sending continuously the same data. There's still nothing on the MOSI line.

    #define CSPIN 11  //spi chip select
    #define SCKPIN 12  //spi clock
    #define MOSIPIN 13  //spi mosi
    #define MISOPIN 14  //spi miso
    
    int main()
    {
      NRF_GPIO->PIN_CNF[CSPIN] = 1;  //output
      NRF_GPIO->PIN_CNF[SCKPIN] = 1;  //output
      NRF_GPIO->PIN_CNF[MOSIPIN] = 1;  //output
      NRF_GPIO->PIN_CNF[MISOPIN] = 0;  //input pin, input buffer connected, no pull, S0S1, sense disabled
      NRF_SPIM0->PSEL.SCK = SCKPIN;
      NRF_SPIM0->PSEL.MOSI = MOSIPIN;
      NRF_SPIM0->PSEL.MISO = MISOPIN;
      NRF_SPIM0->CONFIG = 0b010;  //CPOL 0 -- clock polarity active high, CPHA 1 -- sample on trailing clock edge, send Msb first
      NRF_SPIM0->FREQUENCY = 0x02000000;  //250 kbps
      uint8_t spiTXBuf[2];  //2 byte tx buffer
      uint8_t spiRXBuf[2];  //2 byte rx buffer
      spiTXBuf[0] = 0b10101010;  //example byte
      spiTXBuf[1] = 0b10101010;  //example byte
      NRF_SPIM0->TXD.PTR = (uint32_t)((uint8_t *)spiTXBuf);
      NRF_SPIM0->TXD.MAXCNT = 2;
      NRF_SPIM0->RXD.PTR = (uint32_t)((uint8_t *)spiRXBuf);
      NRF_SPIM0->RXD.MAXCNT = 2;
      NRF_SPIM0->ENABLE = 7;  //enabled
      while(1)
      {
        NRF_SPIM0->EVENTS_ENDTX = 0;
        NRF_SPIM0->EVENTS_ENDRX = 0;
        NRF_GPIO->OUTCLR = 1 << CSPIN;  //drive cs low to initiate spi comm
        for(uint8_t i = 0; i < 21; i++) __asm__("nop\n\t");  //low for 21 machine instructions
        NRF_SPIM0->TASKS_START = 1;
        while(!NRF_SPIM0->EVENTS_ENDTX);  //last byte transmitted
        while(!NRF_SPIM0->EVENTS_ENDRX);  //last byte received
        NRF_SPIM0->TASKS_STOP = 1;
        for(uint8_t i = 0; i < 3; i++) __asm__("nop\n\t");
        NRF_GPIO->OUTSET = 1 << CSPIN;
        for(uint8_t i = 0; i < 21; i++) __asm__("nop\n\t");
      }
    }

  • Ok last change, this makes your code work on my SPI; SPI has to be enabled before you write the Tx and Rx buffers info:

      NRF_SPIM0->ENABLE = 7;  //enabled
    
      NRF_SPIM0->TXD.PTR = (uint32_t)((uint8_t *)spiTXBuf);
      NRF_SPIM0->TXD.MAXCNT = mRxTxBufLength; //2;
      NRF_SPIM0->RXD.PTR = (uint32_t)((uint8_t *)spiRXBuf);
      NRF_SPIM0->RXD.MAXCNT = mRxTxBufLength; //2;
    

  • The placement of the ENABLE command doesn't seem to have any effect for me. I see the clock on my scope but nothing on the MOSI pin. It should look like the square wave of the clock signal since the data is 0b10101010

  • Have a look at this driver for reference.  It works across nRF5x series, support both DMA and non-dma, master/slave. https://github.com/I-SYST/EHAL/blob/master/ARM/Nordic/src/spi_nrf5x.cpp

Related