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

nRF52810 saadc didn't work by calling nrfx_saadc_sample( )

Hi,

 Sorry to bother you in your holidays.I want to get an conversion every time by calling nrfx_saadc_sample( ) .So I had configure saadc like below.But I found the adc didn't call saadc_callback() sometime by calling nrfx_saadc_sample( ). What do I miss?Thanks for your reply.


/*********************************************************************
 * MACROS
 */

#define ADC_DEFAULT_CONFIG                                     \
{                                                              \
    .resolution         = NRF_SAADC_RESOLUTION_12BIT, 				 \
    .oversample         = NRF_SAADC_OVERSAMPLE_4X, 			 			 \
    .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,      \
    .low_power_mode     = NRFX_SAADC_CONFIG_LP_MODE            \
}

#define ADC_DEFAULT_LT_CHANNEL_CONFIG_SE(PIN_P) 		\
{                                                   \
    .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      \
    .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      \
    .gain       = NRF_SAADC_GAIN1_4,                \
    .reference  = NRF_SAADC_REFERENCE_VDD4,     		\
    .acq_time   = NRF_SAADC_ACQTIME_40US,           \
    .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      \
    .burst      = NRF_SAADC_BURST_ENABLED,         \
    .pin_p      = (nrf_saadc_input_t)(PIN_P),       \
    .pin_n      = NRF_SAADC_INPUT_DISABLED          \
}

#define ADC_DEFAULT_HT_CHANNEL_CONFIG_SE(PIN_P) 		\
{                                                   \
    .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      \
    .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      \
    .gain       = NRF_SAADC_GAIN1_4,                \
    .reference  = NRF_SAADC_REFERENCE_VDD4,     		\
    .acq_time   = NRF_SAADC_ACQTIME_10US,           \
    .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      \
    .burst      = NRF_SAADC_BURST_ENABLED,         \
    .pin_p      = (nrf_saadc_input_t)(PIN_P),       \
    .pin_n      = NRF_SAADC_INPUT_DISABLED          \
}



#define		C_NOP			__ASM volatile ("nop");


/*********************************************************************
 * 											Gobal Variable
 */

bool adcFinishFlag = false;

/*********************************************************************
 * 											Local Variable
 */

static bool adcCalibratedone = false;

static bool adcAbortFlag = false;

static nrf_saadc_value_t adcSampleBuffer[4] = { 0 };

/*********************************************************************
 * LOCAL FUNCTIONS
 */

static nrf_saadc_input_t AdcChannelPort( uint8_t inputChannel );


/*********************************************************************
 * adc callback
 */

static void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if ( p_event->type == NRF_DRV_SAADC_EVT_DONE )
     {
			  if( adcAbortFlag )
				 {
						adcAbortFlag = false;
				 }
				else
				 {
						adcFinishFlag = true;
				 }
     }
		else if( p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE )
		 {
				adcCalibratedone = true;
		 }
}


/*********************************************************************
 * @fn      InitAdcModule
 *
 * @brief   initialzing Adc module
 *
 *
 * @param   none
 * 
 *
 * @return  none
 */

void InitAdcModule( )
{
	  ret_code_t err_code;
		nrf_drv_saadc_config_t drv_saadc_cfg = ADC_DEFAULT_CONFIG;
		
    err_code = nrf_drv_saadc_init( &drv_saadc_cfg, saadc_callback );
    APP_ERROR_CHECK(err_code);
	
		adcCalibratedone = false;
		err_code = nrf_drv_saadc_calibrate_offset( );
		APP_ERROR_CHECK(err_code);
	
		if( err_code == NRFX_SUCCESS )
		 {
				err_code = 0;
			  
			  do{
						C_NOP;
						C_NOP;
						C_NOP;
						err_code++;
						if( err_code >= 65536 )
							break;
				}while( !adcCalibratedone );
		 }
}


/*********************************************************************
 * @fn      InitAdcChannel
 *
 * @brief   initialzing Adc channel
 *
 *
 * @param   sdcChannel: adc channel
 * 
 * 					resistanceType: big resistance -> Low temperature
 * 													low resistance -> High temperature
 *
 * @return  none
 */

void InitAdcChannel( uint8_t sdcChannel, check_type_t resistanceType )
{
	  ret_code_t err_code;
	  nrf_saadc_input_t InputAIN;
	
	  InputAIN = AdcChannelPort( sdcChannel );
	
		nrf_saadc_channel_config_t channel_config = 
       ADC_DEFAULT_LT_CHANNEL_CONFIG_SE(InputAIN);
	
		if( resistanceType == HIGH_TEMPERATURE )
		 {
				channel_config.acq_time = NRF_SAADC_ACQTIME_10US;
		 }
	
    err_code = nrf_drv_saadc_channel_init( sdcChannel, &channel_config );
    APP_ERROR_CHECK(err_code);
}

