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

SPI Communication is not working in NRF52840

Hi,

I am using nrf52840 customized dongle  in our project. We have interfaced ADS1118 using spi communication with nrf52840 (customized dongle). The problem here with the spi communication is i am not able to read the data from the ADS1118  using spi communication i am reading the adc value as 0.

When we checked with the oscilloscope  we are not getting clk signal ,MISO ,MOSI signal only Chip select is high.

I am here by attaching the code Please give me the solution what could be the problem.

/**
* Copyright (c) 2015 - 2019, 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"
#include "SEGGER_RTT.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. */

#define TEST_STRING "Nordic"
static uint8_t m_tx_buf[] = {0x0CB,0x9B}; //TEST_STRING; /**< TX buffer. */
static uint8_t m_rx_buf [2];//[sizeof(TEST_STRING) + 1]; /**< RX buffer. */
static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */
static uint8_t m_tx_buf1[] = {0x00,0x00}; //TEST_STRING; /**< TX buffer. */
static uint8_t m_rx_buf1[2]; //TEST_STRING; /**< TX buffer. */

/**
* @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.");
SEGGER_RTT_printf(0," Transfer completed\n");

for(int i=0;i<5;i++)
{
NRF_LOG_INFO("Data=%x\n.",m_rx_buf[i]);
}

if (m_rx_buf[0] != 0)
{
NRF_LOG_INFO(" Received:");
SEGGER_RTT_printf(0," Recieved\n");

NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
}
}

int main(void)
{
bsp_board_init(BSP_INIT_LEDS);
uint8_t data=0xff;

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;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

NRF_LOG_INFO("SPI example started.");

while (1)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf, 0, m_length);
spi_xfer_done = false;

nrf_gpio_cfg_output(31);
nrf_delay_us(100);


nrf_gpio_pin_clear(31);
nrf_delay_ms(100);
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf1, m_length, m_rx_buf1, m_length));
SEGGER_RTT_printf(0," Data Received1: %x\n",m_rx_buf1[0]);
SEGGER_RTT_printf(0," Data Received2: %x\n",m_rx_buf1[1]);


APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
SEGGER_RTT_printf(0," Received1: %x\n",m_rx_buf[0]);
SEGGER_RTT_printf(0," Received2: %x\n",m_rx_buf[1]);

nrf_delay_ms(200);
nrf_delay_ms(200);
nrf_gpio_pin_set(31);

while (!spi_xfer_done)
{
__WFE();
}

NRF_LOG_FLUSH();

bsp_board_led_invert(BSP_BOARD_LED_0);
nrf_delay_ms(500);
}
}

Parents
  • Hi 

    There are a few checks you can do:

    1. Have you configured the SPI for Mode 1 (as per the ADS1118 datasheet - the SPI mode should be 1)? Default SPI config has Mode 0.

    2. Make sure to configure CS as active low. 

    3. Also need to wait for Dout/DRDY to transition to low, which means conversion data is now available 

    4. after making sure of above, check the signals on the SPI pins on ADS1118 with help of oscilloscope / logic analyzer. You can also use PPK2 logic ports. Make sure the signals are as expected.  

     

  • Thanks for the reply.

    The SPI mode  is already set to 1 ,and the chip select is also made as active low ,but we have not waited for the DRDY pin to low and now we are waiting for the DRDY pin to low. When we made this change in the program  now we are reading as FF value from the MISO pin.

    Now the problem is i need to read the ADC channel 0 since it is connected to ground it should read as zero but we are reading as FF when  we read the other ADC channel it is also reading as zero. Even we have changed the PGA  gain ,Data sampling rate to different value but whatever the value we have changed in the configuration register we are reading as FF.

    So when we checked in the oscilloscope the chip select is high, the MISO pin also high but in the clock signal  we are  not getting clock , and in the MOSI signal the signal is low.

    Can you please tell me where we are going wrong . I am attac

    /**
     * Copyright (c) 2015 - 2019, 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 <stdbool.h>
    #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"
    #include "SEGGER_RTT.h"
    #include "ADS118.h"
    //#include "drv_gpio.h"
    #include "boards.h"
    #include "nrf_gpio.h"
    #include "nrf_drv_gpiote.h"
    #include "app_error.h"
    #include "nrf_drv_qspi.h"
    
    
    static uint8_t       m_tx_buf[2]={0x00,0x00}; //= TEST_STRING;           /**< TX buffer. */
    static uint8_t       m_rx_buf[2];//sizeof(TEST_STRING) + 1];    /**< RX buffer. */
    static const uint8_t m_length = sizeof(40);        /**< Transfer length. */
    static uint8_t       m_rx_buf1[2];//sizeof(TEST_STRING) + 1];    /**< RX buffer. */
    
    #define PIN_IN 30
    
    
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */ // 0 indicates cpha=0 and cpol=0
    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. */
    
    //#define TEST_STRING "Nordic"
    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    				nrf_gpio_pin_set(27);			
    				
    	      nrf_gpio_pin_clear(31);
    	      nrf_delay_ms(500);
            
    	
    				nrf_gpio_pin_clear(27);
    				nrf_gpio_pin_set(31);
    	      
    				nrf_delay_ms(500);
    	//nrf_delay_ms(100);
    	
      //  nrf_drv_gpiote_out_toggle(PIN_OUT);
    }
    static void gpio_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_gpiote_init();
        // APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
        //err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
        //APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);//GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
        in_config.pull = NRF_GPIO_PIN_PULLUP;
    
        err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    
    /**
     * @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.");
    	 //SEGGER_RTT_printf(0, "variable value: %s\n", strlen((const char *)m_rx_buf));
        if (m_rx_buf1[0] != 0)
        {
         //   NRF_LOG_INFO(" Received:");
    			  NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf1));
    			 // SEGGER_RTT_printf(0," Transfer12 completed. Received: %d\n",m_rx_buf1);
        }
    }
    
    
    int main(void)
    {
    	  
    		uint32_t i;
        uint32_t err_code;
    	  nrf_gpio_cfg_output(31);
    		nrf_gpio_cfg_output(27);
        uint8_t temp[2]={0x06,0xeb};			
    	
       // 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;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    	
    	
    	 
    	  nrf_gpio_pin_clear(31);//cs
    	  nrf_delay_us(100);
    																					
    			gpio_init();
    		
    		APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 1));
    		nrf_delay_ms(100);
    	
    		
    		while (!spi_xfer_done)
           {
                __WFE();
            }
    		nrf_gpio_pin_set(31);
    	
    		
    		
        while (1)
        {
    			nrf_gpio_pin_clear(31);
    			nrf_delay_us(100);		
    		
    			APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, temp, 2, m_rx_buf1, 2));
    		  while (!spi_xfer_done)
            {
                __WFE();
            }
    		 	 nrf_delay_ms(100);
    								
    				nrf_gpio_pin_set(31);
    				SEGGER_RTT_printf(0," Data Received1: %x\n",m_rx_buf1[0]);
    				SEGGER_RTT_printf(0," Data Received2: %x\n",m_rx_buf1[1]);
       
       
    	     
            
        }
    }
    
    
    
    
    
    
    
    #define NRF_DRV_SPI_DEFAULT_CONFIG                           \
    {                                                            \
        .sck_pin      = NRF_DRV_SPI_PIN_NOT_USED,                \
        .mosi_pin     = NRF_DRV_SPI_PIN_NOT_USED,                \
        .miso_pin     = NRF_DRV_SPI_PIN_NOT_USED,                \
        .ss_pin       = NRF_DRV_SPI_PIN_NOT_USED,                \
        .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY,         \
        .orc          = 0xFF,                                    \
        .frequency    = NRF_DRV_SPI_FREQ_4M,                     \
        .mode         = NRF_DRV_SPI_MODE_1,                      \
        .bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,         \
    }
    
    hing the code here.

    Please help me to resolve this problem.

  • Hi 

    I can say the following after going through your code:

    1. I think you need to study the ADS1118  datasheet carefully. 

    2. The Dout data frame is either 16bit or 32bit. When you are using single-shot conversion by using CS pin, the data frame would be 16bit.  

    3. There is no code to initialize the config register. 

    4. Config register is of R/W type, so you can test if the SPI communication is working ok or not by writing to config register and reading it back and confirming. 

    5. After confirming communication is working ok, you can set up ADS1118 for measuring the temperature by using its internal temperature sensor, which will avoid any external circuit issues. If you can read the current temperature correctly then the device is working fine. Then you can go ahead with reading analog inputs. 

    6. if the above steps do not work and if this is your custom board, you need to make sure the chip is soldered correctly. you should also provide test points on board for easy access to various pins of the chip.

    7. Further you can also run the code in debug more in SES, and step through each code and see if the SPI pins have expected logic on logic analyzer / oscilloscope. you can also see if the code goes into any hard faults.  

    hope the above helps..  

Reply
  • Hi 

    I can say the following after going through your code:

    1. I think you need to study the ADS1118  datasheet carefully. 

    2. The Dout data frame is either 16bit or 32bit. When you are using single-shot conversion by using CS pin, the data frame would be 16bit.  

    3. There is no code to initialize the config register. 

    4. Config register is of R/W type, so you can test if the SPI communication is working ok or not by writing to config register and reading it back and confirming. 

    5. After confirming communication is working ok, you can set up ADS1118 for measuring the temperature by using its internal temperature sensor, which will avoid any external circuit issues. If you can read the current temperature correctly then the device is working fine. Then you can go ahead with reading analog inputs. 

    6. if the above steps do not work and if this is your custom board, you need to make sure the chip is soldered correctly. you should also provide test points on board for easy access to various pins of the chip.

    7. Further you can also run the code in debug more in SES, and step through each code and see if the SPI pins have expected logic on logic analyzer / oscilloscope. you can also see if the code goes into any hard faults.  

    hope the above helps..  

Children
No Data
Related