Commit da500691 authored by Raymond Knopp's avatar Raymond Knopp

conflict resolution after merge with develop

parent 63e7c171
...@@ -1046,10 +1046,6 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -1046,10 +1046,6 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
exit_fun("Exiting"); exit_fun("Exiting");
} }
} else { } else {
<<<<<<< HEAD
// proc->first_rx = 0;
=======
>>>>>>> origin/develop
proc->first_rx--; proc->first_rx--;
*frame = proc->frame_rx; *frame = proc->frame_rx;
*subframe = proc->subframe_rx; *subframe = proc->subframe_rx;
...@@ -1725,14 +1721,9 @@ void init_eNB_proc(int inst) { ...@@ -1725,14 +1721,9 @@ void init_eNB_proc(int inst) {
proc->instance_cnt_FH = -1; proc->instance_cnt_FH = -1;
proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_asynch_rxtx = -1;
proc->CC_id = CC_id; proc->CC_id = CC_id;
<<<<<<< HEAD
proc->first_rx=100; proc->first_rx=100;
=======
proc->instance_cnt_synch = -1; proc->instance_cnt_synch = -1;
proc->first_rx=1;
>>>>>>> origin/develop
proc->first_tx=1; proc->first_tx=1;
proc->frame_offset = 0; proc->frame_offset = 0;
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
#define FIFO_PRIORITY 40 #define FIFO_PRIORITY 40
typedef enum { typedef enum {
pss=0, pss=0,
pbch=1, pbch=1,
si=2 si=2
} sync_mode_t; } sync_mode_t;
void init_UE_threads(PHY_VARS_UE *UE); void init_UE_threads(PHY_VARS_UE *UE);
...@@ -77,100 +77,100 @@ int32_t **txdata; ...@@ -77,100 +77,100 @@ int32_t **txdata;
#define MHz (1000*KHz) #define MHz (1000*KHz)
typedef struct eutra_band_s { typedef struct eutra_band_s {
int16_t band; int16_t band;
uint32_t ul_min; uint32_t ul_min;
uint32_t ul_max; uint32_t ul_max;
uint32_t dl_min; uint32_t dl_min;
uint32_t dl_max; uint32_t dl_max;
lte_frame_type_t frame_type; lte_frame_type_t frame_type;
} eutra_band_t; } eutra_band_t;
typedef struct band_info_s { typedef struct band_info_s {
int nbands; int nbands;
eutra_band_t band_info[100]; eutra_band_t band_info[100];
} band_info_t; } band_info_t;
band_info_t bands_to_scan; band_info_t bands_to_scan;
static const eutra_band_t eutra_bands[] = { static const eutra_band_t eutra_bands[] = {
{ 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD},
{ 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD},
{ 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD},
{ 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD},
{ 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD},
{ 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD},
{ 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD},
{ 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD},
{ 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD},
{10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD},
{11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD},
{12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD},
{13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD},
{14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD},
{17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD},
{20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD},
{22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD},
{33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD},
{34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD},
{35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD},
{36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD},
{37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD},
{38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD},
{39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD},
{40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD},
{41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD},
{42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD},
{43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD},
{44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD},
}; };
void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) {
#ifdef DEADLINE_SCHEDULER #ifdef DEADLINE_SCHEDULER
if (sched_runtime!=0) { if (sched_runtime!=0) {
struct sched_attr attr= {0}; struct sched_attr attr= {0};
attr.size = sizeof(attr); attr.size = sizeof(attr);
attr.sched_policy = SCHED_DEADLINE; attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = sched_runtime; attr.sched_runtime = sched_runtime;
attr.sched_deadline = sched_deadline; attr.sched_deadline = sched_deadline;
attr.sched_period = 0; attr.sched_period = 0;
AssertFatal(sched_setattr(0, &attr, 0) == 0, AssertFatal(sched_setattr(0, &attr, 0) == 0,
"[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno));
LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n",
name, (unsigned long)gettid(), sched_getcpu()); name, (unsigned long)gettid(), sched_getcpu());
} }
#else #else
if (CPU_COUNT(cpuset) > 0) if (CPU_COUNT(cpuset) > 0)
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
struct sched_param sp; struct sched_param sp;
sp.sched_priority = sched_fifo; sp.sched_priority = sched_fifo;
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
"Can't set thread priority, Are you root?\n"); "Can't set thread priority, Are you root?\n");
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
char txt[512]={0}; char txt[512]={0};
for (int j = 0; j < CPU_SETSIZE; j++) for (int j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, cset)) if (CPU_ISSET(j, cset))
sprintf(txt+strlen(txt), " %d ", j); sprintf(txt+strlen(txt), " %d ", j);
printf("CPU Affinity of thread %s is %s\n", name, txt); printf("CPU Affinity of thread %s is %s\n", name, txt);
} }
CPU_FREE(cset); CPU_FREE(cset);
#endif #endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread). // Lock memory from swapping. This is a process wide call (not constraint to this thread).
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
pthread_setname_np( pthread_self(), name ); pthread_setname_np( pthread_self(), name );
// LTS: this sync stuff should be wrong // LTS: this sync stuff should be wrong
printf("waiting for sync (%s)\n",name); printf("waiting for sync (%s)\n",name);
pthread_mutex_lock(&sync_mutex); pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (%s)\n",name); printf("Locked sync_mutex, waiting (%s)\n",name);
while (sync_var<0) while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex); pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf("started %s as PID: %ld\n",name, gettid()); printf("started %s as PID: %ld\n",name, gettid());
} }
void init_UE(int nb_inst) void init_UE(int nb_inst)
...@@ -203,258 +203,258 @@ void init_UE(int nb_inst) ...@@ -203,258 +203,258 @@ void init_UE(int nb_inst)
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void *UE_thread_synch(void *arg) { static void *UE_thread_synch(void *arg) {
static int __thread UE_thread_synch_retval; static int __thread UE_thread_synch_retval;
int i, hw_slot_offset; int i, hw_slot_offset;
PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; PHY_VARS_UE *UE = (PHY_VARS_UE*) arg;
int current_band = 0; int current_band = 0;
int current_offset = 0; int current_offset = 0;
sync_mode_t sync_mode = pbch; sync_mode_t sync_mode = pbch;
int CC_id = UE->CC_id; int CC_id = UE->CC_id;
int freq_offset=0; int freq_offset=0;
char threadname[128]; char threadname[128];
cpu_set_t cpuset; cpu_set_t cpuset;
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
if ( threads.iq != -1 ) if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset); CPU_SET(threads.iq, &cpuset);
// this thread priority must be lower that the main acquisition thread // this thread priority must be lower that the main acquisition thread
sprintf(threadname, "sync UE %d\n", UE->Mod_id); sprintf(threadname, "sync UE %d\n", UE->Mod_id);
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname);
UE->is_synchronized = 0; UE->is_synchronized = 0;
if (UE->UE_scan == 0) { if (UE->UE_scan == 0) {
int ind; int ind;
for ( ind=0; for ( ind=0;
ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]);
ind++) { ind++) {
current_band = eutra_bands[ind].band; current_band = eutra_bands[ind].band;
LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) {
for (i=0; i<4; i++) for (i=0; i<4; i++)
uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
break; break;
} }
} }
AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency");
LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
oai_exit, openair0_cfg[0].rx_num_channels); oai_exit, openair0_cfg[0].rx_num_channels);
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
if (uplink_frequency_offset[CC_id][i] != 0) // if (uplink_frequency_offset[CC_id][i] != 0) //
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
else //FDD else //FDD
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
} }
sync_mode = pbch; sync_mode = pbch;
} else { } else {
current_band=0; current_band=0;
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
} }
}
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
while (oai_exit==0) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
while (UE->proc.instance_cnt_synch < 0)
// the thread waits here most of the time
pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
switch (sync_mode) {
case pss:
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) {
current_band=0;
oai_exit=1;
}
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
case pbch:
LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
if (initial_sync( UE, UE->mode ) == 0) {
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti;
LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
hw_slot_offset,
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
UE->UE_scan_carrier );
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
// rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (freq_offset >= 0)
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
else
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
freq_offset=0;
}
// reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) {
case 6:
openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12;
break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6;
break;
case 50:
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
// openair0_cfg[0].rx_gain[0] -= 3;
break;
case 100:
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
UE->rfdevice.trx_stop_func(&UE->rfdevice);
sleep(1);
init_frame_parms(&UE->frame_parms,1);
if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
LOG_E(HW,"Could not start the device\n");
oai_exit=1;
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 1;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if( UE->mode == rx_dump_frame ) {
FILE *fd;
if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
} else {
LOG_E(PHY,"Cannot open file for writing\n");
exit(0);
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 0;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
}
}
}
} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
if (abs(freq_offset) > 7500) {
LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
FILE *fd;
if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
}
mac_xface->macphy_exit("No cell synchronization found, abandoning");
return &UE_thread_synch_retval; // not reached
}
}
LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
}// initial_sync=0
break;
case si:
default:
break;
} }
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
// indicate readiness
while (oai_exit==0) { UE->proc.instance_cnt_synch--;
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
while (UE->proc.instance_cnt_synch < 0)
// the thread waits here most of the time VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); } // while !oai_exit
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
return &UE_thread_synch_retval;
switch (sync_mode) {
case pss:
LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
current_offset += 20000000; // increase by 20 MHz
if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
current_band++;
current_offset=0;
}
if (current_band==bands_to_scan.nbands) {
current_band=0;
oai_exit=1;
}
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
if (UE->UE_scan_carrier) {
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
}
break;
case pbch:
LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
if (initial_sync( UE, UE->mode ) == 0) {
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti;
LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
hw_slot_offset,
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
UE->UE_scan_carrier );
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
// rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (freq_offset >= 0)
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
else
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
freq_offset=0;
}
// reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) {
case 6:
openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
// openair0_cfg[0].rx_gain[0] -= 12;
break;
case 25:
openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
// openair0_cfg[0].rx_gain[0] -= 6;
break;
case 50:
openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
// openair0_cfg[0].rx_gain[0] -= 3;
break;
case 100:
openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
UE->rfdevice.trx_stop_func(&UE->rfdevice);
sleep(1);
init_frame_parms(&UE->frame_parms,1);
if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
LOG_E(HW,"Could not start the device\n");
oai_exit=1;
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 1;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if( UE->mode == rx_dump_frame ) {
FILE *fd;
if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
} else {
LOG_E(PHY,"Cannot open file for writing\n");
exit(0);
}
} else {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
UE->is_synchronized = 0;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
}
}
}
} else {
// initial sync failed
// calculate new offset and try again
if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
if (abs(freq_offset) > 7500) {
LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
FILE *fd;
if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
fwrite((void*)&UE->common_vars.rxdata[0][0],
sizeof(int32_t),
10*UE->frame_parms.samples_per_tti,
fd);
LOG_I(PHY,"Dummping Frame ... bye bye \n");
fclose(fd);
exit(0);
}
mac_xface->macphy_exit("No cell synchronization found, abandoning");
return &UE_thread_synch_retval; // not reached
}
}
LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
freq_offset,
UE->rx_total_gain_dB,
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
}
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
}// initial_sync=0
break;
case si:
default:
break;
}
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
// indicate readiness
UE->proc.instance_cnt_synch--;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
} // while !oai_exit
return &UE_thread_synch_retval;
} }
...@@ -475,126 +475,126 @@ struct rx_tx_thread_data { ...@@ -475,126 +475,126 @@ struct rx_tx_thread_data {
*/ */
static void *UE_thread_rxn_txnp4(void *arg) { static void *UE_thread_rxn_txnp4(void *arg) {
static __thread int UE_thread_rxtx_retval; static __thread int UE_thread_rxtx_retval;
struct rx_tx_thread_data *rtd = arg; struct rx_tx_thread_data *rtd = arg;
UE_rxtx_proc_t *proc = rtd->proc; UE_rxtx_proc_t *proc = rtd->proc;
PHY_VARS_UE *UE = rtd->UE; PHY_VARS_UE *UE = rtd->UE;
int ret; int ret;
proc->instance_cnt_rxtx=-1; proc->instance_cnt_rxtx=-1;
proc->subframe_rx=proc->sub_frame_start; proc->subframe_rx=proc->sub_frame_start;
char threadname[256]; char threadname[256];
sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
cpu_set_t cpuset; cpu_set_t cpuset;
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 ) if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 )
CPU_SET(threads.even, &cpuset); CPU_SET(threads.even, &cpuset);
if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 ) if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 )
CPU_SET(threads.odd, &cpuset); CPU_SET(threads.odd, &cpuset);
init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
threadname); threadname);
while (!oai_exit) { while (!oai_exit) {
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
} }
while (proc->instance_cnt_rxtx < 0) { while (proc->instance_cnt_rxtx < 0) {
// most of the time, the thread is waiting here // most of the time, the thread is waiting here
pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
}
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
exit_fun("nothing to add");
}
initRefTimes(t2);
initRefTimes(t3);
pickTime(current);
updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");
// Process Rx data for one sub-frame
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
if ((sf_type == SF_DL) ||
(UE->frame_parms.frame_type == FDD) ||
(sf_type == SF_S)) {
if (UE->frame_parms.frame_type == TDD) {
LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
threadname,
UE->frame_parms.tdd_config,
(sf_type==SF_DL? "SF_DL" :
(sf_type==SF_UL? "SF_UL" :
(sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
} else {
LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
threadname,
(UE->frame_parms.frame_type==FDD? "FDD":
(UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
(sf_type==SF_DL? "SF_DL" :
(sf_type==SF_UL? "SF_UL" :
(sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
}
phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
}
if (UE->mac_enabled==1) {
ret = mac_xface->ue_scheduler(UE->Mod_id,
proc->frame_rx,
proc->subframe_rx,
proc->frame_tx,
proc->subframe_tx,
subframe_select(&UE->frame_parms,proc->subframe_tx),
0,
0/*FIXME CC_id*/);
if ( ret != CONNECTION_OK) {
char *txt;
switch (ret) {
case CONNECTION_LOST:
txt="RRC Connection lost, returning to PRACH";
break;
case PHY_RESYNCH:
txt="RRC Connection lost, trying to resynch";
break;
case RESYNCH:
txt="return to PRACH and perform a contention-free access";
break;
default:
txt="UNKNOWN RETURN CODE";
};
LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt );
}
}
// Prepare the future Tx data
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
if (UE->mode != loop_through_memory)
phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
(UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
proc->instance_cnt_rxtx--;
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
} }
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
exit_fun("nothing to add");
}
initRefTimes(t2);
initRefTimes(t3);
pickTime(current);
updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");
// Process Rx data for one sub-frame
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
if ((sf_type == SF_DL) ||
(UE->frame_parms.frame_type == FDD) ||
(sf_type == SF_S)) {
if (UE->frame_parms.frame_type == TDD) {
LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
threadname,
UE->frame_parms.tdd_config,
(sf_type==SF_DL? "SF_DL" :
(sf_type==SF_UL? "SF_UL" :
(sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
} else {
LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
threadname,
(UE->frame_parms.frame_type==FDD? "FDD":
(UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
(sf_type==SF_DL? "SF_DL" :
(sf_type==SF_UL? "SF_UL" :
(sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
}
phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
}
if (UE->mac_enabled==1) {
ret = mac_xface->ue_scheduler(UE->Mod_id,
proc->frame_rx,
proc->subframe_rx,
proc->frame_tx,
proc->subframe_tx,
subframe_select(&UE->frame_parms,proc->subframe_tx),
0,
0/*FIXME CC_id*/);
if ( ret != CONNECTION_OK) {
char *txt;
switch (ret) {
case CONNECTION_LOST:
txt="RRC Connection lost, returning to PRACH";
break;
case PHY_RESYNCH:
txt="RRC Connection lost, trying to resynch";
break;
case RESYNCH:
txt="return to PRACH and perform a contention-free access";
break;
default:
txt="UNKNOWN RETURN CODE";
};
LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt );
}
}
// Prepare the future Tx data
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
if (UE->mode != loop_through_memory)
phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
(UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
proc->instance_cnt_rxtx--;
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
exit_fun("noting to add");
}
}
// thread finished // thread finished
free(arg); free(arg);
return &UE_thread_rxtx_retval; return &UE_thread_rxtx_retval;
} }
/*! /*!
...@@ -608,151 +608,77 @@ static void *UE_thread_rxn_txnp4(void *arg) { ...@@ -608,151 +608,77 @@ static void *UE_thread_rxn_txnp4(void *arg) {
*/ */
void *UE_thread(void *arg) { void *UE_thread(void *arg) {
<<<<<<< HEAD PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
static int UE_thread_retval;
PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
// int tx_enabled = 0; // int tx_enabled = 0;
unsigned int rxs,txs;
int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
openair0_timestamp timestamp,timestamp1; openair0_timestamp timestamp,timestamp1;
void* rxp[2], *txp[2]; void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
#ifdef NAS_UE
MessageDef *message_p;
#endif
int start_rx_stream = 0; int start_rx_stream = 0;
int rx_off_diff = 0;
int rx_correction_timer = 0;
int i; int i;
char threadname[128];
#ifdef DEADLINE_SCHEDULER
cpu_set_t cpuset;
struct sched_attr attr; CPU_ZERO(&cpuset);
unsigned int flags = 0; if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset);
attr.size = sizeof(attr); init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,
attr.sched_flags = 0; "UHD Threads");
attr.sched_nice = 0; if (oaisim_flag == 0)
attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = BBU_HOST;
// This creates a .5 ms reservation every 1ms sprintf(threadname, "Main UE %d", UE->Mod_id);
attr.sched_policy = SCHED_DEADLINE; pthread_setname_np(pthread_self(), threadname);
attr.sched_runtime = 500000; init_UE_threads(UE);
attr.sched_deadline = 500000;
attr.sched_period = 1000000;
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] main eNB thread: sched_setattr failed\n");
exit_fun("Nothing to add");
return &UE_thread_retval;
}
LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n",
(unsigned long)gettid(), sched_getcpu());
#else
struct sched_param sp;
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp);
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("waiting for sync (UE_thread)\n");
pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (UE_thread)\n");
while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex, waiting (UE_thread)\n");
printf("starting UE thread\n");
#ifdef NAS_UE #ifdef NAS_UE
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif #endif
int sub_frame=-1;
//int cumulated_shift=0;
while (!oai_exit) { while (!oai_exit) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
int instance_cnt_synch = UE->proc.instance_cnt_synch;
int is_synchronized = UE->is_synchronized;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if (UE->is_synchronized == 0) { if (is_synchronized == 0) {
if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
}
int instance_cnt_synch = UE->proc.instance_cnt_synch;
if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
}
if (instance_cnt_synch < 0) { // we can invoke the synch if (instance_cnt_synch < 0) { // we can invoke the synch
// grab 10 ms of signal and wakeup synch thread // grab 10 ms of signal and wakeup synch thread
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&rxdata[i][0]; rxp[i] = (void*)&UE->common_vars.rxdata[i][0];
if (UE->mode != loop_through_memory) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
UE->frame_parms.samples_per_tti*10,
UE->frame_parms.nb_antennas_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (rxs!=UE->frame_parms.samples_per_tti*10) {
LOG_E(PHY, "problem in rx 1! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti*10, rxs);
exit_fun("problem in rx 1");
return &UE_thread_retval;
}
}
if (UE->mode != loop_through_memory)
AssertFatal( UE->frame_parms.samples_per_tti*10 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
UE->frame_parms.samples_per_tti*10,
UE->frame_parms.nb_antennas_rx), "");
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
instance_cnt_synch = ++UE->proc.instance_cnt_synch; instance_cnt_synch = ++UE->proc.instance_cnt_synch;
if (instance_cnt_synch == 0) { if (instance_cnt_synch == 0) {
if (pthread_cond_signal(&UE->proc.cond_synch) != 0) { AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" );
exit_fun("nothing to add");
return &UE_thread_retval;
}
} else { } else {
LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
exit_fun("nothing to add"); exit_fun("nothing to add");
return &UE_thread_retval;
} }
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
} // } else {
else {
// grab 10 ms of signal into dummy buffer // grab 10 ms of signal into dummy buffer
if (UE->mode != loop_through_memory) { if (UE->mode != loop_through_memory) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&dummy_rx[i][0]; rxp[i] = (void*)&dummy_rx[i][0];
for (int sf=0;sf<10;sf++) { for (int sf=0; sf<10; sf++)
// printf("Reading dummy sf %d\n",sf); // printf("Reading dummy sf %d\n",sf);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, rxp,
&timestamp, UE->frame_parms.samples_per_tti,
rxp, UE->frame_parms.nb_antennas_rx);
UE->frame_parms.samples_per_tti,
UE->frame_parms.nb_antennas_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (rxs!=UE->frame_parms.samples_per_tti){
LOG_E(PHY, "problem in rx 2! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs);
exit_fun("problem in rx 2");
return &UE_thread_retval;
}
}
} }
} }
...@@ -761,532 +687,141 @@ void *UE_thread(void *arg) { ...@@ -761,532 +687,141 @@ void *UE_thread(void *arg) {
if (start_rx_stream==0) { if (start_rx_stream==0) {
start_rx_stream=1; start_rx_stream=1;
if (UE->mode != loop_through_memory) { if (UE->mode != loop_through_memory) {
if (UE->no_timing_correction==0) { if (UE->no_timing_correction==0) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, AssertFatal(UE->rx_offset ==
&timestamp, UE->rfdevice.trx_read_func(&UE->rfdevice,
(void**)rxdata, &timestamp,
UE->rx_offset, (void**)UE->common_vars.rxdata,
UE->frame_parms.nb_antennas_rx); UE->rx_offset,
if (rxs != UE->rx_offset) { UE->frame_parms.nb_antennas_rx),"");
LOG_E(PHY, "problem in rx 3! want #samples=%d but got only %d!\n", UE->rx_offset, rxs);
exit_fun("problem in rx 3!");
return &UE_thread_retval;
}
} }
UE->rx_offset=0; UE->rx_offset=0;
UE->proc.proc_rxtx[0].frame_rx++; UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++; UE->proc.proc_rxtx[1].frame_rx++;
// read in first symbol // read in first symbol
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp, &timestamp,
(void**)rxdata, (void**)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx); UE->frame_parms.nb_antennas_rx),"");
slot_fep(UE,0, 0, 0, 0, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (rxs != (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0)) {
LOG_E(PHY, "problem in rx 4! want #samples=%d but got only %d!\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, rxs);
exit_fun("problem in rx 4!");
return &UE_thread_retval;
}
slot_fep(UE,
0,
0,
0,
0,
0);
if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) {
exit_fun("problem in rx");
return &UE_thread_retval;
}
} //UE->mode != loop_through_memory } //UE->mode != loop_through_memory
else else
rt_sleep_ns(1000000); rt_sleep_ns(1000*1000);
}// start_rx_stream==0
else {
//UE->proc.proc_rxtx[0].frame_rx++;
//UE->proc.proc_rxtx[1].frame_rx++;
for (int sf=0;sf<10;sf++) { } else {
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) sub_frame++;
rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)]; sub_frame%=10;
// grab signal for subframe UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1];
if (UE->mode != loop_through_memory) { if (UE->mode != loop_through_memory) {
if (sf<9) { for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, UE->frame_parms.nb_prefix_samples0+
&timestamp, sub_frame*UE->frame_parms.samples_per_tti];
rxp, for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
UE->frame_parms.samples_per_tti, txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
UE->frame_parms.nb_antennas_rx);
int readBlockSize, writeBlockSize;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); if (sub_frame<9) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); readBlockSize=UE->frame_parms.samples_per_tti;
if (rxs != UE->frame_parms.samples_per_tti) { writeBlockSize=UE->frame_parms.samples_per_tti;
LOG_E(PHY, "problem in rx 5! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); } else {
exit_fun("problem in rx 5!"); // set TO compensation to zero
return &UE_thread_retval; UE->rx_offset_diff = 0;
} // compute TO compensation that should be applied for this frame
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti &&
// prepare tx buffer pointers UE->rx_offset > 0 )
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) UE->rx_offset_diff = -1 ;
txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); UE->rx_offset_diff = 1;
txs = UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(2*UE->frame_parms.samples_per_tti) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
UE->frame_parms.samples_per_tti,
UE->frame_parms.nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs );
if (txs != UE->frame_parms.samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti);
exit_fun( "problem transmitting samples" );
}
}
else { LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); readBlockSize=UE->frame_parms.samples_per_tti -
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, UE->frame_parms.ofdm_symbol_size -
&timestamp, UE->frame_parms.nb_prefix_samples0 -
rxp, UE->rx_offset_diff;
UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, writeBlockSize=UE->frame_parms.samples_per_tti -
UE->frame_parms.nb_antennas_rx); UE->rx_offset_diff;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs );
if (rxs != (UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0)) {
LOG_E(PHY, "problem in rx 6! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, rxs);
exit_fun("problem in rx 6!");
return &UE_thread_retval;
}
// prepare tx buffer pointers
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 1 );
txs = UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(2*UE->frame_parms.samples_per_tti) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
UE->frame_parms.samples_per_tti - rx_off_diff,
UE->frame_parms.nb_antennas_tx,
1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs );
if (txs != UE->frame_parms.samples_per_tti - rx_off_diff) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti-rx_off_diff);
exit_fun( "problem transmitting samples" );
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 );
// read in first symbol of next frame and adjust for timing drift
rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp1,
(void**)rxdata,
UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff,
UE->frame_parms.nb_antennas_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs );
if (rxs != (UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff)) {
LOG_E(PHY, "problem in rx 7! want #samples=%d but got only %d! rx_off_diff=%d\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff, rxs, rx_off_diff);
exit_fun("problem in rx 7!");
return &UE_thread_retval;
}
rx_off_diff = 0;
}
} }
// operate on thread sf mod 2
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sf&1]; AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 1 ); &timestamp,
// lock mutex rxp,
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { readBlockSize,
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); UE->frame_parms.nb_antennas_rx),"");
exit_fun("nothing to add"); AssertFatal( writeBlockSize ==
return &UE_thread_retval; UE->rfdevice.trx_write_func(&UE->rfdevice,
} timestamp+
// increment instance count and change proc subframe/frame variables (2*UE->frame_parms.samples_per_tti) -
int instance_cnt_rxtx = ++proc->instance_cnt_rxtx; UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
if(sf == 0) openair0_cfg[0].tx_sample_advance,
{ txp,
UE->proc.proc_rxtx[0].frame_rx++; writeBlockSize,
UE->proc.proc_rxtx[1].frame_rx++; UE->frame_parms.nb_antennas_tx,
} 1),"");
proc->subframe_rx=sf; if( sub_frame==9) {
proc->subframe_tx=(sf+4)%10; // read in first symbol of next frame and adjust for timing drift
proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0); int first_symbols=writeBlockSize-readBlockSize;
proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; if ( first_symbols > 0 )
AssertFatal(first_symbols ==
/* UE->rfdevice.trx_read_func(&UE->rfdevice,
if (sf != (timestamp/UE->frame_parms.samples_per_tti)%10) { &timestamp1,
LOG_E(PHY,"steady-state UE_thread error : frame_rx %d, subframe_rx %d, frame_tx %d, subframe_tx %d, rx subframe %d\n",proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,(timestamp/UE->frame_parms.samples_per_tti)%10); (void**)UE->common_vars.rxdata,
exit(-1); first_symbols,
UE->frame_parms.nb_antennas_rx),"");
if ( first_symbols <0 )
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
} }
*/ pickTime(gotIQs);
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { // operate on thread sf mod 2
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" ); AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
exit_fun("nothing to add"); if(sub_frame == 0) {
return &UE_thread_retval; UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 0 ); UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
proc->subframe_rx=sub_frame;
if (instance_cnt_rxtx == 0) { proc->subframe_tx=(sub_frame+4)%10;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 1 ); proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
proc->timestamp_tx = timestamp+
(4*UE->frame_parms.samples_per_tti)-
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
proc->instance_cnt_rxtx++;
if (proc->instance_cnt_rxtx == 0) {
if (pthread_cond_signal(&proc->cond_rxtx) != 0) { if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
exit_fun("nothing to add"); exit_fun("nothing to add");
return &UE_thread_retval;
} }
LOG_D(PHY, "firing up rxtx_thread[%d] at subframe %d\n", sf&1, sf);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 0 );
} else { } else {
LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rxtx); LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
if (instance_cnt_rxtx > 2) { if (proc->instance_cnt_rxtx > 2)
sleep(1);
exit_fun("instance_cnt_rxtx > 2"); exit_fun("instance_cnt_rxtx > 2");
return &UE_thread_retval;
}
}
if (UE->mode == loop_through_memory) {
printf("Processing subframe %d",proc->subframe_rx);
getchar();
} }
}// for sf=0..10
if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) &&
(UE->rx_offset > RX_OFF_MIN) &&
(rx_correction_timer == 0)) {
rx_off_diff = -UE->rx_offset + RX_OFF_MIN;
LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff);
rx_correction_timer = 5;
} else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) &&
(UE->rx_offset < ((10*UE->frame_parms.samples_per_tti)-RX_OFF_MIN)) &&
(rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples
rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset;
LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,10*UE->frame_parms.samples_per_tti-RX_OFF_MIN,rx_off_diff);
rx_correction_timer = 5; AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
initRefTimes(t1);
initStaticTime(lastTime);
updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
pickStaticTime(lastTime);
} else {
printf("Processing subframe %d",proc->subframe_rx);
getchar();
} }
if (rx_correction_timer>0)
rx_correction_timer--;
} // start_rx_stream==1 } // start_rx_stream==1
} // UE->is_synchronized==1 } // UE->is_synchronized==1
} // while !oai_exit } // while !oai_exit
return NULL; return NULL;
} // UE_thread
/*
void *UE_thread_old(void *arg)
{
UNUSED(arg)
static int UE_thread_retval;
PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
int spp = openair0_cfg[0].samples_per_packet;
int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=openair0_cfg[0].tx_scheduling_advance;
#ifdef __AVX2__
int dummy[2][spp] __attribute__((aligned(32)));
#else
int dummy[2][spp] __attribute__((aligned(16)));
#endif
int dummy_dump = 0;
int tx_enabled = 0;
int start_rx_stream = 0;
int rx_off_diff = 0;
int rx_correction_timer = 0;
int first_rx = 0;
RTIME T0;
unsigned int rxs;
void* rxp[2];
openair0_timestamp timestamp;
#ifdef NAS_UE
MessageDef *message_p;
#endif
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE);
// This creates a .5 ms reservation
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 100000;
attr.sched_deadline = 500000;
attr.sched_period = 500000;
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] main eNB thread: sched_setattr failed\n");
exit_fun("Nothing to add");
return &UE_thread_retval;
}
LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n",
(unsigned long)gettid(), sched_getcpu());
#else
struct sched_param sp;
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp);
#endif
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("waiting for sync (UE_thread)\n");
pthread_mutex_lock(&sync_mutex);
printf("Locked sync_mutex, waiting (UE_thread)\n");
while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
printf("unlocked sync_mutex, waiting (UE_thread)\n");
printf("starting UE thread\n");
=======
PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
// int tx_enabled = 0;
int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
openair0_timestamp timestamp,timestamp1;
void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
int start_rx_stream = 0;
int i;
char threadname[128];
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset);
init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,
"UHD Threads");
if (oaisim_flag == 0)
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = BBU_HOST;
sprintf(threadname, "Main UE %d", UE->Mod_id);
pthread_setname_np(pthread_self(), threadname);
init_UE_threads(UE);
>>>>>>> origin/develop
#ifdef NAS_UE
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif
int sub_frame=-1;
//int cumulated_shift=0;
while (!oai_exit) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
int instance_cnt_synch = UE->proc.instance_cnt_synch;
int is_synchronized = UE->is_synchronized;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
if (is_synchronized == 0) {
if (instance_cnt_synch < 0) { // we can invoke the synch
// grab 10 ms of signal and wakeup synch thread
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&UE->common_vars.rxdata[i][0];
if (UE->mode != loop_through_memory)
AssertFatal( UE->frame_parms.samples_per_tti*10 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
UE->frame_parms.samples_per_tti*10,
UE->frame_parms.nb_antennas_rx), "");
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
instance_cnt_synch = ++UE->proc.instance_cnt_synch;
if (instance_cnt_synch == 0) {
AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
} else {
LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
exit_fun("nothing to add");
}
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
} else {
// grab 10 ms of signal into dummy buffer
if (UE->mode != loop_through_memory) {
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&dummy_rx[i][0];
for (int sf=0; sf<10; sf++)
// printf("Reading dummy sf %d\n",sf);
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
UE->frame_parms.samples_per_tti,
UE->frame_parms.nb_antennas_rx);
}
}
} // UE->is_synchronized==0
else {
if (start_rx_stream==0) {
start_rx_stream=1;
if (UE->mode != loop_through_memory) {
if (UE->no_timing_correction==0) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
AssertFatal(UE->rx_offset ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.rxdata,
UE->rx_offset,
UE->frame_parms.nb_antennas_rx),"");
}
UE->rx_offset=0;
UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++;
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void**)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx),"");
slot_fep(UE,0, 0, 0, 0, 0);
} //UE->mode != loop_through_memory
else
rt_sleep_ns(1000*1000);
} else {
sub_frame++;
sub_frame%=10;
UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1];
if (UE->mode != loop_through_memory) {
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
UE->frame_parms.nb_prefix_samples0+
sub_frame*UE->frame_parms.samples_per_tti];
for (i=0; i<UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
int readBlockSize, writeBlockSize;
if (sub_frame<9) {
readBlockSize=UE->frame_parms.samples_per_tti;
writeBlockSize=UE->frame_parms.samples_per_tti;
} else {
// set TO compensation to zero
UE->rx_offset_diff = 0;
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti &&
UE->rx_offset > 0 )
UE->rx_offset_diff = -1 ;
if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
UE->rx_offset_diff = 1;
LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
readBlockSize=UE->frame_parms.samples_per_tti -
UE->frame_parms.ofdm_symbol_size -
UE->frame_parms.nb_prefix_samples0 -
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.samples_per_tti -
UE->rx_offset_diff;
}
AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(2*UE->frame_parms.samples_per_tti) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
1),"");
if( sub_frame==9) {
// read in first symbol of next frame and adjust for timing drift
int first_symbols=writeBlockSize-readBlockSize;
if ( first_symbols > 0 )
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp1,
(void**)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
if ( first_symbols <0 )
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
pickTime(gotIQs);
// operate on thread sf mod 2
AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
if(sub_frame == 0) {
UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++;
}
UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
proc->subframe_rx=sub_frame;
proc->subframe_tx=(sub_frame+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
proc->timestamp_tx = timestamp+
(4*UE->frame_parms.samples_per_tti)-
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
proc->instance_cnt_rxtx++;
if (proc->instance_cnt_rxtx == 0) {
if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
exit_fun("nothing to add");
}
} else {
LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
if (proc->instance_cnt_rxtx > 2)
exit_fun("instance_cnt_rxtx > 2");
}
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
initRefTimes(t1);
initStaticTime(lastTime);
updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
pickStaticTime(lastTime);
} else {
printf("Processing subframe %d",proc->subframe_rx);
getchar();
}
} // start_rx_stream==1
} // UE->is_synchronized==1
} // while !oai_exit
return NULL;
} }
/*! /*!
...@@ -1298,99 +833,99 @@ void *UE_thread_old(void *arg) ...@@ -1298,99 +833,99 @@ void *UE_thread_old(void *arg)
* and the locking between them. * and the locking between them.
*/ */
void init_UE_threads(PHY_VARS_UE *UE) { void init_UE_threads(PHY_VARS_UE *UE) {
struct rx_tx_thread_data *rtd; struct rx_tx_thread_data *rtd;
pthread_attr_init (&UE->proc.attr_ue); pthread_attr_init (&UE->proc.attr_ue);
pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
pthread_mutex_init(&UE->proc.mutex_synch,NULL); pthread_mutex_init(&UE->proc.mutex_synch,NULL);
pthread_cond_init(&UE->proc.cond_synch,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL);
// the threads are not yet active, therefore access is allowed without locking // the threads are not yet active, therefore access is allowed without locking
int nb_threads=2; int nb_threads=2;
for (int i=0; i<nb_threads; i++) { for (int i=0; i<nb_threads; i++) {
rtd = calloc(1, sizeof(struct rx_tx_thread_data)); rtd = calloc(1, sizeof(struct rx_tx_thread_data));
if (rtd == NULL) abort(); if (rtd == NULL) abort();
rtd->UE = UE; rtd->UE = UE;
rtd->proc = &UE->proc.proc_rxtx[i]; rtd->proc = &UE->proc.proc_rxtx[i];
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_start=i;
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
} }
pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
} }
#ifdef OPENAIR2 #ifdef OPENAIR2
void fill_ue_band_info(void) { void fill_ue_band_info(void) {
UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
int i,j; int i,j;
bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
for (i=0; i<bands_to_scan.nbands; i++) { for (i=0; i<bands_to_scan.nbands; i++) {
for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++)
if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) {
memcpy(&bands_to_scan.band_info[i], memcpy(&bands_to_scan.band_info[i],
&eutra_bands[j], &eutra_bands[j],
sizeof(eutra_band_t)); sizeof(eutra_band_t));
printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
bands_to_scan.band_info[i].band, bands_to_scan.band_info[i].band,
UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
bands_to_scan.band_info[i].dl_min, bands_to_scan.band_info[i].dl_min,
bands_to_scan.band_info[i].dl_max, bands_to_scan.band_info[i].dl_max,
bands_to_scan.band_info[i].ul_min, bands_to_scan.band_info[i].ul_min,
bands_to_scan.band_info[i].ul_max, bands_to_scan.band_info[i].ul_max,
(bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
break; break;
} }
} }
} }
#endif #endif
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) {
int i, CC_id;
LTE_DL_FRAME_PARMS *frame_parms;
openair0_rf_map *rf_map;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
rf_map = &phy_vars_ue[CC_id]->rf_map;
AssertFatal( phy_vars_ue[CC_id] !=0, "");
frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
// replace RX signal buffers with mmaped HW versions
rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
}
int i, CC_id; for (i=0; i<frame_parms->nb_antennas_tx; i++) {
LTE_DL_FRAME_PARMS *frame_parms; LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
openair0_rf_map *rf_map; CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
rf_map = &phy_vars_ue[CC_id]->rf_map; phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
AssertFatal( phy_vars_ue[CC_id] !=0, "");
frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
// replace RX signal buffers with mmaped HW versions
rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
}
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
}
// rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
// txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x]
// be careful when releasing memory!
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
} }
return 0;
// rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
// txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x]
// be careful when releasing memory!
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
}
return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment