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

using the spim driver

Hi, the peripheral/spi example calls for nrf_drv_spi.h, which is located in the legacy directory in SDK 15. I found this post in the devzone:

So far we have kept the SPI interface for backwards compatibility (so you can easily port code from the nRF51/nRF52832 that uses it), but it might be removed in future products, so I would recommend using the SPIM instead. The SPIM interface is also more efficient since all the data transfer is handled by the DMA controller.

Since I'm starting a new project I want to use the SPIM driver, I am however unsure how to achieve that. The registers in nrf52832 datasheet clearly indicate that there is SPIM. However nrfx_spim is only available for pca10056 as an example.

Can someone explain how to use the new (non-legacy) SPIM driver with the nrf52832 DK? I want to simply connect it to a sensor slave.

  • You can use the SPI Master Example or the SPI Transaction Manager Example

    The SPIM peripheral is identical in 52832 and 52840, and they share the same driver. 

  • I'm confused now, since the nrfx_spim example is definitly only for 52840. I made it work for 52832 by copying the main.c to the spi example, and modifying some parts (mainly removing the extended feature stuff). Now I only need to use nrfx_spim.h and not the legacy nrf_drv_spi.h.

    I made connection to my sensor and can read and write registers now. However I encountered a strange behaviour that I could not grasp for more than one day now, maybe you have an idea:

    static uint8_t       m_rx_buf[4] = {0};               /**< RX buffer. */
    static const uint8_t m_rx_length = sizeof(m_rx_buf);  /**< Read length. */

    Reading e.g. the whoami register works fine with the RX buffer at a length of 4 (see above code). Setting it to 3 or 5 however will result in the rx buffer being empty. I tried many values, and found out that setting the array length to 10 will work again, 16 also, but in between all will return nothing. 17-23 will work, 23 not, but 24 again, 25 not.

    I'm out of ideas, since the ONLY thing I modify is the length of the rx buffer, it should not affect the data read at all, let alone the sensor itself (data send to sensor is always the same).

    edit: the code for transfer remained mostly the same, I only adjust m_tx_buf before (always size 2).

    m_tx_buf[0] = 0x80+0x41; //read data
    m_tx_buf[1] = 0xFF;
    
    memset(m_rx_buf, 0, m_rx_length); 
    spi_xfer_done = false; 
    APP_ERROR_CHECK(nrfx_spim_xfer(&spi, &xfer_desc, 0)); 
    while (!spi_xfer_done) __WFE();
    NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    NRF_LOG_FLUSH();

  • That is indeed wierd...

    What is your Over Read Character?

    Do you have a scope of the bus? 

  • I tried 0xFF and 0x00 as ORC, without any impact.

    Bus is 4-wire SPI in mode 3, initialized as follows. I'm quite sure this is correct, since i get valid data from whoami register, not so if I change e.g. spi mode (tried everything). 

        nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
        spi_config.frequency      = NRF_SPIM_FREQ_1M;
        spi_config.ss_pin         = 29;
        spi_config.miso_pin       = 28;
        spi_config.mosi_pin       = 4;
        spi_config.sck_pin        = 3;
        spi_config.mode           = NRF_SPIM_MODE_3;
        spi_config.orc            = 0xFF;
        spi_config.bit_order= NRF_SPIM_BIT_ORDER_MSB_FIRST;
        spi_config.ss_active_high = false;

    Two points I'm unsure about, since direct config isn't possible, but it was explicitly mentioned in the datasheet of the sensor:

    1. SCK is "active low", same as SS, but for SCK there is no setting to specify that. Is this taken care of automatically?

    2. Latching and transitioning data is recommended to be done alternating between leading and trailing edge. Is this also taken care of?

    But to be honest, since I can write and read data I assume the setup is correct. I tried all SPI modes and changed other settings, but all resulted in failure while this current one works. Since the only thing that changes is the read buffer, the reason must lay within the nRF52832, which is why I'm posting here and not in the sensor's manufacturers forum.

    1. From nrf_spim_mode_t; SCK active low, sample on trailing edge of clock.
    2. I've never read anything about alternating between leading and trailing edge. What is the general idea and why is that recommended? 

    I need the datasheet for the sensor, and a scope of the bus when using 3 and 4 byte RX buffers?

Related