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.

Parents
  • I don't see the reason why it shouldn't work when you add your timer code, but I don't know how your application is put together. Do you check the return value for APP_UART_FIFO_INIT? What is "ErrorCode" after APP_UART_FIFO_INIT and app_timer_create()?

    I see that you have this line:

    NRF_CLOCK->TASKS_LFCLKSTOP = 1;

    Do you start it again at some point? And what does the UARTTimeout timer do? And what do you mean by that the UART stops working? Are you not able to send messages? Are you not able to receive messages? And again, please check the return values for your UART and app_timer calls.

    Best regards,

    Edvin

  • Hi Edvin, after further testing, it seems that for an unknown reason, NRF_CLOCK ->EVENTS_HFCLKSTARTED never gets sets to 1 sometimes and thus get stuck in the while loop. The issue is  intermittent and I am not sure what is causing that. Do you have an idea why that might be?

  • I am not sure. Do you call:

    NRF_CLOCK->TASKS_HFCLKSTART = 1;

    before that? It looks like you do in the snippet that you have included, but did you change anything regarding the NRF_CLOCK->EVENTS_HFCLKSTARTED?

    Is there any way for me to replicate this on a DK? Are you able to replicate this on a DK?

    You say that this occurs sometimes. Does this mean that it occurs every time on certain devices, and never on other devices, or does it occur sometimes on all devices?

    Best regards,

    Edvin

  • Hello Edvin, 

    you could probably try it on a DK and see if you can reproduce the issue. I see the issue in a pretty simple loop :

    1) I initialize my needed hardware (a few GPIO + Softdevice stack for a peripheral WITHOUT STARTING THE ADVERTISING). The stack init function is the same one as the SDK (ble_stack_init()), with a different  name to match our coding standards. 

    2) I enter the production loop where I call the function StartClockOutput exactly as described in my original post.

    I'd say 3 times out of 4, the initialization is done correctly and the NRF51822 doesn't get stuck in the while loop. 

    Is the CLOCK register persistent through resets? 

  • JFGagnon said:
    Is the CLOCK register persistent through resets? 

     No.

     

    Edvin said:
    You say that this occurs sometimes. Does this mean that it occurs every time on certain devices, and never on other devices, or does it occur sometimes on all devices?

     Please clarify.

    Please provide a project that replicates this if you are not able to debug the issue. 

    Best regards,

    Edvin

  • Hello Edvin,

    I am not going to create a dummy project just to replicate the issue. Feel free to create one yourself if you want to go to the botom of the issue, but I will be closing this ticket as there isn't much more to dscuss here.

    For the use that we have of the PPI clock, I simply forego the while loop check and it seems to work for my need. 

Reply Children
No Data
Related