This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

low power pulsewidth measurement: PPI & lfclk & S210 - some guidance needed

Dear all,

I need to measure a pulse width on a GPIO pin which is in between 100mseconds and 7.2 seconds long without the use of "regular" timers due to low power requirements. I am pretty sure this can be done with PPI and the 32.768 kHz lfclock ( which runs anyway due to S210 use ). But I am simply lost in the examples and driver docs. Especially as I base my work on the bikepower ANT+ example which uses the board support package and app_button. Due to this I cannot copy-paste any code example as this always conflicts with something in the BSP or app_button.

Is there a hint which drivers / app_whatever to "implement" into existing examples that use BSP and app_button to connect a GPIO via PPI to a lsclock counter/timer ?

I "simply" need to start a lsclock counter by a GPIO pin interrupt (Low-High) and stop it by a high-low interrupt. Sadly I seem to be unable to do implement this simple task into the existing example code. As my max pulsewidth is > 10 seconds, a 16 bit counter is not sufficient @ 32.768 kHz clock. I am not sure if I can handle timer overflows due to the softdevice interrupting my program at any time.

Anyhow, the RealTimeCounter is 24 bits which is enough for my purpose. So, with RTC prescaler = 0 ( as used in app_button like it seems..) I could store the current TICK count at the low-high interrupt and then compare to the TICK count at the high-low interrupt and that's it. The counter roll-over case could be handled outside the ISR.

Just: How to do it ?

Any help like "remove this driver, add that one, re-use this timer.. " is very appreciated.

Thanks a lot, Wolfgang

Parents
  • How accurate do the measurements have to be? The most accurate solution would be to use gpiote IN events to start the timer (RTC) on rising edge and stop it/capture the value at falling edge. The problem with this is that gpiote IN requires HFCLK to be on (800-900uA) so this is not applicable in your case.

    Gpiote PORT event do not require HFCLK to be on and is therefore low power. The problem with this event is that it is shared between all pins that are set up with the SENSE mechanism, this includes the button pins if app_button is used. Also, the DETECT signal generating PORT event is not cleared until all pins that are configured for SENSE mechanism and are currently active, will be deactive. Doing it automatically with PPI is therefore not easy. You can read more about the PORT event and SENSE in the Reference Manual.

    My suggestion is to use app_timer together with nrf_drv_gpiote. App_button already use this module (for button debouncing) so RTC1 is “taken”. The problem with this solution is that the SoftDevice can interrupt the reading which can lead to delays. Depending on the connection parameters this can be 0.8-6ms (old values, may be less with newer SoftDevices). This will only influence the accuracy of the reading. If you are ok with milliseconds error in the readings use app_timer.

  • E.g. I tried this, but it crashes the entire application...

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
    		err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, WheelPulseHigh);					// this fails. Why ?
    	//  APP_ERROR_CHECK(err_code);
    
    
    nrf_drv_gpiote_in_event_enable(PIN_IN, true);				// enable event and interrupt
    
Reply
  • E.g. I tried this, but it crashes the entire application...

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
    		err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, WheelPulseHigh);					// this fails. Why ?
    	//  APP_ERROR_CHECK(err_code);
    
    
    nrf_drv_gpiote_in_event_enable(PIN_IN, true);				// enable event and interrupt
    
Children
No Data
Related