/*****************************************************************************/ /** * Description: Time sync implementation file. * * Author: Author's name * Date: 2021-12-04 16:32 * LastEditors: FanHao * LastEditTime: 2022-07-10 20:43 * Revisions: Rev 0.0 * History: * [2022-07-10]: New branch for Dijian. * [2021-12-04]: Initial version. * * Copyright(c) 2021 Beijing Institute of Technology. * Lab of Communication and Networking * ******************************************************************************/ /***************************** Include Files *********************************/ #include #include "time_ctrl.h" #include "../error.h" #include "../common.h" #include "../util/util.h" /************************** Constant Definitions *****************************/ #define VERSION_REG 0x00000004 #define TIME_INT_REG 0x00000008 #define TIME_FRAC_REG 0x0000000C #define TIME_RESET 0x00000010 #define PRESET_HIGH 0x00000014 #define PRESET_LOW 0x00000018 #define TIME_ADJ_INT 0x0000001C #define TIME_ADJ_FRAC 0x00000020 #define TIME_ADJ_TRIG 0x00000024 #define CNTSTEP_OPT 0x00000028 #define TM_RESET_CODE 0x5253542E /***************** Macros (Inline Functions) Definitions *********************/ #define TMC_Read(instPtr, addr) IO_In32(instPtr->config.baseAddr + addr) #define TMC_Write(instPtr, addr, value) IO_Out32(instPtr->config.baseAddr + addr, value) /*****************************************************************************/ /** * @brief Initialize Time-Controller Process * * @param instPtr a second rank pointer to time controller instance * @param config time controller configurations * * @return SUCCESS Initialize successfully. * FAILURE Initialization failed * ******************************************************************************/ int32_t TimeCtrl_Init(TIMECTRL_INST **instPtr, TIMECTRL_CONFIG *config){ ASSERT(config != NULL); ASSERT(instPtr != NULL); (*instPtr) = malloc(sizeof(TIMECTRL_INST)); memcpy(&((*instPtr)->config), config, sizeof(TIMECTRL_CONFIG)); (*instPtr)->modelVer = TMC_Read((*instPtr), VERSION_REG); return SUCCESS; } void TimeCtrl_Destroy(TIMECTRL_INST *instPtr) { free(instPtr); } uint32_t TimeCtrl_GetVersion(TIMECTRL_INST *instPtr){ return TMC_Read(instPtr, VERSION_REG); } /*****************************************************************************/ /** * @brief Apply a reset process to time controller * * @param instPtr a pointer to time controller instance * * @return SUCCESS Initialize successfully. * FAILURE Initialization failed * ******************************************************************************/ void TimeCtrl_Reset(TIMECTRL_INST *instPtr){ ASSERT(instPtr != NULL); TMC_Write(instPtr, CNTSTEP_OPT, TM_RESET_CODE); } /*****************************************************************************/ /** * @brief Assert time controller reset high * * @param instPtr a pointer to time controller instance * * @return NONE * ******************************************************************************/ void TimeCtrl_ResetHigh(TIMECTRL_INST *instPtr){ ASSERT(instPtr != NULL); // TODO: } /*****************************************************************************/ /** * @brief Assert time controller reset low * * @param instPtr a pointer to time controller instance * * @return NONE * ******************************************************************************/ void TimeCtrl_ResetLow(TIMECTRL_INST *instPtr){ ASSERT(instPtr != NULL); // TODO: } /*****************************************************************************/ /** * @brief Get current time integer value. * * @param instPtr a pointer to time controller instance * * @return integer value * ******************************************************************************/ inline TIME_INT TimeCtrl_GetIntCnt(TIMECTRL_INST *instPtr){ ASSERT(instPtr != NULL); return TMC_Read(instPtr, TIME_INT_REG); } /*****************************************************************************/ /** * @brief Get current time fractional value. * * @param instPtr a pointer to time controller instance * * @return fractional value * ******************************************************************************/ inline TIME_FRAC TimeCtrl_GetFracCnt(TIMECTRL_INST *instPtr){ ASSERT(instPtr != NULL); return TMC_Read(instPtr, TIME_FRAC_REG); } /*****************************************************************************/ /** * @brief Get current time value. * * @param instPtr a pointer to time controller instance * @param tmWord a pointer to time data buffer * * @return NONE * ******************************************************************************/ void TimeCtrl_GetCurrentTime(TIMECTRL_INST *instPtr, TIME_WORD* tmWord){ ASSERT(instPtr != NULL); ASSERT(tmWord != NULL); tmWord->frac_part = TMC_Read(instPtr, TIME_FRAC_REG); tmWord->int_part = TMC_Read(instPtr, TIME_INT_REG); } /*****************************************************************************/ /** * @brief Get current optimal counter step adjustment value. * * @param instPtr a pointer to time controller instance * @param config a pointer to time data buffer * * @return NONE. * ******************************************************************************/ void TimeCtrl_GetCurrentStep(TIMECTRL_INST *instPtr, TIME_FRAC* tmFrac) { ASSERT(instPtr != NULL); ASSERT(tmFrac != NULL); *tmFrac = TMC_Read(instPtr, CNTSTEP_OPT); } /*****************************************************************************/ /** * @brief Set a new optimal adjustment value to the counter step. * * @param instPtr a pointer to time controller instance * @param tmWord a pointer to the time data * @param type adjustment type * * @return NONE. * ******************************************************************************/ void TimeCtrl_TimeAdjust(TIMECTRL_INST *instPtr, const TIME_WORD* tmWord, TIMECTRL_ADJ_TYPE type){ ASSERT(instPtr != NULL); ASSERT(tmWord != NULL); if(type < TM_ADJ_ADD || TM_ADJ_ADD > TM_ADJ_SET){ DBG_ERROR("Unsupported adjustment type: %d", type); return; } if(((int32_t)tmWord->frac_part) > COUNTE_FRAC_MAX ) { DBG_ERROR("Invalid fractional value 0x%08X (should <= 0x%08X).\n", tmWord->frac_part, COUNTE_FRAC_MAX); return; } TMC_Write(instPtr, TIME_ADJ_FRAC, tmWord->frac_part); TMC_Write(instPtr, TIME_ADJ_INT, tmWord->int_part); TMC_Write(instPtr, TIME_ADJ_TRIG, type); } /*****************************************************************************/ /** * @brief Set a new optimal adjustment value to the counter step. * * @param instPtr a pointer to time controller instance * @param tmFrac a pointer to the time data * * @return NONE. * ******************************************************************************/ void TimeCtrl_SetOptimizeStep(TIMECTRL_INST* instPtr, TIME_FRAC* tmFrac) { ASSERT(instPtr != NULL); ASSERT(tmFrac != NULL); TMC_Write(instPtr, CNTSTEP_OPT, *tmFrac); } /*****************************************************************************/ /** * @brief Calculate b - a. * * @param a time stamp A * @param b time stamp B * @param gap t round * * @return NONE * ******************************************************************************/ void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap){ ASSERT(a != NULL); ASSERT(b != NULL); ASSERT(gap != NULL); uint64_t timeDiff; timeDiff = (uint64_t) b->frac_part; timeDiff += ((uint64_t)b->int_part) * COUNTE_FRAC_MAX; timeDiff -= ((uint64_t)a->int_part) * COUNTE_FRAC_MAX; timeDiff -= (uint64_t) a->frac_part; gap->frac_part = (TIME_FRAC)(timeDiff % COUNTE_FRAC_MAX); gap->frac_part = (TIME_INT)(timeDiff / COUNTE_FRAC_MAX); }