/*********************************************************************
 * @fn      StartAdc
 *
 * @brief   start sampling
 *
 *
 * @param   none
 * 
 *
 * @return  none
 */

void StartAdc( )
{
	ret_code_t err_code;
	
	adcFinishFlag = false;
  adcAbortFlag = false;
  
  
	err_code = nrf_drv_saadc_buffer_convert( adcSampleBuffer, 2 );
	APP_ERROR_CHECK(err_code);
	
	err_code = nrfx_saadc_sample( );
	APP_ERROR_CHECK(err_code);
}

/*********************************************************************
 * @fn      StopAdc
 *
 * @brief   stop sampling
 *
 *
 * @param   none
 * 
 *
 * @return  none
 */

void StopAdc( )
{
	 if( nrfx_saadc_is_busy( ) )
	  {
			 adcAbortFlag = true;
			 adcFinishFlag = false;
			 nrfx_saadc_abort( );
		}
}


/*********************************************************************
 * @fn      DisableAdcChannel
 *
 * @brief   disable adc channel
 *
 *
 * @param   none
 * 
 *
 * @return  none
 */

void DisableAdcChannel( uint8_t channel )
{
	 ret_code_t err_code;
	 err_code = nrfx_saadc_channel_uninit( channel );
	 APP_ERROR_CHECK(err_code);
}


/*********************************************************************
 * 										Logic Function
 */

static nrf_saadc_input_t AdcChannelPort( uint8_t inputChannel )
{
	  nrf_saadc_input_t  channelAIN;
	  
		switch( inputChannel )
		 {
				case 0:
					channelAIN = NRF_SAADC_INPUT_AIN0;
					break;
				
				case 1:
					channelAIN = NRF_SAADC_INPUT_AIN1;
					break;
				
				case 2:
					channelAIN = NRF_SAADC_INPUT_AIN2;
					break;
				
				case 3:
					channelAIN = NRF_SAADC_INPUT_AIN3;
					break;
				
				case 4:
					channelAIN = NRF_SAADC_INPUT_AIN4;
					break;
				
				case 5:
					channelAIN = NRF_SAADC_INPUT_AIN5;
					break;
				
				case 6:
					channelAIN = NRF_SAADC_INPUT_AIN6;
					break;
				
				case 7:
				default:
					channelAIN = NRF_SAADC_INPUT_AIN7;
					break;
		 }
	 return channelAIN;
}


/**************************************************
 *                  Main
 *************************************************/

