lib/uwb_ccp/src/uwb_ccp.c
/**
 * @fn ccp_slave_timer_ev_cb(struct dpl_event *ev)
 * @brief The OS scheduler is not accurate enough for the timing requirement of an RTLS system.
 * Instead, the OS is used to schedule events in advance of the actual event.
 * The UWB delay start mechanism then takes care of the actual event. This removes the non-deterministic
 * latencies of the OS implementation.
 *
 * @param ev  Pointer to dpl_events.
 * @return void
 */
@fn ccp_slave_timer_ev_cb(struct dpl_event *ev)
@brief The OS scheduler is not accurate enough for the timing requirement of an RTLS system.
Instead, the OS is used to schedule events in advance of the actual event.
The UWB delay start mechanism then takes care of the actual event. This removes the non-deterministic
latencies of the OS implementation.

@param ev  Pointer to dpl_events.
@return void
@fn ccp_slave_timer_ev_cb ( struct dpl_event * ev ) @brief The OS scheduler is not accurate enough for the timing requirement of an RTLS system . Instead the OS is used to schedule events in advance of the actual event . The UWB delay start mechanism then takes care of the actual event . This removes the non - deterministic latencies of the OS implementation . @param ev Pointer to dpl_events . @return void
static void
ccp_slave_timer_ev_cb(struct dpl_event *ev)
{
    int rc;
    uint16_t timeout;
    uint64_t dx_time = 0;
    uint32_t timer_expiry;
    assert(ev != NULL);
    assert(dpl_event_get_arg(ev));
    struct uwb_ccp_instance * ccp = (struct uwb_ccp_instance *) dpl_event_get_arg(ev);
    struct uwb_dev * inst = ccp->dev_inst;
    ccp->blink_frame_duration = uwb_phy_frame_duration(inst, sizeof(uwb_ccp_blink_frame_t));
    if (!ccp->status.enabled) {
        return;
    }
    if (ccp->status.rx_timeout_error) {
        uwb_set_rx_timeout(inst, MYNEWT_VAL(UWB_CCP_LONG_RX_TO));
        ccp_listen(ccp, 0, UWB_BLOCKING);
        goto reset_timer;
    }
    CCP_STATS_INC(slave_cnt);
    dx_time = ccp->local_epoch;
#if MYNEWT_VAL(UWB_WCS_ENABLED)
    if (ccp->wcs) {
        struct uwb_wcs_instance * wcs = ccp->wcs;
        dx_time += DPL_FLOAT64_F64_TO_U64(DPL_FLOAT64_MUL(DPL_FLOAT64_U64_TO_F64((uint64_t)ccp->period << 16),
                                                          wcs->normalized_skew));
    }
#else
    dx_time += ((uint64_t)ccp->period << 16);
#endif
    dx_time -= ((uint64_t)ceilf(uwb_usecs_to_dwt_usecs(uwb_phy_SHR_duration(inst) +
                                                       inst->config.rx.timeToRxStable)) << 16);
    timeout = ccp->blink_frame_duration + MYNEWT_VAL(XTALT_GUARD);
#if MYNEWT_VAL(UWB_CCP_MAX_CASCADE_RPTS) != 0
    timeout += (ccp->config.tx_holdoff_dly + ccp->blink_frame_duration) * MYNEWT_VAL(UWB_CCP_MAX_CASCADE_RPTS);
#endif
    uwb_set_rx_timeout(inst, timeout);
    ccp_listen(ccp, dx_time, UWB_BLOCKING);
    if(ccp->status.start_rx_error){
        uwb_set_rx_timeout(inst, MYNEWT_VAL(UWB_CCP_LONG_RX_TO));
        ccp_listen(ccp, 0, UWB_BLOCKING);
    }
reset_timer:
    if (!ccp->status.enabled) {
        return;
    }
    dpl_cputime_timer_stop(&ccp->timer);
    if (ccp->status.rx_timeout_error &&
        ccp->missed_frames > MYNEWT_VAL(UWB_CCP_TOLERATE_MISSED_FRAMES)) {
        rc = dpl_cputime_timer_relative(&ccp->timer, 0);
    } else {
        ccp->status.rx_timeout_error = 0;
        timer_expiry = ccp->os_epoch + dpl_cputime_usecs_to_ticks(
            - MYNEWT_VAL(OS_LATENCY)
            + (uint32_t)uwb_dwt_usecs_to_usecs(ccp->period)
            - ccp->blink_frame_duration - inst->config.rx.timeToRxStable);
        rc = dpl_cputime_timer_start(&ccp->timer, timer_expiry);
    }
    if (rc == 0) ccp->status.timer_restarted = 1;
}
static void ccp_slave_timer_ev_cb ( struct dpl_event * ev ) { int rc ; uint16_t timeout ; uint64_t dx_time = 0 ; uint32_t timer_expiry ; assert ( ev != NULL ) ; assert ( dpl_event_get_arg ( ev ) ) ; struct uwb_ccp_instance * ccp = ( struct uwb_ccp_instance * ) dpl_event_get_arg ( ev ) ; struct uwb_dev * inst = ccp -> dev_inst ; ccp -> blink_frame_duration = uwb_phy_frame_duration ( inst , sizeof ( uwb_ccp_blink_frame_t ) ) ; if ( ! ccp -> status . enabled ) { return ; } if ( ccp -> status . rx_timeout_error ) { uwb_set_rx_timeout ( inst , MYNEWT_VAL ( UWB_CCP_LONG_RX_TO ) ) ; ccp_listen ( ccp , 0 , UWB_BLOCKING ) ; goto reset_timer ; } CCP_STATS_INC ( slave_cnt ) ; dx_time = ccp -> local_epoch ; #if MYNEWT_VAL ( UWB_WCS_ENABLED ) if ( ccp -> wcs ) { struct uwb_wcs_instance * wcs = ccp -> wcs ; dx_time += DPL_FLOAT64_F64_TO_U64 ( DPL_FLOAT64_MUL ( DPL_FLOAT64_U64_TO_F64 ( ( uint64_t ) ccp -> period << 16 ) , wcs -> normalized_skew ) ) ; } #else dx_time += ( ( uint64_t ) ccp -> period << 16 ) ; #endif dx_time -= ( ( uint64_t ) ceilf ( uwb_usecs_to_dwt_usecs ( uwb_phy_SHR_duration ( inst ) + inst -> config . rx . timeToRxStable ) ) << 16 ) ; timeout = ccp -> blink_frame_duration + MYNEWT_VAL ( XTALT_GUARD ) ; #if MYNEWT_VAL ( UWB_CCP_MAX_CASCADE_RPTS ) != 0 timeout += ( ccp -> config . tx_holdoff_dly + ccp -> blink_frame_duration ) * MYNEWT_VAL ( UWB_CCP_MAX_CASCADE_RPTS ) ; #endif uwb_set_rx_timeout ( inst , timeout ) ; ccp_listen ( ccp , dx_time , UWB_BLOCKING ) ; if ( ccp -> status . start_rx_error ) { uwb_set_rx_timeout ( inst , MYNEWT_VAL ( UWB_CCP_LONG_RX_TO ) ) ; ccp_listen ( ccp , 0 , UWB_BLOCKING ) ; } reset_timer : if ( ! ccp -> status . enabled ) { return ; } dpl_cputime_timer_stop ( & ccp -> timer ) ; if ( ccp -> status . rx_timeout_error && ccp -> missed_frames > MYNEWT_VAL ( UWB_CCP_TOLERATE_MISSED_FRAMES ) ) { rc = dpl_cputime_timer_relative ( & ccp -> timer , 0 ) ; } else { ccp -> status . rx_timeout_error = 0 ; timer_expiry = ccp -> os_epoch + dpl_cputime_usecs_to_ticks ( - MYNEWT_VAL ( OS_LATENCY ) + ( uint32_t ) uwb_dwt_usecs_to_usecs ( ccp -> period ) - ccp -> blink_frame_duration - inst -> config . rx . timeToRxStable ) ; rc = dpl_cputime_timer_start ( & ccp -> timer , timer_expiry ) ; } if ( rc == 0 ) ccp -> status . timer_restarted = 1 ; }
@fn ccp_slave_timer_ev_cb(struct dpl_event *ev)
 @brief The OS scheduler is not accurate enough for the timing requirement of an RTLS system.
@fn ccp_slave_timer_ev_cb ( struct dpl_event * ev ) @brief The OS scheduler is not accurate enough for the timing requirement of an RTLS system .
/* Precalc / update blink frame duration */ /* Sync lost since earlier, just set a long rx timeout and
     * keep listening */ /* Calculate when to expect the ccp packet */ /* Adjust timeout if we're using cascading ccp in anchors */ /* Sync lost, set a long rx timeout */ /* Check if we're still enabled */ /* Ensure timer isn't active */ /* No ccp received, reschedule immediately */ /* ccp received ok, or close enough - reschedule for next ccp event */