Initial version.
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Antenna configuration functions.
|
||||
*
|
||||
* Author: Fan Hao
|
||||
* Date: 2022-06-18 16:37
|
||||
* LastEditors: Fan Hao
|
||||
* LastEditTime: 2022-06-18 17:15
|
||||
* Revisions: Rev 0.0
|
||||
* History:
|
||||
* [2022-06-18]: Initial version.
|
||||
*
|
||||
* Copyright(c) 2022 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "phy_ctrl.h"
|
||||
#include "../error.h"
|
||||
|
||||
#define ANT_PI 3.14159265358979323846
|
||||
#define ANT_COINFO_HEAD 0xAA
|
||||
#define ANT_COINFO_TAIL 0xCC
|
||||
|
||||
#define CTRL_WORD_DEFAULT 0x00
|
||||
|
||||
#define ANT_MODE_BEAM_MASK 0xF0
|
||||
#define ANT_MODE_NARROR_BEAM 0x00 // 8
|
||||
#define ANT_MODE_WIDE_BEAM_1 0x10 // 25
|
||||
#define ANT_MODE_WIDE_BEAM_2 0x20 // 60
|
||||
#define ANT_MODE_WIDE_BEAM_3 0x30 // 120
|
||||
|
||||
#define ANT_MODE_HIGH_POWER 0x00
|
||||
#define ANT_MODE_LOWAPOWER 0x04
|
||||
#define ANT_MODE_STANDBY 0x0F
|
||||
#define ATN_MODE_DEFAULT (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_LOWAPOWER)
|
||||
#define ATN_MODE_HIGH (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_HIGH_POWER)
|
||||
|
||||
#define DEFAULT_CENTRTAL_FREQ 0x06D7 // 26.25GHz
|
||||
|
||||
#define RXTXMODE_RX 0x00
|
||||
#define RXTXMODE_TX 0x01
|
||||
|
||||
#define CALIBRMODE_NORMAL 0x00
|
||||
#define CALIBRMODE_SINGLE_TR_CAL 0x01
|
||||
|
||||
#define MODECTRL_DEFAULT 0x00
|
||||
|
||||
uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] = {0};
|
||||
|
||||
uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] = {1500};
|
||||
|
||||
uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = {
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400
|
||||
};
|
||||
|
||||
uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = {1500};
|
||||
|
||||
uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = { 1500, 1600, 1700,
|
||||
1800, 1900, 2000, 1500, 1600, 1700, 1800, 1900 };
|
||||
|
||||
uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] = {
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400
|
||||
};
|
||||
|
||||
uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = {
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
|
||||
2400, 2400, 2400, 2400, 2400, 2400, 2400
|
||||
};
|
||||
|
||||
uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] ={ 1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600 , 1700,
|
||||
1800, 1900, 2000, 1500, 1600 , 1700, 1800, 1900, 2000, 1500, 1500};
|
||||
|
||||
uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] = { 500, 600, 700, 800, 900, 1000, 500, 600 , 700,
|
||||
800, 900, 1000, 500, 600 , 700, 800, 900, 1000, 500, 500 };
|
||||
|
||||
// Pair by regex
|
||||
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
|
||||
#if defined(PHY_BEAM_SET_PRESET)
|
||||
ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = {
|
||||
{.oaxis = 0 , .raxis = 222}, {.oaxis = 10, .raxis = 85 },
|
||||
{.oaxis = 14, .raxis = 307}, {.oaxis = 17, .raxis = 170},
|
||||
{.oaxis = 19, .raxis = 32 }, {.oaxis = 21, .raxis = 255},
|
||||
{.oaxis = 24, .raxis = 117}, {.oaxis = 25, .raxis = 340},
|
||||
{.oaxis = 27, .raxis = 202}, {.oaxis = 29, .raxis = 65 },
|
||||
{.oaxis = 31, .raxis = 287}, {.oaxis = 32, .raxis = 150},
|
||||
{.oaxis = 34, .raxis = 12 }, {.oaxis = 35, .raxis = 235},
|
||||
{.oaxis = 36, .raxis = 97 }, {.oaxis = 38, .raxis = 320},
|
||||
{.oaxis = 39, .raxis = 182}, {.oaxis = 40, .raxis = 45 },
|
||||
{.oaxis = 41, .raxis = 267}, {.oaxis = 43, .raxis = 130},
|
||||
{.oaxis = 44, .raxis = 352}, {.oaxis = 45, .raxis = 215},
|
||||
{.oaxis = 46, .raxis = 77 }, {.oaxis = 47, .raxis = 300},
|
||||
{.oaxis = 48, .raxis = 162}, {.oaxis = 49, .raxis = 25 },
|
||||
{.oaxis = 50, .raxis = 247}, {.oaxis = 51, .raxis = 110},
|
||||
{.oaxis = 52, .raxis = 332}, {.oaxis = 53, .raxis = 195},
|
||||
{.oaxis = 54, .raxis = 57 }, {.oaxis = 55, .raxis = 280},
|
||||
{.oaxis = 56, .raxis = 142}, {.oaxis = 57, .raxis = 5 },
|
||||
{.oaxis = 58, .raxis = 227}, {.oaxis = 59, .raxis = 90 },
|
||||
{.oaxis = 60, .raxis = 312}
|
||||
};
|
||||
ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = {
|
||||
{.oaxis = 0 , .raxis = 222}, {.oaxis = 7 , .raxis = 85 },
|
||||
{.oaxis = 10, .raxis = 307}, {.oaxis = 13, .raxis = 170},
|
||||
{.oaxis = 15, .raxis = 32 }, {.oaxis = 17, .raxis = 255},
|
||||
{.oaxis = 18, .raxis = 117}, {.oaxis = 20, .raxis = 340},
|
||||
{.oaxis = 21, .raxis = 202}, {.oaxis = 22, .raxis = 65 },
|
||||
{.oaxis = 24, .raxis = 287}, {.oaxis = 25, .raxis = 150},
|
||||
{.oaxis = 26, .raxis = 12 }, {.oaxis = 27, .raxis = 235},
|
||||
{.oaxis = 28, .raxis = 97 }, {.oaxis = 29, .raxis = 320},
|
||||
{.oaxis = 30, .raxis = 182}, {.oaxis = 31, .raxis = 45 },
|
||||
{.oaxis = 32, .raxis = 267}, {.oaxis = 33, .raxis = 130},
|
||||
{.oaxis = 34, .raxis = 352}, {.oaxis = 34, .raxis = 215},
|
||||
{.oaxis = 35, .raxis = 77 }, {.oaxis = 36, .raxis = 300},
|
||||
{.oaxis = 37, .raxis = 162}, {.oaxis = 38, .raxis = 25 },
|
||||
{.oaxis = 38, .raxis = 247}, {.oaxis = 39, .raxis = 110},
|
||||
{.oaxis = 40, .raxis = 332}, {.oaxis = 41, .raxis = 195},
|
||||
{.oaxis = 41, .raxis = 57 }, {.oaxis = 42, .raxis = 280},
|
||||
{.oaxis = 43, .raxis = 142}, {.oaxis = 44, .raxis = 5 },
|
||||
{.oaxis = 44, .raxis = 227}, {.oaxis = 45, .raxis = 90 },
|
||||
{.oaxis = 46, .raxis = 312}, {.oaxis = 46, .raxis = 175},
|
||||
{.oaxis = 47, .raxis = 37 }, {.oaxis = 48, .raxis = 260},
|
||||
{.oaxis = 48, .raxis = 122}, {.oaxis = 49, .raxis = 345},
|
||||
{.oaxis = 49, .raxis = 207}, {.oaxis = 50, .raxis = 70 },
|
||||
{.oaxis = 51, .raxis = 292}, {.oaxis = 51, .raxis = 155},
|
||||
{.oaxis = 52, .raxis = 17 }, {.oaxis = 53, .raxis = 240},
|
||||
{.oaxis = 53, .raxis = 102}, {.oaxis = 54, .raxis = 325},
|
||||
{.oaxis = 54, .raxis = 187}, {.oaxis = 55, .raxis = 50 },
|
||||
{.oaxis = 55, .raxis = 272}, {.oaxis = 56, .raxis = 135},
|
||||
{.oaxis = 57, .raxis = 357}, {.oaxis = 57, .raxis = 220},
|
||||
{.oaxis = 58, .raxis = 82 }, {.oaxis = 58, .raxis = 305},
|
||||
{.oaxis = 59, .raxis = 167}, {.oaxis = 59, .raxis = 30 },
|
||||
{.oaxis = 60, .raxis = 252}
|
||||
};
|
||||
#elif defined(PHY_BEAM_SET_PRESET_LSX)
|
||||
ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = {
|
||||
{.oaxis = 0 , .raxis =2225},{.oaxis = 96 , .raxis =850 },
|
||||
{.oaxis = 135, .raxis =3075},{.oaxis = 166, .raxis =1700},
|
||||
{.oaxis = 192, .raxis =325 },{.oaxis = 215, .raxis =2550},
|
||||
{.oaxis = 236, .raxis =1174},{.oaxis = 255, .raxis =3399},
|
||||
{.oaxis = 273, .raxis =2024},{.oaxis = 290, .raxis =649 },
|
||||
{.oaxis = 306, .raxis =2874},{.oaxis = 321, .raxis =1499},
|
||||
{.oaxis = 336, .raxis =124 },{.oaxis = 350, .raxis =2349},
|
||||
{.oaxis = 363, .raxis =974 },{.oaxis = 377, .raxis =3199},
|
||||
{.oaxis = 389, .raxis =1824},{.oaxis = 402, .raxis =449 },
|
||||
{.oaxis = 414, .raxis =2674},{.oaxis = 426, .raxis =1298},
|
||||
{.oaxis = 438, .raxis =3523},{.oaxis = 449, .raxis =2148},
|
||||
{.oaxis = 460, .raxis =773 },{.oaxis = 471, .raxis =2998},
|
||||
{.oaxis = 482, .raxis =1623},{.oaxis = 492, .raxis =248 },
|
||||
{.oaxis = 503, .raxis =2473},{.oaxis = 513, .raxis =1098},
|
||||
{.oaxis = 523, .raxis =3323},{.oaxis = 533, .raxis =1948},
|
||||
{.oaxis = 543, .raxis =573 },{.oaxis = 553, .raxis =2798},
|
||||
{.oaxis = 563, .raxis =1422},{.oaxis = 572, .raxis =47 },
|
||||
{.oaxis = 581, .raxis =2272},{.oaxis = 591, .raxis =897 },
|
||||
{.oaxis = 600, .raxis =3122}
|
||||
};
|
||||
ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = {
|
||||
{.oaxis = 0 , .raxis =2225},{.oaxis = 74 , .raxis =850 },
|
||||
{.oaxis = 105, .raxis =3075},{.oaxis = 128, .raxis =1700},
|
||||
{.oaxis = 148, .raxis =325 },{.oaxis = 166, .raxis =2550},
|
||||
{.oaxis = 182, .raxis =1174},{.oaxis = 197, .raxis =3399},
|
||||
{.oaxis = 210, .raxis =2024},{.oaxis = 223, .raxis =649 },
|
||||
{.oaxis = 236, .raxis =2874},{.oaxis = 247, .raxis =1499},
|
||||
{.oaxis = 258, .raxis =124 },{.oaxis = 269, .raxis =2349},
|
||||
{.oaxis = 280, .raxis =974 },{.oaxis = 290, .raxis =3199},
|
||||
{.oaxis = 299, .raxis =1824},{.oaxis = 309, .raxis =449 },
|
||||
{.oaxis = 318, .raxis =2674},{.oaxis = 327, .raxis =1298},
|
||||
{.oaxis = 336, .raxis =3523},{.oaxis = 344, .raxis =2148},
|
||||
{.oaxis = 352, .raxis =773 },{.oaxis = 361, .raxis =2998},
|
||||
{.oaxis = 369, .raxis =1623},{.oaxis = 377, .raxis =248 },
|
||||
{.oaxis = 384, .raxis =2473},{.oaxis = 392, .raxis =1098},
|
||||
{.oaxis = 399, .raxis =3323},{.oaxis = 407, .raxis =1948},
|
||||
{.oaxis = 414, .raxis =573 },{.oaxis = 421, .raxis =2798},
|
||||
{.oaxis = 428, .raxis =1422},{.oaxis = 435, .raxis =47 },
|
||||
{.oaxis = 442, .raxis =2272},{.oaxis = 449, .raxis =897 },
|
||||
{.oaxis = 456, .raxis =3122},{.oaxis = 462, .raxis =1747},
|
||||
{.oaxis = 469, .raxis =372 },{.oaxis = 475, .raxis =2597},
|
||||
{.oaxis = 482, .raxis =1222},{.oaxis = 488, .raxis =3447},
|
||||
{.oaxis = 495, .raxis =2072},{.oaxis = 501, .raxis =697 },
|
||||
{.oaxis = 507, .raxis =2922},{.oaxis = 513, .raxis =1546},
|
||||
{.oaxis = 519, .raxis =171 },{.oaxis = 525, .raxis =2396},
|
||||
{.oaxis = 531, .raxis =1021},{.oaxis = 537, .raxis =3246},
|
||||
{.oaxis = 543, .raxis =1871},{.oaxis = 549, .raxis =496 },
|
||||
{.oaxis = 555, .raxis =2721},{.oaxis = 561, .raxis =1346},
|
||||
{.oaxis = 566, .raxis =3571},{.oaxis = 572, .raxis =2196},
|
||||
{.oaxis = 578, .raxis =821 },{.oaxis = 583, .raxis =3045},
|
||||
{.oaxis = 589, .raxis =1670},{.oaxis = 594, .raxis =295 },
|
||||
{.oaxis = 600, .raxis =2520}
|
||||
};
|
||||
#else
|
||||
PHY_ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = {0};
|
||||
PHY_ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = {0};
|
||||
#endif
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param antCoinfoPtr
|
||||
*
|
||||
* @return
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_AntCoinfoInit(PHY_ANT_CONFIG *antCoinfoPtr)
|
||||
{
|
||||
if (antCoinfoPtr == NULL)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
antCoinfoPtr->head = ANT_COINFO_HEAD;
|
||||
antCoinfoPtr->tail = ANT_COINFO_TAIL;
|
||||
antCoinfoPtr->ctrlWord = 0x00;
|
||||
#ifdef ANT_HIGH_POWER
|
||||
antCoinfoPtr->antMode = ATN_MODE_HIGH;
|
||||
#else
|
||||
antCoinfoPtr->antMode = ATN_MODE_DEFAULT;
|
||||
#endif
|
||||
|
||||
|
||||
// FIXME: Dummy default value.
|
||||
// off axis angle setting
|
||||
antCoinfoPtr->oaxis[0] = 0;
|
||||
antCoinfoPtr->oaxis[1] = 0;
|
||||
// round axis angle setting
|
||||
antCoinfoPtr->raxis[0] = 0;
|
||||
antCoinfoPtr->raxis[1] = 0;
|
||||
// ***********************
|
||||
|
||||
antCoinfoPtr->antFreq[0] = (uint8_t)(DEFAULT_CENTRTAL_FREQ);
|
||||
antCoinfoPtr->antFreq[1] = (uint8_t)(DEFAULT_CENTRTAL_FREQ >> 8);
|
||||
|
||||
// FIXME: Dummy default value.
|
||||
// trSelect
|
||||
antCoinfoPtr->trSlect = 0;
|
||||
// Antenna attenuation setting
|
||||
antCoinfoPtr->antAtt = 20;
|
||||
// phase setting
|
||||
antCoinfoPtr->phase = 0;
|
||||
// ***********************
|
||||
|
||||
antCoinfoPtr->rxtxMode = RXTXMODE_RX;
|
||||
antCoinfoPtr->calibrMode = CALIBRMODE_NORMAL;
|
||||
|
||||
// FIXME: Dummy default value.
|
||||
// DD enable
|
||||
antCoinfoPtr->ddEn = 0;
|
||||
// DD mgc
|
||||
antCoinfoPtr->ddMgc = 0;
|
||||
// RF mode control
|
||||
antCoinfoPtr->rfCtrl = 0;
|
||||
// RF MGC control
|
||||
antCoinfoPtr->rfMgc = 0;
|
||||
// RF channel 1&2 calibration mgc
|
||||
antCoinfoPtr->rf12CalMgc = 0;
|
||||
// RF channel 2&3 calibration mgc
|
||||
antCoinfoPtr->rf34CalMgc = 0;
|
||||
// Receive channel 1 MGC
|
||||
antCoinfoPtr->rcv1Mgc = 0;
|
||||
// Receive channel 2 MGC
|
||||
antCoinfoPtr->rcv2Mgc = 0;
|
||||
// Receive channel 3 MGC
|
||||
antCoinfoPtr->rcv3Mgc = 0;
|
||||
// Receive channel 4 MGC
|
||||
antCoinfoPtr->rcv4Mgc = 0;
|
||||
// ***********************
|
||||
|
||||
memset(antCoinfoPtr->dummy, 0x00, sizeof(antCoinfoPtr->dummy));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo)
|
||||
{
|
||||
if(instPtr->beamWd.next == ANT_BEAM_8){
|
||||
if (beamNo >= NUM_ANT_NRRW_PATTERN)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
instPtr->beamNo.next = beamNo;
|
||||
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)(antNrrwPattern[beamNo].oaxis);
|
||||
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)((antNrrwPattern[beamNo].oaxis) >> 8);
|
||||
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)(antNrrwPattern[beamNo].raxis);
|
||||
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)((antNrrwPattern[beamNo].raxis) >> 8);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else if(instPtr->beamWd.next == ANT_BEAM_25){
|
||||
if (beamNo >= NUM_ANT_SUBNRRW_PATTERN)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
instPtr->beamNo.next = beamNo;
|
||||
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].oaxis);
|
||||
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].oaxis) >> 8);
|
||||
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].raxis);
|
||||
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].raxis) >> 8);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Beam number assign not support.
|
||||
// Assign default angle (0,0)
|
||||
instPtr->beamNo.next = 0;
|
||||
instPtr->antCoinfoPtr.oaxis[1] = 0;
|
||||
instPtr->antCoinfoPtr.oaxis[0] = 0;
|
||||
instPtr->antCoinfoPtr.raxis[1] = 0;
|
||||
instPtr->antCoinfoPtr.raxis[0] = 0;
|
||||
DBG_WARNING("Using default beam number...");
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth)
|
||||
{
|
||||
uint8_t beamConfig = instPtr->antCoinfoPtr.antMode & (~ANT_MODE_BEAM_MASK);
|
||||
switch (beamWidth)
|
||||
{
|
||||
case ANT_BEAM_120:
|
||||
beamConfig |= ANT_MODE_WIDE_BEAM_3;
|
||||
break;
|
||||
case ANT_BEAM_60:
|
||||
beamConfig |= ANT_MODE_WIDE_BEAM_2;
|
||||
break;
|
||||
case ANT_BEAM_25:
|
||||
beamConfig |= ANT_MODE_WIDE_BEAM_1;
|
||||
break;
|
||||
case ANT_BEAM_8:
|
||||
beamConfig |= ANT_MODE_NARROR_BEAM;
|
||||
break;
|
||||
default:
|
||||
DBG_ERROR("Beam width code: 0x%08X is illegal.\n\r", beamWidth);
|
||||
return EPARAM;
|
||||
break;
|
||||
}
|
||||
instPtr->antCoinfoPtr.antMode = beamConfig;
|
||||
instPtr->beamWd.next = beamWidth;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Common version radius double input
|
||||
int32_t Phy_SetBeamAngle(PHY_INST *instPtr, double offAx, double rndAx)
|
||||
{
|
||||
uint16_t offAxDeg = 0;
|
||||
uint16_t rndAxDeg = 0;
|
||||
offAxDeg = (offAx > 0) ? (((int32_t)(offAx * 180 / ANT_PI)) % 360) : (((int32_t)(offAx * 180 / ANT_PI)) % 360 + 360);
|
||||
rndAxDeg = (rndAx > 0) ? (((int32_t)(rndAx * 180 / ANT_PI)) % 360) : (((int32_t)(rndAx * 180 / ANT_PI)) % 360 + 360);
|
||||
if (offAxDeg > 60)
|
||||
{
|
||||
DBG_ERROR("Angle out of range, off axis angle: %u(should be 0~60), round axis angle: %u(should be 0~360).",
|
||||
offAxDeg, rndAxDeg);
|
||||
return EPARAM;
|
||||
}
|
||||
offAxDeg = offAxDeg * 10;
|
||||
rndAxDeg = rndAxDeg * 10;
|
||||
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)offAxDeg;
|
||||
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)(offAxDeg >> 8);
|
||||
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)rndAxDeg;
|
||||
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)(rndAxDeg >> 8);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,813 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Implementation of physical control functions
|
||||
*
|
||||
* Date: 2021-11-16 00:08
|
||||
* LastEditTime: 2023-04-23 17:48
|
||||
* Revisions: Rev 0.2
|
||||
* 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.
|
||||
* -Add 61/37 beam switch
|
||||
* -Code simplification.
|
||||
* [2023-04-24]: Feature add:
|
||||
* - Read frame type from PL status register.
|
||||
*
|
||||
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "phy_ctrl.h"
|
||||
#include "../util/util.h"
|
||||
#include "../error.h"
|
||||
#ifndef EMULATION
|
||||
#include "xbram.h"
|
||||
#endif
|
||||
/************************** Constant Definitions *****************************/
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
/************************** Function Prototypes ******************************/
|
||||
static void Phy_RcdShift(PHY_RCD* rcd, int32_t netxVal);
|
||||
static int32_t Phy_SetSendData(PHY_INST* instPtr, L1_FRAME_TYPE frameType, uint8_t* dataBuff);
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Setup data will be sent in next slot.
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return FAILURE Error occurred.
|
||||
* SUCCESS Setting data successful.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int32_t Phy_SetSendData(PHY_INST* instPtr, L1_FRAME_TYPE frameType, uint8_t* dataBuff) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(dataBuff != NULL);
|
||||
uint32_t frameLen, sendCmd;
|
||||
|
||||
frameLen = Phy_GetFrameLen(frameType);
|
||||
|
||||
if (frameLen == L1_FRAME_NONE_LEN) {
|
||||
DBG_ERROR("Invalid frame length.\n");
|
||||
return EPARAM;
|
||||
}
|
||||
instPtr->sendDataOffset = (TXRXDATA_MAX_LEN >> 1) - instPtr->sendDataOffset;
|
||||
memcpy((uint8_t*)(instPtr->sendDataAddr + instPtr->sendDataOffset), dataBuff, frameLen);
|
||||
|
||||
sendCmd = frameLen & SEND_DATA_CMD_LEN_MASK;
|
||||
sendCmd |= (instPtr->sendDataOffset << SEND_DATA_CMD_OFFSET_SHIFT) & SEND_DATA_CMD_OFFSET_MASK;
|
||||
|
||||
// Physical layer start fetching data.
|
||||
PhyWrite(instPtr, SEND_DATA_CMD, sendCmd);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Check whether a frame was detected. (Do not check if the frame was
|
||||
* deoced.)
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return true
|
||||
* false
|
||||
*
|
||||
******************************************************************************/
|
||||
inline bool Phy_IsFrameDetected(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
if(instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq && instPtr->isFrameSync) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Check whether a frame was received. (Do not check if the frame was
|
||||
* crashed.)
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return true
|
||||
* false
|
||||
*
|
||||
******************************************************************************/
|
||||
inline bool Phy_IsFrameReceived(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
if(instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq
|
||||
&& instPtr->isFrameSync && instPtr->isDecode) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Check whether a frame was valid. (if the frame was crashed, it will
|
||||
* be regarded as not valid.
|
||||
*
|
||||
* @param instPtr
|
||||
*
|
||||
* @return true
|
||||
* false
|
||||
*
|
||||
******************************************************************************/
|
||||
inline bool Phy_IsFrameValid(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
if (instPtr->TOR.last == PHY_TOR_RX && instPtr->isAcq && instPtr->isFrameSync
|
||||
&& instPtr->isDecode && instPtr->isValid) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get frame type of the frame in receive data buffer (Base on PL Record).
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return Layer2 frame type. Refer "frame_def.h"
|
||||
*
|
||||
******************************************************************************/
|
||||
inline L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST *instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
if (Phy_IsFrameReceived(instPtr) == false) {
|
||||
return L1_NONE_FRAME;
|
||||
}
|
||||
int32_t frame_type = (PhyRead(instPtr, PHY_MODE_CTRL) & PHY_MODE_CTRL_FRAME_MASK)
|
||||
>> PHY_MODE_CTRL_FRAME_SHIFT;
|
||||
if(frame_type < L1_1M2BPS_5MS_FRAME)
|
||||
return frame_type;
|
||||
else
|
||||
return L1_NONE_FRAME;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get frame type of the frame was sent in last slot.
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return Layer2 frame type. Refer "frame_def.h"
|
||||
*
|
||||
******************************************************************************/
|
||||
inline L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
if (instPtr->TOR.last != PHY_TOR_TX) {
|
||||
return L1_NONE_FRAME;
|
||||
}
|
||||
return instPtr->frameType.last;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Shift l1 status record.(newval->next->curr->last)
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return NONE.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void Phy_RcdShift(PHY_RCD* rcd, int32_t netxVal){
|
||||
ASSERT(rcd != NULL);
|
||||
rcd->last = rcd->curr;
|
||||
rcd->curr = rcd->next;
|
||||
rcd->next = netxVal;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get corresponding frame length in byte of L1 frame.
|
||||
*
|
||||
* @param frameType
|
||||
*
|
||||
* @return Corresponding frame length
|
||||
* L1_FRAME_NONE_LEN if the frame type code cannot be recognized.
|
||||
*
|
||||
******************************************************************************/
|
||||
uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType) {
|
||||
switch (frameType) {
|
||||
case L1_2KBPS_20MS_FRAME:
|
||||
return L1_FRAME_2KBPS_20MS_LEN;
|
||||
case L1_2KBPS_100MS_FRAME:
|
||||
return L1_FRAME_2KBPS_100MS_LEN;
|
||||
case L1_10KBPS_10MS_FRAME:
|
||||
return L1_FRAME_10KBPS_10MS_LEN;
|
||||
case L1_10KBPS_20MS_FRAME:
|
||||
return L1_FRAME_10KBPS_20MS_LEN;
|
||||
case L1_40KBPS_20MS_FRAME:
|
||||
return L1_FRAME_40KBPS_20MS_LEN;
|
||||
case L1_40KBPS_10MS_FRAME:
|
||||
return L1_FRAME_40KBPS_10MS_LEN;
|
||||
case L1_200KBPS_5MS_FRAME:
|
||||
return L1_FRAME_200KBPS_5MS_LEN;
|
||||
case L1_1M2BPS_5MS_FRAME:
|
||||
return L1_FRAME_1M2BPS_5MS_LEN;
|
||||
default:
|
||||
return L1_FRAME_NONE_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Update physical layer status cache.
|
||||
*
|
||||
* @param instPtr A pointer to physical layer control instance.
|
||||
*
|
||||
* @return NONE.
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_UpdateState(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
|
||||
Phy_RcdShift(&(instPtr->TOR),PHY_TOR_SUSPEND);
|
||||
Phy_RcdShift(&(instPtr->frameType),L1_NONE_FRAME);
|
||||
Phy_RcdShift(&(instPtr->antNo), INIT_ANT_NO);
|
||||
Phy_RcdShift(&(instPtr->beamNo), INIT_BEAM_NO);
|
||||
Phy_RcdShift(&(instPtr->beamWd), INIT_ANT_WD);
|
||||
/* Update Frame Sate. */
|
||||
uint32_t txrxSate = PhyRead(instPtr, TXRX_STATE);
|
||||
instPtr->isAcq = ((txrxSate & TXRX_STATE_ACQ_MASK) == TXRX_STATE_ACQ_SUCCESS) ? true : false;
|
||||
instPtr->isFrameSync = ((txrxSate & TXRX_STATE_FSYNC_MASK) == TXRX_STATE_FSYNC_SUCCESS) ? true : false;
|
||||
instPtr->isDecode = ((txrxSate & TXRX_STATE_DECODE_MASK) == TXRX_STATE_DECODE_SUCCESS) ? true : false;
|
||||
if (Phy_IsFrameReceived(instPtr)) {
|
||||
instPtr->isValid = ((txrxSate & TXRX_STATE_CRC_MASK) == TXRX_STATE_CRC_OK) ? true : false;
|
||||
}
|
||||
else {
|
||||
instPtr->isValid = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Initialize physical layer instance accordingly.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
* @param phyConfig a pointer to cinfiguration staructure.
|
||||
*
|
||||
* @return SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_InstInit(PHY_INST** instPtr, PHY_CONFIG *phyConfig) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(phyConfig != NULL);
|
||||
int32_t Status;
|
||||
|
||||
*instPtr = (PHY_INST*) malloc(sizeof(PHY_INST));
|
||||
if ((*instPtr) == NULL) {
|
||||
return EALLOC;
|
||||
}
|
||||
memcpy(&(*instPtr)->phyCofig, phyConfig, sizeof(PHY_CONFIG));
|
||||
|
||||
(*instPtr)->isPhyEn = false;
|
||||
(*instPtr)->isAcq = false;
|
||||
(*instPtr)->isFrameSync = false;
|
||||
(*instPtr)->isDecode = false;
|
||||
(*instPtr)->isValid = false;
|
||||
(*instPtr)->isPresetHop = false;
|
||||
(*instPtr)->antConfigOffset = 0;
|
||||
(*instPtr)->sendDataOffset = 0;
|
||||
Phy_AntCoinfoInit(&((*instPtr)->antCoinfoPtr));
|
||||
|
||||
memset(&((*instPtr))->TOR, PHY_TOR_SUSPEND, sizeof(PHY_RCD));
|
||||
memset(&((*instPtr)->frameType), L1_NONE_FRAME, sizeof(PHY_RCD));
|
||||
memset(&((*instPtr)->antNo), (int32_t)INIT_BEAM_NO, sizeof(PHY_RCD));
|
||||
memset(&((*instPtr)->beamNo), (int32_t)INIT_ANT_NO, sizeof(PHY_RCD));
|
||||
memset(&((*instPtr)->beamWd), (int32_t)INIT_ANT_WD, sizeof(PHY_RCD));
|
||||
|
||||
#ifndef EMULATION
|
||||
XBram antInfoBram;
|
||||
XBram txFrameBram;
|
||||
XBram rxFrameBram;
|
||||
|
||||
XBram_Config *ConfigPtr;
|
||||
ConfigPtr = XBram_LookupConfig(phyConfig->antBramId);
|
||||
if (ConfigPtr == NULL) {
|
||||
Status = EDINVAL;
|
||||
goto error;
|
||||
}
|
||||
Status = XBram_CfgInitialize(&antInfoBram, ConfigPtr,
|
||||
ConfigPtr->CtrlBaseAddress);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* Execute the BRAM driver selftest.
|
||||
*/
|
||||
Status = XBram_SelfTest(&antInfoBram, 0);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ConfigPtr = XBram_LookupConfig(phyConfig->txBramId);
|
||||
if (ConfigPtr == NULL) {
|
||||
Status = EDINVAL;
|
||||
goto error;
|
||||
}
|
||||
Status = XBram_CfgInitialize(&txFrameBram, ConfigPtr,
|
||||
ConfigPtr->CtrlBaseAddress);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* Execute the BRAM driver selftest.
|
||||
*/
|
||||
Status = XBram_SelfTest(&txFrameBram, 0);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ConfigPtr = XBram_LookupConfig(phyConfig->rxBramId);
|
||||
if (ConfigPtr == NULL) {
|
||||
Status = EDINVAL;
|
||||
goto error;
|
||||
}
|
||||
Status = XBram_CfgInitialize(&rxFrameBram, ConfigPtr,
|
||||
ConfigPtr->CtrlBaseAddress);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* Execute the BRAM driver selftest.
|
||||
*/
|
||||
Status = XBram_SelfTest(&rxFrameBram, 0);
|
||||
if (Status != SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
(*instPtr)->antConfigAddr = antInfoBram.Config.MemBaseAddress;
|
||||
(*instPtr)->recvDataAddr = rxFrameBram.Config.MemBaseAddress;
|
||||
(*instPtr)->sendDataAddr = txFrameBram.Config.MemBaseAddress;
|
||||
#else
|
||||
(*instPtr)->antConfigAddr = (uintptr_t)calloc(ANTCONFIG_MAX_LEN/sizeof(uint64_t), sizeof(uint64_t));
|
||||
if ((*instPtr)->antConfigAddr == (uintptr_t)NULL) {
|
||||
Status = EALLOC;
|
||||
goto error;
|
||||
}
|
||||
(*instPtr)->recvDataAddr = (uintptr_t)calloc(TXRXDATA_MAX_LEN/sizeof(uint64_t), sizeof(uint64_t));
|
||||
if ((*instPtr)->recvDataAddr == (uintptr_t)NULL) {
|
||||
Status = EALLOC;
|
||||
goto error;
|
||||
}
|
||||
(*instPtr)->sendDataAddr = (uintptr_t)calloc(TXRXDATA_MAX_LEN/sizeof(uint64_t), sizeof(uint64_t));
|
||||
if ((*instPtr)->sendDataAddr == (uintptr_t)NULL) {
|
||||
Status = EALLOC;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
return SUCCESS;
|
||||
error:
|
||||
Phy_Destroy(*instPtr);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Destroy physical layer inctance, free allocated memory.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_Destroy(PHY_INST* instPtr) {
|
||||
if (instPtr == NULL){
|
||||
return;
|
||||
}
|
||||
#ifdef EMULATION
|
||||
free((void*)instPtr->antConfigAddr);
|
||||
free((void*)instPtr->recvDataAddr);
|
||||
free((void*)instPtr->sendDataAddr);
|
||||
#endif
|
||||
free(instPtr);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Start physical layer
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_Start(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL);
|
||||
if((phyMainCtrl & PHY_MAIN_CTRL_EN_MASK) == PHY_MAIN_CTRL_EN_EN) {
|
||||
DBG_WARNING("Physical layer was allready enabled.\n");
|
||||
}
|
||||
instPtr->isPhyEn = true;
|
||||
// Enable CRC check automatically
|
||||
PhyWrite(instPtr, PHY_MAIN_CTRL, (phyMainCtrl | PHY_MAIN_CTRL_EN_EN));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Halt physical layer operation
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_Halt(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL);
|
||||
if((phyMainCtrl & PHY_MAIN_CTRL_EN_MASK) == PHY_MAIN_CTRL_EN_DSBL) {
|
||||
DBG_WARNING("Physical layer was allready halted.\n");
|
||||
}
|
||||
instPtr->isPhyEn = false;
|
||||
PhyWrite(instPtr, PHY_MAIN_CTRL, (phyMainCtrl & (~PHY_MAIN_CTRL_EN_MASK)));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Set physical layer working mode.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
* @param modeCod intened mode code
|
||||
*
|
||||
* @return SUCCESS
|
||||
* other
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_SetMode(PHY_INST* instPtr, PHY_MODE modeCod) {
|
||||
ASSERT(instPtr != NULL);
|
||||
|
||||
uint32_t phyMainCtrl = PhyRead(instPtr, PHY_MAIN_CTRL) & ~PHY_MAIN_CTRL_MODE_MASK;
|
||||
switch (modeCod) {
|
||||
case PHY_MODE_NONE:
|
||||
phyMainCtrl |= PHY_MAIN_CTRL_MODE_NONE;
|
||||
break;
|
||||
case PHY_MODE_LISTEN:
|
||||
phyMainCtrl |= PHY_MAIN_CTRL_MODE_LISTEN;
|
||||
break;
|
||||
case PHY_MODE_SCHEDULE:
|
||||
phyMainCtrl |= PHY_MAIN_CTRL_MODE_SCHEDULE;
|
||||
break;
|
||||
case PHY_MODE_PULL:
|
||||
phyMainCtrl |= PHY_MAIN_CTRL_MODE_PULL;
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
break;
|
||||
}
|
||||
PhyWrite(instPtr, PHY_MAIN_CTRL, phyMainCtrl);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Setup next slot operation.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
* @param txrxMode tor type of next slot
|
||||
* @param frameType frame type of next slot
|
||||
*
|
||||
* @return SUCCESS
|
||||
* other
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_SetupNextSlot(PHY_INST* instPtr, PHY_TOR_TYPE txrxMode,
|
||||
L1_FRAME_TYPE frameType, uint8_t* dataBuff) {
|
||||
ASSERT(instPtr != NULL);
|
||||
int32_t Status;
|
||||
uint32_t phyModeCtrl, hopNum;
|
||||
uint16_t* hopPattern = NULL;
|
||||
// Implement a ping-pong flow, offset always is 0 or half of buffer depth.
|
||||
instPtr->antConfigOffset = (ANTCONFIG_MAX_LEN >> 1) - instPtr->antConfigOffset;
|
||||
uint32_t antConfigAddr = instPtr->antConfigAddr + instPtr->antConfigOffset;
|
||||
|
||||
instPtr->TOR.next = txrxMode;
|
||||
instPtr->frameType.next = frameType;
|
||||
|
||||
switch (txrxMode) {
|
||||
case PHY_TOR_SUSPEND:
|
||||
phyModeCtrl = PHY_MODE_CTRL_TOR_SUSPEND;
|
||||
break;
|
||||
case PHY_TOR_RX:
|
||||
phyModeCtrl = PHY_MODE_CTRL_TOR_RX;
|
||||
break;
|
||||
case PHY_TOR_TX:
|
||||
phyModeCtrl = PHY_MODE_CTRL_TOR_TX;
|
||||
break;
|
||||
default:
|
||||
return EPARAM;
|
||||
}
|
||||
switch (frameType) {
|
||||
case L1_2KBPS_20MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_20MS;
|
||||
hopNum = L1_FRAME_2KBPS_20MS_HOPS;
|
||||
hopPattern = hopPattern_10KBPS_10MS;
|
||||
break;
|
||||
case L1_2KBPS_100MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_2KBPS_100MS;
|
||||
hopNum = L1_FRAME_2KBPS_100MS_HOPS;
|
||||
hopPattern = hopPattern_2KBPS_100MS;
|
||||
break;
|
||||
case L1_10KBPS_10MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_10MS;
|
||||
hopNum = L1_FRAME_10KBPS_10MS_HOPS;
|
||||
hopPattern = hopPattern_10KBPS_10MS;
|
||||
break;
|
||||
case L1_10KBPS_20MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_10KBPS_20MS;
|
||||
hopNum = L1_FRAME_10KBPS_20MS_HOPS;
|
||||
hopPattern = hopPattern_10KBPS_20MS;
|
||||
break;
|
||||
case L1_40KBPS_20MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS;
|
||||
hopNum = L1_FRAME_200KBPS_5MS_HOPS;
|
||||
hopPattern = hopPattern_200KBPS_5MS;
|
||||
break;
|
||||
case L1_40KBPS_10MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_40KBPS_10MS;
|
||||
hopNum = L1_FRAME_40KBPS_10MS_HOPS;
|
||||
hopPattern = hopPattern_40KBPS_10MS;
|
||||
break;
|
||||
case L1_200KBPS_5MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_200KBPS_5MS;
|
||||
hopNum = L1_FRAME_200KBPS_5MS_HOPS;
|
||||
hopPattern = hopPattern_200KBPS_5MS;
|
||||
break;
|
||||
case L1_1M2BPS_5MS_FRAME:
|
||||
phyModeCtrl |= PHY_MODE_CTRL_FRAME_1M2BPS_5MS;
|
||||
hopNum = L1_FRAME_1M2BPS_5MS_HOPS;
|
||||
hopPattern = hopPattern_1M2BPS_5MS;
|
||||
break;
|
||||
default:
|
||||
return EPARAM;
|
||||
break;
|
||||
}
|
||||
hopPattern = (instPtr->isPresetHop) ? hopPattern : hopPattern_Config;
|
||||
|
||||
uint8_t* dataSrcPtr = (uint8_t*)(&(instPtr->antCoinfoPtr));
|
||||
for (int32_t i = 0; i < hopNum; i++) {
|
||||
instPtr->antCoinfoPtr.antFreq[1] = (uint8_t)(hopPattern[i] & 0x00FF);
|
||||
instPtr->antCoinfoPtr.antFreq[0] = (uint8_t)(
|
||||
(hopPattern[i] >> 8) & 0x00FF);
|
||||
memcpy((uint8_t*) (antConfigAddr + i * sizeof(PHY_ANT_CONFIG)),
|
||||
dataSrcPtr, sizeof(PHY_ANT_CONFIG));
|
||||
}
|
||||
uint32_t antCtrl = (instPtr->antConfigOffset & ANT_CONFIG_OFFSET_MASK)
|
||||
| ((hopNum << ANT_CONFIG_NUM_SHIFT) & ANT_CONFIG_NUM_MASK)
|
||||
| ((sizeof(PHY_ANT_CONFIG) << ANT_CONFIG_LEN_SHIFT) & ANT_CONFIG_LEN_MASK);
|
||||
|
||||
/*
|
||||
memcpy((uint8_t*)antConfigDataAddr, hopPattern, hopNum*sizeof(uint16_t));
|
||||
uint32_t antCtrl = (instPtr->antCoinfigOffset & ANT_CONFIG_OFFSET_MASK)
|
||||
| ((hopNum << ANT_CONFIG_NUM_SHIFT) & ANT_CONFIG_NUM_MASK)
|
||||
| ((sizeof(uint16_t) << ANT_CONFIG_LEN_SHIFT) & ANT_CONFIG_LEN_MASK);
|
||||
*/
|
||||
PhyWrite(instPtr, PHY_MODE_CTRL, phyModeCtrl|PHY_MODE_CTRL_CRC_EN);
|
||||
PhyWrite(instPtr, ANT_CONFIG, antCtrl);
|
||||
|
||||
|
||||
// Trigger physical configuration.
|
||||
if(txrxMode == PHY_TOR_TX) {
|
||||
Status = Phy_SetSendData(instPtr, frameType, dataBuff);
|
||||
if(Status != SUCCESS) {
|
||||
DBG_ERROR("Failed to apply send data.\n");
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
PhyWrite(instPtr, SLOT_CMD, SLOT_CMD_KEY); // Phy statr fetching data.
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get coarse frequency estimation of last valid frame.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
*
|
||||
* @return SUCCESS If load the data successfully.
|
||||
* FAILURE If last receive frame is not valid.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
double Phy_GetCoarseFreqEst(PHY_INST* instPtr) {
|
||||
ASSERT(instPtr != NULL);
|
||||
uint32_t regValue;
|
||||
uint8_t acqFreqIdx;
|
||||
int8_t syncFreqIdx;
|
||||
L1_FRAME_TYPE frameType;
|
||||
double freqEst;
|
||||
|
||||
frameType = Phy_GetLastRecvFrameType(instPtr);
|
||||
if(frameType > L1_1M2BPS_5MS_FRAME || frameType == L1_NONE_FRAME){
|
||||
return INFINITY; // FIXME
|
||||
}
|
||||
regValue = PhyRead(instPtr, COASE_FREQEST);
|
||||
acqFreqIdx = (regValue >> COASE_FREQEST_ACQ_SHIFT) && COASE_FREQEST_ACQ_MASK;
|
||||
acqFreqIdx = 80 - acqFreqIdx;
|
||||
syncFreqIdx = (regValue >> COASE_FREQEST_SYNC_SHIFT) && COASE_FREQEST_SYNC_MASK;
|
||||
syncFreqIdx = 8 - syncFreqIdx;
|
||||
if(frameType >= L1_200KBPS_5MS_FRAME) {
|
||||
freqEst = (double)acqFreqIdx*(250e3/4);
|
||||
freqEst += (double)syncFreqIdx*1.5e6/64/128;
|
||||
}
|
||||
else {
|
||||
freqEst = acqFreqIdx*(250e3/4);
|
||||
freqEst += (double)syncFreqIdx*12e6/64/128;
|
||||
}
|
||||
|
||||
return freqEst;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get the corresponding frequency hopping pattern length of a
|
||||
* specified L1 frame type.
|
||||
*
|
||||
* @param frameType a L1 frame type enumeration.
|
||||
*
|
||||
* @return SUCCESS
|
||||
* FAILURE frame type cannot be recognized
|
||||
*
|
||||
******************************************************************************/
|
||||
uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType){
|
||||
switch (frameType) {
|
||||
case L1_2KBPS_20MS_FRAME:
|
||||
return L1_FRAME_2KBPS_20MS_HOPS;
|
||||
case L1_2KBPS_100MS_FRAME:
|
||||
return L1_FRAME_2KBPS_100MS_HOPS;
|
||||
case L1_10KBPS_10MS_FRAME:
|
||||
return L1_FRAME_10KBPS_10MS_HOPS;
|
||||
case L1_10KBPS_20MS_FRAME:
|
||||
return L1_FRAME_10KBPS_20MS_HOPS;
|
||||
case L1_40KBPS_20MS_FRAME:
|
||||
return L1_FRAME_40KBPS_20MS_HOPS;
|
||||
case L1_40KBPS_10MS_FRAME:
|
||||
return L1_FRAME_40KBPS_10MS_HOPS;
|
||||
case L1_200KBPS_5MS_FRAME:
|
||||
return L1_FRAME_200KBPS_5MS_HOPS;
|
||||
case L1_1M2BPS_5MS_FRAME:
|
||||
return L1_FRAME_1M2BPS_5MS_HOPS;
|
||||
default:
|
||||
return L1_FRAME_NONE_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get the corresponding time compensation value (time interval from
|
||||
* frame start to frame sync)
|
||||
*
|
||||
* @param frameType a L1 frame type enumeration.
|
||||
*
|
||||
* @return SUCCESS
|
||||
* FAILURE frame type cannot be recognized
|
||||
*
|
||||
******************************************************************************/
|
||||
uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType){
|
||||
switch (frameType) {
|
||||
case L1_2KBPS_20MS_FRAME:
|
||||
return L1_FRAME_2KBPS_20MS_COMP;
|
||||
case L1_2KBPS_100MS_FRAME:
|
||||
return L1_FRAME_2KBPS_100MS_COMP;
|
||||
case L1_10KBPS_10MS_FRAME:
|
||||
return L1_FRAME_10KBPS_10MS_COMP;
|
||||
case L1_10KBPS_20MS_FRAME:
|
||||
return L1_FRAME_10KBPS_20MS_COMP;
|
||||
case L1_40KBPS_20MS_FRAME:
|
||||
return L1_FRAME_40KBPS_20MS_COMP;
|
||||
case L1_40KBPS_10MS_FRAME:
|
||||
return L1_FRAME_40KBPS_10MS_COMP;
|
||||
case L1_200KBPS_5MS_FRAME:
|
||||
return L1_FRAME_200KBPS_5MS_COMP;
|
||||
case L1_1M2BPS_5MS_FRAME:
|
||||
return L1_FRAME_1M2BPS_5MS_COMP;
|
||||
default:
|
||||
return L1_FRAME_NONE_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Setup a frequency hopping pattern.
|
||||
*
|
||||
* @param patternBuff a pointer to hopping pattern buffer
|
||||
* @param patternLen a integer indicate the length of hopping pattern.
|
||||
*
|
||||
* @return SUCCESS
|
||||
* FAILURE pattern length exceeds maximum length.
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_SetHopPattern(void* patternBuff, uint32_t patternLen){
|
||||
ASSERT(patternBuff != NULL);
|
||||
if(patternLen > L1_FRAME_MAX_HOPS){
|
||||
return FAILURE;
|
||||
}
|
||||
memcpy(hopPattern_Config, patternBuff, patternLen*sizeof(uint16_t));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Setup a specific timer word register in physical controller.
|
||||
*
|
||||
* @param patternBuff a pointer to hopping pattern buffer
|
||||
* @param patternLen a integer indicate the length of hopping pattern.
|
||||
*
|
||||
* @return SUCCESS
|
||||
* FAILURE pattern length exceeds maximum length.
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t Phy_SetTimeWord(PHY_INST* instPtr, const TIME_WORD* tmWord, PHY_TIME_WORD_TYPE tmType){
|
||||
ASSERT(instPtr != NULL);
|
||||
if(tmWord->frac_part>=PHY_TIME_WORD_L_MAX){
|
||||
return EPARAM;
|
||||
}
|
||||
switch(tmType){
|
||||
case TIME_WORD_POLL:
|
||||
PhyWrite(instPtr, POLLTIME_L, tmWord->frac_part);
|
||||
PhyWrite(instPtr, POLLTIME_H, tmWord->int_part);
|
||||
break;
|
||||
case TIME_WORD_LISTEN_TIMEOUT:
|
||||
PhyWrite(instPtr, LISTENTIMEOUT_L, tmWord->frac_part);
|
||||
PhyWrite(instPtr, LISTENTIMEOUT_H, tmWord->int_part);
|
||||
break;
|
||||
default:
|
||||
return EPARAM;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get the frame sync time of last received frame.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
* @param frameSycT a pointer to the frame sync time data buffer.
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_GetFrameSyncTimeStamp(PHY_INST* instPtr, TIME_WORD* frameSyncT) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(frameSyncT != NULL);
|
||||
frameSyncT->int_part = PhyRead(instPtr, TM_TARGET_H);
|
||||
frameSyncT->frac_part = PhyRead(instPtr, TM_TARGET_L);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get the frame sync time of last received frame.
|
||||
*
|
||||
* @param instPtr a pointer to physical instance
|
||||
* @param slotStart a pointer to the time data buffer.
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_GetLastSlotStartTimeStamp(PHY_INST* instPtr, TIME_WORD* slotStart) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(slotStart != NULL);
|
||||
slotStart->int_part = PhyRead(instPtr, FSTIME_H);
|
||||
slotStart->frac_part = PhyRead(instPtr, FSTIME_L);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get received data (base on PL Record), store it to data buffer.
|
||||
*
|
||||
* @param instPtr a pointer to physical layer control instance.
|
||||
*
|
||||
* @return SUCCESS
|
||||
* FAILURE last frame type cannot be recognized.
|
||||
*
|
||||
******************************************************************************/
|
||||
void Phy_RetrieveRecvData(PHY_INST* instPtr, uint8_t* dataBuff) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(dataBuff != NULL);
|
||||
uint32_t frameLen, offset;
|
||||
|
||||
frameLen = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_LEN_MASK) >> RECVDATA_STATE_LEN_SHIFT;
|
||||
offset = (PhyRead(instPtr, RECVDATA_STATE) & RECVDATA_STATE_OFFSET_MASK) >> RECVDATA_STATE_OFFSET_SHIFT;
|
||||
|
||||
memcpy(dataBuff, (uint8_t*)(instPtr->recvDataAddr + offset), frameLen);
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Physical layer control definitions and function prototypes.
|
||||
*
|
||||
* Date: 2021-12-04 16:32
|
||||
* LastEditTime: 2023-04-24 17:41
|
||||
* 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.
|
||||
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PHY_CTRL_H_
|
||||
#define PHY_CTRL_H_
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <stdint.h>
|
||||
#include "phy_ctrlreg.h"
|
||||
#include "../common.h"
|
||||
#include "../time_ctrl/time_ctrl.h"
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define TMWORD_FRAC_MAX 500000
|
||||
#define ANTCONFIG_MAX_LEN 8192
|
||||
#define TXRXDATA_MAX_LEN 2048
|
||||
#define NUM_ANT_SUBNRRW_PATTERN 37
|
||||
#define NUM_ANT_NRRW_PATTERN 61
|
||||
#define INIT_BEAM_NO 0
|
||||
#define INIT_ANT_WD ANT_BEAM_120
|
||||
#define INIT_ANT_NO 0
|
||||
|
||||
#define L1_FRAME_NONE_HOPS UINT32_MAX
|
||||
#define L1_FRAME_MAX_HOPS 81
|
||||
#define L1_FRAME_2KBPS_20MS_HOPS 1
|
||||
#define L1_FRAME_2KBPS_100MS_HOPS 81
|
||||
#define L1_FRAME_10KBPS_10MS_HOPS 1
|
||||
#define L1_FRAME_10KBPS_20MS_HOPS 11
|
||||
#define L1_FRAME_40KBPS_20MS_HOPS 19
|
||||
#define L1_FRAME_40KBPS_10MS_HOPS 9
|
||||
#define L1_FRAME_200KBPS_5MS_HOPS 20
|
||||
#define L1_FRAME_1M2BPS_5MS_HOPS 20
|
||||
|
||||
#define L1_FRAME_NONE_LEN UINT32_MAX// byte
|
||||
#define L1_FRAME_LEN_MAX (8192/8) // byte
|
||||
#define L1_FRAME_2KBPS_20MS_LEN 1 // byte
|
||||
#define L1_FRAME_2KBPS_100MS_LEN 312/8 // byte
|
||||
#define L1_FRAME_10KBPS_10MS_LEN 1 // byte
|
||||
#define L1_FRAME_10KBPS_20MS_LEN (232/8) // byte
|
||||
#define L1_FRAME_40KBPS_20MS_LEN (2152/8) // byte
|
||||
#define L1_FRAME_40KBPS_10MS_LEN (712/8) // byte
|
||||
#define L1_FRAME_200KBPS_5MS_LEN (2040/8) // byte
|
||||
#define L1_FRAME_1M2BPS_5MS_LEN (8176/8) // byte
|
||||
|
||||
#define L1_FRAME_NONE_COMP UINT32_MAX // *10ns(Timer_L)
|
||||
#define L1_FRAME_2KBPS_20MS_COMP 1841158 // *10ns(Timer_L)
|
||||
#define L1_FRAME_2KBPS_100MS_COMP 1841158 // *10ns(Timer_L)
|
||||
#define L1_FRAME_10KBPS_10MS_COMP 847733 // *10ns(Timer_L)
|
||||
#define L1_FRAME_10KBPS_20MS_COMP 847733 // *10ns(Timer_L)
|
||||
#define L1_FRAME_40KBPS_20MS_COMP 110667 // *10ns(Timer_L)
|
||||
#define L1_FRAME_40KBPS_10MS_COMP 110667 // *10ns(Timer_L)
|
||||
#define L1_FRAME_200KBPS_5MS_COMP 19725 // *10ns(Timer_L)
|
||||
#define L1_FRAME_1M2BPS_5MS_COMP 19725 // *10ns(Timer_L)
|
||||
|
||||
|
||||
#define PHY_TIME_WORD_H_MAX UINT32_MAX
|
||||
#define PHY_TIME_WORD_L_MAX 0x0007A120 // 5ms/10ns
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
typedef enum {
|
||||
L1_NONE_FRAME = 0,
|
||||
L1_2KBPS_20MS_FRAME = 1,
|
||||
L1_2KBPS_100MS_FRAME = 2,
|
||||
L1_10KBPS_10MS_FRAME = 3,
|
||||
L1_10KBPS_20MS_FRAME = 4,
|
||||
L1_40KBPS_20MS_FRAME = 5,
|
||||
L1_40KBPS_10MS_FRAME = 6,
|
||||
L1_200KBPS_5MS_FRAME = 7,
|
||||
L1_1M2BPS_5MS_FRAME = 8
|
||||
} L1_FRAME_TYPE;
|
||||
|
||||
typedef struct {
|
||||
/* Antenna control frame head 0xAA */
|
||||
uint8_t head;
|
||||
/* default 0, reserved for further use */
|
||||
uint8_t ctrlWord;
|
||||
/* high 4 bits specified beam mode.
|
||||
* low 4 bits specified power control */
|
||||
uint8_t antMode;
|
||||
/* off-axis angle range is 0~60,
|
||||
* 0.1 degree each LSB */
|
||||
uint8_t oaxis[2];
|
||||
/* round-axis angle range is 0~360,
|
||||
* 0.1 degree each LSB */
|
||||
uint8_t raxis[2];
|
||||
/* 0~3500Mhz, step 1MHz */
|
||||
uint8_t antFreq[2];
|
||||
/* in single tr mode, 0~63 specified tr channel
|
||||
* in single subarray mode, 0~3 specified the subarray
|
||||
* Only in debug mode*/
|
||||
uint8_t trSlect;
|
||||
/* 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;
|
||||
/* 0x00 Nromal RX, 0x01 Normal TX
|
||||
* 0x11~0xA1 beam debug mode (TR duty 1%~10%)*/
|
||||
uint8_t rxtxMode;
|
||||
/* 0x00 Normal, 0x01 single tr calibration */
|
||||
uint8_t calibrMode;
|
||||
/* reserved for further use */
|
||||
uint8_t reserved;
|
||||
/* DD enable */
|
||||
uint8_t ddEn;
|
||||
/* DD mgc */
|
||||
uint8_t ddMgc;
|
||||
/* [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default) */
|
||||
uint8_t rfCtrl;
|
||||
/* RF MGC control: 0~31, 1dB each LSB*/
|
||||
uint8_t rfMgc;
|
||||
/* RF channel 1&2 calibration mgc: [7:4] Channle1 - max 15db, 1dB each LSB
|
||||
* [3:0] Channle2 - max 15db, 1dB each LSB*/
|
||||
uint8_t rf12CalMgc;
|
||||
/* RF channel 3&4 calibration mgc: [7:4] Channle3 - max 15db, 1dB each LSB
|
||||
* [3:0] Channle4 - max 15db, 1dB each LSB*/
|
||||
uint8_t rf34CalMgc;
|
||||
/* Receive channel 1 MGC: 0~31, 1dB each LSB */
|
||||
uint8_t rcv1Mgc;
|
||||
/* Receive channel 2 MGC: 0~31, 1dB each LSB */
|
||||
uint8_t rcv2Mgc;
|
||||
/* Receive channel 3 MGC: 0~31, 1dB each LSB */
|
||||
uint8_t rcv3Mgc;
|
||||
/* Receive channel 4 MGC: 0~31, 1dB each LSB */
|
||||
uint8_t rcv4Mgc;
|
||||
/* Antenna control frame tail 0xCC */
|
||||
uint8_t tail;
|
||||
uint8_t dummy[6];
|
||||
} PHY_ANT_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
/* off-axis angle range is 0~60,
|
||||
* 0.1 degree each LSB */
|
||||
uint16_t oaxis;
|
||||
/* round-axis angle range is 0~360,
|
||||
* 0.1 degree each LSB */
|
||||
uint16_t raxis;
|
||||
} PHY_ANT_ANGLE;
|
||||
|
||||
typedef enum {
|
||||
TIME_WORD_NONE = 0,
|
||||
TIME_WORD_POLL = 1,
|
||||
TIME_WORD_LISTEN_TIMEOUT = 2
|
||||
} PHY_TIME_WORD_TYPE;
|
||||
|
||||
typedef enum {
|
||||
ANT_BEAM_NONE = 0,
|
||||
ANT_BEAM_120 = 1,
|
||||
ANT_BEAM_60 = 2,
|
||||
ANT_BEAM_25 = 3,
|
||||
ANT_BEAM_8 = 4
|
||||
} PHY_ANT_BEAM_WIDTH;
|
||||
|
||||
typedef enum {
|
||||
PHY_TOR_SUSPEND = 0,
|
||||
PHY_TOR_TX = 1,
|
||||
PHY_TOR_RX = 2
|
||||
} PHY_TOR_TYPE;
|
||||
|
||||
typedef enum {
|
||||
PHY_MODE_NONE = 0,
|
||||
PHY_MODE_LISTEN = 1,
|
||||
PHY_MODE_SCHEDULE = 2,
|
||||
PHY_MODE_PULL = 3
|
||||
} PHY_MODE;
|
||||
|
||||
typedef struct {
|
||||
uint32_t devId;
|
||||
uint32_t txBramId;
|
||||
uint32_t rxBramId;
|
||||
uint32_t antBramId;
|
||||
uintptr_t baseAddr;
|
||||
} PHY_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
int32_t last;
|
||||
int32_t curr;
|
||||
int32_t next;
|
||||
} PHY_RCD;
|
||||
|
||||
typedef struct {
|
||||
PHY_CONFIG phyCofig; // Device address configs
|
||||
uintptr_t recvDataAddr;
|
||||
uintptr_t sendDataAddr;
|
||||
uintptr_t antConfigAddr;
|
||||
bool isPhyEn; // is physical layer running
|
||||
bool isAcq; // is last reception acquisition success
|
||||
bool isFrameSync; // is last reception frame sync success
|
||||
bool isDecode; // is last reception decode success
|
||||
bool isValid; // is last reception frame data valid (crc check pass)
|
||||
bool isPresetHop; // is using preset frequency hop
|
||||
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 antCoinfoPtr;// antenna configuration pointer
|
||||
} 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];
|
||||
|
||||
extern PHY_ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN];
|
||||
extern PHY_ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN];
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
int32_t Phy_InstInit(PHY_INST** instPtr, PHY_CONFIG *phyConfig);
|
||||
void Phy_Destroy(PHY_INST* instPtr);
|
||||
|
||||
void Phy_UpdateState(PHY_INST* instPtr);
|
||||
|
||||
void Phy_Start(PHY_INST* instPtr);
|
||||
void Phy_Halt(PHY_INST* instPtr);
|
||||
int32_t Phy_SetMode(PHY_INST* instPtr, PHY_MODE modeCod);
|
||||
|
||||
int32_t Phy_SetupNextSlot(PHY_INST* instPtr, PHY_TOR_TYPE txrxMode, L1_FRAME_TYPE frameType, uint8_t* dataBuff);
|
||||
void Phy_RetrieveRecvData(PHY_INST* instPtr, uint8_t* dataBuff);
|
||||
|
||||
bool Phy_IsFrameDetected(PHY_INST* instPtr);
|
||||
bool Phy_IsFrameReceived(PHY_INST* instPtr);
|
||||
bool Phy_IsFrameValid(PHY_INST* instPtr);
|
||||
uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType);
|
||||
|
||||
L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST* instPtr);
|
||||
L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST* instPtr);
|
||||
|
||||
int32_t Phy_SetHopPattern(void* patternBuff, uint32_t patternLen);
|
||||
uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType);
|
||||
uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType);
|
||||
|
||||
int32_t Phy_AntCoinfoInit(PHY_ANT_CONFIG* antCoinfoPtr);
|
||||
int32_t Phy_SetBeamWidth(PHY_INST* instPtr, PHY_ANT_BEAM_WIDTH beamWidth);
|
||||
int32_t Phy_SetBeamNo(PHY_INST* instPtr, int32_t beamNo);
|
||||
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);
|
||||
|
||||
double Phy_GetCoarseFreqEst(PHY_INST* instPtr);
|
||||
void Phy_GetFrameSyncTimeStamp(PHY_INST* instPtr, TIME_WORD* frameSyncT);
|
||||
void Phy_GetLastSlotStartTimeStamp(PHY_INST* instPtr, TIME_WORD* slotStart);
|
||||
#endif /* PHY_CTRL_H_ */
|
||||
@@ -0,0 +1,262 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Physical layer register definitions
|
||||
*
|
||||
* Author: Fan Hao
|
||||
* Date: 2021-11-16 00:08
|
||||
* LastEditors: Fan Hao
|
||||
* LastEditTime: 2022-06-18 17:32
|
||||
* Revisions: Rev 0.0
|
||||
* History:
|
||||
* [2021-11-16]: Initial version.
|
||||
* [2022-06-18]: New branch for glink control purpose:
|
||||
* -Add poll modephysical layer will start Tx/Rx procedure
|
||||
* at specific time stamp.
|
||||
*
|
||||
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PHY_CTRLREG_H_
|
||||
#define PHY_CTRLREG_H_
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "../util/util.h"
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
#define PhyRead(instPtr, addr) IO_In32(instPtr->phyCofig.baseAddr + addr)
|
||||
#define PhyWrite(instPtr, addr, value) IO_Out32(instPtr->phyCofig.baseAddr + addr, value)
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
/**
|
||||
* Register: PHY_MAIN_CTRL
|
||||
*/
|
||||
#define PHY_MAIN_CTRL 0X00000000U
|
||||
#define PHY_MAIN_CTRL_EN_SHIFT 0
|
||||
#define PHY_MAIN_CTRL_EN_WIDTH 1
|
||||
#define PHY_MAIN_CTRL_EN_MASK 0x00000001U
|
||||
#define PHY_MAIN_CTRL_MODE_SHIFT 8
|
||||
#define PHY_MAIN_CTRL_MODE_WIDTH 8
|
||||
#define PHY_MAIN_CTRL_MODE_MASK 0x0000FF00U
|
||||
|
||||
#define PHY_MAIN_CTRL_EN_EN 0x00000001U
|
||||
#define PHY_MAIN_CTRL_EN_DSBL 0x00000000U
|
||||
#define PHY_MAIN_CTRL_MODE_NONE 0x00000000U
|
||||
#define PHY_MAIN_CTRL_MODE_LISTEN 0x00000100U
|
||||
#define PHY_MAIN_CTRL_MODE_SCHEDULE 0x00000200U
|
||||
#define PHY_MAIN_CTRL_MODE_PULL 0x00000300U
|
||||
|
||||
/**
|
||||
* Register: TXRX_CTRL
|
||||
*/
|
||||
#define PHY_MODE_CTRL 0x00000004U
|
||||
#define PHY_MODE_CTRL_TOR_SHIFT 0
|
||||
#define PHY_MODE_CTRL_TOR_WIDTH 8
|
||||
#define PHY_MODE_CTRL_TOR_MASK 0x000000FFU
|
||||
#define PHY_MODE_CTRL_FRAME_SHIFT 8
|
||||
#define PHY_MODE_CTRL_FRAME_WIDTH 8
|
||||
#define PHY_MODE_CTRL_FRAME_MASK 0x0000FF00U
|
||||
#define PHY_MODE_CTRL_CRC_SHIFT 8
|
||||
#define PHY_MODE_CTRL_CRC_WIDTH 16
|
||||
#define PHY_MODE_CTRL_CRC_MASK 0x00FF0000U
|
||||
|
||||
#define PHY_MODE_CTRL_TOR_SUSPEND 0x00000000U
|
||||
#define PHY_MODE_CTRL_TOR_TX 0x00000001U
|
||||
#define PHY_MODE_CTRL_TOR_RX 0x00000002U
|
||||
|
||||
#define PHY_MODE_CTRL_FRAME_NONE 0x00000000U
|
||||
#define PHY_MODE_CTRL_FRAME_2KBPS_20MS 0x00000100U
|
||||
#define PHY_MODE_CTRL_FRAME_2KBPS_100MS 0x00000200U
|
||||
#define PHY_MODE_CTRL_FRAME_10KBPS_10MS 0x00000300U // Initial Scan Frame
|
||||
#define PHY_MODE_CTRL_FRAME_10KBPS_20MS 0x00000400U // Benchmark Frame
|
||||
#define PHY_MODE_CTRL_FRAME_40KBPS_20MS 0x00000500U
|
||||
#define PHY_MODE_CTRL_FRAME_40KBPS_10MS 0x00000600U
|
||||
#define PHY_MODE_CTRL_FRAME_200KBPS_5MS 0x00000700U // 2-Way ACQ Frame, Management Frame, Service Frame
|
||||
#define PHY_MODE_CTRL_FRAME_1M2BPS_5MS 0x00000800U // Bistatic Synthetic Aperture Radar Frame
|
||||
|
||||
#define PHY_MODE_CTRL_CRC_EN 0x00010000U
|
||||
#define PHY_MODE_CTRL_CRC_DSBL 0x00000000U
|
||||
/**
|
||||
* Register: POLLTIME_L
|
||||
*/
|
||||
#define POLLTIME_L 0x00000008U
|
||||
#define POLLTIME_L_SHIFT 0
|
||||
#define POLLTIME_L_WIDTH 32
|
||||
#define POLLTIME_L_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: POLLTIME_H
|
||||
*/
|
||||
#define POLLTIME_H 0x0000000CU
|
||||
#define POLLTIME_H_SHIFT 0
|
||||
#define POLLTIME_H_WIDTH 32
|
||||
#define POLLTIME_H_MASK 0xFFFFFFFFU
|
||||
|
||||
|
||||
/**
|
||||
* Register: TIMEOUT_L
|
||||
*/
|
||||
#define LISTENTIMEOUT_L 0x00000010U
|
||||
#define LISTENTIMEOUT_L_SHIFT 0
|
||||
#define LISTENTIMEOUT_L_WIDTH 32
|
||||
#define LISTENTIMEOUT_L_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: TIMEOUT_H
|
||||
*/
|
||||
#define LISTENTIMEOUT_H 0x00000014U
|
||||
#define LISTENTIMEOUT_H_SHIFT 0
|
||||
#define LISTENTIMEOUT_H_WIDTH 32
|
||||
#define LISTENTIMEOUT_H_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: ANT_CTRL
|
||||
*/
|
||||
#define ANT_CONFIG 0x00000018U
|
||||
#define ANT_CONFIG_OFFSET_SHIFT 0
|
||||
#define ANT_CONFIG_OFFSET_WIDTH 16
|
||||
#define ANT_CONFIG_OFFSET_MASK 0x0000FFFFU
|
||||
#define ANT_CONFIG_LEN_SHIFT 16
|
||||
#define ANT_CONFIG_LEN_WIDTH 8
|
||||
#define ANT_CONFIG_LEN_MASK 0x00FF0000U
|
||||
#define ANT_CONFIG_NUM_SHIFT 24
|
||||
#define ANT_CONFIG_NUM_WIDTH 8
|
||||
#define ANT_CONFIG_NUM_MASK 0xFF000000U
|
||||
|
||||
/**
|
||||
* Register: SEND_DATA_CMD
|
||||
*/
|
||||
#define SEND_DATA_CMD 0x0000001CU
|
||||
#define SEND_DATA_CMD_SHIFT 0
|
||||
#define SEND_DATA_CMD_WIDTH 32
|
||||
#define SEND_DATA_CMD_MASK 0xFFFFFFFFU
|
||||
|
||||
#define SEND_DATA_CMD_LEN_SHIFT 0
|
||||
#define SEND_DATA_CMD_LEN_WIDTH 16
|
||||
#define SEND_DATA_CMD_LEN_MASK 0x0000FFFFU
|
||||
#define SEND_DATA_CMD_OFFSET_SHIFT 16
|
||||
#define SEND_DATA_CMD_OFFSET_WIDTH 16
|
||||
#define SEND_DATA_CMD_OFFSET_MASK 0xFFFF0000U
|
||||
|
||||
/**
|
||||
* Register: SEND_CONFIG_CMD
|
||||
*/
|
||||
#define SLOT_CMD 0x00000020U
|
||||
#define SLOT_CMD_SHIFT 0
|
||||
#define SLOT_CMD_WIDTH 32
|
||||
#define SLOT_CMD_MASK 0xFFFFFFFFU
|
||||
#define SLOT_CMD_KEY 0x434D442EU
|
||||
|
||||
/**
|
||||
* Register: TXRX_STATE
|
||||
*/
|
||||
#define TXRX_STATE 0x00000024U
|
||||
#define TXRX_STATE_ACQ_SHIFT 0
|
||||
#define TXRX_STATE_ACQ_WIDTH 8
|
||||
#define TXRX_STATE_ACQ_MASK 0x000000FFU
|
||||
#define TXRX_STATE_ACQ_SUCCESS 0x00000001U
|
||||
#define TXRX_STATE_ACQ_FAIL 0x00000002U
|
||||
|
||||
#define TXRX_STATE_FSYNC_SHIFT 8
|
||||
#define TXRX_STATE_FSYNC_WIDTH 8
|
||||
#define TXRX_STATE_FSYNC_MASK 0x0000FF00U
|
||||
#define TXRX_STATE_FSYNC_SUCCESS 0x00000100U
|
||||
#define TXRX_STATE_FSYNC_FAIL 0x00000200U
|
||||
|
||||
#define TXRX_STATE_DECODE_SHIFT 16
|
||||
#define TXRX_STATE_DECODE_WIDTH 8
|
||||
#define TXRX_STATE_DECODE_MASK 0x00FF0000U
|
||||
#define TXRX_STATE_DECODE_SUCCESS 0x00010000U
|
||||
#define TXRX_STATE_DECODE_FAIL 0x00020000U
|
||||
|
||||
#define TXRX_STATE_CRC_SHIFT 24
|
||||
#define TXRX_STATE_CRC_WIDTH 8
|
||||
#define TXRX_STATE_CRC_MASK 0xFF000000U
|
||||
#define TXRX_STATE_CRC_OK 0x01000000U
|
||||
#define TXRX_STATE_CRC_ERROR 0x02000000U
|
||||
|
||||
|
||||
/**
|
||||
* Register: RECVDATA_STATE
|
||||
*/
|
||||
#define RECVDATA_STATE 0x00000028U
|
||||
#define RECVDATA_STATE_LEN_SHIFT 0
|
||||
#define RECVDATA_STATE_LEN_WIDTH 16
|
||||
#define RECVDATA_STATE_LEN_MASK 0x0000FFFFU
|
||||
|
||||
#define RECVDATA_STATE_OFFSET_SHIFT 16
|
||||
#define RECVDATA_STATE_OFFSET_WIDTH 16
|
||||
#define RECVDATA_STATE_OFFSET_MASK 0xFFFF0000U
|
||||
/**
|
||||
* Register: FSTIME_L
|
||||
*/
|
||||
#define FSTIME_L 0x000002CU
|
||||
#define FSTIME_L_SHIFT 0
|
||||
#define FSTIME_L_WIDTH 32
|
||||
#define FSTIME_L_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: FSTIME_INT1
|
||||
*/
|
||||
#define FSTIME_H 0x0000030U
|
||||
#define FSTIME_H_SHIFT 0
|
||||
#define FSTIME_H_WIDTH 32
|
||||
#define FSTIME_H_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: TM_TARGET_L
|
||||
*/
|
||||
#define TM_TARGET_L 0x0000064U
|
||||
#define TM_TARGET_L_SHIFT 0
|
||||
#define TM_TARGET_L_WIDTH 32
|
||||
#define TM_TARGET_L_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: TM_TARGET_H
|
||||
*/
|
||||
#define TM_TARGET_H 0x0000038U
|
||||
#define TM_TARGET_H_SHIFT 0
|
||||
#define TM_TARGET_H_WIDTH 32
|
||||
#define TM_TARGET_H_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: COASEFREQEST
|
||||
*/
|
||||
#define COASE_FREQEST 0x0000003CU
|
||||
#define COASE_FREQEST_ACQ_SHIFT 0
|
||||
#define COASE_FREQEST_ACQ_WIDTH 8
|
||||
#define COASE_FREQEST_ACQ_MASK 0x000000FFU
|
||||
#define COASE_FREQEST_SYNC_SHIFT 0
|
||||
#define COASE_FREQEST_SYNC_WIDTH 16
|
||||
#define COASE_FREQEST_SYNC_MASK 0x000FF00U
|
||||
|
||||
/**
|
||||
* Register: FINE_FREQEST
|
||||
*/
|
||||
#define FINE_FREQEST 0x00000040U
|
||||
#define FINE_FREQEST_SHIFT 0
|
||||
#define FINE_FREQEST_WIDTH 32
|
||||
#define FINE_FREQEST_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: BEAM_SELECT
|
||||
*/
|
||||
#define BEAM_SELECT_INDEX 0x00000044U
|
||||
#define BEAM_SELECT_INDEX_SHIFT 0
|
||||
#define BEAM_SELECT_INDEX_WIDTH 32
|
||||
#define BEAM_SELECT_INDEX_MASK 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* Register: BEAM_SELECT
|
||||
*/
|
||||
#define BEAM_AXIS 0x00000044U
|
||||
#define BEAM_AXIS_EL_SHIFT 0
|
||||
#define BEAM_AXIS_EL_WIDTH 16
|
||||
#define BEAM_AXIS_EL_MASK 0x0000FFFFU
|
||||
#define BEAM_AXIS_AZ_SHIFT 16
|
||||
#define BEAM_AXIS_AZ_WIDTH 16
|
||||
#define BEAM_AXIS_AZ_MASK 0xFFFF0000U
|
||||
|
||||
// Reserved.
|
||||
#endif /* PHY_CTRLREG_H_ */
|
||||
Reference in New Issue
Block a user