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

some question of nrf51822 timer

I am developing using a nrf51822.I need delay timer that can be substitued for nrf_delay_ms(). in other words,need a task delay that can be taken some event from another side during delay time. Is nrf_timer_delay_ms() possible ? If so,please tell me how to use and attention point regarding sw side and hw side. BR

Parents
  • Here's my best guess. Not tested:

    
    #include <nrf51_bitfields.h>
    #include <nrf51.h>
    
    #define LFCLK_FREQUENCY           (32768UL)                               /**< LFCLK frequency in Hertz, constant. */
    
    // The attribute constructor ensures this runs before main.
    void initClock() __attribute__((constructor));
    
    void initClock()
    {
    	NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Synth << CLOCK_LFCLKSRC_SRC_Pos);
    	NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
    	NRF_CLOCK->TASKS_LFCLKSTART     = 1;
    	while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    	{
    	}
    }
    
    /** @brief Function for configuring the RTC with TICK to 100Hz and COMPARE0 to 10 sec.
     */
    void sleepDelay(uint32_t ms)
    {
    	// We use RTC1 since RTC0 is controlled by the soft device.
    
    	// Enable interrupt.
    	NVIC_EnableIRQ(RTC1_IRQn);
    
    	// Find the minimum prescalar for this delay.
    	//
    	// Freq = 32768 Hz / (PRESCALAR + 1)
    	//
    	// RTC1 has a 24 bit counter.
    	//
    	// So we want 0xFFFFFF / Freq > ms
    	// =>   PRESCALAR > ms * 32768 / 0xFFFFFF - 1
    	//
    	// PRESCALAR is in the range 0 to 2^12-1.
    
    	NRF_RTC1->PRESCALER     = ms * LFCLK_FREQUENCY / 0xFFFFFFUL;
    	NRF_RTC1->CC[0]         = ms * LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1);
    
    	// Enable COMPARE0 event and COMPARE0 interrupt:
    	NRF_RTC1->EVTENSET      = RTC_EVTENSET_COMPARE0_Msk;
    	NRF_RTC1->INTENSET      = RTC_INTENSET_COMPARE0_Msk;
    
    	NRF_RTC1->TASKS_CLEAR = 1;
    	NRF_RTC1->TASKS_START = 1;
    
    	// Wait For Event.
    	// This wakes up when any interrupt is fired so it is possible that the delay will not be as long as requested.
    	__WFE();
    }
    
    /** @brief: Function for handling the RTC0 interrupts.
     * Triggered on TICK and COMPARE0 match.
     */
    void RTC1_IRQHandler()
    {
    	if ((NRF_RTC1->EVENTS_COMPARE[0] != 0) && ((NRF_RTC1->INTENSET & RTC_INTENSET_COMPARE0_Msk) != 0))
    	{
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    		NRF_RTC1->INTENSET = 0;
    		NRF_RTC1->TASKS_STOP = 1;
    	}
    }
    
    
Reply
  • Here's my best guess. Not tested:

    
    #include <nrf51_bitfields.h>
    #include <nrf51.h>
    
    #define LFCLK_FREQUENCY           (32768UL)                               /**< LFCLK frequency in Hertz, constant. */
    
    // The attribute constructor ensures this runs before main.
    void initClock() __attribute__((constructor));
    
    void initClock()
    {
    	NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Synth << CLOCK_LFCLKSRC_SRC_Pos);
    	NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
    	NRF_CLOCK->TASKS_LFCLKSTART     = 1;
    	while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    	{
    	}
    }
    
    /** @brief Function for configuring the RTC with TICK to 100Hz and COMPARE0 to 10 sec.
     */
    void sleepDelay(uint32_t ms)
    {
    	// We use RTC1 since RTC0 is controlled by the soft device.
    
    	// Enable interrupt.
    	NVIC_EnableIRQ(RTC1_IRQn);
    
    	// Find the minimum prescalar for this delay.
    	//
    	// Freq = 32768 Hz / (PRESCALAR + 1)
    	//
    	// RTC1 has a 24 bit counter.
    	//
    	// So we want 0xFFFFFF / Freq > ms
    	// =>   PRESCALAR > ms * 32768 / 0xFFFFFF - 1
    	//
    	// PRESCALAR is in the range 0 to 2^12-1.
    
    	NRF_RTC1->PRESCALER     = ms * LFCLK_FREQUENCY / 0xFFFFFFUL;
    	NRF_RTC1->CC[0]         = ms * LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1);
    
    	// Enable COMPARE0 event and COMPARE0 interrupt:
    	NRF_RTC1->EVTENSET      = RTC_EVTENSET_COMPARE0_Msk;
    	NRF_RTC1->INTENSET      = RTC_INTENSET_COMPARE0_Msk;
    
    	NRF_RTC1->TASKS_CLEAR = 1;
    	NRF_RTC1->TASKS_START = 1;
    
    	// Wait For Event.
    	// This wakes up when any interrupt is fired so it is possible that the delay will not be as long as requested.
    	__WFE();
    }
    
    /** @brief: Function for handling the RTC0 interrupts.
     * Triggered on TICK and COMPARE0 match.
     */
    void RTC1_IRQHandler()
    {
    	if ((NRF_RTC1->EVENTS_COMPARE[0] != 0) && ((NRF_RTC1->INTENSET & RTC_INTENSET_COMPARE0_Msk) != 0))
    	{
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    		NRF_RTC1->INTENSET = 0;
    		NRF_RTC1->TASKS_STOP = 1;
    	}
    }
    
    
Children
No Data
Related