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

PPI interrupt was influenced by BLE connecting event

Hi,

I used PPI module and Timer2 to generate a 4Mhz pwm. But I founld when using softdevice(s110 v7.0), the pwm will be broke a while by BLE advertising or connecting event. So I suppose the ble event will influence the PPI module ?

And is there any other method to generate a 4Mhz or 8Mhz clock to driver external device?

Parents
  • You need to use the GPIOTE tasks to have the PPI driver the GPIO directly without any intervention. I had the same problem and had to jiggle around to get it to work.

    This snippet of code is used to drive a buzzer (via PWM) with two output lines tied together and another output line at the opposite (so when the two are high, I set the other low). But you can strip out a bunch of these to just have it toggle one line.

    // Configure as outputs
    nrf_gpio_cfg_output(BUZZER_OUT_0);
    nrf_gpio_cfg_output(BUZZER_OUT_1);
    nrf_gpio_cfg_output(BUZZER_IN_0);
    
    // Configure GPIOTE_CHANNEL_NUMBER to toggle the GPIO pin state with input.
    // @note Only one GPIOTE task can be coupled to an output pin.
    nrf_gpiote_task_config(0 /*GPIOTE_CHANNEL_NUMBER*/, BUZZER_OUT_0, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_config(1 /*GPIOTE_CHANNEL_NUMBER*/, BUZZER_OUT_1, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_config(2 /*GPIOTE_CHANNEL_NUMBER*/, BUZZER_IN_0, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
    
    // Clear TIMER2
    NRF_TIMER2->TASKS_CLEAR = 1;
    
    // Configure TIMER2 for compare[0] event every xx 
    NRF_TIMER2->PRESCALER = 0;
    NRF_TIMER2->CC[0]     = 1904;
    NRF_TIMER2->MODE      = TIMER_MODE_MODE_Timer;
    NRF_TIMER2->BITMODE   = TIMER_BITMODE_BITMODE_16Bit;
    NRF_TIMER2->SHORTS    = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
    
    // Configure the PPI
    sd_ppi_channel_assign(0 /*ch_num*/, &NRF_TIMER2->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[0]);
    sd_ppi_channel_enable_set(1 << 0 /*ch_num*/);
    
    sd_ppi_channel_assign(1 /*ch_num*/, &NRF_TIMER2->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[1]);
    sd_ppi_channel_enable_set(1 << 1 /*ch_num*/);
    
    sd_ppi_channel_assign(2 /*ch_num*/, &NRF_TIMER2->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[2]);
    sd_ppi_channel_enable_set(1 << 2 /*ch_num*/);
    // Start it
    NRF_TIMER2->TASKS_START = 1;  // Start event generation.
    

    This value here 1904 is for about 4.1Khz. You can calculate this with the formula

    pwm_max_value = 16.000.000 / (2 * 2^PRESCALER * FREQUENCY)

    Hope that helps, I had exactly the same problem with the BLE SD as the interrupts are the highest priority so all the nrf_pwm.c sample code had issues..

  • I notice you haven't set any priority for Timer2. Would that be necessary? I am having similar code causing issues with the Button module which also uses the GPIOTE. Wasn't sure if it was due to not having set the Timer2 Interrupt Priority, or having set APP_GPIOTE_MAX_USERS 1 and not 2.

Reply Children
No Data
Related