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

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

Hi All,

I am a beginner,Can you please explain me what is the role of this line?

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

  • i am using a SPI application to interface a display and sd card using sdk 12.2.0 on nrf51422. I just wanted to know what this line written above means.?

  • nrf_drv_spi is Nordic SPI driver in their SDK (HAL if you want), see Infocenter documentation for all the details including explanation of all functions, their parameters and structures. As you can notice basically all functions in Nordic SDK return uin32_t status code (or error code if you want) and macro APP_ERROR_CHECK() is simple way how to treat all errors (= different return codes then NRF_SUCCESS) as hard-faults, meaning that application will run to error handler where you can do some logging if you want and then typically soft reset the chip and start from scratch. So every such HAL or SD API call which is essential for your application's state machine (meaning that if it fails you have no easy way to recover and resetting whole OS is the easiest option how to ensure 100% recovery) might be encapsulated into this macro. However you can also just do some switch or if-else structure around that uint32_t return code or just ignore it (not recommended but some peole like it like that...)

    For more about SDK error codes read the documentation here, here and of course read header/signature of each SDK function you are using first time;). Btw. macro APP_ERROR_CHECK() is defined and explained in common error handler module.

  • In short it means that on previously initialized and enabled instance of SPI Master peripheral &spi you call full-duplex bi-directional transfer. All SPI transfers are full-duplex bi-directional by nature, but most applications use them half-duplex meaning that certain part is used only by Master->Slave and the second part for Slave->Master. However this is protocol specific (SPI is just low-level electrical protocol spec). The rest of the call means that you supply Tx and Rx buffers with lengths (these will be used by HAL driver to determine how many bytes should be clocked on SPI_CLK line). And finally whole HAL driver function call is expected to return success, otherwise you send the program to app error handler.

  • So you mean, (nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length)

    is not transferring anything but probably checking if the transfer of data has happened?

    I am using this line:- APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));

    after transferring files to sd card.

  • This is how my main(void) looks like:-

    int main(void) { APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_INFO("SPI example\r\n");
    
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = ARDUINO_4_PIN;
    spi_config.miso_pin = ARDUINO_12_PIN;
    spi_config.mosi_pin = ARDUINO_11_PIN;
    spi_config.sck_pin  = ARDUINO_13_PIN;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));
    
    //CHANGES ENDS HERE
    	
    while (1)
    {
      //Reset rx buffer and transfer done flag			 
    		memset(m_rx_buf, 0, m_length);
      spi_xfer_done = false;
    		 		 
     		//SDC Main starts here
    		 
    	  APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    
        while (!spi_xfer_done)
    			{
    		     __WFE();
        }
    	  bsp_board_leds_init();
    
      APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
      NRF_LOG_INFO("\r\nFATFS example.\r\n\r\n");
    
      fatfs_example();
    	
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    
      while (!spi_xfer_done)
      {
            __WFE();
        }
    		 
    		memset(m_rx_buf, 0, m_length);
      spi_xfer_done = false;
    
    		nrf_drv_spi_switch_chips(&spi, SPI_SS_PIN_1);
    		 
    	  //static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(1); 
    		 
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    
      while (!spi_xfer_done)
      {
            __WFE();
      }
    
      ssd1306_power_on();
        ssd1306_init(SSD1306_CONFIG_DC_PIN,
                   SSD1306_CONFIG_RST_PIN,
                   SSD1306_CONFIG_CS_PIN,
                   SSD1306_CONFIG_CLK_PIN,
                   SSD1306_CONFIG_MOSI_PIN);
        ssd1306_begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS, true);
    	
    	  init_text();
        ssd1306_clear_display();
      ssd1306_set_textsize(2);
      ssd1306_set_textcolor(WHITE);
      ssd1306_set_cursor(10, 0);
      
    	  ssd1306_display();
    	
    	  show_text();
    	  
    		//APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    		
    	  while(spi_xfer_done)
    	  {
    		
    	    if(button_pressed) 
    				{
    			  show_text();
    			  button_pressed = false;
    		    }
        		__WFE();
    				
    	  //SDC Main Code ends here
      		  power_manage();
    	  }
     }
    

    }

Related