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

Generating a pulse with RTC1 and PPI

Hi there,

I am trying to generate a pulse on a pin using RTC1 and PPI. Using a TIMER this works fine but my goal is to incur minimum current consumption by using only the LFCLK. Here's my code:

  NRF_RTC1->TASKS_STOP = 1;
  NRF_RTC1->TASKS_CLEAR = 1;               // clear the task first to be usable for later

  NRF_RTC1->PRESCALER = 32; //1kHz
  NRF_RTC1->CC[0] = 1000;  //1s interval
  NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;

  uint8_t ch_num = 0;
  nrf_gpiote_task_config(ch_num, PIN_NO, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
  NRF_PPI->CH[ch_num].EEP = (uint32_t)&NRF_RTC1->EVENTS_COMPARE[0];
  NRF_PPI->CH[ch_num].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[ch_num];
  NRF_PPI->CHEN = 1 << ch_num;

  NRF_RTC1->TASKS_START = 1;
  ...
  __WFI();

This code will make the PIN_NO stay high (because of the NRF_GPIOTE_INITIAL_VALUE_HIGH) for 1s then low indefinitely. I guess this is because the EVENTS_COMPARE[0] is never reset to 0.

Is there a way to make this work? Thanks! florin

Parents
  • void RTC1_IRQHandler(void)
    { 
      static volatile bool pin_state_high = true:
    
      if ( (NRF_RTC1->EVENTS_COMPARE[0] == 1) &&
          ((NRF_RTC1->INTENCLR & (1 << RTC_INTENCLR_COMPARE0_Pos)) != 0 ) )
    	{
    		NRF_RTC1->TASKS_CLEAR = 1;
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    
                if(pin_state_high)
                {
                   NRF_GPIO->OUTCLR = (1 << PIN_NO);
                }
                else
                {
                   NRF_GPIO->OUTSET = (1 << PIN_NO);
                }
                pin_state_high = !pin_state_high;
    	}
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
    	
    	NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART    = 1;
    
        while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
        {
            // Do nothing.
        }
    		
      NRF_RTC1->TASKS_STOP = 1;
      NRF_RTC1->TASKS_CLEAR = 1;               // clear the task first to be usable for later
    
      NRF_RTC1->PRESCALER = 32; //1kHz
      NRF_RTC1->CC[0] = 1000;  //1s interval
      NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
      NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
      NVIC_ClearPendingIRQ(RTC1_IRQn);
      NVIC_EnableIRQ(RTC1_IRQn);
      NRF_RTC1->TASKS_START = 1;
    
      nrf_gpio_set_dir_as_output_something (API not top of my head)
    
        while (true)
        {
            __SEV();
    	    __WFE();
    
    	    __WFE();            
            // Do Nothing - GPIO can be toggled without software intervention.
        }
    }
    
Reply
  • void RTC1_IRQHandler(void)
    { 
      static volatile bool pin_state_high = true:
    
      if ( (NRF_RTC1->EVENTS_COMPARE[0] == 1) &&
          ((NRF_RTC1->INTENCLR & (1 << RTC_INTENCLR_COMPARE0_Pos)) != 0 ) )
    	{
    		NRF_RTC1->TASKS_CLEAR = 1;
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    
                if(pin_state_high)
                {
                   NRF_GPIO->OUTCLR = (1 << PIN_NO);
                }
                else
                {
                   NRF_GPIO->OUTSET = (1 << PIN_NO);
                }
                pin_state_high = !pin_state_high;
    	}
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
    	
    	NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART    = 1;
    
        while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
        {
            // Do nothing.
        }
    		
      NRF_RTC1->TASKS_STOP = 1;
      NRF_RTC1->TASKS_CLEAR = 1;               // clear the task first to be usable for later
    
      NRF_RTC1->PRESCALER = 32; //1kHz
      NRF_RTC1->CC[0] = 1000;  //1s interval
      NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
      NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
      NVIC_ClearPendingIRQ(RTC1_IRQn);
      NVIC_EnableIRQ(RTC1_IRQn);
      NRF_RTC1->TASKS_START = 1;
    
      nrf_gpio_set_dir_as_output_something (API not top of my head)
    
        while (true)
        {
            __SEV();
    	    __WFE();
    
    	    __WFE();            
            // Do Nothing - GPIO can be toggled without software intervention.
        }
    }
    
Children
No Data
Related