diff --git a/df_datalink_sp/src/networking/phy_layer/phy_antenna.c b/df_datalink_sp/src/networking/phy_layer/phy_antenna.c index 8a9f3e3..4b8e2ef 100644 --- a/df_datalink_sp/src/networking/phy_layer/phy_antenna.c +++ b/df_datalink_sp/src/networking/phy_layer/phy_antenna.c @@ -43,10 +43,10 @@ #define CTRL_WORD_DEFAULT 0x00 #define ANT_MODE_BEAM_MASK 0xF0 -#define ANT_BEAM_NARROR 0x00 // 8 +#define ANT_BEAM_NARROR 0x00 // 8 #define ANT_BEAM_SUBNARROR_0 0x10 // 25 #define ANT_BEAM_SUBNARROR_1 0x20 // 60 -#define ANT_BEAM_WIDE 0x30 // 120 +#define ANT_BEAM_WIDE 0x30 // 120 #define ANT_MODE_POWER_MASK 0x0F #define ANT_POWER_FULL 0x00 @@ -68,25 +68,20 @@ #define CALIBRMODE_SINGLE_TR_CAL 0x01 #define RF_CTRL_DEFAULT 0x00 -/** @} PhysicalLayer_AntennaConfig_Constants*/ // Pair by regex // Regex: (([0-9]+, ){8}) -uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] = -{ - 0 -}; -uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] = +const uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] = { 1500 }; -uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = +const uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = { - 0, 44, 88, 131, 175, 219, 263, 306, - 350, 394, 438, 481, 525, 569, 613, 656, - 700, 744, 788, 831, 875, 919, 963, 1006, + 0, 44, 88, 131, 175, 219, 263, 306, + 350, 394, 438, 481, 525, 569, 613, 656, + 700, 744, 788, 831, 875, 919, 963, 1006, 1050, 1094, 1138, 1181, 1225, 1269, 1313, 1356, 1400, 1444, 1488, 1531, 1575, 1619, 1663, 1706, 1750, 1794, 1838, 1881, 1925, 1969, 2013, 2056, @@ -97,57 +92,58 @@ uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = 3500 }; -uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = +const uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = { 1500 }; -//uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = +// uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = //{ // 1500, 1600, 1700, 1800, 1900, 1400, 1300, 1200, // 1100, 1000, 900 -//}; +// }; -uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = +const uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = { 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, - 1500, 1500, 1500 + 1500, 1500, 1500 }; -uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] = +const uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] = { 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1550, 1500 }; -//uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = +// uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = //{ // 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1550, // 1500, 1450, 1400, 1350, 1300, 1250, 1200, 1150, // 1100, 1050, 1000 -//}; +// }; -uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = +const uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = { 1700, 1800, 1900, 2000, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700 }; -uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] = +const uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] = { - 500, 1600, 1700, 1800, 1900, 2000, 1500, 1600, + 500, 1600, 1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800, 1900, 2000, 1500, 1500 }; -uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] = +const uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] = { - 500, 600, 700, 800, 900, 1000, 500, 600, - 700, 800, 900, 1000, 500, 600, 700, 800, - 900, 1000, 500, 500 + 500, 600, 700, 800, 900, 1000, 500, 600, + 700, 800, 900, 1000, 500, 600, 700, 800, + 900, 1000, 500, 500 }; +/** @} PhysicalLayer_AntennaConfig_Constants*/ /*****************************************************************************/ /** @@ -261,10 +257,10 @@ void Phy_SetBeamTable(PHY_INST *instPtr, PHY_ANT_ANGLE *table, uint32_t offset) ASSERT(table != NULL); for (int i = 0; i < L1_NUM_ANT_NRRW_PATTERN; i++) { - instPtr->antNrrwPattern[i] = table[(i+offset) % L1_NUM_ANT_NRRW_PATTERN]; + instPtr->antNrrwPattern[i] = table[(i + offset) % L1_NUM_ANT_NRRW_PATTERN]; } - memcpy((uint32_t*)instPtr->antInfoAddr, instPtr->antNrrwPattern, - L1_NUM_ANT_NRRW_PATTERN*sizeof(PHY_ANT_ANGLE)); + memcpy((uint32_t *)instPtr->antInfoAddr, instPtr->antNrrwPattern, + L1_NUM_ANT_NRRW_PATTERN * sizeof(PHY_ANT_ANGLE)); } /*****************************************************************************/ diff --git a/df_datalink_sp/src/networking/phy_layer/phy_layer.c b/df_datalink_sp/src/networking/phy_layer/phy_layer.c index 6543861..cf0ab25 100644 --- a/df_datalink_sp/src/networking/phy_layer/phy_layer.c +++ b/df_datalink_sp/src/networking/phy_layer/phy_layer.c @@ -60,17 +60,27 @@ #define ANT_COINFO_LEN 32 // bytes -#define ATTN_DEFAULT 0 -#define ATTN_2KBPS_100MS ATTN_DEFAULT -#define ATTN_2KBPS_20MS ATTN_DEFAULT -#define ATTN_10KBPS_10MS 31 -#define ATTN_10KBPS_20MS 31 -#define ATTN_40KBPS_10MS 21 -#define ATTN_40KBPS_20MS 21 -#define ATTN_200KBPS_5MS ATTN_DEFAULT -#define ATTN_1M2BPS_5MS ATTN_DEFAULT +#define ATTN_DEFAULT 0 +#define ATTN_2KBPS_100MS ATTN_DEFAULT +#define ATTN_2KBPS_20MS ATTN_DEFAULT +#define ATTN_10KBPS_10MS 31 +#define ATTN_10KBPS_20MS 31 +#define ATTN_40KBPS_10MS 21 +#define ATTN_40KBPS_20MS 21 +#define ATTN_200KBPS_5MS ATTN_DEFAULT +#define ATTN_1M2BPS_5MS ATTN_DEFAULT /** @} PhysicalLayer_Private_Constants*/ +/************************** Variable Definitions *****************************/ +extern const uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS]; +extern const uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS]; +extern const uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS]; +extern const uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS]; +extern const uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS]; +extern const uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS]; +extern const uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS]; +extern const uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS]; + /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ static void Phy_RcdShift(PHY_RCD *rcd, int32_t netxVal); @@ -80,13 +90,30 @@ static int32_t Phy_SetSendData(PHY_INST *instPtr, L1_FRAME_TYPE frameType, uint8 /************************** Variable Definitions *****************************/ +/*****************************************************************************/ +/** + * @brief Shift l1 status record.(newval->next->curr->last) + * + * @param instPtr A pointer to physical layer control instance. + * + * @return NONE. + * + ******************************************************************************/ +static void Phy_RcdShift(PHY_RCD *rcd, int32_t netxVal) +{ + ASSERT(rcd != NULL); + rcd->last = rcd->curr; + rcd->curr = rcd->next; + rcd->next = netxVal; +} + /*****************************************************************************/ /** * @brief Setup data will be sent in next slot. * * @param instPtr A pointer to physical layer control instance. * - * @return FAILURE Error occurred. + * @return FAILURE Error occurred.\n * SUCCESS Setting data successful. * ******************************************************************************/ @@ -114,6 +141,11 @@ static int32_t Phy_SetSendData(PHY_INST *instPtr, L1_FRAME_TYPE frameType, uint8 return SUCCESS; } +/** + * @addtogroup PhysicalLayer_Utility + * @{ + */ + /*****************************************************************************/ /** * @brief Check whether a frame was detected. (Do not check if the frame was @@ -179,6 +211,112 @@ inline bool Phy_IsFrameValid(PHY_INST *instPtr) return instPtr->isValid; } +/*****************************************************************************/ +/** + * @brief Get corresponding frame length in byte of L1 frame. + * + * @param frameType + * + * @return Corresponding frame length + * L1_FRAME_NONE_LEN if the frame type code cannot be recognized. + * + ******************************************************************************/ +uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + return L1_FRAME_2KBPS_20MS_LEN; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_LEN; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_LEN; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_LEN; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_LEN; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_LEN; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_LEN; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_LEN; + default: + return L1_FRAME_NONE_LEN; + } +} + +/*****************************************************************************/ +/** + * @brief Get the corresponding frequency hopping pattern length of a + * specified L1 frame type. + * + * @param frameType a L1 frame type enumeration. + * + * @return SUCCESS + * FAILURE frame type cannot be recognized + * + ******************************************************************************/ +uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + return L1_FRAME_2KBPS_20MS_HOPS; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_HOPS; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_HOPS; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_HOPS; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_HOPS; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_HOPS; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_HOPS; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_HOPS; + default: + return L1_FRAME_NONE_LEN; + } +} + +/*****************************************************************************/ +/** + * @brief Get the corresponding time compensation value (time interval from + * frame start to frame sync) + * + * @param frameType a L1 frame type enumeration. + * + * @return 32bit unsigned integer (10ns) + * + ******************************************************************************/ +uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType) +{ + switch (frameType) + { + case L1_2KBPS_20MS_FRAME: + return L1_FRAME_2KBPS_20MS_COMP; + case L1_2KBPS_100MS_FRAME: + return L1_FRAME_2KBPS_100MS_COMP; + case L1_10KBPS_10MS_FRAME: + return L1_FRAME_10KBPS_10MS_COMP; + case L1_10KBPS_20MS_FRAME: + return L1_FRAME_10KBPS_20MS_COMP; + case L1_40KBPS_20MS_FRAME: + return L1_FRAME_40KBPS_20MS_COMP; + case L1_40KBPS_10MS_FRAME: + return L1_FRAME_40KBPS_10MS_COMP; + case L1_200KBPS_5MS_FRAME: + return L1_FRAME_200KBPS_5MS_COMP; + case L1_1M2BPS_5MS_FRAME: + return L1_FRAME_1M2BPS_5MS_COMP; + default: + return L1_FRAME_NONE_LEN; + } +} + /*****************************************************************************/ /** * @brief Get frame type of the frame in receive data buffer (Base on PL Record). @@ -238,135 +376,12 @@ inline L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST *instPtr) return instPtr->frameType.last; } -/*****************************************************************************/ +/** @} PhysicalLayer_Utility*/ + /** - * @brief Shift l1 status record.(newval->next->curr->last) - * - * @param instPtr A pointer to physical layer control instance. - * - * @return NONE. - * - ******************************************************************************/ -static void Phy_RcdShift(PHY_RCD *rcd, int32_t netxVal) -{ - ASSERT(rcd != NULL); - rcd->last = rcd->curr; - rcd->curr = rcd->next; - rcd->next = netxVal; -} - -/*****************************************************************************/ -/** - * @brief Get corresponding frame length in byte of L1 frame. - * - * @param frameType - * - * @return Corresponding frame length - * L1_FRAME_NONE_LEN if the frame type code cannot be recognized. - * - ******************************************************************************/ -uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType) -{ - switch (frameType) - { - case L1_2KBPS_20MS_FRAME: - return L1_FRAME_2KBPS_20MS_LEN; - case L1_2KBPS_100MS_FRAME: - return L1_FRAME_2KBPS_100MS_LEN; - case L1_10KBPS_10MS_FRAME: - return L1_FRAME_10KBPS_10MS_LEN; - case L1_10KBPS_20MS_FRAME: - return L1_FRAME_10KBPS_20MS_LEN; - case L1_40KBPS_20MS_FRAME: - return L1_FRAME_40KBPS_20MS_LEN; - case L1_40KBPS_10MS_FRAME: - return L1_FRAME_40KBPS_10MS_LEN; - case L1_200KBPS_5MS_FRAME: - return L1_FRAME_200KBPS_5MS_LEN; - case L1_1M2BPS_5MS_FRAME: - return L1_FRAME_1M2BPS_5MS_LEN; - default: - return L1_FRAME_NONE_LEN; - } -} - -/*****************************************************************************/ -/** - * @brief Update physical layer status cache. - * - * @param instPtr A pointer to physical layer control instance. - * - * @return NONE. - * - ******************************************************************************/ -void Phy_UpdateState(PHY_INST *instPtr) -{ - ASSERT(instPtr != NULL); - - /* Update Frame Sate. */ - uint32_t txrxSate = PhyRead(instPtr, TXRX_STATE); - // instPtr->isAcq = ((txrxSate & TXRX_STATE_ACQ_MASK) == TXRX_STATE_ACQ_SUCCESS) ? true : false; - // instPtr->isFrameSync = ((txrxSate & TXRX_STATE_FSYNC_MASK) == TXRX_STATE_FSYNC_SUCCESS) ? true : false; - - // FIXME: using default value, since physical layer may provide unexpected error value. - instPtr->isAcq = true; - instPtr->isFrameSync = true; - instPtr->isDecode = ((txrxSate & TXRX_STATE_DECODE_MASK) == TXRX_STATE_DECODE_SUCCESS) ? true : false; - if (Phy_IsFrameReceived(instPtr)) - { - instPtr->isValid = ((txrxSate & TXRX_STATE_CRC_MASK) == TXRX_STATE_CRC_OK) ? true : false; - } - else - { - instPtr->isValid = false; - } - Phy_UpdateLogging(instPtr); -} - -/*****************************************************************************/ -/** - * @brief Update physical layer logging. - * - * @param instPtr A pointer to physical layer control instance. - * - * @return NONE. - * - ******************************************************************************/ -void Phy_UpdateLogging(PHY_INST *instPtr) -{ - ASSERT(instPtr != NULL); - uint64_t peak, avg; - // Logging - instPtr->recvSlotTime.int_part = PhyRead(instPtr, TM_TARGET_H); - instPtr->recvSlotTime.frac_part = PhyRead(instPtr, TM_TARGET_L); - instPtr->recvFsTime.int_part = PhyRead(instPtr, FSTIME_H); - instPtr->recvFsTime.frac_part = PhyRead(instPtr, FSTIME_L); - instPtr->phyLog.acqCnt = PhyRead(instPtr, PHY_ACQ_CNT); - instPtr->phyLog.fsyncCnt = PhyRead(instPtr, PHY_FRAME_SYNC_CNT); - instPtr->phyLog.decodeCnt = PhyRead(instPtr, PHY_DECODE_CNT); - instPtr->phyLog.crcCnt = PhyRead(instPtr, PHY_CRC_OK_CNT); - instPtr->phyLog.doppler = Phy_GetFreqEst(instPtr); - instPtr->phyLog.recvStamp = (uint64_t)instPtr->recvFsTime.int_part * TIME_FRAC_MAX + instPtr->recvFsTime.frac_part; - peak = PhyRead(instPtr, PHY_ACQ_PEAK_L); - peak |= ((uint64_t)PhyRead(instPtr, PHY_ACQ_PEAK_H)) << 32; - avg = PhyRead(instPtr, PHY_ACQ_MEAN_L); - avg |= ((uint64_t)PhyRead(instPtr, PHY_ACQ_MEAN_H)) << 32; - instPtr->phyLog.acqPAPR = ((double)peak) / ((double)avg); - instPtr->phyLog.acqPhase = (PhyRead(instPtr, PHY_ACQ_FREQEST) & PHY_ACQ_FREQEST_PHASE_MASK) >> PHY_ACQ_FREQEST_PHASE_SHIFT; - instPtr->phyLog.acqFreqCh = (PhyRead(instPtr, PHY_ACQ_FREQEST) & PHY_ACQ_FREQEST_CHANNEL_MASK) >> PHY_ACQ_FREQEST_CHANNEL_SHIFT; - peak = PhyRead(instPtr, PHY_FRAME_SYNC_PEAK_L); - peak |= ((uint64_t)PhyRead(instPtr, PHY_FRAME_SYNC_PEAK_H)) << 32; - avg = PhyRead(instPtr, PHY_FRAME_SYNC_MEAN_L); - avg |= ((uint64_t)PhyRead(instPtr, PHY_FRAME_SYNC_MEAN_H)) << 32; - instPtr->phyLog.fsyncPAPR = ((double)peak) / ((double)avg); - instPtr->phyLog.fsyncFreqCh = (PhyRead(instPtr, PHY_FRAME_SYNC_FREQEST) & PHY_FRAME_SYNC_FREQEST_CHANNEL_MASK) >> PHY_FRAME_SYNC_FREQEST_CHANNEL_SHIFT; - instPtr->phyLog.deintlvAmpEst = PhyRead(instPtr, PHY_DEINTLV_AMPEST) & PHY_DEINTLV_AMPEST_MASK; - memset(instPtr->phyLog.reserve, 0x00, sizeof(instPtr->phyLog.reserve)); - // Sync logs to system monitor - SysMonitor_UpdatePhysicalLayerLog(&(instPtr->phyLog)); - instPtr->lastLogTime = PhyRead(instPtr, TM_TARGET_H); -} - + * @addtogroup PhysicalLayer_Main + * @{ + */ /*****************************************************************************/ /** * @brief Initialize Physical Layer instance, allocate memory for buffers, @@ -516,7 +531,7 @@ int32_t Phy_Init(PHY_INST **instPtr, PHY_CONFIG *phyConfig) uint32_t phyMainCtrl = PhyRead(*instPtr, PHY_MAIN_CTRL); phyMainCtrl &= ~PHY_MAIN_CTRL_NSCAN_MASK; phyMainCtrl |= PHY_MAIN_CTRL_NSCAN_MASK & - (L1_NUM_ANT_NRRW_PATTERN << PHY_MAIN_CTRL_NSCAN_SHIFT); + (L1_NUM_ANT_NRRW_PATTERN << PHY_MAIN_CTRL_NSCAN_SHIFT); PhyWrite(*instPtr, PHY_MAIN_CTRL, phyMainCtrl); } else @@ -675,6 +690,41 @@ int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod) return SUCCESS; } +/*****************************************************************************/ +/** + * @brief Setup a specific timer word register in physical controller. + * + * @param instPtr + * @param tmWord + * @param tmType + * + * @return SUCCESS + * FAILURE pattern length exceeds maximum length. + * + ******************************************************************************/ +int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType) +{ + ASSERT(instPtr != NULL); + if (tmWord->frac_part >= PHY_TIME_WORD_L_MAX) + { + return EPARAM; + } + switch (tmType) + { + case PHY_TIME_WORD_POLL: + PhyWrite(instPtr, POLLTIME_L, tmWord->frac_part); + PhyWrite(instPtr, POLLTIME_H, tmWord->int_part); + break; + case PHY_TIME_WORD_LISTEN_TIMEOUT: + PhyWrite(instPtr, LISTENTIMEOUT_L, tmWord->frac_part); + PhyWrite(instPtr, LISTENTIMEOUT_H, tmWord->int_part); + break; + default: + return EPARAM; + } + return SUCCESS; +} + /*****************************************************************************/ /** * @brief Setup next slot operation. @@ -712,66 +762,59 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, default: return EPARAM; } - if (instPtr->isPresetHop == false) + switch (frameType) { - hopPattern = hopPattern_Config; - } - else - { - switch (frameType) - { - case L1_2KBPS_20MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_20MS; - hopNum = L1_FRAME_2KBPS_20MS_HOPS; - hopPattern = hopPattern_2KBPS_20MS; - instPtr->antConfig.rfTxMgc = ATTN_2KBPS_20MS; - break; - case L1_2KBPS_100MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_100MS; - hopNum = L1_FRAME_2KBPS_100MS_HOPS; - hopPattern = hopPattern_2KBPS_100MS; - instPtr->antConfig.rfTxMgc = ATTN_2KBPS_100MS; - break; - case L1_10KBPS_10MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_10MS; - hopNum = L1_FRAME_10KBPS_20MS_HOPS; - hopPattern = hopPattern_10KBPS_20MS; - instPtr->antConfig.rfTxMgc = ATTN_10KBPS_10MS; - break; - case L1_10KBPS_20MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_20MS; - hopNum = L1_FRAME_10KBPS_20MS_HOPS; - hopPattern = hopPattern_10KBPS_20MS; - instPtr->antConfig.rfTxMgc = ATTN_10KBPS_20MS; - break; - case L1_40KBPS_20MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_20MS; - hopNum = L1_FRAME_40KBPS_20MS_HOPS; - hopPattern = hopPattern_40KBPS_20MS; - instPtr->antConfig.rfTxMgc = ATTN_40KBPS_20MS; - break; - case L1_40KBPS_10MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_10MS; - hopNum = L1_FRAME_40KBPS_10MS_HOPS; - hopPattern = hopPattern_40KBPS_10MS; - instPtr->antConfig.rfTxMgc = ATTN_40KBPS_10MS; - break; - case L1_200KBPS_5MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS; - hopNum = L1_FRAME_200KBPS_5MS_HOPS; - hopPattern = hopPattern_200KBPS_5MS; - instPtr->antConfig.rfTxMgc = ATTN_200KBPS_5MS; - break; - case L1_1M2BPS_5MS_FRAME: - phyModeCtrl |= PHY_MODE_CTRL_FRAME_1M2BPS_5MS; - hopNum = L1_FRAME_1M2BPS_5MS_HOPS; - hopPattern = hopPattern_1M2BPS_5MS; - instPtr->antConfig.rfTxMgc = ATTN_1M2BPS_5MS; - break; - default: - return EPARAM; - break; - } + case L1_2KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_20MS; + hopNum = L1_FRAME_2KBPS_20MS_HOPS; + hopPattern = hopPattern_2KBPS_20MS; + instPtr->antConfig.rfTxMgc = ATTN_2KBPS_20MS; + break; + case L1_2KBPS_100MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_100MS; + hopNum = L1_FRAME_2KBPS_100MS_HOPS; + hopPattern = hopPattern_2KBPS_100MS; + instPtr->antConfig.rfTxMgc = ATTN_2KBPS_100MS; + break; + case L1_10KBPS_10MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_10MS; + hopNum = L1_FRAME_10KBPS_20MS_HOPS; + hopPattern = hopPattern_10KBPS_20MS; + instPtr->antConfig.rfTxMgc = ATTN_10KBPS_10MS; + break; + case L1_10KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_20MS; + hopNum = L1_FRAME_10KBPS_20MS_HOPS; + hopPattern = hopPattern_10KBPS_20MS; + instPtr->antConfig.rfTxMgc = ATTN_10KBPS_20MS; + break; + case L1_40KBPS_20MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_20MS; + hopNum = L1_FRAME_40KBPS_20MS_HOPS; + hopPattern = hopPattern_40KBPS_20MS; + instPtr->antConfig.rfTxMgc = ATTN_40KBPS_20MS; + break; + case L1_40KBPS_10MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_10MS; + hopNum = L1_FRAME_40KBPS_10MS_HOPS; + hopPattern = hopPattern_40KBPS_10MS; + instPtr->antConfig.rfTxMgc = ATTN_40KBPS_10MS; + break; + case L1_200KBPS_5MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS; + hopNum = L1_FRAME_200KBPS_5MS_HOPS; + hopPattern = hopPattern_200KBPS_5MS; + instPtr->antConfig.rfTxMgc = ATTN_200KBPS_5MS; + break; + case L1_1M2BPS_5MS_FRAME: + phyModeCtrl |= PHY_MODE_CTRL_FRAME_1M2BPS_5MS; + hopNum = L1_FRAME_1M2BPS_5MS_HOPS; + hopPattern = hopPattern_1M2BPS_5MS; + instPtr->antConfig.rfTxMgc = ATTN_1M2BPS_5MS; + break; + default: + return EPARAM; + break; } // Set frame configs @@ -788,7 +831,9 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, memcpy((uint8_t *)(antConfigAddr + i * ANT_COINFO_LEN), dataSrcPtr, sizeof(PHY_ANT_CONFIG)); } - uint32_t antCtrl = (instPtr->antConfigOffset & ANT_CONFIG_OFFSET_MASK) | ((hopNum << ANT_CONFIG_NUM_SHIFT) & ANT_CONFIG_NUM_MASK) | ((ANT_COINFO_LEN << ANT_CONFIG_LEN_SHIFT) & ANT_CONFIG_LEN_MASK); + uint32_t antCtrl = (instPtr->antConfigOffset & ANT_CONFIG_OFFSET_MASK) + | ((hopNum << ANT_CONFIG_NUM_SHIFT) & ANT_CONFIG_NUM_MASK) + | ((ANT_COINFO_LEN << ANT_CONFIG_LEN_SHIFT) & ANT_CONFIG_LEN_MASK); /* memcpy((uint8_t*)antConfigDataAddr, hopPattern, hopNum*sizeof(uint16_t)); @@ -826,75 +871,280 @@ int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, /*****************************************************************************/ /** - * @brief Get the corresponding frequency hopping pattern length of a - * specified L1 frame type. + * @brief Update physical layer status cache. * - * @param frameType a L1 frame type enumeration. + * @param instPtr A pointer to physical layer control instance. * - * @return SUCCESS - * FAILURE frame type cannot be recognized + * @return NONE. * ******************************************************************************/ -uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType) +void Phy_UpdateState(PHY_INST *instPtr) { - switch (frameType) + ASSERT(instPtr != NULL); + + /* Update Frame Sate. */ + uint32_t txrxSate = PhyRead(instPtr, TXRX_STATE); + // instPtr->isAcq = ((txrxSate & TXRX_STATE_ACQ_MASK) == TXRX_STATE_ACQ_SUCCESS) ? true : false; + // instPtr->isFrameSync = ((txrxSate & TXRX_STATE_FSYNC_MASK) == TXRX_STATE_FSYNC_SUCCESS) ? true : false; + + // FIXME: using default value, since physical layer may provide unexpected error value. + instPtr->isAcq = true; + instPtr->isFrameSync = true; + instPtr->isDecode = ((txrxSate & TXRX_STATE_DECODE_MASK) == TXRX_STATE_DECODE_SUCCESS) ? true : false; + if (Phy_IsFrameReceived(instPtr)) { - case L1_2KBPS_20MS_FRAME: - return L1_FRAME_2KBPS_20MS_HOPS; - case L1_2KBPS_100MS_FRAME: - return L1_FRAME_2KBPS_100MS_HOPS; - case L1_10KBPS_10MS_FRAME: - return L1_FRAME_10KBPS_10MS_HOPS; - case L1_10KBPS_20MS_FRAME: - return L1_FRAME_10KBPS_20MS_HOPS; - case L1_40KBPS_20MS_FRAME: - return L1_FRAME_40KBPS_20MS_HOPS; - case L1_40KBPS_10MS_FRAME: - return L1_FRAME_40KBPS_10MS_HOPS; - case L1_200KBPS_5MS_FRAME: - return L1_FRAME_200KBPS_5MS_HOPS; - case L1_1M2BPS_5MS_FRAME: - return L1_FRAME_1M2BPS_5MS_HOPS; - default: - return L1_FRAME_NONE_LEN; + instPtr->isValid = ((txrxSate & TXRX_STATE_CRC_MASK) == TXRX_STATE_CRC_OK) ? true : false; } + else + { + instPtr->isValid = false; + } + Phy_UpdateLogging(instPtr); } /*****************************************************************************/ /** - * @brief Get the corresponding time compensation value (time interval from - * frame start to frame sync) + * @brief Copy ans store the received data, if received data valid. * - * @param frameType a L1 frame type enumeration. + * @param instPtr a pointer to physical layer control instance. * - * @return 32bit unsigned integer (10ns) + * @return NONE * ******************************************************************************/ -uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType) +void Phy_PeekRecvData(PHY_INST *instPtr, uint8_t *dataBuff) { - switch (frameType) + ASSERT(instPtr != NULL); + ASSERT(dataBuff != NULL); + if (instPtr->isValid == false) { - case L1_2KBPS_20MS_FRAME: - return L1_FRAME_2KBPS_20MS_COMP; - case L1_2KBPS_100MS_FRAME: - return L1_FRAME_2KBPS_100MS_COMP; - case L1_10KBPS_10MS_FRAME: - return L1_FRAME_10KBPS_10MS_COMP; - case L1_10KBPS_20MS_FRAME: - return L1_FRAME_10KBPS_20MS_COMP; - case L1_40KBPS_20MS_FRAME: - return L1_FRAME_40KBPS_20MS_COMP; - case L1_40KBPS_10MS_FRAME: - return L1_FRAME_40KBPS_10MS_COMP; - case L1_200KBPS_5MS_FRAME: - return L1_FRAME_200KBPS_5MS_COMP; - case L1_1M2BPS_5MS_FRAME: - return L1_FRAME_1M2BPS_5MS_COMP; - default: - return L1_FRAME_NONE_LEN; + return; } + uint32_t frameLen, offset; + + frameLen = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_LEN_MASK) >> RECVDATA_STATE_LEN_SHIFT; + offset = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_OFFSET_MASK) >> RECVDATA_STATE_OFFSET_SHIFT; + + memcpy(dataBuff, (uint8_t *)(instPtr->recvDataAddr + offset), frameLen); } +/*****************************************************************************/ +/** + * @brief Get the received data (if valid), store it to data buffer. + * and clear data valid flag. + * + * @param instPtr a pointer to physical layer control instance. + * + * @return NONE + * + ******************************************************************************/ +void Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *dataBuff) +{ + ASSERT(instPtr != NULL); + ASSERT(dataBuff != NULL); + if (instPtr->isValid == false) + { + return; + } + Phy_PeekRecvData(instPtr, dataBuff); + instPtr->isValid = false; +} + +/*****************************************************************************/ +/** + * @brief Update physical layer logging. + * + * @param instPtr A pointer to physical layer control instance. + * + * @return NONE. + * + ******************************************************************************/ +void Phy_UpdateLogging(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint64_t peak, avg; + // Logging + instPtr->recvSlotTime.int_part = PhyRead(instPtr, TM_TARGET_H); + instPtr->recvSlotTime.frac_part = PhyRead(instPtr, TM_TARGET_L); + instPtr->recvFsTime.int_part = PhyRead(instPtr, FSTIME_H); + instPtr->recvFsTime.frac_part = PhyRead(instPtr, FSTIME_L); + instPtr->phyLog.acqCnt = PhyRead(instPtr, PHY_ACQ_CNT); + instPtr->phyLog.fsyncCnt = PhyRead(instPtr, PHY_FRAME_SYNC_CNT); + instPtr->phyLog.decodeCnt = PhyRead(instPtr, PHY_DECODE_CNT); + instPtr->phyLog.crcCnt = PhyRead(instPtr, PHY_CRC_OK_CNT); + instPtr->phyLog.doppler = Phy_GetFreqEst(instPtr); + instPtr->phyLog.recvStamp = (uint64_t)instPtr->recvFsTime.int_part * TIME_FRAC_MAX + instPtr->recvFsTime.frac_part; + peak = PhyRead(instPtr, PHY_ACQ_PEAK_L); + peak |= ((uint64_t)PhyRead(instPtr, PHY_ACQ_PEAK_H)) << 32; + avg = PhyRead(instPtr, PHY_ACQ_MEAN_L); + avg |= ((uint64_t)PhyRead(instPtr, PHY_ACQ_MEAN_H)) << 32; + instPtr->phyLog.acqPAPR = ((double)peak) / ((double)avg); + instPtr->phyLog.acqPhase = (PhyRead(instPtr, PHY_ACQ_FREQEST) & PHY_ACQ_FREQEST_PHASE_MASK) >> PHY_ACQ_FREQEST_PHASE_SHIFT; + instPtr->phyLog.acqFreqCh = (PhyRead(instPtr, PHY_ACQ_FREQEST) & PHY_ACQ_FREQEST_CHANNEL_MASK) >> PHY_ACQ_FREQEST_CHANNEL_SHIFT; + peak = PhyRead(instPtr, PHY_FRAME_SYNC_PEAK_L); + peak |= ((uint64_t)PhyRead(instPtr, PHY_FRAME_SYNC_PEAK_H)) << 32; + avg = PhyRead(instPtr, PHY_FRAME_SYNC_MEAN_L); + avg |= ((uint64_t)PhyRead(instPtr, PHY_FRAME_SYNC_MEAN_H)) << 32; + instPtr->phyLog.fsyncPAPR = ((double)peak) / ((double)avg); + instPtr->phyLog.fsyncFreqCh = (PhyRead(instPtr, PHY_FRAME_SYNC_FREQEST) + & PHY_FRAME_SYNC_FREQEST_CHANNEL_MASK) >> PHY_FRAME_SYNC_FREQEST_CHANNEL_SHIFT; + instPtr->phyLog.deintlvAmpEst = PhyRead(instPtr, PHY_DEINTLV_AMPEST) & PHY_DEINTLV_AMPEST_MASK; + memset(instPtr->phyLog.reserve, 0x00, sizeof(instPtr->phyLog.reserve)); + // Sync logs to system monitor + SysMonitor_UpdatePhysicalLayerLog(&(instPtr->phyLog)); + instPtr->lastLogTime = PhyRead(instPtr, TM_TARGET_H); +} + +/*****************************************************************************/ +/** + * @brief Setup a specific timer word register in physical controller. + * + * @param instPtr a pointer to hopping pattern buffer + * @param patternLen a integer indicate the length of hopping pattern. + * + * @return NONE + * + ******************************************************************************/ +void Phy_RefreshHwSate(PHY_INST *instPtr) +{ + ASSERT(instPtr != NULL); + uint32_t rawData; +#ifndef EMULATION + float evalData; + instPtr->hwSate.isSpOk = true; + // -- Update FPGA voltage status; + instPtr->hwSate.spFpgaVolt = 0; + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPINT); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_PS_VALID(evalData)) ? VOLT_PS_OK : 0; + + // -- -- Update Ps aux voltage + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPAUX); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_PSAUX_VALID(evalData)) ? VOLT_PSAUX_OK : 0; + + // -- -- Update DDR voltage + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPDRO); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_DDR_VALID(evalData)) ? VOLT_DDR_OK : 0; + + // -- -- Update PL voltage + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCINT); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_PL_VALID(evalData)) ? VOLT_PL_OK : 0; + + // -- -- Update PL aux voltage + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCAUX); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_PLAUX_VALID(evalData)) ? VOLT_PLAUX_OK : 0; + + // -- -- Update Bram voltage + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VBRAM); + evalData = XAdcPs_RawToVoltage(rawData); + instPtr->hwSate.spFpgaVolt |= (IS_BRAM_VALID(evalData)) ? VOLT_BRAM_OK : 0; + + // -- Update clock lock state + if (instPtr->phyCofig.get_clk_state != NULL) + { + instPtr->hwSate.spClkState = instPtr->phyCofig.get_clk_state(); + } + else + { + instPtr->hwSate.spClkState = 0; + } + + // -- Update AD9361 pll lock state + if (instPtr->phyCofig.get_ad_lock_state != NULL) + { + instPtr->hwSate.spAdLockState = instPtr->phyCofig.get_ad_lock_state(); + } + else + { + instPtr->hwSate.spAdLockState = 0; + } + + // -- Update AD9361-0 temperature, unit 1 Celcius degree + if (instPtr->phyCofig.get_ad0_temp != NULL) + { + instPtr->hwSate.spAdTemp_0 = instPtr->phyCofig.get_ad0_temp(); + } + else + { + instPtr->hwSate.spAdTemp_0 = 0; + } + + // -- Update AD9361-1 temperature, unit 1 Celcius degree + if (instPtr->phyCofig.get_ad1_temp != NULL) + { + instPtr->hwSate.spAdTemp_1 = instPtr->phyCofig.get_ad1_temp(); + } + else + { + instPtr->hwSate.spAdTemp_1 = 0; + } + + // -- Update FPGA Chip temperature, unit 1 deg + rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP); + evalData = XAdcPs_RawToTemperature(rawData); + instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX) + ? INT8_MAX + : ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB)); + instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK)) + && (instPtr->hwSate.spClkState == (CLK_SP_PLL0_LOCK | CLK_SP_PLL1_LOCK)) + && (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK)); +#else + instPtr->hwSate.isSpOk = true; +#endif + /*** Voltage and Status ***/ + rawData = PhyRead(instPtr, ANT_STATUS); + // -- Update Antenna Voltage Status: 1 - normal, 0 - error + // [0] - ANT voltage status + // [2] - RF voltage status + // [4] - NIL voltage status + // [6] - Antenna status + instPtr->hwSate.antVolt = ((rawData & ANT_STATUS_ANT_VOLT_MASK) == ANT_STATUS_ANT_VOLT_OK) ? VOLT_ANT_PROC_OK : 0x00; + instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_RF_VOLT_MASK) == ANT_STATUS_RF_VOLT_OK) ? VOLT_ANT_RF_OK : 0x00; + instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_NIL_VOLT_MASK) == ANT_STATUS_NIL_VOLT_OK) ? VOLT_ANT_NIL_OK : 0x00; + instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_CODE_MASK) == ANT_STATUS_CODE_OK) ? ANT_STATE_OK : 0x00; + + /*** Temperature and Lock Status ***/ + rawData = PhyRead(instPtr, ANT_RF_STATUS); + //-- Update Antenna Temperature (signed 8bit integer, 1 centigrade per LSB) + instPtr->hwSate.antTemp = (uint8_t)(rawData & ANT_RF_STATUS_TEMP_MASK); + // -- Update Antenna PLL Lock Status: 1 - normal, 0 - error + // [0] - BASEBAND lock status + // [2] - PLLA lock status + // [4] - PLLB lock status + instPtr->hwSate.antPll = ((rawData & ANT_RF_STATUS_BBLOCK_MASK) == ANT_RF_STATUS_BBLOCK_OK) ? CLK_ANT_BBPLL_LOCK : 0x00; + instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLA_MASK) == ANT_RF_STATUS_PLLA_OK) ? CLK_ANT_RFPLL0_LOCK : 0x00; + instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLB_MASK) == ANT_RF_STATUS_PLLB_OK) ? CLK_ANT_RFPLL1_LOCK : 0x00; + + /*** MGCs ***/ + rawData = PhyRead(instPtr, ANT_RF_MGC); + // -- Update Antenna MGC (0~15 dB) + // [3:0] - Channel 1 MGC + // [7:4] - Channel 2 MGC + // [11:8] - Channel 3 MGC + // [15:12] - Channel 4 MGC + instPtr->hwSate.antMgc0 = (rawData & ANT_RF_MGC_CH1_MASK); + instPtr->hwSate.antMgc0 |= (rawData & ANT_RF_MGC_CH2_MASK) >> 4; + instPtr->hwSate.antMgc1 = (rawData & ANT_RF_MGC_CH3_MASK) >> 16; + instPtr->hwSate.antMgc1 |= (rawData & ANT_RF_MGC_CH4_MASK) >> 24; + + // Determin if antenna is ok. + instPtr->hwSate.isAntOk = (instPtr->hwSate.antVolt == (VOLT_ANT_PROC_OK | VOLT_ANT_RF_OK | VOLT_ANT_NIL_OK | ANT_STATE_OK)) + && (instPtr->hwSate.antPll == (CLK_ANT_BBPLL_LOCK | CLK_ANT_RFPLL0_LOCK | CLK_ANT_RFPLL1_LOCK)); + + memset(instPtr->hwSate.reserve, 0x00, sizeof(instPtr->hwSate.reserve)); + + SysMonitor_UpdateHardwareStatus(&(instPtr->hwSate)); +} + +/** @} PhysicalLayer_Main*/ + +/** + * @addtogroup PhysicalLayer_Receive_Estimations + * @{ + */ /*****************************************************************************/ /** * @brief Get the last scan beam number after autoscan. @@ -1039,63 +1289,6 @@ double Phy_GetFineFreqEst(PHY_INST *instPtr) return freqEst; } -/*****************************************************************************/ -/** - * @brief Setup a frequency hopping pattern. - * - * @param patternBuff a pointer to hopping pattern buffer - * @param patternLen a integer indicate the length of hopping pattern. - * - * @return SUCCESS - * FAILURE pattern length exceeds maximum length. - * - ******************************************************************************/ -int32_t Phy_SetHopPattern(void *patternBuff, uint32_t patternLen) -{ - ASSERT(patternBuff != NULL); - if (patternLen > L1_FRAME_MAX_HOPS) - { - return FAILURE; - } - memcpy(hopPattern_Config, patternBuff, patternLen * sizeof(uint16_t)); - return SUCCESS; -} - -/*****************************************************************************/ -/** - * @brief Setup a specific timer word register in physical controller. - * - * @param instPtr - * @param tmWord - * @param tmType - * - * @return SUCCESS - * FAILURE pattern length exceeds maximum length. - * - ******************************************************************************/ -int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType) -{ - ASSERT(instPtr != NULL); - if (tmWord->frac_part >= PHY_TIME_WORD_L_MAX) - { - return EPARAM; - } - switch (tmType) - { - case PHY_TIME_WORD_POLL: - PhyWrite(instPtr, POLLTIME_L, tmWord->frac_part); - PhyWrite(instPtr, POLLTIME_H, tmWord->int_part); - break; - case PHY_TIME_WORD_LISTEN_TIMEOUT: - PhyWrite(instPtr, LISTENTIMEOUT_L, tmWord->frac_part); - PhyWrite(instPtr, LISTENTIMEOUT_H, tmWord->int_part); - break; - default: - return EPARAM; - } - return SUCCESS; -} - /*****************************************************************************/ /** * @brief Get the frame sync time of last frame. @@ -1166,196 +1359,6 @@ void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotSta memcpy(slotStart, &(instPtr->recvSlotTime), sizeof(TIME_WORD)); } -/*****************************************************************************/ -/** - * @brief Copy ans store the received data, if received data valid. - * - * @param instPtr a pointer to physical layer control instance. - * - * @return NONE - * - ******************************************************************************/ -void Phy_PeekRecvData(PHY_INST *instPtr, uint8_t *dataBuff) -{ - ASSERT(instPtr != NULL); - ASSERT(dataBuff != NULL); - if (instPtr->isValid == false) - { - return; - } - uint32_t frameLen, offset; - - frameLen = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_LEN_MASK) >> RECVDATA_STATE_LEN_SHIFT; - offset = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_OFFSET_MASK) >> RECVDATA_STATE_OFFSET_SHIFT; - - memcpy(dataBuff, (uint8_t *)(instPtr->recvDataAddr + offset), frameLen); -} - -/*****************************************************************************/ -/** - * @brief Get the received data (if valid), store it to data buffer. - * and clear data valid flag. - * - * @param instPtr a pointer to physical layer control instance. - * - * @return NONE - * - ******************************************************************************/ -void Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *dataBuff) -{ - ASSERT(instPtr != NULL); - ASSERT(dataBuff != NULL); - if (instPtr->isValid == false) - { - return; - } - Phy_PeekRecvData(instPtr, dataBuff); - instPtr->isValid = false; -} - -/*****************************************************************************/ -/** - * @brief Setup a specific timer word register in physical controller. - * - * @param instPtr a pointer to hopping pattern buffer - * @param patternLen a integer indicate the length of hopping pattern. - * - * @return NONE - * - ******************************************************************************/ -void Phy_RefreshHwSate(PHY_INST *instPtr) -{ - ASSERT(instPtr != NULL); - uint32_t rawData; -#ifndef EMULATION - float evalData; - instPtr->hwSate.isSpOk = true; - // -- Update FPGA voltage status; - instPtr->hwSate.spFpgaVolt = 0; - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPINT); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_PS_VALID(evalData)) ? VOLT_PS_OK : 0; - - // -- -- Update Ps aux voltage - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPAUX); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_PSAUX_VALID(evalData)) ? VOLT_PSAUX_OK : 0; - - // -- -- Update DDR voltage - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCPDRO); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_DDR_VALID(evalData)) ? VOLT_DDR_OK : 0; - - // -- -- Update PL voltage - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCINT); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_PL_VALID(evalData)) ? VOLT_PL_OK : 0; - - // -- -- Update PL aux voltage - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VCCAUX); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_PLAUX_VALID(evalData)) ? VOLT_PLAUX_OK : 0; - - // -- -- Update Bram voltage - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_VBRAM); - evalData = XAdcPs_RawToVoltage(rawData); - instPtr->hwSate.spFpgaVolt |= (IS_BRAM_VALID(evalData)) ? VOLT_BRAM_OK : 0; - - // -- Update clock lock state - if (instPtr->phyCofig.get_clk_state != NULL) - { - instPtr->hwSate.spClkState = instPtr->phyCofig.get_clk_state(); - } - else - { - instPtr->hwSate.spClkState = 0; - } - - // -- Update AD9361 pll lock state - if (instPtr->phyCofig.get_ad_lock_state != NULL) - { - instPtr->hwSate.spAdLockState = instPtr->phyCofig.get_ad_lock_state(); - } - else - { - instPtr->hwSate.spAdLockState = 0; - } - - // -- Update AD9361-0 temperature, unit 1 Celcius degree - if (instPtr->phyCofig.get_ad0_temp != NULL) - { - instPtr->hwSate.spAdTemp_0 = instPtr->phyCofig.get_ad0_temp(); - } - else - { - instPtr->hwSate.spAdTemp_0 = 0; - } - - // -- Update AD9361-1 temperature, unit 1 Celcius degree - if (instPtr->phyCofig.get_ad1_temp != NULL) - { - instPtr->hwSate.spAdTemp_1 = instPtr->phyCofig.get_ad1_temp(); - } - else - { - instPtr->hwSate.spAdTemp_1 = 0; - } - - // -- Update FPGA Chip temperature, unit 1 deg - rawData = XAdcPs_GetAdcData(&(instPtr->hwXadc), XADCPS_CH_TEMP); - evalData = XAdcPs_RawToTemperature(rawData); - instPtr->hwSate.spFpgaTemp = (evalData > TEMPERATURE_MAX) - ? INT8_MAX - : ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB)); - instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK)) - && (instPtr->hwSate.spClkState == (CLK_SP_PLL0_LOCK | CLK_SP_PLL1_LOCK)) - && (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK)); -#else - instPtr->hwSate.isSpOk = true; -#endif - /*** Voltage and Status ***/ - rawData = PhyRead(instPtr, ANT_STATUS); - // -- Update Antenna Voltage Status: 1 - normal, 0 - error - // [0] - ANT voltage status - // [2] - RF voltage status - // [4] - NIL voltage status - // [6] - Antenna status - instPtr->hwSate.antVolt = ((rawData & ANT_STATUS_ANT_VOLT_MASK) == ANT_STATUS_ANT_VOLT_OK) ? VOLT_ANT_PROC_OK : 0x00; - instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_RF_VOLT_MASK) == ANT_STATUS_RF_VOLT_OK) ? VOLT_ANT_RF_OK : 0x00; - instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_NIL_VOLT_MASK) == ANT_STATUS_NIL_VOLT_OK) ? VOLT_ANT_NIL_OK : 0x00; - instPtr->hwSate.antVolt |= ((rawData & ANT_STATUS_CODE_MASK) == ANT_STATUS_CODE_OK) ? ANT_STATE_OK : 0x00; - - /*** Temperature and Lock Status ***/ - rawData = PhyRead(instPtr, ANT_RF_STATUS); - //-- Update Antenna Temperature (signed 8bit integer, 1 centigrade per LSB) - instPtr->hwSate.antTemp = (uint8_t)(rawData & ANT_RF_STATUS_TEMP_MASK); - // -- Update Antenna PLL Lock Status: 1 - normal, 0 - error - // [0] - BASEBAND lock status - // [2] - PLLA lock status - // [4] - PLLB lock status - instPtr->hwSate.antPll = ((rawData & ANT_RF_STATUS_BBLOCK_MASK) == ANT_RF_STATUS_BBLOCK_OK) ? CLK_ANT_BBPLL_LOCK : 0x00; - instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLA_MASK) == ANT_RF_STATUS_PLLA_OK) ? CLK_ANT_RFPLL0_LOCK : 0x00; - instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLB_MASK) == ANT_RF_STATUS_PLLB_OK) ? CLK_ANT_RFPLL1_LOCK : 0x00; - - /*** MGCs ***/ - rawData = PhyRead(instPtr, ANT_RF_MGC); - // -- Update Antenna MGC (0~15 dB) - // [3:0] - Channel 1 MGC - // [7:4] - Channel 2 MGC - // [11:8] - Channel 3 MGC - // [15:12] - Channel 4 MGC - instPtr->hwSate.antMgc0 = (rawData & ANT_RF_MGC_CH1_MASK); - instPtr->hwSate.antMgc0 |= (rawData & ANT_RF_MGC_CH2_MASK) >> 4; - instPtr->hwSate.antMgc1 = (rawData & ANT_RF_MGC_CH3_MASK) >> 16; - instPtr->hwSate.antMgc1 |= (rawData & ANT_RF_MGC_CH4_MASK) >> 24; - - // Determin if antenna is ok. - instPtr->hwSate.isAntOk = (instPtr->hwSate.antVolt == (VOLT_ANT_PROC_OK | VOLT_ANT_RF_OK | VOLT_ANT_NIL_OK | ANT_STATE_OK)) - && (instPtr->hwSate.antPll == (CLK_ANT_BBPLL_LOCK | CLK_ANT_RFPLL0_LOCK | CLK_ANT_RFPLL1_LOCK)); - - memset(instPtr->hwSate.reserve, 0x00, sizeof(instPtr->hwSate.reserve)); - - SysMonitor_UpdateHardwareStatus(&(instPtr->hwSate)); -} +/** @} PhysicalLayer_Receive_Estimations*/ /** @} PhysicalLayer*/ \ No newline at end of file diff --git a/df_datalink_sp/src/networking/phy_layer/phy_layer.h b/df_datalink_sp/src/networking/phy_layer/phy_layer.h index 8e271c8..a6e5e79 100644 --- a/df_datalink_sp/src/networking/phy_layer/phy_layer.h +++ b/df_datalink_sp/src/networking/phy_layer/phy_layer.h @@ -224,7 +224,6 @@ typedef struct bool isFrameSync; ///< indicates if last reception frame sync success bool isDecode; ///< indicates if last reception decode success bool isValid; ///< indicates if last reception frame data valid (crc check pass) - bool isPresetHop; ///< indicates if using preset frequency hop TIME_WORD recvSlotTime; ///< last slot start time stamp TIME_WORD recvFsTime; ///< last frame sync time stamp PHY_RCD antNo; ///< antenna number record @@ -244,45 +243,45 @@ typedef struct uint32_t lastLogTime; /// physical state log time stamp } PHY_INST; -/************************** Variable Definitions *****************************/ -extern uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS]; -extern uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS]; -extern uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS]; -extern uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS]; -extern uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS]; -extern uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS]; -extern uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS]; -extern uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS]; -extern uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS]; - /************************** Function Prototypes ******************************/ + +/** + * @defgroup PhysicalLayer_Main + * @{ + */ int32_t Phy_Init(PHY_INST **instPtr, PHY_CONFIG *phyConfig); void Phy_Destroy(PHY_INST *instPtr); - -void Phy_UpdateState(PHY_INST *instPtr); -void Phy_UpdateLogging(PHY_INST *instPtr); -void Phy_RefreshHwSate(PHY_INST *instPtr); - void Phy_Start(PHY_INST *instPtr); void Phy_Halt(PHY_INST *instPtr); -int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod); +int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod); +int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType); int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, L1_FRAME_TYPE frameType, uint8_t *dataBuff); +void Phy_UpdateState(PHY_INST *instPtr); void Phy_PeekRecvData(PHY_INST *instPtr, uint8_t *dataBuff); void Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *dataBuff); +void Phy_UpdateLogging(PHY_INST *instPtr); +void Phy_RefreshHwSate(PHY_INST *instPtr); +/** @} PhysicalLayer_Main*/ +/** + * @defgroup PhysicalLayer_Utility + * @{ + */ bool Phy_IsFrameDetected(PHY_INST *instPtr); bool Phy_IsFrameReceived(PHY_INST *instPtr); bool Phy_IsFrameValid(PHY_INST *instPtr); uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType); - -L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST *instPtr); -L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST *instPtr); - -int32_t Phy_SetHopPattern(void *patternBuff, uint32_t patternLen); uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType); uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType); +L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST *instPtr); +L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST *instPtr); +/** @} PhysicalLayer_Utility*/ +/** + * @defgroup PhysicalLayer_Receive_Estimations + * @{ + */ uint8_t Phy_LastScanBeamNo(PHY_INST *instPtr); double Phy_GetFreqEst(PHY_INST *instPtr); double Phy_GetCoarseFreqEst(PHY_INST *instPtr); @@ -291,6 +290,7 @@ void Phy_GetFrameSyncTimeStamp(PHY_INST *instPtr, TIME_WORD *frameSyncT); void Phy_GetLastReceivedFrameSyncTimeStamp(PHY_INST *instPtr, TIME_WORD *frameSyncT); void Phy_GetSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart); void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart); +/** @} PhysicalLayer_Receive_Estimations*/ /** * @defgroup PhysicalLayer_AntennaControl @@ -302,8 +302,8 @@ void Phy_SetBeamTable(PHY_INST *instPtr, PHY_ANT_ANGLE *table, uint32_t offset); int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth); int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo, PHY_ANT_BEAM_WIDTH beamWidth); int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx); -int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType); /** @} PhysicalLayer_AntennaControl*/ + #endif // PHY_CTRL_H_ /** @} PhysicalLayer*/ \ No newline at end of file