lib/uwb_ccp/src/uwb_ccp.c
/**
 * @fn ccp_send(struct uwb_ccp_instance *ccp, uwb_ccp_modes_t mode)
 * @brief Start clock calibration packets (CCP) blinks with a pulse repetition period of MYNEWT_VAL(UWB_CCP_PERIOD).
 * Precise timing is achieved by adding a fixed period to the transmission time of the previous frame.
 * This removes the need to explicitly read the syst uwb_ccp_stop(ccp); ime register and the assiciated non-deterministic latencies.
 * This function is static function for internl use. It will force a Half Period Delay Warning is called at
 * out of sequence.
 *
 * @param inst   Pointer to struct uwb_ccp_instance *ccp.
 * @param mode   uwb_dev_modes_t for UWB_BLOCKING, UWB_NON_BLOCKING modes.
 *
 * @return struct ccp_status
 */
@fn ccp_send(struct uwb_ccp_instance *ccp, uwb_ccp_modes_t mode)
@brief Start clock calibration packets (CCP) blinks with a pulse repetition period of MYNEWT_VAL(UWB_CCP_PERIOD).
Precise timing is achieved by adding a fixed period to the transmission time of the previous frame.
This removes the need to explicitly read the syst uwb_ccp_stop(ccp); ime register and the assiciated non-deterministic latencies.
This function is static function for internl use. It will force a Half Period Delay Warning is called at
out of sequence.

@param inst   Pointer to struct uwb_ccp_instance *ccp.


