Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Time synchronization with alternating masters

Dear members,

with success I implemented the time synchronization example from the nRF5 SDK guide.
This example works perfect for a single master, but what if the master changes?
When I check my scope it will show that the new master starts sending the sync beacons, but the slave (previous master) is not receiving and stays low.
Would there be a solution to put a master in receiver mode after stopping the sync beacons?

I am using four nRF52840-DKs with Segger Studio, SDK 17 and a S140 softdevice (used for a custom BLE service)

  • Hello,

    The example is not an official release, but I can try to ping the person that made the example if he can take a look. He is currently out of office until after Easter though.

    Kenneth

  • Hello Kenneth,

    that would be great. If I find the solution before Easter I will let you know ;).

    Regards, Egbert

  • Hello Kenneth,

    I was not able to find a solution to this item. Did you managed to contact the creator of this example?

    Regards, Egbert

  • Hi Egbert,

    I suspect there is state information still lingering after stopping the transmitter. Could you try the attached diff on your side?

    My test was  the following, based on 2 x nRF52-DK.

    1) Press button 1 on DK #1 to assign this role of transmitter

    2) Observe that both DKs toggle GPIO in unison

    3) Press button 1 on DK #1 to stop transmitting

    4) Wait until DK #2 reports desynchronization (GPIO stops togglnig)

    5) Press button 1 on DK #2 to assign this role of transmitter

    6) Observe that both DKs toggle GPIO in unison

    diff --git a/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c b/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    index 4a21351..871498a 100644
    --- a/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    +++ b/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    @@ -128,6 +128,7 @@ static nrf_atomic_u32_t m_sync_pkt_ringbuf_idx;
     
     static nrf_atomic_flag_t m_timeslot_session_open;
     static nrf_atomic_flag_t m_pending_close;
    +static nrf_atomic_flag_t m_pending_tx_stop;
     static nrf_atomic_u32_t  m_blocked_cancelled_count;
     static uint32_t          m_total_timeslot_length = 0;
     static uint32_t          m_timeslot_distance = 0;
    @@ -469,6 +470,15 @@ void timeslot_begin_handler(void)
     
         m_total_timeslot_length = 0;
     
    +    if (m_pending_tx_stop)
    +    {
    +        nrf_atomic_flag_clear(&m_send_sync_pkt);
    +        nrf_atomic_flag_clear(&m_pending_tx_stop);
    +        m_timeslot_distance = 0;
    +        m_synchronized = false;
    +        m_master_counter_diff = 0;
    +    }
    +
         if (!m_send_sync_pkt)
         {
             if (m_radio_state    != RADIO_STATE_RX ||
    @@ -737,6 +747,7 @@ void SWI3_EGU3_IRQHandler(void)
             if (m_synchronized)
             {
                 m_synchronized = false;
    +            m_master_counter_diff = 0;
     
                 if (m_callback)
                 {
    @@ -1217,7 +1228,7 @@ uint32_t ts_tx_start(uint32_t sync_freq_hz)
     
     uint32_t ts_tx_stop()
     {
    -    nrf_atomic_flag_clear(&m_send_sync_pkt);
    +    nrf_atomic_flag_set(&m_pending_tx_stop);
     
         return NRF_SUCCESS;
     }
    

    Best regards,

    Audun

  • Hi again,

    I thought about it some more and decided the previous diff was a not so good workaround. This one should work better, as it doesn't reset the "m_master_counter_diff" variable. Resetting this variable would cause a jump in timestamps, which is probably not desirable.

    Best regards,

    Audun

    diff --git a/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c b/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    index 4a21351..65c5c13 100644
    --- a/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    +++ b/nRF5_SDK_16.0.0_98a08e2/examples/common/time_sync.c
    @@ -128,6 +128,7 @@ static nrf_atomic_u32_t m_sync_pkt_ringbuf_idx;
     
     static nrf_atomic_flag_t m_timeslot_session_open;
     static nrf_atomic_flag_t m_pending_close;
    +static nrf_atomic_flag_t m_pending_tx_stop;
     static nrf_atomic_u32_t  m_blocked_cancelled_count;
     static uint32_t          m_total_timeslot_length = 0;
     static uint32_t          m_timeslot_distance = 0;
    @@ -469,6 +470,14 @@ void timeslot_begin_handler(void)
     
         m_total_timeslot_length = 0;
     
    +    if (m_pending_tx_stop)
    +    {
    +        nrf_atomic_flag_clear(&m_send_sync_pkt);
    +        nrf_atomic_flag_clear(&m_pending_tx_stop);
    +        m_timeslot_distance = 0;
    +        m_synchronized = false;
    +    }
    +
         if (!m_send_sync_pkt)
         {
             if (m_radio_state    != RADIO_STATE_RX ||
    @@ -517,6 +526,7 @@ void timeslot_begin_handler(void)
     
         p_pkt->timer_val   = m_params.high_freq_timer[0]->CC[1];
         p_pkt->counter_val = m_params.high_freq_timer[1]->CC[1];
    +    p_pkt->counter_val += m_master_counter_diff;
     
     //    p_pkt->rtc_val     = m_params.rtc->COUNTER;
     
    @@ -1217,7 +1227,7 @@ uint32_t ts_tx_start(uint32_t sync_freq_hz)
     
     uint32_t ts_tx_stop()
     {
    -    nrf_atomic_flag_clear(&m_send_sync_pkt);
    +    nrf_atomic_flag_set(&m_pending_tx_stop);
     
         return NRF_SUCCESS;
     }
    

Related