Author SHA1 Message Date
bit-cyber-fh 06169451f8 misc update 2024-03-28 16:15:26 +08:00
bit-cyber-fh c763f1a481 misc update 2024-03-28 15:59:02 +08:00
bit-cyber-fh 8d72288675 Better struct comment 2024-03-28 15:58:15 +08:00
bit-cyber-fh 16d1ad30a7 unified indentation 2024-03-28 15:25:58 +08:00
Gatsby Van 8779c9855e omit hopping pattern configure methods 2024-03-28 11:04:29 +08:00
bit-cyber-fh 69a8d9d36d Update Comment: Better Doxygen Style 2024-03-28 11:00:12 +08:00
Gatsby Van 41964520a8 misc fix 2024-03-28 00:05:34 +08:00
bit-cyber-fh bab91e13df Common Update: Better Doxygen Style 2024-03-28 00:00:59 +08:00
Gatsby Van 9b416114a1 BSP update: trim unnecessary memory 2024-03-25 13:14:52 +08:00
Gatsby Van e7b45ae1f5 BSP update: trim unnecessary memory 2024-03-24 22:13:44 +08:00
Gatsby Van 3edfce69f2 update physical layer logging scheme 2024-03-24 22:13:22 +08:00
Gatsby Van ad3bc29cfa trim trailing space 2024-03-24 22:05:15 +08:00
Gatsby Van 02fd467708 update test data 2024-03-24 22:04:48 +08:00
Gatsby Van 1fc4fad5ea Merge remote-tracking branch 'refs/remotes/origin/master' 2024-03-22 10:32:07 +08:00
Gatsby Van 957672a191 add test data 2024-03-21 16:22:47 +08:00
Gatsby Van 807b045b75 code simplification 2024-03-20 16:24:05 +08:00
Gatsby Van 6f4774f6b8 add missing logging update 2024-03-20 15:57:21 +08:00
Gatsby Van de5759b392 *add feature: frame type specialized attenuation 2024-03-20 15:14:50 +08:00
Gatsby Van 2b18765563 misc update 2024-03-18 20:21:46 +08:00
Gatsby Van 03a6d86a3a remove unused variables 2024-03-18 11:04:41 +08:00
Gatsby Van 729bbeb60e format and cleanup 2024-03-18 11:02:20 +08:00
Gatsby Van 33545b63e1 config logic simplification 2024-03-18 11:01:56 +08:00
Gatsby Van 6c64421336 update scan frame handling schedule 2024-03-18 11:00:22 +08:00
Gatsby Van dda9d09f2a new linklayer api L2_isStarted 2024-03-18 10:58:16 +08:00
Gatsby Van 14f2be3053 update link brock threshold 2024-03-18 10:57:49 +08:00
Gatsby Van b7607a7a1b cleanup and misc update 2024-03-16 16:57:21 +08:00
Gatsby Van c07cd00f2f comment update and cleanup 2024-03-16 16:26:03 +08:00
Gatsby Van 20da80f6c2 update packet logging method 2024-03-16 16:25:44 +08:00
Gatsby Van c7e3eb2800 *shorten time frame length 2024-03-16 16:20:39 +08:00
Gatsby Van 9acdd0609a update svcFSM 2024-03-16 16:19:15 +08:00
Gatsby Van 66529637a3 add comment add enhance code coherent 2024-03-16 16:18:03 +08:00
53 changed files with 4081 additions and 3926 deletions
+2
View File
@@ -35,6 +35,8 @@
// 2 - print warnings and errors // 2 - print warnings and errors
// 1 - print only errors // 1 - print only errors
// other - print nothing // other - print nothing
#define APP_EMULATE_DATA
#define DATALINK_ENABLE_AUTORECONNECT #define DATALINK_ENABLE_AUTORECONNECT
#define DATALINK_ENABLE_AUTOTIMESYNC #define DATALINK_ENABLE_AUTOTIMESYNC
//#define DATALINK_ENABLE_BERTEST //#define DATALINK_ENABLE_BERTEST
+56 -1
View File
@@ -132,6 +132,47 @@ static MPC_CONFIG mpcConfig = {
.txQueueMax = 16, .txQueueMax = 16,
.rxQueueMax = 16 .rxQueueMax = 16
}; };
#ifdef APP_EMULATE_DATA
uint8_t testDataLj[] =
{
0xEA, 0xDF, 0x3F, 0x27, 0xCE, 0x9B, 0xE6, 0x3F,
0xB5, 0xA3, 0x38, 0x47, 0x1D, 0x1D, 0xFA, 0x3F,
0x39, 0xB4, 0xC8, 0x76, 0xBE, 0xAB, 0x8E, 0x40,
0xC9, 0xE8, 0x80, 0x24, 0xEC, 0xCB, 0x13, 0x40,
0x37, 0x38, 0x7F, 0x22, 0x72, 0x06, 0xF0, 0x01,
0x00, 0x00, 0xB8, 0xAA, 0x08, 0x47, 0x1E, 0xC6,
0xB0, 0x47, 0x54, 0xFD, 0xEB, 0x45, 0xA1, 0x8A,
0x86, 0x44, 0x43, 0xB6, 0xC8, 0x44, 0x4E, 0x19,
0xA8, 0x42
};
uint8_t testDataFlj[] =
{
0xFD, 0x1E, 0xA5, 0x22, 0x72, 0x02, 0x5A, 0x02,
0x00, 0x00, 0x81, 0x97, 0x39, 0x3F, 0xF1, 0xF4,
0xC0, 0x3F, 0x27, 0xF1, 0x65, 0x44, 0x53, 0x5C,
0xD3, 0x3F, 0xB5, 0x24, 0xA6, 0x22, 0x72, 0x02,
0x83, 0x01, 0x00, 0x00, 0xFC, 0xE0, 0x44, 0x47,
0xB7, 0x83, 0x35, 0x47, 0xA4, 0xBF, 0xE5, 0xC4,
0xE8, 0xDC, 0xD1, 0x44, 0x5D, 0x5D, 0xE7, 0x44,
0x7D, 0x1B, 0xE8, 0xC1, 0x60, 0x97, 0x57, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5D, 0x86, 0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02,
0x00, 0x00, 0x97, 0x4E, 0xB5, 0x47, 0xC4, 0x2A,
0xB0, 0x47, 0x2D, 0x00, 0x21, 0xC5, 0x8A, 0x85,
0xD1, 0x44, 0x23, 0xFD, 0xC8, 0x44, 0xA1, 0xC4,
0xEA, 0xC1, 0x91, 0x4E, 0x71, 0xC2, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xAD,
0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02, 0x00, 0x00,
0xCD, 0x07, 0xD6, 0x47, 0x1D, 0xA4, 0xCE, 0x47,
0x6E, 0x61, 0x33, 0xC5, 0x85, 0x55, 0xD1, 0x44,
0x9C, 0x16, 0xBD, 0x44, 0x36, 0xC0, 0xEB, 0xC1,
0xF0, 0xFF, 0x5B, 0x42, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x25, 0x03, 0x00
};
#endif
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
static struct timer_desc *logTmPtr; static struct timer_desc *logTmPtr;
@@ -375,6 +416,10 @@ void ScuTimer_IntrHandler(void *context)
{ {
// Refresh log // Refresh log
Phy_RefreshHwSate(phyInstPtr); Phy_RefreshHwSate(phyInstPtr);
if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
{
Phy_UpdateLogging(phyInstPtr);
}
if (Mpc_IsEnable(mpcDescPtr)) if (Mpc_IsEnable(mpcDescPtr))
{ {
@@ -382,6 +427,16 @@ void ScuTimer_IntrHandler(void *context)
{ {
DBG_ERROR("Failed to apply remote test.\n"); DBG_ERROR("Failed to apply remote test.\n");
} }
#ifdef APP_EMULATE_DATA
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateSendPayload(testDataFlj, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_UpdateSendPayload(testDataLj, PAYLOAD_LEN_LJ_TX);
}
#endif
} }
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance); XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
@@ -443,7 +498,7 @@ int main(void)
} }
/* Physical Layer Initialize */ /* Physical Layer Initialize */
Status = Phy_InstInit(&phyInstPtr, &phyConfig); Status = Phy_Init(&phyInstPtr, &phyConfig);
if (Status == SUCCESS) if (Status == SUCCESS)
{ {
DBG_PRINT("Physical layer Init SUCCESS! \n"); DBG_PRINT("Physical layer Init SUCCESS! \n");
+38 -35
View File
@@ -151,13 +151,14 @@ static int32_t Mpc_GenSelfTestRsp(MPC *instPtr)
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
MPC_HW_FRAME *mpcRsp; MPC_HW_FRAME *mpcRsp;
uint8_t *msg; uint8_t *msg;
if (instPtr->isEnable == false) if (Mpc_IsEnable(instPtr) == false)
{ {
DBG_ERROR("System is not enabled!\n"); DBG_ERROR("System is not enabled!\n");
return EIGNORE; return EIGNORE;
} }
mpcRsp = malloc(sizeof(MPC_HW_FRAME)); mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL) { if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n"); DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM; return ENOMEM;
} }
@@ -169,13 +170,13 @@ static int32_t Mpc_GenSelfTestRsp(MPC *instPtr)
msg[WD_CMD] = CMD_SELF_TEST; msg[WD_CMD] = CMD_SELF_TEST;
msg[WD_PRD] = MY_PRD_ID; msg[WD_PRD] = MY_PRD_ID;
SysMonitor_GetHardwareStatus(hwStatsPtr); SysMonitor_GetHardwareStatus(hwStatsPtr);
if (linkInstPtr->isEnable == false) if (Mpc_IsEnable(instPtr))
{ {
msg[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR; msg[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR;
} }
else else
{ {
msg[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR; msg[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR;
} }
// apply status and omit 2 bytes of overhead. // apply status and omit 2 bytes of overhead.
memcpy(msg + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN); memcpy(msg + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN);
@@ -201,47 +202,49 @@ static int32_t Mpc_SystemConfig(MPC *instPtr, uint8_t *msg)
if (msg[WD_MODE_CMD] == MODE_CMD_HEAD) if (msg[WD_MODE_CMD] == MODE_CMD_HEAD)
{ {
// omit unnecessary reconfiguration // omit unnecessary reconfiguration
if (L2_GetNodeType(linkInstPtr) != L2_NODE_HEAD) reconfig = (L2_NODE_HEAD != L2_GetNodeType(linkInstPtr));
{ linkConfig.myType = L2_NODE_HEAD;
// head node config linkConfig.myId = 2;
linkConfig.myType = L2_NODE_HEAD;
linkConfig.myId = 1;
reconfig = true;
}
} }
else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER ) else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER)
{ {
// omit unnecessary reconfiguration // omit unnecessary reconfiguration
if (L2_GetNodeType(linkInstPtr) != L2_NODE_MEMBER) reconfig = (L2_NODE_MEMBER != L2_GetNodeType(linkInstPtr));
{ linkConfig.myType = L2_NODE_MEMBER;
// member node config linkConfig.myId = 2;
linkConfig.myType = L2_NODE_MEMBER;
linkConfig.myId = 2;
reconfig = true;
}
} }
else else
{ {
// Ignore current command // Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X", DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_MODE_CMD, msg[WD_MODE_CMD]); WD_MODE_CMD, msg[WD_MODE_CMD]);
return EPARAM; return EIGNORE;
} }
if(msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER) if (msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{ {
// high power config // high power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
if (reconfig == true || !Mpc_IsEnable(instPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true; instPtr->isEnable = true;
} }
else if(msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER) else if (msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{ {
// low power config // low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
if (reconfig == true || !Mpc_IsEnable(instPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true; instPtr->isEnable = true;
} }
else if(msg[WD_EN_CMD] == EN_CMD_SILENT) else if (msg[WD_EN_CMD] == EN_CMD_SILENT)
{ {
// silence config // silence config
// TODO: better approach? // TODO: better approach?
@@ -256,20 +259,18 @@ static int32_t Mpc_SystemConfig(MPC *instPtr, uint8_t *msg)
} }
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL); Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
} }
if (reconfig == true) else
{ {
Linklayer_Reconfig(linkInstPtr, &linkConfig); // Ignore current command
} DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
if (instPtr->isEnable == true) WD_EN_CMD, msg[WD_EN_CMD]);
{ return EIGNORE;
Linklayer_Start(linkInstPtr);
} }
instPtr->mpcLog.lastConfig[0] = msg[WD_MODE_CMD]; instPtr->mpcLog.lastConfig[0] = msg[WD_MODE_CMD];
instPtr->mpcLog.lastConfig[1] = msg[WD_EN_CMD]; instPtr->mpcLog.lastConfig[1] = msg[WD_EN_CMD];
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Initialize MPC instance. * @brief Initialize MPC instance.
@@ -371,13 +372,14 @@ int32_t Mpc_PendRemoteTest(MPC *instPtr)
{ {
MPC_HW_FRAME *mpcRsp; MPC_HW_FRAME *mpcRsp;
uint8_t *msg; uint8_t *msg;
if (instPtr->isEnable == false) if (!Mpc_IsEnable(instPtr))
{ {
DBG_ERROR("System is not enabled!\n"); DBG_ERROR("System is not enabled!\n");
return EIGNORE; return EIGNORE;
} }
mpcRsp = malloc(sizeof(MPC_HW_FRAME)); mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL) { if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n"); DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM; return ENOMEM;
} }
@@ -407,7 +409,8 @@ int32_t Mpc_PendRemoteTest(MPC *instPtr)
memcpy(msg + WD_PHY_LOG, &(instPtr->phyLog), WD_PHY_LOG_LEN); memcpy(msg + WD_PHY_LOG, &(instPtr->phyLog), WD_PHY_LOG_LEN);
memcpy(msg + WD_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_HARDWARE_ST_LEN); memcpy(msg + WD_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_HARDWARE_ST_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false){ if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
free(mpcRsp); free(mpcRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n"); DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE; return EQUEUE;
@@ -24,7 +24,7 @@
/* Definitions for interface TMC */ /* Definitions for interface TMC */
#define XPAR_TMC_BASEADDR 0x43C30000 #define XPAR_TMC_BASEADDR 0x43C30000
#define XPAR_TMC_HIGHADDR 0x43C3FFFF #define XPAR_TMC_HIGHADDR 0x43C30FFF
#include "xparameters_ps.h" #include "xparameters_ps.h"
@@ -62,22 +62,22 @@
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */ /* Definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID 1U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID 1U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH 32U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_FAULT_INJECT 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_UE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_STATUS_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_COUNTER_WIDTH 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_REGISTER 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS 0U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR 0x40004000U #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_BASEADDR 0x40004000U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR 0x40005FFFU #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_HIGHADDR 0x40005FFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */ /* Definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */
@@ -93,7 +93,7 @@
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40000000U #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40000000U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40001FFFU #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40000FFFU
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
@@ -111,7 +111,7 @@
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40002000U #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40002000U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40003FFFU #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40002FFFU
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU #define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
@@ -135,8 +135,8 @@
#define XPAR_BRAM_0_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_BRAM_0_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_0_CTRL_HIGHADDR 0xFFFFFFFEU #define XPAR_BRAM_0_CTRL_HIGHADDR 0xFFFFFFFEU
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */ /* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL */
#define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID #define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
#define XPAR_BRAM_1_DATA_WIDTH 32U #define XPAR_BRAM_1_DATA_WIDTH 32U
#define XPAR_BRAM_1_ECC 0U #define XPAR_BRAM_1_ECC 0U
#define XPAR_BRAM_1_FAULT_INJECT 0U #define XPAR_BRAM_1_FAULT_INJECT 0U
@@ -165,7 +165,7 @@
#define XPAR_BRAM_2_ECC_ONOFF_RESET_VALUE 0U #define XPAR_BRAM_2_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_2_WRITE_ACCESS 0U #define XPAR_BRAM_2_WRITE_ACCESS 0U
#define XPAR_BRAM_2_BASEADDR 0x40000000U #define XPAR_BRAM_2_BASEADDR 0x40000000U
#define XPAR_BRAM_2_HIGHADDR 0x40001FFFU #define XPAR_BRAM_2_HIGHADDR 0x40000FFFU
#define XPAR_BRAM_2_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_BRAM_2_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_2_CTRL_HIGHADDR 0xFFFFFFFEU #define XPAR_BRAM_2_CTRL_HIGHADDR 0xFFFFFFFEU
@@ -182,7 +182,7 @@
#define XPAR_BRAM_3_ECC_ONOFF_RESET_VALUE 0U #define XPAR_BRAM_3_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_3_WRITE_ACCESS 0U #define XPAR_BRAM_3_WRITE_ACCESS 0U
#define XPAR_BRAM_3_BASEADDR 0x40002000U #define XPAR_BRAM_3_BASEADDR 0x40002000U
#define XPAR_BRAM_3_HIGHADDR 0x40003FFFU #define XPAR_BRAM_3_HIGHADDR 0x40002FFFU
#define XPAR_BRAM_3_CTRL_BASEADDR 0xFFFFFFFFU #define XPAR_BRAM_3_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_3_CTRL_HIGHADDR 0xFFFFFFFEU #define XPAR_BRAM_3_CTRL_HIGHADDR 0xFFFFFFFEU
@@ -346,7 +346,7 @@
/* Definitions for peripheral SYSTEMBUS */ /* Definitions for peripheral SYSTEMBUS */
#define XPAR_SYSTEMBUS_BASEADDR 0x43C10000 #define XPAR_SYSTEMBUS_BASEADDR 0x43C10000
#define XPAR_SYSTEMBUS_HIGHADDR 0x43C11FFF #define XPAR_SYSTEMBUS_HIGHADDR 0x43C10FFF
/******************************************************************/ /******************************************************************/
@@ -62,23 +62,23 @@ XBram_Config XBram_ConfigTable[] =
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR
}, },
{ {
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DATA_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_FAULT_INJECT,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_FAILING_REGISTERS,
0, 0,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_UE_FAILING_REGISTERS,
0, 0,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_STATUS_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_COUNTER_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_REGISTER,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_RESET_VALUE,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_WRITE_ACCESS,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_HIGHADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR, XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_HIGHADDR
}, },
{ {
XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID, XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID,
+1 -1
View File
@@ -33,7 +33,7 @@ END
BEGIN DRIVER BEGIN DRIVER
PARAMETER DRIVER_NAME = bram PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 4.3 PARAMETER DRIVER_VER = 4.3
PARAMETER HW_INSTANCE = phy_data_interface_ant_info_bram_ctrl PARAMETER HW_INSTANCE = phy_data_interface_ant_config_bram_ctrl
END END
BEGIN DRIVER BEGIN DRIVER
+2 -2
View File
@@ -10,7 +10,7 @@
* History: * History:
* [2021-04-28]: Initial edition. * [2021-04-28]: Initial edition.
* *
* Copyright(c) 2021 Beijing Institute of Technology. * Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking * Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
@@ -56,7 +56,7 @@
#define PHY_BASEADDR XPAR_PHYC_BASEADDR #define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_FORMING_ENABLE #define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs // -- Antenna Bram Configs
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID #define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
#define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID #define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID
// -- Buffers // -- Buffers
#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID #define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
@@ -697,7 +697,6 @@ int32_t spi_engine_write_and_read(struct spi_desc *desc,
uint8_t *data, uint8_t *data,
uint16_t bytes_number) uint16_t bytes_number)
{ {
uint8_t i;
uint8_t word_len; uint8_t word_len;
uint8_t words_number; uint8_t words_number;
int32_t ret; int32_t ret;
+49 -56
View File
@@ -1,33 +1,25 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: A simple circular FIFO bounded queue * @file circ_queue.h
* @author FanHao ([email protected])
* @brief A simple circular FIFO bounded queue
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/chrismerck/rpa_queue.git
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
* *
* Author: Fan Hao ******************************************************************************/
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao /**
* LastEditTime: 2023-02-23 12:53 * @addtogroup Utility
* Revisions: Rev 0.0 * @{
* History: */
* [2023-02-23]: Initial Version.
* /**
* Copyright(c) 2023 Beijing Institute of Technology. * @defgroup CircularQueue
* Lab of Communication and Networking * @{
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git */
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#ifndef CIRC_QUEUE_H #ifndef CIRC_QUEUE_H
#define CIRC_QUEUE_H #define CIRC_QUEUE_H
@@ -36,76 +28,77 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
/** /**
* opaque structure * @struct CIRC_QUEUE
* @brief Circular queue Instance
*/ */
typedef struct { typedef struct
void **data; {
volatile uint32_t nelts; /**< # elements */ void **data;
uint32_t in; /**< next empty location */ volatile uint32_t nelts; ///< number of elements
uint32_t out; /**< next filled location */ uint32_t in; ///< next empty location
uint32_t bounds;/**< max size of queue */ uint32_t out; ///< next filled location
uint32_t bounds; ///< max size of queue
} CIRC_QUEUE; } CIRC_QUEUE;
/** /**
* create a FIFO queue * @brief create a FIFO queue
* @param queue The new queue * @param queue The new queue
* @param queue_capacity maximum size of the queue * @param queue_capacity maximum size of the queue
* @param a pool to allocate queue from * @param a pool to allocate queue from
*/ */
bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity); bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity);
/** free queue memory -- call after destroy /**
* @brief free queue memory -- call after destroy
* @note we do not free in destroy() to follow pthreads convention * @note we do not free in destroy() to follow pthreads convention
*/ */
void CircQueueFree(CIRC_QUEUE * queue); void CircQueueFree(CIRC_QUEUE *queue);
/** /**
* Detects when the CIRC_QUEUE is full. This utility function is expected * @brief Detects when the CIRC_QUEUE is full. This utility function is expected
* to be called from within critical sections, and is not threadsafe. * to be called from within critical sections, and is not threadsafe.
*/ */
bool isCircQueueFull(CIRC_QUEUE *queue); bool isCircQueueFull(CIRC_QUEUE *queue);
/** /**
* Detects when the CIRC_QUEUE is empty. This utility function is expected * @brief Detects when the CIRC_QUEUE is empty. This utility function is expected
* to be called from within critical sections, and is not threadsafe. * to be called from within critical sections, and is not threadsafe.
*/ */
bool isCircQueueEmpty(CIRC_QUEUE *queue); bool isCircQueueEmpty(CIRC_QUEUE *queue);
/** /**
* push/add an object to the queue, blocking if the queue is already full * @brief push/add an object to the queue, blocking if the queue is already full
* *
* @param queue the queue * @param queue the queue
* @param data the data * @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again) * @return RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF the queue has been terminated * @return RPA_EOF the queue has been terminated
* @returns RPA_SUCCESS on a successful push * @return RPA_SUCCESS on a successful push
*/ */
bool CircQueuePush(CIRC_QUEUE *queue, void *data); bool CircQueuePush(CIRC_QUEUE *queue, void *data);
/** /**
* pop/get an object from the queue, blocking if the queue is already empty * @brief pop/get an object from the queue, blocking if the queue is already empty
* *
* @param queue the queue * @param queue the queue
* @param data the data * @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again) * @return RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF if the queue has been terminated * @return RPA_EOF if the queue has been terminated
* @returns RPA_SUCCESS on a successful pop * @return RPA_SUCCESS on a successful pop
*/ */
bool CircQueuePop(CIRC_QUEUE *queue, void **data); bool CircQueuePop(CIRC_QUEUE *queue, void **data);
/** /**
* returns the size of the queue. * @brief returns the size of the queue.
* *
* @warning this is not threadsafe, and is intended for reporting/monitoring
* of the queue.
* @param queue the queue * @param queue the queue
* @returns the size of the queue * @return the size of the queue
*/ */
uint32_t CircQueueSize(CIRC_QUEUE *queue); uint32_t CircQueueSize(CIRC_QUEUE *queue);
#endif /* CIRC_QUEUE_H */ #endif /* CIRC_QUEUE_H */
/** @} CircularQueue*/
/** @} Utility*/
+98 -78
View File
@@ -1,9 +1,25 @@
/*****************************************************************************/
/**
* @file clist.h
* @author FanHao ([email protected])
* @brief A basic list data structure
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/clibs/list
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
// /**
// clist.h * @addtogroup Utility
// * @{
// Copyright (c) 2010 TJ Holowaychuk <[email protected]> */
//
/**
* @defgroup cList
* @{
*/
#ifndef __CLIST_H__ #ifndef __CLIST_H__
#define __CLIST_H__ #define __CLIST_H__
@@ -16,103 +32,107 @@ extern "C"
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
/* /**
* clist_t iterator direction. * @enum clist_direction_t
*/ * @brief clist_t iterator direction.
*/
typedef enum
{
LIST_HEAD,
LIST_TAIL
} clist_direction_t;
typedef enum /**
{ * @struct clist_node_t
LIST_HEAD, * @brief clist_t node struct.
LIST_TAIL */
} clist_direction_t; typedef struct clist_node
{
struct clist_node *prev; ///< previous node
struct clist_node *next; ///< next node
void *val;
} clist_node_t;
/* /**
* clist_t node struct. * @struct clist_t
*/ * @brief clist_t struct.
*/
typedef struct
{
clist_node_t *head; ///< first node
clist_node_t *tail; ///< last node
uint32_t len; ///< list length
void (*free)(void *val); ///< node free function handle
int8_t (*compare)(void *a, void *b); ///< node compare function handle
} clist_t;
typedef struct clist_node /**
{ * @struct clist_iterator_t
struct clist_node *prev; * @brief clist_t iterator struct.
struct clist_node *next; */
void *val; typedef struct
} clist_node_t; {
clist_node_t *next; ///< next element
clist_direction_t direction; ///< iter direction
} clist_iterator_t;
/* // Node prototypes.
* clist_t struct.
*/
typedef struct clist_node_t *
{ clist_node_new(void *val);
clist_node_t *head;
clist_node_t *tail;
uint32_t len;
void (*free)(void *val);
int8_t (*compare)(void *a, void *b);
} clist_t;
/* // clist_t prototypes.
* clist_t iterator struct.
*/
typedef struct clist_t *
{ clist_new(void);
clist_node_t *next;
clist_direction_t direction;
} clist_iterator_t;
// Node prototypes. clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node);
clist_node_t * clist_node_t *
clist_node_new(void *val); clist_lpush(clist_t *self, clist_node_t *node);
// clist_t prototypes. clist_node_t *
clist_find(clist_t *self, void *val);
clist_t * clist_node_t *
clist_new(void); clist_at(clist_t *self, int index);
clist_node_t * clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node); clist_rpop(clist_t *self);
clist_node_t * clist_node_t *
clist_lpush(clist_t *self, clist_node_t *node); clist_lpop(clist_t *self);
clist_node_t * void
clist_find(clist_t *self, void *val); clist_remove(clist_t *self, clist_node_t *node);
clist_node_t * void
clist_at(clist_t *self, int index); clist_clear(clist_t *self);
clist_node_t * void
clist_rpop(clist_t *self); clist_destroy(clist_t *self);
clist_node_t * // clist_t iterator prototypes.
clist_lpop(clist_t *self);
void clist_iterator_t *
clist_remove(clist_t *self, clist_node_t *node); clist_iterator_new(clist_t *list, clist_direction_t direction);
void clist_iterator_t *
clist_clear(clist_t *self); clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction);
void clist_node_t *
clist_destroy(clist_t *self); clist_iterator_next(clist_iterator_t *self);
// clist_t iterator prototypes. void
clist_iterator_destroy(clist_iterator_t *self);
clist_iterator_t *
clist_iterator_new(clist_t *list, clist_direction_t direction);
clist_iterator_t *
clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction);
clist_node_t *
clist_iterator_next(clist_iterator_t *self);
void
clist_iterator_destroy(clist_iterator_t *self);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* __CLIBS_LIST_H__ */ #endif /* __CLIBS_LIST_H__ */
/** @} cList*/
/** @} Utility*/
+16 -15
View File
@@ -1,20 +1,19 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Common definitions * @file common.h
* * @author FanHao ([email protected])
* Date: 2023-12-21 16:32 * @brief Common macros
* LastEditors: Fan Hao * @version 0.0
* LastEditTime: 2022-07-16 17:13 * @date 2022-07-16
* Revisions: Rev 0.1 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* History: * Lab of Communication and Network
* [2023-12-21]: Ensure the code conform ISO C11 standard.
* [2022-07-16]: New branch for Dijian.
* [2021-11-16]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup COMMON_MACRO
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#ifndef __COMMON_H_ #ifndef __COMMON_H_
#define __COMMON_H_ #define __COMMON_H_
@@ -47,8 +46,8 @@
#endif #endif
#if _DEBUG_LEVEL >= 1 #if _DEBUG_LEVEL >= 1
#define DBG_ERROR(...) __PRINT_BLOCK( \ #define DBG_ERROR(...) __PRINT_BLOCK( \
printf("in "__FILE__ \ printf("in "__FILE__ \
":%d [error]\t", \ ":%d [error]\t", \
__LINE__); \ __LINE__); \
printf(__VA_ARGS__);) printf(__VA_ARGS__);)
#endif #endif
@@ -90,3 +89,5 @@
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
void AppAssert(const char *file, int line); void AppAssert(const char *file, int line);
#endif /* __COMMON_H_ */ #endif /* __COMMON_H_ */
/** @} */
+22 -13
View File
@@ -1,19 +1,19 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Error code definitions. * @file common.h
* @author FanHao ([email protected])
* @brief Common error numbers
* @version 0.0
* @date 2022-06-18
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
* *
* Author: Fan Hao ******************************************************************************/
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao /**
* LastEditTime: 2022-06-18 17:12 * @addtogroup COMMON_MACRO
* Revisions: Rev 0.0 * @{
* History: */
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef SRC_ERROR_H_ #ifndef SRC_ERROR_H_
#define SRC_ERROR_H_ #define SRC_ERROR_H_
@@ -24,6 +24,11 @@
/********************** Macros and Constants Definitions **********************/ /********************** Macros and Constants Definitions **********************/
/******************************************************************************/ /******************************************************************************/
/**
* @name ERRORNO
* @{
*/
#ifdef SUCCESS #ifdef SUCCESS
#undef SUCCESS #undef SUCCESS
#endif #endif
@@ -45,3 +50,7 @@
#define IS_ERR_VALUE(x) ((x) != SUCCESS) #define IS_ERR_VALUE(x) ((x) != SUCCESS)
#endif // ERROR_H_ #endif // ERROR_H_
/** @} ERRORNO*/
/** @} COMMON_MACRO*/
+18 -36
View File
@@ -1,41 +1,21 @@
/******************************************************************************* /*****************************************************************************/
* @file util.h /**
* @brief Implementation of utility functions. * @file util.h
* @author DBogdan (dragos.bogdan@analog.com) * @author FanHao (hao_fan_bit_ee@163.com)
******************************************************************************** * @brief Utility functions header file
* Copyright 2018(c) Analog Devices, Inc. * @version 0.0
* @date 2023-05-06
* *
* All rights reserved. * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
* *
* Redistribution and use in source and binary forms, with or without ******************************************************************************/
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright /**
* notice, this list of conditions and the following disclaimer. * @defgroup Utility
* - Redistributions in binary form must reproduce the above copyright * @{
* notice, this list of conditions and the following disclaimer in */
* the documentation and/or other materials provided with the
* distribution.
* - Neither the name of Analog Devices, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* - The use of this software may or may not infringe the patent rights
* of one or more patent holders. This license does not release you
* from the requirement that you obtain separate licenses from these
* patent holders to use this software.
* - Use of the software either in source or binary form, must be run
* on or directly connected to an Analog Devices Inc. component.
*
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __UTIL_H_ #ifndef __UTIL_H_
#define __UTIL_H_ #define __UTIL_H_
@@ -193,3 +173,5 @@ bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_
int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal); int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal);
bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly); bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
#endif // __UTIL_H_ #endif // __UTIL_H_
/** @} */
+3 -3
View File
@@ -23,9 +23,9 @@ _UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
MEMORY MEMORY
{ {
phy_data_interface_rx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x2000 phy_data_interface_rx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x1000
phy_data_interface_tx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40002000, LENGTH = 0x2000 phy_data_interface_tx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40002000, LENGTH = 0x1000
phy_data_interface_ant_info_bram_ctrl_Mem0 : ORIGIN = 0x40004000, LENGTH = 0x2000 phy_data_interface_ant_config_bram_ctrl_Mem0 : ORIGIN = 0x40004000, LENGTH = 0x2000
phy_data_interface_ant_beam_bram_ctrl_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x1000 phy_data_interface_ant_beam_bram_ctrl_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x1000
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000 ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000 ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000
+7 -2
View File
@@ -10,7 +10,7 @@
* History: * History:
* [2023-05-07]: Initial edition. * [2023-05-07]: Initial edition.
* *
* Copyright(c) 2021 Beijing Institute of Technology. * Copyright(c) 2024 Beijing Institute of Technology.
* *
******************************************************************************/ ******************************************************************************/
@@ -360,6 +360,11 @@ void ScuTimer_IntrHandler(void *context)
{ {
// Refresh log // Refresh log
Phy_RefreshHwSate(phyInstPtr); Phy_RefreshHwSate(phyInstPtr);
if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
{
Phy_UpdateLogging(phyInstPtr);
}
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance); XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
} }
else else
@@ -420,7 +425,7 @@ int main(void)
} }
/* Physical Layer Initialize */ /* Physical Layer Initialize */
Status = Phy_InstInit(&phyInstPtr, &phyConfig); Status = Phy_Init(&phyInstPtr, &phyConfig);
if (Status == SUCCESS) if (Status == SUCCESS)
{ {
DBG_PRINT("Physical layer Init SUCCESS! \n"); DBG_PRINT("Physical layer Init SUCCESS! \n");
@@ -1,19 +1,25 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Functions for framing operations. * @file framing.h
* @author FanHao ([email protected])
* @brief DF Linklayer framing functions.
* @version 0.0
* @date 2023-05-06
* *
* Date: 2022-07-16 14:17 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditors: Fan Hao * Lab of Communication and Network
* LastEditTime: 2022-07-16 17:11
* Revisions: Rev 0.0
* History:
* [2022-07-16]: Description of modification.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Framing
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -177,3 +183,7 @@ bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType)
return false; return false;
} }
} }
/** @} LinkLayer_Framing*/
/** @} LinkLayer*/
@@ -1,8 +1,28 @@
// /*****************************************************************************/
// Copyright (C) 2020 OpenSim Ltd. /**
// * @file coord.c
// SPDX-License-Identifier: LGPL-3.0-or-later * @author FanHao ([email protected])
// * @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_Coord
* @{
*/
#include <math.h> #include <math.h>
#include "coord.h" #include "coord.h"
@@ -17,132 +37,132 @@ const COORD COORD_Z_AXIS = {0.0, 0.0, 1.0};
/** @brief Subtracts two coordinate vectors. */ /** @brief Subtracts two coordinate vectors. */
COORD Coord_Sub(COORD a, COORD b) COORD Coord_Sub(COORD a, COORD b)
{ {
COORD ret; COORD ret;
ret.x = a.x - b.x; ret.x = a.x - b.x;
ret.y = a.y - b.y; ret.y = a.y - b.y;
ret.z = a.z - b.z; ret.z = a.z - b.z;
return ret; return ret;
} }
/** @brief Adds two coordinate vectors. */ /** @brief Adds two coordinate vectors. */
COORD Coord_Add(COORD a, COORD b) COORD Coord_Add(COORD a, COORD b)
{ {
COORD ret; COORD ret;
ret.x = a.x + b.x; ret.x = a.x + b.x;
ret.y = a.y + b.y; ret.y = a.y + b.y;
ret.z = a.z + b.z; ret.z = a.z + b.z;
return ret; return ret;
} }
/** @brief Multiplies a coordinate vector by a real number. */ /** @brief Multiplies a coordinate vector by a real number. */
void Coord_ScalarMult(COORD *a, double t) void Coord_ScalarMult(COORD *a, double t)
{ {
a->x *= t; a->x *= t;
a->y *= t; a->y *= t;
a->z *= t; a->z *= t;
} }
/** @brief Multiplies a coordinate vector by a real number. */ /** @brief Multiplies a coordinate vector by a real number. */
COORD Coord_GetScalarMult(COORD a, double t) COORD Coord_GetScalarMult(COORD a, double t)
{ {
COORD ret; COORD ret;
ret.x = a.x * t; ret.x = a.x * t;
ret.y = a.y * t; ret.y = a.y * t;
ret.z = a.z * t; ret.z = a.z * t;
return ret; return ret;
} }
/** @brief Divides a coordinate vector by a real number. */ /** @brief Divides a coordinate vector by a real number. */
void Coord_ScalarDiv(COORD *a, double t) void Coord_ScalarDiv(COORD *a, double t)
{ {
a->x /= t; a->x /= t;
a->y /= t; a->y /= t;
a->z /= t; a->z /= t;
} }
/** @brief Divides a coordinate vector by a real number. */ /** @brief Divides a coordinate vector by a real number. */
COORD Coord_GetScalarDiv(COORD a, double t) COORD Coord_GetScalarDiv(COORD a, double t)
{ {
COORD ret; COORD ret;
ret.x = a.x / t; ret.x = a.x / t;
ret.y = a.y / t; ret.y = a.y / t;
ret.z = a.z / t; ret.z = a.z / t;
return ret; return ret;
} }
/** @brief Dot product. */ /** @brief Dot product. */
inline double Coord_Dot(COORD a, COORD b) inline double Coord_Dot(COORD a, COORD b)
{ {
return (a.x * b.x + a.y * b.y + a.z * b.z); return (a.x * b.x + a.y * b.y + a.z * b.z);
} }
/** @brief Cross product. */ /** @brief Cross product. */
COORD Coord_Cross(COORD a, COORD b) COORD Coord_Cross(COORD a, COORD b)
{ {
COORD ret; COORD ret;
ret.x = a.y * b.z - a.z * b.y; ret.x = a.y * b.z - a.z * b.y;
ret.y = a.z * b.x - a.x * b.z; ret.y = a.z * b.x - a.x * b.z;
ret.z = a.x * b.y - a.y * b.x; ret.z = a.x * b.y - a.y * b.x;
return ret; return ret;
} }
/** @brief Multiplies two coordinate vector in elementwise. */ /** @brief Multiplies two coordinate vector in elementwise. */
COORD Coord_ElementwiseMult(COORD a, COORD b) COORD Coord_ElementwiseMult(COORD a, COORD b)
{ {
COORD ret; COORD ret;
ret.x = a.x * b.x; ret.x = a.x * b.x;
ret.y = a.y * b.y; ret.y = a.y * b.y;
ret.z = a.z * b.z; ret.z = a.z * b.z;
return ret; return ret;
} }
/** @brief Divides two coordinate vector in elementwise. */ /** @brief Divides two coordinate vector in elementwise. */
COORD Coord_ElementwiseDiv(COORD a, COORD b) COORD Coord_ElementwiseDiv(COORD a, COORD b)
{ {
COORD ret; COORD ret;
ret.x = a.x / b.x; ret.x = a.x / b.x;
ret.y = a.y / b.y; ret.y = a.y / b.y;
ret.z = a.z / b.z; ret.z = a.z / b.z;
return ret; return ret;
} }
/** @brief Calculate a coordinate vector length^2 (omits calling square root). */ /** @brief Calculate a coordinate vector length^2 (omits calling square root). */
double Coord_SquareLength(COORD a) double Coord_SquareLength(COORD a)
{ {
return (a.x * a.x + a.y * a.y + a.z * a.z); return (a.x * a.x + a.y * a.y + a.z * a.z);
} }
/** @brief Calculate a coordinate vector length. */ /** @brief Calculate a coordinate vector length. */
double Coord_Length(COORD a) double Coord_Length(COORD a)
{ {
return sqrt(Coord_SquareLength(a)); return sqrt(Coord_SquareLength(a));
} }
/** @brief Calculate two coordinates' distance. */ /** @brief Calculate two coordinates' distance. */
double Coord_Distance(COORD a, COORD b) double Coord_Distance(COORD a, COORD b)
{ {
return Coord_Length(Coord_Sub(a, b)); return Coord_Length(Coord_Sub(a, b));
} }
/** @brief Normalize coordinate vector. */ /** @brief Normalize coordinate vector. */
void Coord_Normalize(COORD *a) void Coord_Normalize(COORD *a)
{ {
Coord_ScalarDiv(a, Coord_Length(*a)); Coord_ScalarDiv(a, Coord_Length(*a));
} }
/** @brief Normalize coordinate vector. */ /** @brief Normalize coordinate vector. */
COORD Coord_GetNormalized(COORD a) COORD Coord_GetNormalized(COORD a)
{ {
Coord_Normalize(&a); Coord_Normalize(&a);
return a; return a;
} }
/** @brief Returns the angle between the two vectors. */ /** @brief Returns the angle between the two vectors. */
double Coord_Angle(COORD a, COORD b) double Coord_Angle(COORD a, COORD b)
{ {
Coord_Normalize(&a); Coord_Normalize(&a);
Coord_Normalize(&b); Coord_Normalize(&b);
return acos(Coord_Dot(a, b)); return acos(Coord_Dot(a, b));
} }
// Additional Coordinates convert // Additional Coordinates convert
@@ -150,62 +170,68 @@ double Coord_Angle(COORD a, COORD b)
/** @brief Convert coordinate from Launch coordinate system to ECEF. */ /** @brief Convert coordinate from Launch coordinate system to ECEF. */
COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda) COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda)
{ {
COORD ret; COORD ret;
double sinA, cosA, sinB, cosB, sinL, cosL; double sinA, cosA, sinB, cosB, sinL, cosL;
double S11, S12, S13, S21, S22, S23, S31, S32, S33; double S11, S12, S13, S21, S22, S23, S31, S32, S33;
sinA = sin(A); sinA = sin(A);
cosA = cos(A); cosA = cos(A);
sinB = sin(B); sinB = sin(B);
cosB = cos(B); cosB = cos(B);
sinL = sin(lambda); sinL = sin(lambda);
cosL = cos(lambda); cosL = cos(lambda);
S11 = -sinA * sinL - cosA * sinB * cosL; S11 = -sinA * sinL - cosA * sinB * cosL;
S12 = cosB * cosL; S12 = cosB * cosL;
S13 = -cosA * sinL + sinA * sinB * cosL; S13 = -cosA * sinL + sinA * sinB * cosL;
S21 = sinA * cosL - cosA * sinB * sinL; S21 = sinA * cosL - cosA * sinB * sinL;
S22 = cosB * sinL; S22 = cosB * sinL;
S23 = cosA * cosL + sinA * sinB * sinL; S23 = cosA * cosL + sinA * sinB * sinL;
S31 = cosA * cosB; S31 = cosA * cosB;
S32 = sinB; S32 = sinB;
S33 = -sinA * cosB; S33 = -sinA * cosB;
ret.x = p.x * (S11 + S21 + S31) + o.x; ret.x = p.x * (S11 + S21 + S31) + o.x;
ret.y = p.y * (S12 + S22 + S32) + o.y; ret.y = p.y * (S12 + S22 + S32) + o.y;
ret.z = p.z * (S13 + S23 + S33) + o.z; ret.z = p.z * (S13 + S23 + S33) + o.z;
return ret; return ret;
} }
/** @brief Convert coordinate from launch coordinate system to Inertia coordinate system. */ /** @brief Convert coordinate from launch coordinate system to Inertia coordinate system. */
COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, double t) COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, double t)
{ {
COORD ret; COORD ret;
double OmgX, OmgY, OmgZ, sinwet, coswet; double OmgX, OmgY, OmgZ, sinwet, coswet;
double M11, M12, M13, M21, M22, M23, M31, M32, M33; double M11, M12, M13, M21, M22, M23, M31, M32, M33;
OmgX = cos(A) * cos(B); OmgX = cos(A) * cos(B);
OmgY = sin(B); OmgY = sin(B);
OmgZ = -sin(A) * cos(B); OmgZ = -sin(A) * cos(B);
sinwet = sin(we * t); sinwet = sin(we * t);
coswet = cos(we * t); coswet = cos(we * t);
M11 = 1 - (1 - OmgX * OmgX) * (1 - coswet); M11 = 1 - (1 - OmgX * OmgX) * (1 - coswet);
M12 = OmgX * OmgY * (1 - coswet) + OmgZ * sinwet; M12 = OmgX * OmgY * (1 - coswet) + OmgZ * sinwet;
M13 = OmgX * OmgZ * (1 - coswet) - OmgY * sinwet; M13 = OmgX * OmgZ * (1 - coswet) - OmgY * sinwet;
M21 = OmgY * OmgX * (1 - coswet) - OmgZ * sinwet; M21 = OmgY * OmgX * (1 - coswet) - OmgZ * sinwet;
M22 = 1 - (1 - OmgY * OmgY) * (1 - coswet); M22 = 1 - (1 - OmgY * OmgY) * (1 - coswet);
M23 = OmgY * OmgZ * (1 - coswet) + OmgX * sinwet; M23 = OmgY * OmgZ * (1 - coswet) + OmgX * sinwet;
M31 = OmgZ * OmgX * (1 - coswet) + OmgY * sinwet; M31 = OmgZ * OmgX * (1 - coswet) + OmgY * sinwet;
M32 = OmgZ * OmgY * (1 - coswet) - OmgX * sinwet; M32 = OmgZ * OmgY * (1 - coswet) - OmgX * sinwet;
M33 = 1 - (1 - OmgZ * OmgZ) * (1 - coswet); M33 = 1 - (1 - OmgZ * OmgZ) * (1 - coswet);
ret.x = p.x * (M11 + M21 + M31) + o.x; ret.x = p.x * (M11 + M21 + M31) + o.x;
ret.y = p.y * (M12 + M22 + M32) + o.y; ret.y = p.y * (M12 + M22 + M32) + o.y;
ret.z = p.z * (M13 + M23 + M33) + o.z; ret.z = p.z * (M13 + M23 + M33) + o.z;
return ret; return ret;
} }
/** @} LinkLayerGeometry_Coord */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,25 +1,41 @@
// /*****************************************************************************/
// Copyright (C) 2020 OpenSim Ltd. /**
// * @file coord.h
// SPDX-License-Identifier: LGPL-3.0-or-later * @author FanHao ([email protected])
// * @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
#ifndef _COORD_H #ifndef _COORD_H
#define _COORD_H #define _COORD_H
/** /**
* @brief Structure for storing 3D coordinates. * @addtogroup LinkLayer
* * @{
* Some comparison and basic arithmetic operators are implemented.
*
* @ingroup utils
*/ */
/**
* @defgroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_Coord
* @{
*/
/**
* @struct COORD
* @brief Structure for storing 3D coordinates.
*/
typedef struct typedef struct
{ {
double x; double x;
double y; double y;
double z; double z;
} COORD; } COORD;
extern const COORD COORD_NIL; extern const COORD COORD_NIL;
@@ -78,3 +94,9 @@ COORD Coord_GetNormalized(COORD a);
double Coord_Angle(COORD a, COORD b); double Coord_Angle(COORD a, COORD b);
#endif #endif
/** @} LinkLayerGeometry_Coord */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,8 +1,29 @@
// /*****************************************************************************/
// Copyright (C) 2020 OpenSim Ltd. /**
// * @file eulerangles.c
// SPDX-License-Identifier: LGPL-3.0-or-later * @author FanHao ([email protected])
// * @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_EulerAngles
* @{
*/
#include <math.h> #include <math.h>
#include "eulerangles.h" #include "eulerangles.h"
@@ -13,49 +34,55 @@ const EULERANGLES EULERANGLES_ZERO = {0.0, 0.0, 0.0};
/** @brief Add two EulerAngles. */ /** @brief Add two EulerAngles. */
EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2) EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2)
{ {
EULERANGLES ret; EULERANGLES ret;
ret.alpha = e1.alpha + e2.alpha; ret.alpha = e1.alpha + e2.alpha;
ret.beta = e1.beta + e2.beta; ret.beta = e1.beta + e2.beta;
ret.gamma = e1.gamma + e2.gamma; ret.gamma = e1.gamma + e2.gamma;
return ret; return ret;
} }
/** @brief Subtracts two EulerAngles. */ /** @brief Subtracts two EulerAngles. */
EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2) EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2)
{ {
EULERANGLES ret; EULERANGLES ret;
ret.alpha = e1.alpha - e2.alpha; ret.alpha = e1.alpha - e2.alpha;
ret.beta = e1.beta - e2.beta; ret.beta = e1.beta - e2.beta;
ret.gamma = e1.gamma - e2.gamma; ret.gamma = e1.gamma - e2.gamma;
return ret; return ret;
} }
/** @brief Multiplies EulerAngles by a real number. */ /** @brief Multiplies EulerAngles by a real number. */
void EulerAngles_ScalarMult(EULERANGLES *e, double f) void EulerAngles_ScalarMult(EULERANGLES *e, double f)
{ {
e->alpha *= f; e->alpha *= f;
e->beta *= f; e->beta *= f;
e->gamma *= f; e->gamma *= f;
} }
/** @brief Multiplies EulerAngles by a real number. */ /** @brief Multiplies EulerAngles by a real number. */
EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f) EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f)
{ {
EulerAngles_ScalarMult(&e, f); EulerAngles_ScalarMult(&e, f);
return e; return e;
} }
/** @brief Normalize EulerAngles. */ /** @brief Normalize EulerAngles. */
void EulerAngles_Normalize(EULERANGLES *e) void EulerAngles_Normalize(EULERANGLES *e)
{ {
e->alpha = fmod(e->alpha, 2 * EUL_PI); e->alpha = fmod(e->alpha, 2 * EUL_PI);
e->beta = fmod(e->beta, 2 * EUL_PI); e->beta = fmod(e->beta, 2 * EUL_PI);
e->gamma = fmod(e->gamma, 2 * EUL_PI); e->gamma = fmod(e->gamma, 2 * EUL_PI);
} }
/** @brief Normalize EulerAngles. */ /** @brief Normalize EulerAngles. */
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e) EULERANGLES EulerAngles_GetNormalize(EULERANGLES e)
{ {
EulerAngles_Normalize(&e); EulerAngles_Normalize(&e);
return e; return e;
} }
/** @} LinkLayerGeometry_EulerAngles */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,3 +1,30 @@
/*****************************************************************************/
/**
* @file eulerangles.h
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_EulerAngles
* @{
*/
#ifndef __EULERANGLES_H #ifndef __EULERANGLES_H
#define __EULERANGLES_H #define __EULERANGLES_H
@@ -16,6 +43,11 @@
* rotation along the Y axis rotates Z into X (leans forward), positive rotation * rotation along the Y axis rotates Z into X (leans forward), positive rotation
* along the X axis rotates Y into Z (leans right). * along the X axis rotates Y into Z (leans right).
*/ */
/**
* @struct EULERANGLES
* @brief Structure for standard quaternion
*/
typedef struct typedef struct
{ {
double alpha; // unit rad double alpha; // unit rad
@@ -53,3 +85,9 @@ void EulerAngles_Normalize(EULERANGLES *e);
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e); EULERANGLES EulerAngles_GetNormalize(EULERANGLES e);
#endif #endif
/** @} LinkLayerGeometry_EulerAngles */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,8 +1,29 @@
// /*****************************************************************************/
// Copyright (C) 2014 OpenSim Ltd. /**
// * @file quaternion.c
// SPDX-License-Identifier: LGPL-3.0-or-later * @author FanHao ([email protected])
// * @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_Quaternion
* @{
*/
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
@@ -13,14 +34,14 @@
typedef union typedef union
{ {
float value; float value;
uint32_t raw; uint32_t raw;
} SOFT_FLOAT; } SOFT_FLOAT;
typedef union typedef union
{ {
double value; double value;
uint64_t raw; uint64_t raw;
} SOFT_DOUBLE; } SOFT_DOUBLE;
const SOFT_FLOAT EPS_FLOAT = {.raw = 0x34000000}; const SOFT_FLOAT EPS_FLOAT = {.raw = 0x34000000};
@@ -28,425 +49,432 @@ const SOFT_DOUBLE EPS_DOUBLE = {.raw = 0x3CB0000000000000};
const QUATERNION QUATERNION_IDENTITY = {1.0, 0.0, 0.0, 0.0}; const QUATERNION QUATERNION_IDENTITY = {1.0, 0.0, 0.0, 0.0};
const QUATERNION QUATERNION_NIL = {NAN, NAN, NAN, NAN}; const QUATERNION QUATERNION_NIL = {NAN, NAN, NAN, NAN};
/** @brief Subtracts two quaternions. */ /** @brief Subtracts two quaternions. */
QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2) QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2)
{ {
QUATERNION ret; QUATERNION ret;
ret.s = q1.s - q2.s; ret.s = q1.s - q2.s;
ret.i = q1.i - q2.i; ret.i = q1.i - q2.i;
ret.j = q1.j - q2.j; ret.j = q1.j - q2.j;
ret.k = q1.k - q2.k; ret.k = q1.k - q2.k;
return ret; return ret;
} }
/** @brief Adds two quaternions. */ /** @brief Adds two quaternions. */
QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2) QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2)
{ {
QUATERNION ret; QUATERNION ret;
ret.s = q1.s + q2.s; ret.s = q1.s + q2.s;
ret.i = q1.i + q2.i; ret.i = q1.i + q2.i;
ret.j = q1.j + q2.j; ret.j = q1.j + q2.j;
ret.k = q1.k + q2.k; ret.k = q1.k + q2.k;
return ret; return ret;
} }
/** @brief Multiplies a quaternion by a real number. */ /** @brief Multiplies a quaternion by a real number. */
void Quaternion_ScalarMult(QUATERNION *q, double t) void Quaternion_ScalarMult(QUATERNION *q, double t)
{ {
q->s *= t; q->s *= t;
q->i *= t; q->i *= t;
q->j *= t; q->j *= t;
q->k *= t; q->k *= t;
} }
/** @brief Multiplies a quaternion by a real number. */ /** @brief Multiplies a quaternion by a real number. */
QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t) QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t)
{ {
Quaternion_ScalarMult(&a, t); Quaternion_ScalarMult(&a, t);
return a; return a;
} }
/** @brief Divides a quaternion by a real number. */ /** @brief Divides a quaternion by a real number. */
void Quaternion_ScalarDiv(QUATERNION *q, double t) void Quaternion_ScalarDiv(QUATERNION *q, double t)
{ {
q->s /= t; q->s /= t;
q->i /= t; q->i /= t;
q->j /= t; q->j /= t;
q->k /= t; q->k /= t;
} }
/** @brief Divides a quaternion by a real number. */ /** @brief Divides a quaternion by a real number. */
QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t) QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t)
{ {
Quaternion_ScalarDiv(&q, t); Quaternion_ScalarDiv(&q, t);
return q; return q;
} }
/** @brief Multiplies two quaternions. */ /** @brief Multiplies two quaternions. */
QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2) QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2)
{ {
QUATERNION ret; QUATERNION ret;
ret.s = q1.s * q2.s - (q1.i * q2.i + q1.j * q2.j + q1.k * q2.k); ret.s = q1.s * q2.s - (q1.i * q2.i + q1.j * q2.j + q1.k * q2.k);
ret.i = q1.j * q2.k - q1.k * q2.j + q1.s * q2.i + q1.i * q2.s; ret.i = q1.j * q2.k - q1.k * q2.j + q1.s * q2.i + q1.i * q2.s;
ret.j = q1.k * q2.i - q1.i * q2.k + q1.s * q2.j + q1.j * q2.s; ret.j = q1.k * q2.i - q1.i * q2.k + q1.s * q2.j + q1.j * q2.s;
ret.k = q1.i * q2.j - q1.j * q2.i + q1.s * q2.k + q1.k * q2.s; ret.k = q1.i * q2.j - q1.j * q2.i + q1.s * q2.k + q1.k * q2.s;
return ret; return ret;
} }
/** @brief Divides two quaternions. */ /** @brief Divides two quaternions. */
QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2) QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2)
{ {
Quaternion_Inverse(&q2); Quaternion_Inverse(&q2);
return Quaternion_Mult(q1, q2); return Quaternion_Mult(q1, q2);
} }
/** @brief Dot product. */ /** @brief Dot product. */
inline double Quaternion_Dot(QUATERNION q1, QUATERNION q2) inline double Quaternion_Dot(QUATERNION q1, QUATERNION q2)
{ {
return (q1.s * q2.s + q1.i * q2.i + q1.j * q2.j + q1.k * q2.k); return (q1.s * q2.s + q1.i * q2.i + q1.j * q2.j + q1.k * q2.k);
} }
/** @brief Calculate a quaternion length^2 (omits calling square root). */ /** @brief Calculate a quaternion length^2 (omits calling square root). */
inline double Quaternion_SquareLength(QUATERNION q) inline double Quaternion_SquareLength(QUATERNION q)
{ {
return (q.s * q.s + q.i * q.i + q.j * q.j + q.k * q.k); return (q.s * q.s + q.i * q.i + q.j * q.j + q.k * q.k);
} }
/** @brief Calculate a quaternion length. */ /** @brief Calculate a quaternion length. */
inline double Quaternion_Length(QUATERNION q) inline double Quaternion_Length(QUATERNION q)
{ {
return sqrt(Quaternion_SquareLength(q)); return sqrt(Quaternion_SquareLength(q));
} }
/** @brief Normalize quaternion. */ /** @brief Normalize quaternion. */
void Quaternion_Normalize(QUATERNION *q) void Quaternion_Normalize(QUATERNION *q)
{ {
Quaternion_ScalarDiv(q, Quaternion_Length(*q)); Quaternion_ScalarDiv(q, Quaternion_Length(*q));
} }
/** @brief Normalize quaternion. */ /** @brief Normalize quaternion. */
QUATERNION Quaternion_GetNormalized(QUATERNION q) QUATERNION Quaternion_GetNormalized(QUATERNION q)
{ {
Quaternion_Normalize(&q); Quaternion_Normalize(&q);
return q; return q;
} }
/** @brief Conjugated quaternion. */ /** @brief Conjugated quaternion. */
void Quaternion_Conjugated(QUATERNION *q) void Quaternion_Conjugated(QUATERNION *q)
{ {
q->i = -q->i; q->i = -q->i;
q->j = -q->j; q->j = -q->j;
q->k = -q->k; q->k = -q->k;
} }
/** @brief Conjugated quaternion. */ /** @brief Conjugated quaternion. */
QUATERNION Quaternion_GetConjugated(QUATERNION q) QUATERNION Quaternion_GetConjugated(QUATERNION q)
{ {
Quaternion_Conjugated(&q); Quaternion_Conjugated(&q);
return q; return q;
} }
/** @brief Inverse quaternion. */ /** @brief Inverse quaternion. */
void Quaternion_Inverse(QUATERNION *q) void Quaternion_Inverse(QUATERNION *q)
{ {
Quaternion_Conjugated(q); Quaternion_Conjugated(q);
Quaternion_ScalarDiv(q, Quaternion_SquareLength(*q)); Quaternion_ScalarDiv(q, Quaternion_SquareLength(*q));
} }
/** @brief Inverse quaternion. */ /** @brief Inverse quaternion. */
QUATERNION Quaternion_GeInverse(QUATERNION q) QUATERNION Quaternion_GeInverse(QUATERNION q)
{ {
Quaternion_Inverse(&q); Quaternion_Inverse(&q);
return q; return q;
} }
inline double Quaternion_GetRotationAngle(QUATERNION q) inline double Quaternion_GetRotationAngle(QUATERNION q)
{ {
return (acos(q.s) * 2); return (acos(q.s) * 2);
} }
/** @brief Get axis of quaternion. */ /** @brief Get axis of quaternion. */
COORD Quaternion_GetRotationAxis(QUATERNION q) COORD Quaternion_GetRotationAxis(QUATERNION q)
{ {
double sin_theta_inv; double sin_theta_inv;
COORD ret; COORD ret;
sin_theta_inv = 1.0 / sin(acos(q.s)); sin_theta_inv = 1.0 / sin(acos(q.s));
ret.x = q.i * sin_theta_inv; ret.x = q.i * sin_theta_inv;
ret.y = q.j * sin_theta_inv; ret.y = q.j * sin_theta_inv;
ret.z = q.k * sin_theta_inv; ret.z = q.k * sin_theta_inv;
return ret; return ret;
} }
/** @brief Get the axis and rotate angle of a unit Quaternion */ /** @brief Get the axis and rotate angle of a unit Quaternion */
void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle) void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle)
{ {
double sin_theta_inv; double sin_theta_inv;
*angle = acos(q.s); *angle = acos(q.s);
// pre-compute to save time // pre-compute to save time
sin_theta_inv = 1.0 / sin(*angle); sin_theta_inv = 1.0 / sin(*angle);
// now the vector // now the vector
axis->x = q.i * sin_theta_inv; axis->x = q.i * sin_theta_inv;
axis->y = q.j * sin_theta_inv; axis->y = q.j * sin_theta_inv;
axis->z = q.k * sin_theta_inv; axis->z = q.k * sin_theta_inv;
*angle = (*angle) * 2; *angle = (*angle) * 2;
} }
/** @brief Decompose the rotation on to 2 parts. */ /** @brief Decompose the rotation on to 2 parts. */
void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist) void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist)
{ {
double p; double p;
COORD v; COORD v;
v.x = q.i; v.x = q.i;
v.y = q.j; v.y = q.j;
v.z = q.k; v.z = q.k;
// return projection v1 on to v2 (parallel component) // return projection v1 on to v2 (parallel component)
p = Coord_Dot(v, axis); p = Coord_Dot(v, axis);
v = Coord_GetScalarMult(axis, p); v = Coord_GetScalarMult(axis, p);
twist->s = q.s; twist->s = q.s;
twist->i = v.x; twist->i = v.x;
twist->j = v.y; twist->j = v.y;
twist->k = v.z; twist->k = v.z;
Quaternion_Normalize(twist); Quaternion_Normalize(twist);
*swing = Quaternion_Mult(q, Quaternion_GetConjugated(*twist)); *swing = Quaternion_Mult(q, Quaternion_GetConjugated(*twist));
} }
/** @brief rotates v by this quaternion (quaternion must be unit) */ /** @brief rotates v by this quaternion (quaternion must be unit) */
COORD Quaternion_Rotate(QUATERNION q, COORD v) COORD Quaternion_Rotate(QUATERNION q, COORD v)
{ {
QUATERNION temp; QUATERNION temp;
COORD ret; COORD ret;
temp.s = 0; temp.s = 0;
temp.i = v.x; temp.i = v.x;
temp.j = v.y; temp.j = v.y;
temp.k = v.z; temp.k = v.z;
temp = Quaternion_Mult(q, temp); temp = Quaternion_Mult(q, temp);
Quaternion_Conjugated(&q); Quaternion_Conjugated(&q);
temp = Quaternion_Mult(temp, q); temp = Quaternion_Mult(temp, q);
ret.x = temp.i; ret.x = temp.i;
ret.y = temp.j; ret.y = temp.j;
ret.z = temp.k; ret.z = temp.k;
return ret; return ret;
} }
/** @brief returns the euler angles from a rotation Quaternion */ /** @brief returns the euler angles from a rotation Quaternion */
EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type) EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type)
{ {
EULERANGLES ret; EULERANGLES ret;
switch (type) switch (type)
{ {
case EULERANGLES_ZYX: case EULERANGLES_ZYX:
{ {
/* Covert form matlab 2023a */ /* Covert form matlab 2023a */
// Cap all inputs to asin to 1, since values >1 produce complex // Cap all inputs to asin to 1, since values >1 produce complex
// results // results
// Since the quaternion is of unit length, this should never happen, // Since the quaternion is of unit length, this should never happen,
// but some code generation configuration seem to hit this edge case // but some code generation configuration seem to hit this edge case
// under some circumstances. // under some circumstances.
double asinValue; double asinValue;
bool mask1, mask2; bool mask1, mask2;
asinValue = -2.0 * (q.i * q.k - q.s * q.j); asinValue = -2.0 * (q.i * q.k - q.s * q.j);
mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value; mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value; mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value;
if (mask1) if (mask1)
asinValue = 1; asinValue = 1;
if (mask2) if (mask2)
asinValue = -1; asinValue = -1;
if (mask1 || mask2) if (mask1 || mask2)
{ {
ret.alpha = (asinValue > 0) ? (-2.0 * atan2(q.i, q.s)) : (2.0 * atan2(q.i, q.s)); ret.alpha = (asinValue > 0) ? (-2.0 * atan2(q.i, q.s)) : (2.0 * atan2(q.i, q.s));
ret.gamma = 0; ret.gamma = 0;
} }
else else
{ {
ret.alpha = atan2(2.0 * (q.i * q.j + q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k); ret.alpha = atan2(2.0 * (q.i * q.j + q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k);
ret.gamma = atan2(2.0 * (q.j * q.k + q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k); ret.gamma = atan2(2.0 * (q.j * q.k + q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k);
} }
ret.beta = asin(asinValue); ret.beta = asin(asinValue);
break; break;
} }
case EULERANGLES_ZYZ: case EULERANGLES_ZYZ:
{ {
// TODO; // TODO;
ret = EULERANGLES_NIL; ret = EULERANGLES_NIL;
break; break;
} }
case EULERANGLES_XYZ: case EULERANGLES_XYZ:
{ {
/* Covert form matlab 2023a */ /* Covert form matlab 2023a */
// Prevent singularities as done in ZYX case // Prevent singularities as done in ZYX case
// Alternative to rotm2eul(quat2rotm(q), 'XYZ') with fewer // Alternative to rotm2eul(quat2rotm(q), 'XYZ') with fewer
// operations // operations
// sin(y) = R13 = 2 * (qx*qz + qy*qw) // sin(y) = R13 = 2 * (qx*qz + qy*qw)
// tan(x) = sin(x) / cos(x) = -R23 / R33 // tan(x) = sin(x) / cos(x) = -R23 / R33
// = -2 * (qy*qz - qx*qw) / (1 - 2*(qx^2 + qy^2)) // = -2 * (qy*qz - qx*qw) / (1 - 2*(qx^2 + qy^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 - qx^2 - qy^2 + qz^2) // = -2 * (qy*qz - qx*qw) / (qw^2 - qx^2 - qy^2 + qz^2)
// tan(z) = sin(z) / cos(z) = -R12 / R11 // tan(z) = sin(z) / cos(z) = -R12 / R11
// = -2 * (qx*qy - qz*qw) / (1 - 2*(qy^2 + qz^2)) // = -2 * (qx*qy - qz*qw) / (1 - 2*(qy^2 + qz^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 + qx^2 - qy^2 - qz^2) // = -2 * (qy*qz - qx*qw) / (qw^2 + qx^2 - qy^2 - qz^2)
double asinValue; double asinValue;
bool mask1, mask2; bool mask1, mask2;
asinValue = 2.0 * (q.i * q.k + q.s * q.j); asinValue = 2.0 * (q.i * q.k + q.s * q.j);
mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value; mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value; mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value;
if (mask1) if (mask1)
asinValue = 1; asinValue = 1;
if (mask2) if (mask2)
asinValue = -1; asinValue = -1;
if (mask1 || mask2) if (mask1 || mask2)
{ {
ret.alpha = 0; ret.alpha = 0;
ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s)); ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s));
} }
else else
{ {
ret.alpha = atan2(-2.0 * (q.j * q.k - q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k); ret.alpha = atan2(-2.0 * (q.j * q.k - q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k);
ret.gamma = atan2(-2.0 * (q.i * q.j - q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k); ret.gamma = atan2(-2.0 * (q.i * q.j - q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k);
} }
ret.beta = asin(asinValue); ret.beta = asin(asinValue);
break; break;
} }
default: default:
ret = EULERANGLES_NIL; ret = EULERANGLES_NIL;
} }
return ret; return ret;
} }
/** @brief returns the rotation Quaternion from a euler angles */ /** @brief returns the rotation Quaternion from a euler angles */
QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type) QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type)
{ {
QUATERNION ret; QUATERNION ret;
double cosx, sinx, cosy, siny, cosz, sinz; double cosx, sinx, cosy, siny, cosz, sinz;
cosx = cos(e.alpha * 0.5); cosx = cos(e.alpha * 0.5);
sinx = sin(e.alpha * 0.5); sinx = sin(e.alpha * 0.5);
cosy = cos(e.beta * 0.5); cosy = cos(e.beta * 0.5);
siny = sin(e.beta * 0.5); siny = sin(e.beta * 0.5);
cosz = cos(e.gamma * 0.5); cosz = cos(e.gamma * 0.5);
sinz = sin(e.gamma * 0.5); sinz = sin(e.gamma * 0.5);
switch (type) switch (type)
{ {
case EULERANGLES_ZYX: case EULERANGLES_ZYX:
ret.s = cosx * cosy * cosz + sinx * siny * sinz; ret.s = cosx * cosy * cosz + sinx * siny * sinz;
ret.i = cosx * cosy * sinz - sinx * siny * cosz; ret.i = cosx * cosy * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * cosy * sinz; ret.j = cosx * siny * cosz + sinx * cosy * sinz;
ret.k = sinx * cosy * cosz - cosx * siny * sinz; ret.k = sinx * cosy * cosz - cosx * siny * sinz;
break; break;
case EULERANGLES_ZYZ: case EULERANGLES_ZYZ:
ret.s = cosx * cosy * cosz - sinx * cosy * sinz; ret.s = cosx * cosy * cosz - sinx * cosy * sinz;
ret.i = cosx * siny * sinz - sinx * siny * cosz; ret.i = cosx * siny * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * siny * sinz; ret.j = cosx * siny * cosz + sinx * siny * sinz;
ret.k = sinx * cosy * cosz + cosx * cosy * sinz; ret.k = sinx * cosy * cosz + cosx * cosy * sinz;
break; break;
case EULERANGLES_XYZ: case EULERANGLES_XYZ:
ret.s = cosx * cosy * cosz - sinx * siny * sinz; ret.s = cosx * cosy * cosz - sinx * siny * sinz;
ret.i = sinx * cosy * cosz + cosx * siny * sinz; ret.i = sinx * cosy * cosz + cosx * siny * sinz;
ret.j = -sinx * cosy * sinz + cosx * siny * cosz; ret.j = -sinx * cosy * sinz + cosx * siny * cosz;
ret.k = cosx * cosy * sinz + sinx * siny * cosz; ret.k = cosx * cosy * sinz + sinx * siny * cosz;
break; break;
default: default:
ret = QUATERNION_NIL; ret = QUATERNION_NIL;
break; break;
} }
return ret; return ret;
} }
/** @brief adapted from https://svn.code.sf.net/p/irrlicht/code/trunk/include/quaternion.h */ /** @brief adapted from https://svn.code.sf.net/p/irrlicht/code/trunk/include/quaternion.h */
QUATERNION Quaternion_RotationFromTo(COORD from, COORD to) QUATERNION Quaternion_RotationFromTo(COORD from, COORD to)
{ {
// Based on Stan Melax's article in Game Programming Gems // Based on Stan Melax's article in Game Programming Gems
COORD axis; COORD axis;
QUATERNION ret; QUATERNION ret;
double c, s; double c, s;
Coord_Normalize(&from); Coord_Normalize(&from);
Coord_Normalize(&to); Coord_Normalize(&to);
c = Coord_Dot(from, to); c = Coord_Dot(from, to);
if (c >= 1.0) if (c >= 1.0)
{ // If dot == 1, vectors are the same { // If dot == 1, vectors are the same
return QUATERNION_IDENTITY; // identity return QUATERNION_IDENTITY; // identity
} }
else if (c <= -1.0) else if (c <= -1.0)
{ // exactly opposite { // exactly opposite
axis = Coord_Cross(COORD_X_AXIS, from); axis = Coord_Cross(COORD_X_AXIS, from);
if (Coord_Length(axis) == 0) if (Coord_Length(axis) == 0)
axis = Coord_Cross(COORD_Y_AXIS, from); axis = Coord_Cross(COORD_Y_AXIS, from);
// same as fromAxisAngle(axis, PI).normalize(); // same as fromAxisAngle(axis, PI).normalize();
ret.s = 0; ret.s = 0;
ret.i = axis.x; ret.i = axis.x;
ret.j = axis.y; ret.j = axis.y;
ret.k = axis.z; ret.k = axis.z;
Quaternion_Normalize(&ret); Quaternion_Normalize(&ret);
return ret; return ret;
} }
s = sqrt((1 + c) * 2); s = sqrt((1 + c) * 2);
axis = Coord_Cross(from, to); axis = Coord_Cross(from, to);
Coord_ScalarDiv(&axis, s); Coord_ScalarDiv(&axis, s);
ret.s = s * 0.5; ret.s = s * 0.5;
ret.i = axis.x; ret.i = axis.x;
ret.j = axis.y; ret.j = axis.y;
ret.k = axis.z; ret.k = axis.z;
Quaternion_Normalize(&ret); Quaternion_Normalize(&ret);
return ret; return ret;
} }
/** @brief linear quaternion interpolation */ /** @brief linear quaternion interpolation */
QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t) QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t)
{ {
QUATERNION ret; QUATERNION ret;
Quaternion_ScalarMult(&q1, 1 - t); Quaternion_ScalarMult(&q1, 1 - t);
Quaternion_ScalarMult(&q1, t); Quaternion_ScalarMult(&q1, t);
ret = Quaternion_Add(q1, q2); ret = Quaternion_Add(q1, q2);
Quaternion_Normalize(&ret); Quaternion_Normalize(&ret);
return ret; return ret;
} }
/** @brief spherical linear interpolation */ /** @brief spherical linear interpolation */
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t) QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t)
{ {
double dot; double dot;
QUATERNION q3, ret; QUATERNION q3, ret;
dot = Quaternion_Dot(q1, q2); dot = Quaternion_Dot(q1, q2);
/* dot = cos(theta) /* dot = cos(theta)
if (dot < 0), q1 and q2 are more than 90 degrees apart, if (dot < 0), q1 and q2 are more than 90 degrees apart,
so we can invert one to reduce spinning */ so we can invert one to reduce spinning */
if (dot < 0) if (dot < 0)
{ {
dot = -dot; dot = -dot;
q3.s = -q2.s; q3.s = -q2.s;
q3.i = -q2.i; q3.i = -q2.i;
q3.j = -q2.j; q3.j = -q2.j;
q3.k = -q2.k; q3.k = -q2.k;
} }
else else
{ {
q3 = q2; q3 = q2;
} }
if (dot < 0.95) if (dot < 0.95)
{ {
double angle = acos(dot); double angle = acos(dot);
Quaternion_ScalarMult(&q1, sin(angle * (1 - t))); Quaternion_ScalarMult(&q1, sin(angle * (1 - t)));
Quaternion_ScalarMult(&q3, sin(angle * t)); Quaternion_ScalarMult(&q3, sin(angle * t));
ret = Quaternion_Add(q1, q3); ret = Quaternion_Add(q1, q3);
Quaternion_ScalarDiv(&ret, sin(angle)); Quaternion_ScalarDiv(&ret, sin(angle));
return ret; return ret;
} }
// if the angle is small, use linear interpolation // if the angle is small, use linear interpolation
else else
{ {
return Quaternion_Lerp(q1, q3, t); return Quaternion_Lerp(q1, q3, t);
} }
} }
/** @} LinkLayerGeometry_Quaternion */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,3 +1,29 @@
/*****************************************************************************/
/**
* @file quaternion.h
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_Quaternion
* @{
*/
#ifndef __QUATERNION_H #ifndef __QUATERNION_H
#define __QUATERNION_H #define __QUATERNION_H
@@ -5,13 +31,16 @@
#include "coord.h" #include "coord.h"
#include "eulerangles.h" #include "eulerangles.h"
// borrowed and adapted from https://github.com/MegaManSE/willperone/blob/master/Math/quaternion.h /**
* @struct QUATERNION
* @brief Structure for standard quaternion
*/
typedef struct typedef struct
{ {
double s; double s;
double i; double i;
double j; double j;
double k; double k;
} QUATERNION; } QUATERNION;
extern const QUATERNION QUATERNION_IDENTITY; extern const QUATERNION QUATERNION_IDENTITY;
@@ -78,13 +107,13 @@ COORD Quaternion_GetRotationAxis(QUATERNION q);
void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle); void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle);
/** @brief Decompose the rotation on to 2 parts. /** @brief Decompose the rotation on to 2 parts.
1. Twist - rotation around the "direction" vector 1. Twist - rotation around the "direction" vector
2. Swing - rotation around axis that is perpendicular to "direction" vector 2. Swing - rotation around axis that is perpendicular to "direction" vector
The rotation can be composed back by rotation = swing * twist The rotation can be composed back by rotation = swing * twist
has singularity in case of swing_rotation close to 180 degrees rotation. has singularity in case of swing_rotation close to 180 degrees rotation.
if the input quaternion is of non-unit length, the outputs are non-unit as well if the input quaternion is of non-unit length, the outputs are non-unit as well
otherwise, outputs are both unit otherwise, outputs are both unit
*/ */
void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist); void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist);
@@ -107,3 +136,9 @@ QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t);
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t); QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t);
#endif #endif
/** @} LinkLayerGeometry_Quaternion */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,19 +1,21 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: A brief description of this file * @file link_layer.c
* @author FanHao ([email protected])
* @brief DF Linklayer implementation file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2021-11-13 13:32 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2021-11-23 10:57 * Lab of Communication and Network
* Revisions: Rev 0.0
* History:
* [2021-11-23]: Initial version.
* [2022-03-28]: Add bre test mode.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -31,7 +33,7 @@
#endif #endif
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
#define NET_START_TIME_INFTY UINT32_MAX #define NET_START_TIME_INFTY UINT32_MAX
#define LINK_BROCK_THRESHOLD (3 * 200) // 3 secods #define LINK_BROCK_THRESHOLD L2_SLOTS_PER_FRAME // 0.5 secods
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
@@ -43,6 +45,18 @@ static void L2_SetSlotNum(L2_INST *instPtr, uint32_t newSlotNum);
static void L2_SetFrameNum(L2_INST *instPtr, uint32_t newFrameNum); static void L2_SetFrameNum(L2_INST *instPtr, uint32_t newFrameNum);
static void L2_UpdateSlotNum(L2_INST *instPtr); static void L2_UpdateSlotNum(L2_INST *instPtr);
static void L2_DataAvailUpdate(L2_INST *instPtr, bool status); static void L2_DataAvailUpdate(L2_INST *instPtr, bool status);
static void L2_FrameStateUpdate(L2_INST *instPtr);
/**
* @brief Shift L2 status record.(newval->next->curr->last)
*/
inline void L2_RcdShift(L2_RCD *rcd, int32_t netxVal)
{
ASSERT(rcd != NULL);
rcd->last = rcd->curr;
rcd->curr = rcd->next;
rcd->next = netxVal;
}
/** /**
* @brief helper function to update linkelayer state * @brief helper function to update linkelayer state
@@ -102,6 +116,79 @@ static inline void L2_DataAvailUpdate(L2_INST *instPtr, bool status)
instPtr->dataAvail = status; instPtr->dataAvail = status;
} }
/*****************************************************************************/
/**
* @brief Update L2 frame state, check if there is any valid L2 frame data in
* data buffer, update receive frame status.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
static void L2_FrameStateUpdate(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
bool isValid;
L2_FRAME_TYPE recvType = L2_GetLastOptFrameType(instPtr);
// Update frame state.
if (Phy_IsFrameValid(phyRef) == false)
{
L2_DataAvailUpdate(instPtr, false);
}
else
{
DBG_INFO("A frame received, checking data validation...\n");
DBG_INFO("Last frame type is: %" PRId32 ".\n", instPtr->frame.last);
Phy_RetrieveRecvData(phyRef, instPtr->recvPktData);
instPtr->log.frameRecv++;
// Update frame state.
switch (recvType)
{
case L2_SCAN_FRAME:
case L2_ADV_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_ADV_PACK_LEN, L2_CRC16_1021);
instPtr->log.advRecvCnt++;
instPtr->log.advCorrectCnt = isValid ? instPtr->log.advCorrectCnt + 1 : instPtr->log.advCorrectCnt;
break;
case L2_CFM_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_CMF_PACK_LEN, L2_CRC16_1021);
instPtr->log.cfmRecvCnt++;
instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break;
case L2_SVC_FRAME:
#ifndef DATALINK_ENABLE_BERTEST
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021);
#else
isValid = true;
#endif
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
default:
isValid = false;
break;
}
if (isValid)
{
instPtr->log.frameCorrect++;
L2_DataAvailUpdate(instPtr, true);
}
else
{
L2_DataAvailUpdate(instPtr, false);
}
}
}
/**
* @addtogroup LinkLayer_Utility
* @{
*/
/** /**
* @brief Get the current node ID. * @brief Get the current node ID.
*/ */
@@ -147,6 +234,15 @@ inline L2_NODE_STATE L2_GetMainState(L2_INST *instPtr)
return instPtr->mainState; return instPtr->mainState;
} }
/**
* @brief Check if there is a valid l2 frame.
*/
inline bool L2_isStarted(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
return instPtr->isEnable;
}
/** /**
* @brief Check if there is a valid l2 frame. * @brief Check if there is a valid l2 frame.
*/ */
@@ -165,6 +261,14 @@ inline bool L2_isCxn2Net(L2_INST *instPtr)
return instPtr->cxn2Net; return instPtr->cxn2Net;
} }
/**
* @brief Get corresponding frame length in byte of L2 frame.
*/
inline uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType)
{
return Phy_GetFrameLen(L2_L2frame2L1frame(l2FrameType));
}
/** /**
* @brief Get last frame number. * @brief Get last frame number.
*/ */
@@ -272,24 +376,6 @@ inline L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr)
return instPtr->tor.next; return instPtr->tor.next;
} }
/*****************************************************************************/
/**
* @brief Shift L2 status record.(newval->next->curr->last)
*
* @param instPtr A pointer to physical layer control instance.
*
* @return NONE.
*
******************************************************************************/
inline void L2_RcdShift(L2_RCD *rcd, int32_t netxVal)
{
ASSERT(rcd != NULL);
rcd->last = rcd->curr;
rcd->curr = rcd->next;
rcd->next = netxVal;
}
// FIXME:
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Infer last received frame type. * @brief Infer last received frame type.
@@ -317,292 +403,6 @@ L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr)
return L2_NONE_FRAME; return L2_NONE_FRAME;
} }
} }
/*****************************************************************************/
/**
* @brief Update L2 frame state, check if there is any valid L2 frame data in
* data buffer, update receive frame status.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
void L2_FrameStateUpdate(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
bool isValid;
L2_FRAME_TYPE recvType = L2_GetLastOptFrameType(instPtr);
// Update frame state.
if (Phy_IsFrameValid(phyRef) == false)
{
L2_DataAvailUpdate(instPtr, false);
}
else
{
DBG_INFO("A frame received, checking data validation...\n");
DBG_INFO("Last frame type is: %" PRId32 ".\n", instPtr->frame.last);
Phy_RetrieveRecvData(phyRef, instPtr->recvPktData);
instPtr->log.frameRecv++;
// Update frame state.
switch (recvType)
{
case L2_SCAN_FRAME:
case L2_ADV_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_ADV_PACK_LEN, L2_CRC16_1021);
instPtr->log.advRecvCnt++;
instPtr->log.advCorrectCnt = isValid ? instPtr->log.advCorrectCnt + 1 : instPtr->log.advCorrectCnt;
break;
case L2_CFM_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_CMF_PACK_LEN, L2_CRC16_1021);
instPtr->log.cfmRecvCnt++;
instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break;
case L2_SVC_FRAME:
#ifndef DATALINK_ENABLE_BERTEST
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021);
#else
isValid = true;
#endif
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
default:
isValid = false;
break;
}
if (isValid)
{
instPtr->log.frameCorrect++;
L2_DataAvailUpdate(instPtr, true);
}
else
{
L2_DataAvailUpdate(instPtr, false);
}
}
}
/*****************************************************************************/
/**
* @brief Steer antenna beam to specified node.
*
* @param instPtr a pointer to link layer descriptor instance
* @param nodeId destination node
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
// FIXME: To Complete.
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId)
{
ASSERT(instPtr != NULL);
ASSERT(instPtr->config.phyInstPtr != NULL);
int32_t Status;
COORD myPos, dstPos, beamDir;
Status = L2_GetNodePos(instPtr->nodeList, nodeId, &dstPos);
if (Status != SUCCESS)
{
DBG_ERROR("Failed to retrieve position info of node %" PRIu8 ", remain last configuration.\n", nodeId);
return EPARAM;
}
myPos.x = instPtr->sysInfo.posX;
myPos.y = instPtr->sysInfo.posY;
myPos.z = instPtr->sysInfo.posZ;
// TODO Check data format
EULERANGLES attitudeEuler, antAttitudeEuler;
attitudeEuler.alpha = DEG2RAD(instPtr->sysInfo.pitch);
attitudeEuler.beta = DEG2RAD(instPtr->sysInfo.yaw);
attitudeEuler.gamma = DEG2RAD(instPtr->sysInfo.roll);
// FIXME: confirm date source.
antAttitudeEuler.alpha = DEG2RAD(0);
antAttitudeEuler.beta = DEG2RAD(0);
antAttitudeEuler.gamma = DEG2RAD(0);
// TODO Check data format
QUATERNION attitude, antAttitude;
attitude = Quaternion_FromeEulerAngles(attitudeEuler, EULERANGLES_XYZ);
antAttitude = Quaternion_FromeEulerAngles(antAttitudeEuler, EULERANGLES_XYZ);
// --- --- Algorithm --- ---
// TODO Check result validation
// Compute beam direction vector
beamDir = Coord_Sub(dstPos, myPos);
// Compute antenna attitude respect to ECEF
antAttitude = Quaternion_Mult(attitude, antAttitude);
// Convert beam direction vector to antenna coordinate
beamDir = Quaternion_Rotate(Quaternion_GeInverse(antAttitude), beamDir);
// Normalize
Coord_Normalize(&beamDir);
double oAxis, rAxis;
oAxis = RAD2DEG(atan2(beamDir.z, beamDir.y));
rAxis = RAD2DEG(acos(Coord_Dot(beamDir, COORD_X_AXIS)));
Status = Phy_SetBeamAngle(instPtr->config.phyInstPtr, oAxis, rAxis);
return Status;
}
/*****************************************************************************/
/**
* @brief Layer 2 setup next slot operation, update current operating frame.
*
* @param instPtr a pointer to linklayer instance
* @param txrxMode tx/rx state for next slot
* @param frameType frame type of next slot.
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME)
{
return FAILURE;
}
// logging
if (txrxMode == L2_TOR_TX)
{
instPtr->log.frameTx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advTxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmTxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcTxCnt++;
break;
default:
break;
}
}
else if (txrxMode == L2_TOR_RX)
{
instPtr->log.frameRx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advRxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcRxCnt++;
break;
default:
break;
}
}
#if _DEBUG_LEVEL >= 3
char *torStr = NULL;
char *frameStr = NULL;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
torStr = "SUSPEND";
break;
case L2_TOR_TX:
torStr = "TX";
break;
case L2_TOR_RX:
torStr = "RX";
break;
}
switch (frameType)
{
case L2_SCAN_FRAME:
frameStr = "Scan";
break;
case L2_ADV_FRAME:
frameStr = "Advertisement";
break;
case L2_CFM_FRAME:
frameStr = "Confirm";
break;
case L2_SVC_FRAME:
frameStr = "Service";
break;
default:
frameStr = "UNKNOWN Frame";
break;
}
DBG_INFO("# Setup Next Slot # [%" PRIu32 "-%" PRIu32 "], %s, %s.\n",
instPtr->frameNum.next,
instPtr->slotNum.next,
torStr, frameStr);
#endif
// Update frame and tx/rx mode record.
// Frame types shift (last <- curr <- next)
L2_RcdShift(&(instPtr->frame), frameType);
L2_RcdShift(&(instPtr->tor), txrxMode);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1;
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
if (Status != SUCCESS)
{
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 "\n", Status);
}
PHY_TOR_TYPE tor;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
tor = PHY_TOR_SUSPEND;
break;
case L2_TOR_TX:
tor = PHY_TOR_TX;
break;
case L2_TOR_RX:
tor = PHY_TOR_RX;
break;
default:
DBG_ERROR("Invalid txrx mode :%" PRId8 ".\n", txrxMode);
return EPARAM;
}
Status = Phy_SetupNextSlot(phyRef, tor, L2_L2frame2L1frame(frameType), instPtr->sendPktData);
if (Status != SUCCESS)
{
DBG_ERROR("Physical setup failed, with error code: %" PRId32 "\n", Status);
}
return Status;
}
/*****************************************************************************/
/**
* @brief Get corresponding frame length in byte of L2 frame.
*
* @param l2FrameType
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType)
{
return Phy_GetFrameLen(L2_L2frame2L1frame(l2FrameType));
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Convert L2 frame type to L1 frame type * @brief Convert L2 frame type to L1 frame type
@@ -627,6 +427,12 @@ L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame)
return L1_NONE_FRAME; return L1_NONE_FRAME;
} }
} }
/** @} LinkLayer_Utility*/
/**
* @defgroup LinkLayer_Main
* @{
*/
/*****************************************************************************/ /*****************************************************************************/
/** /**
@@ -948,7 +754,7 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
case L2_EV_LOST_CXN: case L2_EV_LOST_CXN:
{ {
DBG_INFO("Event L2_EV_LOST_CXN asserted....\n"); DBG_INFO("Event L2_EV_LOST_CXN asserted....\n");
if (instPtr->config.myType == L2_NODE_HEAD) if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{ {
DBG_ERROR("Illegal event, only None_Head node can assert L2_EV_LOST_CXN.\n"); DBG_ERROR("Illegal event, only None_Head node can assert L2_EV_LOST_CXN.\n");
break; break;
@@ -1171,6 +977,8 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
{ {
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
int32_t Status; int32_t Status;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
TMC_INST *tmcRef = instPtr->config.tmcInstPtr;
if (instPtr->isEnable == false) if (instPtr->isEnable == false)
{ {
@@ -1179,7 +987,7 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
} }
// FIXME: Consider time wrapping. // FIXME: Consider time wrapping.
uint32_t nextTimeUnit = (TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1) / L2_SLOTS_PER_FRAME; uint32_t nextTimeUnit = (TimeCtrl_GetIntCnt(tmcRef) + 1) / L2_SLOTS_PER_FRAME;
if (nextTimeUnit < instPtr->netStartTime) if (nextTimeUnit < instPtr->netStartTime)
{ {
DBG_WARNING("Linklayer not start yet, next time unit: %" PRIu32 ", start time unit: %" PRIu32 ".\n", DBG_WARNING("Linklayer not start yet, next time unit: %" PRIu32 ", start time unit: %" PRIu32 ".\n",
@@ -1211,19 +1019,19 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
// Run Link layer routine, setup next slot procedure. // Run Link layer routine, setup next slot procedure.
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD) if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{ {
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL); Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Linklayer_Routine(instPtr); Status = Linklayer_Routine(instPtr);
} }
else else
{ // L2_NODE_MEMBER { // L2_NODE_MEMBER
if (L2_isCxn2Net(instPtr)) if (L2_isCxn2Net(instPtr))
{ {
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL); Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Linklayer_Routine(instPtr); Status = Linklayer_Routine(instPtr);
} }
else else
{ {
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_LISTEN); Phy_SetMode(phyRef, PHY_MODE_LISTEN);
Status = L2_Scan_Proc(instPtr); Status = L2_Scan_Proc(instPtr);
} }
} }
@@ -1241,14 +1049,14 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
instPtr->mainState = instPtr->nextState; instPtr->mainState = instPtr->nextState;
instPtr->linkLog.tuNum = instPtr->frameNum.curr; instPtr->linkLog.tuNum = instPtr->frameNum.curr;
instPtr->linkLog.slotNum = (uint8_t)instPtr->slotNum.curr; instPtr->linkLog.slotNum = (uint8_t)instPtr->slotNum.curr;
instPtr->linkLog.nodeType = (instPtr->config.myType == L2_NODE_HEAD) ? 0xAA : 0xCC; instPtr->linkLog.nodeType = (L2_GetNodeType(instPtr) == L2_NODE_HEAD) ? 0xAA : 0xCC;
instPtr->linkLog.cxnStatus = (instPtr->cxn2Net) ? 0x11 : 0x00; instPtr->linkLog.cxnStatus = (instPtr->cxn2Net) ? 0x11 : 0x00;
instPtr->linkLog.linkStage = (instPtr->mainState == L2_INIT_STATE) ? 0x11 : 0x22; instPtr->linkLog.linkStage = (instPtr->mainState == L2_INIT_STATE) ? 0x11 : 0x22;
instPtr->linkLog.recxnCnt = instPtr->log.reconnectCnt; instPtr->linkLog.recxnCnt = instPtr->log.reconnectCnt;
instPtr->linkLog.beamNo = instPtr->scanFSM->beamNo; instPtr->linkLog.beamNo = instPtr->scanFSM->beamNo;
instPtr->linkLog.beamWidth = instPtr->log.lastBeamWidth; instPtr->linkLog.beamWidth = instPtr->log.lastBeamWidth;
instPtr->linkLog.beamAz = instPtr->config.phyInstPtr->antNrrwPattern[instPtr->scanFSM->beamNo].oaxis; instPtr->linkLog.beamAz = phyRef->antNrrwPattern[instPtr->scanFSM->beamNo].oaxis;
instPtr->linkLog.beamEl = instPtr->config.phyInstPtr->antNrrwPattern[instPtr->scanFSM->beamNo].raxis; instPtr->linkLog.beamEl = phyRef->antNrrwPattern[instPtr->scanFSM->beamNo].raxis;
instPtr->linkLog.advTxCnt = (uint16_t)instPtr->log.advTxCnt; instPtr->linkLog.advTxCnt = (uint16_t)instPtr->log.advTxCnt;
instPtr->linkLog.advRecvCnt = (uint16_t)instPtr->log.advRecvCnt; instPtr->linkLog.advRecvCnt = (uint16_t)instPtr->log.advRecvCnt;
instPtr->linkLog.advCorrectCnt = (uint16_t)instPtr->log.advCorrectCnt; instPtr->linkLog.advCorrectCnt = (uint16_t)instPtr->log.advCorrectCnt;
@@ -1260,9 +1068,211 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
instPtr->linkLog.svcCorrectCnt = instPtr->log.svcCorrectCnt; instPtr->linkLog.svcCorrectCnt = instPtr->log.svcCorrectCnt;
instPtr->linkLog.timeDev = (instPtr->log.timeDev > INT32_MAX) instPtr->linkLog.timeDev = (instPtr->log.timeDev > INT32_MAX)
? INT32_MAX : ((instPtr->log.timeDev < INT32_MIN) ? INT32_MIN : (int32_t)instPtr->log.timeDev); ? INT32_MAX : ((instPtr->log.timeDev < INT32_MIN) ? INT32_MIN : (int32_t)instPtr->log.timeDev);
instPtr->linkLog.sendId = instPtr->serviceFSM->txLog.dataId; instPtr->linkLog.sendId = instPtr->log.txLog.dataId;
instPtr->linkLog.recvId = instPtr->serviceFSM->rxLog.dataId; instPtr->linkLog.recvId = instPtr->log.rxLog.dataId;
SysMonitor_UpdateLinklayerLog(&(instPtr->linkLog)); SysMonitor_UpdateLinklayerLog(&(instPtr->linkLog));
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/
/**
* @brief Steer antenna beam to specified node.
*
* @param instPtr a pointer to link layer descriptor instance
* @param nodeId destination node
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId)
{
ASSERT(instPtr != NULL);
int32_t Status;
COORD myPos, dstPos, beamDir;
Status = L2_GetNodePos(instPtr->nodeList, nodeId, &dstPos);
if (Status != SUCCESS)
{
DBG_ERROR("Failed to retrieve position info of node %" PRIu8 ", remain last configuration.\n", nodeId);
return EPARAM;
}
myPos.x = instPtr->sysInfo.posX;
myPos.y = instPtr->sysInfo.posY;
myPos.z = instPtr->sysInfo.posZ;
// TODO Check data format
EULERANGLES attitudeEuler, antAttitudeEuler;
attitudeEuler.alpha = DEG2RAD(instPtr->sysInfo.pitch);
attitudeEuler.beta = DEG2RAD(instPtr->sysInfo.yaw);
attitudeEuler.gamma = DEG2RAD(instPtr->sysInfo.roll);
// FIXME: confirm date source.
antAttitudeEuler.alpha = DEG2RAD(0);
antAttitudeEuler.beta = DEG2RAD(0);
antAttitudeEuler.gamma = DEG2RAD(0);
// TODO Check data format
QUATERNION attitude, antAttitude;
attitude = Quaternion_FromeEulerAngles(attitudeEuler, EULERANGLES_XYZ);
antAttitude = Quaternion_FromeEulerAngles(antAttitudeEuler, EULERANGLES_XYZ);
// --- --- Algorithm --- ---
// TODO Check result validation
// Compute beam direction vector
beamDir = Coord_Sub(dstPos, myPos);
// Compute antenna attitude respect to ECEF
antAttitude = Quaternion_Mult(attitude, antAttitude);
// Convert beam direction vector to antenna coordinate
beamDir = Quaternion_Rotate(Quaternion_GeInverse(antAttitude), beamDir);
// Normalize
Coord_Normalize(&beamDir);
double oAxis, rAxis;
oAxis = RAD2DEG(atan2(beamDir.z, beamDir.y));
rAxis = RAD2DEG(acos(Coord_Dot(beamDir, COORD_X_AXIS)));
Status = Phy_SetBeamAngle(instPtr->config.phyInstPtr, oAxis, rAxis);
return Status;
}
/*****************************************************************************/
/**
* @brief Layer 2 setup next slot operation, update current operating frame.
*
* @param instPtr a pointer to linklayer instance
* @param txrxMode tx/rx state for next slot
* @param frameType frame type of next slot.
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME)
{
return FAILURE;
}
// logging
if (txrxMode == L2_TOR_TX)
{
instPtr->log.frameTx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advTxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmTxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcTxCnt++;
break;
default:
break;
}
}
else if (txrxMode == L2_TOR_RX)
{
instPtr->log.frameRx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advRxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcRxCnt++;
break;
default:
break;
}
}
#if _DEBUG_LEVEL >= 3
char *torStr = NULL;
char *frameStr = NULL;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
torStr = "SUSPEND";
break;
case L2_TOR_TX:
torStr = "TX";
break;
case L2_TOR_RX:
torStr = "RX";
break;
}
switch (frameType)
{
case L2_SCAN_FRAME:
frameStr = "Scan";
break;
case L2_ADV_FRAME:
frameStr = "Advertisement";
break;
case L2_CFM_FRAME:
frameStr = "Confirm";
break;
case L2_SVC_FRAME:
frameStr = "Service";
break;
default:
frameStr = "UNKNOWN Frame";
break;
}
DBG_INFO("# Setup Next Slot # [%" PRIu32 "-%" PRIu32 "], %s, %s.\n",
instPtr->frameNum.next,
instPtr->slotNum.next,
torStr, frameStr);
#endif
// Update frame and tx/rx mode record.
// Frame types shift (last <- curr <- next)
L2_RcdShift(&(instPtr->frame), frameType);
L2_RcdShift(&(instPtr->tor), txrxMode);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1;
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
if (Status != SUCCESS)
{
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 "\n", Status);
}
PHY_TOR_TYPE tor;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
tor = PHY_TOR_SUSPEND;
break;
case L2_TOR_TX:
tor = PHY_TOR_TX;
break;
case L2_TOR_RX:
tor = PHY_TOR_RX;
break;
default:
DBG_ERROR("Invalid txrx mode :%" PRId8 ".\n", txrxMode);
return EPARAM;
}
Status = Phy_SetupNextSlot(phyRef, tor, L2_L2frame2L1frame(frameType), instPtr->sendPktData);
if (Status != SUCCESS)
{
DBG_ERROR("Physical setup failed, with error code: %" PRId32 "\n", Status);
}
return Status;
}
/** @} LinkLayer_Main*/
/** @} LinkLayer*/
@@ -1,19 +1,21 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Header file for df linklayer functions * @file link_layer.h
* @author FanHao ([email protected])
* @brief DF Linklayer header file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2021-11-13 13:33 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2022-07-16 10:12 * Lab of Communication and Network
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-23]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup LinkLayer
* @{
*/
#ifndef __LINK_LAYER_H_ #ifndef __LINK_LAYER_H_
#define __LINK_LAYER_H_ #define __LINK_LAYER_H_
@@ -30,78 +32,96 @@
#define AssertL2Event(instPtr, event) Linklayer_EventHandler(instPtr, event) #define AssertL2Event(instPtr, event) Linklayer_EventHandler(instPtr, event)
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/**
* @struct L2_CONFIG
* @brief A struct holds all linklayer initialization parameters
*/
typedef struct typedef struct
{ {
L2_NODE_TYPE myType; L2_NODE_TYPE myType; ///< node type
bool isInterHead; bool isInterHead; ///< indicate if node is head node
uint8_t clustId; uint8_t clustId; ///< node cluster id
uint8_t myId; uint8_t myId; ///< node id
uint8_t headId; uint8_t headId; ///< head node id
uint8_t bkpHeadId; uint8_t bkpHeadId; ///< backup head id
uint8_t netScale; uint8_t netScale; ///< net scale
PHY_INST *phyInstPtr; PHY_INST *phyInstPtr; ///< pointer to system physical layer instance
TMC_INST *tmcInstPtr; TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
} L2_CONFIG; } L2_CONFIG;
/**
* @struct L2_LOG
* @brief A struct holds linklayer operating log
*/
typedef struct typedef struct
{ {
uint32_t frameRx; uint32_t frameRx; ///< total rx frame count
uint32_t frameTx; uint32_t frameTx; ///< total tx frame count
uint32_t frameRecv; uint32_t frameRecv; ///< total received frame count
uint32_t frameCorrect; uint32_t frameCorrect; ///< total correctly received frame count
uint32_t advRxCnt; uint32_t advRxCnt; ///< advertise rx frame count
uint32_t advTxCnt; uint32_t advTxCnt; ///< advertise tx frame count
uint32_t advRecvCnt; uint32_t advRecvCnt; ///< advertise received frame count
uint32_t advCorrectCnt; uint32_t advCorrectCnt; ///< advertise correctly received frame count
uint32_t cfmRxCnt; uint32_t cfmRxCnt; ///< confirm rx frame count
uint32_t cfmTxCnt; uint32_t cfmTxCnt; ///< confirm tx frame count
uint32_t cfmRecvCnt; uint32_t cfmRecvCnt; ///< confirm received frame count
uint32_t cfmCorrectCnt; uint32_t cfmCorrectCnt; ///< confirm correctly received frame count
uint32_t svcRxCnt; uint32_t svcRxCnt; ///< service rx frame count
uint32_t svcTxCnt; uint32_t svcTxCnt; ///< service tx frame count
uint32_t svcRecvCnt; uint32_t svcRecvCnt; ///< service received frame count
uint32_t svcCorrectCnt; uint32_t svcCorrectCnt; ///< service correctly received frame count
int64_t timeDev; int64_t timeDev; ///< last time deviation estimation result
uint8_t lastBeamWidth; uint8_t lastBeamWidth; ///< last beam width
uint32_t reconnectCnt; uint32_t reconnectCnt; ///< reconnect trial count
PAYLOAD rxLog;
PAYLOAD txLog;
} L2_LOG; } L2_LOG;
/**
* @struct L2_INST
* @brief A linklayer instance
*/
typedef struct typedef struct
{ {
L2_CONFIG config; L2_CONFIG config; ///< linklayer configuration parameters
L2_NODE_INFO myInfo; L2_NODE_INFO myInfo; ///< current node info
NODE_LIST *nodeList; NODE_LIST *nodeList; ///< discovered node list
L2_SCHD_POOL *schdEventPool; L2_SCHD_POOL *schdEventPool; ///< event schedule pool
uint32_t netStartTime; uint32_t netStartTime; ///< network start time
bool isEnable; // if the node is connected to the network bool isEnable; ///< indicates if the node is connected to the network
bool dataAvail; // if there is a valid received frame data in rx buffer bool dataAvail; ///< indicates if there is a valid received frame data in rx buffer
bool cxn2Net; // if the node is connected to the network bool cxn2Net; ///< indicates if the node is connected to the network
L2_RCD frameNum; // stores the last current and next frame number. L2_RCD frameNum; ///< stores the last current and next frame number.
L2_RCD slotNum; // stores the last current and next slot number. L2_RCD slotNum; ///< stores the last current and next slot number.
L2_RCD frame; // stores the last current and next link layer frame type. L2_RCD frame; ///< stores the last current and next link layer frame type.
L2_RCD tor; // stores the last current and next link layer tx/rx state. L2_RCD tor; ///< stores the last current and next link layer tx/rx state.
L2_NODE_STATE mainState; // the main state of link layer state L2_NODE_STATE mainState; ///< the main state of link layer state
L2_NODE_STATE nextState; // next state of link layer state, which will be applied to mainState every second. L2_NODE_STATE nextState; ///< next state of link layer state, which will be applied to mainState every second.
L2_RTNE_CONFIG rtneConfig; // current routine table configuration and status. L2_RTNE_CONFIG rtneConfig; ///< current routine table configuration and status.
L2_SCAN_FSM *scanFSM; // FSM of scan net (link set up) L2_SCAN_FSM *scanFSM; ///< FSM of scan net (link set up)
L2_SVC_FSM *serviceFSM; // FSM of service net (data service) L2_SVC_FSM *serviceFSM; ///< FSM of service net (data service)
uint8_t *sendPktData; uint8_t *sendPktData; ///< send data buffer
uint8_t *recvPktData; uint8_t *recvPktData; ///< received data buffer
L2_LOG log; L2_LOG log; ///< Linklayer operating log
// for system log // for system log
SYSINFO sysInfo; SYSINFO sysInfo; ///< system info
LINKLOG linkLog; LINKLOG linkLog; ///< linklayer log for system monitor
} L2_INST; } L2_INST;
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD]; extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD]; extern L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD];
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
// Main /**
* @defgroup LinkLayer_Main
* @{
*/
int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config); int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config);
int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config); int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config);
void Linklayer_Destroy(L2_INST *instPtr); void Linklayer_Destroy(L2_INST *instPtr);
@@ -112,24 +132,33 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event);
int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType); int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType);
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId); int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId);
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType); int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
void L2_FrameStateUpdate(L2_INST *instPtr); /** @} LinkLayer_Main*/
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
// Scheduling Event /**
* @defgroup LinkLayer_Framing
* @{
*/
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk);
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk);
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType);
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
/** @} LinkLayer_Framing*/
/**
* @defgroup LinkLayer_Scheduler
* @{
*/
void L2_EventPoolHandler(L2_INST *instPtr); void L2_EventPoolHandler(L2_INST *instPtr);
int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo); int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots); int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots);
int32_t L2_RescheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo); int32_t L2_RescheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_RescheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots); int32_t L2_RescheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots);
/** @} LinkLayer_Scheduler*/
// Framing /**
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk); * @defgroup LinkLayer_Scan
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk); * @{
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType); */
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
// Scanning
int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr); int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr);
void L2_Scan_RefreashScanTable(L2_INST *instPtr); void L2_Scan_RefreashScanTable(L2_INST *instPtr);
void L2_Scan_Reset(L2_SCAN_FSM *scanFSMPtr); void L2_Scan_Reset(L2_SCAN_FSM *scanFSMPtr);
@@ -137,21 +166,38 @@ void L2_Scan_Destroy(L2_SCAN_FSM *scanFSMPtr);
int32_t L2_Scan_Proc(L2_INST *instPtr); int32_t L2_Scan_Proc(L2_INST *instPtr);
int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg); int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg);
int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry); int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
/** @} LinkLayer_Scan*/
// Service /**
* @defgroup LinkLayer_Service
* @{
*/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr); int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr);
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr); void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr);
void L2_Service_Destroy(L2_SVC_FSM *svcFSMPtr); void L2_Service_Destroy(L2_SVC_FSM *svcFSMPtr);
int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg); int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg);
int32_t L2_Service_Proc(L2_INST *instPtr); int32_t L2_Service_Proc(L2_INST *instPtr);
int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry); int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
/** @} LinkLayer_Service*/
// Miscellaneous /**
* @defgroup LinkLayer_TimeSync
* @{
*/
int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative, int64_t *timeDev);
void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev);
/** @} LinkLayer_TimeSync*/
/**
* @defgroup LinkLayer_Utility
* @{
*/
uint8_t L2_GetNodeId(L2_INST *instPtr); uint8_t L2_GetNodeId(L2_INST *instPtr);
uint8_t L2_GetClusterId(L2_INST *instPtr); uint8_t L2_GetClusterId(L2_INST *instPtr);
uint8_t L2_GetHeadId(L2_INST *instPtr); uint8_t L2_GetHeadId(L2_INST *instPtr);
L2_NODE_TYPE L2_GetNodeType(L2_INST *instPtr); L2_NODE_TYPE L2_GetNodeType(L2_INST *instPtr);
L2_NODE_STATE L2_GetMainState(L2_INST *instPtr); L2_NODE_STATE L2_GetMainState(L2_INST *instPtr);
bool L2_isStarted(L2_INST *instPtr);
bool L2_isDataAvail(L2_INST *instPtr); bool L2_isDataAvail(L2_INST *instPtr);
bool L2_isCxn2Net(L2_INST *instPtr); bool L2_isCxn2Net(L2_INST *instPtr);
uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType); uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType);
@@ -167,10 +213,10 @@ uint32_t L2_GetNextFrameNum(L2_INST *instPtr);
uint32_t L2_GetNextSlotNum(L2_INST *instPtr); uint32_t L2_GetNextSlotNum(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetNextFrameType(L2_INST *instPtr); L2_FRAME_TYPE L2_GetNextFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr); L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
// Time syncronization L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative, int64_t* timeDev); /** @} LinkLayer_Utility*/
void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev);
#endif /* __LINK_LAYER_H_ */ #endif /* __LINK_LAYER_H_ */
/** @} LinkLayer*/
@@ -1,17 +1,19 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: A brief description of this file * @file link_layer_types.h
* @author FanHao ([email protected])
* @brief DF Linklayer types definition.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2022-08-28 22:53 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2022-08-29 00:45 * Lab of Communication and Network
* Revisions: Rev 0.0
* History:
* [2022-08-29]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup LinkLayer
* @{
*/
#ifndef __LINK_LAYER_DEF_H_ #ifndef __LINK_LAYER_DEF_H_
#define __LINK_LAYER_DEF_H_ #define __LINK_LAYER_DEF_H_
@@ -26,6 +28,10 @@
#include "../config/app_config.h" #include "../config/app_config.h"
#endif #endif
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/**
* @name Linklayer_Common_Constants
* @{
*/
// Common node ID definition // Common node ID definition
#define L2_BROADCAST_ID 0xFF #define L2_BROADCAST_ID 0xFF
#define L2_NONE_ID 0 #define L2_NONE_ID 0
@@ -39,7 +45,7 @@
#define L2_FRAMENO_NONE 0 #define L2_FRAMENO_NONE 0
// Common number of slots definition // Common number of slots definition
#define L2_SLOTS_PER_FRAME 200 #define L2_SLOTS_PER_FRAME 100
#define L2_SLOTS_PER_SUBFRAME 20 #define L2_SLOTS_PER_SUBFRAME 20
#define L2_NUM_SLOTS_NONE UINT32_MAX #define L2_NUM_SLOTS_NONE UINT32_MAX
@@ -48,9 +54,14 @@
#define L2_NUM_SLOTS_10MS 2 #define L2_NUM_SLOTS_10MS 2
#define L2_NUM_SLOTS_5MS 1 #define L2_NUM_SLOTS_5MS 1
#define L2_NUM_SLOTS_SKIP 0 #define L2_NUM_SLOTS_SKIP 0
/** @} Linklayer_Common_Constants*/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/**
* @struct L2_RCD
* @brief Linklayer recode buffer
*/
typedef struct typedef struct
{ {
uint32_t last; uint32_t last;
@@ -58,7 +69,8 @@ typedef struct
uint32_t next; uint32_t next;
} L2_RCD; } L2_RCD;
/** @name Tx/Rx mode code /**
* @enum L2_TOR_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -67,7 +79,8 @@ typedef enum
L2_TOR_RX = 2 L2_TOR_RX = 2
} L2_TOR_TYPE; } L2_TOR_TYPE;
/** @name Prior information type definition /**
* @enum L2_NODE_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -77,7 +90,8 @@ typedef enum
L2_NODE_BACKUP = 3 L2_NODE_BACKUP = 3
} L2_NODE_TYPE; } L2_NODE_TYPE;
/** @name Node state type definition /**
* @enum L2_NODE_STATE
*/ */
typedef enum typedef enum
{ {
@@ -89,23 +103,24 @@ typedef enum
L2_SEEK_STATE = 5 L2_SEEK_STATE = 5
} L2_NODE_STATE; } L2_NODE_STATE;
/** @name Node information type definition /**
* The following types define the detail node info which needed by the link layer. * @struct L2_NODE_INFO
* @brief Node information struct contains the detail node info which needed by the link layer.
*/ */
typedef struct typedef struct
{ {
uint8_t nodeId; uint8_t nodeId; ///< node ID
uint8_t clustId; uint8_t clustId; ///< node cluster ID
uint8_t headId; uint8_t headId; ///< cluster head ID
L2_NODE_TYPE nodeType; L2_NODE_TYPE nodeType; ///< node type
uint8_t beamNo; uint8_t beamNo; ///< beam number to this node
COORD pos; COORD pos; ///< node position
COORD speed; COORD speed; ///< node speed
QUATERNION attitude; QUATERNION attitude; ///< node attitude
} L2_NODE_INFO; } L2_NODE_INFO;
/** @name L2 event enum /**
* A enum of L2 event types. * @enum L2_EVENT_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -123,17 +138,18 @@ typedef enum
L2_ROUTINE_UPDATE = 11 L2_ROUTINE_UPDATE = 11
} L2_EVENT_TYPE; } L2_EVENT_TYPE;
/** @name L2 event /**
* A definition of L2 event instance. * @struct L2_EVENT
* @brief Linklayer event instance
*/ */
typedef struct typedef struct
{ {
L2_EVENT_TYPE event; L2_EVENT_TYPE event; ///< event type
void *msg; void *msg; ///< event message
} L2_EVENT; } L2_EVENT;
/** @name Slot types /**
* A definition of different slots. * @enum L2_SLOT_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -145,8 +161,8 @@ typedef enum
L2_SLOT_SERVICE = 5, L2_SLOT_SERVICE = 5,
} L2_SLOT_TYPE; } L2_SLOT_TYPE;
/** @name Frame types /**
* A definition of different frame types. * @enum L2_FRAME_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -157,8 +173,8 @@ typedef enum
L2_SVC_FRAME = 4 L2_SVC_FRAME = 4
} L2_FRAME_TYPE; } L2_FRAME_TYPE;
/** @name Frame types /**
* A definition of different frame types. * @enum L2_CRC_TYPE
*/ */
typedef enum typedef enum
{ {
@@ -168,17 +184,21 @@ typedef enum
L2_CRC8_31 = 3 L2_CRC8_31 = 3
} L2_CRC_TYPE; } L2_CRC_TYPE;
/** @name Schedule subtable entry /**
* A definition of Schedule subtable entry. * @struct L2_RTNE_TABLE_ENTRY
* @brief Linklayer routine table entry
*/ */
typedef struct typedef struct
{ {
L2_SLOT_TYPE slotType : 8; L2_SLOT_TYPE slotType : 8; ///< slot type
uint8_t slotSeq; uint8_t slotSeq; ///< slot sequence number
uint8_t src; uint8_t src; ///< source node ID
uint8_t dst; uint8_t dst; ///< destination node ID
} L2_RTNE_TABLE_ENTRY; } L2_RTNE_TABLE_ENTRY;
/**
* @enum SCAN_STAGE
*/
typedef enum typedef enum
{ {
L2_SCAN_NONE_STAGE = 0, L2_SCAN_NONE_STAGE = 0,
@@ -187,47 +207,56 @@ typedef enum
L2_SCAN_CFM_STAGE = 3 L2_SCAN_CFM_STAGE = 3
} SCAN_STAGE; } SCAN_STAGE;
/** @name Scan procedure FSM /**
* @struct L2_SCAN_FSM
* @brief Linklayer scan process FSM instance
*/ */
typedef struct typedef struct
{ {
bool isLocked; // init acq done. bool isLocked; ///< indicates if init acq done(beam locked).
bool isAdvRecvd; // bm received. bool isAdvRecvd; ///< indicates if advertisement frame done(beam locked).
bool isAckPending; // 2way acq done. bool isAckPending; ///< indicates if confirm message acked
uint8_t scanCnt; uint8_t scanCnt; ///< scan count
uint8_t advTimeout; uint8_t advTimeout; ///< adv receive try count
uint8_t cfmTimeout; uint8_t cfmTimeout; ///< cmf receive try count
SCAN_STAGE scanStage; // only for member node SCAN_STAGE scanStage; ///< scan stage \n
uint8_t beamNo; /// only for member node
uint8_t tableNo; uint8_t beamNo; ///< locked beam number
uint8_t tableNo; ///< scan table index
} L2_SCAN_FSM; } L2_SCAN_FSM;
/**
/** @name Service procedure FSM * @struct L2_SVC_FSM
* @brief Linklayer service process FSM
*/ */
typedef struct typedef struct
{ {
PAYLOAD rxLog; uint32_t txCnt; ///< tx frame count
PAYLOAD txLog; uint32_t rxCnt; ///< rx frame count
uint32_t pktRecv; uint32_t rxdCnt; ///< received frame count
uint32_t pktCorrect;
#ifdef DATALINK_ENABLE_BERTEST #ifdef DATALINK_ENABLE_BERTEST
uint32_t bitTotal; uint32_t bitTotal; ///< received bits count
uint32_t bitError; uint32_t bitError; ///< error bits count
double lossRate; double lossRate; ///< packet loss rate
double errorRate; double errorRate; ///< bit error rate
#endif #endif
} L2_SVC_FSM; } L2_SVC_FSM;
/**
* @struct L2_RTNE_CONFIG
* @brief Linklayer routine table configuration
*/
typedef struct typedef struct
{ {
L2_RTNE_TABLE_ENTRY **rtneTable; L2_RTNE_TABLE_ENTRY **rtneTable; ///< routine table
uint32_t rtnePrd; uint32_t rtnePrd; ///< period of routine table
L2_RTNE_TABLE_ENTRY *last; L2_RTNE_TABLE_ENTRY *last; ///< last routine entry
L2_RTNE_TABLE_ENTRY *curr; L2_RTNE_TABLE_ENTRY *curr; ///< curent routine entry
L2_RTNE_TABLE_ENTRY *next; L2_RTNE_TABLE_ENTRY *next; ///< next routine entry
} L2_RTNE_CONFIG; } L2_RTNE_CONFIG;
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
#endif /* __LINK_LAYER_DEF_H_ */ #endif /* __LINK_LAYER_DEF_H_ */
/** @} LinkLayer*/
@@ -1,23 +1,31 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Header of 814 linklayer messages * @file msg_def.c
* @author FanHao ([email protected])
* @brief DF Linklayer message definition constants.
* @version 0.0
* @date 2023-05-06
* *
* Date: 2022-07-14 00:08 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2022-07-14 22:52 * Lab of Communication and Network
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @name LinkLayer_MSG_Constants
* @{
*/
#ifndef __L2_MSG_DEF_H_ #ifndef __L2_MSG_DEF_H_
#define __L2_MSG_DEF_H_ #define __L2_MSG_DEF_H_
#define L2_PACK_LEN_MAX 512 // bytes #define L2_PACK_LEN_MAX 512 // bytes
#define L2_ADV_PACK_LEN 28 // bytes #define L2_ADV_PACK_LEN 28 // bytes
#define L2_CMF_PACK_LEN 268 // bytes #define L2_CMF_PACK_LEN 268 // bytes
#define L2_SVC_PACK_LEN 268 // bytes #define L2_SVC_PACK_LEN 268 // bytes
@@ -115,5 +123,8 @@
#define L2_MSG_SVC_CRC 266 #define L2_MSG_SVC_CRC 266
#define L2_MSG_SVC_CRC_LEN 2 #define L2_MSG_SVC_CRC_LEN 2
#endif //__L2_MSG_DEF_H_ #endif //__L2_MSG_DEF_H_
/** @} LinkLayer_MSG_Constants*/
/** @} LinkLayer*/
@@ -1,19 +1,25 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Implementations of 814 linklayer local record. * @file node_list.c
* @author FanHao ([email protected])
* @brief DF Linklayer node list implementation file
* @version 0.0
* @date 2023-05-06
* *
* Date: 2022-07-14 00:08 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditors: Fan Hao * Lab of Communication and Network
* LastEditTime: 2022-07-14 22:52
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_NodeList
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -94,7 +100,7 @@ int32_t L2_NodeList_Init(NODE_LIST **list)
* @brief Clear all nodes in the node list, free allocated memory. * @brief Clear all nodes in the node list, free allocated memory.
* *
* @param list * @param list
*NONE * @return NONE
* *
******************************************************************************/ ******************************************************************************/
void L2_NodeList_Clear(NODE_LIST *list) void L2_NodeList_Clear(NODE_LIST *list)
@@ -123,7 +129,7 @@ void L2_NodeList_Destroy(NODE_LIST *list)
* @param list * @param list
* @param nodeId * @param nodeId
* *
* @return Node entry * @return Node entry \n
* NULL if node dose not exist. * NULL if node dose not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -154,7 +160,7 @@ NODE_ENTRY *L2_GetNodeById(NODE_LIST *list, uint8_t nodeId)
* @param nodeId * @param nodeId
* @param nodeType * @param nodeType
* *
* @return SUCCESS Node was added successfully. * @return SUCCESS Node was added successfully.\n
* Other Error occurred.(Node already exist, memory alloc error ect.) * Other Error occurred.(Node already exist, memory alloc error ect.)
* *
******************************************************************************/ ******************************************************************************/
@@ -201,7 +207,7 @@ NODE_ENTRY *L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType
* @param list * @param list
* @param nodeId * @param nodeId
* *
* @return SUCCESS Node has been successfully deleted. * @return SUCCESS Node has been successfully deleted.\n
* Other Node not exist. * Other Node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -227,7 +233,7 @@ int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId)
* @param list * @param list
* @param nodeId * @param nodeId
* *
* @return true node in the list * @return true node in the list\n
* false node not in the list * false node not in the list
* *
******************************************************************************/ ******************************************************************************/
@@ -245,7 +251,7 @@ bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId)
* @param nodeId * @param nodeId
* @param dst A pointer to store distance. * @param dst A pointer to store distance.
* *
* @return SUCCESS distance has been successfully store in dst * @return SUCCESS distance has been successfully store in dst\n
* FAILURE Node dose not exit. * FAILURE Node dose not exit.
* *
******************************************************************************/ ******************************************************************************/
@@ -273,7 +279,7 @@ int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *d
* @param nodeId * @param nodeId
* @param newPos A structure stores the corresponding node position info. * @param newPos A structure stores the corresponding node position info.
* *
* @return SUCCESS update successfully. * @return SUCCESS update successfully.\n
* FAILURE node not exist. * FAILURE node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -300,7 +306,7 @@ int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos)
* @param nodeId * @param nodeId
* @param newPos A structure stores the corresponding node position info. * @param newPos A structure stores the corresponding node position info.
* *
* @return SUCCESS update successfully. * @return SUCCESS update successfully.\n
* FAILURE node not exist. * FAILURE node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -327,7 +333,7 @@ int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos)
* @param nodeId * @param nodeId
* @param newSpeed A structure stores the corresponding node speed info. * @param newSpeed A structure stores the corresponding node speed info.
* *
* @return SUCCESS update successfully. * @return SUCCESS update successfully.\n
* FAILURE node not exist. * FAILURE node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -354,7 +360,7 @@ int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpee
* @param nodeId * @param nodeId
* @param newSpeed A structure stores the corresponding node speed info. * @param newSpeed A structure stores the corresponding node speed info.
* *
* @return SUCCESS update successfully. * @return SUCCESS update successfully.\n
* FAILURE node not exist. * FAILURE node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -380,7 +386,7 @@ int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed)
* @param nodeId * @param nodeId
* @param devi * @param devi
* *
* @return SUCCESS update successfully. * @return SUCCESS update successfully.\n
* FAILURE Node not exist. * FAILURE Node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -432,7 +438,7 @@ int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc)
* @param list * @param list
* @param nodeId * @param nodeId
* *
* @return SUCCESS TTL has been successfully cleared. * @return SUCCESS TTL has been successfully cleared.\n
* FAILURE Node not exist. * FAILURE Node not exist.
* *
******************************************************************************/ ******************************************************************************/
@@ -486,7 +492,7 @@ int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl)
* @param operation A pointer to a function handled "NODE_ENTRY*" as input * @param operation A pointer to a function handled "NODE_ENTRY*" as input
* which defines the operations need to be apply. * which defines the operations need to be apply.
* *
* @return SUCCESS Operations has been applied successfully to all nodes. * @return SUCCESS Operations has been applied successfully to all nodes.\n
* Other Error occurred. * Other Error occurred.
* *
******************************************************************************/ ******************************************************************************/
@@ -520,7 +526,7 @@ int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)
* *
* @param list * @param list
* @param condition A pointer to a function handled "NODE_ENTRY*" as input * @param condition A pointer to a function handled "NODE_ENTRY*" as input
* which defines the condition need to be verify. * which defines the condition need to be verify.
* *
* @return SUCCESS * @return SUCCESS
* *
@@ -545,3 +551,7 @@ int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *))
clist_iterator_destroy(iter); clist_iterator_destroy(iter);
return SUCCESS; return SUCCESS;
} }
/** @} LinkLayer_NodeList*/
/** @} LinkLayer*/
@@ -1,19 +1,27 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Header of 814 linklayer local record. * @file node_list.h
* @author FanHao ([email protected])
* @brief DF Linklayer node list header file
* @version 0.0
* @date 2023-05-06
* *
* Date: 2022-07-14 00:08 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditors: Fan Hao * Lab of Communication and Network
* LastEditTime: 2022-07-14 22:52
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @defgroup LinkLayer_NodeList
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#ifndef NODE_LIST_H_ #ifndef NODE_LIST_H_
#define NODE_LIST_H_ #define NODE_LIST_H_
@@ -29,7 +37,11 @@
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
typedef struct NODE_LIST_ENTRY /**
* @struct NODE_ENTRY
* @brief Linklayer discovered node list node entry
*/
typedef struct
{ {
L2_NODE_INFO nodeInfo; L2_NODE_INFO nodeInfo;
uint32_t ttlCnt; uint32_t ttlCnt;
@@ -62,3 +74,6 @@ int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)); int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *));
#endif /* NODE_LIST_H_ */ #endif /* NODE_LIST_H_ */
/** @} LinkLayer_NodeList*/
/** @} LinkLayer*/
@@ -1,467 +1,30 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Time allocations for df datalink, * @file routine_table.c
* Date: 2022-07-16 17:05 * @author FanHao ([email protected])
* LastEditTime: 2022-07-16 17:05 * @brief DF Linklayer node list implementation file
* Revisions: Rev 0.1 * @version 0.0
* History: * @date 2023-05-06
* [2021-11-13]: Initial version.
* *
* Copyright(c) 2021 Beijing Institute of Technology. * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Networking * Lab of Communication and Network
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @name RoutineTable
* @{
*/
#include <inttypes.h> #include <inttypes.h>
#include "link_layer.h" #include "link_layer.h"
#include "link_layer_types.h" #include "link_layer_types.h"
#define LINKLAYER_INSERT_EXTRGAP
#ifndef LINKLAYER_INSERT_EXTRGAP
L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
// SubFrame 0
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 1
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 2
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 3
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_ADVERTISE, 0x00, 0x01, 0xFF},
{L2_SLOT_ADVERTISE, 0x01, 0x01, 0xFF},
{L2_SLOT_ADVERTISE, 0x02, 0x01, 0xFF},
{L2_SLOT_ADVERTISE, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 4
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 5
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 6
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
// SubFrame 7
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
// SubFrame 8
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 9
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
};
L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = {
// SubFrame 0
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 1
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 2
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 3
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 4
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 5
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 6
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 7
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 8
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 9
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
};
#else
L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = { L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
// SubFrame 0 // SubFrame 0
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF}, {L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
@@ -572,116 +135,6 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01}, {L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01}, {L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 5
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 6
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 7
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 8
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 9
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
}; };
L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = { L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = {
@@ -794,118 +247,7 @@ L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01}, {L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01}, {L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00}, {L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 5
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 6
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 7
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 8
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 9
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
}; };
#endif
L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] = L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] =
{ {
@@ -916,3 +258,6 @@ L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD] =
{ {
normalSub normalSub
}; };
/** @} RoutineTable*/
/** @} LinkLayer*/
+264 -232
View File
@@ -1,18 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Implementations of df linklayer scan net. * @file scan.c
* @author FanHao ([email protected])
* @brief DF Linklayer scan implementation file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2021-11-10 19:04 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2022-07-16 17:04 * Lab of Communication and Network
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-10]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scan
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <string.h> #include <string.h>
@@ -26,7 +32,7 @@
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
#define ADV_LISTEN_TIMEOUT 40 #define ADV_LISTEN_TIMEOUT 40
#define CFM_LISTEN_TIMEOUT 25 #define CFM_LISTEN_TIMEOUT 5
#define ADV_FRAME_SLOTS 4 #define ADV_FRAME_SLOTS 4
#define CFM_FRAME_SLOTS 5 #define CFM_FRAME_SLOTS 5
/***************** Macros (In-line Functions) Definitions *********************/ /***************** Macros (In-line Functions) Definitions *********************/
@@ -36,7 +42,7 @@
/************************** Variable Definitions *****************************/ /************************** Variable Definitions *****************************/
// Pair by regex // Pair by regex
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2}) // Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
PHY_ANT_ANGLE antNrrwPattern_0[L1_NUM_ANT_NRRW_PATTERN] = PHY_ANT_ANGLE antNrrwPattern_0[L1_NUM_ANT_NRRW_PATTERN] =
{ {
{.oaxis = 0 , .raxis = 0 }, {.oaxis = 0 , .raxis = 0 },
{.oaxis = 139, .raxis = 2225}, {.oaxis = 139, .raxis = 2225},
@@ -77,7 +83,7 @@ PHY_ANT_ANGLE antNrrwPattern_0[L1_NUM_ANT_NRRW_PATTERN] =
{.oaxis = 450, .raxis = 897 } {.oaxis = 450, .raxis = 897 }
}; };
PHY_ANT_ANGLE antNrrwPattern_1[L1_NUM_ANT_NRRW_PATTERN] = PHY_ANT_ANGLE antNrrwPattern_1[L1_NUM_ANT_NRRW_PATTERN] =
{ {
{.oaxis = 0 , .raxis = 0 }, {.oaxis = 0 , .raxis = 0 },
{.oaxis = 139, .raxis = 1155}, {.oaxis = 139, .raxis = 1155},
@@ -198,30 +204,34 @@ static int32_t Scan_InitScanHandler(L2_INST *instPtr)
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM; L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
DBG_INFO("** Net-Setup - InitScan Procedure (Attempts: %" PRIu8 ")**\n", scanFsmPtr->scanCnt); DBG_INFO("** Net-Setup - InitScan Procedure (Attempts: %" PRIu8 ")**\n", scanFsmPtr->scanCnt);
if(scanFsmPtr->scanCnt == 0) if (scanFsmPtr->scanCnt == 0)
{ {
// Update scan beam table // Update scan beam table
L2_Scan_RefreashScanTable(instPtr); L2_Scan_RefreashScanTable(instPtr);
} }
else if(Phy_IsFrameDetected(phyRef)) else if (Phy_IsFrameDetected(phyRef))
{ {
// last scan beam number // last scan beam number
instPtr->scanFSM->beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr); scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
// Update scan beam table // Update scan beam table
L2_Scan_RefreashScanTable(instPtr); L2_Scan_RefreashScanTable(instPtr);
} }
if (scanFsmPtr->isLocked == true) if (scanFsmPtr->isLocked == true)
{ {
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE); scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
/* Antenna setting (reserved.) */ Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME); L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
} /* Otherwise remain L2_SCAN_INIT_STAGE */ } /* Otherwise remain L2_SCAN_INIT_STAGE */
else else
{ {
/* Antenna setting (reserved.) */ /* Antenna steering (reserved, automatically accomplished by physical layer) */
Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME); L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME);
scanFsmPtr->scanCnt++; scanFsmPtr->scanCnt++;
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
} }
return SUCCESS; return SUCCESS;
} }
@@ -239,19 +249,22 @@ static int32_t Scan_InitScanHandler(L2_INST *instPtr)
******************************************************************************/ ******************************************************************************/
static int32_t Scan_AdvHandler(L2_INST *instPtr) static int32_t Scan_AdvHandler(L2_INST *instPtr)
{ {
ASSERT(instPtr != NULL);
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM; L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("** Net-Setup - Advertisement Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->advTimeout); DBG_INFO("** Net-Setup - Advertisement Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->advTimeout);
// if received a valid bm frame. // if received a valid bm frame.
if (scanFsmPtr->isAdvRecvd == true) if (scanFsmPtr->isAdvRecvd == true)
{ {
// last scan beam number // last scan beam number
instPtr->scanFSM->beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr); scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
// reset listen counter.
scanFsmPtr->advTimeout = 0;
scanFsmPtr->advTimeout = 0; /* reset listen counter. */ // Update scan stage
DBG_INFO("Received Adv frame, skipping 10ms for turn around...\n");
// TODO: check functionality.
StageUpdate(scanFsmPtr, L2_SCAN_CFM_STAGE); StageUpdate(scanFsmPtr, L2_SCAN_CFM_STAGE);
DBG_INFO("Received Adv frame, skipping 10ms for turn around...\n");
return SUCCESS; return SUCCESS;
} }
// no valid bm frame was received. // no valid bm frame was received.
@@ -260,16 +273,20 @@ static int32_t Scan_AdvHandler(L2_INST *instPtr)
/* if time out reached, go back to init scan stage. */ /* if time out reached, go back to init scan stage. */
if (scanFsmPtr->advTimeout > ADV_LISTEN_TIMEOUT) if (scanFsmPtr->advTimeout > ADV_LISTEN_TIMEOUT)
{ {
/* Antenna setting (reserved.) */ /* Antenna steering (reserved, automatically accomplished by physical layer) */
Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME); L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME);
DBG_WARNING("Adv timeout, restart net scan from L2_SCAN_INIT_STAGE.\n"); DBG_WARNING("Adv timeout, restart net scan from L2_SCAN_INIT_STAGE.\n");
L2_Scan_Reset(scanFsmPtr); L2_Scan_Reset(scanFsmPtr);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
} }
else else
{ {
/* Antenna setting (reserved.) */ /* Antenna steering (reserved, automatically accomplished by physical layer) */
Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME); L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME);
scanFsmPtr->advTimeout++; scanFsmPtr->advTimeout++;
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
} }
return SUCCESS; return SUCCESS;
} }
@@ -286,7 +303,9 @@ static int32_t Scan_AdvHandler(L2_INST *instPtr)
******************************************************************************/ ******************************************************************************/
static int32_t Scan_CfmHandler(L2_INST *instPtr) static int32_t Scan_CfmHandler(L2_INST *instPtr)
{ {
ASSERT(instPtr != NULL);
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM; L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("** Net-Setup - Confirm Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->cfmTimeout); DBG_INFO("** Net-Setup - Confirm Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->cfmTimeout);
// 2 way acq failed, back to init stage. // 2 way acq failed, back to init stage.
@@ -300,9 +319,9 @@ static int32_t Scan_CfmHandler(L2_INST *instPtr)
{ {
// using pull mode to receive confirm frame // using pull mode to receive confirm frame
// since first time sync procedure is accomplished in ADV stage. // since first time sync procedure is accomplished in ADV stage.
Phy_SetBeamWidth(instPtr->config.phyInstPtr, PHY_ANT_BEAM_16); Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
Phy_SetBeamNo(instPtr->config.phyInstPtr, scanFsmPtr->beamNo, PHY_ANT_BEAM_16); Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL); Phy_SetMode(phyRef, PHY_MODE_PULL);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_CFM_FRAME); L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_CFM_FRAME);
scanFsmPtr->cfmTimeout++; // increase counter. scanFsmPtr->cfmTimeout++; // increase counter.
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16; instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
@@ -327,12 +346,13 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
int32_t Status; int32_t Status;
uint32_t dataChunk; uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData; uint8_t *buff = instPtr->sendPktData;
if(type < L2_ADV_FRAME || type > L2_CFM_FRAME) if (type < L2_ADV_FRAME || type > L2_CFM_FRAME)
{ {
DBG_ERROR("Unexpected frame type: %" PRId8 ".\n", type); DBG_ERROR("Unexpected frame type: %" PRId8 ".\n", type);
return EPARAM; return EPARAM;
} }
// Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr); dataChunk = L2_GetNextFrameNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk); L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk);
dataChunk = L2_GetNextSlotNum(instPtr); dataChunk = L2_GetNextSlotNum(instPtr);
@@ -382,7 +402,7 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
// Packing extra payload // Packing extra payload
uint32_t dataId; uint32_t dataId;
if(L2_GetNodeType(instPtr) == L2_NODE_HEAD) if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{ {
SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX); SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
} }
@@ -404,6 +424,10 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status); DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
return Status; return Status;
} }
// Logging...
memcpy(instPtr->log.txLog.data, buff, L2_CMF_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break; break;
} }
default: default:
@@ -415,6 +439,208 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/
/**
* @brief Scan net packet handler.
*
* @param instPtr a pointer to linklayer layer instance
* @param msg A pointer to frame data buffer.
*
* @return
*
******************************************************************************/
int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
int32_t Status;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
switch (frameType)
{
case L2_SCAN_FRAME:
case L2_ADV_FRAME:
{
if (L2_GetLastOptFrameType(instPtr) == L2_SCAN_FRAME)
{
LockStateUpdate(scanFsmPtr, true);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
}
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
DBG_ERROR("Unexpected call from head node, only member Node can handle L2_SCAN_FRAME and L2_ADV_FRAME.\n");
Status = EUNEXP;
break;
}
uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId);
NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
{
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if (node == NULL)
{
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
Status = ENOMEM;
break;
}
}
// Update node info.
float nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double)nodePos;
node->nodeInfo.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr);
// Reset node ttl
node->ttlCnt = 0;
uint32_t netstartTime;
// Update net start time.
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &netstartTime);
L2_EVENT netSetupDoneEvent = {
.event = L2_EV_NET_ADV_UPDATE,
.msg = &netstartTime};
AssertL2Event(instPtr, &netSetupDoneEvent);
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
// trigger flag
AdvRecvStateUpdate(scanFsmPtr, true);
Status = SUCCESS;
break;
}
case L2_CFM_FRAME:
{
uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId);
NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
{
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if (node == NULL)
{
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
Status = ENOMEM;
break;
}
}
// Update node info.
float nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double)nodePos;
float nodeSpeed;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &nodeSpeed);
node->nodeInfo.speed.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &nodeSpeed);
node->nodeInfo.speed.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &nodeSpeed);
node->nodeInfo.speed.z = (double)nodePos;
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// check if net setup finished.
if (L2_isCxn2Net(instPtr) == false)
{
// Assert Net-Setup Done.
L2_EVENT l2Event;
l2Event.event = L2_EV_NET_SETUP_DONE;
l2Event.msg = NULL;
AssertL2Event(instPtr, &l2Event);
// Assert update routine event...
L2_RTNE_CONFIG newRtneConfig = {0};
L2_EVENT rtneUpEvent =
{
.event = L2_ROUTINE_UPDATE,
.msg = &newRtneConfig
};
newRtneConfig.rtneTable = initTable;
newRtneConfig.rtnePrd = ARRAY_SIZE(initTable);
AssertL2Event(instPtr, &rtneUpEvent);
}
PendCfmAck(instPtr->scanFSM);
}
else
{
if (L2_GetMainState(instPtr) == L2_INIT_STATE
&& L2_GetNodeListLen(instPtr->nodeList) >= instPtr->config.netScale - 1)
{
// Assert Net-Setup Done.
L2_EVENT l2Event;
L2_NODE_STATE newState = L2_NORMAL_STATE;
l2Event.event = L2_EV_MAIN_STATE_UPDATE;
l2Event.msg = &newState;
AssertL2Event(instPtr, &l2Event);
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
// Get data payload
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
}
// Logging...
memcpy(instPtr->log.rxLog.data, msg, L2_CMF_PACK_LEN);
instPtr->log.rxLog.dataId = dataId;
Status = SUCCESS;
break;
}
default:
DBG_ERROR("Unsupported frame type: %" PRId8 ".\n", frameType);
Status = EUNEXP;
break;
}
return Status;
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Initialize scan FSM. * @brief Initialize scan FSM.
@@ -500,204 +726,6 @@ void L2_Scan_RefreashScanTable(L2_INST *instPtr)
} }
} }
/*****************************************************************************/
/**
* @brief Scan net packet handler.
*
* @param instPtr a pointer to linklayer layer instance
* @param msg A pointer to frame data buffer.
*
* @return
*
******************************************************************************/
int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
int32_t Status;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
L2_FRAME_TYPE frameType = L2_GetLastOptFrameType(instPtr);
switch (frameType)
{
case L2_SCAN_FRAME:
LockStateUpdate(scanFsmPtr, true);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
case L2_ADV_FRAME:
{
if (instPtr->config.myType == L2_NODE_HEAD)
{
DBG_ERROR("Unexpected call from head node, only member Node can handle L2_SCAN_FRAME and L2_ADV_FRAME.\n");
Status = EUNEXP;
break;
}
uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId);
NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
{
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if(node == NULL)
{
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
Status = ENOMEM;
break;
}
}
// Update node info.
float nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double) nodePos;
node->nodeInfo.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr);
// Reset node ttl
node->ttlCnt = 0;
uint32_t netstartTime;
// Update net start time.
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &netstartTime);
L2_EVENT netSetupDoneEvent = {
.event = L2_EV_NET_ADV_UPDATE,
.msg = &netstartTime};
AssertL2Event(instPtr, &netSetupDoneEvent);
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
// trigger flag
AdvRecvStateUpdate(scanFsmPtr, true);
Status = SUCCESS;
break;
}
case L2_CFM_FRAME:
{
uint8_t nodeId;
L2_FrameGetChunk(msg, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &nodeId);
NODE_ENTRY *node;
node = L2_GetNodeById(instPtr->nodeList, nodeId);
if (node == NULL)
{
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if(node == NULL)
{
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
Status = ENOMEM;
break;
}
}
// Update node info.
float nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double) nodePos;
float nodeSpeed;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &nodeSpeed);
node->nodeInfo.speed.x = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &nodeSpeed);
node->nodeInfo.speed.y = (double) nodePos;
L2_FrameGetChunk(msg, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &nodeSpeed);
node->nodeInfo.speed.z = (double) nodePos;
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// check if net setup finished.
if (L2_isCxn2Net(instPtr) == false)
{
// Assert Net-Setup Done.
L2_EVENT l2Event;
l2Event.event = L2_EV_NET_SETUP_DONE;
l2Event.msg = NULL;
AssertL2Event(instPtr, &l2Event);
// Assert update routine event...
L2_RTNE_CONFIG newRtneConfig = {0};
L2_EVENT rtneUpEvent =
{
.event = L2_ROUTINE_UPDATE,
.msg = &newRtneConfig
};
newRtneConfig.rtneTable = initTable;
newRtneConfig.rtnePrd = ARRAY_SIZE(initTable);
AssertL2Event(instPtr, &rtneUpEvent);
}
PendCfmAck(instPtr->scanFSM);
}
else
{
if (L2_GetMainState(instPtr) == L2_INIT_STATE
&& L2_GetNodeListLen(instPtr->nodeList) >= instPtr->config.netScale - 1)
{
// Assert Net-Setup Done.
L2_EVENT l2Event;
L2_NODE_STATE newState = L2_NORMAL_STATE;
l2Event.event = L2_EV_MAIN_STATE_UPDATE;
l2Event.msg = &newState;
AssertL2Event(instPtr, &l2Event);
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
// Get data payload
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if(dataId != DATA_ID_NONE)
{
if(L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayload(msg+L2_MSG_CFM_PAYLOAD, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayload(msg+L2_MSG_CFM_PAYLOAD, PAYLOAD_LEN_LJ_RX);
}
}
Status = SUCCESS;
break;
}
default:
DBG_ERROR("Unsupported frame type: %" PRId8 ".\n", frameType);
Status = EUNEXP;
break;
}
return Status;
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Execute a member node scan net procedure. * @brief Execute a member node scan net procedure.
@@ -756,7 +784,8 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
L2_TOR_TYPE torState; L2_TOR_TYPE torState;
int32_t Status; int32_t Status;
const NODE_ENTRY* commNode; const NODE_ENTRY *commNode;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("-------- Scan Routine --------\n"); DBG_INFO("-------- Scan Routine --------\n");
if (rtneEntry->slotSeq != 0) if (rtneEntry->slotSeq != 0)
@@ -782,11 +811,11 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
} }
// Setup antenna beam // Setup antenna beam
Phy_SetBeamWidth(instPtr->config.phyInstPtr, PHY_ANT_BEAM_16); Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16; instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
if (commNode != NULL) if (commNode != NULL)
{ {
Phy_SetBeamNo(instPtr->config.phyInstPtr, commNode->nodeInfo.beamNo, PHY_ANT_BEAM_16); Phy_SetBeamNo(phyRef, commNode->nodeInfo.beamNo, PHY_ANT_BEAM_16);
} }
} }
else else
@@ -804,7 +833,7 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
torState = L2_TOR_SUSPEND; torState = L2_TOR_SUSPEND;
} }
// Setup antenna beam // Setup antenna beam
Phy_SetBeamWidth(instPtr->config.phyInstPtr, PHY_ANT_BEAM_120); Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120; instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120;
} }
@@ -870,3 +899,6 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
routine_err: routine_err:
return Status; return Status;
} }
/** @} LinkLayer_Scan*/
/** @} LinkLayer*/
@@ -1,19 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Event scheduling implementation * @file schdevent.c
* @author FanHao ([email protected])
* @brief DF Linklayer Event scheduling implementation file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-12-21 13:32 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditors: Fan Hao * Lab of Communication and Network
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scheduler
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdlib.h> #include <stdlib.h>
#include "schdevent.h" #include "schdevent.h"
@@ -428,3 +433,6 @@ inline bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent)
ASSERT(schdEvent != NULL); ASSERT(schdEvent != NULL);
return schdEvent->isSchd; return schdEvent->isSchd;
} }
/** @} LinkLayer_Scheduler*/
/** @} LinkLayer*/
@@ -1,18 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Event scheduling implementation * @file schdevent.c
* @author FanHao ([email protected])
* @brief DF Linklayer Event scheduling header file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-12-21 13:32 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditors: Fan Hao * Lab of Communication and Network
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scheduler
* @{
*/
#ifndef SCHDEVENT_H_ #ifndef SCHDEVENT_H_
#define SCHDEVENT_H_ #define SCHDEVENT_H_
@@ -24,8 +30,9 @@
#include "clist.h" #include "clist.h"
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/** @name L2 event /**
* A definition of L2 event instance. * @struct L2_SCHD_EVENT
* @brief Linklayer scheduled event descriptor
*/ */
typedef struct typedef struct
{ {
@@ -38,8 +45,9 @@ typedef struct
uint32_t schdSlot; uint32_t schdSlot;
} L2_SCHD_EVENT; } L2_SCHD_EVENT;
/** @name L2 event /**
* A definition of L2 event instance. * @struct L2_SCHD_POOL
* @brief Linklayer schedule event pool instance
*/ */
typedef struct typedef struct
{ {
@@ -63,3 +71,6 @@ bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent); int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent);
#endif // SCHDEVENT_H_ #endif // SCHDEVENT_H_
/** @} LinkLayer_Scheduler*/
/** @} LinkLayer*/
+111 -100
View File
@@ -1,18 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Implementations for df datalink service net. * @file service.c
* Date: 2021-11-16 00:08 * @author FanHao ([email protected])
* LastEditTime: 2022-07-16 17:04 * @brief DF Linklayer service implementation file.
* Revisions: Rev 0.1 * @version 0.0
* History: * @date 2023-05-06
* [2022-07-16]: New branch for DiJian.
* [2021-11-16]: Initial version.
* *
* Copyright(c) 2021 Beijing Institute of Technology. * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Networking * Lab of Communication and Network
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Service
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
@@ -88,6 +94,7 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
uint32_t dataChunk; uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData; uint8_t *buff = instPtr->sendPktData;
// Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr); dataChunk = L2_GetNextFrameNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk); L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk);
dataChunk = L2_GetNextSlotNum(instPtr); dataChunk = L2_GetNextSlotNum(instPtr);
@@ -113,7 +120,7 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &(instPtr->sysInfo.vZ)); L2_FrameInsertChunk(buff, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &(instPtr->sysInfo.vZ));
uint32_t dataId; uint32_t dataId;
if(L2_GetNodeType(instPtr) == L2_NODE_HEAD) if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{ {
SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX); SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
} }
@@ -128,12 +135,6 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData); L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData);
} }
// // packing payload
// uint32_t dataId;
// dataId = DATA_ID_TEST;
// L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
// L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData);
Status = L2_CrcAppend(buff, L2_SVC_PACK_LEN - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_CRC, L2_CRC16_1021); Status = L2_CrcAppend(buff, L2_SVC_PACK_LEN - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_CRC, L2_CRC16_1021);
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
@@ -141,8 +142,8 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
return Status; return Status;
} }
memcpy(instPtr->serviceFSM->txLog.data, buff, L2_SVC_PACK_LEN); memcpy(instPtr->log.txLog.data, buff, L2_SVC_PACK_LEN);
instPtr->serviceFSM->txLog.dataId = dataId; instPtr->log.txLog.dataId = dataId;
break; break;
} }
default: default:
@@ -159,62 +160,6 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
#endif #endif
} }
/*****************************************************************************/
/**
* @brief Initialize service net FSM
*
* @param serviceFSM A pointer to service FSM instance.
*
* @return SUCCESS Initialize successfully.
* Other Initialize failed.
*
******************************************************************************/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
*svcFSMPtr = (L2_SVC_FSM *)malloc(sizeof(L2_SVC_FSM));
if (*svcFSMPtr == NULL)
{
return ENOMEM;
}
L2_Service_Reset(*svcFSMPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ServiceNet FSM
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
memset((&svcFSMPtr->rxLog), 0x00, sizeof(PAYLOAD));
memset((&svcFSMPtr->txLog), 0x00, sizeof(PAYLOAD));
#ifdef DATALINK_ENABLE_BERTEST
svcFSMPtr->bitTotal = 0;
svcFSMPtr->bitError = 0;
#endif
}
/*****************************************************************************/
/**
* @brief Destroy ServiceNet FSM, free memory
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Destroy(L2_SVC_FSM *serviceFSM)
{
free(serviceFSM);
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Handle service received packet. Send data up to MPC * @brief Handle service received packet. Send data up to MPC
@@ -231,7 +176,7 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
ASSERT(msg != NULL); ASSERT(msg != NULL);
int32_t Status; int32_t Status;
#ifndef DATALINK_ENABLE_BERTEST #ifndef DATALINK_ENABLE_BERTEST
uint8_t frameType; L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType); L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
switch (frameType) switch (frameType)
{ {
@@ -244,7 +189,7 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
if (node == NULL) if (node == NULL)
{ {
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER); node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
if(node == NULL) if (node == NULL)
{ {
DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId); DBG_ERROR("Failed to append new node [id: %" PRIu8 "]", nodeId);
Status = ENOMEM; Status = ENOMEM;
@@ -255,18 +200,18 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
// Update node info. // Update node info.
float nodePos; float nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSX, L2_MSG_SVC_SRC_POSX_LEN, &nodePos); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSX, L2_MSG_SVC_SRC_POSX_LEN, &nodePos);
node->nodeInfo.pos.x = (double) nodePos; node->nodeInfo.pos.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSY, L2_MSG_SVC_SRC_POSY_LEN, &nodePos); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSY, L2_MSG_SVC_SRC_POSY_LEN, &nodePos);
node->nodeInfo.pos.y = (double) nodePos; node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSZ, L2_MSG_SVC_SRC_POSZ_LEN, &nodePos); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_POSZ, L2_MSG_SVC_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double) nodePos; node->nodeInfo.pos.z = (double)nodePos;
float nodeSpeed; float nodeSpeed;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDX, L2_MSG_SVC_SRC_SPEEDX_LEN, &nodeSpeed); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDX, L2_MSG_SVC_SRC_SPEEDX_LEN, &nodeSpeed);
node->nodeInfo.speed.x = (double) nodePos; node->nodeInfo.speed.x = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDY, L2_MSG_SVC_SRC_SPEEDY_LEN, &nodeSpeed); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDY, L2_MSG_SVC_SRC_SPEEDY_LEN, &nodeSpeed);
node->nodeInfo.speed.y = (double) nodePos; node->nodeInfo.speed.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &nodeSpeed); L2_FrameGetChunk(msg, L2_MSG_SVC_SRC_SPEEDZ, L2_MSG_SVC_SRC_SPEEDZ_LEN, &nodeSpeed);
node->nodeInfo.speed.z = (double) nodePos; node->nodeInfo.speed.z = (double)nodePos;
// Reset node ttl // Reset node ttl
node->ttlCnt = 0; node->ttlCnt = 0;
@@ -285,21 +230,19 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
uint32_t dataId; uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId); L2_FrameGetChunk(msg, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
if(dataId != DATA_ID_NONE) if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{ {
if(L2_GetNodeType(instPtr) == L2_NODE_HEAD) SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
{ }
SysMonitor_UpdateRecvPayload(msg+L2_MSG_SVC_PAYLOAD, PAYLOAD_LEN_FLJ_RX); else
} {
else SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
{
SysMonitor_UpdateRecvPayload(msg+L2_MSG_SVC_PAYLOAD, PAYLOAD_LEN_LJ_RX);
}
} }
// Logging // Logging
memcpy(instPtr->serviceFSM->rxLog.data, msg, L2_SVC_PACK_LEN); memcpy(instPtr->log.rxLog.data, msg, L2_SVC_PACK_LEN);
instPtr->serviceFSM->rxLog.dataId = dataId; instPtr->log.rxLog.dataId = dataId;
instPtr->serviceFSM->rxdCnt++;
#ifdef DATALINK_ENABLE_AUTOTIMESYNC #ifdef DATALINK_ENABLE_AUTOTIMESYNC
// Implement a auto time sync. // Implement a auto time sync.
@@ -346,6 +289,65 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
#endif #endif
} }
/*****************************************************************************/
/**
* @brief Initialize service net FSM
*
* @param serviceFSM A pointer to service FSM instance.
*
* @return SUCCESS Initialize successfully.
* Other Initialize failed.
*
******************************************************************************/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
*svcFSMPtr = (L2_SVC_FSM *)malloc(sizeof(L2_SVC_FSM));
if (*svcFSMPtr == NULL)
{
return ENOMEM;
}
L2_Service_Reset(*svcFSMPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ServiceNet FSM
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
svcFSMPtr->txCnt = 0;
svcFSMPtr->rxCnt = 0;
svcFSMPtr->rxdCnt = 0;
#ifdef DATALINK_ENABLE_BERTEST
svcFSMPtr->bitTotal = 0;
svcFSMPtr->bitError = 0;
svcFSMPtr->lossRate = 0;
svcFSMPtr->errorRate = 0;
#endif
}
/*****************************************************************************/
/**
* @brief Destroy ServiceNet FSM, free memory
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Destroy(L2_SVC_FSM *serviceFSM)
{
free(serviceFSM);
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Service FSM Routine. * @brief Service FSM Routine.
@@ -366,9 +368,10 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
return SUCCESS; // skip return SUCCESS; // skip
} }
PHY_INST* phyRef = instPtr->config.phyInstPtr; PHY_INST *phyRef = instPtr->config.phyInstPtr;
L2_SVC_FSM *svcFSMPtr = instPtr->serviceFSM;
L2_TOR_TYPE torState; L2_TOR_TYPE torState;
const NODE_ENTRY* commNode; const NODE_ENTRY *commNode;
if (rtneEntry->src == L2_GetNodeId(instPtr)) if (rtneEntry->src == L2_GetNodeId(instPtr))
{ {
torState = L2_TOR_TX; torState = L2_TOR_TX;
@@ -402,6 +405,7 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
case L2_SLOT_SERVICE: case L2_SLOT_SERVICE:
if (torState == L2_TOR_TX) if (torState == L2_TOR_TX)
{ {
svcFSMPtr->txCnt++;
#ifndef DATALINK_ENABLE_BERTEST #ifndef DATALINK_ENABLE_BERTEST
// Packing service data // Packing service data
Service_Packing(instPtr, L2_SVC_FRAME, rtneEntry->dst); Service_Packing(instPtr, L2_SVC_FRAME, rtneEntry->dst);
@@ -409,6 +413,10 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
memcpy(instPtr->sendPktData, testData, L2_SVC_PACK_LEN); memcpy(instPtr->sendPktData, testData, L2_SVC_PACK_LEN);
#endif #endif
} }
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME); L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME);
break; break;
default: default:
@@ -417,11 +425,14 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
} }
#ifdef DATALINK_ENABLE_BERTEST #ifdef DATALINK_ENABLE_BERTEST
uint32_t pktLoss; uint32_t pktLoss;
pktLoss = instPtr->log.svcRecvCnt - instPtr->log.svcCorrectCnt; pktLoss = svcFSMPtr->rxCnt - svcFSMPtr->rxdCnt;
instPtr->serviceFSM->lossRate = (instPtr->log.svcRecvCnt == 0) ? 0 : (double)pktLoss / (double)instPtr->serviceFSM->pktRecv; svcFSMPtr->lossRate = (svcFSMPtr->rxCnt == 0) ? 0 : (double)pktLoss / (double)svcFSMPtr->rxCnt;
instPtr->serviceFSM->errorRate = (instPtr->serviceFSM->bitTotal == 0) ? 0 : (double)instPtr->serviceFSM->bitError / (double)instPtr->serviceFSM->bitTotal; svcFSMPtr->errorRate = (svcFSMPtr->bitTotal == 0) ? 0 : (double)svcFSMPtr->bitError / (double)svcFSMPtr->bitTotal;
DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->serviceFSM->pktRecv, pktLoss); DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->log.svcRxCnt, pktLoss);
DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", instPtr->serviceFSM->bitTotal, instPtr->serviceFSM->bitError); DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", svcFSMPtr->bitTotal, svcFSMPtr->bitError);
#endif #endif
return SUCCESS; return SUCCESS;
} }
/** @} LinkLayer_Service*/
/** @} LinkLayer*/
@@ -1,21 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Time sync implementation file. * @file time_sync.c
* @author FanHao ([email protected])
* @brief DF Linklayer time sync implementation file.
* @version 0.0
* @date 2023-05-06
* *
* Author: Author's name * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Date: 2021-12-04 16:32 * Lab of Communication and Network
* LastEditors: FanHao
* LastEditTime: 2022-07-10 20:43
* Revisions: Rev 0.0
* History:
* [2022-07-10]: New branch for Dijian.
* [2021-12-04]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_TimeSync
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@@ -49,7 +52,8 @@ int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNu
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
ASSERT(timeDev != NULL); ASSERT(timeDev != NULL);
L1_FRAME_TYPE lastRecvdFrame; L1_FRAME_TYPE lastRecvdFrame;
lastRecvdFrame = Phy_GetLastRecvFrameType(instPtr->config.phyInstPtr); PHY_INST *phyRef = instPtr->config.phyInstPtr;
lastRecvdFrame = Phy_GetLastRecvFrameType(phyRef);
if (lastRecvdFrame == L1_NONE_FRAME) if (lastRecvdFrame == L1_NONE_FRAME)
{ {
DBG_ERROR("Invalid TimeAlign operation, no frame was received."); DBG_ERROR("Invalid TimeAlign operation, no frame was received.");
@@ -68,7 +72,7 @@ int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNu
expectTime += (uint64_t)instPtr->netStartTime * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX; expectTime += (uint64_t)instPtr->netStartTime * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX;
} }
Phy_GetLastReceivedFrameSyncTimeStamp(instPtr->config.phyInstPtr, &timeStamp); Phy_GetLastReceivedFrameSyncTimeStamp(phyRef, &timeStamp);
currTime = (uint64_t)timeStamp.frac_part; currTime = (uint64_t)timeStamp.frac_part;
currTime += ((uint64_t)timeStamp.int_part) * TIME_FRAC_MAX; currTime += ((uint64_t)timeStamp.int_part) * TIME_FRAC_MAX;
@@ -76,7 +80,6 @@ int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNu
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Implement time adjustment by applying time deviation. * @brief Implement time adjustment by applying time deviation.
@@ -96,3 +99,7 @@ void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev)
slotTimerAdjmet.frac_part = (uint32_t)(*timeDev % TIME_FRAC_MAX); slotTimerAdjmet.frac_part = (uint32_t)(*timeDev % TIME_FRAC_MAX);
TimeCtrl_TimeAdjust(instPtr->config.tmcInstPtr, &slotTimerAdjmet, TM_ADJ_ADD); TimeCtrl_TimeAdjust(instPtr->config.tmcInstPtr, &slotTimerAdjmet, TM_ADJ_ADD);
} }
/** @} LinkLayer_TimeSync*/
/** @} LinkLayer*/
@@ -15,12 +15,26 @@
* Lab of Communication and Networking * Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup PhysicalLayer
* @{
*/
/**
* @addtogroup PhysicalLayer_AntennaControl
* @{
*/
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
#include "error.h" #include "error.h"
#include "phy_layer.h" #include "phy_layer.h"
/**
* @name PhysicalLayer_AntennaConfig_Constants
* @{
*/
#define ANT_PI 3.14159265358979323846 #define ANT_PI 3.14159265358979323846
#define ANT_COINFO_HEAD 0xAA #define ANT_COINFO_HEAD 0xAA
@@ -29,10 +43,10 @@
#define CTRL_WORD_DEFAULT 0x00 #define CTRL_WORD_DEFAULT 0x00
#define ANT_MODE_BEAM_MASK 0xF0 #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_0 0x10 // 25
#define ANT_BEAM_SUBNARROR_1 0x20 // 60 #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_MODE_POWER_MASK 0x0F
#define ANT_POWER_FULL 0x00 #define ANT_POWER_FULL 0x00
@@ -57,21 +71,16 @@
// Pair by regex // Pair by regex
// Regex: (([0-9]+, ){8}) // Regex: (([0-9]+, ){8})
uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] = const uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] =
{
0
};
uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] =
{ {
1500 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, 0, 44, 88, 131, 175, 219, 263, 306,
350, 394, 438, 481, 525, 569, 613, 656, 350, 394, 438, 481, 525, 569, 613, 656,
700, 744, 788, 831, 875, 919, 963, 1006, 700, 744, 788, 831, 875, 919, 963, 1006,
1050, 1094, 1138, 1181, 1225, 1269, 1313, 1356, 1050, 1094, 1138, 1181, 1225, 1269, 1313, 1356,
1400, 1444, 1488, 1531, 1575, 1619, 1663, 1706, 1400, 1444, 1488, 1531, 1575, 1619, 1663, 1706,
1750, 1794, 1838, 1881, 1925, 1969, 2013, 2056, 1750, 1794, 1838, 1881, 1925, 1969, 2013, 2056,
@@ -82,57 +91,46 @@ uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] =
3500 3500
}; };
uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = const uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] =
{ {
1500 1500
}; };
//uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = const 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] =
{ {
1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 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, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1550,
1500 1500
}; };
//uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = const 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] =
{ {
1700, 1800, 1900, 2000, 1700, 1700, 1700, 1700, 1700, 1800, 1900, 2000, 1700, 1700, 1700, 1700,
1700, 1700, 1700, 1700, 1700, 1700, 1700, 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, 1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800,
1900, 2000, 1500, 1500 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, 500, 600, 700, 800, 900, 1000, 500, 600,
700, 800, 900, 1000, 500, 600, 700, 800, 700, 800, 900, 1000, 500, 600, 700, 800,
900, 1000, 500, 500 900, 1000, 500, 500
}; };
/** @} PhysicalLayer_AntennaConfig_Constants*/
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief Initialize antenna configurations (load preset values) * @brief Initialize antenna configurations (load preset values)
@@ -224,6 +222,8 @@ void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode)
} }
instPtr->phyLog.antMode = mode; instPtr->phyLog.antMode = mode;
instPtr->antConfig.antMode = config; instPtr->antConfig.antMode = config;
// Sync logs to system monitor
SysMonitor_UpdatePhysicalLayerLog(&(instPtr->phyLog));
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -243,10 +243,10 @@ void Phy_SetBeamTable(PHY_INST *instPtr, PHY_ANT_ANGLE *table, uint32_t offset)
ASSERT(table != NULL); ASSERT(table != NULL);
for (int i = 0; i < L1_NUM_ANT_NRRW_PATTERN; i++) 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, memcpy((uint32_t *)instPtr->antInfoAddr, instPtr->antNrrwPattern,
L1_NUM_ANT_NRRW_PATTERN*sizeof(PHY_ANT_ANGLE)); L1_NUM_ANT_NRRW_PATTERN * sizeof(PHY_ANT_ANGLE));
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -365,3 +365,7 @@ int32_t Phy_SetBeamAngle(PHY_INST *instPtr, double offAx, double rndAx)
instPtr->antConfig.raxis[1] = (uint8_t)rndAxDeg; instPtr->antConfig.raxis[1] = (uint8_t)rndAxDeg;
return SUCCESS; return SUCCESS;
} }
/** @} PhysicalLayer_AntennaControl*/
/** @} PhysicalLayer*/
File diff suppressed because it is too large Load Diff
@@ -1,26 +1,21 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Physical layer control definitions and function prototypes. * @file phy_layer.c
* @author FanHao ([email protected])
* @brief Physical layer control header file.
* @version 0.0
* @date 2023-04-24
* *
* Date: 2021-12-04 16:32 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2024-01-20 17:41 * Lab of Communication and Network
* Revisions: Rev 0.1
* History:
* [2021-12-08]: Initial version.
* [2022-06-18]: New branch for glink control purpose:
* -Add poll mode, physical layer will start Tx/Rx procedure
* at specific time stamp.
* -Add 61/37 beam switch
* -Code simplification.
* [2023-04-24]: Feature add:
* - Read frame type from PL status register.
* [2024-01-20]: New branch for DUIFEI.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup PhysicalLayer
* @{
*/
#ifndef PHY_CTRL_H_ #ifndef PHY_CTRL_H_
#define PHY_CTRL_H_ #define PHY_CTRL_H_
@@ -35,13 +30,17 @@
#include "../../system_monitor.h" #include "../../system_monitor.h"
#include "../../time_ctrl/time_ctrl.h" #include "../../time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/**
* @name PhysicalLayer_Common_Constant
* @{
*/
#define L1_NUM_ANT_NRRW_PATTERN 37 #define L1_NUM_ANT_NRRW_PATTERN 37
#define L1_INIT_BEAM_NO 0 #define L1_INIT_BEAM_NO 0
#define L1_INIT_ANT_WD PHY_ANT_BEAM_120 #define L1_INIT_ANT_WD PHY_ANT_BEAM_120
#define L1_INIT_ANT_NO 0 #define L1_INIT_ANT_NO 0
#define L1_FRAME_NONE_LEN UINT32_MAX // byte #define L1_FRAME_NONE_LEN UINT32_MAX // byte
#define L1_FRAME_NONE_COMP UINT32_MAX // *10ns(Timer_L) #define L1_FRAME_NONE_COMP UINT32_MAX // *10ns(Timer_L)
#define L1_FRAME_NONE_HOPS UINT32_MAX #define L1_FRAME_NONE_HOPS UINT32_MAX
#define L1_FRAME_MAX_HOPS 81 #define L1_FRAME_MAX_HOPS 81
#define L1_FRAME_2KBPS_20MS_HOPS 1 #define L1_FRAME_2KBPS_20MS_HOPS 1
@@ -52,11 +51,13 @@
#define L1_FRAME_40KBPS_10MS_HOPS 9 #define L1_FRAME_40KBPS_10MS_HOPS 9
#define L1_FRAME_200KBPS_5MS_HOPS 20 #define L1_FRAME_200KBPS_5MS_HOPS 20
#define L1_FRAME_1M2BPS_5MS_HOPS 20 #define L1_FRAME_1M2BPS_5MS_HOPS 20
#define PHY_LOG_EXPIRE 40 // 50*5ms
#define PHY_TIME_WORD_H_MAX UINT32_MAX /** @} */
#define PHY_TIME_WORD_L_MAX 0x0007A120 // 5ms/10ns
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/**
* @enum L1_FRAME_TYPE
*/
typedef enum typedef enum
{ {
L1_NONE_FRAME = 0, L1_NONE_FRAME = 0,
@@ -70,71 +71,63 @@ typedef enum
L1_1M2BPS_5MS_FRAME = 8 L1_1M2BPS_5MS_FRAME = 8
} L1_FRAME_TYPE; } L1_FRAME_TYPE;
/**
* @struct PHY_ANT_CONFIG
* @brief PhysicalLayer antenna config
*/
typedef struct typedef struct
{ {
/*** Ant Control ***/ /*** Ant Control ***/
/* Antenna control frame head 0xAA */ uint8_t ctrlWord; ///< Antenna control frame head 0xAA\n
/* default 0, reserved for further use */ /// default 0, reserved for further use
uint8_t ctrlWord; uint8_t antMode; ///< high 4 bits specified beam mode.\n
/* high 4 bits specified beam mode. /// low 4 bits specified power control
* low 4 bits specified power control */ uint8_t oaxis[2]; ///< off-axis angle range is 0~60 \n
uint8_t antMode; /// 0.1 degree each LSB
/* off-axis angle range is 0~60, uint8_t raxis[2]; ///< round-axis angle range is 0~360, \n
* 0.1 degree each LSB */ /// 0.1 degree each LSB
uint8_t oaxis[2]; uint8_t antFreq[2]; ///< 0~3500Mhz, step 1MHz
/* round-axis angle range is 0~360, uint8_t trSlect; ///< in single tr mode, 0~63 specified tr channel \n
* 0.1 degree each LSB */ /// in single subarray mode, 0~3 specified the subarray
uint8_t raxis[2]; /// ! Only in debug mode!
/* 0~3500Mhz, step 1MHz */ uint8_t antAtt; ///< Antenna attenuation 0~31, 0.5dB each LSB, Only in debug mode
uint8_t antFreq[2]; uint8_t phase; ///< 0~63, 5.625 degree each LSB, Only in debug mode
/* in single tr mode, 0~63 specified tr channel uint8_t rxtxMode; ///< Only for debug \n
* in single subarray mode, 0~3 specified the subarray /// default 0x00
* Only in debug mode*/ uint8_t calibrMode; ///< 0x00 Normal, 0x01 single tr calibration
uint8_t trSlect; uint8_t antReserved; ///< reserved for further use
/* Antenna attenuation 0~31, 0.5dB each LSB, Only in debug mode */
uint8_t antAtt;
/* 0~63, 5.625 degree each LSB, Only in debug mode*/
uint8_t phase;
/* Only for debug */
/* default 0x00 */
uint8_t rxtxMode;
/* 0x00 Normal, 0x01 single tr calibration */
uint8_t calibrMode;
/* reserved for further use */
uint8_t antReserved;
/*** RF Control ***/ /*** RF Control ***/
/* [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default) */ uint8_t rfCtrl; ///< [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default)
uint8_t rfCtrl; uint8_t rfFreq[2]; ///< 0~3500Mhz, step 1MHz
/* 0~3500Mhz, step 1MHz */ uint8_t rfTxMgc; ///< RF MGC control: 0~31, 1dB each LSB
uint8_t rfFreq[2]; uint8_t rf12CalMgc; ///< RF channel 1&2 calibration mgc\n
/* RF MGC control: 0~31, 1dB each LSB*/ /// [7:4] Channle1 - max 15db, 1dB each LSB \n
uint8_t rfTxMgc; /// [3:0] Channle2 - max 15db, 1dB each LSB
/* RF channel 1&2 calibration mgc: [7:4] Channle1 - max 15db, 1dB each LSB uint8_t rf34CalMgc; ///< RF channel 3&4 calibration mgc\n
* [3:0] Channle2 - max 15db, 1dB each LSB*/ /// [7:4] Channle3 - max 15db, 1dB each LSB
uint8_t rf12CalMgc; /// [3:0] Channle4 - max 15db, 1dB each LSB
/* RF channel 3&4 calibration mgc: [7:4] Channle3 - max 15db, 1dB each LSB uint8_t rcvMgc; ///< Receive channel 1-4 MGC: 0~31, 1dB each LSB
* [3:0] Channle4 - max 15db, 1dB each LSB*/ uint8_t rfMonitor; ///< Receive monitor, 0-normal, 1-switch to monitor port
uint8_t rf34CalMgc; uint8_t rfReserved0; ///< reserved for further use
/* Receive channel 1-4 MGC: 0~31, 1dB each LSB */ uint8_t rfReserved1; ///< reserved for further use
uint8_t rcvMgc;
/* Receive monitor, 0-normal, 1-switch to monitor port */
uint8_t rfMonitor;
/* reserved for further use */
uint8_t rfReserved0;
uint8_t rfReserved1;
} PHY_ANT_CONFIG; } PHY_ANT_CONFIG;
/**
* @struct PHY_ANT_ANGLE
* @brief Describe the PhysicalLayer antenna angle
*/
typedef struct typedef struct
{ {
/* off-axis angle range is 0~60, uint16_t oaxis; ///< off-axis angle range is 0~60
* 0.1 degree each LSB */ /// 0.1 degree each LSB
uint16_t oaxis; uint16_t raxis; ///< round-axis angle range is 0~360
/* round-axis angle range is 0~360, /// 0.1 degree each LSB
* 0.1 degree each LSB */
uint16_t raxis;
} PHY_ANT_ANGLE; } PHY_ANT_ANGLE;
/**
* @enum PHY_TIME_WORD_TYPE
*/
typedef enum typedef enum
{ {
PHY_TIME_WORD_NONE = 0, PHY_TIME_WORD_NONE = 0,
@@ -142,6 +135,9 @@ typedef enum
PHY_TIME_WORD_LISTEN_TIMEOUT = 2 PHY_TIME_WORD_LISTEN_TIMEOUT = 2
} PHY_TIME_WORD_TYPE; } PHY_TIME_WORD_TYPE;
/**
* @enum PHY_ANT_BEAM_WIDTH
*/
typedef enum typedef enum
{ {
PHY_ANT_BEAM_NONE = 0, PHY_ANT_BEAM_NONE = 0,
@@ -151,6 +147,9 @@ typedef enum
PHY_ANT_BEAM_16 = 4 PHY_ANT_BEAM_16 = 4
} PHY_ANT_BEAM_WIDTH; } PHY_ANT_BEAM_WIDTH;
/**
* @enum PHY_TOR_TYPE
*/
typedef enum typedef enum
{ {
PHY_TOR_SUSPEND = 0, PHY_TOR_SUSPEND = 0,
@@ -158,6 +157,9 @@ typedef enum
PHY_TOR_RX = 2 PHY_TOR_RX = 2
} PHY_TOR_TYPE; } PHY_TOR_TYPE;
/**
* @enum PHY_MODE
*/
typedef enum typedef enum
{ {
PHY_MODE_NONE = 0, PHY_MODE_NONE = 0,
@@ -166,6 +168,9 @@ typedef enum
PHY_MODE_PULL = 3 PHY_MODE_PULL = 3
} PHY_MODE; } PHY_MODE;
/**
* @enum PHY_ANT_MODE
*/
typedef enum typedef enum
{ {
PHY_ANT_MODE_NONE = 0, PHY_ANT_MODE_NONE = 0,
@@ -174,23 +179,10 @@ typedef enum
PHY_ANT_MODE_POWER_FULL = 3, PHY_ANT_MODE_POWER_FULL = 3,
} PHY_ANT_MODE; } PHY_ANT_MODE;
typedef struct /**
{ * @struct PHY_RCD
uint32_t devId; * @brief Physical Layer recode buffer
uint32_t txBramId; */
uint32_t rxBramId;
uint32_t antBramId;
uint32_t antInfoBramId;
uint32_t hwXadcId;
uintptr_t baseAddr;
#ifndef EMULATION
uint8_t (*get_clk_state)(void);
uint8_t (*get_ad_lock_state)(void);
int8_t (*get_ad0_temp)(void);
int8_t (*get_ad1_temp)(void);
#endif
} PHY_CONFIG;
typedef struct typedef struct
{ {
int32_t last; int32_t last;
@@ -198,84 +190,101 @@ typedef struct
int32_t next; int32_t next;
} PHY_RCD; } PHY_RCD;
/**
* @struct PHY_CONFIG
* @brief struct holds all physical layer initialization parameters
*/
typedef struct typedef struct
{ {
PHY_CONFIG phyCofig; // Device address configs uint32_t devId; ///< device ID
uintptr_t recvDataAddr; uint32_t txBramId; ///< tx bram ID
uintptr_t sendDataAddr; uint32_t rxBramId; ///< rx bram ID
uintptr_t antConfigAddr; uint32_t antBramId; ///< antenna config bram ID
uintptr_t antInfoAddr; uint32_t antInfoBramId; ///< antenna beam info bram ID
bool isPhyEn; // if physical layer running uint32_t hwXadcId; ///< hardware xadc device ID
bool isAcq; // if last reception acquisition success uintptr_t baseAddr; ///< Physical layer controller base address
bool isFrameSync; // if last reception frame sync success
bool isDecode; // if last reception decode success
bool isValid; // if last reception frame data valid (crc check pass)
bool isPresetHop; // 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
PHY_RCD beamNo; // beam number record
PHY_RCD beamWd; // beam width record
PHY_RCD tor; // tx rx state record
PHY_RCD frameType; // frame type record
uint32_t sendDataOffset; // antenna configuration bram offset (to implement ping-pong data flow)
uint32_t antConfigOffset; // antenna configuration bram offset (to implement ping-pong data flow)
PHY_ANT_CONFIG antConfig; // antenna configuration pointer
#ifndef EMULATION #ifndef EMULATION
XAdcPs hwXadc; uint8_t (*get_clk_state)(void); ///< function handle returns hardware clock state
uint8_t (*get_ad_lock_state)(void); ///< function handle returns adc lock state
int8_t (*get_ad0_temp)(void); ///< function handle returns adc0 temperature state
int8_t (*get_ad1_temp)(void); ///< function handle returns adc1 temperature state
#endif #endif
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN]; } PHY_CONFIG;
HWSTATE hwSate;
PHYLOG phyLog; /**
* @struct PHY_INST
* @brief Physical Layer operating instance
*/
typedef struct
{
PHY_CONFIG phyCofig; ///< physical layer configuration parameters
uintptr_t recvDataAddr; ///< receive data bram address
uintptr_t sendDataAddr; ///< send data bram address
uintptr_t antConfigAddr; ///< antenna config data bram address
uintptr_t antInfoAddr; ///< antenna beam info data bram address
bool isPhyEn; ///< indicates if physical layer running
bool isAcq; ///< indicates if last reception acquisition success
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)
TIME_WORD recvSlotTime; ///< last slot start time stamp
TIME_WORD recvFsTime; ///< last frame sync time stamp
PHY_RCD antNo; ///< antenna number record
PHY_RCD beamNo; ///< beam number record
PHY_RCD beamWd; ///< beam width record
PHY_RCD tor; ///< tx rx state record
PHY_RCD frameType; ///< frame type record
uint32_t sendDataOffset; ///< antenna configuration bram offset (to implement ping-pong data flow)
uint32_t antConfigOffset; ///< antenna configuration bram offset (to implement ping-pong data flow)
PHY_ANT_CONFIG antConfig; ///< antenna configuration pointer
#ifndef EMULATION
XAdcPs hwXadc; ///< hardware Xadc instance
#endif
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN]; ///< antenna beam scan pattern
HWSTATE hwSate; ///< hardware state log
PHYLOG phyLog; ///< physical state log
uint32_t lastLogTime; /// physical state log time stamp
} PHY_INST; } 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 ******************************/ /************************** Function Prototypes ******************************/
int32_t Phy_InstInit(PHY_INST **instPtr, PHY_CONFIG *phyConfig);
/**
* @defgroup PhysicalLayer_Main
* @{
*/
int32_t Phy_Init(PHY_INST **instPtr, PHY_CONFIG *phyConfig);
void Phy_Destroy(PHY_INST *instPtr); void Phy_Destroy(PHY_INST *instPtr);
void Phy_UpdateState(PHY_INST *instPtr);
void Phy_RefreshHwSate(PHY_INST *instPtr);
void Phy_Start(PHY_INST *instPtr); void Phy_Start(PHY_INST *instPtr);
void Phy_Halt(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); 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_PeekRecvData(PHY_INST *instPtr, uint8_t *dataBuff);
void Phy_RetrieveRecvData(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_IsFrameDetected(PHY_INST *instPtr);
bool Phy_IsFrameReceived(PHY_INST *instPtr); bool Phy_IsFrameReceived(PHY_INST *instPtr);
bool Phy_IsFrameValid(PHY_INST *instPtr); bool Phy_IsFrameValid(PHY_INST *instPtr);
uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType); 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_GetHopLength(L1_FRAME_TYPE frameType);
uint32_t Phy_GetTimeComp(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*/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig); /**
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode); * @defgroup PhysicalLayer_Receive_Estimations
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);
uint8_t Phy_LastScanBeamNo(PHY_INST *instPtr); uint8_t Phy_LastScanBeamNo(PHY_INST *instPtr);
double Phy_GetFreqEst(PHY_INST *instPtr); double Phy_GetFreqEst(PHY_INST *instPtr);
double Phy_GetCoarseFreqEst(PHY_INST *instPtr); double Phy_GetCoarseFreqEst(PHY_INST *instPtr);
@@ -284,4 +293,20 @@ void Phy_GetFrameSyncTimeStamp(PHY_INST *instPtr, TIME_WORD *frameSyncT);
void Phy_GetLastReceivedFrameSyncTimeStamp(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_GetSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart);
void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart); void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart);
/** @} PhysicalLayer_Receive_Estimations*/
/**
* @defgroup PhysicalLayer_AntennaControl
* @{
*/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig);
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode);
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);
/** @} PhysicalLayer_AntennaControl*/
#endif // PHY_CTRL_H_ #endif // PHY_CTRL_H_
/** @} PhysicalLayer*/
@@ -1,24 +1,24 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Physical layer register definitions * @file phy_layer.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Physical layer controller register definition
* @version 0.0
* @date 2023-04-24
* *
* Author: Fan Hao * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Date: 2021-11-16 00:08 * Lab of Communication and Network
* LastEditors: Fan Hao
* LastEditTime: 2023-04-24 17:32
* Revisions: Rev 0.1
* History:
* [2021-11-16]: Initial version.
* [2022-06-18]: New branch for glink control purpose:
* -Add poll mode physical layer will start Tx/Rx procedure
* at specific time stamp.
* [2023-04-24]: Porting for DUIFEI.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup PhysicalLayer
* @{
*/
/**
* @name PhysicalLayer_REG_Constants
* @{
*/
#ifndef PHY_REG_H_ #ifndef PHY_REG_H_
#define PHY_REG_H_ #define PHY_REG_H_
@@ -491,3 +491,7 @@
#define PHY_DEINTLV_AMPEST_MASK 0x0000FFFFU #define PHY_DEINTLV_AMPEST_MASK 0x0000FFFFU
#endif /* PHY_REG_H_ */ #endif /* PHY_REG_H_ */
/** @} PhysicalLayer_REG_Constants*/
/** @} PhysicalLayer*/
+144 -33
View File
@@ -1,9 +1,19 @@
/**
* @addtogroup SystemMonitor
* @{
*/
/***************************** Include Files *********************************/
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include "common.h" #include "common.h"
#include "system_monitor.h" #include "system_monitor.h"
/************************** Constant Definitions *****************************/
/**
* @name SystemMonitor_Private_Constants
* @{
*/
#define BUFF_A 0x00 #define BUFF_A 0x00
#define BUFF_B 0x01 #define BUFF_B 0x01
#define BUFF_NONE 0xFF #define BUFF_NONE 0xFF
@@ -13,14 +23,23 @@
#define SLOTLOG_PACK_LEN 88 // bytes #define SLOTLOG_PACK_LEN 88 // bytes
#define PRTCLLOG_PACK_ELN 24 // bytes #define PRTCLLOG_PACK_ELN 24 // bytes
#define HWSTATE_PACK_ELN 12 // bytes #define HWSTATE_PACK_ELN 12 // bytes
/** @} SystemMonitor_Private_Constants*/
/************************** Data Type Definitions ****************************/
/**
* @struct PINGPONG
* @brief PingPing Control
*/
typedef struct typedef struct
{ {
uint8_t latest; uint8_t latest; ///< latest available index
uint8_t rBusy; uint8_t rBusy; ///< current read busy index
uint8_t wBusy; uint8_t wBusy; ///< current write busy index
} PINGPONG; } PINGPONG;
/**
* @struct SYSMONITOR
* @brief System Monitor struct holds all the system log info
*/
typedef struct typedef struct
{ {
PINGPONG recvCtrl; PINGPONG recvCtrl;
@@ -37,12 +56,14 @@ typedef struct
HWSTATE hwState[2]; HWSTATE hwState[2];
} SYSMONITOR; } SYSMONITOR;
/************************** Function Prototypes ******************************/
static uint8_t GetWritable(PINGPONG ctrllor);
static uint8_t GetReadable(PINGPONG ctrllor);
/************************** Variable Definitions *****************************/
static SYSMONITOR *sysMonitorInst; static SYSMONITOR *sysMonitorInst;
uint8_t GetWritable(PINGPONG ctrllor); /*********************** Function Implementations ***************************/
uint8_t GetReadable(PINGPONG ctrllor); inline static uint8_t GetWritable(PINGPONG ctrllor)
inline uint8_t GetWritable(PINGPONG ctrllor)
{ {
// Allow only one write. // Allow only one write.
ASSERT(ctrllor.wBusy == BUFF_NONE); ASSERT(ctrllor.wBusy == BUFF_NONE);
@@ -52,7 +73,7 @@ inline uint8_t GetWritable(PINGPONG ctrllor)
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B); return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
} }
inline uint8_t GetReadable(PINGPONG ctrllor) inline static uint8_t GetReadable(PINGPONG ctrllor)
{ {
if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest) if (ctrllor.wBusy == BUFF_NONE || ctrllor.wBusy != ctrllor.latest)
return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B); return ((ctrllor.latest == BUFF_NONE) ? BUFF_A : BUFF_B);
@@ -60,7 +81,11 @@ inline uint8_t GetReadable(PINGPONG ctrllor)
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B); return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
} }
// System monitor initialise /**
* @brief Initialize System monitor
*
* @return SUCCESS
*/
int32_t SysMonitor_Init(void) int32_t SysMonitor_Init(void)
{ {
sysMonitorInst = calloc(1, sizeof(SYSMONITOR)); sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
@@ -82,15 +107,23 @@ int32_t SysMonitor_Init(void)
return SUCCESS; return SUCCESS;
} }
// System monitor initialise /**
* @brief Destroy system monitor release all allocated memory
*/
void SysMonitor_Destroy(void) void SysMonitor_Destroy(void)
{ {
free(sysMonitorInst); free(sysMonitorInst);
} }
// @System Info
/** /**
* Update system info. * @name SystemInfo_API
* @{
*/
/**
* @brief Update system info.
*
* @param info
*/ */
void SysMonitor_UpdateSysinfo(const SYSINFO *info) void SysMonitor_UpdateSysinfo(const SYSINFO *info)
{ {
@@ -103,7 +136,9 @@ void SysMonitor_UpdateSysinfo(const SYSINFO *info)
} }
/** /**
* Get system info. * @brief Get system info.
*
* @param info
*/ */
void SysMonitor_GetSysinfo(SYSINFO *info) void SysMonitor_GetSysinfo(SYSINFO *info)
{ {
@@ -118,14 +153,26 @@ void SysMonitor_GetSysinfo(SYSINFO *info)
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO)); memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old; sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
} }
/** @} SystemInfo_API*/
// @Send Payload
/** /**
* Update send payload by. * @name ServicePayload_API
* @{
*/
/**
* @brief Update send payload by
*
* @param buff
* @param len
*/ */
void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len) void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx; uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->sendCtrl); buffIndx = GetWritable(sysMonitorInst->sendCtrl);
sysMonitorInst->sendCtrl.wBusy = buffIndx; sysMonitorInst->sendCtrl.wBusy = buffIndx;
@@ -136,11 +183,21 @@ void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len)
} }
/** /**
* Get the latest send payload. * @brief Get the latest send payload.
*
* @param buff
* @param id
* @param len
*/ */
void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len) void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
ASSERT(id != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx, buffIndex_old; uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sendCtrl.rBusy; buffIndex_old = sysMonitorInst->sendCtrl.rBusy;
if (buffIndex_old != BUFF_NONE) if (buffIndex_old != BUFF_NONE)
@@ -156,28 +213,46 @@ void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len)
sysMonitorInst->sendCtrl.rBusy = buffIndex_old; sysMonitorInst->sendCtrl.rBusy = buffIndex_old;
} }
// @Receive Payload
/** /**
* Update receive payload. * @brief Update receive payload.
*
* @param buff
* @param id
* @param len
*/ */
void SysMonitor_UpdateRecvPayload(const uint8_t *buff, size_t len) void SysMonitor_UpdateRecvPayload(const uint8_t *buff, uint32_t id, size_t len)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
if (id == DATA_ID_NONE || len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx; uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->recvCtrl); buffIndx = GetWritable(sysMonitorInst->recvCtrl);
sysMonitorInst->recvCtrl.wBusy = buffIndx; sysMonitorInst->recvCtrl.wBusy = buffIndx;
memcpy(sysMonitorInst->recv[buffIndx].data, buff, len); memcpy(sysMonitorInst->recv[buffIndx].data, buff, len);
sysMonitorInst->recv[buffIndx].dataId++; sysMonitorInst->recv[buffIndx].dataId = id;
sysMonitorInst->recvCtrl.latest = buffIndx; sysMonitorInst->recvCtrl.latest = buffIndx;
sysMonitorInst->recvCtrl.wBusy = BUFF_NONE; sysMonitorInst->recvCtrl.wBusy = BUFF_NONE;
} }
/** /**
* Get the latest receive payload. * @brief Get the latest receive payload.
*
* @param buff
* @param id
* @param len
*/ */
void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len) void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(buff != NULL);
ASSERT(id != NULL);
if (len > PAYLOAD_LEN_MAX)
{
return;
}
uint8_t buffIndx, buffIndex_old; uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->recvCtrl.rBusy; buffIndex_old = sysMonitorInst->recvCtrl.rBusy;
if (buffIndex_old != BUFF_NONE) if (buffIndex_old != BUFF_NONE)
@@ -192,14 +267,22 @@ void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len)
*id = sysMonitorInst->recv[buffIndx].dataId; *id = sysMonitorInst->recv[buffIndx].dataId;
sysMonitorInst->recvCtrl.rBusy = buffIndex_old; sysMonitorInst->recvCtrl.rBusy = buffIndex_old;
} }
/** @} ServicePayload_API*/
// @Link layer log
/** /**
* Update link layer log * @name Linklayer_Log_API
* @{
*/
/**
* @brief Update link layer log
*
* @param log
*/ */
void SysMonitor_UpdateLinklayerLog(const LINKLOG *log) void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx; uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl); buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
sysMonitorInst->linkLogCtrl.wBusy = buffIndx; sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
@@ -209,11 +292,14 @@ void SysMonitor_UpdateLinklayerLog(const LINKLOG *log)
} }
/** /**
* Get the latest link layer log * @brief Get the latest link layer log
*
* @param log
*/ */
void SysMonitor_GetLinklayerLog(LINKLOG *log) void SysMonitor_GetLinklayerLog(LINKLOG *log)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old; uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy; buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE) if (buffIndex_old != BUFF_NONE)
@@ -224,14 +310,22 @@ void SysMonitor_GetLinklayerLog(LINKLOG *log)
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG)); memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old; sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
} }
/** @} Linklayer_Log_API*/
// @Physical layer log
/** /**
* Update physical layer log * @name PhysicalLayer_Log_API
* @{
*/
/**
* @brief Update physical layer log
*
* @param log
*/ */
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log) void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx; uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl); buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
sysMonitorInst->phyLogCtrl.wBusy = buffIndx; sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
@@ -241,11 +335,14 @@ void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
} }
/** /**
* Get the latest physical layer log * @brief Get the latest physical layer log
*
* @param log
*/ */
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log) void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old; uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy; buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE) if (buffIndex_old != BUFF_NONE)
@@ -256,15 +353,22 @@ void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG)); memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old; sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
} }
/** @} */
// @Hardware state
/** /**
* Log hardware running status. * @name HardwareState_Log_API
* @{
*/
/**
* @brief Log hardware running status.
*
* @param state
*/ */
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state) void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(state != NULL);
uint8_t buffIndx; uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl); buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
sysMonitorInst->hwStateCtrl.wBusy = buffIndx; sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
@@ -274,11 +378,14 @@ void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
} }
/** /**
* Get the latest hardware running status. * @brief Get the latest hardware running status.
*
* @param state
*/ */
void SysMonitor_GetHardwareStatus(HWSTATE *state) void SysMonitor_GetHardwareStatus(HWSTATE *state)
{ {
ASSERT(sysMonitorInst != NULL); ASSERT(sysMonitorInst != NULL);
ASSERT(state != NULL);
uint8_t buffIndx, buffIndex_old; uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy; buffIndex_old = sysMonitorInst->hwStateCtrl.rBusy;
if (buffIndex_old != BUFF_NONE) if (buffIndex_old != BUFF_NONE)
@@ -289,3 +396,7 @@ void SysMonitor_GetHardwareStatus(HWSTATE *state)
memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE)); memcpy(state, &(sysMonitorInst->hwState[buffIndx]), sizeof(HWSTATE));
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old; sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
} }
/** @} HardwareState_Log_API */
/** @} SystemMonitor*/
+132 -96
View File
@@ -1,10 +1,21 @@
/**
* @defgroup SystemMonitor
* @{
*/
#ifndef __SYSTEM_MONITOR_H_ #ifndef __SYSTEM_MONITOR_H_
#define __SYSTEM_MONITOR_H_ #define __SYSTEM_MONITOR_H_
/***************************** Include Files *********************************/
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "util.h" #include "util.h"
/************************* Constant Definitions ******************************/
/**
* @name SystemMonitor_Constants
* @{
*/
#define PAYLOAD_LEN_MAX 256 #define PAYLOAD_LEN_MAX 256
#define PAYLOAD_LEN_FLJ_RX 168 #define PAYLOAD_LEN_FLJ_RX 168
#define PAYLOAD_LEN_FLJ_TX 66 #define PAYLOAD_LEN_FLJ_TX 66
@@ -36,12 +47,19 @@
#define VOLT_ANT_NIL_OK BIT(4) #define VOLT_ANT_NIL_OK BIT(4)
#define ANT_STATE_OK BIT(6) #define ANT_STATE_OK BIT(6)
// Xilinx Recommended
// #define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95)
// #define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71)
// #define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14)
// #define IS_PL_VALID(x) (x <= 1.03 && x >= 0.97)
// #define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
// #define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.97)
#define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95) #define IS_PS_VALID(x) (x <= 1.05 && x >= 0.95)
#define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71) #define IS_PSAUX_VALID(x) (x <= 1.89 && x >= 1.71)
#define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14) #define IS_DDR_VALID(x) (x <= 1.89 && x >= 1.14)
#define IS_PL_VALID(x) (x <= 1.03 && x >= 0.97) #define IS_PL_VALID(x) (x <= 1.03 && x >= 0.96)
#define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71) #define IS_PLAUX_VALID(x) (x <= 1.89 && x >= 1.71)
#define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.97) #define IS_BRAM_VALID(x) (x <= 1.03 && x >= 0.96)
#define CLK_SP_PLL0_LOCK BIT(0) #define CLK_SP_PLL0_LOCK BIT(0)
#define CLK_SP_PLL1_LOCK BIT(2) #define CLK_SP_PLL1_LOCK BIT(2)
@@ -58,131 +76,147 @@
#define TEMPERATURE_LSB 1.0 // Celsius degree #define TEMPERATURE_LSB 1.0 // Celsius degree
#define TEMPERATURE_MAX 127.0 // Celsius degree #define TEMPERATURE_MAX 127.0 // Celsius degree
#define TEMPERATURE_MIN -128.0 // Celsius degree #define TEMPERATURE_MIN -128.0 // Celsius degree
/** @} SystemMonitor_Constants */
/************************* Data Type Definitions ****************************/
/**
* @struct SYSINFO
* @brief System Infomation log
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
// -- unit: ms, 0~604799999 uint32_t psBDS; ///< -- unit: ms, 0~604799999
uint32_t psBDS; uint16_t pBDS; ///< -- unit: week, 0~0~8191
// -- unit: week, 0~0~8191 uint32_t psGPS; ///< -- unit: ms, 0~604799999
uint16_t pBDS; uint16_t pGPS; ///< -- unit: week, 0~0~8191
// -- unit: ms, 0~604799999 uint8_t tmInd; ///< Time validation indicator \n
uint32_t psGPS; // -- [0] GPS\n
// -- unit: week, 0~0~8191 // -- [1] reserve.\n
uint16_t pGPS; // -- [2] UTC\n
// Time validation indicator // -- [3] BDS\n
// -- [0] GPS float tmFly; ///< Time of flying uint: s
// -- [1] reserve. uint8_t stFly; ///< Status of flying \n
// -- [2] UTC // [7:6] departure status 11 - departed/00 - not departed \n
// -- [3] BDS // [5:4] ready status 11 - ready/00 - not ready \n
uint8_t tmInd; // [3:2] attitude status 11 - attitude ok/00 - attitude not ok \n
// Time of flying // [1:0] attitude adjust status 11 - adjusted/00 - not adjusted
// uint: s float posX; ///< coord X Position in launch coordinate system
float tmFly; float posY; ///< coord Y Position in launch coordinate system
// Status of flying float posZ; ///< coord Z Position in launch coordinate system
// [7:6] departure status 11 - departed/00 - not departed float vX; ///< Speed X in launch coordinate system
// [5:4] ready status 11 - ready/00 - not ready float vY; ///< Speed Y in launch coordinate system
// [3:2] attitude status 11 - attitude ok/00 - attitude not ok float vZ; ///< Speed Z in launch coordinate system
// [1:0] attitude adjust status 11 - adjusted/00 - not adjusted float pitch; ///< Pitch Attitude in launch inertia coordinate system
uint8_t stFly; float yaw; ///< Yaw Attitude in launch inertia coordinate system
// Position in launch coordinate system float roll; ///< Roll Attitude in launch inertia coordinate system
float posX;
float posY;
float posZ;
// Speed in launch coordinate system
float vX;
float vY;
float vZ;
// Attitude in launch inertia coordinate system
float pitch;
float yaw;
float roll;
} SYSINFO; } SYSINFO;
/**
* @struct SYSBUSLOG
* @brief System Info holds the system bus log
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
// SystemBus log // SystemBus log
// -- last valid config
// byte 0: 0x11 FLJ, 0x00 LJ uint8_t lastConfig[2]; ///< Last valid config \n
// byte 1: 0x66 Full Power, 0x88 Low Power // byte 0: 0x11 FLJ, 0x00 LJ \n
uint8_t lastConfig[2]; // byte 1: 0x66 Full Power, 0x88 Low Power
uint32_t pollCnt; uint32_t pollCnt; ///< number of poll commands
uint32_t svcCnt; uint32_t svcCnt; ///< number of service commands
uint32_t remoteCnt; uint32_t remoteCnt; ///< number of remote check commands
} SYSBUSLOG; } SYSBUSLOG;
/**
* @struct LINKLOG
* @brief Linklayer Log struct holds the Linklayer log
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
// Network log // Network log
uint32_t tuNum; uint32_t tuNum; ///< current time unite number
uint8_t slotNum; uint8_t slotNum; ///< current slot number
uint8_t nodeType; uint8_t nodeType; ///< current node type
uint8_t cxnStatus; uint8_t cxnStatus; ///< current connection status
uint8_t linkStage; uint8_t linkStage; ///< current linklayer working stage
uint32_t recxnCnt; uint32_t recxnCnt; ///< reconnect trial count
uint8_t beamNo; uint8_t beamNo; ///< current working beam number
uint8_t beamWidth; uint8_t beamWidth; ///< current working beam width
uint16_t beamAz; uint16_t beamAz; ///< current working beam angle Az
uint16_t beamEl; uint16_t beamEl; ///< current working beam angle Ez
uint16_t advTxCnt; uint16_t advTxCnt; ///< adv frame send count
uint16_t advRecvCnt; uint16_t advRecvCnt; ///< adv frame received count
uint16_t advCorrectCnt; uint16_t advCorrectCnt; ///< adv frame received correctly count
uint32_t cfmTxCnt; uint32_t cfmTxCnt; ///< cfm frame send count
uint32_t cfmRecvCnt; uint32_t cfmRecvCnt; ///< cfm frame received count
uint32_t cfmCorrectCnt; uint32_t cfmCorrectCnt; ///< adv frame received correctly count
uint32_t svcTxCnt; uint32_t svcTxCnt; ///< svc frame send count
uint32_t svcRecvCnt; uint32_t svcRecvCnt; ///< svc frame received count
uint32_t svcCorrectCnt; uint32_t svcCorrectCnt; ///< svc frame received correctly count
int32_t timeDev; int32_t timeDev; ///< last time deviation result
uint32_t sendId; uint32_t sendId; ///< last send data id
uint32_t recvId; uint32_t recvId; ///< last received data id
uint8_t reserve[4]; uint8_t reserve[4]; ///< reserved data
} LINKLOG; } LINKLOG;
/**
* @struct PHYLOG
* @brief Physical Layer Log struct holds the Linklayer log
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
uint32_t acqCnt; uint32_t acqCnt; ///< aquisition count
uint32_t fsyncCnt; uint32_t fsyncCnt; ///< frame sync count
uint32_t decodeCnt; uint32_t decodeCnt; ///< decode count
uint32_t crcCnt; uint32_t crcCnt; ///< crc valid count
double doppler; double doppler; ///< last doppler estimation result
uint64_t recvStamp; uint64_t recvStamp; ///< last frame arrival time
double acqPAPR; double acqPAPR; ///< last acquisition peak-average ration
uint8_t acqPhase; uint8_t acqPhase; ///< last acquisition phase estimation
uint8_t acqFreqCh; uint8_t acqFreqCh; ///< last acquisition frequency deviation estimation
double fsyncPAPR; double fsyncPAPR; ///< last frame sync peak-average ration
uint8_t fsyncFreqCh; uint8_t fsyncFreqCh; ///< last frame sync frequency estimation
uint16_t deintlvAmpEst; uint16_t deintlvAmpEst; ///< de-interleave amplitude estimation
uint8_t antMode; uint8_t antMode; ///< current antenna working mode
uint8_t reserve[3]; uint8_t reserve[3]; ///< reserved data
} PHYLOG; } PHYLOG;
/**
* @struct HWSTATE
* @brief Hardware Status Log struct holds all hardware status
*/
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))
{ {
// Hardware status bool isSpOk; ///< signal processor state
bool isSpOk; bool isAntOk; ///< antenna state
bool isAntOk;
// -- Signal processor status // -- Signal processor status
uint8_t spFpgaVolt; uint8_t spFpgaVolt; ///< Signal processor voltage state indicator
uint8_t spClkState; uint8_t spClkState; ///< Signal processor clock state indicator
uint8_t spAdLockState; uint8_t spAdLockState; ///< Signal processor adc lock state indicator
uint8_t spAdTemp_0; uint8_t spAdTemp_0; ///< Signal processor adc0 temperature
uint8_t spAdTemp_1; uint8_t spAdTemp_1; ///< Signal processor adc1 temperature
uint8_t spFpgaTemp; uint8_t spFpgaTemp; ///< Signal processor FPGA temperature
// -- Antenna status // -- Antenna status
uint8_t antVolt; uint8_t antVolt; ///< Antenna voltage state indicator
uint8_t antTemp; uint8_t antTemp; ///< Antenna rf temperature
uint8_t antPll; uint8_t antPll; ///< Antenna rf lock state indicator
uint8_t antMgc0; uint8_t antMgc0; ///< Antenna rf mgc0~1 indicator
uint8_t antMgc1; uint8_t antMgc1; ///< Antenna rf mgc2~3 indicator
uint8_t reserve[2]; uint8_t reserve[2];
} HWSTATE; } HWSTATE;
/**
* @struct PAYLOAD
* @brief Payload struct holds the service payload
*/
typedef struct typedef struct
{ {
uint32_t dataId; uint32_t dataId;
uint8_t data[PAYLOAD_LEN_MAX]; uint8_t data[PAYLOAD_LEN_MAX];
} PAYLOAD; } PAYLOAD;
/************************** Function Prototypes ******************************/
int32_t SysMonitor_Init(void); int32_t SysMonitor_Init(void);
void SysMonitor_Destroy(void); void SysMonitor_Destroy(void);
@@ -190,7 +224,7 @@ void SysMonitor_UpdateSysinfo(const SYSINFO *info);
void SysMonitor_GetSysinfo(SYSINFO *info); void SysMonitor_GetSysinfo(SYSINFO *info);
void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len); void SysMonitor_UpdateSendPayload(const uint8_t *buff, size_t len);
void SysMonitor_UpdateRecvPayload(const uint8_t *buff, size_t len); void SysMonitor_UpdateRecvPayload(const uint8_t *buff, uint32_t id, size_t len);
void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len); void SysMonitor_GetSendPayload(uint8_t *buff, uint32_t *id, size_t len);
void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len); void SysMonitor_GetRecvPayload(uint8_t *buff, uint32_t *id, size_t len);
@@ -202,3 +236,5 @@ void SysMonitor_GetPhysicalLayerLog(PHYLOG *log);
void SysMonitor_GetHardwareStatus(HWSTATE *state); void SysMonitor_GetHardwareStatus(HWSTATE *state);
#endif //__SYSTEM_MONITOR_H_ #endif //__SYSTEM_MONITOR_H_
/** @} */
+127 -115
View File
@@ -1,22 +1,21 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: System bus protocol implementation file. * @file systembus.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus protocol implementation file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-05-06 10:13 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Last Edit Time: [2023-05-06 21:45]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
* [2023-09-13]: Update to 485 protocol-20220816
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Network * Lab of Communication and Network
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup SystemBus
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
@@ -27,10 +26,18 @@
#include "common.h" #include "common.h"
#include "error.h" #include "error.h"
#include "circ_queue.h" #include "circ_queue.h"
#include "../system_monitor.h" #include "../system_monitor.h"
/**
* @addtogroup SystemBus_Protocol_Routine
* @{
*/
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/**
* @name SystemBus_MSG_Constants
* @{
*/
// Common Field // Common Field
// -- Command word // -- Command word
#define WD_CMD 0x00 #define WD_CMD 0x00
@@ -190,10 +197,9 @@
#define LJ_RM_TEST_RESP_LEN 158 #define LJ_RM_TEST_RESP_LEN 158
// My Production Type // My Production Type
#define MY_PRD_ID PRD_DL_K #define MY_PRD_ID PRD_DL_K
/** @} SystemBus_MSG_Constants*/
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr); static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg); static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg);
@@ -238,7 +244,8 @@ static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr)
{ {
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) { if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n"); DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n");
return ENOMEM; return ENOMEM;
} }
@@ -248,13 +255,13 @@ static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr)
sysbusRsp->data[WD_CMD] = CMD_SELF_TEST; sysbusRsp->data[WD_CMD] = CMD_SELF_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID; sysbusRsp->data[WD_PRD] = MY_PRD_ID;
SysMonitor_GetHardwareStatus(hwStatsPtr); SysMonitor_GetHardwareStatus(hwStatsPtr);
if (linkInstPtr->isEnable == false) if (L2_isStarted(linkInstPtr))
{ {
sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR; sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR;
} }
else else
{ {
sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR; sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR;
} }
// apply status and omit 2 bytes of overhead. // apply status and omit 2 bytes of overhead.
memcpy(sysbusRsp->data + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN); memcpy(sysbusRsp->data + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN);
@@ -278,56 +285,54 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr; PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr; TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
bool reconfig = false; bool reconfig = false;
bool start = false;
if (msg[WD_MODE_CMD] == MODE_CMD_HEAD) if (msg[WD_MODE_CMD] == MODE_CMD_HEAD)
{ {
// omit unnecessary reconfiguration // head node config
if (L2_GetNodeType(linkInstPtr) != L2_NODE_HEAD) reconfig = (L2_NODE_HEAD != L2_GetNodeType(linkInstPtr));
{ linkConfig.myType = L2_NODE_HEAD;
// head node config linkConfig.myId = 1;
linkConfig.myType = L2_NODE_HEAD;
linkConfig.myId = 1;
reconfig = true;
}
} }
else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER ) else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER)
{ {
// omit unnecessary reconfiguration // member node config
if (L2_GetNodeType(linkInstPtr) != L2_NODE_MEMBER) reconfig = (L2_NODE_MEMBER != L2_GetNodeType(linkInstPtr));
{ linkConfig.myType = L2_NODE_MEMBER;
// member node config linkConfig.myId = 2;
linkConfig.myType = L2_NODE_MEMBER;
linkConfig.myId = 2;
reconfig = true;
}
} }
else else
{ {
// Ignore current command // Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X", DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_MODE_CMD, msg[WD_MODE_CMD]); WD_MODE_CMD, msg[WD_MODE_CMD]);
return EPARAM; return EPARAM;
} }
if(msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER) if (msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{ {
// high power config // full power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
start = true; if (reconfig || !L2_isStarted(linkInstPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
} }
else if(msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER) else if (msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{ {
// low power config // low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
start = true; if (reconfig || !L2_isStarted(linkInstPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
} }
else if(msg[WD_EN_CMD] == EN_CMD_SILENT) else if (msg[WD_EN_CMD] == EN_CMD_SILENT)
{ {
// silence config // silence config
// TODO: better approach? // TODO: better approach?
start = false;
Linklayer_Halt(linkInstPtr); Linklayer_Halt(linkInstPtr);
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY); Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY);
TIME_WORD pullTime = {0, 0}; TIME_WORD pullTime = {0, 0};
@@ -338,13 +343,12 @@ static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
} }
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL); Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
} }
if (reconfig == true) else
{ {
Linklayer_Reconfig(linkInstPtr, &linkConfig); // Ignore current command
} DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
if (start == true) WD_EN_CMD, msg[WD_EN_CMD]);
{ return EIGNORE;
Linklayer_Start(linkInstPtr);
} }
instPtr->sysbusLog.lastConfig[0] = msg[WD_MODE_CMD]; instPtr->sysbusLog.lastConfig[0] = msg[WD_MODE_CMD];
instPtr->sysbusLog.lastConfig[1] = msg[WD_EN_CMD]; instPtr->sysbusLog.lastConfig[1] = msg[WD_EN_CMD];
@@ -359,7 +363,8 @@ static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame)
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
ASSERT(frame != NULL); ASSERT(frame != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) { if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n"); DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n");
return ENOMEM; return ENOMEM;
} }
@@ -384,12 +389,13 @@ static int32_t SystemBus_GenPollRsp(SYSBUS *instPtr, uint8_t *msg)
size_t dataLen; size_t dataLen;
uint8_t *payload; uint8_t *payload;
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) { if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n"); DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n");
return ENOMEM; return ENOMEM;
} }
if(msg[WD_CMD] == CMD_FLJ_POLL) if (msg[WD_CMD] == CMD_FLJ_POLL)
{ {
sysbusRsp->len = FLJ_POLL_RESP_LEN; sysbusRsp->len = FLJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_FLJ_POLL; sysbusRsp->data[WD_CMD] = CMD_FLJ_POLL;
@@ -397,7 +403,7 @@ static int32_t SystemBus_GenPollRsp(SYSBUS *instPtr, uint8_t *msg)
dataLen = PAYLOAD_LEN_FLJ_RX; dataLen = PAYLOAD_LEN_FLJ_RX;
payload = sysbusRsp->data + FLJ_DATA_OFFSET; payload = sysbusRsp->data + FLJ_DATA_OFFSET;
} }
else if(msg[WD_CMD] == CMD_LJ_POLL) else if (msg[WD_CMD] == CMD_LJ_POLL)
{ {
sysbusRsp->len = LJ_POLL_RESP_LEN; sysbusRsp->len = LJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_LJ_POLL; sysbusRsp->data[WD_CMD] = CMD_LJ_POLL;
@@ -437,7 +443,8 @@ static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg)
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
ASSERT(msg != NULL); ASSERT(msg != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME)); SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) { if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n"); DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM; return ENOMEM;
} }
@@ -447,7 +454,7 @@ static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg)
TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord); TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord);
time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part; time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part;
if(msg[WD_CMD] == CMD_FLJ_RM_TEST) if (msg[WD_CMD] == CMD_FLJ_RM_TEST)
{ {
sysbusRsp->len = FLJ_RM_TEST_RESP_LEN; sysbusRsp->len = FLJ_RM_TEST_RESP_LEN;
memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN); memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN);
@@ -485,7 +492,8 @@ static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg)
return EUNEXP; return EUNEXP;
} }
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){ if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp); free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n"); DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE; return EQUEUE;
@@ -494,64 +502,6 @@ static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg)
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/
/**
* @brief Initialize System Bus instance.
*
* @param InstPtr A double pointer to System Bus instance.
* @param config A pointer to System Bus configurations.
*
* @return None.
*
******************************************************************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
SYSBUS_UART_CONFIG uartConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(SYSBUS));
if ((*instPtr) == NULL)
{
return FAILURE;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
memset(&((*instPtr)->sysbusLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
uartConfig.baseAddr = config->baseAddr;
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
if (Status != SUCCESS)
{
Status = ENOMEM;
goto sysbus_init_error;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
{
Status = ENOMEM;
goto sysbus_init_error;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
Status = ENOMEM;
goto sysbus_init_error;
}
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
sysbus_init_error:
free((*instPtr)->uartInst);
free((*instPtr)->txQueue);
free((*instPtr)->rxQueue);
free(*instPtr);
return Status;
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief A handler function. This handler evaluate the message from system * @brief A handler function. This handler evaluate the message from system
@@ -698,6 +648,66 @@ int32_t SystemBus_MakeResp(SYSBUS *instPtr)
return Status; return Status;
} }
/** @} */
/*****************************************************************************/
/**
* @brief Initialize System Bus instance.
*
* @param InstPtr A double pointer to System Bus instance.
* @param config A pointer to System Bus configurations.
*
* @return None.
*
******************************************************************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
SYSBUS_UART_CONFIG uartConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(SYSBUS));
if ((*instPtr) == NULL)
{
return FAILURE;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
memset(&((*instPtr)->sysbusLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
uartConfig.baseAddr = config->baseAddr;
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
if (Status != SUCCESS)
{
Status = ENOMEM;
goto sysbus_init_error;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
{
Status = ENOMEM;
goto sysbus_init_error;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
Status = ENOMEM;
goto sysbus_init_error;
}
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
sysbus_init_error:
free((*instPtr)->uartInst);
free((*instPtr)->txQueue);
free((*instPtr)->rxQueue);
free(*instPtr);
return Status;
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
* @brief This function handles the systembus tx irq events. * @brief This function handles the systembus tx irq events.
@@ -751,3 +761,5 @@ recv_error:
free(sysbusReq); free(sysbusReq);
return Status; return Status;
} }
/** @} SystemBus*/
+40 -23
View File
@@ -1,18 +1,20 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: System bus protocol head file. * @file systembus.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus protocol header file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-05-06 10:12 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Last Edit Time: [2023-05-06 10:13] * Lab of Communication and Network
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup SystemBus
* @{
*/
#ifndef __SYSTEMBUS_H_ #ifndef __SYSTEMBUS_H_
#define __SYSTEMBUS_H_ #define __SYSTEMBUS_H_
@@ -25,34 +27,47 @@
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/ /************************** Data Type Definitions ****************************/
// Definition of SystemBus instance.
/**
* @struct SYSBUS_CONFIG
* @brief SystemBus Config struct holds SystemBus initialization parameters
*/
typedef struct typedef struct
{ {
uintptr_t baseAddr; uintptr_t baseAddr; ///< base address in memory
uint32_t txQueueMax; uint32_t txQueueMax; ///< maximum tx queue length
uint32_t rxQueueMax; uint32_t rxQueueMax; ///< maximum rx queue length
} SYSBUS_CONFIG; } SYSBUS_CONFIG;
/**
* @struct SYSBUS
* @brief SystemBus Instance struct
*/
typedef struct typedef struct
{ {
SYSBUS_CONFIG config; SYSBUS_CONFIG config; ///< SystemBus initialization parameters
SYSBUSLOG sysbusLog; // systembus log SYSBUSLOG sysbusLog; ///< SystemBus log
LINKLOG linkLog; // Link layer log LINKLOG linkLog; ///< Link layer log
PHYLOG phyLog; // Physical layer log PHYLOG phyLog; ///< Physical layer log
HWSTATE hwState; // Hardware status HWSTATE hwState; ///< Hardware status
SYSBUS_UART *uartInst; SYSBUS_UART *uartInst; ///< physical uart controller instance
CIRC_QUEUE *txQueue; CIRC_QUEUE *txQueue; ///< tx queue
CIRC_QUEUE *rxQueue; CIRC_QUEUE *rxQueue; ///< rx queue
bool isRxDone; bool isRxDone; ///< tx done indicator
bool isTxDone; bool isTxDone; ///< rx done indicator
} SYSBUS; } SYSBUS;
/************************** Function Prototypes ******************************/ /************************** Function Prototypes ******************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config); int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config);
/**
* @defgroup SystemBus_Protocol_Routine
* @{
*/
int32_t SystemBus_HandleCmd(SYSBUS *instPtr); int32_t SystemBus_HandleCmd(SYSBUS *instPtr);
int32_t SystemBus_MakeResp(SYSBUS *instPtr); int32_t SystemBus_MakeResp(SYSBUS *instPtr);
/** @} */
int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr); int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr);
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr); int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr);
@@ -64,3 +79,5 @@ bool SystemBus_IsTxBusy(SYSBUS *instPtr);
bool SystemBus_IsRxBusy(SYSBUS *instPtr); bool SystemBus_IsRxBusy(SYSBUS *instPtr);
#endif //__SYSTEMBUS_H_ #endif //__SYSTEMBUS_H_
/** @} SystemBus*/
+26 -10
View File
@@ -1,18 +1,26 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: System bus uart driver implementation file. * @file systembus_uart.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus uart driver implementation file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-05-06 10:59 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2023-05-06 21:56 * Lab of Communication and Network
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup SystemBus
* @{
*/
/**
* @addtogroup SystemBus_UART
* @{
*/
/***************************** Include Files *******************************/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
@@ -20,6 +28,10 @@
#include "systembus_uart.h" #include "systembus_uart.h"
#include "common.h" #include "common.h"
/**
* @name SystemBus_UART_Driver_Constants
* @{
*/
// Control and status register // Control and status register
#define MODULE_VERSION 0 #define MODULE_VERSION 0
#define UART_STATUS 4 #define UART_STATUS 4
@@ -47,7 +59,7 @@
#define FRAME_CHECK_LEN 1 // CheckSum #define FRAME_CHECK_LEN 1 // CheckSum
#define FRAME_INFO_LEN 3 // CheckSum, Dummy and DataLen #define FRAME_INFO_LEN 3 // CheckSum, Dummy and DataLen
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen #define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
/*************************** Function Definitions ****************************/ /** @} SystemBus_UART_Driver_Constants*/
/*****************************************************************************/ /*****************************************************************************/
/** /**
@@ -246,3 +258,7 @@ bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr)
return false; return false;
} }
} }
/** @} SystemBus_UART*/
/** @} SystemBus*/
+32 -8
View File
@@ -1,17 +1,25 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: System bus uart driver implementation file. * @file systembus_uart.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus uart driver header file.
* @version 0.1
* @date 2023-05-06
* *
* Date: 2023-05-06 10:59 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* LastEditTime: 2023-05-06 21:48 * Lab of Communication and Network
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup SystemBus
* @{
*/
/**
* @defgroup SystemBus_UART
* @{
*/
#ifndef SYSTEMBUS_UART_H #ifndef SYSTEMBUS_UART_H
#define SYSTEMBUS_UART_H #define SYSTEMBUS_UART_H
@@ -61,16 +69,28 @@
IO_In32((baseAddr) + (offset)) IO_In32((baseAddr) + (offset))
/************************** Data Type Definitions ****************************/ /************************** Data Type Definitions ****************************/
/**
* @struct SYSBUS_UART_CONFIG
* @brief SystemBus UART driver initialization parameters
*/
typedef struct typedef struct
{ {
uintptr_t baseAddr; uintptr_t baseAddr;
} SYSBUS_UART_CONFIG; } SYSBUS_UART_CONFIG;
/**
* @struct SYSBUS_UART
* @brief SystemBus UART driver instance
*/
typedef struct typedef struct
{ {
SYSBUS_UART_CONFIG config; SYSBUS_UART_CONFIG config;
} SYSBUS_UART; } SYSBUS_UART;
/**
* @struct SYSBUS_UART_FRAME
* @brief SystemBus UART frame definition
*/
typedef struct typedef struct
{ {
uint16_t len; uint16_t len;
@@ -96,3 +116,7 @@ bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr);
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr); bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr);
#endif // SYSTEMBUS_UART_H #endif // SYSTEMBUS_UART_H
/** @} SystemBus_UART*/
/** @} SystemBus*/
+22 -12
View File
@@ -1,20 +1,21 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: Time sync implementation file. * @file time_ctrl.c
* * @author FanHao (hao_fan_bit_ee@163.com)
* Author: Author's name * @brief Time sync controller driver implementation file.
* Date: 2023-12-20 16:32 * @version 0.0
* LastEditors: FanHao * @date 2023-12-20
* LastEditTime: 2023-12-22 20:43 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Revisions: Rev 0.0 * Lab of Communication and Network
* History:
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup TimeController_Driver
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include <string.h> #include <string.h>
#include "time_ctrl.h" #include "time_ctrl.h"
@@ -23,6 +24,10 @@
#include "util.h" #include "util.h"
/************************** Constant Definitions *****************************/ /************************** Constant Definitions *****************************/
/**
* @name TimeController_REG_Constants
* @{
*/
#define VERSION_REG 0x00000004 #define VERSION_REG 0x00000004
#define TIME_INT_REG 0x00000008 #define TIME_INT_REG 0x00000008
#define TIME_FRAC_REG 0x0000000C #define TIME_FRAC_REG 0x0000000C
@@ -36,6 +41,9 @@
#define CNTSTEP_OPT 0x0000002c #define CNTSTEP_OPT 0x0000002c
#define TM_RESET_CODE 0x5253542E #define TM_RESET_CODE 0x5253542E
/** @} TimeController_REG_Constants*/
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
#define TMC_Read(instPtr, addr) IO_In32(instPtr->config.baseAddr + addr) #define TMC_Read(instPtr, addr) IO_In32(instPtr->config.baseAddr + addr)
#define TMC_Write(instPtr, addr, value) IO_Out32(instPtr->config.baseAddr + addr, value) #define TMC_Write(instPtr, addr, value) IO_Out32(instPtr->config.baseAddr + addr, value)
@@ -296,3 +304,5 @@ void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD
gap->frac_part = (TIME_FRAC)(timeDiff % TIME_FRAC_MAX); gap->frac_part = (TIME_FRAC)(timeDiff % TIME_FRAC_MAX);
gap->frac_part = (TIME_INT)(timeDiff / TIME_FRAC_MAX); gap->frac_part = (TIME_INT)(timeDiff / TIME_FRAC_MAX);
} }
/** @} TimeController_Driver*/
+35 -18
View File
@@ -1,19 +1,20 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: A simplified version of timesync for datalink 814 (Dijian) * @file time_ctrl.h
* * @author FanHao (hao_fan_bit_ee@163.com)
* Date: 2023-12-20-04 16:32 * @brief Time sync controller driver header file.
* LastEditors: Fan Hao * @version 0.0
* LastEditTime: 2023-12-20 16:32 * @date 2023-12-20
* Revisions: Rev 0.0 * @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* History: * Lab of Communication and Network
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @defgroup TimeController_Driver
* @{
*/
#ifndef TIME_CTRL_H_ #ifndef TIME_CTRL_H_
#define TIME_CTRL_H_ #define TIME_CTRL_H_
@@ -23,30 +24,44 @@
#define TIME_FRAC_MAX 500000 // how many 10ns in a 5ms #define TIME_FRAC_MAX 500000 // how many 10ns in a 5ms
/***************** Macros (Inline Functions) Definitions *********************/ /***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/ /**************************** Type Definitions *******************************/
/**
* @enum TIMECTRL_ADJ_TYPE
* @brief defines the time adjustment methods
*/
typedef enum typedef enum
{ {
TM_ADJ_NONE = 0, TM_ADJ_NONE = 0, ///< none
TM_ADJ_ADD = 1, TM_ADJ_ADD = 1, ///< adjust time by add
TM_ADJ_SET = 2 TM_ADJ_SET = 2 ///< adjust time by set
} TIMECTRL_ADJ_TYPE; } TIMECTRL_ADJ_TYPE;
typedef uint32_t TIME_FRAC; typedef uint32_t TIME_FRAC;
typedef uint32_t TIME_INT; typedef uint32_t TIME_INT;
/**
* @struct TIME_WORD
* @brief Time controller time word
*/
typedef struct typedef struct
{ {
/* 5ms each LSB */ TIME_INT int_part; ///< 5ms each LSB
TIME_INT int_part; TIME_FRAC frac_part; ///< 10ns each LSB
/* 10ns each LSB */
TIME_FRAC frac_part;
} TIME_WORD; } TIME_WORD;
/**
* @struct TMC_CONFIG
* @brief TmcConfig holds the initialization parameters of time controller
*/
typedef struct typedef struct
{ {
uintptr_t baseAddr; uintptr_t baseAddr;
uint32_t reset; // time for reset (unit: us) uint32_t reset; // time for reset (unit: us)
} TMC_CONFIG; } TMC_CONFIG;
/**
* @struct TMC_INST
* @brief An instance struct of time controller
*/
typedef struct typedef struct
{ {
TMC_CONFIG config; TMC_CONFIG config;
@@ -72,3 +87,5 @@ void TimeCtrl_TimeAdjust(TMC_INST *instPtr, const TIME_WORD *tmWord, TIMECTRL_AD
void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap); void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap);
#endif /* TIME_SYNC_H_ */ #endif /* TIME_SYNC_H_ */
/** @} */
+80 -87
View File
@@ -1,34 +1,25 @@
/*****************************************************************************/ /*****************************************************************************/
/** /**
* Description: A simple circular FIFO bounded queue * @file circ_queue.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief A simple circular FIFO bounded queue
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/chrismerck/rpa_queue.git
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
* *
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:18
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @addtogroup CircularQueue
* @{
*/
#include "circ_queue.h" #include "circ_queue.h"
#include "common.h" #include "common.h"
#include <stdio.h> #include <stdio.h>
@@ -37,105 +28,107 @@
inline bool isCircQueueFull(CIRC_QUEUE *queue) inline bool isCircQueueFull(CIRC_QUEUE *queue)
{ {
ASSERT(queue != NULL); ASSERT(queue != NULL);
return ((queue)->nelts == (queue)->bounds); return ((queue)->nelts == (queue)->bounds);
} }
inline bool isCircQueueEmpty(CIRC_QUEUE *queue) inline bool isCircQueueEmpty(CIRC_QUEUE *queue)
{ {
ASSERT(queue != NULL); ASSERT(queue != NULL);
return ((queue)->nelts == 0); return ((queue)->nelts == 0);
} }
void CircQueueFree(CIRC_QUEUE *queue) void CircQueueFree(CIRC_QUEUE *queue)
{ {
ASSERT(queue != NULL); ASSERT(queue != NULL);
if (queue->data) if (queue->data)
free(queue->data); free(queue->data);
free(queue); free(queue);
} }
/** /**
* Initialize the CIRC_QUEUE. * @brief Initialize the CIRC_QUEUE.
*/ */
bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity) bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity)
{ {
ASSERT(q != NULL); ASSERT(q != NULL);
CIRC_QUEUE *queue; CIRC_QUEUE *queue;
queue = malloc(sizeof(CIRC_QUEUE)); queue = malloc(sizeof(CIRC_QUEUE));
if (!queue) if (!queue)
{ {
return false; return false;
} }
*q = queue; *q = queue;
memset(queue, 0, sizeof(CIRC_QUEUE)); memset(queue, 0, sizeof(CIRC_QUEUE));
/* Set all the data in the queue to NULL */ /* Set all the data in the queue to NULL */
queue->data = malloc(queueCapacity * sizeof(void *)); queue->data = malloc(queueCapacity * sizeof(void *));
if (queue->data == NULL) if (queue->data == NULL)
{ {
goto error; goto error;
} }
queue->bounds = queueCapacity; queue->bounds = queueCapacity;
queue->nelts = 0; queue->nelts = 0;
queue->in = 0; queue->in = 0;
queue->out = 0; queue->out = 0;
return true; return true;
error: error:
free(queue); free(queue);
return false; return false;
} }
/** /**
* Push new data onto the queue. * @brief Push new data onto the queue.
*/ */
bool CircQueuePush(CIRC_QUEUE *queue, void *data) bool CircQueuePush(CIRC_QUEUE *queue, void *data)
{ {
ASSERT(queue != NULL); ASSERT(queue != NULL);
if (isCircQueueFull(queue)) if (isCircQueueFull(queue))
{ {
return false; return false;
} }
queue->data[queue->in] = data; queue->data[queue->in] = data;
queue->in++; queue->in++;
if (queue->in >= queue->bounds) if (queue->in >= queue->bounds)
{ {
queue->in -= queue->bounds; queue->in -= queue->bounds;
} }
queue->nelts++; queue->nelts++;
return true; return true;
} }
/** /**
* Return current number of element in queue. * @brief Return current number of element in queue.
*/ */
inline uint32_t CircQueueSize(CIRC_QUEUE *queue) inline uint32_t CircQueueSize(CIRC_QUEUE *queue)
{ {
return queue->nelts; return queue->nelts;
} }
/** /**
* Retrieves the next item from the queue. * @brief Retrieves the next item from the queue.
*/ */
bool CircQueuePop(CIRC_QUEUE *queue, void **data) bool CircQueuePop(CIRC_QUEUE *queue, void **data)
{ {
ASSERT(queue != NULL); ASSERT(queue != NULL);
if (isCircQueueEmpty(queue)) if (isCircQueueEmpty(queue))
{ {
return false; return false;
} }
*data = queue->data[queue->out]; *data = queue->data[queue->out];
queue->nelts--; queue->nelts--;
queue->out++; queue->out++;
if (queue->out >= queue->bounds) if (queue->out >= queue->bounds)
{ {
queue->out -= queue->bounds; queue->out -= queue->bounds;
} }
return true; return true;
} }
/** @} CircularQueue*/
/** @} Utility*/
+225 -214
View File
@@ -1,3 +1,25 @@
/*****************************************************************************/
/**
* @file clist.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief A basic list data structure
* @version 0.1
* @date 2023-02-23
* @note Forked from https://github.com/clibs/list
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @addtogroup cList
* @{
*/
#ifndef LIST_MALLOC #ifndef LIST_MALLOC
#define LIST_MALLOC malloc #define LIST_MALLOC malloc
#endif #endif
@@ -6,337 +28,326 @@
#define LIST_FREE free #define LIST_FREE free
#endif #endif
//
// list.c
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#include <stdint.h> #include <stdint.h>
#include "clist.h" #include "clist.h"
/* /**
* Allocates a new clist_node_t. NULL on failure. * @brief a new clist_node_t. NULL on failure.
*/ */
clist_node_t * clist_node_t *
clist_node_new(void *val) clist_node_new(void *val)
{ {
clist_node_t *self; clist_node_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_node_t)))) if (!(self = LIST_MALLOC(sizeof(clist_node_t))))
return NULL; return NULL;
self->prev = NULL; self->prev = NULL;
self->next = NULL; self->next = NULL;
self->val = val; self->val = val;
return self; return self;
} }
/* /**
* Allocate a new clist_t. NULL on failure. * @brief Allocate a new clist_t. NULL on failure.
*/ */
clist_t * clist_t *
clist_new(void) clist_new(void)
{ {
clist_t *self; clist_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_t)))) if (!(self = LIST_MALLOC(sizeof(clist_t))))
return NULL; return NULL;
self->head = NULL; self->head = NULL;
self->tail = NULL; self->tail = NULL;
self->free = NULL; self->free = NULL;
self->compare = NULL; self->compare = NULL;
self->len = 0; self->len = 0;
return self; return self;
} }
/* /**
* Remove all the node in list. * @brief Remove all the node in list.
* @self: Pointer to the list * @param self: Pointer to the list
*/ */
void clist_clear(clist_t *self) void clist_clear(clist_t *self)
{ {
clist_node_t *next; clist_node_t *next;
clist_node_t *curr = self->head; clist_node_t *curr = self->head;
while (curr != NULL) while (curr != NULL)
{ {
next = curr->next; next = curr->next;
if (self->free) if (self->free)
self->free(curr->val); self->free(curr->val);
LIST_FREE(curr); LIST_FREE(curr);
curr = next; curr = next;
} }
self->len = 0; self->len = 0;
self->head = NULL; self->head = NULL;
} }
/* /**
* Free the list. * @brief Free the list.
* @self: Pointer to the list * @param self: Pointer to the list
*/ */
void clist_destroy(clist_t *self) void clist_destroy(clist_t *self)
{ {
clist_clear(self); clist_clear(self);
LIST_FREE(self); LIST_FREE(self);
} }
/* /**
* Append the given node to the list * @brief Append the given node to the list and return the node, NULL on failure.
* and return the node, NULL on failure. * @param self: Pointer to the list for popping node
* @self: Pointer to the list for popping node * @param node: the node to push
* @node: the node to push
*/ */
clist_node_t * clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node) clist_rpush(clist_t *self, clist_node_t *node)
{ {
if (!node) if (!node)
return NULL; return NULL;
if (self->len) if (self->len)
{ {
node->prev = self->tail; node->prev = self->tail;
node->next = NULL; node->next = NULL;
self->tail->next = node; self->tail->next = node;
self->tail = node; self->tail = node;
} }
else else
{ {
self->head = self->tail = node; self->head = self->tail = node;
node->prev = node->next = NULL; node->prev = node->next = NULL;
} }
++self->len; ++self->len;
return node; return node;
} }
/* /**
* Return / detach the last node in the list, or NULL. * @brief Return / detach the last node in the list, or NULL.
* @self: Pointer to the list for popping node * @param self: Pointer to the list for popping node
*/ */
clist_node_t * clist_node_t *
clist_rpop(clist_t *self) clist_rpop(clist_t *self)
{ {
if (!self->len) if (!self->len)
return NULL; return NULL;
clist_node_t *node = self->tail; clist_node_t *node = self->tail;
if (--self->len) if (--self->len)
{ {
(self->tail = node->prev)->next = NULL; (self->tail = node->prev)->next = NULL;
} }
else else
{ {
self->tail = self->head = NULL; self->tail = self->head = NULL;
} }
node->next = node->prev = NULL; node->next = node->prev = NULL;
return node; return node;
} }
/* /**
* Return / detach the first node in the list, or NULL. * @brief Return / detach the first node in the list, or NULL.
* @self: Pointer to the list for popping node * @param self: Pointer to the list for popping node
*/ */
clist_node_t * clist_node_t *
clist_lpop(clist_t *self) clist_lpop(clist_t *self)
{ {
if (!self->len) if (!self->len)
return NULL; return NULL;
clist_node_t *node = self->head; clist_node_t *node = self->head;
if (--self->len) if (--self->len)
{ {
(self->head = node->next)->prev = NULL; (self->head = node->next)->prev = NULL;
} }
else else
{ {
self->head = self->tail = NULL; self->head = self->tail = NULL;
} }
node->next = node->prev = NULL; node->next = node->prev = NULL;
return node; return node;
} }
/* /**
* Prepend the given node to the list * @brief Prepend the given node to the list and return the node, NULL on failure.
* and return the node, NULL on failure. * @param self: Pointer to the list for pushing node
* @self: Pointer to the list for pushing node * @param node: the node to push
* @node: the node to push
*/ */
clist_node_t * clist_node_t *
clist_lpush(clist_t *self, clist_node_t *node) clist_lpush(clist_t *self, clist_node_t *node)
{ {
if (!node) if (!node)
return NULL; return NULL;
if (self->len) if (self->len)
{ {
node->next = self->head; node->next = self->head;
node->prev = NULL; node->prev = NULL;
self->head->prev = node; self->head->prev = node;
self->head = node; self->head = node;
} }
else else
{ {
self->head = self->tail = node; self->head = self->tail = node;
node->prev = node->next = NULL; node->prev = node->next = NULL;
} }
++self->len; ++self->len;
return node; return node;
} }
/* /**
* Return the node associated to val or NULL. * @brief Return the node associated to val or NULL.
* @self: Pointer to the list for finding given value * @param self: Pointer to the list for finding given value
* @val: Value to find * @param val: Value to find
*/ */
clist_node_t * clist_node_t *
clist_find(clist_t *self, void *val) clist_find(clist_t *self, void *val)
{ {
clist_iterator_t *it = clist_iterator_new(self, LIST_HEAD); clist_iterator_t *it = clist_iterator_new(self, LIST_HEAD);
clist_node_t *node; clist_node_t *node;
while ((node = clist_iterator_next(it))) while ((node = clist_iterator_next(it)))
{ {
if (self->compare) if (self->compare)
{ {
if (self->compare(val, node->val) == 0) if (self->compare(val, node->val) == 0)
{ {
clist_iterator_destroy(it); clist_iterator_destroy(it);
return node; return node;
} }
} }
else else
{ {
if (val == node->val) if (val == node->val)
{ {
clist_iterator_destroy(it); clist_iterator_destroy(it);
return node; return node;
} }
} }
} }
clist_iterator_destroy(it); clist_iterator_destroy(it);
return NULL; return NULL;
} }
/* /**
* Return the node at the given index or NULL. * @brief Return the node at the given index or NULL.
* @self: Pointer to the list for finding given index * @param self: Pointer to the list for finding given index
* @index: the index of node in the list * @param index: the index of node in the list
*/ */
clist_node_t * clist_node_t *
clist_at(clist_t *self, int index) clist_at(clist_t *self, int index)
{ {
clist_direction_t direction = LIST_HEAD; clist_direction_t direction = LIST_HEAD;
if (index < 0) if (index < 0)
{ {
direction = LIST_TAIL; direction = LIST_TAIL;
index = ~index; index = ~index;
} }
if ((unsigned)index < self->len) if ((unsigned)index < self->len)
{ {
clist_iterator_t *it = clist_iterator_new(self, direction); clist_iterator_t *it = clist_iterator_new(self, direction);
clist_node_t *node = clist_iterator_next(it); clist_node_t *node = clist_iterator_next(it);
while (index--) while (index--)
node = clist_iterator_next(it); node = clist_iterator_next(it);
clist_iterator_destroy(it); clist_iterator_destroy(it);
return node; return node;
} }
return NULL; return NULL;
} }
/* /**
* Remove the given node from the list, freeing it and it's value. * @brief Remove the given node from the list, freeing it and it's value.
* @self: Pointer to the list to delete a node * @param self: Pointer to the list to delete a node
* @node: Pointer the node to be deleted * @param node: Pointer the node to be deleted
*/ */
void clist_remove(clist_t *self, clist_node_t *node) void clist_remove(clist_t *self, clist_node_t *node)
{ {
node->prev node->prev
? (node->prev->next = node->next) ? (node->prev->next = node->next)
: (self->head = node->next); : (self->head = node->next);
node->next node->next
? (node->next->prev = node->prev) ? (node->next->prev = node->prev)
: (self->tail = node->prev); : (self->tail = node->prev);
if (self->free) if (self->free)
self->free(node->val); self->free(node->val);
LIST_FREE(node); LIST_FREE(node);
--self->len; --self->len;
} }
/* /**
* Allocate a new clist_iterator_t. NULL on failure. * @brief Allocate a new clist_iterator_t. NULL on failure.\n
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL. * Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/ */
clist_iterator_t * clist_iterator_t *
clist_iterator_new(clist_t *list, clist_direction_t direction) clist_iterator_new(clist_t *list, clist_direction_t direction)
{ {
clist_node_t *node = direction == LIST_HEAD clist_node_t *node = direction == LIST_HEAD
? list->head ? list->head
: list->tail; : list->tail;
return clist_iterator_new_from_node(node, direction); return clist_iterator_new_from_node(node, direction);
} }
/* /**
* Allocate a new clist_iterator_t with the given start * @brief Allocate a new clist_iterator_t with the given start
* node. NULL on failure. * node. NULL on failure.
*/ */
clist_iterator_t * clist_iterator_t *
clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction) clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction)
{ {
clist_iterator_t *self; clist_iterator_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_iterator_t)))) if (!(self = LIST_MALLOC(sizeof(clist_iterator_t))))
return NULL; return NULL;
self->next = node; self->next = node;
self->direction = direction; self->direction = direction;
return self; return self;
} }
/* /**
* Return the next clist_node_t or NULL when no more * @brief Return the next clist_node_t or NULL when no more
* nodes remain in the list. * nodes remain in the list.
*/ */
clist_node_t * clist_node_t *
clist_iterator_next(clist_iterator_t *self) clist_iterator_next(clist_iterator_t *self)
{ {
clist_node_t *curr = self->next; clist_node_t *curr = self->next;
if (curr) if (curr)
{ {
self->next = self->direction == LIST_HEAD self->next = self->direction == LIST_HEAD
? curr->next ? curr->next
: curr->prev; : curr->prev;
} }
return curr; return curr;
} }
/* /**
* Free the list iterator. * @brief Free the list iterator.
*/ */
void clist_iterator_destroy(clist_iterator_t *self) void clist_iterator_destroy(clist_iterator_t *self)
{ {
LIST_FREE(self); LIST_FREE(self);
self = NULL; self = NULL;
} }
/** @} cList*/
/** @} Utility*/
+7 -2
View File
@@ -10,11 +10,14 @@
* [2022-07-16]: New branch for Dijian. * [2022-07-16]: New branch for Dijian.
* [2021-11-16]: Initial version. * [2021-11-16]: Initial version.
* *
* Copyright(c) 2021 Beijing Institute of Technology. * Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking * Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup COMMON_MACRO
* @{
*/
/***************************** Include Files *********************************/ /***************************** Include Files *********************************/
#include "common.h" #include "common.h"
#include "error.h" #include "error.h"
@@ -44,3 +47,5 @@ void AppAssert(const char *file, int line)
while (1) while (1)
; ;
} }
/** @} */
+299 -294
View File
@@ -11,11 +11,14 @@
* [2022-07-17]: Add CRC16_0x8005 CRC8_0x31. * [2022-07-17]: Add CRC16_0x8005 CRC8_0x31.
* [2022-01-06]: Initial verion (Basic CRC-16). * [2022-01-06]: Initial verion (Basic CRC-16).
* *
* Copyright(c) 2021 Beijing Institute of Technology. * Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking * Lab of Communication and Networking
* *
******************************************************************************/ ******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
#include "util.h" #include "util.h"
#include "error.h" #include "error.h"
@@ -24,223 +27,223 @@
// Reversed // Reversed
static const uint16_t crc16_1021_lsb_lut[256] = static const uint16_t crc16_1021_lsb_lut[256] =
{ {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
}; };
// CRC-16-MAXIM G(X)=X16+X15+X2+1 // CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_lsb_lut[256] = const uint16_t crc16_8005_lsb_lut[256] =
{ {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
}; };
// CRC-8-MAXIM G(X)=X8+X5+X4+1 // CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_lsb_lut[256] = const uint8_t crc8_31_lsb_lut[256] =
{ {
0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83, 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41, 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E, 0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E,
0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC, 0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC,
0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0, 0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0,
0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62, 0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62,
0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D, 0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D,
0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF, 0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF,
0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5, 0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5,
0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07, 0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07,
0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58, 0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58,
0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A, 0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A,
0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6, 0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6,
0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24, 0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24,
0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B, 0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B,
0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9, 0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9,
0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F, 0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F,
0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD, 0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD,
0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92, 0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92,
0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50, 0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50,
0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C, 0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C,
0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE, 0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE,
0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1, 0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1,
0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73, 0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73,
0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49, 0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49,
0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B, 0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B,
0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4, 0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4,
0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16, 0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16,
0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A, 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A,
0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8, 0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8,
0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7, 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7,
0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35
}; };
#else #else
// CRC-16-CCITT G(X)=X16+X12+X5+1 // CRC-16-CCITT G(X)=X16+X12+X5+1
static const uint16_t crc16_1021_msb_lut[256] = static const uint16_t crc16_1021_msb_lut[256] =
{ {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
}; };
// CRC-16-MAXIM G(X)=X16+X15+X2+1 // CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_msb_lut[256] = const uint16_t crc16_8005_msb_lut[256] =
{ {
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
}; };
// CRC-8-MAXIM G(X)=X8+X5+X4+1 // CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_msb_lut[256] = const uint8_t crc8_31_msb_lut[256] =
{ {
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97, 0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E, 0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4, 0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D, 0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11, 0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8, 0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52, 0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB, 0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA, 0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13, 0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9, 0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50, 0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C, 0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95, 0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F, 0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6, 0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED, 0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54, 0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE, 0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17, 0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B, 0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2, 0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28, 0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91, 0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0, 0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69, 0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93, 0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A, 0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56, 0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF, 0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15, 0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC 0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
}; };
#endif #endif
@@ -252,12 +255,12 @@ uint8_t/uint16_t/uint32_t crc_val = 0x0;
// LSB // LSB
for(int i = 0; i < sizeof(dataBuff); i++) for(int i = 0; i < sizeof(dataBuff); i++)
{ {
crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])]; crc_val = (crc_val >> BITS_IN_BYTE) ^ crc_lsb_lut[(uint8)(crc_val^dataBuff[i])];
} }
// MSB // MSB
for(int i = 0; i < sizeof(dataBuff); i++) for(int i = 0; i < sizeof(dataBuff); i++)
{ {
crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])]; crc_val = (crc_val << BITS_IN_BYTE) ^ crc_msb_lut[(uint8)((crc_val>>8)^dataBuff[i])];
} }
*/ */
@@ -276,32 +279,32 @@ for(int i = 0; i < sizeof(dataBuff); i++)
******************************************************************************/ ******************************************************************************/
int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal) int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal)
{ {
uint8_t crc = CRC8_INIT; uint8_t crc = CRC8_INIT;
const uint8_t *crc_lut = NULL; const uint8_t *crc_lut = NULL;
switch (poly) switch (poly)
{ {
#ifdef __CRC_LSB #ifdef __CRC_LSB
case 0x31: case 0x31:
crc_lut = crc8_31_lsb_lut; crc_lut = crc8_31_lsb_lut;
break; break;
default: default:
return FAILURE; return FAILURE;
#else #else
case 0x31: case 0x31:
crc_lut = crc8_31_msb_lut; crc_lut = crc8_31_msb_lut;
break; break;
default: default:
return FAILURE; return FAILURE;
#endif #endif
} }
for (int i = 0; i < dataLen; i++) for (int i = 0; i < dataLen; i++)
{ {
crc = crc_lut[(uint8_t)(crc ^ buffPtr[i])]; crc = crc_lut[(uint8_t)(crc ^ buffPtr[i])];
} }
*crcVal = crc; *crcVal = crc;
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -319,40 +322,40 @@ int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal)
******************************************************************************/ ******************************************************************************/
int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal) int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal)
{ {
uint16_t crc = CRC16_INIT; uint16_t crc = CRC16_INIT;
const uint16_t *crc_lut = NULL; const uint16_t *crc_lut = NULL;
switch (poly) switch (poly)
{ {
#ifdef __CRC_LSB #ifdef __CRC_LSB
case 0x8005: case 0x8005:
crc_lut = crc16_8005_lsb_lut; crc_lut = crc16_8005_lsb_lut;
break; break;
case 0x1021: case 0x1021:
crc_lut = crc16_1021_lsb_lut; crc_lut = crc16_1021_lsb_lut;
break; break;
default: default:
return FAILURE; return FAILURE;
#else #else
case 0x8005: case 0x8005:
crc_lut = crc16_8005_msb_lut; crc_lut = crc16_8005_msb_lut;
break; break;
case 0x1021: case 0x1021:
crc_lut = crc16_1021_msb_lut; crc_lut = crc16_1021_msb_lut;
break; break;
default: default:
return FAILURE; return FAILURE;
#endif #endif
} }
for (int i = 0; i < dataLen; i++) for (int i = 0; i < dataLen; i++)
{ {
#ifdef __CRC_LSB #ifdef __CRC_LSB
crc = (crc >> 8) ^ crc_lut[(uint8_t)(crc ^ buffPtr[i])]; crc = (crc >> 8) ^ crc_lut[(uint8_t)(crc ^ buffPtr[i])];
#else #else
crc = (crc << 8) ^ crc_lut[(uint8_t)((crc >> 8) ^ buffPtr[i])]; crc = (crc << 8) ^ crc_lut[(uint8_t)((crc >> 8) ^ buffPtr[i])];
#endif #endif
} }
*crcVal = crc; *crcVal = crc;
return SUCCESS; return SUCCESS;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -370,30 +373,30 @@ int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVa
******************************************************************************/ ******************************************************************************/
bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly)
{ {
int Status = SUCCESS; int Status = SUCCESS;
uint8_t crc_comp; uint8_t crc_comp;
uint8_t crc; uint8_t crc;
if (dataLen == 0) if (dataLen == 0)
{ {
return false; return false;
} }
crc_comp = (uint8_t)(*(buffPtr + crcOffset)); crc_comp = (uint8_t)(*(buffPtr + crcOffset));
Status = crc8_gen(buffPtr, dataLen, poly, &crc); Status = crc8_gen(buffPtr, dataLen, poly, &crc);
if (Status == SUCCESS) if (Status == SUCCESS)
{ {
if (crc == crc_comp) if (crc == crc_comp)
{ {
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
else else
{ {
return false; return false;
} }
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -411,29 +414,31 @@ bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t
******************************************************************************/ ******************************************************************************/
bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly)
{ {
int Status = SUCCESS; int Status = SUCCESS;
uint16_t crc_comp; uint16_t crc_comp;
uint16_t crc; uint16_t crc;
if (dataLen == 0) if (dataLen == 0)
{ {
return false; return false;
} }
crc_comp = (uint16_t)(*(buffPtr + crcOffset)); crc_comp = (uint16_t)(*(buffPtr + crcOffset));
crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8); crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8);
Status = crc16_gen(buffPtr, dataLen, poly, &crc); Status = crc16_gen(buffPtr, dataLen, poly, &crc);
if (Status == SUCCESS) if (Status == SUCCESS)
{ {
if (crc == crc_comp) if (crc == crc_comp)
{ {
return true; return true;
} }
else else
{ {
return false; return false;
} }
} }
else else
{ {
return false; return false;
} }
} }
/** @}*/
+1 -1
View File
@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* @file list.c * @file list.c
* @brief List library implementation * @brief List library implementation
* @author Mihail Chindris (mihail.chindris@analog.com) * @author Mihail Chindris (mihail.chindris@analog.com)
******************************************************************************** ********************************************************************************
+56 -21
View File
@@ -1,15 +1,30 @@
/******************************************************************************/ /*****************************************************************************/
/**
* @file util.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Utility functions implementation file
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files **********************************/ /***************************** Include Files **********************************/
/******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
// #include <arm_acle.h> // #include <arm_acle.h>
#include "util.h" #include "util.h"
#include "error.h" #include "error.h"
/******************************************************************************/
/************************** Functions Implementation **************************/ /************************** Functions Implementation **************************/
/******************************************************************************/
#ifdef __BITSWAP_TABLE #ifdef __BITSWAP_TABLE
static uint8_t byte_flipLR[256] = static uint8_t byte_flipLR[256] =
{ {
@@ -48,17 +63,26 @@ static uint8_t byte_flipLR[256] =
}; };
#endif #endif
/**
* @brief Write a 32bit word to specific memory address
*/
inline void IO_Out32(uintptr_t addr, uint32_t value) inline void IO_Out32(uintptr_t addr, uint32_t value)
{ {
volatile uint32_t *localAddr = (volatile uint32_t *)addr; volatile uint32_t *localAddr = (volatile uint32_t *)addr;
*localAddr = value; *localAddr = value;
} }
/**
* @brief Read a 32bit word from specific memory address
*/
inline uint32_t IO_In32(uintptr_t addr) inline uint32_t IO_In32(uintptr_t addr)
{ {
return *(volatile uint32_t *)addr; return *(volatile uint32_t *)addr;
} }
/**
* @brief Swap a byte word bit-wise
*/
uint8_t byte_bit_swap(uint8_t byte) uint8_t byte_bit_swap(uint8_t byte)
{ {
#ifdef __BITSWAP_TABLE #ifdef __BITSWAP_TABLE
@@ -68,6 +92,9 @@ uint8_t byte_bit_swap(uint8_t byte)
#endif #endif
} }
/**
* @brief Swap 32bit word bit-wise
*/
uint32_t word_bit_swap(uint32_t word) uint32_t word_bit_swap(uint32_t word)
{ {
#ifdef __BITSWAP_TABLE #ifdef __BITSWAP_TABLE
@@ -85,6 +112,9 @@ uint32_t word_bit_swap(uint32_t word)
#endif #endif
} }
/**
* @brief Count ones in an 32bit word
*/
uint32_t count_ones(uint32_t word) uint32_t count_ones(uint32_t word)
{ {
#ifdef __GNUC__ #ifdef __GNUC__
@@ -101,13 +131,16 @@ uint32_t count_ones(uint32_t word)
#endif #endif
} }
/**
* @brief Convert fix ;oint number to float number
*/
double fix2double(int32_t val, uint8_t frac_bits) double fix2double(int32_t val, uint8_t frac_bits)
{ {
return (((double)val) / (BIT(frac_bits))); return (((double)val) / (BIT(frac_bits)));
} }
/** /**
* Find first set bit in word. * @brief Find first set bit in word.
*/ */
uint32_t find_first_set_bit(uint32_t word) uint32_t find_first_set_bit(uint32_t word)
{ {
@@ -136,7 +169,7 @@ uint32_t find_first_set_bit(uint32_t word)
} }
/** /**
* Find last set bit in word. * @brief Find last set bit in word.
*/ */
uint32_t find_last_set_bit(uint32_t word) uint32_t find_last_set_bit(uint32_t word)
{ {
@@ -166,7 +199,7 @@ uint32_t find_last_set_bit(uint32_t word)
} }
/** /**
* Locate the closest element in an array. * @brief Locate the closest element in an array.
*/ */
uint32_t find_closest(int32_t val, uint32_t find_closest(int32_t val,
const int32_t *array, const int32_t *array,
@@ -189,7 +222,7 @@ uint32_t find_closest(int32_t val,
} }
/** /**
* Shift the value and apply the specified mask. * @brief Shift the value and apply the specified mask.
*/ */
uint32_t field_prep(uint32_t mask, uint32_t val) uint32_t field_prep(uint32_t mask, uint32_t val)
{ {
@@ -197,7 +230,7 @@ uint32_t field_prep(uint32_t mask, uint32_t val)
} }
/** /**
* Get a field specified by a mask from a word. * @brief Get a field specified by a mask from a word.
*/ */
uint32_t field_get(uint32_t mask, uint32_t word) uint32_t field_get(uint32_t mask, uint32_t word)
{ {
@@ -205,7 +238,7 @@ uint32_t field_get(uint32_t mask, uint32_t word)
} }
/** /**
* Log base 2 of the given number. * @brief Log base 2 of the given number.
*/ */
int32_t log_base_2(uint32_t x) int32_t log_base_2(uint32_t x)
{ {
@@ -213,7 +246,7 @@ int32_t log_base_2(uint32_t x)
} }
/** /**
* Find greatest common divisor of the given two numbers. * @brief Find greatest common divisor of the given two numbers.
*/ */
uint32_t greatest_common_divisor(uint32_t a, uint32_t greatest_common_divisor(uint32_t a,
uint32_t b) uint32_t b)
@@ -232,7 +265,7 @@ uint32_t greatest_common_divisor(uint32_t a,
} }
/** /**
* Calculate best rational approximation for a given fraction. * @brief Calculate best rational approximation for a given fraction.
*/ */
void rational_best_approximation(uint32_t given_numerator, void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator, uint32_t given_denominator,
@@ -257,7 +290,7 @@ void rational_best_approximation(uint32_t given_numerator,
} }
/** /**
* Calculate the number of set bits. * @brief Calculate the number of set bits.
*/ */
uint32_t hweight8(uint32_t word) uint32_t hweight8(uint32_t word)
{ {
@@ -274,7 +307,7 @@ uint32_t hweight8(uint32_t word)
} }
/** /**
* Calculate the quotient and the remainder of an integer division. * @brief Calculate the quotient and the remainder of an integer division.
*/ */
uint64_t do_div(uint64_t *n, uint64_t do_div(uint64_t *n,
uint64_t base) uint64_t base)
@@ -288,7 +321,7 @@ uint64_t do_div(uint64_t *n,
} }
/** /**
* Unsigned 64bit divide with 64bit divisor and remainder * @brief Unsigned 64bit divide with 64bit divisor and remainder
*/ */
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder) uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{ {
@@ -298,7 +331,7 @@ uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
} }
/** /**
* Unsigned 64bit divide with 32bit divisor with remainder * @brief Unsigned 64bit divide with 32bit divisor with remainder
*/ */
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder) uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{ {
@@ -308,7 +341,7 @@ uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
} }
/** /**
* Signed 64bit divide with 32bit divisor with remainder * @brief Signed 64bit divide with 32bit divisor with remainder
*/ */
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder) int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
{ {
@@ -317,7 +350,7 @@ int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
} }
/** /**
* Unsigned 64bit divide with 32bit divisor * @brief Unsigned 64bit divide with 32bit divisor
*/ */
uint64_t div_u64(uint64_t dividend, uint32_t divisor) uint64_t div_u64(uint64_t dividend, uint32_t divisor)
{ {
@@ -327,7 +360,7 @@ uint64_t div_u64(uint64_t dividend, uint32_t divisor)
} }
/** /**
* Signed 64bit divide with 32bit divisor * @brief Signed 64bit divide with 32bit divisor
*/ */
int64_t div_s64(int64_t dividend, int32_t divisor) int64_t div_s64(int64_t dividend, int32_t divisor)
{ {
@@ -336,7 +369,7 @@ int64_t div_s64(int64_t dividend, int32_t divisor)
} }
/** /**
* Converts from string to int32_t * @brief Converts from string to int32_t
* @param *str * @param *str
* @return int32_t * @return int32_t
*/ */
@@ -352,7 +385,7 @@ int32_t str_to_int32(const char *str)
} }
/** /**
* Converts from string to uint32_t * @brief Converts from string to uint32_t
* @param *str * @param *str
* @return uint32_t * @return uint32_t
*/ */
@@ -366,3 +399,5 @@ uint32_t srt_to_uint32(const char *str)
else else
return value; return value;
} }
/** @} */
@@ -68,7 +68,7 @@ void linklayer_setup(void)
ASSERT_EQUAL(SUCCESS, Status); ASSERT_EQUAL(SUCCESS, Status);
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig); Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_EQUAL(SUCCESS, Status); ASSERT_EQUAL(SUCCESS, Status);
Status = Phy_InstInit(&phyInstPtr, &l1Config); Status = Phy_Init(&phyInstPtr, &l1Config);
ASSERT_EQUAL(SUCCESS, Status); ASSERT_EQUAL(SUCCESS, Status);
// Update l2 config // Update l2 config