Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52832 SPI function

Hi,

I am trying to make a simple function for writing via SPI. I am using the SPI example and it works fine. Now I would just like to make two SPI functions that I can use in my project:

- initSPI()

- ReadWriteSPI()

I have made the following so far and the event handler and initSPI seems to work fine if I keep the original example code for the spi transfer. It is just the ReadWriteSPI function which doesn't work. I am sure it has something to do with my function arguments. I am not too familiar with using pointers. The code below compiles without errors, but the LED does not flash as it is the case with the original sample code. See my code below.

Any help is appreciated.

Regards,

Jan

Here is my code so far

void spi_event_handler(nrf_drv_spi_evt_t const * p_event)
{
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.\r\n");
SEGGER_RTT_WriteString(0, "SPI transfer completed!\n");
if (m_rx_buf[0] != 0)
{
NRF_LOG_INFO(" Received: \r\n");
SEGGER_RTT_WriteString(0, "SPI received!\n");
NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
}
}


static void initSPI(void)
{
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = SPI_SS_PIN; // Slave Select pin
spi_config.miso_pin = SPI_MISO_PIN; // Output
spi_config.mosi_pin = SPI_MOSI_PIN; // Input
spi_config.sck_pin = SPI_SCK_PIN; // Clock pin
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));
}

void ReadWriteSPI(nrf_drv_spi_t spi, uint8_t m_tx_buf, uint8_t m_rx_buf, uint8_t m_length)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf, 0, m_length);
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));


while (!spi_xfer_done)
{
__WFE(); // Wait For Event
}

NRF_LOG_FLUSH();

bsp_board_led_invert(BSP_BOARD_LED_0);
nrf_delay_ms(1000);

}

int main(void)

{

 initSPI();

    while (1)

     {

      ReadWriteSPI(spi, m_tx_buf, m_rx_buf, m_length);

     }

}

  • Hi,

    I have just found that if I add the pointer operator '&' in front of m_tx_buf and m_rx_buf, then it seems to work. But why is that not necessary in the sample code..?

    So this seems to work

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf, m_length, &m_rx_buf, m_length));

    Regards,

    Jan

  • There is a bug in the code you list above, but due to the way the c compiler works you can fool the code into working. Look at the definition of nrf_drv_spi_transfer(), it requires pointers to the buffers

    ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance,
                                    uint8_t const * p_tx_buffer,
                                    uint8_t         tx_buffer_length,
                                    uint8_t       * p_rx_buffer,
                                    uint8_t         rx_buffer_length)
    

    The buffers mTxBuf[] and mRxBuf[] are pointers as they are defined as arrays, and are used as pointers by nrf_drv_spi_transfer():

    uint8_t mTxBuf[] = {ADS_CMND_RREG, NUMBER_OF_ADS_REGISTERS-1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    uint8_t mRxBuf[sizeof(mTxBuf)];
    
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&mAfeSpiInstance, mTxBuf, mRxTxBufLength, mRxBuf, mRxTxBufLength));
    

    Your function definition omits the pointer definition, and so expects uint8_t values, which in practice  probably passes as 32-bit values which you have been able to force to pointers (also 32-bit values)

    void ReadWriteSPI(nrf_drv_spi_t spi, uint8_t m_tx_buf, uint8_t m_rx_buf, uint8_t m_length)
    

    Change function definition to use pointers to correct this issue:

    void ReadWriteSPI(nrf_drv_spi_t spi, uint8_t *m_tx_buf, uint8_t *m_rx_buf, uint8_t m_length)
    

  • Thanks for your reply. It works now when I change the m_tx_buf and m_rx_buf arguments to pointers. So just to make sure that I understand it correctly...

    Since mTxBuf[] and mRxBuf[] in your example above are both defined as arrays, then simply writing 'mTxBuf' and 'mRxBuf' is the same as writing &mTxBuf and &mRxBuf if they were only defined as simple uint8_t (not an array of uint8_t). Is that correctly understood?

  • Technically you would write &mTxBuf[0] to correctly form the exact same pointer as mTxBuf; often something like &mTxBuf[strlen(mTxBuf)] is used to obtain a pointer to the location where one would append text to a string, assuming an ascii string of course as that has the \0 terminator which strlen() requires to identify the end-of-string. Note &mTxSomething where mTxSomething is a single character cannot be used as a string pointer, just a pointer to a single character. If that is passed to a function which requires a pointer to data the system would die a horrible death unless the length was set to 1.

  • Hello Jan,

    I am also trying same 

    Is it working Reg_read and  Reg_write function for SPI Communication?

    please let me know

    thanks and regards,

    rohit

Related