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

nrf52 SAADC - NRFX_SAADC_EVT_DONE never called

using nRF5SDK 160098a08e2

I have the following code:

#define ADC_NOF_SAMPLES 16u
static int16_t s_sample_buffer[ ADC_NOF_SAMPLES ];
static nrf_saadc_channel_config_t const s_adc_channel0 = NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE( NRF_SAADC_INPUT_AIN5 );
static void saadc_event_isr( nrfx_saadc_evt_t const *p_event )
{
    volatile uint32_t numOfSamples = 0;
    switch ( p_event->type )
    {
    case NRFX_SAADC_EVT_DONE:  // Event generated when the buffer is filled with samples.
        numOfSamples = p_event->data.done.size;
        break;
    case NRFX_SAADC_EVT_LIMIT: // Event generated after one of the limits is reached.
        break;
    case NRFX_SAADC_EVT_CALIBRATEDONE: // Event generated when the calibration is complete.
        {
            nrfx_err_t err;
            err = nrfx_saadc_buffer_convert( &s_sample_buffer[0], ADC_NOF_SAMPLES );
            APP_ERROR_CHECK(err);
            /*err = nrfx_saadc_sample();
            APP_ERROR_CHECK(err);*/
        }
        break;
    default:
        break;
    }
}

    nrfx_err_t err;
    static nrfx_saadc_config_t const s_saadc_config = {
            .resolution = NRF_SAADC_RESOLUTION_12BIT,
            .oversample = NRF_SAADC_OVERSAMPLE_256X,
            .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,
            .low_power_mode = false
    };

    // ADC driver is initialized in non-blocking mode, since an event handler is given
    err = nrfx_saadc_init( &s_saadc_config, saadc_event_isr );

    if ( err == NRFX_SUCCESS )
    {
        // Initialize the ADC channel 0
        err = nrfx_saadc_channel_init( 0, &s_adc_channel0 );

        if ( err == NRFX_SUCCESS )
        {
            /*
            * Calibrate the offset with a call to nrfx_saadc_calibrate_offset.
            * You need to wait for the SAADCs DONE event before you can proceed.
            * */
            do
            {
                err = nrfx_saadc_calibrate_offset();
            } while ( err == NRFX_ERROR_BUSY );

            rc = 1u;
        }
    }



I never receive NRFX_SAADC_EVT_DONE. Please advise

Parents
  • Hello,

    Could you tell me, are you working out of the provided SAADC example from the SDK?
    Please provide the entire source code, as the root cause for your error might be located elsewhere.

    For future reference, when inserting code as part of a question, I ask that you format it with the code option to significantly increase readability.

    Best regards,
    Karl

  • So I tried to add the following code:

    			nrfx_err_t err;
    			err = nrfx_saadc_buffer_convert( &s_sample_buffer[0], ADC_NOF_SAMPLES );
    			APP_ERROR_CHECK(err);
    			err = nrfx_saadc_sample();
    			APP_ERROR_CHECK(err);
    
    			while(1)
    			{
    				while( nrfx_saadc_is_busy() ) {}
    				err = nrfx_saadc_sample();
    				APP_ERROR_CHECK(err);
    			}

    I never gets past nrfx_saadc_is_busy(). So the SAADC never gets into idle state. What is wrong with my initialization of this module ?

        nrfx_err_t err;
        static nrfx_saadc_config_t const s_saadc_config = {
        		.resolution = NRF_SAADC_RESOLUTION_12BIT,
        		.oversample = NRF_SAADC_OVERSAMPLE_DISABLED,//NRF_SAADC_OVERSAMPLE_128X,//NRF_SAADC_OVERSAMPLE_256X,
        		.interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,
        		.low_power_mode = false
        };
    
        // ADC driver is initialized in non-blocking mode, since an event handler is given
        err = nrfx_saadc_init( &s_saadc_config, saadc_event_isr );
    
        if ( err == NRFX_SUCCESS )
        {
        	// Initialize the ADC channel 0
        	err = nrfx_saadc_channel_init( 0, &s_adc_channel0 );
    
        	if ( err == NRFX_SUCCESS )
        	{
        		/*
        		 * Calibrate the offset with a call to nrfx_saadc_calibrate_offset.
        		 * You need to wait for the SAADCs DONE event before you can proceed.
        		 * */
        		do
        		{
        			/*
    					The SAADC has a temperature dependent offset.
    					Therefore, it is recommended to calibrate the SAADC at least once before use,
    					and to re-run calibration every time the ambient temperature has changed by more than 10 °C.
    					Offset calibration is started by triggering the CALIBRATEOFFSET task, and the CALIBRATEDONE
    					event is generated when calibration is done.
        			 */
        			err = nrfx_saadc_calibrate_offset();
        		} while ( err == NRFX_ERROR_BUSY );
    
        		rc = 1u;
        	}
        }

  • BardenDK said:
    I do, here:

    My mistake, I had a hard time reading your initially posted code.
    Thank you for formatting all the code in your comments!

    BardenDK said:
    What is wrong with my initialization of this module ?

    Your initialization looks fine from what I can gather, I suspect this is rather a problem with the timing of the operations.

    Looking back at the code you posted originally, what is your intention when the NRFX_SAADC_EVT_DONE event occurs?
    Also, how often or at what event do you intend for the ADC to sample? I see from your first comment that you are showing me a call to app_timer_init, but I see no mention of it anywhere else.

    It is hard to get a good overview and understanding of your application without seeing all the relevant code.
    Let me know, if you would like me to make your ticket private at any time.

    Best regards,
    Karl

Reply
  • BardenDK said:
    I do, here:

    My mistake, I had a hard time reading your initially posted code.
    Thank you for formatting all the code in your comments!

    BardenDK said:
    What is wrong with my initialization of this module ?

    Your initialization looks fine from what I can gather, I suspect this is rather a problem with the timing of the operations.

    Looking back at the code you posted originally, what is your intention when the NRFX_SAADC_EVT_DONE event occurs?
    Also, how often or at what event do you intend for the ADC to sample? I see from your first comment that you are showing me a call to app_timer_init, but I see no mention of it anywhere else.

    It is hard to get a good overview and understanding of your application without seeing all the relevant code.
    Let me know, if you would like me to make your ticket private at any time.

    Best regards,
    Karl

Children
No Data
Related