Commit 08d89933 authored by Raymond Knopp's avatar Raymond Knopp

expressmimo TX ok.

parent 6d51052e
...@@ -2562,8 +2562,14 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl ...@@ -2562,8 +2562,14 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
AssertFatal(proc->subframe_rx == subframe, "Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)",proc->subframe_rx,subframe); if (proc->subframe_rx != subframe){
AssertFatal(proc->frame_rx == frame, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)",proc->frame_rx,frame); LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
exit_fun("Exiting");
}
if (proc->frame_rx != frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
exit_fun("Exiting");
}
} else { } else {
proc->first_rx = 0; proc->first_rx = 0;
} }
......
...@@ -158,6 +158,10 @@ typedef struct { ...@@ -158,6 +158,10 @@ typedef struct {
int rx_num_channels; int rx_num_channels;
//! number of TX channels (=TX antennas) //! number of TX channels (=TX antennas)
int tx_num_channels; int tx_num_channels;
//! \brief RX base addresses for mmapped_dma
int32_t* rxbase[4];
//! \brief TX base addresses for mmapped_dma
int32_t* txbase[4];
//! \brief Center frequency in Hz for RX. //! \brief Center frequency in Hz for RX.
//! index: [0..rx_num_channels[ //! index: [0..rx_num_channels[
double rx_freq[4]; double rx_freq[4];
......
...@@ -64,7 +64,10 @@ ...@@ -64,7 +64,10 @@
#include <pthread.h> #include <pthread.h>
#define max(a,b) ((a)>(b) ? (a) : (b)) #define max(a,b) ((a)>(b) ? (a) : (b))
exmimo_pci_interface_bot_virtual_t openair0_exmimo_pci[MAX_CARDS]; // contains userspace pointers for each card exmimo_pci_interface_bot_virtual_t openair0_exmimo_pci[MAX_CARDS]; // contains userspace pointers for each card
char *bigshm_top[MAX_CARDS] = INIT_ZEROS; char *bigshm_top[MAX_CARDS] = INIT_ZEROS;
...@@ -90,6 +93,7 @@ extern volatile int oai_exit; ...@@ -90,6 +93,7 @@ extern volatile int oai_exit;
void kill_watchdog(openair0_device *); void kill_watchdog(openair0_device *);
void create_watchdog(openair0_device *); void create_watchdog(openair0_device *);
void rt_sleep(struct timespec *,long );
unsigned int log2_int( unsigned int x ) unsigned int log2_int( unsigned int x )
{ {
...@@ -272,6 +276,20 @@ int openair0_stop_without_reset(int card) ...@@ -272,6 +276,20 @@ int openair0_stop_without_reset(int card)
#define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX) #define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
#define RF_MODE_BASE (LNA1ON + RFBBNORM) #define RF_MODE_BASE (LNA1ON + RFBBNORM)
void rt_sleep(struct timespec *ts,long tv_nsec) {
clock_gettime(CLOCK_MONOTONIC, ts);
ts->tv_nsec += tv_nsec;
if (ts->tv_nsec>=1000000000L) {
ts->tv_nsec -= 1000000000L;
ts->tv_sec++;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
}
static void *watchdog_thread(void *arg) { static void *watchdog_thread(void *arg) {
int policy, s, j; int policy, s, j;
...@@ -284,6 +302,11 @@ static void *watchdog_thread(void *arg) { ...@@ -284,6 +302,11 @@ static void *watchdog_thread(void *arg) {
volatile unsigned int *daq_mbox = openair0_daq_cnt(); volatile unsigned int *daq_mbox = openair0_daq_cnt();
unsigned int mbox,diff; unsigned int mbox,diff;
int first_acquisition; int first_acquisition;
struct timespec sleep_time,wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
/* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* Set affinity mask to include CPUs 1 to MAX_CPUS */
/* CPU 0 is reserved for UHD threads */ /* CPU 0 is reserved for UHD threads */
...@@ -388,6 +411,8 @@ static void *watchdog_thread(void *arg) { ...@@ -388,6 +411,8 @@ static void *watchdog_thread(void *arg) {
first_acquisition=1; first_acquisition=1;
// main loop to keep up with DMA transfers from exmimo2 // main loop to keep up with DMA transfers from exmimo2
int cnt_diff0=0;
while ((!oai_exit) && (!exm->watchdog_exit)) { while ((!oai_exit) && (!exm->watchdog_exit)) {
if (exm->daq_state == running) { if (exm->daq_state == running) {
...@@ -403,7 +428,7 @@ static void *watchdog_thread(void *arg) { ...@@ -403,7 +428,7 @@ static void *watchdog_thread(void *arg) {
} }
exm->last_mbox = mbox; exm->last_mbox = mbox;
pthread_mutex_lock(&exm->watchdog_mutex); pthread_mutex_timedlock(&exm->watchdog_mutex,&wait);
exm->ts += (diff*exm->samples_per_frame/150) ; exm->ts += (diff*exm->samples_per_frame/150) ;
if (first_acquisition==1) //set last read to a closest subframe boundary if (first_acquisition==1) //set last read to a closest subframe boundary
...@@ -416,9 +441,14 @@ static void *watchdog_thread(void *arg) { ...@@ -416,9 +441,14 @@ static void *watchdog_thread(void *arg) {
first_acquisition=0; first_acquisition=0;
if (diff == 0) { if (diff == 0) {
cnt_diff0++;
if (cnt_diff0 == 10) {
exm->watchdog_exit = 1; exm->watchdog_exit = 1;
printf("exiting, HW stopped\n"); printf("exiting, HW stopped\n");
} }
}
else
cnt_diff0=0;
if (exm->ts - exm->last_ts_rx > exm->samples_per_frame) { if (exm->ts - exm->last_ts_rx > exm->samples_per_frame) {
exm->watchdog_exit = 1; exm->watchdog_exit = 1;
...@@ -427,12 +457,11 @@ static void *watchdog_thread(void *arg) { ...@@ -427,12 +457,11 @@ static void *watchdog_thread(void *arg) {
// printf("ts %lu, last_ts_rx %lu, mbox %d, diff %d\n",exm->ts, exm->last_ts_rx,mbox,diff); // printf("ts %lu, last_ts_rx %lu, mbox %d, diff %d\n",exm->ts, exm->last_ts_rx,mbox,diff);
pthread_mutex_unlock(&exm->watchdog_mutex); pthread_mutex_unlock(&exm->watchdog_mutex);
} }
rt_sleep(&sleep_time,250000L);
usleep(500); // sleep for 500us
} }
oai_exit=1; oai_exit=1;
printf("Exiting watchdog\n");
return NULL; return NULL;
} }
...@@ -473,13 +502,23 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi ...@@ -473,13 +502,23 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
exmimo_state_t *exm=device->priv; exmimo_state_t *exm=device->priv;
openair0_config_t *cfg=&device->openair0_cfg[0]; openair0_config_t *cfg=&device->openair0_cfg[0];
openair0_timestamp ts,diff; openair0_timestamp old_ts=0,ts,diff;
struct timespec sleep_time;
unsigned long tv_nsec;
// int i; // int i;
struct timespec wait;
pthread_mutex_lock(&exm->watchdog_mutex); wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (exm->watchdog_exit == 1)
return(0);
pthread_mutex_timedlock(&exm->watchdog_mutex,&wait);
ts = exm->ts; ts = exm->ts;
pthread_mutex_unlock(&exm->watchdog_mutex); pthread_mutex_unlock(&exm->watchdog_mutex);
while (ts < exm->last_ts_rx + nsamps) { while ((ts < exm->last_ts_rx + nsamps) &&
(exm->watchdog_exit==0)) {
diff = exm->last_ts_rx+nsamps - ts; // difference in samples between current timestamp and last RX received sample diff = exm->last_ts_rx+nsamps - ts; // difference in samples between current timestamp and last RX received sample
// go to sleep until we should have enough samples (1024 for a bit more) // go to sleep until we should have enough samples (1024 for a bit more)
...@@ -487,14 +526,21 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi ...@@ -487,14 +526,21 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
printf("Reading %d samples, ts %lu, last_ts_rx %lu (%lu) => sleeping %u us\n",nsamps,ts,exm->last_ts_rx,exm->last_ts_rx+nsamps, printf("Reading %d samples, ts %lu, last_ts_rx %lu (%lu) => sleeping %u us\n",nsamps,ts,exm->last_ts_rx,exm->last_ts_rx+nsamps,
(unsigned int)((double)(diff+1024)*1e6/cfg->sample_rate)); (unsigned int)((double)(diff+1024)*1e6/cfg->sample_rate));
#endif #endif
usleep((unsigned int)((double)(diff+1024)*1e6/cfg->sample_rate)); tv_nsec=(unsigned long)((double)(diff+3840)*1e9/cfg->sample_rate);
// tv_nsec = 500000L;
old_ts = ts;
rt_sleep(&sleep_time,tv_nsec);
#ifdef DEBUG_EXMIMO #ifdef DEBUG_EXMIMO
printf("back\n"); printf("back\n");
#endif #endif
// get new timestamp, in case we have to sleep again // get new timestamp, in case we have to sleep again
pthread_mutex_lock(&exm->watchdog_mutex); pthread_mutex_timedlock(&exm->watchdog_mutex,&wait);
ts = exm->ts; ts = exm->ts;
pthread_mutex_unlock(&exm->watchdog_mutex); pthread_mutex_unlock(&exm->watchdog_mutex);
if (old_ts == ts) {
printf("ts stopped, returning\n");
return(0);
}
} }
/* /*
...@@ -511,6 +557,7 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi ...@@ -511,6 +557,7 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
*ptimestamp=exm->last_ts_rx; *ptimestamp=exm->last_ts_rx;
exm->last_ts_rx += nsamps; exm->last_ts_rx += nsamps;
return(nsamps); return(nsamps);
} }
...@@ -659,6 +706,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) ...@@ -659,6 +706,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
/* device specific */ /* device specific */
openair0_cfg[card].iq_txshift = 4;//shift openair0_cfg[card].iq_txshift = 4;//shift
openair0_cfg[card].iq_rxrescale = 15;//rescale iqs openair0_cfg[card].iq_rxrescale = 15;//rescale iqs
openair0_cfg[card].mmapped_dma = 1;
if (openair0_cfg[card].sample_rate==30.72e6) { if (openair0_cfg[card].sample_rate==30.72e6) {
resampling_factor = 0; resampling_factor = 0;
...@@ -690,6 +738,10 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) ...@@ -690,6 +738,10 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
#endif #endif
for (ant=0; ant<4; ant++) { for (ant=0; ant<4; ant++) {
openair0_cfg[card].rxbase[ant] = (int32_t*)openair0_exmimo_pci[card].adc_head[ant];
openair0_cfg[card].txbase[ant] = (int32_t*)openair0_exmimo_pci[card].dac_head[ant];
if (openair0_cfg[card].rx_freq[ant] || openair0_cfg[card].tx_freq[ant]) { if (openair0_cfg[card].rx_freq[ant] || openair0_cfg[card].tx_freq[ant]) {
ACTIVE_RF += (1<<ant)<<5; ACTIVE_RF += (1<<ant)<<5;
p_exmimo_config->rf.rf_mode[ant] = RF_MODE_BASE; p_exmimo_config->rf.rf_mode[ant] = RF_MODE_BASE;
...@@ -697,14 +749,14 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) ...@@ -697,14 +749,14 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
printf("card %d, antenna %d, autocal %d\n",card,ant,openair0_cfg[card].autocal[ant]); printf("card %d, antenna %d, autocal %d\n",card,ant,openair0_cfg[card].autocal[ant]);
} }
if (openair0_cfg[card].tx_freq[ant]) { if (openair0_cfg[card].tx_freq[ant]>0) {
p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX + TXLPFNORM + TXLPFEN + tx_filter); p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX + TXLPFNORM + TXLPFEN + tx_filter);
p_exmimo_config->rf.rf_freq_tx[ant] = (unsigned int)openair0_cfg[card].tx_freq[ant]; p_exmimo_config->rf.rf_freq_tx[ant] = (unsigned int)openair0_cfg[card].tx_freq[ant];
p_exmimo_config->rf.tx_gain[ant][0] = (unsigned int)openair0_cfg[card].tx_gain[ant]; p_exmimo_config->rf.tx_gain[ant][0] = (unsigned int)openair0_cfg[card].tx_gain[ant];
printf("openair0 : programming card %d TX antenna %d (freq %u, gain %d)\n",card,ant,p_exmimo_config->rf.rf_freq_tx[ant],p_exmimo_config->rf.tx_gain[ant][0]);
} }
if (openair0_cfg[card].rx_freq[ant]) { if (openair0_cfg[card].rx_freq[ant]>0) {
p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX + RXLPFNORM + RXLPFEN + rx_filter); p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX + RXLPFNORM + RXLPFEN + rx_filter);
p_exmimo_config->rf.rf_freq_rx[ant] = (unsigned int)openair0_cfg[card].rx_freq[ant]; p_exmimo_config->rf.rf_freq_rx[ant] = (unsigned int)openair0_cfg[card].rx_freq[ant];
...@@ -786,13 +838,14 @@ int openair0_reconfig(openair0_config_t *openair0_cfg) ...@@ -786,13 +838,14 @@ int openair0_reconfig(openair0_config_t *openair0_cfg)
if (openair0_cfg[card].tx_freq[ant]) { if (openair0_cfg[card].tx_freq[ant]) {
p_exmimo_config->rf.rf_freq_tx[ant] = (unsigned int)openair0_cfg[card].tx_freq[ant]; p_exmimo_config->rf.rf_freq_tx[ant] = (unsigned int)openair0_cfg[card].tx_freq[ant];
p_exmimo_config->rf.tx_gain[ant][0] = (unsigned int)openair0_cfg[card].tx_gain[ant]; p_exmimo_config->rf.tx_gain[ant][0] = (unsigned int)openair0_cfg[card].tx_gain[ant];
//printf("openair0 : programming TX antenna %d (freq %u, gain %d)\n",ant,p_exmimo_config->rf.rf_freq_tx[ant],p_exmimo_config->rf.tx_gain[ant][0]); printf("openair0 : programming TX antenna %d (freq %u, gain %d)\n",ant,p_exmimo_config->rf.rf_freq_tx[ant],p_exmimo_config->rf.tx_gain[ant][0]);
} }
if (openair0_cfg[card].rx_freq[ant]) { if (openair0_cfg[card].rx_freq[ant]) {
p_exmimo_config->rf.rf_freq_rx[ant] = (unsigned int)openair0_cfg[card].rx_freq[ant]; p_exmimo_config->rf.rf_freq_rx[ant] = (unsigned int)openair0_cfg[card].rx_freq[ant];
p_exmimo_config->rf.rx_gain[ant][0] = (unsigned int)openair0_cfg[card].rx_gain[ant]; p_exmimo_config->rf.rx_gain[ant][0] = (unsigned int)openair0_cfg[card].rx_gain[ant];
//printf("openair0 : programming RX antenna %d (freq %u, gain %d)\n",ant,p_exmimo_config->rf.rf_freq_rx[ant],p_exmimo_config->rf.rx_gain[ant][0]); printf("openair0 : programming RX antenna %d (freq %u, gain %d)\n",ant,p_exmimo_config->rf.rf_freq_rx[ant],p_exmimo_config->rf.rx_gain[ant][0]);
switch (openair0_cfg[card].rxg_mode[ant]) { switch (openair0_cfg[card].rxg_mode[ant]) {
default: default:
......
...@@ -337,6 +337,10 @@ static void* eNB_thread_rxtx( void* param ) { ...@@ -337,6 +337,10 @@ static void* eNB_thread_rxtx( void* param ) {
struct sched_param sparam; struct sched_param sparam;
char cpu_affinity[1024]; char cpu_affinity[1024];
cpu_set_t cpuset; cpu_set_t cpuset;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
/* Set affinity mask to include CPUs 1 to MAX_CPUS */ /* Set affinity mask to include CPUs 1 to MAX_CPUS */
/* CPU 0 is reserved for UHD threads */ /* CPU 0 is reserved for UHD threads */
...@@ -402,7 +406,7 @@ static void* eNB_thread_rxtx( void* param ) { ...@@ -402,7 +406,7 @@ static void* eNB_thread_rxtx( void* param ) {
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_timedlock(&proc->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB RXn-TXnp4\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB RXn-TXnp4\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
...@@ -442,7 +446,7 @@ static void* eNB_thread_rxtx( void* param ) { ...@@ -442,7 +446,7 @@ static void* eNB_thread_rxtx( void* param ) {
* (may be relaxed in the future for performance reasons) * (may be relaxed in the future for performance reasons)
*/ */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n"); LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
...@@ -569,9 +573,9 @@ static void* eNB_thread_rxtx( void* param ) { ...@@ -569,9 +573,9 @@ static void* eNB_thread_rxtx( void* param ) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
#ifdef DEBUG_THREADS
printf( "Exiting eNB thread TX\n"); printf( "Exiting eNB thread RXn_TXnp4\n");
#endif
eNB_thread_rxtx_status = 0; eNB_thread_rxtx_status = 0;
return &eNB_thread_rxtx_status; return &eNB_thread_rxtx_status;
...@@ -613,6 +617,10 @@ static void* eNB_thread_rx_common( void* param ) { ...@@ -613,6 +617,10 @@ static void* eNB_thread_rx_common( void* param ) {
FILE *rx_time_file = NULL; FILE *rx_time_file = NULL;
char rx_time_name[101]; char rx_time_name[101];
//int i; //int i;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (opp_enabled == 1) { if (opp_enabled == 1) {
snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB"); snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB");
...@@ -766,7 +774,7 @@ static void* eNB_thread_rx_common( void* param ) { ...@@ -766,7 +774,7 @@ static void* eNB_thread_rx_common( void* param ) {
// wake up TX for subframe n+4 // wake up TX for subframe n+4
// lock the TX mutex and make sure the thread is ready // lock the TX mutex and make sure the thread is ready
if (pthread_mutex_lock(&proc_rxtx->mutex_rxtx) != 0) { if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx ); LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx );
exit_fun( "error locking mutex_rxtx" ); exit_fun( "error locking mutex_rxtx" );
break; break;
...@@ -815,9 +823,9 @@ static void* eNB_thread_rx_common( void* param ) { ...@@ -815,9 +823,9 @@ static void* eNB_thread_rx_common( void* param ) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
} }
#ifdef DEBUG_THREADS
printf( "Exiting eNB thread RXn-TXnp4\n"); printf( "Exiting eNB thread rx_common\n");
#endif
eNB_thread_rx_status = 0; eNB_thread_rx_status = 0;
return &eNB_thread_rx_status; return &eNB_thread_rx_status;
...@@ -832,8 +840,16 @@ static void* eNB_thread_rx_common( void* param ) { ...@@ -832,8 +840,16 @@ static void* eNB_thread_rx_common( void* param ) {
static void* eNB_thread_prach( void* param ) { static void* eNB_thread_prach( void* param ) {
static int eNB_thread_prach_status; static int eNB_thread_prach_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id];
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
// set default return value // set default return value
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
...@@ -935,7 +951,7 @@ static void* eNB_thread_prach( void* param ) { ...@@ -935,7 +951,7 @@ static void* eNB_thread_prach( void* param ) {
if (oai_exit) break; if (oai_exit) break;
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_timedlock(&proc->mutex_prach,&wait) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
...@@ -957,7 +973,7 @@ static void* eNB_thread_prach( void* param ) { ...@@ -957,7 +973,7 @@ static void* eNB_thread_prach( void* param ) {
prach_procedures(eNB,0); prach_procedures(eNB,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_timedlock(&proc->mutex_prach,&wait) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
...@@ -972,9 +988,9 @@ static void* eNB_thread_prach( void* param ) { ...@@ -972,9 +988,9 @@ static void* eNB_thread_prach( void* param ) {
} }
} }
#ifdef DEBUG_THREADS
printf( "Exiting eNB thread PRACH\n"); printf( "Exiting eNB thread PRACH\n");
#endif
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
return &eNB_thread_prach_status; return &eNB_thread_prach_status;
...@@ -1083,16 +1099,17 @@ void kill_eNB_proc(void) { ...@@ -1083,16 +1099,17 @@ void kill_eNB_proc(void) {
proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race! proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race!
proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
proc->instance_cnt_prach = 0;
pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); pthread_cond_signal( &proc_rxtx[0].cond_rxtx );
pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); pthread_cond_signal( &proc_rxtx[1].cond_rxtx );
pthread_cond_signal( &proc->cond_prach );
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
#ifdef DEBUG_THREADS pthread_join( proc->pthread_rx, (void**)&status );
printf( "Joining eNB TX CC_id %d thread\n", CC_id);
#endif
int result,i; int result,i;
for (i=0;i<1;i++) { for (i=0;i<2;i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
...@@ -1151,6 +1168,7 @@ void kill_eNB_proc(void) { ...@@ -1151,6 +1168,7 @@ void kill_eNB_proc(void) {
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) { int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) {
int i, CC_id; int i, CC_id;
int j;
uint16_t N_TA_offset = 0; uint16_t N_TA_offset = 0;
...@@ -1174,25 +1192,17 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1174,25 +1192,17 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
N_TA_offset = 624/4; N_TA_offset = 624/4;
} }
/*
if (openair0_cfg[CC_id].mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
#ifdef EXMIMO
openair0_cfg[CC_id].tx_num_channels = 0;
openair0_cfg[CC_id].rx_num_channels = 0;
for (i=0; i<frame_parms->nb_antennas_rx; i++) { for (i=0; i<frame_parms->nb_antennas_rx; i++) {
printf("Mapping eNB CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i); printf("Mapping eNB CC_id %d, rx_ant %d\n",CC_id,i);
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].adc_head[rf_map[CC_id].chain+i]; phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[CC_id].rxbase[i];
if (openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i]) {
printf("Error with rf_map! A channel has already been allocated!\n");
return(-1);
} else {
openair0_cfg[rf_map[CC_id].card].rx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[rf_map[CC_id].card].rx_gain[rf_map[CC_id].chain+i] = rx_gain[CC_id][i];
openair0_cfg[rf_map[CC_id].card].rx_num_channels++;
}
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
...@@ -1203,18 +1213,9 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1203,18 +1213,9 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
} }
for (i=0; i<frame_parms->nb_antennas_tx; i++) { for (i=0; i<frame_parms->nb_antennas_tx; i++) {
printf("Mapping eNB CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",CC_id,i,downlink_frequency[CC_id][i],rf_map[CC_id].card,rf_map[CC_id].chain+i); printf("Mapping eNB CC_id %d, tx_ant %d\n",CC_id,i);
free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = (int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i]; phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[CC_id].txbase[i];//(int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i];
if (openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i]) {
printf("Error with rf_map! A channel has already been allocated!\n");
return(-1);
} else {
openair0_cfg[rf_map[CC_id].card].tx_freq[rf_map[CC_id].chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[rf_map[CC_id].card].tx_gain[rf_map[CC_id].chain+i] = tx_gain[CC_id][i];
openair0_cfg[rf_map[CC_id].card].tx_num_channels++;
}
printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
...@@ -1223,9 +1224,9 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1223,9 +1224,9 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16-j; phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16-j;
} }
} }
}
else { // not memory-mapped DMA
#else // not EXMIMO
*/
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*)); txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
...@@ -1246,6 +1247,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1246,6 +1247,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
} }
} }
}
return(0); return(0);
} }
......
...@@ -416,12 +416,21 @@ void help (void) { ...@@ -416,12 +416,21 @@ void help (void) {
void exit_fun(const char* s) void exit_fun(const char* s)
{ {
int CC_id;
if (s != NULL) { if (s != NULL) {
printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
} }
oai_exit = 1; oai_exit = 1;
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);
}
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
sleep(1); //allow lte-softmodem threads to exit first sleep(1); //allow lte-softmodem threads to exit first
itti_terminate_tasks (TASK_UNKNOWN); itti_terminate_tasks (TASK_UNKNOWN);
...@@ -1563,8 +1572,16 @@ int main( int argc, char **argv ) ...@@ -1563,8 +1572,16 @@ int main( int argc, char **argv )
for (i=0; i<4; i++) { for (i=0; i<4; i++) {
if (i<openair0_cfg[card].tx_num_channels)
openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i]; openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
else
openair0_cfg[card].tx_freq[i]=0.0;
if (i<openair0_cfg[card].rx_num_channels)
openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i]; openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
else
openair0_cfg[card].rx_freq[i]=0.0;
printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
card,i, openair0_cfg[card].tx_gain[i], card,i, openair0_cfg[card].tx_gain[i],
openair0_cfg[card].rx_gain[i], openair0_cfg[card].rx_gain[i],
...@@ -1953,9 +1970,13 @@ int main( int argc, char **argv ) ...@@ -1953,9 +1970,13 @@ int main( int argc, char **argv )
pthread_mutex_destroy(&sync_mutex); pthread_mutex_destroy(&sync_mutex);
// *** Handle per CC_id openair0 // *** Handle per CC_id openair0
if (UE_flag==1)
openair0.trx_end_func(&openair0); openair0.trx_end_func(&openair0);
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);
} }
......
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