Commit f91457d8 authored by knopp's avatar knopp

added common acquisition interfaces for ExpressMIMO2

parent 626d1079
...@@ -494,7 +494,7 @@ include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/") ...@@ -494,7 +494,7 @@ include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ") #set (option_HWEXMIMOLIB_lib "-l ")
set(HWLIB_EXMIMO_SOURCE set(HWLIB_EXMIMO_SOURCE
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c # ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
) )
add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} ) add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} )
...@@ -535,8 +535,8 @@ if (${RF_BOARD} STREQUAL "EXMIMO") ...@@ -535,8 +535,8 @@ if (${RF_BOARD} STREQUAL "EXMIMO")
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/") include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/") include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
set(HW_SOURCE ${HW_SOURCE} set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c)
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c) # ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c)
set(option_HW_lib "-rdynamic -ldl") set(option_HW_lib "-rdynamic -ldl")
elseif (${RF_BOARD} STREQUAL "OAI_USRP") elseif (${RF_BOARD} STREQUAL "OAI_USRP")
...@@ -1478,9 +1478,9 @@ add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") ...@@ -1478,9 +1478,9 @@ add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????")
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c
) )
add_library(OPENAIR0_LIB # add_library(OPENAIR0_LIB
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c # ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
) # )
# System packages that are required # System packages that are required
# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
......
...@@ -692,7 +692,9 @@ function main() { ...@@ -692,7 +692,9 @@ function main() {
#add exmimo compilation #add exmimo compilation
#TODO EXMIMO library support #TODO EXMIMO library support
compilations \
$build_dir oai_exmimodevif \
liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL
echo_info "liboai_device.so is linked to EXMIMO device library" echo_info "liboai_device.so is linked to EXMIMO device library"
elif [ "$HW" == "OAI_USRP" ] ; then elif [ "$HW" == "OAI_USRP" ] ; then
if [ -d "/usr/include/uhd" ] ; then if [ -d "/usr/include/uhd" ] ; then
......
...@@ -30,20 +30,10 @@ ...@@ -30,20 +30,10 @@
#include "PHY/defs.h" #include "PHY/defs.h"
#include "PHY/extern.h" #include "PHY/extern.h"
#ifdef EXMIMO
#include "openair0_lib.h"
extern int card;
#endif
void void
phy_adjust_gain (PHY_VARS_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) phy_adjust_gain (PHY_VARS_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id)
{ {
#ifdef EXMIMO
exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr;
uint16_t i;
#endif
LOG_D(PHY,"Gain control: rssi %d (%d,%d)\n", LOG_D(PHY,"Gain control: rssi %d (%d,%d)\n",
rx_power_fil_dB, rx_power_fil_dB,
ue->measurements.rssi, ue->measurements.rssi,
...@@ -80,77 +70,6 @@ phy_adjust_gain (PHY_VARS_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) ...@@ -80,77 +70,6 @@ phy_adjust_gain (PHY_VARS_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id)
LOG_D(PHY,"Gain control: rx_total_gain_dB = %d (max %d,rxpf %d)\n",ue->rx_total_gain_dB,MAX_RF_GAIN,rx_power_fil_dB); LOG_D(PHY,"Gain control: rx_total_gain_dB = %d (max %d,rxpf %d)\n",ue->rx_total_gain_dB,MAX_RF_GAIN,rx_power_fil_dB);
#ifdef EXMIMO
if (ue->rx_total_gain_dB>ue->rx_gain_max[0]) {
ue->rx_total_gain_dB = ue->rx_gain_max[0];
for (i=0; i<ue->frame_parms.nb_antennas_rx; i++) {
p_exmimo_config->rf.rx_gain[i][0] = 30;
}
} else if (ue->rx_total_gain_dB<(ue->rx_gain_max[0]-30)) {
// for the moment we stay in max gain mode
ue->rx_total_gain_dB = ue->rx_gain_max[0] - 30;
for (i=0; i<ue->frame_parms.nb_antennas_rx; i++) {
p_exmimo_config->rf.rx_gain[i][0] = 0;
}
/*
ue->rx_gain_mode[0] = byp;
ue->rx_gain_mode[1] = byp;
exmimo_pci_interface->rf.rf_mode0 = 22991; //bypass
exmimo_pci_interface->rf.rf_mode1 = 22991; //bypass
if (ue->rx_total_gain_dB<(ue->rx_gain_byp[0]-50)) {
exmimo_pci_interface->rf.rx_gain00 = 0;
exmimo_pci_interface->rf.rx_gain10 = 0;
}
*/
} else {
for (i=0; i<ue->frame_parms.nb_antennas_rx; i++) {
p_exmimo_config->rf.rx_gain[i][0] = 30 - ue->rx_gain_max[0] + ue->rx_total_gain_dB;
}
}
/*
break;
case med_gain:
case byp_gain:
if (ue->rx_total_gain_dB>ue->rx_gain_byp[0]) {
ue->rx_gain_mode[0] = max_gain;
ue->rx_gain_mode[1] = max_gain;
exmimo_pci_interface->rf.rf_mode0 = 55759; //max gain
exmimo_pci_interface->rf.rf_mode1 = 55759; //max gain
if (ue->rx_total_gain_dB>ue->rx_gain_max[0]) {
exmimo_pci_interface->rf.rx_gain00 = 50;
exmimo_pci_interface->rf.rx_gain10 = 50;
}
else {
exmimo_pci_interface->rf.rx_gain00 = 50 - ue->rx_gain_max[0] + ue->rx_total_gain_dB;
exmimo_pci_interface->rf.rx_gain10 = 50 - ue->rx_gain_max[1] + ue->rx_total_gain_dB;
}
}
else if (ue->rx_total_gain_dB<(ue->rx_gain_byp[0]-50)) {
exmimo_pci_interface->rf.rx_gain00 = 0;
exmimo_pci_interface->rf.rx_gain10 = 0;
}
else {
exmimo_pci_interface->rf.rx_gain00 = 50 - ue->rx_gain_byp[0] + ue->rx_total_gain_dB;
exmimo_pci_interface->rf.rx_gain10 = 50 - ue->rx_gain_byp[1] + ue->rx_total_gain_dB;
}
break;
default:
exmimo_pci_interface->rf.rx_gain00 = 50;
exmimo_pci_interface->rf.rx_gain10 = 50;
break;
}
*/
#endif
#ifdef DEBUG_PHY #ifdef DEBUG_PHY
/* if ((ue->frame%100==0) || (ue->frame < 10)) /* if ((ue->frame%100==0) || (ue->frame < 10))
msg("[PHY][ADJUST_GAIN] frame %d, rx_power = %d, rx_power_fil = %d, rx_power_fil_dB = %d, coef=%d, ncoef=%d, rx_total_gain_dB = %d (%d,%d,%d)\n", msg("[PHY][ADJUST_GAIN] frame %d, rx_power = %d, rx_power_fil = %d, rx_power_fil_dB = %d, coef=%d, ncoef=%d, rx_total_gain_dB = %d (%d,%d,%d)\n",
......
...@@ -6817,6 +6817,7 @@ void dft60(int16_t *x,int16_t *y,unsigned char scale) ...@@ -6817,6 +6817,7 @@ void dft60(int16_t *x,int16_t *y,unsigned char scale)
for (i=0; i<60; i++) { for (i=0; i<60; i++) {
y128[i] = mulhi_int16(y128[i],norm128); y128[i] = mulhi_int16(y128[i],norm128);
printf("y[%d] = (%d,%d)\n",i,((int16_t*)&y128[i])[0],((int16_t*)&y128[i])[1]);
} }
} }
...@@ -18553,6 +18554,7 @@ int main(int argc, char**argv) ...@@ -18553,6 +18554,7 @@ int main(int argc, char**argv)
simd_q15_t x[4096],y[4096],tw0,tw1,tw2,tw3; simd_q15_t x[4096],y[4096],tw0,tw1,tw2,tw3;
#endif #endif
int i; int i;
simd_q15_t *x128=x,*y128=y;
set_taus_seed(0); set_taus_seed(0);
opp_enabled = 1; opp_enabled = 1;
...@@ -18592,17 +18594,22 @@ int main(int argc, char**argv) ...@@ -18592,17 +18594,22 @@ int main(int argc, char**argv)
((int16_t *)&tw3)[5] = 0; ((int16_t *)&tw3)[5] = 0;
((int16_t *)&tw3)[6] = 32767; ((int16_t *)&tw3)[6] = 32767;
((int16_t *)&tw3)[7] = 0; ((int16_t *)&tw3)[7] = 0;
*/
for (i=0;i<300;i++) { for (i=0;i<300;i++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
x[i] = _mm_set1_epi32(taus()); x[i] = _mm_set1_epi32(taus());
x[i] = _mm_srai_epi16(x[i],4); x[i] = _mm_srai_epi16(x[i],4);
#else
x[i] = _mm256_set1_epi32(taus());
x[i] = _mm256_srai_epi16(x[i],4);
#endif
#elif defined(__arm__) #elif defined(__arm__)
x[i] = (int16x8_t)vdupq_n_s32(taus()); x[i] = (int16x8_t)vdupq_n_s32(taus());
x[i] = vshrq_n_s16(x[i],4); x[i] = vshrq_n_s16(x[i],4);
#endif #endif
} }
/*
bfly2_tw1(x,x+1,y,y+1); bfly2_tw1(x,x+1,y,y+1);
printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1]); printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1]);
printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3]); printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3]);
...@@ -18743,27 +18750,27 @@ int main(int argc, char**argv) ...@@ -18743,27 +18750,27 @@ int main(int argc, char**argv)
for (i=0;i<48;i++) for (i=0;i<48;i++)
printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]); printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
printf("\n"); printf("\n");
*/
dft60((int16_t *)x,(int16_t *)y,1); dft60((int16_t *)x,(int16_t *)y,1);
printf("\n\n60-point\n"); printf("\n\n60-point\n");
printf("X: "); printf("X: ");
for (i=0;i<60;i++) for (i=0;i<60;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]); printf("%d,%d,",((int16_t*)(&x128[i]))[0],((int16_t *)(&x128[i]))[1]);
printf("\nY:"); printf("\nY:");
for (i=0;i<60;i++) for (i=0;i<60;i++)
printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]); printf("%d,%d,",((int16_t*)(&y128[i]))[0],((int16_t *)(&y128[i]))[1]);
printf("\n"); printf("\n");
dft72((int16_t *)x,(int16_t *)y,1); dft72((int16_t *)x,(int16_t *)y,1);
printf("\n\n72-point\n"); printf("\n\n72-point\n");
printf("X: "); printf("X: ");
for (i=0;i<72;i++) for (i=0;i<72;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]); printf("%d,%d,",((int16_t*)(&x128[i]))[0],((int16_t *)(&x128[i]))[1]);
printf("\nY:"); printf("\nY:");
for (i=0;i<72;i++) for (i=0;i<72;i++)
printf("%d: %d,%d\n",i,((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]); printf("%d: %d,%d\n",i,((int16_t*)(&y128[i]))[0],((int16_t *)(&y128[i]))[1]);
printf("\n"); printf("\n");
/*
dft96((int16_t *)x,(int16_t *)y,1); dft96((int16_t *)x,(int16_t *)y,1);
printf("\n\n96-point\n"); printf("\n\n96-point\n");
printf("X: "); printf("X: ");
...@@ -18783,17 +18790,17 @@ int main(int argc, char**argv) ...@@ -18783,17 +18790,17 @@ int main(int argc, char**argv)
for (i=0;i<108;i++) for (i=0;i<108;i++)
printf("%d: %d,%d\n",i,((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]); printf("%d: %d,%d\n",i,((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
printf("\n"); printf("\n");
*/
dft120((int16_t *)x,(int16_t *)y,1); dft120((int16_t *)x,(int16_t *)y,1);
printf("\n\n120-point\n"); printf("\n\n120-point\n");
printf("X: "); printf("X: ");
for (i=0;i<120;i++) for (i=0;i<120;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]); printf("%d,%d,",((int16_t*)(&x128[i]))[0],((int16_t *)(&x128[i]))[1]);
printf("\nY:"); printf("\nY:");
for (i=0;i<120;i++) for (i=0;i<120;i++)
printf("%d: %d,%d\n",i,((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]); printf("%d: %d,%d\n",i,((int16_t*)(&y128[i]))[0],((int16_t *)(&y128[i]))[1]);
printf("\n"); printf("\n");
/*
dft144((int16_t *)x,(int16_t *)y,1); dft144((int16_t *)x,(int16_t *)y,1);
printf("\n\n144-point\n"); printf("\n\n144-point\n");
printf("X: "); printf("X: ");
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
#define BBU_LOCAL_RADIO_HEAD 0 #define BBU_LOCAL_RADIO_HEAD 0
#define BBU_REMOTE_RADIO_HEAD 1 #define BBU_REMOTE_RADIO_HEAD 1
#define MAX_CARDS 8
typedef int64_t openair0_timestamp; typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp; typedef volatile int64_t openair0_vtimestamp;
...@@ -59,9 +62,9 @@ typedef volatile int64_t openair0_vtimestamp; ...@@ -59,9 +62,9 @@ typedef volatile int64_t openair0_vtimestamp;
typedef struct openair0_device_t openair0_device; typedef struct openair0_device_t openair0_device;
#ifndef EXMIMO
#define MAX_CARDS 1
#endif
//#define USRP_GAIN_OFFSET (56.0) // 86 calibrated for USRP B210 @ 2.6 GHz to get equivalent RS EPRE in OAI to SMBV100 output //#define USRP_GAIN_OFFSET (56.0) // 86 calibrated for USRP B210 @ 2.6 GHz to get equivalent RS EPRE in OAI to SMBV100 output
...@@ -145,16 +148,12 @@ typedef struct { ...@@ -145,16 +148,12 @@ typedef struct {
unsigned int samples_per_frame; unsigned int samples_per_frame;
//! the sample rate for both transmit and receive. //! the sample rate for both transmit and receive.
double sample_rate; double sample_rate;
//! number of samples per RX/TX packet (USRP + Ethernet) //! flag to indicate that the device is doing mmapped DMA transfers
unsigned int samples_per_packet; int mmapped_dma;
//! delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist
int tx_scheduling_advance;
//! offset in samples between TX and RX paths //! offset in samples between TX and RX paths
int tx_sample_advance; int tx_sample_advance;
//! configurable tx thread lauch delay int samples_per_packet;
int txlaunch_wait; /* 1 or 0 */ int tx_scheduling_advance;
//! configurable tx thread lauch delay
int txlaunch_wait_slotcount;
//! number of RX channels (=RX antennas) //! number of RX channels (=RX antennas)
int rx_num_channels; int rx_num_channels;
//! number of TX channels (=TX antennas) //! number of TX channels (=TX antennas)
...@@ -165,7 +164,7 @@ typedef struct { ...@@ -165,7 +164,7 @@ typedef struct {
//! \brief Center frequency in Hz for TX. //! \brief Center frequency in Hz for TX.
//! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels //! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels
double tx_freq[4]; double tx_freq[4];
//! \brief memory
//! \brief Pointer to Calibration table for RX gains //! \brief Pointer to Calibration table for RX gains
rx_gain_calib_table_t *rx_gain_calib_table; rx_gain_calib_table_t *rx_gain_calib_table;
......
...@@ -36,17 +36,34 @@ ...@@ -36,17 +36,34 @@
* 28.01.2013: Initial version * 28.01.2013: Initial version
*/ */
#include <fcntl.h> #define _GNU_SOURCE
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
#include <linux/sched.h>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
#include <sys/sysinfo.h>
#include <sys/ioctl.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <syscall.h>
#include "openair0_lib.h" #include "openair0_lib.h"
#include "openair_device.h" #include "openair_device.h"
#include "common_lib.h" #include "common_lib.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
...@@ -66,6 +83,14 @@ static uint32_t rf_vcocal[4] = {910,910,910,910}; ...@@ -66,6 +83,14 @@ static uint32_t rf_vcocal[4] = {910,910,910,910};
static uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015}; static uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015};
static uint32_t rf_rxdc[4] = {32896,32896,32896,32896}; static uint32_t rf_rxdc[4] = {32896,32896,32896,32896};
extern volatile int oai_exit;
void kill_watchdog(openair0_device *);
void create_watchdog(openair0_device *);
unsigned int log2_int( unsigned int x ) unsigned int log2_int( unsigned int x )
{ {
unsigned int ans = 0 ; unsigned int ans = 0 ;
...@@ -247,16 +272,279 @@ int openair0_stop_without_reset(int card) ...@@ -247,16 +272,279 @@ 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)
static void *watchdog_thread(void *arg) {
int policy, s, j;
struct sched_param sparam;
char cpu_affinity[1024];
cpu_set_t cpuset;
exmimo_state_t *exm=((openair0_device *)arg)->priv;
openair0_config_t *cfg=&((openair0_device *)arg)->openair0_cfg[0];
volatile unsigned int *daq_mbox = openair0_daq_cnt();
unsigned int mbox,diff;
/* Set affinity mask to include CPUs 1 to MAX_CPUS */
/* CPU 0 is reserved for UHD threads */
/* CPU 1 is reserved for all TX threads */
/* Enable CPU Affinity only if number of CPUs >2 */
CPU_ZERO(&cpuset);
#ifdef CPU_AFFINITY
if (get_nprocs() > 2)
{
for (j = 1; j < get_nprocs(); j++)
CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
perror( "pthread_setaffinity_np");
printf("Error setting processor affinity");
}
}
#endif //CPU_AFFINITY
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
perror( "pthread_getaffinity_np");
printf("Error getting processor affinity ");
}
memset(cpu_affinity,0,sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset))
{
char temp[1024];
sprintf (temp, " CPU_%d", j);
strcat(cpu_affinity, temp);
}
memset(&sparam, 0 , sizeof (sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0)
{
perror("pthread_setschedparam : ");
printf("Error setting thread priority");
}
s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0)
{
perror("pthread_getschedparam : ");
printf("Error getting thread priority");
}
printf("EXMIMO2 Watchdog TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",
sched_getcpu(),
syscall(__NR_gettid),
(policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???",
sparam.sched_priority,
cpu_affinity );
mlockall(MCL_CURRENT | MCL_FUTURE);
exm->watchdog_exit = 0;
exm->ts = 0;
exm->last_mbox = 0;
if (cfg->sample_rate==30.72e6) {
exm->samples_per_tick = 15360;
exm->samples_per_frame = 307200;
}
else if (cfg->sample_rate==23.04e6) {
exm->samples_per_tick = 11520;
exm->samples_per_frame = 230400;
}
else if (cfg->sample_rate==15.36e6) {
exm->samples_per_tick = 7680;
exm->samples_per_frame = 153600;
}
else if (cfg->sample_rate==7.68e6) {
exm->samples_per_tick = 3840;
exm->samples_per_frame = 76800;
}
else if (cfg->sample_rate==3.84e6) {
exm->samples_per_tick = 1920;
exm->samples_per_frame = 38400;
}
else if (cfg->sample_rate==1.92e6) {
exm->samples_per_tick = 960;
exm->samples_per_frame = 19200;
}
else {
printf("Unknown sampling rate %f, exiting \n",cfg->sample_rate);
exm->watchdog_exit=1;
}
// main loop to keep up with DMA transfers from exmimo2
while ((!oai_exit) && (!exm->watchdog_exit)) {
if (exm->daq_state == running) {
// grab time from MBOX
mbox = daq_mbox[0];
if (mbox<exm->last_mbox) { // wrap-around
diff = 150 + mbox - exm->last_mbox;
}
else {
diff = mbox - exm->last_mbox;
}
exm->last_mbox = mbox;
pthread_mutex_lock(&exm->watchdog_mutex);
exm->ts += (diff*exm->samples_per_frame/150) ;
if (diff > 10) // we're too late so exit
exm->watchdog_exit = 1;
if (exm->ts - exm->last_ts_rx > exm->samples_per_frame) {
exm->watchdog_exit = 1;
printf("RX Overflow, exiting\n");
}
pthread_mutex_unlock(&exm->watchdog_mutex);
}
usleep(500); // sleep for 500us
}
oai_exit=1;
return NULL;
}
void create_watchdog(openair0_device *dev) {
exmimo_state_t *priv = dev->priv;
priv->watchdog_exit=0;
#ifndef DEADLINE_SCHEDULER
priv->watchdog_sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&priv->watchdog_attr,&priv->watchdog_sched_param);
pthread_attr_setschedpolicy(&priv->watchdog_attr,SCHED_FIFO);
pthread_create(&priv->watchdog,&priv->watchdog_attr,watchdog_thread,dev);
#else
pthread_create(&priv->watchdog,NULL,watchdog_thread,devv);
#endif
pthread_mutex_init(&priv->watchdog_mutex,NULL);
}
int trx_exmimo_start(openair0_device *device) {
exmimo_state_t *exm=device->priv;
openair0_start_rt_acquisition(0);
exm->daq_state = running;
return(0);
}
int trx_exmimo_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc, int flags) {
return(0);
}
int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
exmimo_state_t *exm=device->priv;
openair0_config_t *cfg=&device->openair0_cfg[0];
openair0_timestamp ts,diff;
int i;
pthread_mutex_lock(&exm->watchdog_mutex);
ts = exm->ts;
pthread_mutex_unlock(&exm->watchdog_mutex);
while (ts < exm->last_ts_rx + nsamps) {
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)
usleep((unsigned int)((double)(diff+1024)*1e6/cfg->sample_rate));
// get new timestamp, in case we have to sleep again
pthread_mutex_lock(&exm->watchdog_mutex);
ts = exm->ts;
pthread_mutex_unlock(&exm->watchdog_mutex);
}
if (cfg->mmapped_dma == 0) { // if buff is not the dma buffer, do a memcpy, otherwise do nothing
for (i=0;i<cc;i++) {
memcpy(buff[i],
openair0_exmimo_pci[0].adc_head[i]+(exm->last_ts_rx % exm->samples_per_frame),
nsamps*sizeof(int));
}
}
*ptimestamp=exm->last_ts_rx;
exm->last_ts_rx += nsamps;
return(0);
}
void trx_exmimo_end(openair0_device *device) {
exmimo_state_t *exm=device->priv;
exm->daq_state = idle;
openair0_stop(0);
}
int trx_exmimo_get_stats(openair0_device* device) {
return(0);
}
int trx_exmimo_reset_stats(openair0_device* device) {
return(0);
}
int trx_exmimo_stop(int card) {
return(0);
}
int trx_exmimo_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1,int exmimo_dump_config) {
return(0);
}
int trx_exmimo_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
return(0);
}
void kill_watchdog(openair0_device *device) {
exmimo_state_t *exm=(exmimo_state_t *)device->priv;
exm->watchdog_exit=1;
}
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// Initialize card // Initialize card
// exmimo_config_t *p_exmimo_config; // exmimo_config_t *p_exmimo_config;
exmimo_id_t *p_exmimo_id; exmimo_id_t *p_exmimo_id;
int ret; int ret;
exmimo_state_t *exm = (exmimo_state_t *)malloc(sizeof(exmimo_state_t));
ret = openair0_open(); ret = openair0_open();