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

how to drive spi CS line low for 32 bits.

Hi,

Can you please direct me to the document that explains about generating more than 8 bits of clock in SPI and keeping CS line low for that entire period.

Also, if i have to send two 16bit data, would i have to send them in lots of 8bit ? or i can send them as 16bits using nrf_drv_spi_transfer API?

I am modifying the SPI example found under SDK15/example/peripheral/spi.

And i have to achieve the sequence attached in the image. 

Thank you  

  • Hi,

     

    You are not waiting for the SPI transfer to be finished (missing while(!spi_xfer_done)).

    Since you initialize the SPI driver with a spi_handler set, this will set the driver into non-blocking mode. If you want blocking mode, set the handler to NULL when initializing the driver.

    Kind regards,

    Håkon

  • Hi Hakon,

    I need to enable pull ups on SPI lines. Datasheet of IC recommends to use 10K pull up resistors on SPI lines . How can I enable internal pull ups on SPI lines ? I have used  nrf_gpio_cfg_output API to enable PULL UPS by changing its definition in nrf_gpio.h like this : 

    __STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
    {
        nrf_gpio_cfg(
            pin_number,
            NRF_GPIO_PIN_DIR_OUTPUT,
            NRF_GPIO_PIN_INPUT_DISCONNECT,
            NRF_GPIO_PIN_PULLUP,
            NRF_GPIO_PIN_S0S1,
            NRF_GPIO_PIN_NOSENSE);
    }

    Is this the right way to do so or there is any other better way also??

    /**
     * Copyright (c) 2015 - 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.
     * 
     */
    #include "nrf_drv_spi.h"
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    
    static uint32_t       m_tx_buf4= 0b10000000001100000000000000000000;    //0X80BC
    //static uint16_t       m_tx_buf5= 0b;
     
     
    
    
    
    static uint16_t       m_rx_buf1[2];    /**< RX buffer. */
    static const uint8_t  m_length1 = 4;        /**< Transfer length. */
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    
    
    
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf1[0] != 0)
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf1, strlen((const char *)m_rx_buf1));
        }
    }
    
    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   = SPI_SS_PIN;
            spi_config.miso_pin = SPI_MISO_PIN;
            spi_config.mosi_pin = SPI_MOSI_PIN;
            spi_config.sck_pin  = SPI_SCK_PIN;
            spi_config.mode = NRF_DRV_SPI_MODE_2;
    
            nrf_gpio_cfg_output(SPI_SS_PIN);
            nrf_gpio_cfg_input(SPI_MISO_PIN, NRF_GPIO_PIN_PULLUP);
            nrf_gpio_cfg_output(SPI_MOSI_PIN);
            nrf_gpio_cfg_output(SPI_SCK_PIN);
            
            APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
           NRF_LOG_INFO("SPI example started.");
    
            memset(m_rx_buf1, 0, m_length1);
            spi_xfer_done = false;
    
              //Send 80H to BCH to read power factor from BCH register
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf4, m_length1, m_rx_buf1, m_length1));
              
             while (!spi_xfer_done)
            {
                __WFE();
            }
    
            
          
            NRF_LOG_FLUSH();
            bsp_board_led_invert(3);
            nrf_delay_ms(200);
    
    
          
          //  memset(m_rx_buf1, 0, m_length1);
          //  spi_xfer_done = false;
           // APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf5, m_length1, m_rx_buf1, m_length1));
              
          //    while (!spi_xfer_done)
          //  {
          //      __WFE();
          //  }
    
          //  NRF_LOG_FLUSH();
          //  bsp_board_led_invert(2);
          //  nrf_delay_ms(200);
    
       }
    

    Thanks,

  • Hi,

     

    I am sorry for the late reply.

    You cannot enable pull up on a gpio configured as output. If you need a pull-resistor on a GPIO configured as output, you can either set the level (1 or 0), or add an external pull-resistor.

    Kind regards,

    Håkon

  • Hi Hakon,

    I am still struggling to produce correct SPI timings . Below is the actual SPI timing sent to me by an Application Engineer from MICROCHIP. I need to replicate the same using nrf52840 chip :

    I am getting these SPI timings using the same operation as in above image through nrf52840 chip . 

    Can you identify what is going wrong with my attached firmware ????

    Any kind of help or suggestion will be appreciated . We are really running late now on our project .

    #include "nrf_drv_spi.h"
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    
    static uint16_t       m_tx_buf4= 0b1000000000110000;    //0X30H
    static uint16_t       m_tx_buf5= 0b0000000000000000;
     
    
    static uint8_t       m_rx_buf[2];    /**< RX buffer. */
    static const uint8_t  m_length = 4;        /**< Transfer length. */
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    
    
    
    void spi_event_handler(nrf_drv_spi_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));
        }
    }
    
    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   = SPI_SS_PIN;
            spi_config.miso_pin = SPI_MISO_PIN;
            spi_config.mosi_pin = SPI_MOSI_PIN;
            spi_config.sck_pin  = SPI_SCK_PIN;
            spi_config.mode = NRF_DRV_SPI_MODE_0;
            APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
            NRF_LOG_INFO("SPI example started.");
    
            while(1){
    
            memset(m_rx_buf, 0, m_length);
            spi_xfer_done = false;
           
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &m_tx_buf4, m_length, m_rx_buf, m_length));
            
                  while (!spi_xfer_done)
            {
                __WFE();
            }
    
            NRF_LOG_FLUSH();
    
    
            bsp_board_led_invert(3);
            nrf_delay_ms(200);  
    
          }
        
    }
    

    Thanks,

    Arshdeep

  • Hi,

     

    1. You are overflowing your buffer (m_rx_buffer) by 2 bytes, as the buffer is declared as 2 byte and you are receiving 4 bytes. This is _very crucial_ that you fix.

    2. You are no longer switching SPI mode as per the spec for the sensor you are communicating with.

    Best regards,

    Håkon

Related