Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
openairinterface5G
Commits
f91457d8
Commit
f91457d8
authored
Jun 18, 2016
by
knopp
Browse files
added common acquisition interfaces for ExpressMIMO2
parent
626d1079
Changes
9
Hide whitespace changes
Inline
Side-by-side
cmake_targets/CMakeLists.txt
View file @
f91457d8
...
...
@@ -494,7 +494,7 @@ include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ")
set
(
HWLIB_EXMIMO_SOURCE
${
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
}
)
...
...
@@ -535,8 +535,8 @@ if (${RF_BOARD} STREQUAL "EXMIMO")
include_directories
(
"
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/"
)
include_directories
(
"
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/DEFS/"
)
set
(
HW_SOURCE
${
HW_SOURCE
}
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
)
#
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c)
set
(
option_HW_lib
"-rdynamic -ldl"
)
elseif
(
${
RF_BOARD
}
STREQUAL
"OAI_USRP"
)
...
...
@@ -1478,9 +1478,9 @@ add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????")
${
OPENAIR1_DIR
}
/SIMULATION/ETH_TRANSPORT/pgm_link.c
)
add_library
(
OPENAIR0_LIB
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
)
#
add_library(OPENAIR0_LIB
#
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
#
)
# System packages that are required
# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
...
...
cmake_targets/build_oai
View file @
f91457d8
...
...
@@ -692,7 +692,9 @@ function main() {
#add exmimo compilation
#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"
elif
[
"
$HW
"
==
"OAI_USRP"
]
;
then
if
[
-d
"/usr/include/uhd"
]
;
then
...
...
openair1/PHY/LTE_ESTIMATION/adjust_gain.c
View file @
f91457d8
...
...
@@ -30,20 +30,10 @@
#include
"PHY/defs.h"
#include
"PHY/extern.h"
#ifdef EXMIMO
#include
"openair0_lib.h"
extern
int
card
;
#endif
void
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
"
,
rx_power_fil_dB
,
ue
->
measurements
.
rssi
,
...
...
@@ -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
);
#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
/* 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",
...
...
openair1/PHY/TOOLS/lte_dfts.c
View file @
f91457d8
...
...
@@ -6817,6 +6817,7 @@ void dft60(int16_t *x,int16_t *y,unsigned char scale)
for (i=0; i<60; i++) {
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)
simd_q15_t x[4096],y[4096],tw0,tw1,tw2,tw3;
#endif
int i;
simd_q15_t *x128=x,*y128=y;
set_taus_seed(0);
opp_enabled = 1;
...
...
@@ -18592,17 +18594,22 @@ int main(int argc, char**argv)
((int16_t *)&tw3)[5] = 0;
((int16_t *)&tw3)[6] = 32767;
((int16_t *)&tw3)[7] = 0;
*/
for (i=0;i<300;i++) {
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
x[i] = _mm_set1_epi32(taus());
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__)
x[i] = (int16x8_t)vdupq_n_s32(taus());
x[i] = vshrq_n_s16(x[i],4);
#endif
}
/*
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])[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)
for (i=0;i<48;i++)
printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
printf("\n");
*/
dft60((int16_t *)x,(int16_t *)y,1);
printf("\n\n60-point\n");
printf("X: ");
for (i=0;i<60;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]);
printf("%d,%d,",((int16_t*)(&x
128
[i]))[0],((int16_t *)(&x
128
[i]))[1]);
printf("\nY:");
for (i=0;i<60;i++)
printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
printf("%d,%d,",((int16_t*)(&y
128
[i]))[0],((int16_t *)(&y
128
[i]))[1]);
printf("\n");
dft72((int16_t *)x,(int16_t *)y,1);
printf("\n\n72-point\n");
printf("X: ");
for (i=0;i<72;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]);
printf("%d,%d,",((int16_t*)(&x
128
[i]))[0],((int16_t *)(&x
128
[i]))[1]);
printf("\nY:");
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*)(&y
128
[i]))[0],((int16_t *)(&y
128
[i]))[1]);
printf("\n");
/*
dft96((int16_t *)x,(int16_t *)y,1);
printf("\n\n96-point\n");
printf("X: ");
...
...
@@ -18783,17 +18790,17 @@ int main(int argc, char**argv)
for (i=0;i<108;i++)
printf("%d: %d,%d\n",i,((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
printf("\n");
*/
dft120((int16_t *)x,(int16_t *)y,1);
printf("\n\n120-point\n");
printf("X: ");
for (i=0;i<120;i++)
printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]);
printf("%d,%d,",((int16_t*)(&x
128
[i]))[0],((int16_t *)(&x
128
[i]))[1]);
printf("\nY:");
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*)(&y
128
[i]))[0],((int16_t *)(&y
128
[i]))[1]);
printf("\n");
/*
dft144((int16_t *)x,(int16_t *)y,1);
printf("\n\n144-point\n");
printf("X: ");
targets/ARCH/COMMON/common_lib.h
View file @
f91457d8
...
...
@@ -51,6 +51,9 @@
#define BBU_LOCAL_RADIO_HEAD 0
#define BBU_REMOTE_RADIO_HEAD 1
#define MAX_CARDS 8
typedef
int64_t
openair0_timestamp
;
typedef
volatile
int64_t
openair0_vtimestamp
;
...
...
@@ -59,9 +62,9 @@ typedef volatile int64_t openair0_vtimestamp;
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
...
...
@@ -145,16 +148,12 @@ typedef struct {
unsigned
int
samples_per_frame
;
//! the sample rate for both transmit and receive.
double
sample_rate
;
//! number of samples per RX/TX packet (USRP + Ethernet)
unsigned
int
samples_per_packet
;
//! delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist
int
tx_scheduling_advance
;
//! flag to indicate that the device is doing mmapped DMA transfers
int
mmapped_dma
;
//! offset in samples between TX and RX paths
int
tx_sample_advance
;
//! configurable tx thread lauch delay
int
txlaunch_wait
;
/* 1 or 0 */
//! configurable tx thread lauch delay
int
txlaunch_wait_slotcount
;
int
samples_per_packet
;
int
tx_scheduling_advance
;
//! number of RX channels (=RX antennas)
int
rx_num_channels
;
//! number of TX channels (=TX antennas)
...
...
@@ -165,7 +164,7 @@ typedef struct {
//! \brief Center frequency in Hz for TX.
//! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels
double
tx_freq
[
4
];
//! \brief memory
//! \brief Pointer to Calibration table for RX gains
rx_gain_calib_table_t
*
rx_gain_calib_table
;
...
...
targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
View file @
f91457d8
...
...
@@ -36,17 +36,34 @@
* 28.01.2013: Initial version
*/
#include
<fcntl.h>
#include
<sys/ioctl.h>
#include
<sys/mman.h>
#include
<string.h>
#include
<unistd.h>
#define _GNU_SOURCE
#include
<stdio.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
"openair_device.h"
#include
"common_lib.h"
#include
<pthread.h>
#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
...
...
@@ -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_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
ans
=
0
;
...
...
@@ -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 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
)
{
// Initialize card
// exmimo_config_t *p_exmimo_config;
exmimo_id_t
*
p_exmimo_id
;