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

restricted peripheral access

Hi,

I want to access restricted peripheral: TIMER0. After small research found that I should use sd_ wrappers, in my case sd_nvic_SetPendingIRQ(TIMER0_IRQn) however I got always NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE error. How can I check if resource is currently used by softDevice? __sd_nvic_app_accessible_irq(TIMER0_IRQn) also gives always false.

  • The Soft Device Specification has a table is section 11 of the peripherals. TIMER0 is not restricted, it is blocked with the caveat that it is accessible using the multi protocol timeslot. So, you cannot access it using the Soft Device without the timeslot feature enabled.

    What is it about TIMER0 that you can't do with TIMER1 or TIMER2? There may be other alternatives if we know what you are trying to accomplish.

  • I have enabled timeslot and my question is related to timeslot. I want to terminate timeslot so I'm calling:

    timer0_enter_critical();
    radio_enter_critical();
    //__disable_irq();
    
    // terminate immediately if in timeslot
    if(m_timeslot.in_timeslot)// && __sd_nvic_app_accessible_irq(TIMER0_IRQn)) // start immediately if in timeslot
    {
    	// set session terminate flag
    	m_timeslot.terminate_flag = true;
    
    	// report when session is closed
    	m_timeslot.external_session_close_flag = true;
    
    	// stop and clear TIMER0
    	NRF_TIMER0->TASKS_STOP 	 = 1;
    	NRF_TIMER0->TASKS_CLEAR  = 1;
    
    	// disable TIMER0 interrupts
    	NRF_TIMER0->INTENCLR 	 = ((TIMER_INTENSET_COMPARE1_Enabled  << TIMER_INTENSET_COMPARE1_Pos)  & TIMER_INTENSET_COMPARE1_Msk);
    	NRF_TIMER0->CC[1]    	 = 0;
    
    	// clear and set pending TIMER0 interrupt
    	NVIC_ClearPendingIRQ(TIMER0_IRQn);
    	NVIC_SetPendingIRQ(TIMER0_IRQn);
    }
    else
    {
    	// set session terminate flag
    	m_timeslot.terminate_flag = true;
    
    	// report when session is closed
    	m_timeslot.external_session_close_flag = true;
    }
    
    timer0_exit_critical();
    radio_exit_critical();
    //__enable_irq();
    

    I'm setting m_timeslot.in_timeslot to true after NRF_RADIO_CALLBACK_SIGNAL_TYPE_START and to false after NRF_EVT_RADIO_SESSION_IDLE

    and in static nrf_radio_signal_callback_return_param_t * m_timeslot_callback(uint8_t signal_type):

    ...

    if(m_timeslot.terminate_flag)
    {
    	//SEGGER_SYSVIEW_Print("terminate_flag");
    	//SEGGER_RTT_printf(0,"terminate_flag\n");
    
    	m_timeslot.terminate_flag = false;
    
    	NRF_PPI->CHENCLR 								   = ((PPI_CHEN_CH8_Enabled << PPI_CHEN_CH8_Pos) & PPI_CHEN_CH8_Msk);
    	signal_callback_return_param.params.request.p_next = NULL;
    	signal_callback_return_param.callback_action       = NRF_RADIO_SIGNAL_CALLBACK_ACTION_END;
    	m_timeslot.in_timeslot    						   = false;
    
    	return ( &signal_callback_return_param );
    }
    

    ...

    But after some time I'm landing in hard fault handler so I'm guessing that problem is accesing TIMER0 while it's used by softdevice.

  • Unfortunately you have advanced beyond my ability to help. I know of the timeslot feature but I have not used it. Hopefully someone else can address your question.

  • Hi,

    For reference consult the tutorial on timeslots and the infocenter reference.

    After returning NRF_RADIO_SIGNAL_CALLBACK_ACTION_END you will terminate the ongoing timeslot. Which hard fault are you getting?

    You could get issues if you do not requests timeslots specifically with HFCLK active, are you calling

    m_timeslot_request.params.your_config.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
    

    as part of your request to ensure that you have guaranteed crystal usage?

    Best regards,

    Øyvind

  • I have HFCLK active. My request looks like:

    static nrf_radio_request_t * m_request_earliest(enum NRF_RADIO_PRIORITY priority) { m_timeslot.timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST; m_timeslot.timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED; m_timeslot.timeslot_request.params.earliest.priority = priority; m_timeslot.timeslot_request.params.earliest.length_us = TIMESLOT_LEN_US; m_timeslot.timeslot_request.params.earliest.timeout_us = 1000000; return &m_timeslot.timeslot_request; }

    Ofcourse I'm returning NRF_RADIO_SIGNAL_CALLBACK_ACTION_END in nrf_radio_signal_callback_return_param_t * m_timeslot_callback, but I must wait for any signal to enter this callback. To avoid delay I'm calling NVIC_SetPendingIRQ(TIMER0_IRQn); which causes immediate enter to this callback but it's problematic when softdevice is currently running. So if I good understanding I must check if soft device is running before call NVIC_SetPendingIRQ(TIMER0_IRQn); How to do that?

Related