Commit d9501248 authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'enhancement-10-harmony' of...

Merge branch 'enhancement-10-harmony' of https://gitlab.eurecom.fr/oai/openairinterface5g into enhancement-10-harmony

Conflicts:
	targets/RT/USER/lte-softmodem.c
parents 89a9be9b b804f1e4
......@@ -963,7 +963,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_mobipass_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
......
......@@ -296,9 +296,6 @@ function main() {
if [ "$HW" = "None" -a "$TP" = "None" ] ; then
echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
fi
if [ "$HW" != "None" -a "$TP" != "None" ] ; then
echo_fatal "Currently eNB can not support simultaniously local and remote radio heads!!"
fi
if [ "$HW" = "None" ] ; then
echo_info "No radio head has been selected (HW set to $HW)"
fi
......
This diff is collapsed.
......@@ -38,7 +38,6 @@
* \warning
*/
#include <stdint.h>
#include "PHY/defs.h"
/// Macro for IF4 packet type
......@@ -57,7 +56,7 @@ struct IF4_header {
/// Frame Status
uint32_t frame_status;
};
} __attribute__ ((__packed__));
typedef struct IF4_header IF4_header_t;
#define sizeof_IF4_header_t 12
......@@ -71,3 +70,5 @@ void gen_IF4_prach_header(IF4_header_t*, int, int);
void send_IF4(PHY_VARS_eNB*, int, int, uint16_t, int);
void recv_IF4(PHY_VARS_eNB*, int*, int*, uint16_t*, uint32_t*);
void malloc_IF4_buffer(PHY_VARS_eNB*);
#include <stdint.h>
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
uint8_t send_IF5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t init_seq) {
uint8_t seqno=init_seq;
void *txp[2];
void *tx_buffer=NULL;
__m128i *data_block=NULL,*main_data_block=NULL;
__m128i *txp128;
__m128i t0, t1;
uint16_t packet_id=0, i;
uint16_t db_fulllength = 640;
tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (__m128i *)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4);
main_data_block = data_block;
header->flags = 0;
header->fifo_status = 0;
header->ack = 0;
header->seqno = seqno;
header->rsvd = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][proc->subframe_tx*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<(7680*2)/640; packet_id++) {
header->time_stamp = proc->timestamp_tx + packet_id*640;
data_block = main_data_block;
for (i=0; i<db_fulllength>>3; i+=2) {
t0 = _mm_srli_epi16(*txp128++, 4);
t1 = _mm_srli_epi16(*txp128++, 4);
*data_block++ = _mm_packs_epi16(t0, t1);
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id,
&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}
header->seqno += 1;
}
seqno = header->seqno;
free(tx_buffer);
return(seqno);
}
#include <stdint.h>
#include "PHY/defs.h"
#define IF5_MOBIPASS 0x0050
struct IF5_mobipass_header {
/// Type
uint16_t flags;
/// Sub-Type
uint16_t fifo_status;
/// Reserved
uint8_t seqno;
uint8_t ack;
uint32_t rsvd;
/// Frame Status
uint32_t time_stamp;
} __attribute__ ((__packed__));
typedef struct IF5_mobipass_header IF5_mobipass_header_t;
#define sizeof_IF5_mobipass_header_t 14
uint8_t send_IF5(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint8_t);
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/if5_tools.c
* \brief
* \author S. Sandeep Kumar, Raymond Knopp
* \date 2016
* \version 0.1
* \company Eurecom
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe, uint8_t *seqno, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
void *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
void *tx_buffer=NULL;
uint16_t packet_id=0, i=0;
if (packet_type == IF5_RRH_GW_DL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth),
txp,
spp_eth,
fp->nb_antennas_tx,
0);
}
} else if (packet_type == IF5_RRH_GW_UL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth),
rxp,
spp_eth,
fp->nb_antennas_rx,
0);
}
} else if (packet_type == IF5_MOBIPASS) {
uint16_t db_fulllength=640;
__m128i *data_block=NULL, *data_block_head=NULL;
__m128i *txp128;
__m128i t0, t1;
tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4);
header->flags = 0;
header->fifo_status = 0;
header->seqno = *seqno;
header->ack = 0;
header->word0 = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<(fp->samples_per_tti*2)/db_fulllength; packet_id++) {
header->time_stamp = proc_timestamp + packet_id*db_fulllength;
data_block = data_block_head;
for (i=0; i<db_fulllength>>3; i+=2) {
t0 = _mm_srli_epi16(*txp128++, 4);
t1 = _mm_srli_epi16(*txp128++, 4);
*data_block++ = _mm_packs_epi16(t0, t1);
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id,
&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}
header->seqno += 1;
}
*seqno = header->seqno;
} else {
AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type);
}
free(tx_buffer);
return;
}
void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
void *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
void *rx_buffer=NULL;
uint16_t packet_id=0, i=0;
if (packet_type == IF5_RRH_GW_DL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
openair0_timestamp timestamp[spsf / spp_eth];
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp[packet_id],
txp,
spp_eth,
fp->nb_antennas_tx);
}
*proc_timestamp = timestamp[0];
} else if (packet_type == IF5_RRH_GW_UL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
openair0_timestamp timestamp[spsf / spp_eth];
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_tx; i++)
rxp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&timestamp[packet_id],
rxp,
spp_eth,
fp->nb_antennas_rx);
}
*proc_timestamp = timestamp[0];
} else if (packet_type == IF5_MOBIPASS) {
} else {
AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);
}
free(rx_buffer);
return;
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/if5_tools.h
* \brief
* \author S. Sandeep Kumar, Raymond Knopp
* \date 2016
* \version 0.1
* \company Eurecom
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
* \note
* \warning
*/
#include <stdint.h>
#include "PHY/defs.h"
#define IF5_RRH_GW_DL 0x0022
#define IF5_RRH_GW_UL 0x0023
#define IF5_MOBIPASS 0xbffe
struct IF5_mobipass_header {
///
uint16_t flags;
///
uint16_t fifo_status;
///
uint8_t seqno;
///
uint8_t ack;
///
uint32_t word0;
///
uint32_t time_stamp;
} __attribute__ ((__packed__));
typedef struct IF5_mobipass_header IF5_mobipass_header_t;
#define sizeof_IF5_mobipass_header_t 14
void send_IF5(PHY_VARS_eNB*, openair0_timestamp, int, uint8_t*, uint16_t);
void recv_IF5(PHY_VARS_eNB*, openair0_timestamp*, int, uint16_t);
/**
* @companders.c - implementation
*
* @copy Copyright (C) <2012> <M. A. Chatterjee>
* @author M A Chatterjee <deftio [at] deftio [dot] com>
* @version 1.01 M. A. Chatterjee, cleaned up naming
*
* This file contains integer math compander functions for analog/audio representations on
* embedded systems. Linear2Alaw derived from Mark Spencer, Sun Microsystem and from
* the A Law specification
*
* @license:
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#include "companders.h"
DIO_s8 DIO_LinearToALaw(DIO_s16 sample)
{
const DIO_s16 cClip = 32635;
const static DIO_s8 LogTable[128] =
{
1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
DIO_s32 sign, exponent, mantissa;
DIO_s8 compandedValue;
sample = (sample ==-32768) ? -32767 : sample;
sign = ((~sample) >> 8) & 0x80;
if (!sign)
sample = (short)-sample;
if (sample > cClip)
sample = cClip;
if (sample >= 256)
{
exponent = (int)LogTable[(sample >> 8) & 0x7F];
mantissa = (sample >> (exponent + 3) ) & 0x0F;
compandedValue = ((exponent << 4) | mantissa);
}
else
{
compandedValue = (unsigned char)(sample >> 4);
}
compandedValue ^= (sign ^ 0x55);
return compandedValue;
}
DIO_s16 DIO_ALawToLinear(DIO_s8 aLawByte)
{
const static DIO_s16 ALawDecompTable[256]={
5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
344, 328, 376, 360, 280, 264, 312, 296,
472, 456, 504, 488, 408, 392, 440, 424,
88, 72, 120, 104, 24, 8, 56, 40,
216, 200, 248, 232, 152, 136, 184, 168,
1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
688, 656, 752, 720, 560, 528, 624, 592,
944, 912, 1008, 976, 816, 784, 880, 848,
-5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
-7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
-3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
-22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
-30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
-11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
-15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
-344, -328, -376, -360, -280, -264, -312, -296,
-472, -456, -504, -488, -408, -392, -440, -424,
-88, -72, -120, -104, -24, -8, -56, -40,
-216, -200, -248, -232, -152, -136, -184, -168,
-1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
-1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
-688, -656, -752, -720, -560, -528, -624, -592,
-944, -912, -1008, -976, -816, -784, -880, -848};
DIO_s16 addr = ((DIO_s16)aLawByte)+128; // done for compilers with poor expr type enforcement
return ALawDecompTable[addr];
}
// see companders.h
// fixed-radix IIR averager implementation supporting arbitrarily chosen windows
DIO_s32 DIO_IIRavgFR (DIO_s32 prevAvg, DIO_u16 windowLen, DIO_s16 newSample, DIO_u8 radix)
{
DIO_s32 iirAvg=0;
iirAvg = ((prevAvg * (windowLen-1)) + (DIO_I2FR(newSample,radix)))/windowLen;
return iirAvg;
}
// see companders.h
// fixed-radix IIR averager implementation using power-of-2 sized windows
// and only shift operations for cpu efficiency
DIO_s32 DIO_IIRavgPower2FR (DIO_s32 prevAvg, DIO_u8 windowLenInBits, DIO_s16 newSample, DIO_u8 radix)
{
DIO_s32 iirAvg=0;
iirAvg = (((prevAvg<<windowLenInBits)-prevAvg) + (DIO_I2FR(newSample,radix)))>>windowLenInBits;
return iirAvg;
}
#ifdef MAIN
int main(int argc, char* argv[])
{
return 0;
}
#endif
/**
* @companders.h - header definition file for embedded companding routines
*
* @copy Copyright (C) <2001-2012> <M. A. Chatterjee>
* @author M A Chatterjee <deftio [at] deftio [dot] com>
* @version 1.01 M. A. Chatterjee, cleaned up naming
*
* This file contains integer math settable fixed point radix math routines for
* use on systems in which floating point is not desired or unavailable.
*
* @license:
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#ifndef __DIO_Compand_h__
#define __DIO_Compand_h__
#ifdef __cplusplus
extern "C"
{
#endif
//"DIO" prefixes are to assist in prevent name collisions if global namespace is used.
//typedefs ... change for platform dependant register size
// u/s = unsigned/signed 8/16/32 = num of bits
// keywords "int" and "long" in C/C++ are platform dependant
typedef unsigned char DIO_u8 ;
typedef signed char DIO_s8 ;
typedef unsigned short DIO_u16 ;
typedef signed short DIO_s16 ;
typedef unsigned long DIO_u32 ;
typedef signed long DIO_s32 ;
// macros for converting from Fixed-Radix to integer, vice-versa
// r represents radix precision in bits, converts to/from integer w truncation
#define DIO_I2FR(x,r) ((x)<<(r))
#define DIO_FR2I(x,r) ((x)>>(r))
// convert FR to double, this is for debug only and WILL NOT compile under many embedded systems.
// use this in test harnesses. Since this is a macro if its not used it won't expand / link
#define DIO_FR2D(x,r) ((double)(((double)(x))/((double)(1<<(r)))))
//convert signed linear 16 bit sample to an 8 bit A-Law companded sample
DIO_s8 DIO_LinearToALaw(DIO_s16 sample);
//convert 8bit Alaw companded representation back to linear 16 bit
DIO_s16 DIO_ALawToLinear(DIO_s8 aLawByte);
//DC Offset correction for integer companders
//IIR: y_0=(y_1*(w-1)+x_0)/(w)
//where w is the window length
//below are fixed radix precision IIR averagers which allow runtime tradeoffs for windowLen & precision
//Note that (windowLen)*(1<<radix) must < 32767
//DIO_IIRavgPower2FR() allows any window length but uses a divide instruction.
//output is in radix number of bits
DIO_s32 DIO_IIRavgFR (DIO_s32 prevAvg, DIO_u16 windowLen, DIO_s16 newSample, DIO_u8 radix);
//DIO_IIRavgPower2FR() similar to above, but window length is specified as a number of bits
//which removes the need for a divide in the implementation
//outpit is in radix number of bits
DIO_s32 DIO_IIRavgPower2FR (DIO_s32 prevAvg, DIO_u8 windowLenInBits, DIO_s16 newSample, DIO_u8 radix);
#ifdef __cplusplus
}
#endif
#endif /* __DIO_Compand_h__ */
/**
* @file compandit.c - implementation test file for integer companding with
* compand/uncompand support & IIR correction
*
* @copy Copyright (C) <2012> <M. A. Chatterjee>
* @author M A Chatterjee <deftio [at] deftio [dot] com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#include <stdio.h>
#include <string.h>
#include "companders.h"
//===============================================
//main program for testing the functions
int main (int argc, char *argv[])
{
int ret_val = 0;
int i=0,j=0;
printf("\n============================================================\n");
printf("compandit library quikie program\n");
printf("M. A. Chatterjee (c) 2012\n\n");
printf("These routines were developed for use on embedded projects\n");
printf("for more info see the accompanying compand.txt\n");
printf("\n");
//uncomment to
//show how linear-->alaw-->linear-->alaw progression / quantization error works
/*
{
char alaw=0,alaw2;
short rev=0;
for (i= -32768; i <= 32767; i++)
{
alaw = DIO_LinearToALaw((short)i);
rev = DIO_ALawToLinear(alaw);
alaw2 =DIO_LinearToALaw(rev);
if (alaw != alaw2)
printf("***********");
printf("%7d %7d %7d %7d\n",i,(int)alaw,(int)rev,(int)alaw2);
}
}
// IIR averager examples
//IIR window length of 8 samples, using fractional precision of 4 bits
{
int a3=0, a4=0;
unsigned char rad=4; //4 bits fixed-radix fractional precision
printf(" index wave IIRav(i) IIRav(f) IIRavP2(i) IIRavP2(f)\n");
for (i=0; i < 300; i++)
{
j=(i&0x3f)-20; // triangle wave with range -20 to + 43
a3= DIO_IIRavgFR(a3,8,j,rad);
a4= DIO_IIRavgPower2FR(a4,3,j,rad);
printf("%6d %6d %6d %9.4f %6d %9.4f \n",i,j,
DIO_FR2I(a3,rad),DIO_FR2D(a3,rad) ,DIO_FR2I(a4,rad),DIO_FR2D(a4,rad));
}
}
//IIR window length of 64 samples
{
int a3=0, a4=0;
unsigned char rad=6; //rad is the number of bits of precision
printf(" index wave IIRav(i) IIRav(f) IIRavP2(i) IIRavP2(f)\n");
for (i=0; i < 300; i++)
{
j=(i&0x3f)-20; // triangle wave with range -20 to + 43
a3= DIO_IIRavgFR(a3,64,j,rad);
a4= DIO_IIRavgPower2FR(a4,6,j,rad);
printf("%6d %6d %6d %9.4f %6d %9.4f \n",i,j,
DIO_FR2I(a3,rad),DIO_FR2D(a3,rad) ,DIO_FR2I(a4,rad),DIO_FR2D(a4,rad));
}
}
// */
//Typical microcontroller application. See readme-companders.txt
// the input here simulates an A/D which has a range 0..3.3V mapped as 12 bits (0..4095)
// with a DC bias of 1.55V ==> (1.55/3.3)*4095 counts = 1923 counts
//now window length of 256 is used for rejecting the resistor bias. at 8KHz this window
// would be approx 8000/256 ~= 31 Hz (not quite but explaining Z xforms is beyond what
// can be explained in this small space.)
//we seed the DC average at 3.3/2 = 1.65V (we guess its in the middle) and let the long window
//length hone in on the correct value. (1.65V/3.3V) *4095 = 2048 counts
{
int actualDCbias =1923;
int calculatedDCbias =2048; //2048 is our initial estimate as outlined above
unsigned char windowLenPow2InBits = 8; // 8 bit long window = 256 sample long window
unsigned char rad=6; //rad is the number of bits of precision
calculatedDCbias = DIO_I2FR(calculatedDCbias,rad);
printf(" index wave actDCbias calcDCbias calcDCbias(f) alaw\n");
for (i=0; i < 1000; i++) // if 8000 hz sample rate this represents the number of samples captured
{
j=(((i&0x3f)<<1)-63)+1923; // triangle wave w range 0..127 with a bias set at actualDCbias
calculatedDCbias = DIO_IIRavgPower2FR(calculatedDCbias,windowLenPow2InBits,j,rad);
printf("%6d %6d %6d %6d %9.4f %3d\n",i,j,actualDCbias,
DIO_FR2I(calculatedDCbias,rad),DIO_FR2D(calculatedDCbias,rad),
(int)(DIO_LinearToALaw(j-DIO_FR2I(calculatedDCbias,rad)) ));
}
}
printf("\n");
return ret_val;
}
This diff is collapsed.
......@@ -158,10 +158,11 @@ enum transmission_access_mode {
CBA_ACCESS};
typedef enum {
eNodeB_3GPP=0, // classical eNodeB function
eNodeB_3GPP=0, // classical eNodeB function
eNodeB_3GPP_BBU, // eNodeB with NGFI IF5
NGFI_RRU_IF4, // NGFI_RRU (NGFI remote radio-unit, currently split at common - ue_specific interface, IF4)
NGFI_RCC_IF4 // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4)
NGFI_RRU_IF5, // NGFI_RRU with IF5
NGFI_RRU_IF4, // NGFI_RRU (NGFI remote radio-unit, currently split at common - ue_specific interface, IF4)
NGFI_RCC_IF4 // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4)
} eNB_func_t;
typedef struct UE_SCAN_INFO_s {
......@@ -513,7 +514,8 @@ typedef struct PHY_VARS_eNB_s {
/// RF and Interface devices per CC
openair0_device rfdevice;
openair0_device ifdevice;
// *** Handle spatially distributed MIMO antenna ports
/// Pointer for ifdevice buffer struct
if_buffer_t ifbuffer;
} PHY_VARS_eNB;
......
......@@ -45,6 +45,7 @@
#include "SCHED/extern.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
......@@ -2524,6 +2525,8 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
int prach_rx;
uint8_t seqno=0;
uint16_t packet_type;
uint32_t symbol_number=0;
uint32_t symbol_mask, symbol_mask_full;
......@@ -2545,7 +2548,8 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot)
if ((eNB->node_function == NGFI_RRU_IF4) ||
if ((eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == NGFI_RRU_IF5) ||
(eNB->node_function == eNodeB_3GPP)) { // acquisition from RF
for (i=0; i<fp->nb_antennas_rx; i++)
......@@ -2585,11 +2589,32 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
} else if(eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF
/// **** trx_read_func from IF device **** ///
}
/// **** recv_IF5 of rxdata from RRH **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
recv_IF5(eNB, &proc->timestamp_rx, proc->subframe_rx, IF5_RRH_GW_UL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
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 {
proc->first_rx = 0;
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx );
}
if ((eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == eNodeB_3GPP) ||
(eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing
......@@ -2654,6 +2679,12 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
}
}
} else if (eNB->node_function == NGFI_RRU_IF5) {
/// **** send_IF5 of rxdata to BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
} else if (eNB->node_function == NGFI_RCC_IF4) {
/// **** recv_IF4 of rxdataF from RRU **** ///
/// **** recv_IF4 of rxsigF from RRU **** ///
......@@ -2709,11 +2740,11 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
if (proc->first_rx == 0) {
if (proc->subframe_rx != subframe){
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");
//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");
//exit_fun("Exiting");
}
} else {
proc->first_rx = 0;
......
......@@ -331,9 +331,11 @@ const char* eurecomFunctionsNames[] = {
"itti_relay_thread",
"test",
/* IF4 signals */
/* IF4/IF5 signals */
"send_if4",
"recv_if4"
"recv_if4",
"send_if5",
"recv_if5"
};
struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = {
......
......@@ -308,10 +308,12 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_RELAY_THREAD,
VCD_SIGNAL_DUMPER_FUNCTIONS_TEST,
/* IF4 signals */
/* IF4/IF5 signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4,
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4,
VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5,
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5,
VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
} vcd_signal_dump_functions;
......
......@@ -236,6 +236,14 @@ typedef struct {
} eth_params_t;
typedef struct {
//! Tx buffer for if device
void *tx;
//! Rx buffer for if device
void *rx;
} if_buffer_t;
/*!\brief structure holds the parameters to configure USRP devices */
struct openair0_device_t {
/*!brief Module ID of this device */
......
......@@ -51,9 +51,6 @@
#include "common_lib.h"
#include "ethernet_lib.h"
#include "if_defs.h"
#include "openair1/PHY/LTE_TRANSPORT/if4_tools.h"
#include "openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
#define DEBUG 0
......@@ -124,11 +121,11 @@ int eth_socket_init_raw(openair0_device *device) {
/* Construct the Ethernet header */
ether_aton_r(local_mac, (struct ether_addr *)(&(eth->eh.ether_shost)));
ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->eh.ether_dhost)));
// if (((*) device->priv)->flags == ETH_RAW_IF5_MOBIPASS) {
if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
eth->eh.ether_type = htons(0xbffe);
// } else {
// eth->eh.ether_type = htons((short)device->openair0_cfg->my_port);
// }
} else {
eth->eh.ether_type = htons((short)device->openair0_cfg->my_port);
}
printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5]);
return 0;
......@@ -315,13 +312,11 @@ int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp,
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t;
void *test_buffer = (void*)malloc(packet_size);
IF4_header_t *test_header = (IF4_header_t*)(test_buffer + MAC_HEADER_SIZE_BYTES);
ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t;
IF4_header_t *test_header = (IF4_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES);
bytes_received = recv(eth->sockfd[Mod_id],
test_buffer,
buff[0],
packet_size,
MSG_PEEK);
if (bytes_received ==-1) {
......@@ -339,11 +334,7 @@ int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp,
} else {
packet_size = RAW_IF4_PRACH_SIZE_BYTES;
}
buff[0] = (void*)malloc(packet_size);
bytes_received = 0;
while(bytes_received < packet_size) {
bytes_received = recv(eth->sockfd[Mod_id],
buff[0],
......@@ -360,7 +351,6 @@ int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp,
}
eth->rx_nsamps = nsamps;
free(test_buffer);
return(bytes_received);
}
......@@ -397,7 +387,8 @@ int eth_set_dev_conf_raw(openair0_device *device) {
int eth_set_dev_conf_raw_IF4(openair0_device *device) {
int eth_set_dev_conf_raw_IF4(openair0_device *device) {
// use for cc_id info
int Mod_id = device->Mod_id;
eth_state_t *eth = (eth_state_t*)device->priv;
......@@ -458,6 +449,7 @@ int eth_get_dev_conf_raw(openair0_device *device) {
int eth_get_dev_conf_raw_IF4(openair0_device *device) {
// use for cc_id info
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
......
......@@ -52,7 +52,6 @@
#include "common_lib.h"
#include "ethernet_lib.h"
#include "if_defs.h"
#define DEBUG 0
struct sockaddr_in dest_addr[MAX_INST];
......
......@@ -51,7 +51,6 @@
#include "common_lib.h"
#include "ethernet_lib.h"
#include "if_defs.h"
int num_devices_eth = 0;
struct sockaddr_in dest_addr[MAX_INST];
......@@ -83,7 +82,7 @@ int trx_eth_start(openair0_device *device) {
if(eth_get_dev_conf_raw_IF4(device)!=0) return -1;
}
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
if(ethernet_tune (device,MTU_SIZE,RAW_IF4_PRACH_SIZE_BYTES)!=0) return -1;
} else if (eth->flags == ETH_UDP_IF4_MODE) {
......@@ -107,8 +106,6 @@ int trx_eth_start(openair0_device *device) {
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
}
/* adjust MTU wrt number of samples per packet */
//if(ethernet_tune (device,MTU_SIZE,UDP_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
}
/* apply additional configuration */
if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1;
......@@ -386,8 +383,6 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
device->priv = eth;
/* device specific */
//openair0_cfg[0].txlaunch_wait = 0;//manage when TX processing is triggered
//openair0_cfg[0].txlaunch_wait_slotcount = 0; //manage when TX processing is triggered
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance;
......@@ -397,19 +392,19 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
/*Note scheduling advance values valid only for case 7680000 */
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
openair0_cfg[0].samples_per_packet = 4096;
openair0_cfg[0].samples_per_packet = 3840;
break;
case 23040000:
openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].samples_per_packet = 2880;
break;
case 15360000:
openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].samples_per_packet = 1920;
break;
case 7680000:
openair0_cfg[0].samples_per_packet = 1024;
openair0_cfg[0].samples_per_packet = 960;
break;
case 1920000:
openair0_cfg[0].samples_per_packet = 256;
openair0_cfg[0].samples_per_packet = 240;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
......
......@@ -41,6 +41,9 @@
#include <netinet/ether.h>
#include <stdint.h>
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
// ETH transport preference modes
#define ETH_UDP_MODE 0
#define ETH_RAW_MODE 1
......@@ -56,7 +59,7 @@
#define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
// Packet sizes for IF4 interface format
#define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(int16_t)*scaled_nblocks)
#define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks)
#define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*839*2) // FIX hard coded prach size (uncompressed)
#define RAW_IF4_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))
......
......@@ -69,7 +69,7 @@
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#include "PHY/extern.h"
#include "SCHED/extern.h"
......@@ -302,6 +302,8 @@ static void* eNB_thread_rxtx( void* param ) {
uint16_t packet_type;
uint32_t symbol_number=0;
uint8_t seqno=0;
if (opp_enabled == 1) {
snprintf(tx_time_name, 100,"/tmp/%s_tx_time_thread_sf", "eNB");
tx_time_file = fopen(tx_time_name,"w");
......@@ -434,7 +436,9 @@ static void* eNB_thread_rxtx( void* param ) {
if (oai_exit) break;
// UE-specific RX processing for subframe n
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) {
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 );
// this is the ue-specific processing for the subframe and can be multi-threaded later
phy_procedures_eNB_uespec_RX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay );
......@@ -472,7 +476,9 @@ static void* eNB_thread_rxtx( void* param ) {
if (oai_exit) break;
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) {
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4)) {
phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL );
/* we're done, let the next one proceed */
......@@ -489,21 +495,28 @@ static void* eNB_thread_rxtx( void* param ) {
exit_fun("nothing to add");
break;
}
} else {
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) {
/// **** recv_IF4 of txdataF from RCC **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
while (symbol_number < PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.symbols_per_tti-1) {
do {
recv_IF4(PHY_vars_eNB_g[0][proc->CC_id], &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
}
} while (symbol_number < PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.symbols_per_tti-1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
// Check the recv frame/subframe
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF5) {
/// **** recv_IF5 of txdata from BBU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
recv_IF5(PHY_vars_eNB_g[0][proc->CC_id], &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
}
}
// eNodeB_3GPP, _BBU and RRU create txdata
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) {
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
......@@ -525,8 +538,9 @@ static void* eNB_thread_rxtx( void* param ) {
// eNodeB_3GPP, RRU write to RF device
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP ||
PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) {
if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) ||
(PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF5)) {
// Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
......@@ -547,14 +561,17 @@ static void* eNB_thread_rxtx( void* param ) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff );
} else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) {
/// **** trx_write_func to IF device **** ///
// send_IF5(PHY_vars_eNB_g[0][proc->CC_id], proc, 0);
/// **** send_IF5 of txdata to RRH **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
send_IF5(PHY_vars_eNB_g[0][proc->CC_id], proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
} else {
/// **** send_IF4 of txdataF to RRU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc->frame_tx, proc->subframe_tx, IF4_PDLFFT, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
}
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
......@@ -626,10 +643,8 @@ static void* eNB_thread_rx_common( void* param ) {
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
uint8_t seqno=0;
FILE *rx_time_file = NULL;
char rx_time_name[101];
int i;
struct timespec wait;
wait.tv_sec=0;
......@@ -753,6 +768,18 @@ static void* eNB_thread_rx_common( void* param ) {
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif
// Create buffer for IF device and free when stopping
if (eNB->node_function == NGFI_RCC_IF4 || eNB->node_function == NGFI_RRU_IF4) {
malloc_IF4_buffer(eNB);
} else if (eNB->node_function == NGFI_RRU_IF5 || eNB->node_function == eNodeB_3GPP_BBU) {
//malloc_IF5_buffer(eNB);
} else {
eNB->ifbuffer.tx = NULL;
eNB->ifbuffer.rx = NULL;
}
// Start IF device for this CC
if (eNB->node_function != eNodeB_3GPP) {
if (eNB->ifdevice.trx_start_func(&eNB->ifdevice) != 0 )
......@@ -760,18 +787,12 @@ static void* eNB_thread_rx_common( void* param ) {
}
// Start RF device for this CC
if (eNB->node_function == eNodeB_3GPP || eNB->node_function == NGFI_RRU_IF4) {
if ((eNB->node_function == eNodeB_3GPP) ||
(eNB->node_function == NGFI_RRU_IF4) ||
(eNB->node_function == NGFI_RRU_IF5)) {
if (eNB->rfdevice.trx_start_func(&eNB->rfdevice) != 0 )
LOG_E(HW,"Could not start the RF device\n");
}
// proc->proc_rxtx[0].timestamp_tx = 0;
// seqno = send_IF5(eNB, &proc->proc_rxtx[0], 0);
// for (i=0; i<1000;i++) {
// seqno = send_IF5(eNB, &proc->proc_rxtx[0], seqno);
// proc->proc_rxtx[0].timestamp_tx += 7680*2;
// }
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
......
......@@ -385,9 +385,11 @@ void help (void) {
printf(" --ue-txgain set UE TX gain\n");
printf(" --ue-scan_carrier set UE to scan around carrier\n");
printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
printf(" --RCC run using NGFI RCC node function\n");
printf(" --RRU run using NGFI RRU node function\n");
printf(" --RCC run using NGFI RCC node function IF4 split\n");
printf(" --RRU run using NGFI RRU node function IF4 split\n");
printf(" --eNB run using 3GPP eNB node function\n");
printf(" --BBU run using 3GPP eNB node function with IF5 split\n");
printf(" --RRH run using RRH node function with IF5 split\n");
printf(" -C Set the downlink frequency for all component carriers\n");
printf(" -d Enable soft scope and L1 and L2 stats (Xforms)\n");
printf(" -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
......@@ -687,7 +689,8 @@ static void get_options (int argc, char **argv)
LONG_OPTION_RCC,
LONG_OPTION_RRU,
LONG_OPTION_ENB,
LONG_OPTION_ENB_BBU
LONG_OPTION_ENB_BBU,
LONG_OPTION_RRH
#if T_TRACER
,
LONG_OPTION_T_PORT,
......@@ -715,6 +718,7 @@ static void get_options (int argc, char **argv)
{"RRU", no_argument, NULL, LONG_OPTION_RRU},
{"eNB", no_argument, NULL, LONG_OPTION_ENB},
{"BBU", no_argument, NULL, LONG_OPTION_ENB_BBU},
{"RRH", no_argument, NULL, LONG_OPTION_RRH},
#if T_TRACER
{"T_port", required_argument, 0, LONG_OPTION_T_PORT},
{"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT},
......@@ -821,6 +825,10 @@ static void get_options (int argc, char **argv)
case LONG_OPTION_ENB_BBU:
node_function = eNodeB_3GPP_BBU;
break;
case LONG_OPTION_RRH:
node_function = NGFI_RRU_IF5;
break;
#if T_TRACER
case LONG_OPTION_T_PORT: {
......@@ -1650,19 +1658,13 @@ int main( int argc, char **argv )
if (UE_flag == 0) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (node_function == NGFI_RRU_IF4) {
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST;
if (node_function == NGFI_RRU_IF4 || node_function == NGFI_RRU_IF5) {
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST;
} else {
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
}
PHY_vars_eNB_g[0][CC_id]->rfdevice.type = NONE_DEV;
PHY_vars_eNB_g[0][CC_id]->rfdevice.transp_type = NONE_TP;
PHY_vars_eNB_g[0][CC_id]->ifdevice.type = NONE_DEV;
PHY_vars_eNB_g[0][CC_id]->ifdevice.transp_type = NONE_TP;
}
}
/* device host type is set*/
......@@ -1703,8 +1705,7 @@ int main( int argc, char **argv )
// Handle spatially distributed MIMO antenna ports
// Load RF device and initialize
if (node_function == NGFI_RRU_IF4 || node_function == eNodeB_3GPP) {
if (node_function == NGFI_RRU_IF5 || node_function == NGFI_RRU_IF4 || node_function == eNodeB_3GPP) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (mode!=loop_through_memory) {
returns= (UE_flag == 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