Initial version.

This commit is contained in:
Gatsby Van
2023-12-20 00:11:03 +08:00
commit 416bd53733
1043 changed files with 293547 additions and 0 deletions
+850
View File
@@ -0,0 +1,850 @@
/*****************************************************************************/
/**
* Description: Inter-Communication protocol implementation.
*
* Date: 2022-06-18 16:37
* LastEditTime: 2023-04-24 17:38
* Revisions: Rev 0.1
* History:
* [2022-06-18]: Initial version.
* [2023-04-24]: Bug fix:
* - Read frame type from PL status register.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "inter_comm.h"
#include "../error.h"
#include "../util/util.h"
#include "../phy_ctrl/phy_ctrl.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static uint64_t GetTimeWord(uint8_t* buffPtr);
static uint32_t GetMsgLen(uint8_t msgCode);
static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr);
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
* @brief Get a 64 bit time word from specified buffer pointer.
*
* @param buffPtr
*
* @return 64bit unsigned timer word
*
******************************************************************************/
static uint64_t GetTimeWord(uint8_t* buffPtr){
ASSERT(buffPtr != NULL);
uint64_t timeWord = 0;
timeWord |= (uint64_t)buffPtr[0];
timeWord |= ((uint64_t)buffPtr[1])<<8;
timeWord |= ((uint64_t)buffPtr[2])<<16;
timeWord |= ((uint64_t)buffPtr[3])<<24;
timeWord |= ((uint64_t)buffPtr[4])<<32;
timeWord |= ((uint64_t)buffPtr[5])<<40;
timeWord |= ((uint64_t)buffPtr[6])<<48;
timeWord |= ((uint64_t)buffPtr[7])<<56;
return timeWord;
}
/*****************************************************************************/
/**
* @brief Invoke a glink message reception process, check data crc, test the
* validation of received data.
*
* @param instPtr a pointer to inter communication instance
* @param frameType
*
* @return SUCCESS
* ECRC crc check failed.
*
******************************************************************************/
static uint32_t GetMsgLen(uint8_t msgCode){
switch(msgCode){
case INTER_MSG_ST_REQ_CODE:
return INTER_MSG_ST_REQ_LEN;
case INTER_MSG_ST_RSP_CODE:
return INTER_MSG_ST_RSP_LEN;
case INTER_MSG_WAKE_REQ_CODE:
return INTER_MSG_WAKE_REQ_LEN;
case INTER_MSG_WAKE_RSP_CODE:
return INTER_MSG_WAKE_RSP_LEN;
case INTER_MSG_MODESW_CODE:
return INTER_MSG_MODESW_LEN;
case INTER_MSG_CTRL_CODE:
return INTER_MSG_CTRL_LEN;
case INTER_MSG_DSEGWR_CODE:
return INTER_MSG_DSEGWR_LEN;
case INTER_MSG_DSEGRD_CODE:
return INTER_MSG_DSEGRD_LEN;
case INTER_MSG_RT_CODE:
return INTER_MSG_RT_LEN;
default:
return INTER_MSG_LEN_NONE;
}
}
/*****************************************************************************/
/**
* @brief Evaluate glink command and get ready to receive/send the required
* frame.
*
* @param instPtr a pointer to inter communication instance
* @param msgPtr a pointer to message buffer
*
* @return SUCCESS
* EPARAM illegal command setting detected.
* EIGNORE unsupported command detected.
*
******************************************************************************/
static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
ASSERT(instPtr != NULL);
ASSERT(msgPtr != NULL);
int32_t Status;
PHY_INST* phyRef = instPtr->phyInstPtr;
L1_FRAME_TYPE frameType = L1_NONE_FRAME;
PHY_TOR_TYPE torState = PHY_TOR_SUSPEND;
PHY_ANT_BEAM_WIDTH beamWidth = ANT_BEAM_NONE;
uint32_t beamNo = 0;
uint16_t msg_Recv = 0;
msg_Recv |= (uint16_t)msgPtr[TYPE_CODE_OFFSET];
msg_Recv |= ((uint16_t)msgPtr[TYPE_CODE_OFFSET+1])<<8;
if(msg_Recv != INTER_MSG_CTRL_CODE){
return EIGNORE;
}
if(msgPtr[INTER_MSG_CTRL_TOR_OFFSET] == CTRL_TOR_TX){
torState = PHY_TOR_TX;
}
else if(msgPtr[INTER_MSG_CTRL_TOR_OFFSET] == CTRL_TOR_RX){
torState = PHY_TOR_RX;
}
else{
DBG_ERROR("[PHY Control] Tx/Rx state cannot be recognized...\n\r");
return EIGNORE;
}
instPtr->lastCtrlTimeTag = GetTimeWord(msgPtr+CTRL_TIME_OFFSET);
if(torState == PHY_TOR_TX){
if(instPtr->lastCtrlTimeTag != instPtr->lastDataTimeTag){
return EPARAM;
}
}
switch(msgPtr[CTRL_FRAME_TYPE_OFFSET]){
case CTRL_FRAME_10K10MS:
frameType = L1_10KBPS_10MS_FRAME;
break;
case CTRL_FRAME_10K20MS:
frameType = L1_10KBPS_20MS_FRAME;
break;
case CTRL_FRAME_200K5MS:
frameType = L1_200KBPS_5MS_FRAME;
break;
case CTRL_FRAME_1M25MS:
frameType = L1_1M2BPS_5MS_FRAME;
break;
case CTRL_FRAME_2K20MS:
frameType = L1_2KBPS_20MS_FRAME;
break;
case CTRL_FRAME_2K100MS:
frameType = L1_2KBPS_100MS_FRAME;
break;
case CTRL_FRAME_40K10MS:
frameType = L1_40KBPS_10MS_FRAME;
break;
case CTRL_FRAME_40K20MS:
frameType = L1_40KBPS_20MS_FRAME;
break;
default:
DBG_ERROR("[PHY Control] Frame Type cannot be recognized...\n\r");
return EIGNORE;
break;
}
// FIXME: no extra antenna in current stage
////////////////////////////////////
// Antenna configurations
////////////////////////////////////
// FIXME: no switch control in current stage
////////////////////////////////////
// Switch configurations
////////////////////////////////////
uint16_t hop_msg_Recv = 0;
hop_msg_Recv |= (uint16_t)msgPtr[INTER_MSG_CTRL_HOP_MODE_OFFSET];
hop_msg_Recv |= ((uint16_t)msgPtr[INTER_MSG_CTRL_HOP_MODE_OFFSET+1])<<8;
if(hop_msg_Recv == CTRL_HOP_PRESET){
phyRef->isPresetHop = true;
}
else if(hop_msg_Recv == CTRL_HOP_CONFIG){
phyRef->isPresetHop = false;
}
else{
DBG_ERROR("[PHY Control] Hopping Pattern Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using default preset hopping pattern instead...\n\r");
return EIGNORE;
}
if(phyRef->isPresetHop == false){
Status = Phy_SetHopPattern(msgPtr+INTER_MSG_CTRL_HOP_PATTERN_OFFSET,
Phy_GetHopLength(frameType));
if(Status != SUCCESS){
return Status;
}
}
if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_WIDE){
beamWidth = ANT_BEAM_120;
}
else if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_SUBNRW){
beamWidth = ANT_BEAM_25;
}
else if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_NRW){
beamWidth = ANT_BEAM_8;
}
else{
DBG_ERROR("[PHY Control] Beam Width Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using default WILD beam (120 deg) instead...\n\r");
return EIGNORE;
}
Status = Phy_SetBeamWidth(phyRef, beamWidth);
if(Status != SUCCESS){
return Status;
}
beamNo = (uint32_t)msgPtr[INTER_MSG_CTRL_BEAM_NO_OFFSET];
if((beamNo<NUM_ANT_SUBNRRW_PATTERN && beamWidth == ANT_BEAM_25)
||(beamNo<NUM_ANT_NRRW_PATTERN && beamWidth == ANT_BEAM_8)
|| (beamNo == 0 && beamWidth == ANT_BEAM_120)){
Phy_SetBeamNo(phyRef, beamNo);
}
else{
if(beamNo != 0x000000FF){
DBG_ERROR("[PHY Control] Beam Number Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using Beam Angle configure instead...\n\r");
return EIGNORE;
}
// the angle config is a 16 bit fixed point data
// 1 bit sign 2 bit integer 13 bit fraction
uint16_t offAxAgnel = 0;
uint16_t rndAxAgnel = 0;
offAxAgnel |= (uint16_t)msgPtr[INTER_MSG_CTRL_OFFAX_OFFSET];
offAxAgnel |= ((uint16_t)msgPtr[INTER_MSG_CTRL_OFFAX_OFFSET+1])<<8;
rndAxAgnel |= (uint16_t)msgPtr[INTER_MSG_CTRL_RNDAX_OFFSET];
rndAxAgnel |= ((uint16_t)msgPtr[INTER_MSG_CTRL_RNDAX_OFFSET+1])<<8;
Status = Phy_SetBeamAngle(phyRef, offAxAgnel/10, rndAxAgnel/10);
if(Status != SUCCESS){
return Status;
}
}
TIME_WORD tmWord = {0};
tmWord.int_part = (uint32_t)(instPtr->lastCtrlTimeTag >> 32);
tmWord.frac_part = (uint32_t)(instPtr->lastCtrlTimeTag);
Status = Phy_SetTimeWord(phyRef, &tmWord, TIME_WORD_POLL);
Status = Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Phy_SetupNextSlot(phyRef, torState, frameType, instPtr->phySendBuff);
if(Status != SUCCESS){
return Status;
}
instPtr->lastCtrlTimeTag = 0;
instPtr->lastDataTimeTag = 0;
return Status;
}
/*****************************************************************************/
/**
* @brief Initialize the inter communication instance, allocate space for
* message buffers.
*
* @param instPtr a second rank pointer to inter communication instance
* @param configPtr a pointer to inter communication instance configuration
* set.
*
* @return SUCCESS
* EALLOC memory allocate failed.
*
******************************************************************************/
int32_t InterComm_Init(INTER_COMM_INST** instPtr, INTER_COMM_CONFIG* configPtr){
int32_t Status;
if (configPtr == NULL) {
return EPARAM;
}
*instPtr = (INTER_COMM_INST*) malloc(sizeof(INTER_COMM_INST));
if ((*instPtr) == NULL) {
return EALLOC;
}
memset(*instPtr, 0x00, sizeof(INTER_COMM_INST));
(*instPtr)->rxRemain = 0;
(*instPtr)->txRemain = 0;
(*instPtr)->lastCtrlTimeTag = 0;
(*instPtr)->lastDataTimeTag = 0;
(*instPtr)->lastPhyTimeTag = 0;
(*instPtr)->phyInstPtr = configPtr->phyInstPtr;
(*instPtr)->data_send = configPtr->data_send;
(*instPtr)->data_recv = configPtr->data_recv;
(*instPtr)->isSleep = false;
// Initial message buffer
(*instPtr)->recvBuff = calloc(INTER_MSG_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->recvBuff == NULL) {
Status = EALLOC;
goto init_failed;
}
(*instPtr)->sendBuff = calloc(INTER_MSG_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->sendBuff == NULL) {
Status = EALLOC;
goto init_failed;
}
// Initial physical buffer
(*instPtr)->phyRecvBuff = calloc(TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->phyRecvBuff == NULL) {
Status = EALLOC;
goto init_failed;
}
(*instPtr)->phySendBuff = calloc(TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->phySendBuff == NULL) {
Status = EALLOC;
goto init_failed;
}
return SUCCESS;
init_failed:
InterComm_Destroy(*instPtr);
return Status;
}
/*****************************************************************************/
/**
* @brief Destroy the inter communication instance, free all allocated memory.
*
* @param instPtr a second rank pointer to inter communication instance
*
* @return NONE
*
******************************************************************************/
void InterComm_Destroy(INTER_COMM_INST* instPtr) {
if(instPtr == NULL) {
return;
}
free(instPtr->sendBuff);
free(instPtr->recvBuff);
free(instPtr->phySendBuff);
free(instPtr->phyRecvBuff);
free(instPtr);
}
/*****************************************************************************/
/**
* @brief Invoke a glink message reception process, check data crc, test the
* validation of received data.
*
* @param instPtr a pointer to inter communication instance
* @param frameType
*
* @return SUCCESS
* ECRC crc check failed.
* FAILURE command code cannot be recognized.
******************************************************************************/
int32_t InterComm_RecvMsg(INTER_COMM_INST* instPtr){
bool ret;
int32_t Status;
uint32_t msgLen = 0;
uint8_t* msgRecvPtr = (uint8_t*)instPtr->recvBuff;
Status = instPtr->data_recv(msgRecvPtr, INTER_MSG_LEN);
msgLen = GetMsgLen(msgRecvPtr[TYPE_CODE_OFFSET]);
if(Status == SUCCESS){
if(msgLen == INTER_MSG_LEN_NONE){
return FAILURE;
}
ret = CrcCheck(msgRecvPtr, msgLen);
if(ret == true){
return SUCCESS;
}
else{
return ECRC;
}
}
return Status;
}
/*****************************************************************************/
/**
* @brief Invoke a data sending process, append crc check ro the send data.
*
* @param instPtr a pointer to inter communication instance
* @param dataLen length of the send data.
*
* @return SUCCESS
* FAILURE data too long, exceeded glink buffer length.
*
******************************************************************************/
int32_t InterComm_SendMsg(INTER_COMM_INST* instPtr, int32_t dataLen, uint16_t subAddr){
int32_t Status;
if(dataLen > INTER_MSG_LEN){
return FAILURE;
}
Status = AppendCrc((uint8_t*)instPtr->sendBuff, dataLen);
if(Status == SUCCESS){
Status = instPtr->data_send((uint16_t*)instPtr->sendBuff, dataLen, subAddr);
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief A full function of inter communication message handler, evaluate
* all the protocol command and response properly.
*
* @param instPtr a pointer to inter communication instance
*
* @return SUCCESS
* EDINVAL device in sleep mode, not functional.
* EIGNORE received a command not supported by current protocol.
* IGNORE_COMMAND_ERROR received a dummy command ignored by current protocol.
*
******************************************************************************/
int32_t InterComm_MsgHandler(INTER_COMM_INST* instPtr){
ASSERT(instPtr != NULL);
int32_t Status = SUCCESS;
uint8_t* msgRecvPtr = (uint8_t*) instPtr->recvBuff;
uint8_t* msgSendPtr = (uint8_t*) instPtr->sendBuff;
uint16_t msg_Recv = 0;
msg_Recv |= (uint16_t)msgRecvPtr[TYPE_CODE_OFFSET];
msg_Recv |= ((uint16_t)msgRecvPtr[TYPE_CODE_OFFSET+1])<<8;
if(instPtr->isSleep == true){
if(msg_Recv != INTER_MSG_WAKE_REQ_CODE){
DBG_WARNING("Device is in sleep mode, ignore command...");
return EDINVAL;
}
}
switch(msg_Recv){
case INTER_MSG_ST_REQ_CODE:{
uint16_t cmdCode = 0;
memset(msgSendPtr, 0x00, INTER_MSG_ST_RSP_LEN);
cmdCode |= (uint16_t)msgRecvPtr[ST_CMD_OFFSET];
cmdCode |= ((uint16_t)msgRecvPtr[ST_CMD_OFFSET+1])<<8;
if(cmdCode == ST_CMD){
////////////////////////
// Run a self test...
/////////////////////////
msgSendPtr[TYPE_CODE_OFFSET] = (uint8_t)INTER_MSG_ST_RSP_CODE;
msgSendPtr[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_ST_RSP_CODE>>8);
msgSendPtr[ST_RSP_STATE_OFFSET] = (uint8_t)ST_RSP_STATE_OK;
msgSendPtr[ST_RSP_STATE_OFFSET+1] = (uint8_t)(ST_RSP_STATE_OK>>8);
Status = InterComm_SendMsg(instPtr, INTER_MSG_ST_RSP_LEN, INTER_MSG_OTHER_ADDR);
}
else{
return EIGNORE;
}
break;
}
case INTER_MSG_WAKE_REQ_CODE:{
uint16_t cmdCode = 0;
memset(msgSendPtr, 0x00, INTER_MSG_WAKE_RSP_LEN);
cmdCode |= (uint16_t)msgRecvPtr[WAKE_CMD_OFFSET];
cmdCode |= ((uint16_t)msgRecvPtr[WAKE_CMD_OFFSET+1])<<8;
if(cmdCode == WAKE_CMD_UP_LPW){
if(instPtr->isSleep == true){
DBG_WARNING("Device is already in sleep mode...");
msgSendPtr[TYPE_CODE_OFFSET] = (uint8_t)INTER_MSG_WAKE_RSP_CODE;
msgSendPtr[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_WAKE_RSP_CODE>>8);
msgSendPtr[WAKE_CMD_OFFSET] = (uint8_t)WAKE_CMD_LPW_LPW;
msgSendPtr[WAKE_CMD_OFFSET+1] = (uint8_t)(WAKE_CMD_LPW_LPW>>8);
}
else{
////////////////////////
// Run a lowpower sleep routine...
/////////////////////////
instPtr->isSleep = true;
msgSendPtr[TYPE_CODE_OFFSET] = (uint8_t)INTER_MSG_WAKE_RSP_CODE;
msgSendPtr[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_WAKE_RSP_CODE>>8);
msgSendPtr[WAKE_CMD_OFFSET] = (uint8_t)WAKE_CMD_UP_LPW;
msgSendPtr[WAKE_CMD_OFFSET+1] = (uint8_t)(WAKE_CMD_UP_LPW>>8);
}
}
else if(cmdCode == WAKE_CMD_LPW_UP){
if(instPtr->isSleep == false){
DBG_WARNING("Device is already in wake mode...");
msgSendPtr[TYPE_CODE_OFFSET] = (uint8_t)INTER_MSG_WAKE_RSP_CODE;
msgSendPtr[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_WAKE_RSP_CODE>>8);
msgSendPtr[WAKE_CMD_OFFSET] = (uint8_t)WAKE_CMD_UP_UP;
msgSendPtr[WAKE_CMD_OFFSET+1] = (uint8_t)(WAKE_CMD_UP_UP>>8);
}
else{
////////////////////////
// Run a wake up routine...
/////////////////////////
instPtr->isSleep = false;
msgSendPtr[TYPE_CODE_OFFSET] = (uint8_t)INTER_MSG_WAKE_RSP_CODE;
msgSendPtr[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_WAKE_RSP_CODE>>8);
msgSendPtr[WAKE_CMD_OFFSET] = (uint8_t)WAKE_CMD_LPW_UP;
msgSendPtr[WAKE_CMD_OFFSET+1] = (uint8_t)(WAKE_CMD_LPW_UP>>8);
}
}
else{
return EIGNORE;
}
Status = InterComm_SendMsg(instPtr, INTER_MSG_WAKE_RSP_LEN,INTER_MSG_OTHER_ADDR);
break;
}
case INTER_MSG_MODESW_CODE:{
if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NORMAL){
Phy_SetMode(instPtr->phyInstPtr, PHY_MODE_PULL);
}
else if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NETSET){
uint64_t timeTemp;
TIME_WORD tmWord;
timeTemp = GetTimeWord(msgRecvPtr + MODESW_START_TIME_OFFSET);
tmWord.int_part = (uint32_t)(timeTemp>>32);;
tmWord.frac_part = (uint32_t)(timeTemp);
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_POLL);
if(Status != SUCCESS){
return EPARAM;
}
timeTemp = GetTimeWord(msgRecvPtr + MODESW_TIMEOUT_OFFSET);
if(timeTemp == 0){
tmWord.frac_part = 0;
tmWord.int_part = 0;
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_LISTEN_TIMEOUT);
if(Status != SUCCESS){
return EPARAM;
}
}
else{
tmWord.frac_part += (uint32_t)(timeTemp);
tmWord.int_part += (uint32_t)(timeTemp>>32);
tmWord.int_part = (tmWord.frac_part >= TMWORD_FRAC_MAX) ? tmWord.int_part + 1:tmWord.int_part;
tmWord.frac_part %= TMWORD_FRAC_MAX;
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_LISTEN_TIMEOUT);
if(Status != SUCCESS){
return EPARAM;
}
}
instPtr->phyInstPtr->isPresetHop = true ;
Status = Phy_SetMode(instPtr->phyInstPtr, PHY_MODE_LISTEN);
Status = Phy_SetupNextSlot(instPtr->phyInstPtr, PHY_TOR_RX, L1_10KBPS_20MS_FRAME, NULL);
}
else{
return EPARAM;
}
break;
}
case INTER_MSG_CTRL_CODE:{
Status = EvalPhyConfig(instPtr, msgRecvPtr);
break;
}
case INTER_MSG_DSEGWR_CODE:{
uint16_t subPktLen;
uint8_t* phyTxBuff;
phyTxBuff= (uint8_t*)instPtr->phySendBuff;
subPktLen = (uint16_t)msgRecvPtr[DSEGWR_PDLEN_OFFSET];
subPktLen |= ((uint16_t)msgRecvPtr[DSEGWR_PDLEN_OFFSET+1])<<8;
if(msgRecvPtr[DSEGWR_TYPE_OFFSET] == DSEGWR_TYPE_PKN){
memcpy(phyTxBuff, msgRecvPtr+DSEGWR_PD_OFFSET, (size_t)subPktLen);
}
else if(msgRecvPtr[DSEGWR_TYPE_OFFSET] == DSEGWR_TYPE_PK1){
memcpy(phyTxBuff, msgRecvPtr+DSEGWR_PD_OFFSET, (size_t)subPktLen);
}
else if(msgRecvPtr[DSEGWR_TYPE_OFFSET] == DSEGWR_TYPE_PK2){
memcpy(phyTxBuff+DSEGWR_PD_LEN, msgRecvPtr+DSEGWR_PD_OFFSET, (size_t)subPktLen);
}
else if(msgRecvPtr[DSEGWR_TYPE_OFFSET] == DSEGWR_TYPE_PK3){
memcpy(phyTxBuff+DSEGWR_PD_LEN*2, msgRecvPtr+DSEGWR_PD_OFFSET, (size_t)subPktLen);
}
else{
return EPARAM;
}
// Store time tag last to prevent get a error command time tag
// e.g. if DSEGWR_TYPE not cannot be recognized, function will return
// in earlier stage, interComm instance won't get a time tag in a
// error command.
// FIXME: Check data integrity?
instPtr->lastDataTimeTag = GetTimeWord(msgRecvPtr+DSEGWR_TIME_OFFSET);
////////////////////////
// Invoke a time sync process ...
/////////////////////////
break;
}
default:
return FAILURE;
break;
}
return Status;
}
/*****************************************************************************/
/**
* @brief Invoke a data sending process, append crc check ro the send data.
*
* @param instPtr a pointer to inter communication instance
*
* @return SUCCESS
* FAILURE data too long, exceeded glink buffer length.
*
******************************************************************************/
int32_t InterComm_SendRemotCheck(INTER_COMM_INST* instPtr, XSysMon* SysMonInstPtr, C2C_EXTRA* c2cExtraBuffPtr){
ASSERT(instPtr != NULL);
ASSERT(SysMonInstPtr != NULL);
ASSERT(c2cExtraBuffPtr != NULL);
int32_t Status;
uint8_t* msgTxBuff = (uint8_t*) instPtr->sendBuff;
memset(msgTxBuff, 0x00, INTER_MSG_LEN);
// Set message code
msgTxBuff[TYPE_CODE_OFFSET] = (uint8_t)(INTER_MSG_RT_CODE);
msgTxBuff[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_RT_CODE>>8);
msgTxBuff[RT_PHY_OFFSET] = (uint8_t)(0x0003);
msgTxBuff[RT_PHY_OFFSET+1] = (uint8_t)(0x0003>>8);
uint8_t* TimeBuff = (uint8_t*)(&(instPtr->lastPhyTimeTag));
msgTxBuff[RT_TIME_OFFSET] = (uint8_t)(TimeBuff[0]);
msgTxBuff[RT_TIME_OFFSET+1] = (uint8_t)(TimeBuff[1]);
msgTxBuff[RT_TIME_OFFSET+2] = (uint8_t)(TimeBuff[2]);
msgTxBuff[RT_TIME_OFFSET+3] = (uint8_t)(TimeBuff[3]);
msgTxBuff[RT_TIME_OFFSET+4] = (uint8_t)(TimeBuff[4]);
msgTxBuff[RT_TIME_OFFSET+5] = (uint8_t)(TimeBuff[5]);
msgTxBuff[RT_TIME_OFFSET+6] = (uint8_t)(TimeBuff[6]);
msgTxBuff[RT_TIME_OFFSET+7] = (uint8_t)(TimeBuff[7]);
uint32_t VccAuxRawData;
uint16_t VccAuxData;
VccAuxRawData = XSysMon_GetAdcData(SysMonInstPtr,XSM_CH_VCCINT );
VccAuxData = (int16_t)(XSysMon_RawToVoltage(VccAuxRawData)*10);
msgTxBuff[RT_SP_VOLT_OFFSET] = (uint8_t)(VccAuxData);
msgTxBuff[RT_SP_VOLT_OFFSET+1] = (uint8_t)(VccAuxData>>8);
uint32_t TempRawData;
int16_t TempData;
TempRawData = XSysMon_GetAdcData(SysMonInstPtr, XSM_CH_TEMP);
TempData = (int16_t)(XSysMon_RawToTemperature(TempRawData)*10);
msgTxBuff[RT_SP_TEMP_OFFSET] = (uint8_t)(TempData);
msgTxBuff[RT_SP_TEMP_OFFSET+1] = (uint8_t)(TempData>>8);
msgTxBuff[RT_SP_CHIP_OFFSET] = (uint8_t)(0x0001);
msgTxBuff[RT_SP_CHIP_OFFSET+1] = (uint8_t)(0x0001>>8);
uint8_t* ExtraBuff = (uint8_t*)(c2cExtraBuffPtr->extra);
msgTxBuff[RT_ANT_VOLT_OFFSET] = (uint8_t)(ExtraBuff[0]);
msgTxBuff[RT_ANT_VOLT_OFFSET+1] = (uint8_t)(ExtraBuff[1]);
msgTxBuff[RT_ANT_TEMP_OFFSET] = (uint8_t)(ExtraBuff[2]);
msgTxBuff[RT_ANT_TEMP_OFFSET+1] = (uint8_t)(ExtraBuff[3]);
msgTxBuff[RT_ANT_LOCK_OFFSET] = (uint8_t)(0x0001);
msgTxBuff[RT_ANT_LOCK_OFFSET+1] = (uint8_t)(0x0001>>8);
msgTxBuff[RT_ANT_MGC_OFFSET] = (uint8_t)(0x0000);
msgTxBuff[RT_ANT_MGC_OFFSET+1] = (uint8_t)(0x0000>>8);
msgTxBuff[RT_ANT_STATE_OFFSET] = (uint8_t)(0x0001);
msgTxBuff[RT_ANT_STATE_OFFSET+1] = (uint8_t)(0x0001>>8);
Status = InterComm_SendMsg(instPtr, (int32_t)INTER_MSG_RT_LEN, INTER_MSG_RT_ADDR);
return Status;
}
/*****************************************************************************/
/**
* @brief Invoke a data frame upload process, split the received data frame
* to multiple subpackages if needed, and send the send them in a properly
* order defined by inter communication protocol.
*
* @param instPtr a pointer to inter communication instance
*
* @return SUCCESS
* FAILURE frame cannot be recognized.
* EIGNORE received a command not supported by current protocol.
* IGNORE_COMMAND_ERROR received a dummy command ignored by current protocol.
*
******************************************************************************/
// FIXME: only support ONE physical device now.
int32_t InterComm_PhyDataUpload(INTER_COMM_INST* instPtr){
int32_t Status;
uint32_t remainDataLen, numPkt, subPktLen;
uint8_t *txMsgBuff, *phyRxBuff;
L1_FRAME_TYPE lastFrameType;
txMsgBuff = (uint8_t*)instPtr->sendBuff;
phyRxBuff = (uint8_t*)instPtr->phyRecvBuff;
lastFrameType = Phy_GetLastRecvFrameType(instPtr->phyInstPtr);
remainDataLen = Phy_GetFrameLen(lastFrameType);
if(remainDataLen == L1_FRAME_NONE_LEN){
return FAILURE;
}
numPkt = 1 + ((remainDataLen - 1) / DSEGRD_PD_LEN); // dived and round up equals to ceil(x/y)
if(numPkt > MSG_DSEGRD_SUBPKG_MAX){
return FAILURE;
}
txMsgBuff[TYPE_CODE_OFFSET] = (uint8_t)(INTER_MSG_DSEGRD_CODE);
txMsgBuff[TYPE_CODE_OFFSET+1] = (uint8_t)(INTER_MSG_DSEGRD_CODE>>8);
// Time Estimate
uint32_t fsTimeL, fsTimeH;
fsTimeL = PhyRead(instPtr->phyInstPtr, FSTIME_L);
fsTimeH = PhyRead(instPtr->phyInstPtr, FSTIME_H);
instPtr->lastPhyTimeTag = fsTimeL;
instPtr->lastPhyTimeTag |= ((uint64_t)fsTimeH)<<32;
uint32_t timeComp = Phy_GetTimeComp(lastFrameType);
if(timeComp == L1_FRAME_NONE_COMP){
return FAILURE;
}
fsTimeH -= timeComp/TMWORD_FRAC_MAX;
timeComp %= TMWORD_FRAC_MAX;
fsTimeH = (fsTimeL < timeComp)?(fsTimeH - 1):fsTimeH;
fsTimeL = (fsTimeL < timeComp)?(TMWORD_FRAC_MAX + fsTimeL - timeComp) : (fsTimeL - timeComp);
memcpy(txMsgBuff+DSEGRD_TIME_OFFSET, &fsTimeL, DSEGRD_TIME_LEN/2);
memcpy(txMsgBuff+DSEGRD_TIME_OFFSET + DSEGRD_TIME_LEN/2, &fsTimeH, DSEGRD_TIME_LEN/2);
// Doppler Estimate
double doppler = Phy_GetCoarseFreqEst(instPtr->phyInstPtr);
// LSB = 0.001Hz
int64_t dopplerQnt = doppler*1000;
memcpy(txMsgBuff+DSEGRD_DPL_OFFSET, &dopplerQnt, DSEGRD_DPL_LEN);
// Check if last frame is a initial acquisition frame
// L1_2KBPS_20MS_FRAME and L1_10KBPS_10MS_FRAME is initial acquisition frame
// if acquisition frame was received successfully, mark it out.
//
// when physical layer acquisition synchronization procedure is done successfully in
// acquisition frame reception period, initial acquisition is considered as success.
if(lastFrameType == L1_2KBPS_20MS_FRAME || lastFrameType == L1_10KBPS_10MS_FRAME){
txMsgBuff[DSEGRD_IACQ_OFFSET] = (Phy_IsFrameDetected(instPtr->phyInstPtr)) ? 0xAA : 0xFF;
txMsgBuff[DSEGRD_IACQ_BEAM_OFFSET] = (Phy_IsFrameDetected(instPtr->phyInstPtr)) ? (uint8_t)instPtr->phyInstPtr->beamNo.last : 0xFF;
}
else{
txMsgBuff[DSEGRD_IACQ_OFFSET] = 0xFF;
txMsgBuff[DSEGRD_IACQ_BEAM_OFFSET] = 0xFF;
}
if(numPkt == 1){
// Initialize payload segment.
memset(txMsgBuff+DSEGRD_PD_OFFSET, 0x00, (size_t)DSEGRD_PD_LEN);
subPktLen = remainDataLen;
txMsgBuff[DSEGRD_TYPE_OFFSET] = (uint8_t)DSEGRD_TYPE_PKN;
txMsgBuff[DSEGRD_TYPE_OFFSET+1] = (uint8_t)(DSEGRD_TYPE_PKN>>8);
txMsgBuff[DSEGRD_PDLEN_OFFSET] = (uint8_t)subPktLen;
txMsgBuff[DSEGRD_PDLEN_OFFSET+1] = (uint8_t)(subPktLen>>8);
memcpy(txMsgBuff+DSEGRD_PD_OFFSET, phyRxBuff, (size_t)subPktLen);
Status = InterComm_SendMsg(instPtr, (int32_t)INTER_MSG_DSEGWR_LEN, INTER_MSG_DSEGRD_PKN_ADDR);
if(Status != SUCCESS){
return Status;
}
}
else{
for(int32_t i = 0; i < numPkt; i++){
// Initialize payload segment.
memset(txMsgBuff+DSEGRD_PD_OFFSET, 0x00, (size_t)DSEGRD_PD_LEN);
subPktLen = (remainDataLen >= DSEGRD_PD_LEN) ? DSEGRD_PD_LEN : remainDataLen;
remainDataLen = remainDataLen - subPktLen;
txMsgBuff[DSEGRD_PDLEN_OFFSET] = (uint8_t)subPktLen;
txMsgBuff[DSEGRD_PDLEN_OFFSET+1] = (uint8_t)(subPktLen>>8);
if(i == 0){
txMsgBuff[DSEGRD_TYPE_OFFSET] = (uint8_t)DSEGRD_TYPE_PK1;
txMsgBuff[DSEGRD_TYPE_OFFSET+1] = (uint8_t)(DSEGRD_TYPE_PK1>>8);
memcpy(txMsgBuff+DSEGRD_PD_OFFSET, phyRxBuff+i*DSEGRD_PD_LEN, (size_t)subPktLen);
Status = InterComm_SendMsg(instPtr, (int32_t) INTER_MSG_DSEGWR_LEN, INTER_MSG_DSEGRD_PK1_ADDR);
}
else if(i == 1){
txMsgBuff[DSEGRD_TYPE_OFFSET] = (uint8_t)DSEGRD_TYPE_PK2;
txMsgBuff[DSEGRD_TYPE_OFFSET+1] = (uint8_t)(DSEGRD_TYPE_PK2>>8);
memcpy(txMsgBuff+DSEGRD_PD_OFFSET, phyRxBuff+i*DSEGRD_PD_LEN, (size_t)subPktLen);
Status = InterComm_SendMsg(instPtr, (int32_t) INTER_MSG_DSEGWR_LEN, INTER_MSG_DSEGRD_PK2_ADDR);
}
else if(i == 2){
txMsgBuff[DSEGRD_TYPE_OFFSET] = (uint8_t)DSEGRD_TYPE_PK3;
txMsgBuff[DSEGRD_TYPE_OFFSET+1] = (uint8_t)(DSEGRD_TYPE_PK3>>8);
memcpy(txMsgBuff+DSEGRD_PD_OFFSET, phyRxBuff+i*DSEGRD_PD_LEN, (size_t)subPktLen);
Status = InterComm_SendMsg(instPtr, (int32_t) INTER_MSG_DSEGWR_LEN, INTER_MSG_DSEGRD_PK3_ADDR);
}
else{ // should never reached.
return EUNEXP;
}
if(Status != SUCCESS){
return Status;
}
}
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Append frame CRC-16 result to frame data buffer.
*
* @param buffPtr
* @param dataLen
*
* @return SUCCESS append successfully
* Other frame cannot be recognized.
*
******************************************************************************/
int AppendCrc(uint8_t* buffPtr, uint32_t dataLen) {
ASSERT(buffPtr != NULL);
int32_t Status = SUCCESS;
if (dataLen == 0) {
return FAILURE;
}
uint16_t crc = 0;
Status = crc16_gen(buffPtr, dataLen - COMMON_CRC_LEN, 0x1021, &crc);
if(Status != SUCCESS){
DBG_ERROR("C2C gernerate failed, error code: %d.\r\n", Status);
}
uint8_t* crcSegPtr = (buffPtr + dataLen - COMMON_CRC_LEN);
#ifdef CRC_COMPARE
*crcSegPtr = (uint8_t) crc & 0x00FF;
*(crcSegPtr + 1) = (uint8_t)((crc & 0xFF00) >> 8);
#else
*crcSegPtr = (uint8_t)((crc & 0xFF00) >> 8); (uint8_t) crc & 0x00FF;
*(crcSegPtr + 1) = (uint8_t) crc & 0x00FF;
#endif
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Check the frame CRC-16, witch can infer the frame should be dump
* or not.
*
* @param frameBuffPtr
* @param frameType
*
* @return true CRC check passed, good frame.
* false CRC check failed, bad frame.
*
******************************************************************************/
bool CrcCheck(uint8_t* buffPtr, uint32_t dataLen){
if (dataLen == 0) {
return false;
}
bool ret = false;
#ifdef CRC_COMPARE
ret = crc16_check(buffPtr, dataLen - COMMON_CRC_LEN, dataLen - COMMON_CRC_LEN, 0x1021);
#else
uint16_t crc = 0;
uint32_t Status = 0;
Status = crc16_gen(buffPtr, dataLen, 0x1021, &crc);
if(Status != SUCCESS){
DBG_ERROR("C2C gernerate failed, error code: %d.\r\n", Status);
}
ret = (crc == 0);
#endif
return ret;
}
+309
View File
@@ -0,0 +1,309 @@
/*****************************************************************************/
/**
* Description: Inter-Communication protocol, definitions and function
* prototypes.
*
* Date: 2022-06-18 16:37
* LastEditTime: 2023-04-24 17:38
* Revisions: Rev 0.2
* History:
* [2022-06-18]: Initial version.
* [2023-04-24]: Bug fix:
* - Read frame type from PL status register.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef INTER_COMM_H_
#define INTER_COMM_H_
/***************************** Include Files *********************************/
#include <stdint.h>
#include "../phy_ctrl/phy_ctrl.h"
#include "xsysmon.h"
#include "../config/app_config.h"
/************************** Constant Definitions *****************************/
#define COMMON_CRC_LEN 2
#define INTER_MSG_LEN 512 //Byte
#define INTER_MSG_CRC_LEN 2
#define INTER_MSG_LEN_NONE UINT32_MAX
#define TYPE_CODE_OFFSET 0x0000
// self test request
#define INTER_MSG_ST_REQ_LEN 0x00006
#define INTER_MSG_ST_REQ_CODE 0x0011
#define ST_CMD_OFFSET 0x0002
#define ST_CMD_LEN 0x0002
#define ST_CMD 0x1111
// self test response
#define INTER_MSG_ST_RSP_LEN 0x0008
#define INTER_MSG_ST_RSP_CODE 0x0021
#define ST_RSP_STATE_OFFSET 0x0002
#define ST_RSP_STATE_LEN 0x0002
#define ST_RSP_STATE_OK 0xAAAA
#define ST_RSP_STATE_ERR 0x5555
#define ST_RSP_MASK1_OFFSET 0x0004
#define ST_RSP_MASK1_LEN 0x0002
#define ST_RSP_MASK2_OFFSET 0x0006
#define ST_RSP_MASK2_LEN 0x0002
// wake up requirement/response
#define INTER_MSG_WAKE_REQ_LEN 0x0006
#define INTER_MSG_WAKE_REQ_CODE 0x0012
#define INTER_MSG_WAKE_RSP_LEN 0x0006
#define INTER_MSG_WAKE_RSP_CODE 0x0022
#define WAKE_CMD_OFFSET 0x0002
#define WAKE_CMD_LEN 0x0002
#define WAKE_CMD_LPW_LPW 0xFFAA
#define WAKE_CMD_UP_LPW 0xAAAA
#define WAKE_CMD_UP_UP 0xFFCC
#define WAKE_CMD_LPW_UP 0xCCCC
// mode swicth command
#define INTER_MSG_MODESW_LEN 0x0016 // 20byte + crc
#define INTER_MSG_MODESW_CODE 0x0041
#define MODESW_START_TIME_OFFSET 0x0002
#define MODESW_START_TIME_LEN 0x0008
#define MODESW_TIMEOUT_OFFSET 0x000A
#define MODESW_TIMEOUT_LEN 0x0008
#define MODESW_MODE_OFFSET 0x0012
#define MODESW_MODE_LEN 0x0002
#define MODESW_MODE_NORMAL 0x0001
#define MODESW_MODE_NETSET 0x0002
// physical layer control
#define INTER_MSG_CTRL_LEN 0x00BC // 186byte + 2byte crc
#define INTER_MSG_CTRL_CODE 0x0013
#define CTRL_TIME_OFFSET 0x0002
#define CTRL_TIME_LEN 0x0008
#define CTRL_FRAME_TYPE_OFFSET 0x000A
#define CTRL_FRAME_TYPE_LEN 0x0001
#define CTRL_FRAME_10K10MS 0x01
#define CTRL_FRAME_10K20MS 0x02
#define CTRL_FRAME_200K5MS 0x03
#define CTRL_FRAME_1M25MS 0x04
#define CTRL_FRAME_2K20MS 0x05
#define CTRL_FRAME_2K100MS 0x06
#define CTRL_FRAME_40K10MS 0x07
#define CTRL_FRAME_40K20MS 0x08
#define INTER_MSG_CTRL_ANT_OFFSET 0x000B
#define INTER_MSG_CTRL_ANT_LEN 0x0001
#define CTRL_ANT_ALL 0x3F
#define CTRL_ANT_FRONT 0x01
#define CTRL_ANT_3QUAD2 0x02
#define CTRL_ANT_3QUAD4 0x04
#define CTRL_ANT_BOTT 0x08
#define CTRL_ANT_RSV1 0x10
#define CTRL_ANT_RSV2 0x20
#define INTER_MSG_CTRL_TOR_OFFSET 0x000C
#define INTER_MSG_CTRL_TOR_LEN 0x0001
#define CTRL_TOR_TX 0xAA
#define CTRL_TOR_RX 0xCC
#define INTER_MSG_CTRL_SW_OFFSET 0x000D
#define INTER_MSG_CTRL_SW_LEN 0x0001
#define CTRL_SW_PW BIT(0)
#define CTRL_SW_TR BIT(1)
#define CTRL_SW_TOR BIT(2)
#define INTER_MSG_CTRL_HOP_MODE_OFFSET 0x000E
#define INTER_MSG_CTRL_HOP_MODE_LEN 0x0002
#define CTRL_HOP_PRESET 0x2222
#define CTRL_HOP_CONFIG 0x5555
#define INTER_MSG_CTRL_HOP_PATTERN_OFFSET 0x0010
#define INTER_MSG_CTRL_HOP_PATTERN_LEN 0x00A2
#define INTER_MSG_CTRL_BEAM_MODE_OFFSET 0x00B2
#define INTER_MSG_CTRL_BEAM_MODE_LEN 0x0001
#define BEAM_MODE_WIDE 0x51
#define BEAM_MODE_NRW 0x52
#define BEAM_MODE_SUBNRW 0x53
#define INTER_MSG_CTRL_BEAM_NO_OFFSET 0x00B3
#define INTER_MSG_CTRL_BEAM_NO_LEN 0x0001
#define INTER_MSG_CTRL_AMP_WT_OFFSET 0x00B4
#define INTER_MSG_CTRL_AMP_WT_LEN 0x0002
#define INTER_MSG_CTRL_OFFAX_OFFSET 0x00B6
#define INTER_MSG_CTRL_OFFAX_LEN 0x0002
#define INTER_MSG_CTRL_RNDAX_OFFSET 0x00B8
#define INTER_MSG_CTRL_RNDAX_LEN 0x0002
// data segment write
#define MSG_DSEGWR_SUBPKG_MAX 3
#define INTER_MSG_DSEGWR_LEN 0x0200 //510 byte + 2byte crc
#define INTER_MSG_DSEGWR_CODE 0x0014
#define DSEGWR_TYPE_OFFSET 0x0002
#define DSEGWR_TYPE_LEN 0x0002
#define DSEGWR_TYPE_PKN 0x0010
#define DSEGWR_TYPE_PK1 0x0012
#define DSEGWR_TYPE_PK2 0x0013
#define DSEGWR_TYPE_PK3 0x0014
#define DSEGWR_TIME_OFFSET 0x0004
#define DSEGWR_TIME_LEN 0x0008
#define DSEGWR_PDLEN_OFFSET 0x000C
#define DSEGWR_PDLEN_LEN 0x0002
#define DSEGWR_PD_OFFSET 0x000E
#define DSEGWR_PD_LEN 0x01F0
// data segment read
#define MSG_DSEGRD_SUBPKG_MAX 3
#define INTER_MSG_DSEGRD_LEN 0x0200 //510 byte + 2byte crc
#define INTER_MSG_DSEGRD_CODE 0x0023
#define DSEGRD_TYPE_OFFSET 0x0002
#define DSEGRD_TYPE_LEN 0x0001
#define DSEGRD_TYPE_PKN 0x0010
#define DSEGRD_TYPE_PK1 0x0012
#define DSEGRD_TYPE_PK2 0x0013
#define DSEGRD_TYPE_PK3 0x0014
#define DSEGRD_TIME_OFFSET 0x0004
#define DSEGRD_TIME_LEN 0x0008
#define DSEGRD_DPL_OFFSET 0x000C
#define DSEGRD_DPL_LEN 0x0008
#define DSEGRD_PDLEN_OFFSET 0x0016
#define DSEGRD_PDLEN_LEN 0x0002
#define DSEGRD_IACQ_OFFSET 0x0014
#define DSEGRD_IACQ_LEN 0x0001
#define DSEGRD_IACQ_BEAM_OFFSET 0x0015
#define DSEGRD_IACQ_BEAM_LEN 0x0001
#define DSEGRD_PD_OFFSET 0x0018
#define DSEGRD_PD_LEN 0x01E6
// Remote state test.
#define INTER_MSG_RT_LEN 0x0022 // 32 bytes + 2byte crc
#define INTER_MSG_RT_CODE 0x0031 // remote test.
#define RT_PHY_OFFSET 0x0002
#define RT_PHY_LEN 0x0002
#define RT_TIME_OFFSET 0x0004
#define RT_TIME_LEN 0x0008
#define RT_BEAM_OFFSET 0x000C
#define RT_BEAM_LEN 0x0004
#define RT_SP_VOLT_OFFSET 0x0010
#define RT_SP_VOLT_LEN 0x0002
#define RT_SP_TEMP_OFFSET 0x0012
#define RT_SP_TEMP_LEN 0x0002
#define RT_SP_CHIP_OFFSET 0x0014
#define RT_SP_CHIP_LEN 0x0002
#define RT_ANT_VOLT_OFFSET 0x0016
#define RT_ANT_VOLT_LEN 0x0002
#define RT_ANT_TEMP_OFFSET 0x0018
#define RT_ANT_TEMP_LEN 0x0002
#define RT_ANT_LOCK_OFFSET 0x001A
#define RT_ANT_LOCK_LEN 0x0001
#define RT_ANT_MGC_OFFSET 0x001C
#define RT_ANT_MGC_LEN 0x0002
#define RT_ANT_STATE_OFFSET 0x001E
#define RT_ANT_STATE_LEN 0x0001
#ifdef ANT_DEVICE_ID
#if ANT_DEVICE_ID == 0x0000
#define INTER_MSG_DSEGRD_PKN_ADDR 0x0001
#define INTER_MSG_DSEGRD_PK1_ADDR 0x0001
#define INTER_MSG_DSEGRD_PK2_ADDR 0x0002
#define INTER_MSG_DSEGRD_PK3_ADDR 0x0003
#define INTER_MSG_RT_ADDR 0x0004
#define INTER_MSG_OTHER_ADDR 0x0005
#elif ANT_DEVICE_ID == 0x0001
#define INTER_MSG_DSEGRD_PKN_ADDR 0x0006
#define INTER_MSG_DSEGRD_PK1_ADDR 0x0006
#define INTER_MSG_DSEGRD_PK2_ADDR 0x0007
#define INTER_MSG_DSEGRD_PK3_ADDR 0x0008
#define INTER_MSG_RT_ADDR 0x0009
#define INTER_MSG_OTHER_ADDR 0x000A
#elif ANT_DEVICE_ID == 0x0002
#define INTER_MSG_DSEGRD_PKN_ADDR 0x000B
#define INTER_MSG_DSEGRD_PK1_ADDR 0x000B
#define INTER_MSG_DSEGRD_PK2_ADDR 0x000C
#define INTER_MSG_DSEGRD_PK3_ADDR 0x000D
#define INTER_MSG_RT_ADDR 0x000E
#define INTER_MSG_OTHER_ADDR 0x000F
#elif ANT_DEVICE_ID == 0x0003
#define INTER_MSG_DSEGRD_PKN_ADDR 0x0010
#define INTER_MSG_DSEGRD_PK1_ADDR 0x0010
#define INTER_MSG_DSEGRD_PK2_ADDR 0x0011
#define INTER_MSG_DSEGRD_PK3_ADDR 0x0012
#define INTER_MSG_RT_ADDR 0x0013
#define INTER_MSG_OTHER_ADDR 0x0014
#elif ANT_DEVICE_ID == 0x0004
#define INTER_MSG_DSEGRD_PKN_ADDR 0x0015
#define INTER_MSG_DSEGRD_PK1_ADDR 0x0015
#define INTER_MSG_DSEGRD_PK2_ADDR 0x0016
#define INTER_MSG_DSEGRD_PK3_ADDR 0x0017
#define INTER_MSG_RT_ADDR 0x0018
#define INTER_MSG_OTHER_ADDR 0x0019
#elif ANT_DEVICE_ID == 0x0005
#define INTER_MSG_DSEGRD_PKN_ADDR 0x001A
#define INTER_MSG_DSEGRD_PK1_ADDR 0x001A
#define INTER_MSG_DSEGRD_PK2_ADDR 0x001B
#define INTER_MSG_DSEGRD_PK3_ADDR 0x001C
#define INTER_MSG_RT_ADDR 0x001D
#define INTER_MSG_OTHER_ADDR 0x001E
#elif ANT_DEVICE_ID == 0x0006
#else
#error Cannot Eval Antenna ID...
#endif
#else
#error Antenna ID must be specified...
#endif
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct{
PHY_INST* phyInstPtr;
int32_t (*data_send) (void* buffPtr, int32_t dataLen, uint16_t subAddr);
int32_t (*data_recv) (void* buffPtr, int32_t dataLen);
}INTER_COMM_CONFIG;
// FIXME: only support ONE physical device now.
typedef struct{
uint8_t* recvBuff;
uint8_t* sendBuff;
bool isSleep;
uint32_t rxRemain;
uint32_t txRemain;
uint64_t lastCtrlTimeTag;
uint64_t lastDataTimeTag;
uint64_t lastPhyTimeTag;
PHY_INST* phyInstPtr;
uint8_t* phyRecvBuff;
uint8_t* phySendBuff;
int32_t (*data_send) (void* buffPtr, int32_t dataLen, uint16_t subAddr);
int32_t (*data_recv) (void* buffPtr, int32_t buffSize);
}INTER_COMM_INST;
typedef struct {
uint16_t glinkSubAddr;
uint8_t extra[14];
} C2C_EXTRA;
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
int32_t InterComm_Init(INTER_COMM_INST** instPtr, INTER_COMM_CONFIG* configPtr);
void InterComm_Destroy(INTER_COMM_INST* instPtr);
int32_t InterComm_RecvMsg(INTER_COMM_INST* instPtr);
int32_t InterComm_SendMsg(INTER_COMM_INST* instPtr, int32_t dataLen, uint16_t subAddr);
int32_t InterComm_MsgHandler(INTER_COMM_INST* instPtr);
int32_t InterComm_SendRemotCheck(INTER_COMM_INST* instPtr, XSysMon* SysMonInstPtr, C2C_EXTRA* c2cExtraBuffPtr);
int32_t InterComm_PhyDataUpload(INTER_COMM_INST* instPtr);
// Helper functions
int AppendCrc(uint8_t* buffPtr, uint32_t dataLen);
bool CrcCheck(uint8_t* buffPtr, uint32_t dataLen);
#endif