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

How to resolve conflict when generating HF clock out

I have code running on a nRF52 device, with SoftDevice enabled, based on the example given in this topic:

devzone.nordicsemi.com/.../

This runs fine on its own, and produces an 8MHz clock. But if I enable another timer, even if it's using a different timer instance, this 8MHz clock output stops. It starts and runs until the other timer is started, and then this one stop. If I start the other timer first and then this one, it runs (although I believe the first one stops - I haven't confirmed that yet).

I tried changing the two timers to use different instances, but it doesn't seem to matter. How can I avoid this conflict?

I would also like to change this code to use the API provided by the SDK wherever possible (instead of manipulating registers directly). What functions or libraries should be looking for to do this?

EDIT: I did some further debugging and found that the 8MHz clock output stops when nrf_drv_gpiote_in_init is called. The code that starts the second timer (which causes the 8MHz clock output to stop) is shown below, without the error handling and other clutter to simplify reading. I had assumed that the clock stopped when this function reached nrf_drv_timer_init at the end, but I found that it happens the first time nrf_drv_gpiote_in_init is called. The clock output code is almost identical to what is shown in the topic referenced above, except I changed the pin from 18 to 20, and I changed references to NRF_TIMER1 to NRF_TIMER2.

Why is initializing the GPIO input causing timer 2 to stop?

static const nrf_drv_timer_t m_tof_timer = NRF_DRV_TIMER_INSTANCE(1);

#define TOF_TIMER_CFG { \
    .frequency          = (nrf_timer_frequency_t)NRF_TIMER_FREQ_16MHz, \
    .mode               = (nrf_timer_mode_t)NRF_TIMER_MODE_TIMER, \
    .bit_width          = (nrf_timer_bit_width_t)NRF_TIMER_BIT_WIDTH_32, \
    .interrupt_priority = TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \
    .p_context          = NULL \
}

#define START_STOP_CFG { \
    .sense = NRF_GPIOTE_POLARITY_LOTOHI, \
    .pull  = NRF_GPIO_PIN_NOPULL, \
    .is_watcher = false, \
    .hi_accuracy = true \
}

ret_code_t tof_init()
{
    if (!nrf_drv_gpiote_is_init()){
        nrf_drv_gpiote_init();
    }

    nrf_drv_timer_config_t tof_timer_cfg = TOF_TIMER_CFG;

    nrf_drv_gpiote_in_config_t start_stop_config = START_STOP_CFG;

    nrf_drv_gpiote_out_config_t trigger_config = GPIOTE_CONFIG_OUT_SIMPLE(0);

    nrf_drv_gpiote_in_init(12, &start_stop_config, start_event_handler);

    nrf_drv_gpiote_out_init(11, &trigger_config);

    nrf_drv_gpiote_in_init(13, &start_stop_config, stop_event_handler);

    nrf_drv_gpiote_in_event_enable(12, true);
    nrf_drv_gpiote_in_event_enable(13, true);

    nrf_drv_timer_init(&m_tof_timer, &tof_timer_cfg, tof_timer_handler);

    return NRF_SUCCESS;
}
  • Hi, Any progress? I see that you are not checking the return codes of any of the gpiote functions in tof_init(). Have you tried debugging like this to check if maybe the return codes can give us a clue? If you call [nrf_drv_gpiote_in_init()](http:// nrf_drv_gpiote_in_init) twice with the same pin number, for example, it will return an error and your code will probably not work.

  • Hi, yes I have typical error checking in the code and it gives no errors - I just removed all that to make this snippet easier to read. But I since found out that the code above somehow interferes with the GPIOTE in an unexpected way. I had four GPIOTE channels being used (four interrupts generated from four hardware pins) and they were all working fine, but after running the above code, one of the interrupts doesn't work. If the above code doesn't run, all interrupts are generated as normal. I understand there are 8 channels, but I'm only using 4 that I know it. (I don't think the SoftDevice uses any right?)

  • Do you mind posting your entire code relevant to this? I can't see where you are initiating a second timer for example. You can edit your initial question and just add a .c file. Also,

    1. What SDK are you using?
    2. Did you confirm this: "If I start the other timer first and then this one, it runs (although I believe the first one stops - I haven't confirmed that yet)."
    3. The softdevice is not using any GPIOTE channels as you can see here.
Related