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

PPI AND SOFTDEVICE

Hi

I try to configure a ppi channel with timers to generate pwm signal My entire code is working well without softdevice. Here my ppi init function:

 NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[0];
        NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];   
        
	// Enable PPI channels 0.
	NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos); 

Now, i try to adapt my code for softdevice. So i used sd_ppi_channel_assign function instead NRF_PPI registers :

sd_ppi_channel_assign(0,&NRF_TIMER2->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[0]); sd_ppi_channel_enable_set(1 << 0);

sd_ppi_channel_assign call cause an hardfault error...

Does anybody have an idea were it can come from?

  • I can't due to confidentiality. I will open a new support case.

    Thanks

    -------------------------------Edit 30/07/14------------------------------------------

    Here response from nordic's support. It may be helpful....

    Hi,

    I tried to compile and run your code, but think the hardfault occur when you try to write to the CLOCK module directly, this module is protected by the softdevice. The solution is to use the nrf_soc API in timer_init() as shown below:

    /** @brief Function for initializing the Timer 2 peripheral.
    
     */
    
    static void timer_init(void)
    
    {
    
        // Start 16 MHz crystal oscillator .
    
        //NRF_CLOCK->EVENTS_HFCLKSTARTED  = 0;
    
        //NRF_CLOCK->TASKS_HFCLKSTART     = 1;
    
        sd_clock_hfclk_request();
    
     
    
        // Wait for the external oscillator to start up.
    
        //while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    
        //{
    
            //Do nothing.
    
        //}
    
        uint32_t crystal_is_running = 0;
    
       
    
        while(!crystal_is_running)
    
        {
    
            sd_clock_hfclk_is_running(&crystal_is_running);
    
        }   
    
     
    
        PWM_TIMER->MODE                = TIMER_MODE_MODE_Timer;
    
                                    PWM_TIMER->BITMODE                                             = 0;
    
                                    PWM_TIMER->PRESCALER                          = PRESCAL ;
    
                                   
    
        // Clears the timer, sets it to 0.
    
        PWM_TIMER->TASKS_CLEAR = 1;
    
                                   
    
        // Interrupt setup.
    
        PWM_TIMER->INTENSET = TIMER_INTENSET_COMPARE0_Msk | TIMER_INTENSET_COMPARE1_Msk;
    
                                                                                                                                                                     
    
    }
    

    Best regards,

Related