Upper and lower limit interrupt events in [nrfx_saadc_limits_set ]

hi,In SAADC sampling, the upper limit and lower limit of sampling results are set. Interrupt events are generated only when they are less than the lower limit or greater than the upper limit. But in my code, as long as the sampling ends, it will generate an interrupt event. What's the problem?

17.0.2sdk,52833

The general functions are as follows:
1. ADC sampling result > = 500, generates upper limit interrupt event and wakes up;
2. ADC sampling result < = 300, generates lower limit interrupt event and wakes up;
3.300 < ADC sampling result < 500, sleep;


int main(void)
{
	ret_code_t ret;
	
	NRF_UICR->NFCPINS = 0; 				

	gpio_output_voltage_setup_3v3();
 	UART_Init();
	
    log_init();
	printf("\r\n***************************************************\r\n");
	 
	ret = nrf_drv_clock_init();
	APP_ERROR_CHECK(ret);
	nrf_drv_clock_lfclk_request(NULL);
	
    timers_init();

    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
	
    // Start execution.
    NRF_LOG_INFO("Debug logging for UART over RTT started.");
    advertising_start();

	saadc__limit_init();
	#define BAT_ADC_POWER_PIN				NRF_GPIO_PIN_MAP(0,23)
	nrf_gpio_cfg_output(BAT_ADC_POWER_PIN);
	nrf_gpio_pin_set(BAT_ADC_POWER_PIN);	
	

    for (;;)
    {
		nrf_delay_ms(500);

		nrfx_saadc_sample();
		printf("into idle state\n");
		nrf_delay_ms(10);
		idle_state_handle();
    }
}




#define 						SAMPLES_BUFFER_LEN 1
static nrf_saadc_value_t     	m_buffer_pool[2][SAMPLES_BUFFER_LEN];
static uint32_t       			m_adc_evt_counter;


void saadc_callback(nrfx_saadc_evt_t const * p_event)
{
	float  val;  
	  
	if (p_event->type == NRFX_SAADC_EVT_DONE)
    {
        ret_code_t err_code;

		err_code = nrfx_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_BUFFER_LEN);
        APP_ERROR_CHECK(err_code);
        int i;
			  
        printf("\r\nADC event number: %d\r\n", (int)m_adc_evt_counter);

        for (i = 0; i < SAMPLES_BUFFER_LEN; i++)
        {
            
			printf("Sample value: %d    ", p_event->data.done.p_buffer[i]);

			      
			val = p_event->data.done.p_buffer[i] * 3.6 /1024;	
			printf("Voltage = %.3fV\r\n", val);
        }
        
		m_adc_evt_counter++;
    }

	if(p_event->type == NRF_DRV_SAADC_EVT_LIMIT)
	{
		printf("Limit Event\r\n");
	}
}


void saadc__limit_init(void)
{
  ret_code_t err_code;

  nrf_saadc_channel_config_t channel_config =
  NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);

  nrfx_saadc_limits_set(0,300,500);
 
  nrfx_saadc_config_t saadc_config = NRFX_SAADC_DEFAULT_CONFIG;
  saadc_config.resolution = NRF_SAADC_RESOLUTION_10BIT;
  saadc_config.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;
  saadc_config.low_power_mode = false;
  saadc_config.interrupt_priority = 6;
  err_code = nrfx_saadc_init(&saadc_config, saadc_callback);

  err_code = nrfx_saadc_channel_init(0, &channel_config);
  APP_ERROR_CHECK(err_code);

  err_code = nrfx_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_BUFFER_LEN);
  APP_ERROR_CHECK(err_code);

  err_code = nrfx_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_BUFFER_LEN);
  APP_ERROR_CHECK(err_code);
}



In nrfx_ In the SAADC. C document, I have enabled the [nrf_saadc_int_ch3limit nrf_saadc_int_ch3limit] interrupt,see the #if ,

nrfx_err_t nrfx_saadc_init(nrfx_saadc_config_t const * p_config,
                           nrfx_saadc_event_handler_t  event_handler)
{
    NRFX_ASSERT(p_config);
    NRFX_ASSERT(event_handler);
    nrfx_err_t err_code;

    if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
    {
        err_code = NRFX_ERROR_INVALID_STATE;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    m_cb.event_handler = event_handler;
    nrf_saadc_resolution_set(p_config->resolution);
    nrf_saadc_oversample_set(p_config->oversample);
    m_cb.low_power_mode       = p_config->low_power_mode;
    m_cb.state                = NRFX_DRV_STATE_INITIALIZED;
    m_cb.adc_state            = NRF_SAADC_STATE_IDLE;
    m_cb.active_channels      = 0;
    m_cb.limits_enabled_flags = 0;
    m_cb.conversions_end      = false;

    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);

	#if 1
	nrf_saadc_event_clear(NRF_SAADC_EVENT_CH3_LIMITH);
	nrf_saadc_event_clear(NRF_SAADC_EVENT_CH3_LIMITL);

	#endif
	
    NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, p_config->interrupt_priority);
    NRFX_IRQ_ENABLE(SAADC_IRQn);

#if 1
    nrf_saadc_int_enable(NRF_SAADC_INT_CH3LIMITH|NRF_SAADC_INT_CH3LIMITL);
#else
    nrf_saadc_int_enable(NRF_SAADC_INT_END);

    if (m_cb.low_power_mode)
    {
        nrf_saadc_int_enable(NRF_SAADC_INT_STARTED);
    }
#endif

    nrf_saadc_enable();

    err_code = NRFX_SUCCESS;
    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));

    return err_code;
}

thanks

  • Yes, I read datasheet and [nrfx_saadc_irq_handler] code. As soon as SAADC ends, it will enter IRQ. In IRQ, it will analyze the event type, and then set the event parameter of [saadc_callback] function.

    As you said, as long as any event occurs, it will wake up.I'll find another way to solve it.

    Thank you.

  • Great, I am happy to hear that this answered your questions.

    can23 said:
    As you said, as long as any event occurs, it will wake up.I'll find another way to solve it.

    If you would like to avoid any unnecessary events from being generated you might have to implement a simpler, custom version of the SAADC driver yourself, so that it only does exactly what you have intended it to do, with a minimum of interrupts and events enabled.

    Please do not hesitate to open another ticket if you encounter any issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl

Related