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

[NRF51822] UART stops working when enabling PPI

Hello,

I am having a strange issue. We are currently in pre-production with our product which uses the NRF51822.

Just for context, the production tests use the UART peripheral to receive command and initiate short test sequences and return a response to our test jig.

One of the test is to output an 8MHz clock to check if the crystal is correctly installed and within spec. To do so, I use the PPI as described here : https://devzone.nordicsemi.com/f/nordic-q-a/4988/how-to-get-3mhz-5mhz-clock-signal-out-from-gpio-of-nrf51822

On it's own, it is working correctly and I can output a precise 8MHz clock on the GPIO 04 pin. However, as soon as I start the 8MHz clock with PPI, the UART is not sending or receiving data anymore. 

Here is the function for the Clock output.

static void StartClockOutput (void)
{
  nrf_gpio_cfg_output(CLOCK_MEASURE_PIN);
  nrf_gpio_pin_set(CLOCK_MEASURE_PIN);

  //init the HF clock if it's not done already
  NRF_CLOCK->TASKS_HFCLKSTART = 1;

  //wait until the clock is started
  while(0 == NRF_CLOCK ->EVENTS_HFCLKSTARTED)
  {
  }
  //clear the HF CLK Started flag
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

  //test
  NRF_CLOCK->TASKS_LFCLKSTOP = 1;

  //configure the timer
  NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos |
  GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos |
  CLOCK_MEASURE_PIN << GPIOTE_CONFIG_PSEL_Pos |
  GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;

  //Freq = 16MHz/(2^PRESCALER). Since we toggle on/off, the prescaler is 0 for a 8MHz clock
  NRF_TIMER1->PRESCALER =0;
  //since we want the fastest clock, we need to set the compare counter (CC) to 1 so that it triggers every 125ns
  NRF_TIMER1->CC[0] = 1;
  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;
}

And here is the function where I initialize the UART peripheral

void UART_Init(void)
{
  uint32_t ErrorCode;
  const app_uart_comm_params_t comm_params = 
  {
    UART_RX_PIN, //RX_PIN_NUMBER,
    UART_TX_PIN, //TX_PIN_NUMBER,
    NULL, //RTS_PIN_NUMBER,
    NULL, //CTS_PIN_NUMBER,
    APP_UART_FLOW_CONTROL_DISABLED,
    false,
    UART_BAUDRATE_BAUDRATE_Baud115200
};

  APP_UART_FIFO_INIT(&comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_error_handle,
    APP_IRQ_PRIORITY_LOWEST,
    ErrorCode);

  //Create UART Timeout timer
  ErrorCode = app_timer_create(&UARTTimeout, APP_TIMER_MODE_SINGLE_SHOT, UART_TimeoutHandler);
  APP_ERROR_CHECK(ErrorCode);
  (void)ErrorCode;
}

UART_RX_PIN = GPIO01
UART_TX_PIN = GPIO02
CLOCK_MEASURE_PIN = GPIO04

Reading through the reference manual v3.0, on page 151, there is a section Shared Ressources where it is written that the UART0 is sharing registers with other ressources. What I cannot find is with which preripheral does it share its ressources.

Also, is it possible to confirm that the PPI configuration should not interfere with the UART?

Thanks

EDIT: For clarifications, I am still investigating the issue, but I would like to confirm that the PPI shouldn't have any impact on the UART.

Related