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

Sending a single Byte over SPI

I'm working in SDK 14.2, and trying to send a single byte over SPI between two NRF5 boards using the SPI peripheral examples (1 master and 1 slave). However, SPI always seems to want to send at least 2 bytes at a time. 

I see that the errata acknowledges this issue and mentions the following work-around

My question is, as a newbie, how do I use this work-around properly? 

The workaround function has input 3 parameters:

1) The SPIM instance*

2) An unused PPI channel**

3) An unused GPIOTE channel***


*The SPIM instance should just be "spi" as its defined in the main.c of the SPI master example, right?

**I know there are 16 PPI channels, can I just say "16" to use the last one? Do I need to assign/initialize an unused PPI channel somewhere else? 

***Same for GPIOTE, I know there are 8 channels, can I just say "8" as the parameter? If not, how do I assign/initialize an unused GPIOTE channel?

Therefore, can I just copy the errata function code into my main.c and run the following line after my initialization functions?

setup_workaround_for_ftpan_58(spi, 16, 8);


What am I missing? Thank you!

Scott

  • Hi Scott,

    When working with SPI I highly recommend that you use a logic analyzer (ex. saleae) to check what is going on in the different signal lines.

    When it comes to the errata 58 here is a thread describing how to use it.

  • The best solution I found was given by joe.ker: 

    devzone.nordicsemi.com/.../43155

    I can confirm this works in SDK15.2 (Sept-2018). 

    if (len == 1)
    {
        err_code = nrf_drv_spi_transfer(&m_spi_master, m_buffer_tx_spi, len, m_buffer_rx_spi, 0);
    }
    else
    {
        err_code = nrf_drv_spi_transfer(&m_spi_master, m_buffer_tx_spi, len, m_buffer_rx_spi, len);
    }

  • Hi Eric, 

    I am using SDK 15. Need to send a single byte - address of the register. Nothing to read in the first transfer. Then send another byte "0" to read the data. I am using your approach of setting 0 for rx buffer len. But doesn't work. Did you change the driver as suggested by 

    This method did not work for me using SDK11. Nordic provided the following fix. The SDK drivers is not designed for this workaround.

    The stop event was not handled. In srf_drv_spi.c replace irq_handler_spim at line 557 with the below

    https://devzone.nordicsemi.com/f/nordic-q-a/11438/problems-implementing-workaround-to-get-nrf52-to-send-an-octet-one-byte-through-spi/43155?focus=true

    This is my code: 

    int main(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
        spi_config.miso_pin = 7;
        spi_config.mosi_pin = 15;
        spi_config.sck_pin  = 12;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        SEGGER_RTT_printf(0,"SPI example started.");
        
    
        while (1)
        {
            // Reset rx buffer and transfer done flag
            memset(m_rx_buf, 0, 1);
            spi_xfer_done = false;
    
            ret_code_t err_code;
    
    
            m_tx_buf = 0xAE;
    
            nrf_gpio_pin_clear(16);
            err_code = nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, 0);
    
            m_tx_buf = 0x00;
            err_code = nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, 1);
    
            APP_ERROR_CHECK(err_code);
    
            nrf_gpio_pin_set(16);
            SEGGER_RTT_printf(0,"SPI 1.");
            while (!spi_xfer_done)
            {
                __WFE();
            }
    
            SEGGER_RTT_printf(0,"SPI 2.");    
            SEGGER_RTT_printf(0, "%d Should be = 51\n", m_rx_buf);
            NRF_LOG_FLUSH();
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            nrf_delay_ms(200);
        }
    }
    

    I am getting stuck in while (!spi_xfer_done)
    {
    __WFE();
    }

    I am trying to use SPI with ADS1293 with nRF52832. Here's arduino code that works:

    byte readRegister(byte reg) {
      byte data;
      reg |= 1 << 7;
      digitalWrite(pin_SS, LOW);
      SPI.transfer(reg);
      data = SPI.transfer(0);
      digitalWrite(pin_SS, HIGH);
      return data;
    }

Related