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.

  • Figured it out now thanks to your question for the scope. I have none here at my current position, but use UART with the LOG_INFO functions for debugging. The event handler from the SPIM example was not fundamentally changed (here in original):

    void spim_event_handler(nrfx_spim_evt_t const * p_event,
                           void *                  p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf[0] != 0)
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
        }
    }
    
    /**
     * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */

    With this, however, there were two problems:

    1. I first read the if condition as "if(buffer_empty)", however it only adresses the first byte. If that is empty, it will report nothing recieved, even if there is data coming afterwards.

    2. As you see above, I also placed the logging function outside the handler (and the if), but NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf)) will ALSO report nothing - independently -  if alone the first byte is empty, which is very unintuitive if you have a look at its arguments. In order to get "scope-like" data I wrote an alternative logging function:

    NRF_LOG_INFO("\"0x%X\", \"0x%X\", \"0x%X\", \"0x%X\" and \"0x%X\" from slave.", m_rx_buf[0], m_rx_buf[1], m_rx_buf[2], m_rx_buf[3], m_rx_buf[4]);

    See the results for yourself:

    <info> app: Sent "0xF5" and "0xFF" to slave. Got:
    <info> app: "0x0", "0x98" and "0x0" from slave.  //rx_buf[3]
    
    <info> app: Sent "0xF5" and "0xFF" to slave. Got:
    <info> app: "0xFF", "0x98", "0x0" and "0xEB" from slave.  //rx_buf[4]
    
    <info> app: Sent "0xF5" and "0xFF" to slave. Got:
    <info> app: "0x0", "0x98", "0x0", "0xEB" and "0x46" from slave.  //rx_buf[5]

    It seems data always arrived, but the first byte changed dependent on how large the rx_buf is. Why this happens I still do not know, but its irrelevant anyway, just need to check for the second byte and thats always there as we know now.

    You might consider changing the hexdump function to really dump all the hex values even if the first byte is 0, to avoid future confusion. But thats only a suggestion, my matter is settled now.

    Thank you greatly for your suggestions and support!

  • "You might consider changing the hexdump function to really dump all the hex values even if the first byte is 0, to avoid future confusion. But thats only a suggestion, my matter is settled now."
    -I agree, that's a dangerous assumption given the nature of the SPI protocol. 

    The content of byte 0 must be determined by the nRF MCU because the slave has no idea how long any given transfer will be when it transmits byte 0. 

    Maybe the array is overwritten by some other part of the program or something something compiler optimization magic. 

Related