Output HFCLK with PPI while SoftDevice is enabled

Using 52840, I would like to drive an external device at 800Khz

Works well without enabling the SoftDevice

// works well without SD enabled
void output_800KHz_noSD()
{
#define PIN 43
  nrf_gpio_cfg_output  (PIN); 

  NRF_CLOCK->TASKS_HFCLKSTART = 1; // Start high frequency clock
  while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
      // Wait for HFCLK to start
    }
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; // Clear event

  // Configure GPIOTE to toggle pin 
  unsigned long mask = 
      GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos |
      GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos |
      PIN << GPIOTE_CONFIG_PSEL_Pos |
      GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;

  NRF_GPIOTE->CONFIG[0] = mask;


  // Configure timer
  NRF_TIMER1->PRESCALER = 0;
  NRF_TIMER1->CC[0] = 10; // Adjust the output frequency by adjusting the CC.
  NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled
                       << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
  //NRF_TIMER1->TASKS_START = 1;

  // Configure PPI
  NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0];
  NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];

  NRF_PPI->CHENSET = PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos;

  NRF_TIMER1->TASKS_START = 1;
  
  for(;;) __WFE();
}

But once the SD is enabled - this does not work

// does not work with SD enabled - 0Hz
void output_800KHz()
{
#define PIN 43

  nrf_gpio_cfg_output (PIN);

  sd_clock_hfclk_request();
  uint32_t crystal_is_running = 0;
  while(!crystal_is_running)
  {
    sd_clock_hfclk_is_running(&crystal_is_running);
  } 

  NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Task       << GPIOTE_CONFIG_MODE_Pos)     | \
                          (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | \
                          (PIN                           << GPIOTE_CONFIG_PSEL_Pos)     | \
                          (GPIOTE_CONFIG_OUTINIT_Low     << GPIOTE_CONFIG_OUTINIT_Pos);    

  // Configure timer
  NRF_TIMER1->PRESCALER = 0; 
  NRF_TIMER1->CC[0] = 10;     //  800KHz
  NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; 

  // Configure PPI
  sd_ppi_channel_assign(0,&NRF_TIMER1->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[0]); 

  sd_ppi_channel_enable_set(1 << 0);

  NRF_TIMER1->TASKS_START = 1;

}

void stop_800KHz()
{
  NRF_TIMER1->TASKS_STOP = 1;
}  

Ideas?

Related