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

sd_clock_hfclk_request() ; start of ext. 16MHz Stuck

EDIT:

I'm using nRF51422-QFAA E00 and S310 v1.0.0, SDK - nRF51 5.2.0.

I'm starting HFCLK from externall crystal for ADC conversion. Since I have no SD enabled everything is OK, but within SD and using function sd_clock_hfclk_request() problem appears. It simmply stuck in the loop where sd_clock_hfclk_is_running(&tmp) is checked -> still returning 0. Enabling SD I have same as in examples and if I try the other SD funcs (like sd_temp_get()) they works ok. Example project with BLE and ANT works ok - I can see broadcast.

I tried to recompile project with S210 v 3.0.0 with same behaviour. I can't see in PAN doc any problem about that for my revision.

Here is my code for hfclk start for SD and non SD use:

void V_hw_HFClock_Enabled(void)
{
	u32 p_is_running;
	
	// XTALFREQ is set by UICR (16MHz default)	
	/* Start 16 MHz crystal oscillator */
	#ifdef NO_SD
		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
		NRF_CLOCK->TASKS_HFCLKSTART = 1;
		/* Wait for the external oscillator to start up */
		while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {} 
		NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
	#else
		(void)sd_clock_hfclk_request();
		do { 
			sd_clock_hfclk_is_running(&p_is_running); 
		}while(p_is_running==0);	
	#endif
}


void V_hw_SD_Setup(void)
{
	u32 err_code;

	err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, softdevice_assert_callback);		// ABS06-32.768kHz-9-T +-20ppm
	if(err_code != NRF_SUCCESS) V_error_handler(E_SD_EN);
  err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW); 
  if(err_code != NRF_SUCCESS) V_error_handler(E_SD_SP);
  err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);      
  if(err_code != NRF_SUCCESS) V_error_handler(E_SD_EI);	
}

main loop:
V_hw_SoC_Init();
	
	sd_temp_get(&p);
	tmp2 = sd_clock_hfclk_request();
	if(tmp2 != NRF_SUCCESS) NRF_GPIO->OUTSET = (1UL << LED);
	do { 
			tmp2 = sd_clock_hfclk_is_running(&tmp); 
			if(tmp2 != NRF_SUCCESS) NRF_GPIO->OUTSET = (1UL << LED);
		}while(tmp==0);	
	NRF_GPIO->OUTSET = (1UL << LED);

LED is still OFF, so no error and can't get out of loop (unitl WDG after 2sec made a reset).

I don't know why it works when I'm not using SD and start HF CLK with registers and why not with enabled SD and HF start by SD funcs. I have attached HF CLK XTAL 16MHz (NX2520SA) startup if someone can compare for startup time.

scope_0.png scope_1.png scope_2.png

  • I tried to debug that and probably found a clue. Inside my ADC conversion function I start the HF Clock and a few lines below I use my delay function which starts RTC1 and here it stucks. Same for BlinkLed I start there same delay function. So it is not possible to have HF clock running and simultanously use some other peripheral using LFCLK?

    BTW with non SD HF Clk started by code you wrote above it's not a problem - no stuck.

  • So where does it stuck? In sd_clock_hfclk_request() or in V_hw_BlinkLed()? What's inside V_hw_BlinkLed()?

  • I put here what's inside my delay to be clear. It will stuck in sd_app_evt_wait(); but IRQ routine is called so it should wake up.

    V_hw_SoC_Init();
    V_hw_BlinkLed(100, 3);	  
    sd_temp_get(&p);
    sd_clock_hfclk_request();
    sd_temp_get(&p);
    NRF_GPIO->OUTSET = (1UL << LED);
    NRF_RTC1->TASKS_START = 1;
    U32_delay_ms = 100;	
    sd_app_evt_wait();
    NRF_GPIO->OUTCLR = (1UL << LED);
    U32_delay_ms = 0;
    NRF_RTC1->TASKS_STOP = 1;
    
  • I can't understand how your RTC is working, post init code for rtc and irq handler.

  • Here it is. It always stuck with first call of sd_app_evt_wait() when sd_clock_hfclk_request() was called before. IRQ routine is entered each 1ms so that's OK.

    void V_hw_rtc_init(void)
    {	
    	NRF_RTC1->PRESCALER = RTC1_PRESCALER; 
    	NRF_RTC1->CC[0] = RTC1_CC0;   
    	
    	NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; 		
      NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
    	
      #ifdef NO_SD
    		NVIC_SetPriority(RTC1_IRQn, APP_IRQ_PRIORITY_HIGH); // HIGH - for accurate delay timing
    		NVIC_ClearPendingIRQ(RTC1_IRQn);
    		NVIC_EnableIRQ(RTC1_IRQn);
    	#else
    		sd_nvic_SetPriority(RTC1_IRQn, APP_IRQ_PRIORITY_HIGH); // HIGH - for accurate delay timing
    		sd_nvic_ClearPendingIRQ(RTC1_IRQn);
    		sd_nvic_EnableIRQ(RTC1_IRQn);
    	#endif
      //NRF_RTC1->TASKS_START = 1;
    	/* Nordic example for app_timer has a few us delay here */	
    	
    	U32_delay_ms = 0;	
    }
    
    void RTC1_IRQHandler(void)	/*lint !e765 !e714 */
    {  
    	/* Every 1ms */
    	if (NRF_RTC1->EVENTS_COMPARE[0] != 0)
      {
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    		NRF_RTC1->TASKS_CLEAR = 1;  // Clear Counter		
    		
    		if(U32_delay_ms) U32_delay_ms--; // used in V_hw_delay_ms()		
    		
      }
    }
    
    void V_hw_delay_ms(volatile u32 ms)
    {	
    	U32_delay_ms = ms;
    	NRF_RTC1->TASKS_START = 1;
    		
    	while(U32_delay_ms) (void)sd_app_evt_wait();		
    	
    	NRF_RTC1->TASKS_STOP = 1;
    }
    

    I tried also with NRF_APP_PRIORITY_LOW but with same result.

Related