int main(void)
{
		uint32_t main_code=0;
    //bool erase_bonds;

    // Initialize.
	  PortInit( );
    log_init( );
    timers_init( );
    power_management_init( );
    ble_stack_init( );
    gap_params_init( );
    gatt_init( );
    services_init( );
		advertising_init( );
    conn_params_init( );
    //peer_manager_init( );
		
    // Start execution.
    NRF_LOG_INFO("Application started.");
	  ApplicationParamterInit( );
    application_timers_start( );
		
	InitAdcModule( );
	InitAdcChannel( 0, 0 );
	StartAdc( );
		
    // Enter main loop.
    for (;;)
    {
		if( adcFinishFlag )
    	 {
    	    AdcMeasurePoll();
    		adcFinishFlag = false;
    	 }
    }
}

  • You won't get a callback until you've filled your buffer. You initialized your buffer with a size of two, but you only took one sample. 

  • Sorry for the late reply. Sorry again.I had posted the test code.There is my code below.

    /*********************************************************************
     * MACROS
     */
    
    #define ADC_DEFAULT_CONFIG                                     \
    {                                                              \
        .resolution         = NRF_SAADC_RESOLUTION_12BIT, 				 \
        .oversample         = NRF_SAADC_OVERSAMPLE_4X, 			 			 \
        .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,      \
        .low_power_mode     = NRFX_SAADC_CONFIG_LP_MODE            \
    }
    
    #define ADC_DEFAULT_LT_CHANNEL_CONFIG_SE(PIN_P) 		\
    {                                                   \
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      \
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      \
        .gain       = NRF_SAADC_GAIN1_4,                \
        .reference  = NRF_SAADC_REFERENCE_VDD4,     		\
        .acq_time   = NRF_SAADC_ACQTIME_40US,           \
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      \
        .burst      = NRF_SAADC_BURST_ENABLED,         \
        .pin_p      = (nrf_saadc_input_t)(PIN_P),       \
        .pin_n      = NRF_SAADC_INPUT_DISABLED          \
    }
    
    #define ADC_DEFAULT_HT_CHANNEL_CONFIG_SE(PIN_P) 		\
    {                                                   \
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      \
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      \
        .gain       = NRF_SAADC_GAIN1_4,                \
        .reference  = NRF_SAADC_REFERENCE_VDD4,     		\
        .acq_time   = NRF_SAADC_ACQTIME_10US,           \
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      \
        .burst      = NRF_SAADC_BURST_ENABLED,         \
        .pin_p      = (nrf_saadc_input_t)(PIN_P),       \
        .pin_n      = NRF_SAADC_INPUT_DISABLED          \
    }
    
    
    
    #define		C_NOP			__ASM volatile ("nop");
    
    
    /*********************************************************************
     * 											Gobal Variable
     */
    
    bool adcFinishFlag = false;
    
    /*********************************************************************
     * 											Local Variable
     */
    
    static bool adcCalibratedone = false;
    
    static bool adcAbortFlag = false;
    
    static nrf_saadc_value_t adcSampleBuffer[4] = { 0 };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static nrf_saadc_input_t AdcChannelPort( uint8_t inputChannel );
    
    
    /*********************************************************************
     * adc callback
     */
    
    static void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        if ( p_event->type == NRF_DRV_SAADC_EVT_DONE )
         {
    			  if( adcAbortFlag )
    				 {
    						adcAbortFlag = false;
    				 }
    				else
    				 {
    						adcFinishFlag = true;
    				 }
         }
    		else if( p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE )
    		 {
    				adcCalibratedone = true;
    		 }
    }
    
    
    /*********************************************************************
     * @fn      InitAdcModule
     *
     * @brief   initialzing Adc module
     *
     *
     * @param   none
     * 
     *
     * @return  none
     */
    
    void InitAdcModule( )
    {
    	  ret_code_t err_code;
    		nrf_drv_saadc_config_t drv_saadc_cfg = ADC_DEFAULT_CONFIG;
    		
        err_code = nrf_drv_saadc_init( &drv_saadc_cfg, saadc_callback );
        APP_ERROR_CHECK(err_code);
    	
    		adcCalibratedone = false;
    		err_code = nrf_drv_saadc_calibrate_offset( );
    		APP_ERROR_CHECK(err_code);
    	
    		if( err_code == NRFX_SUCCESS )
    		 {
    				err_code = 0;
    			  
    			  do{
    						C_NOP;
    						C_NOP;
    						C_NOP;
    						err_code++;
    						if( err_code >= 65536 )
    							break;
    				}while( !adcCalibratedone );
    		 }
    }
    
    
    /*********************************************************************
     * @fn      InitAdcChannel
     *
     * @brief   initialzing Adc channel
     *
     *
     * @param   sdcChannel: adc channel
     * 
     * 					resistanceType: big resistance -> Low temperature
     * 													low resistance -> High temperature
     *
     * @return  none
     */
    
    void InitAdcChannel( uint8_t sdcChannel, check_type_t resistanceType )
    {
    	  ret_code_t err_code;
    	  nrf_saadc_input_t InputAIN;
    	
    	  InputAIN = AdcChannelPort( sdcChannel );
    	
    		nrf_saadc_channel_config_t channel_config = 
           ADC_DEFAULT_LT_CHANNEL_CONFIG_SE(InputAIN);
    	
    		if( resistanceType == HIGH_TEMPERATURE )
    		 {
    				channel_config.acq_time = NRF_SAADC_ACQTIME_10US;
    		 }
    	
        err_code = nrf_drv_saadc_channel_init( sdcChannel, &channel_config );
        APP_ERROR_CHECK(err_code);
    }
    
    /*********************************************************************
     * @fn      StartAdc
     *
     * @brief   start sampling
     *
     *
     * @param   none
     * 
     *
     * @return  none
     */
    
    void StartAdc( )
    {
    	ret_code_t err_code;
    	
    	adcFinishFlag = false;
      adcAbortFlag = false;
      
      
    	err_code = nrf_drv_saadc_buffer_convert( adcSampleBuffer, 2 );
    	APP_ERROR_CHECK(err_code);
    	
    	err_code = nrfx_saadc_sample( );
    	APP_ERROR_CHECK(err_code);
    }
    
    /*********************************************************************
     * @fn      StopAdc
     *
     * @brief   stop sampling
     *
     *
     * @param   none
     * 
     *
     * @return  none
     */
    
    void StopAdc( )
    {
    	 if( nrfx_saadc_is_busy( ) )
    	  {
    			 adcAbortFlag = true;
    			 adcFinishFlag = false;
    			 nrfx_saadc_abort( );
    		}
    }
    
    
    /*********************************************************************
     * @fn      DisableAdcChannel
     *
     * @brief   disable adc channel
     *
     *
     * @param   none
     * 
     *
     * @return  none
     */
    
    void DisableAdcChannel( uint8_t channel )
    {
    	 ret_code_t err_code;
    	 err_code = nrfx_saadc_channel_uninit( channel );
    	 APP_ERROR_CHECK(err_code);
    }
    
    
    /*********************************************************************
     * 										Logic Function
     */
    
    static nrf_saadc_input_t AdcChannelPort( uint8_t inputChannel )
    {
    	  nrf_saadc_input_t  channelAIN;
    	  
    		switch( inputChannel )
    		 {
    				case 0:
    					channelAIN = NRF_SAADC_INPUT_AIN0;
    					break;
    				
    				case 1:
    					channelAIN = NRF_SAADC_INPUT_AIN1;
    					break;
    				
    				case 2:
    					channelAIN = NRF_SAADC_INPUT_AIN2;
    					break;
    				
    				case 3:
    					channelAIN = NRF_SAADC_INPUT_AIN3;
    					break;
    				
    				case 4:
    					channelAIN = NRF_SAADC_INPUT_AIN4;
    					break;
    				
    				case 5:
    					channelAIN = NRF_SAADC_INPUT_AIN5;
    					break;
    				
    				case 6:
    					channelAIN = NRF_SAADC_INPUT_AIN6;
    					break;
    				
    				case 7:
    				default:
    					channelAIN = NRF_SAADC_INPUT_AIN7;
    					break;
    		 }
    	 return channelAIN;
    }
    
    /***************************************************/
    
    void ParamterInit( )
    {
       fristGroupFlag = true;
       secondGroupFlag = false;
       timerOutFlag = false;
       sampleCnt = 0;
    }
    
    
    /**************************************************
     *                  Main
     *************************************************/
    
    int main(void)
    {
    		uint32_t main_code=0;
        //bool erase_bonds;
    
        // Initialize.
    	  PortInit( );
        log_init( );
        timers_init( );
        power_management_init( );
        ble_stack_init( );
        gap_params_init( );
        gatt_init( );
        services_init( );
    		advertising_init( );
        conn_params_init( );
        //peer_manager_init( );
    		
        // Start execution.
        NRF_LOG_INFO("Application started.");
    	  ApplicationParamterInit( );
        application_timers_start( );
    		
    	InitAdcModule( );
    	InitAdcChannel( 0, 0 );
    	InitAdcChannel( 1, 0 );
    	StartAdc( );
    		
        // Enter main loop.
        for (;;)
        {
    		if( adcFinishFlag )
        	 {
        	    //AdcMeasurePoll();
        	    if( fristGroupFlag )
        	     {
        	         SampleTransfer( adcSampleBuffer );
        	         sampleCnt++;
        	         
        	         if( sampleCnt>= 4 )
        	          {
        	             sampleCnt = 0;
        	             DisableAdcChannel(0);
        	             DisableAdcChannel(1);
        	             
        	             fristGroupFlag = false;
        	             secondGroupFlag = true;
        	             
        	             InitAdcChannel( 2, 0 );
    	                 InitAdcChannel( 3, 0 );
    	                 StartAdc( );
        	          }
        	         else
        	          {
        	             StartAdc( );
        	          }
        	     }
        	    else if( secondGroupFlag )
                 {
                     SampleTransfer( adcSampleBuffer );
        	         sampleCnt++;
        	         if( sampleCnt>= 4 )
        	          {
        	             sampleCnt = 0;
        	             DisableAdcChannel(0);
        	             DisableAdcChannel(1);
        	             
        	             fristGroupFlag = false;
        	             secondGroupFlag = true;
        	             
        	             SimpleFinishHandle( );
        	             startAdcTimer( );              //500ms time out
        	          }
        	         else
        	          {
        	             StartAdc( );
        	          }
                 }
        		adcFinishFlag = false;
        	 }
        	 
            if( timerOutFlag )  //500ms
             {
                 sampleCnt = 0;
                 InitAdcChannel( 0, 0 );
              	 InitAdcChannel( 1, 0 );
    	         StartAdc( );
                 timerOutFlag = false;
             }
        }
    }

  • Try this:

    void StartAdc( )
    {
    	ret_code_t err_code;
    	
    	adcFinishFlag = false;
      adcAbortFlag = false;
      
      
    	err_code = nrf_drv_saadc_buffer_convert( adcSampleBuffer, 2 ); // Needs two samples to get a callback
    	APP_ERROR_CHECK(err_code);
    	
    	err_code = nrfx_saadc_sample( );
    	APP_ERROR_CHECK(err_code);
    	
    	err_code = nrfx_saadc_sample( ); // Take a second sample
    	APP_ERROR_CHECK(err_code);
    }

  • Hi haakonsh,

     I had tried.adcSampleBuffer[0] is used to store conversion of saadc channel 0,adcSampleBuffer[1] is used to store conversion of saadc channel 1. At the first time both SampleBuffer[0] and SampleBuffer[1] are correct.But value of SampleBuffer[1]  became the same as  SampleBuffer[0]  after a while.Why?

Related