Initial version.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user