frame resynchronization in RAU and RRU
This commit is contained in:
+11
-3
@@ -559,7 +559,9 @@ typedef struct eNB_proc_t_s {
|
|||||||
/// mutex for RU access to eNB processing (PRACH BR)
|
/// mutex for RU access to eNB processing (PRACH BR)
|
||||||
pthread_mutex_t mutex_RU_PRACH_br;
|
pthread_mutex_t mutex_RU_PRACH_br;
|
||||||
/// mask for RUs serving eNB (PDSCH/PUSCH)
|
/// mask for RUs serving eNB (PDSCH/PUSCH)
|
||||||
int RU_mask;
|
int RU_mask[10];
|
||||||
|
/// time measurements for RU arrivals
|
||||||
|
struct timespec t[10];
|
||||||
/// mask for RUs serving eNB (PRACH)
|
/// mask for RUs serving eNB (PRACH)
|
||||||
int RU_mask_prach;
|
int RU_mask_prach;
|
||||||
#ifdef Rel14
|
#ifdef Rel14
|
||||||
@@ -687,7 +689,8 @@ typedef enum {
|
|||||||
/// Some commamds to RRU. Not sure we should do it like this !
|
/// Some commamds to RRU. Not sure we should do it like this !
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EMPTY = 0,
|
EMPTY = 0,
|
||||||
STOP_RU = 1
|
STOP_RU = 1,
|
||||||
|
RU_FRAME_RESYNCH = 2
|
||||||
} rru_cmd_t;
|
} rru_cmd_t;
|
||||||
|
|
||||||
typedef struct RU_t_s{
|
typedef struct RU_t_s{
|
||||||
@@ -709,6 +712,8 @@ typedef struct RU_t_s{
|
|||||||
int rx_offset;
|
int rx_offset;
|
||||||
/// flag to indicate the RU is a slave to another source
|
/// flag to indicate the RU is a slave to another source
|
||||||
int is_slave;
|
int is_slave;
|
||||||
|
/// counter to delay start of processing of RU until HW settles
|
||||||
|
int wait_cnt;
|
||||||
/// Total gain of receive chain
|
/// Total gain of receive chain
|
||||||
uint32_t rx_total_gain_dB;
|
uint32_t rx_total_gain_dB;
|
||||||
/// number of bands that this device can support
|
/// number of bands that this device can support
|
||||||
@@ -812,6 +817,8 @@ typedef struct RU_t_s{
|
|||||||
rru_state_t state;
|
rru_state_t state;
|
||||||
/// Command to do
|
/// Command to do
|
||||||
rru_cmd_t cmd;
|
rru_cmd_t cmd;
|
||||||
|
/// value to be passed using command
|
||||||
|
uint16_t cmdval;
|
||||||
/// process scheduling variables
|
/// process scheduling variables
|
||||||
RU_proc_t proc;
|
RU_proc_t proc;
|
||||||
/// stats thread pthread descriptor
|
/// stats thread pthread descriptor
|
||||||
@@ -1501,7 +1508,8 @@ typedef enum {
|
|||||||
RRU_config_ok=4,
|
RRU_config_ok=4,
|
||||||
RRU_start=5,
|
RRU_start=5,
|
||||||
RRU_stop=6,
|
RRU_stop=6,
|
||||||
RRU_sync_ok=7
|
RRU_sync_ok=7,
|
||||||
|
RRU_frame_resynch=8
|
||||||
} rru_config_msg_type_t;
|
} rru_config_msg_type_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
|
|||||||
|
|
||||||
// UE-specific RX processing for subframe n
|
// UE-specific RX processing for subframe n
|
||||||
if (nfapi_mode == 0 || nfapi_mode == 1) {
|
if (nfapi_mode == 0 || nfapi_mode == 1) {
|
||||||
|
LOG_I(PHY,"Calling RX procedures for SFNSF %d.%d\n",proc->frame_rx,proc->subframe_rx);
|
||||||
phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
|
phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +251,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
|
|||||||
|
|
||||||
if (oai_exit) return(-1);
|
if (oai_exit) return(-1);
|
||||||
|
|
||||||
LOG_D(PHY,"Calling eNB_procedures_TX for SFN.SF %d.%d\n",proc->frame_tx,proc->subframe_tx);
|
LOG_I(PHY,"Calling eNB_procedures_TX for SFN.SF %d.%d\n",proc->frame_tx,proc->subframe_tx);
|
||||||
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
|
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
|
||||||
|
|
||||||
stop_meas( &softmodem_stats_rxtx_sf );
|
stop_meas( &softmodem_stats_rxtx_sf );
|
||||||
@@ -416,21 +417,21 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
|
|||||||
pthread_mutex_lock(&proc->mutex_RU);
|
pthread_mutex_lock(&proc->mutex_RU);
|
||||||
for (i=0;i<eNB->num_RU;i++) {
|
for (i=0;i<eNB->num_RU;i++) {
|
||||||
if (ru == eNB->RU_list[i]) {
|
if (ru == eNB->RU_list[i]) {
|
||||||
if ((proc->RU_mask&(1<<i)) > 0)
|
if ((proc->RU_mask[ru->proc.subframe_rx]&(1<<i)) > 0)
|
||||||
LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
|
LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
|
||||||
eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
|
eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask[ru->proc.subframe_rx]);
|
||||||
proc->RU_mask |= (1<<i);
|
proc->RU_mask[ru->proc.subframe_rx] |= (1<<i);
|
||||||
}else if (eNB->RU_list[i]->state == RU_SYNC){
|
}else if (eNB->RU_list[i]->state == RU_SYNC){
|
||||||
proc->RU_mask |= (1<<i);
|
proc->RU_mask[ru->proc.subframe_rx] |= (1<<i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (proc->RU_mask != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
|
if (proc->RU_mask[ru->proc.subframe_rx] != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
|
||||||
LOG_E(PHY,"Not all RUs have provided their info\n");
|
LOG_E(PHY,"Not all RUs have provided their info\n");
|
||||||
pthread_mutex_unlock(&proc->mutex_RU);
|
pthread_mutex_unlock(&proc->mutex_RU);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
else { // all RUs have provided their information so continue on and wakeup eNB processing
|
else { // all RUs have provided their information so continue on and wakeup eNB processing
|
||||||
proc->RU_mask = 0;
|
proc->RU_mask[ru->proc.subframe_rx] = 0;
|
||||||
pthread_mutex_unlock(&proc->mutex_RU);
|
pthread_mutex_unlock(&proc->mutex_RU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,7 +725,7 @@ void init_eNB_proc(int inst) {
|
|||||||
|
|
||||||
proc->first_rx=1;
|
proc->first_rx=1;
|
||||||
proc->first_tx=1;
|
proc->first_tx=1;
|
||||||
proc->RU_mask=0;
|
for (i=0;i<10;i++) proc->RU_mask[i]=0;
|
||||||
proc->RU_mask_prach=0;
|
proc->RU_mask_prach=0;
|
||||||
|
|
||||||
pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
|
pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
|
||||||
|
|||||||
+96
-69
@@ -584,6 +584,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) {
|
|||||||
|
|
||||||
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
|
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
|
||||||
recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
|
recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
|
||||||
|
if (ru->cmd == STOP_RU) break;
|
||||||
// grab first prach information for this new subframe
|
// grab first prach information for this new subframe
|
||||||
if (got_prach_info==0) {
|
if (got_prach_info==0) {
|
||||||
prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx);
|
prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx);
|
||||||
@@ -793,6 +794,12 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
|
|||||||
ru->nb_rx);
|
ru->nb_rx);
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
|
||||||
|
|
||||||
|
if (ru->cmd==RU_FRAME_RESYNCH) {
|
||||||
|
ru->ts_offset += (proc->frame_rx - ru->cmdval)*fp->samples_per_tti*10;
|
||||||
|
*frame = ru->cmdval;
|
||||||
|
ru->cmd=EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
proc->timestamp_rx = ts-ru->ts_offset;
|
proc->timestamp_rx = ts-ru->ts_offset;
|
||||||
|
|
||||||
@@ -1240,6 +1247,7 @@ void wakeup_eNBs(RU_t *ru) {
|
|||||||
PHY_VARS_eNB **eNB_list = ru->eNB_list;
|
PHY_VARS_eNB **eNB_list = ru->eNB_list;
|
||||||
PHY_VARS_eNB *eNB=eNB_list[0];
|
PHY_VARS_eNB *eNB=eNB_list[0];
|
||||||
eNB_proc_t *proc = &eNB->proc;
|
eNB_proc_t *proc = &eNB->proc;
|
||||||
|
struct timespec t;
|
||||||
|
|
||||||
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d (state %s)ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru_states[ru->state],ru->eNB_top);
|
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d (state %s)ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru_states[ru->state],ru->eNB_top);
|
||||||
|
|
||||||
@@ -1248,32 +1256,36 @@ void wakeup_eNBs(RU_t *ru) {
|
|||||||
|
|
||||||
char string[20];
|
char string[20];
|
||||||
sprintf(string,"Incoming RU %d",ru->idx);
|
sprintf(string,"Incoming RU %d",ru->idx);
|
||||||
LOG_D(PHY,"Frame %d, Subframe %d: RU %d Waking up eNB,RU_mask %x\n",ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,proc->RU_mask);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&proc->mutex_RU);
|
pthread_mutex_lock(&proc->mutex_RU);
|
||||||
|
LOG_D(PHY,"Frame %d, Subframe %d: RU %d done,RU_mask[%d] %x\n",ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]);
|
||||||
|
|
||||||
|
if (proc->RU_mask[ru->proc.subframe_rx] == 0)
|
||||||
|
clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]);
|
||||||
for (i=0;i<eNB->num_RU;i++) {
|
for (i=0;i<eNB->num_RU;i++) {
|
||||||
LOG_D(PHY,"RU %d state %s\n",eNB->RU_list[i]->idx,ru_states[eNB->RU_list[i]->state]);
|
LOG_D(PHY,"RU %d state %s\n",eNB->RU_list[i]->idx,ru_states[eNB->RU_list[i]->state]);
|
||||||
if (ru == eNB->RU_list[i]) {
|
if (ru == eNB->RU_list[i]) {
|
||||||
// AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",eNB->Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
|
// AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",eNB->Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
|
||||||
proc->RU_mask |= (1<<i);
|
proc->RU_mask[ru->proc.subframe_rx] |= (1<<i);
|
||||||
}else if (eNB->RU_list[i]->state == RU_SYNC){
|
}else if (eNB->RU_list[i]->state == RU_SYNC || eNB->RU_list[i]->wait_cnt > 0){
|
||||||
proc->RU_mask |= (1<<i);
|
proc->RU_mask[ru->proc.subframe_rx] |= (1<<i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_D(PHY,"RU mask is now %x\n",proc->RU_mask);
|
LOG_D(PHY,"RU mask is now %x\n",proc->RU_mask[ru->proc.subframe_rx]);
|
||||||
if (proc->RU_mask != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
|
|
||||||
pthread_mutex_unlock(&proc->mutex_RU);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else { // all RUs have provided their information so continue on and wakeup eNB processing
|
|
||||||
proc->RU_mask = 0;
|
|
||||||
pthread_mutex_unlock(&proc->mutex_RU);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (proc->RU_mask[ru->proc.subframe_rx] == (1<<eNB->num_RU)-1) {
|
||||||
|
proc->RU_mask[ru->proc.subframe_rx] = 0;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC,&t);
|
||||||
|
AssertFatal(t.tv_nsec > proc->t[ru->proc.subframe_rx].tv_nsec+500000,
|
||||||
|
"Time difference for subframe %d => %d > 5ms\n",
|
||||||
|
ru->proc.subframe_rx,t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&proc->mutex_RU);
|
||||||
LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx);
|
LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx);
|
||||||
ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string);
|
ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string);
|
||||||
}
|
}
|
||||||
else {
|
else { // multiple eNB case for later
|
||||||
|
|
||||||
LOG_D(PHY,"ru->num_eNB:%d\n", ru->num_eNB);
|
LOG_D(PHY,"ru->num_eNB:%d\n", ru->num_eNB);
|
||||||
|
|
||||||
@@ -1564,9 +1576,8 @@ static void* ru_thread_control( void* param ) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RRU_capabilities: // RAU
|
case RRU_capabilities: // RAU
|
||||||
if (ru->if_south == LOCAL_RF){
|
if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_capab msg...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_capab msg...Ignoring\n");
|
|
||||||
}
|
|
||||||
else{
|
else{
|
||||||
msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t);
|
msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t);
|
||||||
|
|
||||||
@@ -1629,15 +1640,13 @@ static void* ru_thread_control( void* param ) {
|
|||||||
"RU %d failed send CONFIG_OK to RAU\n",ru->idx);
|
"RU %d failed send CONFIG_OK to RAU\n",ru->idx);
|
||||||
reset_proc(ru);
|
reset_proc(ru);
|
||||||
ru->state = RU_READY;
|
ru->state = RU_READY;
|
||||||
}else{
|
} else LOG_E(PHY,"Received RRU_config msg...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_config msg...Ignoring\n");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RRU_config_ok: // RAU
|
case RRU_config_ok: // RAU
|
||||||
if (ru->if_south == LOCAL_RF){
|
if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_config_ok msg...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_config_ok msg...Ignoring\n");
|
else{
|
||||||
}else{
|
|
||||||
|
|
||||||
if (setup_RU_buffers(ru)!=0) {
|
if (setup_RU_buffers(ru)!=0) {
|
||||||
printf("Exiting, cannot initialize RU Buffers\n");
|
printf("Exiting, cannot initialize RU Buffers\n");
|
||||||
@@ -1701,27 +1710,30 @@ static void* ru_thread_control( void* param ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else LOG_E(PHY,"RRU not ready, cannot start\n");
|
||||||
LOG_I(PHY,"RRU not ready, cannot start\n");
|
|
||||||
}
|
} else LOG_E(PHY,"Received RRU_start msg...Ignoring\n");
|
||||||
}else{
|
|
||||||
LOG_I(PHY,"Received RRU_start msg...Ignoring\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RRU_sync_ok: //RAU
|
case RRU_sync_ok: //RAU
|
||||||
if (ru->if_south == LOCAL_RF){
|
if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_config_ok msg...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_config_ok msg...Ignoring\n");
|
else{
|
||||||
}else{
|
|
||||||
if (ru->is_slave == 1){
|
if (ru->is_slave == 1){
|
||||||
|
LOG_I(PHY,"Received RRU_sync_ok from RRU %d\n",ru->idx);
|
||||||
// Just change the state of the RRU to unblock ru_thread()
|
// Just change the state of the RRU to unblock ru_thread()
|
||||||
ru->state = RU_RUN;
|
ru->state = RU_RUN;
|
||||||
}else{
|
}else LOG_E(PHY,"Received RRU_sync_ok from a master RRU...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_sync_ok from a master RRU...Ignoring\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RRU_frame_resynch: //RRU
|
||||||
|
if (ru->if_south != LOCAL_RF) LOG_E(PHY,"Received RRU frame resynch message, should not happen in RAU\n");
|
||||||
|
else {
|
||||||
|
ru->cmd = RU_FRAME_RESYNCH;
|
||||||
|
ru->cmdval = ((uint16_t*)&rru_config_msg.msg[0])[0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case RRU_stop: // RRU
|
case RRU_stop: // RRU
|
||||||
if (ru->if_south == LOCAL_RF){
|
if (ru->if_south == LOCAL_RF){
|
||||||
@@ -1735,9 +1747,8 @@ static void* ru_thread_control( void* param ) {
|
|||||||
}else{
|
}else{
|
||||||
LOG_I(PHY,"RRU not running, can't stop\n");
|
LOG_I(PHY,"RRU not running, can't stop\n");
|
||||||
}
|
}
|
||||||
}else{
|
}else LOG_E(PHY,"Received RRU_stop msg...Ignoring\n");
|
||||||
LOG_I(PHY,"Received RRU_stop msg...Ignoring\n");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1778,16 +1789,17 @@ static void* ru_thread( void* param ) {
|
|||||||
|
|
||||||
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]);
|
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (!oai_exit) {
|
while (!oai_exit) {
|
||||||
|
|
||||||
|
if (ru->if_south != LOCAL_RF) ru->wait_cnt = 100;
|
||||||
|
else ru->wait_cnt = 0;
|
||||||
|
|
||||||
// wait to be woken up
|
// wait to be woken up
|
||||||
if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break;
|
if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break;
|
||||||
|
|
||||||
if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru->state = %d != RU_RUN\n",ru->state);
|
if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]);
|
||||||
else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC,"ru->state = %d != RU_SYNC\n",ru->state);
|
else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN,"ru %d state = %s != RU_SYNC or RU_RUN\n",ru->idx,ru_states[ru->state]);
|
||||||
// Start RF device if any
|
// Start RF device if any
|
||||||
if (ru->start_rf) {
|
if (ru->start_rf) {
|
||||||
if (ru->start_rf(ru) != 0)
|
if (ru->start_rf(ru) != 0)
|
||||||
@@ -1826,10 +1838,6 @@ static void* ru_thread( void* param ) {
|
|||||||
subframe++;
|
subframe++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_D(PHY,"RU thread %d, frame %d (%p), subframe %d (%p)\n",
|
|
||||||
ru->idx, frame,&frame,subframe,&subframe);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// synchronization on input FH interface, acquire signals/data and block
|
// synchronization on input FH interface, acquire signals/data and block
|
||||||
if (ru->stop_rf && ru->cmd == STOP_RU) {
|
if (ru->stop_rf && ru->cmd == STOP_RU) {
|
||||||
@@ -1848,43 +1856,62 @@ static void* ru_thread( void* param ) {
|
|||||||
|
|
||||||
if (ru->fh_south_in && ru->state == RU_RUN ) ru->fh_south_in(ru,&frame,&subframe);
|
if (ru->fh_south_in && ru->state == RU_RUN ) ru->fh_south_in(ru,&frame,&subframe);
|
||||||
else AssertFatal(1==0, "No fronthaul interface at south port");
|
else AssertFatal(1==0, "No fronthaul interface at south port");
|
||||||
|
if (ru->wait_cnt > 0) {
|
||||||
|
ru->wait_cnt--;
|
||||||
|
|
||||||
if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) {
|
if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != RC.ru[0]->proc.frame_rx) {
|
||||||
wakeup_prach_ru(ru);
|
// Send RRU_frame adjust
|
||||||
|
RRU_CONFIG_msg_t rru_config_msg;
|
||||||
|
rru_config_msg.type = RRU_frame_resynch;
|
||||||
|
rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
|
||||||
|
((uint16_t*)&rru_config_msg.msg[0])[0] = RC.ru[0]->proc.frame_rx;
|
||||||
|
LOG_I(PHY,"Sending Frame Resynch %d to RRU\n", ru->idx,RC.ru[0]->proc.frame_rx);
|
||||||
|
AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
LOG_D(PHY,"RU thread %d, frame %d, subframe %d \n",
|
||||||
|
ru->idx,frame,subframe);
|
||||||
|
|
||||||
|
|
||||||
|
if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) {
|
||||||
|
wakeup_prach_ru(ru);
|
||||||
|
}
|
||||||
#ifdef Rel14
|
#ifdef Rel14
|
||||||
else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) {
|
else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) {
|
||||||
wakeup_prach_ru_br(ru);
|
wakeup_prach_ru_br(ru);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// adjust for timing offset between RU
|
// adjust for timing offset between RU
|
||||||
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
|
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
|
||||||
|
|
||||||
// At this point, all information for subframe has been received on FH interface
|
// At this point, all information for subframe has been received on FH interface
|
||||||
// If this proc is to provide synchronization, do so
|
// If this proc is to provide synchronization, do so
|
||||||
wakeup_slaves(proc);
|
wakeup_slaves(proc);
|
||||||
|
|
||||||
// do RX front-end processing (frequency-shift, dft) if needed
|
// do RX front-end processing (frequency-shift, dft) if needed
|
||||||
if (ru->feprx) ru->feprx(ru);
|
if (ru->feprx) ru->feprx(ru);
|
||||||
|
|
||||||
// wakeup all eNB processes waiting for this RU
|
// wakeup all eNB processes waiting for this RU
|
||||||
if (ru->num_eNB>0) wakeup_eNBs(ru);
|
if (ru->num_eNB>0) wakeup_eNBs(ru);
|
||||||
|
|
||||||
// wait until eNBs are finished subframe RX n and TX n+4
|
// wait until eNBs are finished subframe RX n and TX n+4
|
||||||
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
|
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
|
||||||
|
|
||||||
|
|
||||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||||
|
|
||||||
// do OFDM if needed
|
// do OFDM if needed
|
||||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||||
// do outgoing fronthaul (south) if needed
|
// do outgoing fronthaul (south) if needed
|
||||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||||
|
|
||||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // while !oai_exit
|
} // while !oai_exit
|
||||||
|
|||||||
Reference in New Issue
Block a user