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

TimeSync synchronization stopped when setting ts_set_trigger() tick target to small

Hi

I'm doing a project using the TimeSync library (latest version) on 2 nRF52832 development boards.

I've ported the library to my project, the time synchronization works, but when using a too short interval when calling ts_set_trigger() in the ts_evt_callback() function, the application does one of two things after some time:

- ts_set_trigger() gets executed but suddenly doesn't generate a TS_EVT_TRIGGERED event anymore.

- TS_EVT_DESYNCHRONIZED occurs and triggering stopped

When using a larger trigger period of 20*2.5 ms = 50 ms, for example, the application runs without a problem for days.

The previous version of the TimeSync library didn't have this problem (since it was using compare registers and PPI directly to toggle a GPIO, without event callbacks).

Ideally, we'd like to get a TS_EVT_TRIGGERED event every 1 ms. (By adjusting TIME_SYNC_TIMER_MAX_VAL to 16000.)

I've tried changing the TIME_SYNC_EVT_HANDLER_IRQ_PRIORITY to a higher priority, without success.

A potential hypothesis: From this case, we see that there due to a corner case the timer on the central gets sampled incorrectly. This causes the timer on the receiver to be set incorrectly, and potentially setting the ts_set_trigger() compare value to a value in the past.

In my test setup the following parameters were used:

 

#ifndef TS_SOC_OBSERVER_PRIO
#define TS_SOC_OBSERVER_PRIO 0
#endif

#ifndef TIME_SYNC_TIMER_MAX_VAL
#define TIME_SYNC_TIMER_MAX_VAL (40000)
// #define TIME_SYNC_TIMER_MAX_VAL (16000)
#endif

#ifndef TIME_SYNC_RTC_MAX_VAL
#define TIME_SYNC_RTC_MAX_VAL   (0xFFFFFF)
#endif

#ifndef TIME_SYNC_DESYNC_TIMEOUT
#define TIME_SYNC_DESYNC_TIMEOUT 10000000 /* Timeout for desynchronization [us] */
#endif

#ifndef TIME_SYNC_TX_OFFSET_REALIGN_TIMEOUT
#define TIME_SYNC_TX_OFFSET_REALIGN_TIMEOUT 10000000 /* Set to 0 to disable [us] */
#endif

#ifndef TIME_SYNC_EVT_HANDLER_IRQ_PRIORITY
#define TIME_SYNC_EVT_HANDLER_IRQ_PRIORITY 7 /* Priority of event handler */
#endif

static void ts_imu_trigger_enable(void)
{
    uint64_t time_now_ticks;
    uint32_t time_now_msec;
    uint32_t time_target;
    uint32_t err_code;

    if (m_imu_trigger_enabled)
    {
        return;
    }

    // Round up to nearest second to next 1000 ms to start toggling.
    // If the receiver has received a valid sync packet within this time, the GPIO toggling polarity will be the same.

    time_now_ticks = ts_timestamp_get_ticks_u64();
    time_now_msec = TIME_SYNC_TIMESTAMP_TO_USEC(time_now_ticks) / 1000;

    time_target = TIME_SYNC_MSEC_TO_TICK(time_now_msec) + (1000 * 2);
    time_target = (time_target / 1000) * 1000;

    err_code = ts_set_trigger(time_target, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3));
    APP_ERROR_CHECK(err_code);

    nrf_gpiote_task_set(NRF_GPIOTE_TASKS_CLR_3);

    m_imu_trigger_enabled = true;
}

static void ts_imu_trigger_disable(void)
{
    m_imu_trigger_enabled = false;
}

static void ts_evt_callback(const ts_evt_t* evt)
{
    NRF_LOG_INFO("ts_evt_callback");

    APP_ERROR_CHECK_BOOL(evt != NULL);

    switch (evt->type)
    {
        case TS_EVT_SYNCHRONIZED:
            NRF_LOG_INFO("TS_EVT_SYNCHRONIZED");
            ts_imu_trigger_enable();
            break;
        case TS_EVT_DESYNCHRONIZED:
            NRF_LOG_INFO("TS_EVT_DESYNCHRONIZED");
            ts_imu_trigger_disable();
            break;
        case TS_EVT_TRIGGERED:
            // NRF_LOG_INFO("TS_EVT_TRIGGERED");
            if (m_imu_trigger_enabled)
            {
                uint32_t tick_target;

                tick_target = evt->params.triggered.tick_target + 2;

                uint32_t time;
                time = TIME_SYNC_TIMESTAMP_TO_USEC(tick_target) / 1000;
                NRF_LOG_INFO("target   %d", tick_target);

                uint32_t err_code = ts_set_trigger(tick_target, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3));
                if(err_code != NRF_SUCCESS)
                {
                    NRF_LOG_INFO("err_code: %d", err_code);
                }
                APP_ERROR_CHECK(err_code);
            }
            else
            {
                // Ensure pin is low when triggering is stopped
                nrf_gpiote_task_set(NRF_GPIOTE_TASKS_CLR_3);
                NRF_LOG_INFO("Triggering stopped");
            }

            uint64_t time_now_ticks;
            uint32_t time_now_msec;
            time_now_ticks = ts_timestamp_get_ticks_u64();
            time_now_msec = TIME_SYNC_TIMESTAMP_TO_USEC(time_now_ticks) / 1000;
            NRF_LOG_INFO("now  %d", TIME_SYNC_MSEC_TO_TICK(time_now_msec));
            
            break;
        default:
            APP_ERROR_CHECK_BOOL(false);
            break;
    }
}

static void sync_timer_init(void)
{
    uint32_t err_code;

    // Debug pin:
    // nRF52-DK (PCA10040) Toggle P0.24 from sync timer to allow pin measurement
    // nRF52840-DK (PCA10056) Toggle P1.14 from sync timer to allow pin measurement
#if defined(BOARD_PCA10040)
    nrf_gpiote_task_configure(3, NRF_GPIO_PIN_MAP(0, 24), NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_enable(3);
#elif defined(BOARD_PCA10056)
    nrf_gpiote_task_configure(3, NRF_GPIO_PIN_MAP(1, 14), NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_enable(3);
#else
#warning Debug pin not set
#endif

    ts_init_t init_ts =
    {
        .high_freq_timer[0] = NRF_TIMER3,
        .high_freq_timer[1] = NRF_TIMER4,
        .egu                = NRF_EGU3,
        .egu_irq_type       = SWI3_EGU3_IRQn,
        .evt_handler        = ts_evt_callback,
    };

    err_code = ts_init(&init_ts);
    APP_ERROR_CHECK(err_code);

	ts_rf_config_t rf_config =
	{
		.rf_chn = 80,
		.rf_addr = { 0xDE, 0xAD, 0xBE, 0xEF, 0x19 }
	};

    err_code = ts_enable(&rf_config);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_INFO("Started listening for beacons.\r\n");
    NRF_LOG_INFO("Press Button 1 to start transmitting sync beacons\r\n");
    NRF_LOG_INFO("GPIO toggling will begin when transmission has started.\r\n");
}

Any help would be appreciated!

Parents Reply Children
No Data
Related