Commit 275c7a7c authored by Raymond Knopp's avatar Raymond Knopp

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5414 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent fe2e0ed0
......@@ -28,15 +28,15 @@
*******************************************************************************/
/*! \file lte-softmodem.c
* \brief main program to control HW and scheduling
* \author R. Knopp, F. Kaltenberger
* \date 2012
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
* \brief main program to control HW and scheduling
* \author R. Knopp, F. Kaltenberger
* \date 2012
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
......@@ -174,9 +174,9 @@ static pthread_t thread3; //emos
#endif
/*
static int instance_cnt=-1; //0 means worker is busy, -1 means its free
int instance_cnt_ptr_kern,*instance_cnt_ptr_user;
int pci_interface_ptr_kern;
static int instance_cnt=-1; //0 means worker is busy, -1 means its free
int instance_cnt_ptr_kern,*instance_cnt_ptr_user;
int pci_interface_ptr_kern;
*/
//extern unsigned int bigphys_top;
//extern unsigned int mem_base;
......@@ -221,14 +221,14 @@ static unsigned int rxg_byp[4] = {120,120,120,120};
static int tx_max_power = 0;
/*
uint32_t rf_mode_max[4] = {55759,55759,55759,55759};
uint32_t rf_mode_med[4] = {39375,39375,39375,39375};
uint32_t rf_mode_byp[4] = {22991,22991,22991,22991};
uint32_t rf_mode_max[4] = {55759,55759,55759,55759};
uint32_t rf_mode_med[4] = {39375,39375,39375,39375};
uint32_t rf_mode_byp[4] = {22991,22991,22991,22991};
*/
static uint32_t rf_mode[4] = {MY_RF_MODE,0,0,0};
static uint32_t rf_local[4] = {8255000,8255000,8255000,8255000}; // UE zepto
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
//{8254617, 8254617, 8254617, 8254617}; //eNB khalifa
//{8255067,8254810,8257340,8257340}; // eNB PETRONAS
static uint32_t rf_vcocal[4] = {910,910,910,910};
static uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015};
......@@ -252,6 +252,8 @@ static int mbox_bounds[20] = {8,16,24,30,38,46,54,60,68,7
static LTE_DL_FRAME_PARMS *frame_parms;
int multi_thread=0;
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
{
return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
......@@ -549,7 +551,7 @@ static void wait_system_ready (char *message, volatile int *start_flag)
}
#endif
#if defined(ENABLE_ITTI)
#if defined(ENABLE_ITTI)
void *l2l1_task(void *arg)
{
MessageDef *message_p = NULL;
......@@ -623,7 +625,183 @@ void *l2l1_task(void *arg)
}
#endif
/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void * eNB_proc_thread(void *param) {
//unsigned long cpuid;
eNB_proc_t *proc = (eNB_proc_t*)param;
int i,tx_offset;
int next_slot,last_slot;
RTIME time_in,time_out;
#ifdef RTAI
RT_TASK *task;
char task_name[8];
#endif
int dummy_tx_b[7680*4] __attribute__((aligned(16)));
unsigned int aa,slot_offset,slot_offset_F,slot_offset_F2;
#ifdef RTAI
sprintf(task_name,"eNB_proc %d",proc->subframe);
task = rt_task_init_schmod(nam2num(task_name), 0, 0, 0, SCHED_FIFO, 0xF);
if (task==NULL) {
LOG_E(PHY,"[SCHED][eNB] Problem starting eNB_proc thread_index %d (%s)!!!!\n",proc->subframe,task_name);
return 0;
}
else {
LOG_I(PHY,"[SCHED][eNB] dlsch_thread for process %d started with id %p\n",
proc->subframe,
task);
}
#endif
mlockall(MCL_CURRENT | MCL_FUTURE);
//rt_set_runnable_on_cpuid(task,1);
//cpuid = rtai_cpuid();
#ifdef HARD_RT
rt_make_hard_real_time();
#endif
last_slot = ((proc->subframe<<1)-1)%20;
next_slot = ((proc->subframe<<1)+1)%20;
while (!oai_exit){
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC0+proc->subframe,0);
if (pthread_mutex_lock(&proc->mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error locking mutex for eNB proc %d\n",proc->subframe);
}
else {
while (proc->instance_cnt < 0) {
pthread_cond_wait(&proc->cond,&proc->mutex);
}
if (pthread_mutex_unlock(&proc->mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for eNB proc %d\n",proc->subframe);
}
}
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC0+proc->subframe,1);
if (oai_exit) break;
if ((((PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == TDD)&&(subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL))||
(PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == FDD))) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(last_slot, next_slot, no_relay) != 0 )
#endif
phy_procedures_eNB_TX(next_slot,PHY_vars_eNB_g[0],0,no_relay,NULL);
}
if ((((PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == TDD )&&(subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,last_slot>>1)==SF_UL)) ||
(PHY_vars_eNB_g[0]->lte_frame_parms.frame_type == FDD))){
phy_procedures_eNB_RX(last_slot,PHY_vars_eNB_g[0],0,no_relay);
}
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(last_slot, next_slot, no_relay) != 0 )
#endif
phy_procedures_eNB_TX(next_slot,PHY_vars_eNB_g[0],0,no_relay,NULL);
}
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,last_slot>>1)==SF_S)){
phy_procedures_eNB_S_RX(last_slot,PHY_vars_eNB_g[0],0,no_relay);
}
}
slot_offset_F = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
slot_offset = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1);
slot_offset_F2 = (next_slot+1)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)||
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<PHY_vars_eNB_g[0]->lte_frame_parms.nb_antennas_tx; aa++) {
if (PHY_vars_eNB_g[0]->lte_frame_parms.Ncp == 1) {
PHY_ofdm_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F],
dummy_tx_b,
PHY_vars_eNB_g[0]->lte_frame_parms.log2_symbol_size,
6,
PHY_vars_eNB_g[0]->lte_frame_parms.nb_prefix_samples,
PHY_vars_eNB_g[0]->lte_frame_parms.twiddle_ifft,
PHY_vars_eNB_g[0]->lte_frame_parms.rev,
CYCLIC_PREFIX);
PHY_ofdm_mod(&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdataF[0][aa][slot_offset_F2],
dummy_tx_b+(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1),
PHY_vars_eNB_g[0]->lte_frame_parms.log2_symbol_size,
6,
PHY_vars_eNB_g[0]->lte_frame_parms.nb_prefix_samples,
PHY_vars_eNB_g[0]->lte_frame_parms.twiddle_ifft,
PHY_vars_eNB_g[0]->lte_frame_parms.rev,
CYCLIC_PREFIX);
}
#ifdef EXMIMO
for (i=0; i<PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti; i++) {
tx_offset = (int)slot_offset+time_offset[aa]+i;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]=
((short*)dummy_tx_b)[2*i]<<4;
((short*)&PHY_vars_eNB_g[0]->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
((short*)dummy_tx_b)[2*i+1]<<4;
}
#endif //EXMIMO
}
}
if (pthread_mutex_lock(&proc->mutex) != 0) {
msg("[openair][SCHED][eNB] error locking mutex for eNB proc %d\n",proc->subframe);
}
else {
proc->instance_cnt--;
if (pthread_mutex_unlock(&proc->mutex) != 0) {
msg("[openair][SCHED][eNB] error unlocking mutex for eNB proc %d\n",proc->subframe);
}
}
#ifdef HARD_RT
rt_make_soft_real_time();
#endif
}
void init_eNB_proc() {
int i;
for (i=0;i<10;i++) {
PHY_vars_eNB_g[0]->proc[i].instance_cnt=0;
PHY_vars_eNB_g[0]->proc[i].subframe=i;
pthread_mutex_init(&PHY_vars_eNB_g[0]->proc[i].mutex,NULL);
pthread_cond_init(&PHY_vars_eNB_g[0]->proc[i].cond,NULL);
pthread_create(&PHY_vars_eNB_g[0]->proc[i].pthread,NULL,eNB_proc_thread,(void*)&PHY_vars_eNB_g[0]->proc[i]);
}
}
void kill_eNB_proc() {
int i;
for (i=0;i<10;i++) {
pthread_join(PHY_vars_eNB_g[0]->proc[i].pthread,NULL);
pthread_mutex_destroy(&PHY_vars_eNB_g[0]->proc[i].mutex);
pthread_cond_destroy(&PHY_vars_eNB_g[0]->proc[i].cond);
}
}
/* This is the main eNB thread. */
static void *eNB_thread(void *arg)
{
#ifdef RTAI
......@@ -638,6 +816,7 @@ static void *eNB_thread(void *arg)
int mbox_target=0,mbox_current=0;
int i,ret;
int tx_offset;
int sf;
#if defined(ENABLE_ITTI)
/* Wait for eNB application initialization to be complete (eNB registration to MME) */
......@@ -726,7 +905,7 @@ static void *eNB_thread(void *arg)
last_slot = (slot)%LTE_SLOTS_PER_FRAME;
if (last_slot <0)
last_slot+=20;
next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
next_slot = (slot+2)%LTE_SLOTS_PER_FRAME;
//PHY_vars_eNB_g[0]->frame = frame;
if (frame>5)
......@@ -763,15 +942,15 @@ static void *eNB_thread(void *arg)
if (fs4_test==0)
{
if (multi_thread == 0) {
phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[0], 0, no_relay,NULL);
#ifndef IFFT_FPGA
slot_offset_F = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.ofdm_symbol_size)*
((PHY_vars_eNB_g[0]->lte_frame_parms.Ncp==1) ? 6 : 7);
slot_offset = (next_slot)*
(PHY_vars_eNB_g[0]->lte_frame_parms.samples_per_tti>>1);
if ((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_DL)||
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)&&((next_slot&1)==0)))
((subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms,next_slot>>1)==SF_S)))
{
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
......@@ -820,14 +999,22 @@ static void *eNB_thread(void *arg)
}
}
}
else { // multi-thread > 0
#endif //IFFT_FPGA
/*
if (frame%100==0)
LOG_D(HW,"hw_slot %d (after): DAQ_MBOX %d\n",hw_slot,DAQ_MBOX[0]);
*/
if ((slot&1) == 0) {
sf = (slot<<1)+1;
if (PHY_vars_eNB_g[0]->proc[sf].instance_cnt == 0) {
if (pthread_cond_signal(&PHY_vars_eNB_g[0]->proc[sf].cond) != 0) {
LOG_E(PHY,"[eNB] ERROR pthread_cond_signal for eNB proc %d\n",sf);
}
}
else {
LOG_W(PHY,"[eNB] Frame %d, eNB proc %d busy!!\n",PHY_vars_eNB_g[0]->frame,sf);
}
}
}
}
}
/*
if ((slot%2000)<10)
LOG_D(HW,"fun0: doing very hard work\n");
......@@ -856,11 +1043,11 @@ static void *eNB_thread(void *arg)
#endif
LOG_D(HW,"Task deleted. returning\n");
return 0;
}
}
/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void *UE_thread(void *arg)
{
/* This is the main UE thread. Initially it is doing a periodic get_frame. One synchronized it gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void *UE_thread(void *arg)
{
#ifdef RTAI
RT_TASK *task;
#endif
......@@ -1091,10 +1278,10 @@ static void *UE_thread(void *arg)
#endif
LOG_D(HW,"Task deleted. returning\n");
return 0;
}
}
static void get_options (int argc, char **argv)
{
static void get_options (int argc, char **argv)
{
int c;
char line[1000];
int l;
......@@ -1122,7 +1309,7 @@ static void get_options (int argc, char **argv)
{"no-L2-connect", no_argument, NULL, LONG_OPTION_NO_L2_CONNECT},
{NULL, 0, NULL, 0}};
while ((c = getopt_long (argc, argv, "C:dF:K:qO:ST:UVR",long_options,NULL)) != -1)
while ((c = getopt_long (argc, argv, "C:dF:K:qO:ST:UVRM",long_options,NULL)) != -1)
{
switch (c)
{
......@@ -1156,7 +1343,9 @@ static void get_options (int argc, char **argv)
case LONG_OPTION_NO_L2_CONNECT:
mode = no_L2_connect;
break;
case 'M':
multi_thread=1;
break;
case 'C':
downlink_frequency[0] = atof(optarg); // Use float to avoid issue with frequency over 2^31.
downlink_frequency[1] = downlink_frequency[0];
......@@ -1296,9 +1485,9 @@ static void get_options (int argc, char **argv)
uplink_frequency_offset[i] = enb_properties->properties[0]->uplink_frequency_offset;
}
}
}
}
int main(int argc, char **argv) {
int main(int argc, char **argv) {
#ifdef RTAI
// RT_TASK *task;
#endif
......@@ -1740,7 +1929,7 @@ int main(int argc, char **argv) {
#endif
#ifdef OPENAIR2
//if (otg_enabled) {
//if (otg_enabled) {
init_all_otg(0);
g_otg->seed = 0;
init_seeds(g_otg->seed);
......@@ -1754,7 +1943,7 @@ int main(int argc, char **argv) {
}
}
init_predef_traffic(UE_flag ? 1 : 0, UE_flag ? 0 : 1);
// }
// }
#endif
#ifdef OPENAIR2
......@@ -1983,6 +2172,9 @@ int main(int argc, char **argv) {
#ifdef ULSCH_THREAD
init_ulsch_threads();
#endif
init_eNB_proc();
printf("eNB threads created\n");
}
......@@ -2073,9 +2265,9 @@ int main(int argc, char **argv) {
logClean();
return 0;
}
}
void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) {
void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) {
p_exmimo_config->framing.eNB_flag = !UE_flag;
p_exmimo_config->framing.tdd_config = 0;
#if (BOARD_SWREV_CNTL2>=0x0A)
......@@ -2093,9 +2285,9 @@ void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) {
p_exmimo_config->rf.rf_local[ant] = build_rflocal(20,25,26,04);
p_exmimo_config->rf.rf_rxdc[ant] = build_rfdc(128, 128);
p_exmimo_config->rf.rf_vcocal[ant] = (0xE<<6) + 0xE;
}
}
void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
int i;
if (phy_vars_ue) {
......@@ -2124,9 +2316,9 @@ void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms,
printf("txdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.txdata[i]);
}
}
}
}
void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier) {
int i,j;
......@@ -2163,4 +2355,4 @@ void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_par
}
}
}
}
}
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