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

Timeslot API - low power optimization

Hello,

I'm working with timeslot API (basing on github.com/.../observer). I have an advertising and active scanning running concurrently. However, I want to completly switch off scanning functionality for some period of time. For example, I want to scan with 15000us timeslot length and 30000us timeslot distance, but just for every 5 seconds. To manage that I have a timer running and switching on/off scanning:

static void scanner_timer_timeout_handler(void * p_context)
{
	btle_status_codes_t btle_err_code;
    UNUSED_PARAMETER(p_context);
		
	scan_run ^= true;
	
	if(scan_run)
	{
		btle_err_code = btle_scan_init (SWI1_IRQn);
		scan_enable.scan_enable = BTLE_SCAN_MODE_ENABLE;
		btle_err_code = btle_scan_enable_set (scan_enable);

	} else {
		scan_enable.scan_enable = BTLE_SCAN_MODE_DISABLE;
		btle_err_code = btle_scan_enable_set (scan_enable);
	}
}

It works fine, scanning is enabled / disabled for every timer callback call. However, I noticed that after scan disable (btle_scan_enable_set(..disable param..)) there is about 950uA current consumption.

I tested it in a following way: before an endless loop in the main() I'm invoking:

// current consumption before invoking timeslot_init() is about 0.01mA
timeslot_init()
{    
  btle_err_code = btle_scan_init (SWI1_IRQn);
  btle_err_code = btle_scan_param_set (scan_param);

  // enable scanning, current consumption here is about 11mA  
  btle_err_code = btle_scan_enable_set (scan_enable);

   // wait for 2 sec    
   nrf_delay_us(2000000);
   
   // disable scanning   
   scan_enable.scan_enable = BTLE_SCAN_MODE_DISABLE;
   btle_err_code = btle_scan_enable_set (scan_enable);
  
   // ..after disable, current is about 950uA!
}
   
main()
{    
   // some initialization here..
 
    timeslot_init();

    while(1) {
       sd_app_evt_wait();

       if(sw_interrupt()){
           // handling adv and resp packets
       }
    }
}

void SWI1_IRQHandler(void)
{
   sw_interrupt = true;
}

and I'm stuck.. I'm searching in TS source code and considering what can be disabled, but can't find anything.. (I'm using PCA10004 dev board for tests).

Could you please advise me what can I do?

Thanks!

Parents
  • @adriand : Have you tried to disable the HFCLK crystal after you disable scaning ?

    It seemed that when you request the timeslot with earliest possible type, the HFCLK crystal was kept running and hadn't been turned off after you finish.

  • Ok, I suppose I found the problem, but I doubt if I solved it correctly. In the file ll_scan.c in function ll_scan_start() I commented out every line that has GPIOTE->CONFIG:

      /* Toggle pin when radio reaches END (RX or TX) */
      // NRF_GPIOTE->CONFIG[DBG_RADIO_END] = ..
    
      /* Toggle pin when radio reaches READY (RX or TX) */
      // NRF_GPIOTE->CONFIG[DBG_RADIO_READY]= ..
    
       /* Toggle pin when timer triggers radio START (TX) */
       // NRF_GPIOTE->CONFIG[DBG_RADIO_TIMER] = ..
    

    maybe it's strange but it works (only several minutes test): advertising works, disabling / enabling scanner works, connecting works. And current consumption is ok.

Reply
  • Ok, I suppose I found the problem, but I doubt if I solved it correctly. In the file ll_scan.c in function ll_scan_start() I commented out every line that has GPIOTE->CONFIG:

      /* Toggle pin when radio reaches END (RX or TX) */
      // NRF_GPIOTE->CONFIG[DBG_RADIO_END] = ..
    
      /* Toggle pin when radio reaches READY (RX or TX) */
      // NRF_GPIOTE->CONFIG[DBG_RADIO_READY]= ..
    
       /* Toggle pin when timer triggers radio START (TX) */
       // NRF_GPIOTE->CONFIG[DBG_RADIO_TIMER] = ..
    

    maybe it's strange but it works (only several minutes test): advertising works, disabling / enabling scanner works, connecting works. And current consumption is ok.

Children
No Data
Related