adc windows mode in nrf sdk connect

Hi, 

I was looking for the best solution for our case where an interrupt should be triggered/generated when the adc value is between two values (min and max) something like window mode. 

SOC: nrf5340

SDK: 2.2.0

Thanks in advance!

Parents Reply Children
  • Hi Karl, 

    I have implemented the comp peripheral as it is shown below. in the beginning, when the application starts the comp works fine so every time I press the button it shows the correct log ( up or down) but after 10 times of pressing the switch, the comp becomes unstable. and shows two logs (up and down ) in one click. I'm not sure what I'm doing here wrong! 

    /**
     * @brief COMP driver default configuration.
     *
     * This configuration sets up COMP with the following options:
     * - single-ended mode
     * - reference voltage: internal VDD
     * - lower threshold: 0.5 V
     * - upper threshold: 1.0 V
     * - Normal speed mode
     * - hysteresis disabled
     * - current source disabled
     *
     * @param[in] _input Analog input.
     */
    const nrfx_comp_config_t config = {
    	.reference			=		NRF_COMP_REF_VDD,
    	.main_mode			=		NRF_COMP_MAIN_MODE_SE,
    	.threshold.th_up	=		NRFX_VOLTAGE_THRESHOLD_TO_INT(1.5, 3),
    	.threshold.th_down	=		NRFX_VOLTAGE_THRESHOLD_TO_INT(0.5, 3),
    	.speed_mode			=		NRF_COMP_SP_MODE_Normal,
    	.hyst				=		NRF_COMP_HYST_50mV,
    	.isource			=		NRF_COMP_ISOURCE_Off,
    	.input				=		NRF_COMP_INPUT_0,
    	.interrupt_priority	=		NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY
    };
    .......
    	if (nrfx_comp_init (&config, comp_handler) == NRFX_SUCCESS) {
    		IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_COMP), IRQ_PRIO_LOWEST, nrfx_comp_irq_handler,0);
    		nrfx_comp_start(NRFX_COMP_EVT_EN_UP_MASK | NRFX_COMP_EVT_EN_DOWN_MASK, 
    						NRFX_COMP_SHORT_STOP_AFTER_UP_EVT | NRFX_COMP_SHORT_STOP_AFTER_DOWN_EVT);
    	} else {
    		LOG_ERR("COMP init error");
    	}
    	
    
    void comp_handler(nrf_comp_event_t event) {
    	nrfx_comp_stop();
    	switch (event) {
    		case NRF_COMP_EVENT_READY:
    			LOG_INF("COMP : NRF_COMP_EVENT_READY");
    			break;
    			
    		case NRF_COMP_EVENT_DOWN:
    			LOG_INF("COMP : NRF_COMP_EVENT_DOWN");
    			nrfx_comp_start(NRFX_COMP_EVT_EN_UP_MASK, NRFX_COMP_SHORT_STOP_AFTER_UP_EVT);
    			break;
    
    		case NRF_COMP_EVENT_UP:
    			LOG_INF("COMP : NRF_COMP_EVENT_UP");
    			nrfx_comp_start(NRFX_COMP_EVT_EN_DOWN_MASK, NRFX_COMP_SHORT_STOP_AFTER_DOWN_EVT);
    			// gpio_pin_toggle_dt(&led);
    			break;
    
    		case NRF_COMP_EVENT_CROSS:
    			LOG_INF("COMP : NRF_COMP_EVENT_CROSS");
    			break;
    		
    		default:
    			LOG_INF("COMP : UNKOWN");
    			break;
    	}
    }

  • [Update] I modified the code to this way and now looks more stable 

    	if (nrfx_comp_init (&config, comp_handler) == NRFX_SUCCESS) {
    		IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_COMP), IRQ_PRIO_LOWEST, nrfx_comp_irq_handler,0);
    		nrfx_comp_start(NRFX_COMP_EVT_EN_READY_MASK | NRFX_COMP_EVT_EN_DOWN_MASK | NRFX_COMP_EVT_EN_UP_MASK, 0);
    	} else {
    		LOG_ERR("COMP init error");
    	}
    
    
        return 0;
    }
    
    void comp_handler(nrf_comp_event_t event) {
    	gpio_pin_toggle_dt(&led);
    	switch (event) {
    		case NRF_COMP_EVENT_READY:
    			LOG_INF("COMP : NRF_COMP_EVENT_READY");
    			break;
    			
    		case NRF_COMP_EVENT_DOWN:
    			LOG_INF("COMP : NRF_COMP_EVENT_DOWN");
    			break;
    
    		case NRF_COMP_EVENT_UP:
    			LOG_INF("COMP : NRF_COMP_EVENT_UP");
    			break;
    
    		case NRF_COMP_EVENT_CROSS:
    			LOG_INF("COMP : NRF_COMP_EVENT_CROSS");
    			break;
    		
    		default:
    			LOG_INF("COMP : UNKOWN");
    			break;
    	}
    }

  • Great, thanks for the update - I am happy to hear that you've got it working as intended now :) 

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

    Best regards,
    Karl

Related