@fn ccp_send ( struct uwb_ccp_instance * ccp uwb_ccp_modes_t mode ) @brief Start clock calibration packets ( CCP ) blinks with a pulse repetition period of MYNEWT_VAL ( UWB_CCP_PERIOD ) . Precise timing is achieved by adding a fixed period to the transmission time of the previous frame . This removes the need to explicitly read the syst uwb_ccp_stop ( ccp ) ; ime register and the assiciated non - deterministic latencies . This function is static function for internl use . It will force a Half Period Delay Warning is called at out of sequence . @param inst Pointer to struct uwb_ccp_instance * ccp .
static struct uwb_ccp_status
ccp_send(struct uwb_ccp_instance *ccp, uwb_dev_modes_t mode)
{
    assert(ccp);
    struct uwb_dev * inst = ccp->dev_inst;
    CCP_STATS_INC(send);
    uwb_phy_forcetrxoff(inst);
    dpl_error_t err = dpl_sem_pend(&ccp->sem, DPL_TIMEOUT_NEVER);
    assert(err == DPL_OK);
    uwb_ccp_frame_t * previous_frame = ccp->frames[(uint16_t)(ccp->idx)%ccp->nframes];
    uwb_ccp_frame_t * frame = ccp->frames[(ccp->idx+1)%ccp->nframes];
    frame->rpt_count = 0;
    frame->rpt_max = MYNEWT_VAL(UWB_CCP_MAX_CASCADE_RPTS);
    frame->epoch_to_rm_us = uwb_phy_SHR_duration(inst);
    uint64_t timestamp = previous_frame->transmission_timestamp.timestamp
                        + ((uint64_t)ccp->period << 16);
    timestamp = timestamp & 0xFFFFFFFFFFFFFE00ULL; 
    uwb_set_delay_start(inst, timestamp);
    timestamp += inst->tx_antenna_delay;
    frame->transmission_timestamp.timestamp = timestamp;
    frame->seq_num = ++ccp->seq_num;
    frame->euid = inst->euid;
    frame->short_address = inst->my_short_address;
    frame->transmission_interval = ((uint64_t)ccp->period << 16);
    uwb_write_tx(inst, frame->array, 0, sizeof(uwb_ccp_blink_frame_t));
    uwb_write_tx_fctrl(inst, sizeof(uwb_ccp_blink_frame_t), 0);
    uwb_set_wait4resp(inst, false);
    ccp->status.start_tx_error = uwb_start_tx(inst).start_tx_error;
    if (ccp->status.start_tx_error) {
        uint64_t systime = uwb_read_systime(inst);
        uint64_t late_us = ((systime - timestamp)&UWB_DTU_40BMASK) >> 16;
        CCP_STATS_INC(tx_start_error);
        previous_frame->transmission_timestamp.timestamp = (frame->transmission_timestamp.timestamp
                        + ((uint64_t)ccp->period << 16));
        ccp->idx++;
        ccp->os_epoch += dpl_cputime_usecs_to_ticks(uwb_dwt_usecs_to_usecs(ccp->period - late_us));
        ccp->os_epoch -= dpl_cputime_usecs_to_ticks(MYNEWT_VAL(OS_LATENCY));
        ccp->master_epoch.timestamp += ((uint64_t)ccp->period)<<16;
        ccp->local_epoch += ((uint64_t)ccp->period)<<16;
#if MYNEWT_VAL(UWB_CCP_TOLERATE_MISSED_FRAMES) > 0
        struct uwb_mac_interface * lcbs = NULL;
        if(!(SLIST_EMPTY(&inst->interface_cbs))) {
            SLIST_FOREACH(lcbs, &inst->interface_cbs, next) {
                if (lcbs != NULL && lcbs->superframe_cb) {
                    if(lcbs->superframe_cb((struct uwb_dev*)inst, lcbs)) continue;
                }
            }
        }
#endif
        err = dpl_sem_release(&ccp->sem);
        assert(err == DPL_OK);
    }else if(mode == UWB_BLOCKING){
#if MYNEWT_VAL(UWB_CCP_STATS)
        uint32_t margin = 0xffffffffU&(frame->transmission_timestamp.lo - uwb_read_systime_lo32(inst));
        CCP_STATS_SET(os_lat_margin, uwb_dwt_usecs_to_usecs(margin>>16));
#endif
        err = dpl_sem_pend(&ccp->sem, DPL_TIMEOUT_NEVER); 
        assert(err == DPL_OK);
        err = dpl_sem_release(&ccp->sem);
        assert(err == DPL_OK);
    }
    return ccp->status;
}
static struct uwb_ccp_status ccp_send ( struct uwb_ccp_instance * ccp , uwb_dev_modes_t mode ) { assert ( ccp ) ; struct uwb_dev * inst = ccp -> dev_inst ; CCP_STATS_INC ( send ) ; uwb_phy_forcetrxoff ( inst ) ; dpl_error_t err = dpl_sem_pend ( & ccp -> sem , DPL_TIMEOUT_NEVER ) ; assert ( err == DPL_OK ) ; uwb_ccp_frame_t * previous_frame = ccp -> frames [ ( uint16_t ) ( ccp -> idx ) % ccp -> nframes ] ; uwb_ccp_frame_t * frame = ccp -> frames [ ( ccp -> idx + 1 ) % ccp -> nframes ] ; frame -> rpt_count = 0 ; frame -> rpt_max = MYNEWT_VAL ( UWB_CCP_MAX_CASCADE_RPTS ) ; frame -> epoch_to_rm_us = uwb_phy_SHR_duration ( inst ) ; uint64_t timestamp = previous_frame -> transmission_timestamp . timestamp + ( ( uint64_t ) ccp -> period << 16 ) ; timestamp = timestamp & 0xFFFFFFFFFFFFFE00ULL ; uwb_set_delay_start ( inst , timestamp ) ; timestamp += inst -> tx_antenna_delay ; frame -> transmission_timestamp . timestamp = timestamp ; frame -> seq_num = ++ ccp -> seq_num ; frame -> euid = inst -> euid ; frame -> short_address = inst -> my_short_address ; frame -> transmission_interval = ( ( uint64_t ) ccp -> period << 16 ) ; uwb_write_tx ( inst , frame -> array , 0 , sizeof ( uwb_ccp_blink_frame_t ) ) ; uwb_write_tx_fctrl ( inst , sizeof ( uwb_ccp_blink_frame_t ) , 0 ) ; uwb_set_wait4resp ( inst , false ) ; ccp -> status . start_tx_error = uwb_start_tx ( inst ) . start_tx_error ; if ( ccp -> status . start_tx_error ) { uint64_t systime = uwb_read_systime ( inst ) ; uint64_t late_us = ( ( systime - timestamp ) & UWB_DTU_40BMASK ) >> 16 ; CCP_STATS_INC ( tx_start_error ) ; previous_frame -> transmission_timestamp . timestamp = ( frame -> transmission_timestamp . timestamp + ( ( uint64_t ) ccp -> period << 16 ) ) ; ccp -> idx ++ ; ccp -> os_epoch += dpl_cputime_usecs_to_ticks ( uwb_dwt_usecs_to_usecs ( ccp -> period - late_us ) ) ; ccp -> os_epoch -= dpl_cputime_usecs_to_ticks ( MYNEWT_VAL ( OS_LATENCY ) ) ; ccp -> master_epoch . timestamp += ( ( uint64_t ) ccp -> period ) << 16 ; ccp -> local_epoch += ( ( uint64_t ) ccp -> period ) << 16 ; #if MYNEWT_VAL ( UWB_CCP_TOLERATE_MISSED_FRAMES ) > 0 struct uwb_mac_interface * lcbs = NULL ; if ( ! ( SLIST_EMPTY ( & inst -> interface_cbs ) ) ) { SLIST_FOREACH ( lcbs , & inst -> interface_cbs , next ) { if ( lcbs != NULL && lcbs -> superframe_cb ) { if ( lcbs -> superframe_cb ( ( struct uwb_dev * ) inst , lcbs ) ) continue ; } } } #endif err = dpl_sem_release ( & ccp -> sem ) ; assert ( err == DPL_OK ) ; } else if ( mode == UWB_BLOCKING ) { #if MYNEWT_VAL ( UWB_CCP_STATS ) uint32_t margin = 0xffffffffU & ( frame -> transmission_timestamp . lo - uwb_read_systime_lo32 ( inst ) ) ; CCP_STATS_SET ( os_lat_margin , uwb_dwt_usecs_to_usecs ( margin >> 16 ) ) ; #endif err = dpl_sem_pend ( & ccp -> sem , DPL_TIMEOUT_NEVER ) ; assert ( err == DPL_OK ) ; err = dpl_sem_release ( & ccp -> sem ) ; assert ( err == DPL_OK ) ; } return ccp -> status ; }
@fn ccp_send(struct uwb_ccp_instance *ccp, uwb_ccp_modes_t mode)
 @brief Start clock calibration packets (CCP) blinks with a pulse repetition period of MYNEWT_VAL(UWB_CCP_PERIOD).
@fn ccp_send ( struct uwb_ccp_instance * ccp uwb_ccp_modes_t mode ) @brief Start clock calibration packets ( CCP ) blinks with a pulse repetition period of MYNEWT_VAL ( UWB_CCP_PERIOD ) .
/* Mask off the last 9 bits */ /* Handle missed transmission and update epochs as tx_complete would have done otherwise */ /* Call all available superframe callbacks */ // Wait for completion of transactions