diff --git a/srsapps/common/include/srsapps/common/binsem.h b/srsapps/common/include/srsapps/common/binsem.h deleted file mode 100644 index 5a8cad53c..000000000 --- a/srsapps/common/include/srsapps/common/binsem.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include - -#ifndef BINSEM_H -#define BINSEM_H - -/** Implementation of a binary semaphore using POSIX condition variable and mutex - */ - -namespace srslte { - - class binsem - { - public: - binsem() { - pthread_mutex_init(&mutex, NULL); - pthread_cond_init(&cv, NULL); - state = true; - } - ~binsem() { - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cv); - } - void take() { - pthread_mutex_lock(&mutex); - while(!state) { - pthread_cond_wait(&cv, &mutex); - } - state = false; - pthread_mutex_unlock(&mutex); - } - void give() { - pthread_mutex_lock(&mutex); - pthread_cond_signal(&cv); - state = true; - pthread_mutex_unlock(&mutex); - } - private: - pthread_cond_t cv; - pthread_mutex_t mutex; - bool state; - }; -} - -#endif diff --git a/srsapps/common/include/srsapps/common/queue.h b/srsapps/common/include/srsapps/common/queue.h deleted file mode 100644 index 4d7889ea6..000000000 --- a/srsapps/common/include/srsapps/common/queue.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include -/****************************************************************************** - * File: queue.h - * - * Description: Queue used at interface of PHY/MAC - * - * Reference: - *****************************************************************************/ - - - -#ifndef QUEUE_H -#define QUEUE_H - -namespace srslte { -namespace ue { - -class queue -{ -public: - - class element - { - public: - element() { - state = READY; - tti = 0; - } - ~element(); - void release() - { - state = RELEASED; - } - bool is_released() - { - return state == RELEASED; - } - void ready() { - state = READY; - } - bool is_ready() { - return state == READY; - } - uint32_t tti; - protected: - enum { - RELEASED, READY - } state; - }; - - queue(uint32_t nof_elements, uint32_t element_size); - ~queue(); - - element* get(uint32_t tti); - -private: - uint32_t nof_elements; - uint32_t element_size; - element* *buffer_of_elements; - -}; - -} - -} -#endif - diff --git a/srsapps/common/include/srsapps/common/threads.h b/srsapps/common/include/srsapps/common/threads.h index f8ad2c43b..d35a217db 100644 --- a/srsapps/common/include/srsapps/common/threads.h +++ b/srsapps/common/include/srsapps/common/threads.h @@ -38,5 +38,31 @@ #ifdef __cplusplus } + +#ifndef THREADS_ +#define THREADS_ + +class thread +{ +public: + bool start(uint32_t prio = 0) { + return threads_new_rt_prio(&_thread, thread_function_entry, this, prio); + } + void print_priority() { + threads_print_self(); + } + void wait_thread_finish() { + pthread_join(_thread, NULL); + } +protected: + virtual void run_thread() = 0; +private: + static void *thread_function_entry(void *_this) { ((thread*) _this)->run_thread();} + pthread_t _thread; +}; + + +#endif + #endif diff --git a/srsapps/common/include/srsapps/common/tti_sync.h b/srsapps/common/include/srsapps/common/tti_sync.h deleted file mode 100644 index 7a45939ea..000000000 --- a/srsapps/common/include/srsapps/common/tti_sync.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - - -#include - - -#ifndef TTISYNC_H -#define TTISYNC_H - - -namespace srslte { -namespace ue { - - /* Interface used for PHY-MAC synchronization (producer-consumer model). - * The consumer waits while its counter is lower than the producer counter. - * The PHY is the consumer. The MAC is the producer. - */ -class tti_sync -{ - public: - tti_sync(uint32_t modulus_) - { - modulus = modulus_; - increment = 1; - init_counters(0); - } - virtual void increase() = 0; - virtual void resync() = 0; - virtual uint32_t wait() = 0; - virtual void set_producer_cntr(uint32_t) = 0; - uint32_t get_producer_cntr() { return producer_cntr; } - uint32_t get_consumer_cntr() { return consumer_cntr; } - void set_increment(uint32_t increment_) { - increment = increment_; - } - protected: - void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; } - void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; } - bool wait_condition() { return producer_cntr == consumer_cntr; } - void init_counters(uint32_t val) - { - consumer_cntr = val; - producer_cntr = val; - } - uint32_t increment; - uint32_t modulus; - uint32_t producer_cntr; - uint32_t consumer_cntr; -}; -} -} - -#endif diff --git a/srsapps/common/include/srsapps/common/tti_sync_cv.h b/srsapps/common/include/srsapps/common/tti_sync_cv.h deleted file mode 100644 index a4026f42e..000000000 --- a/srsapps/common/include/srsapps/common/tti_sync_cv.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include -#include "srsapps/common/tti_sync.h" - - -#ifndef TTISYNC_CV_H -#define TTISYNC_CV_H - - -namespace srslte { -namespace ue { - - /* Implements tti_sync interface with condition variables. - */ - -class tti_sync_cv : public tti_sync -{ - public: - tti_sync_cv(uint32_t modulus = 10240); - ~tti_sync_cv(); - void increase(); - uint32_t wait(); - void resync(); - void set_producer_cntr(uint32_t producer_cntr); - - private: - pthread_cond_t cond; - pthread_mutex_t mutex; -}; -} -} - -#endif diff --git a/srsapps/common/src/queue.cc b/srsapps/common/src/queue.cc deleted file mode 100644 index 3f51cec83..000000000 --- a/srsapps/common/src/queue.cc +++ /dev/null @@ -1,64 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include "srsapps/common/queue.h" - -namespace srslte { -namespace ue { - queue::queue(uint32_t nof_elements_, uint32_t element_size) - { - nof_elements = nof_elements_; - buffer_of_elements = (queue::element**) malloc(sizeof(queue::element*) * nof_elements); - for (int i=0;itti = tti; - return el; - } - -} // namespace ue -} // namespace srslte - diff --git a/srsapps/common/src/tti_sync_cv.cc b/srsapps/common/src/tti_sync_cv.cc deleted file mode 100644 index da5b5096a..000000000 --- a/srsapps/common/src/tti_sync_cv.cc +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include - -#include "srsapps/common/tti_sync_cv.h" - -namespace srslte { - namespace ue { - - tti_sync_cv::tti_sync_cv(uint32_t modulus): tti_sync(modulus) - { - pthread_mutex_init(&mutex, NULL); - pthread_cond_init(&cond, NULL); - } - - tti_sync_cv::~tti_sync_cv() - { - pthread_cond_destroy(&cond); - pthread_mutex_destroy(&mutex); - } - - uint32_t tti_sync_cv::wait() - { - pthread_mutex_lock(&mutex); - while(wait_condition()) { - pthread_cond_wait(&cond, &mutex); - } - uint32_t x = consumer_cntr; - increase_consumer(); - pthread_mutex_unlock(&mutex); - return x; - } - - void tti_sync_cv::resync() - { - consumer_cntr = producer_cntr; - } - - void tti_sync_cv::set_producer_cntr(uint32_t producer_cntr) - { - pthread_mutex_lock(&mutex); - init_counters(producer_cntr); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - } - - void tti_sync_cv::increase() - { - pthread_mutex_lock(&mutex); - increase_producer(); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - } - } -} diff --git a/srsapps/ue/CMakeLists.txt b/srsapps/ue/CMakeLists.txt index 980e7c5a1..c23f9567e 100644 --- a/srsapps/ue/CMakeLists.txt +++ b/srsapps/ue/CMakeLists.txt @@ -23,5 +23,5 @@ INCLUDE_DIRECTORIES(phy/include/) INCLUDE_DIRECTORIES(mac/include/) add_subdirectory(phy) -add_subdirectory(mac) +#add_subdirectory(mac) diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac_params.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac_params.h index 4c9c55e6c..b4ee6c5d1 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac_params.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac_params.h @@ -44,57 +44,6 @@ namespace ue { mac_params() : params_db(NOF_PARAMS) {} ~mac_params() {} - typedef enum { - - // These 4 parameters must be together!! - RNTI_C = 0, - RNTI_SPS, - RNTI_TEMP, - RNTI_RA, - - SPS_DL_SCHED_INTERVAL, - SPS_DL_NOF_PROC, - - BCCH_SI_WINDOW_ST, - BCCH_SI_WINDOW_LEN, - - PCCH_RECEIVE, - - CONTENTION_ID, // Transmitted UE Contention ID - - TIMER_TIMEALIGN, - - // Random Access parameters. See 5.1.1 - RA_CONFIGINDEX, - RA_PREAMBLEINDEX, - RA_MASKINDEX, - RA_NOFPREAMBLES, - RA_NOFGROUPAPREAMBLES, - RA_MESSAGEPOWEROFFSETB, - RA_MESSAGESIZEA, - RA_PCMAX, - RA_DELTAPREAMBLEMSG3, - RA_RESPONSEWINDOW, - RA_POWERRAMPINGSTEP, - RA_PREAMBLETRANSMAX, - RA_INITRECEIVEDPOWER, - RA_CONTENTIONTIMER, - - SR_PUCCH_CONFIGURED, - SR_TRANS_MAX, - - BSR_TIMER_PERIODIC, - BSR_TIMER_RETX, - - HARQ_MAXTX, - HARQ_MAXMSG3TX, - - PDSCH_RSPOWER, - PDSCH_PB, - - - NOF_PARAMS, - } mac_param_t; }; } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h deleted file mode 100644 index c060012b5..000000000 --- a/srsapps/ue/phy/include/srsapps/ue/phy/dl_buffer.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include "srslte/srslte.h" -#include "srsapps/common/log.h" -#include "srsapps/common/queue.h" -#include "srsapps/ue/phy/ul_sched_grant.h" -#include "srsapps/ue/phy/dl_sched_grant.h" -#include "srsapps/ue/phy/phy_params.h" - -#ifndef UEDLBUFFER_H -#define UEDLBUFFER_H - -namespace srslte { -namespace ue { - - /* Class for the processing of Downlink buffers. The MAC obtains a buffer for a given TTI and then - * gets ul/dl scheduling grants and/or processes phich/pdsch channels - */ - class dl_buffer : public queue::element { - public: - - int buffer_id; - - bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h_); - void free_cell(); - void set_crnti(uint16_t rnti); - bool recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time); - bool get_ul_grant(ul_sched_grant *grant); - bool get_dl_grant(dl_sched_grant *grant); - void discard_pending_rar_grant(); - void set_rar_grant(srslte_dci_rar_grant_t *rar_grant); - void set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]); - void reset_softbuffer(); - bool decode_ack(ul_sched_grant *pusch_grant); - bool decode_data(dl_sched_grant *pdsch_grant, uint8_t *payload); // returns true or false for CRC OK/NOK - bool decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softbuffer, uint8_t *payload); - - private: - phy_params *params_db; - log *log_h; - srslte_cell_t cell; - srslte_ue_dl_t ue_dl; - srslte_phich_t phich; - cf_t *signal_buffer; - uint32_t cfi; - bool sf_symbols_and_ce_done; - bool pdcch_llr_extracted; - bool pending_rar_grant; - srslte_dci_rar_grant_t rar_grant; - }; -} -} -#endif diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/dl_sched_grant.h b/srsapps/ue/phy/include/srsapps/ue/phy/dl_sched_grant.h deleted file mode 100644 index 956160c54..000000000 --- a/srsapps/ue/phy/include/srsapps/ue/phy/dl_sched_grant.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include - -#include "srslte/srslte.h" -#include "srsapps/ue/phy/sched_grant.h" - -#ifndef UEDLSCHEDGRANT_H -#define UEDLSCHEDGRANT_H - -namespace srslte { -namespace ue { - - /* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */ - class dl_sched_grant : public sched_grant { - public: - - dl_sched_grant(rnti_type_t type, uint16_t rnti) : sched_grant(type, rnti) {} - dl_sched_grant(uint16_t rnti) : sched_grant(rnti) {} - - uint32_t get_rv() { - return dl_dci.rv_idx; - } - void set_rv(uint32_t rv) { - dl_dci.rv_idx = rv; - } - bool get_ndi() { - return dl_dci.ndi; - } - void set_ndi(bool value) { - dl_dci.ndi = value; - } - uint32_t get_harq_process() { - return dl_dci.harq_process; - } - void get_dl_grant(srslte_ra_dl_grant_t *ul_grant) { - memcpy(ul_grant, &grant, sizeof(srslte_ra_dl_grant_t)); - } - bool is_sps_release() { - return false; - } - uint32_t get_tbs() { - return grant.mcs.tbs; - } - uint32_t get_ncce() { - return ncce; - } - uint32_t get_mcs() { - return dl_dci.mcs_idx; - } - const char* get_dciformat_string() { - switch(dl_dci.dci_format) { - case srslte_ra_dl_dci_t::SRSLTE_RA_DCI_FORMAT1: - return "Format1"; - case srslte_ra_dl_dci_t::SRSLTE_RA_DCI_FORMAT1A: - return "Format1A"; - case srslte_ra_dl_dci_t::SRSLTE_RA_DCI_FORMAT1C: - return "Format1C"; - } - } - bool create_from_dci(srslte_dci_msg_t *msg, uint32_t nof_prb, uint32_t ncce_) { - ncce = ncce_; - if (srslte_dci_msg_to_dl_grant(msg, rnti, nof_prb, &dl_dci, &grant)) { - return false; - } else { - return true; - } - } - bool get_pdsch_cfg(uint32_t sf_idx, uint32_t cfi, srslte_ue_dl_t *ue_dl) { - memcpy(&ue_dl->pdsch_cfg.grant, &grant, sizeof(srslte_ra_dl_grant_t)); - - /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ - if (srslte_ue_dl_cfg_grant(ue_dl, NULL, cfi, sf_idx, rnti, get_rv())) { - return false; - } - return true; - } - private: - srslte_ra_dl_grant_t grant; - srslte_ra_dl_dci_t dl_dci; - uint32_t ncce; - }; - -} -} - -#endif diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h index 7fac5b204..7757144a5 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h @@ -29,153 +29,105 @@ #include "srslte/srslte.h" +#include "srsapps/common/phy_interface.h" #include "srsapps/common/log.h" -#include "srsapps/common/tti_sync.h" -#include "srsapps/ue/phy/dl_buffer.h" -#include "srsapps/ue/phy/ul_buffer.h" +#include "srsapps/ue/phy/phch_recv.h" #include "srsapps/ue/phy/prach.h" #include "srsapps/ue/phy/phy_params.h" -#include "srsapps/ue/phy/sched_grant.h" -#include "srsapps/common/queue.h" +#include "srsapps/ue/phy/phch_worker.h" +#include "srsapps/ue/phy/phch_common.h" #include "srsapps/radio/radio.h" +#include "srsapps/common/task_dispatcher.h" #include "srsapps/common/trace.h" +#include "srsapps/common/mac_interface.h" #ifndef UEPHY_H #define UEPHY_H namespace srslte { namespace ue { - - -/* The procedure for attaching to an eNodeB is the following: - * - * 1) Call init() to initialize the PHY (starts an internal thread) - * 2) Call set_rx_freq() and set_rx_gain() to set Downlink frequency and receiver gain - * 3) Call decode_mib() to receive and decode MIB from PBCH in the current frequency - * 4) Call set_cell() to set the current eNodeB - * 5) Call start_rxtx() to start continuous RX/TX stream - * 6) Call set_tx_freq()/set_tx_gain() to set Uplink frequency and transmitter gain - * 7) Call send_prach() to send the PRACH - * - */ - + typedef _Complex float cf_t; -class phy +class phy : public phy_interface, phy_interface_params { public: phy(); - void set(); - bool init(radio *radio_handler, tti_sync *ttisync, log *log_h); - bool init_agc(radio *radio_handler, tti_sync *ttisync, log *log_h); + bool init(radio *radio_handler, mac_interface_phy *mac, log *log_h); + bool init_agc(radio *radio_handler, mac_interface_phy *mac, log *log_h); void stop(); - - // These functions can be called only if PHY is in IDLE (ie, not RX/TX) - bool measure(); // TBD - bool decode_mib(uint32_t N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]); - bool decode_mib_best(srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]); - bool set_cell(srslte_cell_t cell); - - // Sets the PHY in continuous RX/TX mode - bool start_rxtx(); - bool stop_rxtx(); - - float get_agc_gain(); void set_crnti(uint16_t rnti); - void pregen_signals(); - // Indicate the PHY to send PRACH as soon as possible - bool init_prach(); - bool send_prach(uint32_t preamble_idx); - bool send_prach(uint32_t preamble_idx, int allowed_subframe); - bool send_prach(uint32_t preamble_idx, int allowed_subframe, int target_power_dbm); - - // Indicate the PHY to send SR as soon as possible or not - void send_sr(bool enable); - int sr_last_tx_tti(); + // Get status + bool status_is_sync(); - // Returns TTI when PRACH was transmitted. -1 if not yet transmitted - int get_prach_transmitted_tti(); + static uint32_t tti_to_SFN(uint32_t tti); + static uint32_t tti_to_subf(uint32_t tti); - // Get handler to the radio - radio* get_radio(); - - // Time advance commands - void set_timeadv_rar(uint32_t ta_cmd); - void set_timeadv(uint32_t ta_cmd); + void enable_pregen_signals(bool enable); - // Convert Msg3 UL grant to ul_sched_grant - void rar_ul_grant(srslte_dci_rar_grant_t *rar, ul_sched_grant *grant); + void start_trace(); + void write_trace(std::string filename); - // Get status - bool status_is_idle(); - bool status_is_rxtx(); + /********** MAC INTERFACE ********************/ + /* Instructs the PHY to configure using the parameters written with set_param() */ + void configure_prach_params(); + void configure_ul_params(); + + /* Functions to synchronize with a cell */ + void sync_start(); + void sync_stop(); - void set_param(phy_params::phy_param_t param, int64_t value); - int64_t get_param(phy_params::phy_param_t param); + /* Functions to initialize and transmit PRACH in the next opportunity */ + void prach_send(prach_cfg_t *cfg); - uint32_t get_current_tti(); - static uint32_t tti_to_SFN(uint32_t tti); - static uint32_t tti_to_subf(uint32_t tti); + /* Indicates the transmission of a SR signal in the next opportunity */ + void sr_send(); - ul_buffer* get_ul_buffer(uint32_t tti); - dl_buffer* get_dl_buffer(uint32_t tti); + // Time advance commands + void set_timeadv_rar(uint32_t ta_cmd); + void set_timeadv(uint32_t ta_cmd); + + /* Sets RAR grant payload */ + void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]); - void start_trace(); - void write_trace(std::string filename); + /* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */ + void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1); + void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1); - bool sr_is_ready_to_send(uint32_t tti); - bool cqi_is_ready_to_send(uint32_t tti); + /* Get/Set PHY parameters */ + void set_param(phy_param_t param, int64_t value); + int64_t get_param(phy_param_t param); - void main_radio_loop(); + void reset(); -private: - enum { - IDLE, RXTX - } phy_state; + uint32_t get_current_tti(); - static const int NOF_ULDL_QUEUES = 10; +private: + + const static int NOF_WORKERS = 1; + const static int SF_RECV_THREAD_PRIO = 1; + const static int WORKERS_THREAD_PRIO = 0; - tti_sync *ttisync; radio *radio_handler; log *log_h; + + thread_pool workers_pool; + std::vector workers; + phch_common workers_common; + phch_recv sf_recv; + prach prach_buffer; - srslte_cell_t cell; - bool cell_is_set; - bool is_sfn_synched; - volatile bool started; - - srslte_ue_sync_t ue_sync; - srslte_ue_mib_t ue_mib; - - queue *ul_buffer_queue; - queue *dl_buffer_queue; - prach prach_buffer; phy_params params_db; - pthread_t phy_thread; - float time_adv_sec; + /* Current time advance */ uint32_t n_ta; - bool radio_is_streaming; - srslte_timestamp_t last_rx_time; - float cellsearch_cfo; - bool do_agc; - double last_gain; - bool sr_enabled; - - bool init_(radio *radio_handler, tti_sync *ttisync, log *log_h, bool do_agc); - static void *phy_thread_fnc(void *arg); - bool decode_mib_N_id_2(int force_N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]); - int sync_sfn(); - void run_rx_tx_state(); - ul_buffer* get_ul_buffer_adv(uint32_t tti); - float old_gain; - uint32_t sr_tx_tti; - - bool is_first_of_burst; + srslte_cell_t cell; + bool init_(radio *radio_handler, mac_interface_phy *mac, log *log_h, bool do_agc); + trace tr_start_time; trace tr_end_time; bool tr_enabled; diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h index 1096eedb3..33ae1dc1a 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h @@ -29,6 +29,7 @@ #include "srslte/srslte.h" #include "srsapps/common/params_db.h" +#include "srsapps/common/phy_interface.h" #ifndef PHYPARAMS_H #define PHYPARAMS_H @@ -41,77 +42,10 @@ namespace ue { { public: - phy_params() : params_db(NOF_PARAMS) { } + phy_params() : params_db(phy_interface_params::NOF_PARAMS) { } ~phy_params() {} - typedef enum { - - DL_FREQ = 0, - UL_FREQ, - - CELLSEARCH_TIMEOUT_PSS_NFRAMES, - CELLSEARCH_TIMEOUT_MIB_NFRAMES, - CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD, // integer that will be divided by 10 - - PUSCH_BETA, - PUSCH_EN_64QAM, - PUSCH_RS_CYCLIC_SHIFT, - PUSCH_RS_GROUP_ASSIGNMENT, - DMRS_GROUP_HOPPING_EN, - DMRS_SEQUENCE_HOPPING_EN, - - PUSCH_HOPPING_N_SB, - PUSCH_HOPPING_INTRA_SF, - PUSCH_HOPPING_OFFSET, - - PUCCH_BETA, - PUCCH_DELTA_SHIFT, - PUCCH_CYCLIC_SHIFT, - PUCCH_N_RB_2, - PUCCH_N_PUCCH_1_0, - PUCCH_N_PUCCH_1_1, - PUCCH_N_PUCCH_1_2, - PUCCH_N_PUCCH_1_3, - PUCCH_N_PUCCH_1, - PUCCH_N_PUCCH_2, - PUCCH_N_PUCCH_SR, - - SR_CONFIG_INDEX, - - SRS_BETA, - SRS_UE_TXCOMB, - SRS_UE_NRRC, - SRS_UE_DURATION, - SRS_UE_CONFIGINDEX, - SRS_UE_BW, - SRS_UE_HOP, - SRS_UE_CS, - SRS_UE_CYCLICSHIFT, - SRS_CS_BWCFG, - SRS_CS_SFCFG, - SRS_CS_ACKNACKSIMUL, - SRS_IS_CONFIGURED, - - CQI_PERIODIC_PMI_IDX, - CQI_PERIODIC_SIMULT_ACK, - CQI_PERIODIC_FORMAT_SUBBAND, - CQI_PERIODIC_FORMAT_SUBBAND_K, - CQI_PERIODIC_CONFIGURED, - - UCI_I_OFFSET_ACK, - UCI_I_OFFSET_RI, - UCI_I_OFFSET_CQI, - - PRACH_CONFIG_INDEX, - PRACH_ROOT_SEQ_IDX, - PRACH_HIGH_SPEED_FLAG, - PRACH_ZC_CONFIG, - PRACH_FREQ_OFFSET, - - NOF_PARAMS, - } phy_param_t; - }; } } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h index 149a0966a..853fb496a 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/prach.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/prach.h @@ -30,7 +30,7 @@ #include "srslte/srslte.h" #include "srsapps/radio/radio.h" #include "srsapps/common/log.h" -#include "srsapps/common/queue.h" +#include "srsapps/common/phy_interface.h" #include "srsapps/ue/phy/phy_params.h" #ifndef UEPRACH_H @@ -46,14 +46,16 @@ namespace ue { initiated = false; signal_buffer = NULL; } - bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h); + void init(phy_params *params_db, log *log_h); + bool init_cell(srslte_cell_t cell); void free_cell(); - bool prepare_to_send(uint32_t preamble_idx); - bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe); - bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe, int target_power_dbm); + bool prepare_to_send(phy_interface::prach_cfg_t* cfg); + bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1); bool is_ready_to_send(uint32_t current_tti); - int get_transmitted_tti(); - bool send(srslte::radio* radio_handler, float cfo, srslte_timestamp_t rx_time); + void get_rar_cfg(uint16_t* rar_rnti, uint32_t* tti_start, uint32_t* tti_end); + + bool send(radio* radio_handler, float cfo, srslte_timestamp_t rx_time); + private: static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission phy_params *params_db; @@ -68,6 +70,8 @@ namespace ue { srslte_cell_t cell; cf_t *signal_buffer; srslte_cfo_t cfo_h; + + phy_interface::prach_cfg_t prach_cfg; }; } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/sched_grant.h b/srsapps/ue/phy/include/srsapps/ue/phy/sched_grant.h deleted file mode 100644 index 8933a9a61..000000000 --- a/srsapps/ue/phy/include/srsapps/ue/phy/sched_grant.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include "srslte/srslte.h" -#include "srsapps/common/queue.h" - -#ifndef UESCHEDGRANT_H -#define UESCHEDGRANT_H - -namespace srslte { -namespace ue { - - /* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */ - class sched_grant { - public: - typedef enum { - RNTI_TYPE_NOTDEFINED = 0, - RNTI_TYPE_CRNTI, - RNTI_TYPE_RA, - RNTI_TYPE_SPS, - RNTI_TYPE_TEMP, - RNTI_TYPE_SIRNTI, - RNTI_TYPE_PRNTI, - RNTI_TYPE_TPC_PUSCH, - RNTI_TYPE_TPC_PUCCH - } rnti_type_t; - - sched_grant(uint16_t rnti_) { - rnti = rnti_; - rnti_type = RNTI_TYPE_NOTDEFINED; - } - sched_grant(rnti_type_t rnti_type_, uint16_t rnti_) { - rnti = rnti_; - rnti_type = rnti_type_; - } - uint16_t get_rnti() { - return rnti; - } - bool is_temp_rnti() { - return rnti_type == RNTI_TYPE_TEMP; - } - bool is_crnti() { - return rnti_type == RNTI_TYPE_CRNTI; - } - bool is_ra_rnti() { - return rnti_type == RNTI_TYPE_RA; - } - bool is_SPS_rnti() { - return rnti_type == RNTI_TYPE_SPS; - } - bool is_sys_rnti() { - return (rnti_type == RNTI_TYPE_SIRNTI || rnti_type == RNTI_TYPE_PRNTI); - } - bool is_tpc_rnti() { - return (rnti_type == RNTI_TYPE_TPC_PUSCH || rnti_type == RNTI_TYPE_TPC_PUCCH); - } - uint32_t get_tti() { - return tti; - } - void set_tti(uint32_t tti_) { - tti = tti_; - } - virtual uint32_t get_rv() = 0; - virtual void set_rv(uint32_t rv) = 0; - virtual bool get_ndi() = 0; - virtual void set_ndi(bool value) = 0; - virtual bool is_sps_release() = 0; - virtual uint32_t get_tbs() = 0; - protected: - uint16_t rnti; - rnti_type_t rnti_type; - uint32_t tti; - }; - -} -} - -#endif diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h deleted file mode 100644 index a9af179f3..000000000 --- a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h +++ /dev/null @@ -1,89 +0,0 @@ - /** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include "srslte/srslte.h" -#include "srsapps/radio/radio.h" -#include "srsapps/common/log.h" -#include "srsapps/common/queue.h" -#include "srsapps/ue/phy/ul_sched_grant.h" -#include "srsapps/ue/phy/dl_sched_grant.h" -#include "srsapps/ue/phy/phy_params.h" -#include "srsapps/radio/radio.h" - -#ifndef UEULBUFFER_H -#define UEULBUFFER_H - - -namespace srslte { -namespace ue { - - /* Uplink scheduling assignment. The MAC instructs the PHY to prepare an UL packet (PUSCH or PUCCH) - * for transmission. The MAC must call generate_data() to set the packet ready for transmission - */ - class ul_buffer : public queue::element { - - public: - bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h, radio *radio_h); - void free_cell(); - void set_crnti(uint16_t rnti); - void set_current_tx_nb(uint32_t current_tx_nb); - bool generate_ack(bool ack, dl_sched_grant *last_dl_grant); - bool generate_ack(bool ack[2]); - bool generate_sr(); - bool generate_cqi_report(); - bool uci_ready(); - bool srs_is_ready_to_send(); - bool generate_data(); - bool generate_data(ul_sched_grant *pusch_grant, uint8_t *payload); - bool generate_data(ul_sched_grant *pusch_grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload); - void set_tx_params(float cfo, float time_adv_sec, srslte_timestamp_t tx_time); - void send_end_of_burst(); - void send(); - void pregen_signals(); - static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission - static const bool normalize_amp = true; - private: - log *log_h; - phy_params *params_db; - radio *radio_h; - float cfo; - srslte_timestamp_t tx_time; - srslte_cell_t cell; - srslte_ue_ul_t ue_ul; - bool cell_initiated; - cf_t* signal_buffer; - uint32_t current_tx_nb; - uint32_t last_n_cce; - srslte_uci_data_t uci_data; - bool uci_pending; - }; - -} -} - -#endif \ No newline at end of file diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/ul_sched_grant.h b/srsapps/ue/phy/include/srsapps/ue/phy/ul_sched_grant.h deleted file mode 100644 index b8df04eb2..000000000 --- a/srsapps/ue/phy/include/srsapps/ue/phy/ul_sched_grant.h +++ /dev/null @@ -1,134 +0,0 @@ - /** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ -#include - - -#include "srslte/srslte.h" -#include "srsapps/ue/phy/sched_grant.h" - -#ifndef UEULSCHEDGRANT_H -#define UEULSCHEDGRANT_H - -namespace srslte { -namespace ue { - - /* Uplink/Downlink scheduling grant generated by a successfully decoded PDCCH */ - class ul_sched_grant : public sched_grant { - public: - - ul_sched_grant(rnti_type_t type, uint16_t rnti) : sched_grant(type, rnti) {} - ul_sched_grant(uint16_t rnti) : sched_grant(rnti) {} - - uint32_t get_rv() { - return ul_dci.rv_idx; - } - void set_rv(uint32_t rv) { - ul_dci.rv_idx = rv; - } - bool get_ndi() { - return ul_dci.ndi; - } - void set_ndi(bool value) { - ul_dci.ndi = value; - } - bool get_cqi_request() { - return ul_dci.cqi_request; - } - void get_ul_grant(srslte_ra_ul_grant_t *ul_grant) { - memcpy(ul_grant, &grant, sizeof(srslte_ra_ul_grant_t)); - } - bool is_sps_release() { - return false; - } - uint32_t get_tbs() { - return grant.mcs.tbs; - } - uint32_t get_mcs() { - return ul_dci.mcs_idx; - } - uint32_t get_current_tx_nb() { - return current_tx_nb; - } - void set_current_tx_nb(uint32_t current_tx_nb) { - current_tx_nb = current_tx_nb; - } - uint32_t get_I_lowest() { - return grant.n_prb[0]; - } - uint32_t get_n_dmrs() { - return ul_dci.n_dmrs; - } - bool is_from_rar() { - return grant_is_from_rar; - } - bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t n_rb_ho) { - grant_is_from_rar = false; - if (srslte_dci_msg_to_ul_grant(msg, cell.nof_prb, n_rb_ho, &ul_dci, &grant)) { - return false; - } else { - if (SRSLTE_VERBOSE_ISINFO()) { - srslte_ra_pusch_fprint(stdout, &ul_dci, cell.nof_prb); - } - return true; - } - } - bool create_from_rar(srslte_dci_rar_grant_t *rar, srslte_cell_t cell, uint32_t n_rb_ho) { - grant_is_from_rar = true; - if (srslte_dci_rar_to_ul_grant(rar, cell.nof_prb, n_rb_ho, &ul_dci, &grant)) { - return false; - } else { - if (SRSLTE_VERBOSE_ISINFO()) { - srslte_ra_pusch_fprint(stdout, &ul_dci, cell.nof_prb); - } - return true; - } - } - bool to_pusch_cfg(srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg, uint32_t tti, srslte_ue_ul_t *ue_ul) { - memcpy(&ue_ul->pusch_cfg.grant, &grant, sizeof(srslte_ra_ul_grant_t)); - - uint32_t cyclic_shift_for_dmrs = 0; - if (!is_from_rar()) { - cyclic_shift_for_dmrs = get_n_dmrs(); - } - - if (srslte_ue_ul_cfg_grant(ue_ul, NULL, hopping_cfg, srs_cfg, tti, cyclic_shift_for_dmrs, get_rv())) { - return false; - } - return true; - } - private: - srslte_ra_ul_grant_t grant; - srslte_ra_ul_dci_t ul_dci; - uint32_t current_tx_nb; - uint16_t rnti; - bool grant_is_from_rar; - }; - -} -} - -#endif diff --git a/srsapps/ue/phy/src/dl_buffer.cc b/srsapps/ue/phy/src/dl_buffer.cc deleted file mode 100644 index cd655eda7..000000000 --- a/srsapps/ue/phy/src/dl_buffer.cc +++ /dev/null @@ -1,235 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2014 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Lesser General Public License for more details. - * - * A copy of the GNU Lesser General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include "srslte/srslte.h" - -#include "srsapps/common/log.h" -#include "srsapps/ue/phy/sched_grant.h" -#include "srsapps/ue/phy/dl_buffer.h" -#include "srsapps/ue/phy/phy.h" -#include "srsapps/ue/phy/phy_params.h" - - -namespace srslte { -namespace ue { - -bool dl_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) -{ - log_h = log_h_; - params_db = params_db_; - cell = cell_; - sf_symbols_and_ce_done = false; - pdcch_llr_extracted = false; - pending_rar_grant = false; - tti = 0; - if (!srslte_ue_dl_init(&ue_dl, cell)) { - signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - return signal_buffer?true:false; - } else { - return false; - } -} - -void dl_buffer::free_cell() -{ - if (signal_buffer) { - free(signal_buffer); - } - srslte_ue_dl_free(&ue_dl); -} - -void dl_buffer::set_crnti(uint16_t rnti) -{ - srslte_ue_dl_set_rnti(&ue_dl, rnti); -} - -// FIXME: Avoid this memcpy modifying ue_sync to directly write into provided pointer -bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time) -{ - bool ret = false; - cf_t *sf_buffer = NULL; - sf_symbols_and_ce_done = false; - pdcch_llr_extracted = false; - if (signal_buffer) { - bzero(signal_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - if (srslte_ue_sync_get_buffer(ue_sync, &sf_buffer) == 1) { - memcpy(signal_buffer, sf_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - ready(); - ret = true; - } - srslte_ue_sync_get_last_timestamp(ue_sync, rx_time); - } - return ret; -} - -void dl_buffer::discard_pending_rar_grant() { - pending_rar_grant = false; -} - -bool dl_buffer::get_ul_grant(ul_sched_grant *grant) -{ - if (signal_buffer) { - if (pending_rar_grant && grant->is_temp_rnti()) { - return grant->create_from_rar(&rar_grant, cell, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET)); - } else { - if (!sf_symbols_and_ce_done) { - if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { - return false; - } - sf_symbols_and_ce_done = true; - } - if (!pdcch_llr_extracted) { - if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) { - return false; - } - pdcch_llr_extracted = true; - } - - srslte_dci_msg_t dci_msg; - if (srslte_ue_dl_find_ul_dci(&ue_dl, &dci_msg, cfi, tti%10, grant->get_rnti()) != 1) { - return false; - } - - grant->set_tti(tti); - - Info("PDCCH: UL DCI Format0 cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits); - - return grant->create_from_dci(&dci_msg, cell, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET)); - } - } -} - -// Unpack RAR grant as defined in Section 6.2 of 36.213 -void dl_buffer::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) -{ - pending_rar_grant = true; - srslte_dci_rar_grant_unpack(&rar_grant, grant_payload); -} - -void dl_buffer::set_rar_grant(srslte_dci_rar_grant_t* rar_grant_) -{ - pending_rar_grant = true; - memcpy(&rar_grant, rar_grant_, sizeof(srslte_dci_rar_grant_t)); -} - -bool dl_buffer::get_dl_grant(dl_sched_grant *grant) -{ - if (signal_buffer && is_ready()) { - Debug("DL Buffer TTI %d: Getting DL grant\n", tti); - if (!sf_symbols_and_ce_done) { - Debug("DL Buffer TTI %d: Getting DL grant. Calling fft estimate\n", tti); - if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { - return false; - } - sf_symbols_and_ce_done = true; - } - if (!pdcch_llr_extracted) { - Debug("DL Buffer TTI %d: Getting DL grant. extracting LLR\n", tti); - if (srslte_pdcch_extract_llr(&ue_dl.pdcch, ue_dl.sf_symbols, ue_dl.ce, 0, tti%10, cfi)) { - return false; - } - pdcch_llr_extracted = true; - } - - if (SRSLTE_VERBOSE_ISDEBUG()) { - srslte_vec_save_file((char*) "ce1", ue_dl.ce[0], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t)); - srslte_vec_save_file((char*) "ce2", ue_dl.ce[1], SRSLTE_SF_LEN_RE(ue_dl.cell.nof_prb, ue_dl.cell.cp)*sizeof(cf_t)); - srslte_vec_save_file((char*) "pdcch_d", ue_dl.pdcch.d, 36*ue_dl.pdcch.nof_cce*sizeof(cf_t)); - srslte_vec_save_file((char*) "pdcch_llr", ue_dl.pdcch.llr, 72*ue_dl.pdcch.nof_cce*sizeof(cf_t)); - } - - srslte_dci_msg_t dci_msg; - if (srslte_ue_dl_find_dl_dci(&ue_dl, &dci_msg, cfi, tti%10, grant->get_rnti()) != 1) { - return false; - } - - grant->set_tti(tti); - - Info("PDCCH: DL DCI %s cce_index=%d, n_data_bits=%d\n", grant->get_dciformat_string(), ue_dl.last_n_cce, dci_msg.nof_bits); - - return grant->create_from_dci(&dci_msg, cell.nof_prb, srslte_ue_dl_get_ncce(&ue_dl)); - } -} - -bool dl_buffer::decode_ack(ul_sched_grant *grant) -{ - if (signal_buffer && is_ready()) { - if (!sf_symbols_and_ce_done) { - if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { - return false; - } - sf_symbols_and_ce_done = true; - } - - return srslte_ue_dl_decode_phich(&ue_dl, tti%10, grant->get_I_lowest(), grant->get_n_dmrs()); - } -} - -void dl_buffer::reset_softbuffer() -{ - srslte_softbuffer_rx_reset(&ue_dl.softbuffer); -} - -bool dl_buffer::decode_data(dl_sched_grant *grant, uint8_t *payload) -{ - return decode_data(grant, &ue_dl.softbuffer, payload); -} - -bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softbuffer, uint8_t *payload) -{ - if (signal_buffer && is_ready()) { - Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti); - if (!sf_symbols_and_ce_done) { - Debug("DL Buffer TTI %d: Decoding PDSCH. Calling fft estimate\n", tti); - if (srslte_ue_dl_decode_fft_estimate(&ue_dl, signal_buffer, tti%10, &cfi) < 0) { - return false; - } - sf_symbols_and_ce_done = true; - } - - grant->get_pdsch_cfg(tti%10, cfi, &ue_dl); - if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) { - - int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols, - ue_dl.ce, 0, grant->get_rnti(), payload); - - if (SRSLTE_VERBOSE_ISDEBUG()) { - srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits.nof_re*sizeof(cf_t)); - } - if (ret == SRSLTE_SUCCESS) { - return true; - } - } - return false; - } -} - -} -} \ No newline at end of file diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index 8834bbb02..3b00d5260 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -36,29 +36,53 @@ #include "srsapps/common/threads.h" #include "srsapps/common/log.h" #include "srsapps/ue/phy/phy.h" -#include "srsapps/ue/phy/prach.h" -#include "srsapps/ue/phy/ul_buffer.h" -#include "srsapps/ue/phy/dl_buffer.h" +#include "srsapps/ue/phy/phch_worker.h" namespace srslte { namespace ue { -phy::phy() : tr_end_time(1024*10), tr_start_time(1024*10) +phy::phy() : tr_end_time(1024*10), tr_start_time(1024*10), workers_pool(NOF_WORKERS), workers(NOF_WORKERS) { - started = false; - is_sfn_synched = false; - cell_is_set = false; - phy_state = IDLE; } -bool phy::init(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h) { - return init_(radio_handler_, ttisync_, log_h, false); +bool phy::init(radio* radio_handler_, mac_interface_phy *mac, log *log_h) { + return init_(radio_handler_, mac, log_h, false); } -bool phy::init_agc(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, log *log_h) { - return init_(radio_handler_, ttisync_, log_h, true); +bool phy::init_agc(radio* radio_handler_, mac_interface_phy *mac, log *log_h) { + return init_(radio_handler_, mac, log_h, true); } + +bool phy::init_(radio* radio_handler_, mac_interface_phy *mac, log *log_h_, bool do_agc) +{ + + mlockall(MCL_CURRENT | MCL_FUTURE); + + log_h = log_h_; + radio_handler = radio_handler_; + + // Set default params + params_db.set_param(phy_interface_params::CELLSEARCH_TIMEOUT_PSS_NFRAMES, 100); + params_db.set_param(phy_interface_params::CELLSEARCH_TIMEOUT_PSS_CORRELATION_THRESHOLD, 160); + params_db.set_param(phy_interface_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES, 100); + + prach_buffer.init(¶ms_db, log_h); + workers_common.init(¶ms_db, log_h, radio_handler, mac); + sf_recv.init(radio_handler, mac, &prach_buffer, &workers_pool, &workers_common, log_h, do_agc); + + // Add workers to workers pool and start threads + for (int i=0;iget(i))->free_cell(); - ((dl_buffer*) dl_buffer_queue->get(i))->free_cell(); + for (int i=0;icreate_from_rar(rar, cell, params_db.get_param(phy_params::PUSCH_HOPPING_OFFSET)); + sf_recv.set_time_adv_sec(((float) n_ta)*SRSLTE_LTE_TS); + Info("Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, n_ta, ((float) n_ta)*SRSLTE_LTE_TS*1e6); } -void phy::set_param(phy_params::phy_param_t param, int64_t value) { +void phy::set_param(phy_interface_params::phy_param_t param, int64_t value) { params_db.set_param((uint32_t) param, value); } -int64_t phy::get_param(phy_params::phy_param_t param) { +int64_t phy::get_param(phy_interface_params::phy_param_t param) { return params_db.get_param((uint32_t) param); } -// FIXME: Add PRACH power control -bool phy::send_prach(uint32_t preamble_idx) { - return send_prach(preamble_idx, -1, 0); -} -bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe) { - return send_prach(preamble_idx, allowed_subframe, 0); -} -bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe, int target_power_dbm) -{ - if (phy_state == RXTX) { - return prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm); - } - return false; -} - -/* Instruct the PHY to send a SR as soon as possible */ -void phy::send_sr(bool enable) +void phy::configure_prach_params() { - sr_enabled = enable; - if (!enable) { - sr_tx_tti = 0; - } -} - -int phy::sr_last_tx_tti() { - if (sr_enabled) { - return -1; - } else { - return (int) sr_tx_tti; + Info("Configuring PRACH parameters\n"); + if (prach_buffer.init_cell(cell)) { + Error("Configuring PRACH parameters\n"); } } -bool phy::cqi_is_ready_to_send(uint32_t tti) +void phy::configure_ul_params() { - /* - if (params_db.get_param(phy_params::CQI_PERIODIC_CONFIGURED)) { - if (srslte_cqi_send(params_db.get_param(phy_params::CQI_PERIODIC_PMI_IDX), tti)) { - Warning("Sending PUCCH CQI\n"); - return true; - } - } - */ - return false; -} - -bool phy::sr_is_ready_to_send(uint32_t tti_) { - if (sr_enabled) { - // Get I_sr parameter - uint32_t I_sr = params_db.get_param(phy_params::SR_CONFIG_INDEX); - if (srslte_ue_ul_sr_send_tti(I_sr, tti_)) { - sr_enabled = false; - sr_tx_tti = tti_; - Info("SR transmission at TTI=%d\n", tti_); - return true; - } + Info("Configuring UL parameters\n"); + for (int i=0;iget(i))->set_crnti(rnti); - ((dl_buffer*) dl_buffer_queue->get(i))->set_crnti(rnti); - } + workers_common.set_dl_rnti(rnti_type, rnti); } -void phy::pregen_signals() +void phy::prach_send(phy_interface::prach_cfg_t* cfg) { - for(uint32_t i=0;iget(i))->pregen_signals(); + + if (prach_buffer.prepare_to_send(cfg)) { + Error("Preparing PRACH to send\n"); } } -bool phy::start_rxtx() +void phy::reset() { - if (phy_state == IDLE) { - if (cell_is_set) { - // Set RX/TX sampling rate - radio_handler->set_rx_srate((float) srslte_sampling_freq_hz(cell.nof_prb)); - radio_handler->set_tx_srate((float) srslte_sampling_freq_hz(cell.nof_prb)); - - phy_state = RXTX; - return true; - } else { - Error("Can not change state to RXTX: cell is not set\n"); - } - } else { - Error("Can not change state to RXTX: invalid state %d\n", phy_state); - } - return false; + // TODO } -bool phy::stop_rxtx() +uint32_t phy::get_current_tti() { - if (phy_state == RXTX) { - // Stop streaming - radio_handler->stop_rx(); - phy_state = IDLE; - return true; - } else { - Error("Can not change state to RXTX: invalid state %d\n", phy_state); - } - return false; + return sf_recv.get_current_tti(); } -float phy::get_agc_gain() +void phy::sr_send() { - return 10*log10(srslte_agc_get_gain(&ue_sync.agc)); -} - -bool phy::status_is_idle() { - return phy_state == IDLE; -} - -bool phy::status_is_rxtx() { - return phy_state == RXTX; -} - -uint32_t phy::get_current_tti() { - return ttisync->get_producer_cntr(); -} -uint32_t phy::tti_to_SFN(uint32_t tti) { - return tti/10; -} - -uint32_t phy::tti_to_subf(uint32_t tti) { - return tti%10; -} - -void* phy::phy_thread_fnc(void *arg) { - phy* phy = static_cast(arg); - phy->main_radio_loop(); - return NULL; + workers_common.sr_enabled = true; } -int radio_recv_wrapper_cs(void *h,void *data, uint32_t nsamples, srslte_timestamp_t *rx_time) +bool phy::status_is_sync() { - radio *radio_handler = (radio*) h; - int n = radio_handler->rx_now(data, nsamples, rx_time); - return n; + return sf_recv.status_is_sync(); } -double callback_set_rx_gain(void *h, double gain) { - radio *radio_handler = (radio*) h; - return radio_handler->set_rx_gain_th(gain); -} - -bool phy::set_cell(srslte_cell_t cell_) { - if (phy_state == IDLE) { - cell_is_set = false; - cell = cell_; - if (!srslte_ue_mib_init(&ue_mib, cell)) - { - if (!srslte_ue_sync_init(&ue_sync, cell, radio_recv_wrapper_cs, radio_handler)) - { - - if (do_agc) { - srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, last_gain); - } - - srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); - for(uint32_t i=0;iget(i))->init_cell(cell, ¶ms_db, log_h, radio_handler); - ((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, ¶ms_db, log_h); - ((dl_buffer*) dl_buffer_queue->get(i))->buffer_id = i; - ((ul_buffer*) ul_buffer_queue->get(i))->ready(); - ((dl_buffer*) dl_buffer_queue->get(i))->release(); - } - cell_is_set = true; - } else { - Error("Error setting cell: initiating ue_sync"); - } - } else { - Error("Error setting cell: initiating ue_mib\n"); - } - } else { - Error("Error setting cell: Invalid state %d\n", phy_state); - } - return cell_is_set; -} - -bool phy::init_prach() { - return prach_buffer.init_cell(cell, ¶ms_db, log_h); -} - -ul_buffer* phy::get_ul_buffer(uint32_t tti) +void phy::sync_start() { - tti=tti%10240; - if (tti + 1 < get_current_tti() && tti > NOF_ULDL_QUEUES) { - Warning("Warning access to PHY UL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti()); - } - return (ul_buffer*) ul_buffer_queue->get(tti); + sf_recv.sync_start(); } -ul_buffer* phy::get_ul_buffer_adv(uint32_t tti) +void phy::sync_stop() { - return (ul_buffer*) ul_buffer_queue->get(tti + ul_buffer::tx_advance_sf); + sf_recv.sync_stop(); } -dl_buffer* phy::get_dl_buffer(uint32_t tti) +void phy::set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) { - tti=tti%10240; - if (tti + 4 < get_current_tti()) { - Warning("Warning access to PHY DL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti()); - // return NULL; - } - return (dl_buffer*) dl_buffer_queue->get(tti); -} - -bool phy::decode_mib(uint32_t N_id_2, srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]) { - return decode_mib_N_id_2((int) N_id_2, cell, payload); + workers_common.set_rar_grant(tti, grant_payload); } -bool phy::decode_mib_best(srslte_cell_t *cell, uint8_t payload[SRSLTE_BCH_PAYLOAD_LEN]) { - return decode_mib_N_id_2(-1, cell, payload); +void phy::set_crnti(uint16_t rnti) { + for(uint32_t i=0;iset_rx_srate(1920000.0); - radio_handler->start_rx(); - - /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ - uint32_t max_peak_cell = 0; - int ret = SRSLTE_ERROR; - if (force_N_id_2 >= 0 && force_N_id_2 < 3) { - ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); - max_peak_cell = force_N_id_2; - } else { - ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); - } - - last_gain = srslte_agc_get_gain(&cs.ue_sync.agc); - - radio_handler->stop_rx(); - srslte_ue_cellsearch_free(&cs); - - if (ret < 0) { - Error("Error decoding MIB: Error searching PSS\n"); - return false; - } else if (ret == 0) { - Error("Error decoding MIB: Could not find any PSS in this frequency\n"); - return false; - } - - // Save result - cell_ptr->id = found_cells[max_peak_cell].cell_id; - cell_ptr->cp = found_cells[max_peak_cell].cp; - cellsearch_cfo = found_cells[max_peak_cell].cfo; - - Info("\nFound CELL ID: %d CP: %s, CFO: %f\n", cell_ptr->id, srslte_cp_string(cell_ptr->cp), cellsearch_cfo); - - srslte_ue_mib_sync_t ue_mib_sync; - - if (srslte_ue_mib_sync_init(&ue_mib_sync, cell_ptr->id, cell_ptr->cp, radio_recv_wrapper_cs, radio_handler)) { - return false; + for(uint32_t i=0;istart_rx(); - ret = srslte_ue_mib_sync_decode(&ue_mib_sync, params_db.get_param(phy_params::CELLSEARCH_TIMEOUT_MIB_NFRAMES), - bch_payload, &cell_ptr->nof_ports, &sfn_offset); - radio_handler->stop_rx(); - last_gain = srslte_agc_get_gain(&ue_mib_sync.ue_sync.agc); - srslte_ue_mib_sync_free(&ue_mib_sync); +uint32_t phy::tti_to_SFN(uint32_t tti) { + return tti/10; +} - if (ret == 1) { - srslte_pbch_mib_unpack(bch_payload, cell_ptr, NULL); - return true; - } else { - Warning("Error decoding MIB: Error decoding PBCH\n"); - return false; - } +uint32_t phy::tti_to_subf(uint32_t tti) { + return tti%10; } -int phy::sync_sfn(void) { - - cf_t *sf_buffer = NULL; - int ret = SRSLTE_ERROR; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - - srslte_ue_sync_decode_sss_on_track(&ue_sync, true); - ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); - if (ret < 0) { - Error("Error calling ue_sync_get_buffer"); - return -1; - } - - if (ret == 1) { - if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { - uint32_t sfn_offset=0; - srslte_pbch_decode_reset(&ue_mib.pbch); - int n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); - if (n < 0) { - Error("Error decoding MIB while synchronising SFN"); - return -1; - } else if (n == SRSLTE_UE_MIB_FOUND) { - uint32_t sfn; - srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); - - sfn = (sfn + sfn_offset)%1024; - ttisync->set_producer_cntr(10*sfn+1); - srslte_ue_sync_decode_sss_on_track(&ue_sync, false); - return 1; - } - } - } - return 0; -} -void phy::run_rx_tx_state() -{ - int ret; - if (!is_sfn_synched) { - if (!radio_is_streaming) { - // Start streaming - radio_handler->start_rx(); - radio_is_streaming = true; - } - - ret = sync_sfn(); - switch(ret) { - default: - phy_state = IDLE; - break; - case 1: - is_sfn_synched = true; - is_first_of_burst = true; - break; - case 0: - break; - } - } else { - uint32_t current_tti = ttisync->get_producer_cntr(); - log_h->step(current_tti); - float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000; - - srslte_timestamp_add(&last_rx_time, 0, 1e-3); - - /* Set CFO and next TX time for UL buffer for TTI+4 */ - get_ul_buffer(current_tti+4)->set_tx_params(cfo, time_adv_sec, last_rx_time); - - // Every subframe, TX a PRACH or a PUSCH/PUCCH - if (prach_buffer.is_ready_to_send(current_tti)) { - // send prach if we have to - prach_buffer.send(radio_handler, cfo, last_rx_time); - radio_handler->tx_end(); - } - - // Receive alligned buffer for the current tti - tr_log_end(); - get_dl_buffer(current_tti)->recv_ue_sync(&ue_sync, &last_rx_time); - tr_log_start(); - ttisync->increase(); - } -} -void phy::main_radio_loop() { - while(started) { - switch(phy_state) { - case IDLE: - usleep(50000); - break; - case RXTX: - run_rx_tx_state(); - break; - } - } -} + } diff --git a/srsapps/ue/phy/src/prach.cc b/srsapps/ue/phy/src/prach.cc index 5ca8d72ff..e0b7b0f5e 100644 --- a/srsapps/ue/phy/src/prach.cc +++ b/srsapps/ue/phy/src/prach.cc @@ -33,7 +33,7 @@ #include "srsapps/common/log.h" #include "srsapps/ue/phy/prach.h" #include "srsapps/ue/phy/phy.h" -#include "srsapps/ue/phy/phy_params.h" +#include "srsapps/common/phy_interface.h" namespace srslte { namespace ue { @@ -55,17 +55,21 @@ void prach::free_cell() } } -bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) +void prach::init(phy_params* params_db_, log* log_h_) { - cell = cell_; log_h = log_h_; params_db = params_db_; +} + +bool prach::init_cell(srslte_cell_t cell_) +{ + cell = cell_; preamble_idx = -1; if (srslte_prach_init(&prach_obj, srslte_symbol_sz(cell.nof_prb), - srslte_prach_get_preamble_format(params_db->get_param(phy_params::PRACH_CONFIG_INDEX)), - params_db->get_param(phy_params::PRACH_ROOT_SEQ_IDX), - params_db->get_param(phy_params::PRACH_HIGH_SPEED_FLAG)?true:false, - params_db->get_param(phy_params::PRACH_ZC_CONFIG))) { + srslte_prach_get_preamble_format(params_db->get_param(phy_interface_params::PRACH_CONFIG_INDEX)), + params_db->get_param(phy_interface_params::PRACH_ROOT_SEQ_IDX), + params_db->get_param(phy_interface_params::PRACH_HIGH_SPEED_FLAG)?true:false, + params_db->get_param(phy_interface_params::PRACH_ZC_CONFIG))) { return false; } @@ -75,7 +79,7 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) if(!buffer[i]) { return false; } - if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_params::PRACH_FREQ_OFFSET), buffer[i])) { + if(srslte_prach_gen(&prach_obj, i, params_db->get_param(phy_interface_params::PRACH_FREQ_OFFSET), buffer[i])) { return false; } } @@ -86,13 +90,16 @@ bool prach::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) return initiated; } -bool prach::prepare_to_send(uint32_t preamble_idx_) { - return prepare_to_send(preamble_idx_, -1, 0); -} -bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_) { - return prepare_to_send(preamble_idx_, allowed_subframe_, 0); +bool prach::prepare_to_send(phy_interface::prach_cfg_t* cfg) +{ + int allowed_sf = cfg->allowed_subframe_enabled?(int) cfg->allowed_subframe:-1; + bool ret = prepare_to_send(cfg->preamble_idx, allowed_sf, cfg->target_power_dbm); + if (ret) { + memcpy(&prach_cfg, cfg, sizeof(phy_interface::prach_cfg_t)); + } } -bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, int target_power_dbm) + +bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm) { if (initiated && preamble_idx_ < 64) { preamble_idx = preamble_idx_; @@ -109,7 +116,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_) { if (initiated && preamble_idx >= 0 && preamble_idx < 64 && params_db != NULL) { // consider the number of subframes the transmission must be anticipated uint32_t current_tti = (current_tti_ + tx_advance_sf)%10240; - uint32_t config_idx = (uint32_t) params_db->get_param(phy_params::PRACH_CONFIG_INDEX); + uint32_t config_idx = (uint32_t) params_db->get_param(phy_interface_params::PRACH_CONFIG_INDEX); if (srslte_prach_send_tti(config_idx, current_tti, allowed_subframe)) { Info("PRACH Buffer: Ready to send at tti: %d (now is %d)\n", current_tti, current_tti_); transmitted_tti = current_tti; @@ -119,11 +126,16 @@ bool prach::is_ready_to_send(uint32_t current_tti_) { return false; } -int prach::get_transmitted_tti() { - if (initiated) { - return transmitted_tti; - } else { - return -1; +void prach::get_rar_cfg(uint16_t *rar_rnti, uint32_t *tti_start, uint32_t *tti_end) +{ + if (rar_rnti) { + *rar_rnti = prach_cfg.rar_rnti; + } + if (tti_start) { + *tti_start = transmitted_tti + prach_cfg.rar_start; + } + if (tti_end) { + *tti_end = transmitted_tti + prach_cfg.rar_start + prach_cfg.rar_window; } } @@ -137,18 +149,13 @@ bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time) // Correct CFO before transmission srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, cfo /srslte_symbol_sz(cell.nof_prb)); - // Compute peak - float max = 0; - float *t = (float*) signal_buffer; - for (int i=0;i<2*len;i++) { - if (fabsf(t[i]) > max) { - max = fabsf(t[i]); - } - } + // Normalize signal amplitude + srslte_vec_norm_cfc(signal_buffer, 0.9, signal_buffer, len); radio_handler->tx(signal_buffer, len, tx_time); - Debug("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f, PeakAmplitude=%.2f\n", - cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs, max); + + Debug("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n", + cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs); preamble_idx = -1; } diff --git a/srsapps/ue/phy/src/ul_buffer.cc b/srsapps/ue/phy/src/ul_buffer.cc deleted file mode 100644 index 923ca3845..000000000 --- a/srsapps/ue/phy/src/ul_buffer.cc +++ /dev/null @@ -1,344 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2014 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE 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 Lesser General Public License for more details. - * - * A copy of the GNU Lesser General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include - -#include "srslte/srslte.h" - -#include "srsapps/common/log.h" -#include "srsapps/ue/phy/sched_grant.h" -#include "srsapps/ue/phy/ul_buffer.h" -#include "srsapps/ue/phy/phy.h" -#include "srsapps/ue/phy/phy_params.h" - -namespace srslte { -namespace ue { - -bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_, radio *radio_h_) { - cell = cell_; - log_h = log_h_; - radio_h = radio_h_; - params_db = params_db_; - current_tx_nb = 0; - - if (!srslte_ue_ul_init(&ue_ul, cell)) { - srslte_ue_ul_set_normalization(&ue_ul, false); - signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - cell_initiated = (signal_buffer)?true:false; - srslte_ue_ul_set_cfo_enable(&ue_ul, true); - bzero(&uci_data, sizeof(srslte_uci_data_t)); - uci_pending = false; - return cell_initiated; - } else { - return false; - } -} - -void ul_buffer::free_cell() { - if (cell_initiated) { - if (signal_buffer) { - free(signal_buffer); - } - srslte_ue_ul_free(&ue_ul); - } -} - -void ul_buffer::set_crnti(uint16_t rnti) -{ - srslte_ue_ul_set_rnti(&ue_ul, rnti); -} - -void ul_buffer::pregen_signals() -{ - srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg; - bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - dmrs_cfg.beta_pusch = (float) params_db->get_param(phy_params::PUSCH_BETA)/10; - bool group_hopping_en = params_db->get_param(phy_params::DMRS_GROUP_HOPPING_EN); - bool sequence_hopping_en = params_db->get_param(phy_params::DMRS_SEQUENCE_HOPPING_EN); - dmrs_cfg.cyclic_shift = params_db->get_param(phy_params::PUSCH_RS_CYCLIC_SHIFT); - dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT); - - srslte_refsignal_srs_cfg_t srs_cfg; - bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); - srs_cfg.configured = params_db->get_param(phy_params::SRS_IS_CONFIGURED)?true:false; - srs_cfg.subframe_config = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG); - srs_cfg.bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG); - srs_cfg.I_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX); - srs_cfg.B = (uint32_t) params_db->get_param(phy_params::SRS_UE_BW); - srs_cfg.b_hop = (uint32_t) params_db->get_param(phy_params::SRS_UE_HOP); - srs_cfg.n_rrc = (uint32_t) params_db->get_param(phy_params::SRS_UE_NRRC); - srs_cfg.k_tc = (uint32_t) params_db->get_param(phy_params::SRS_UE_TXCOMB); - srs_cfg.n_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CYCLICSHIFT); - srs_cfg.beta_srs = ((float) params_db->get_param(phy_params::SRS_BETA))/10; - - srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, &srs_cfg, NULL, group_hopping_en, sequence_hopping_en); - srslte_ue_ul_pregen_signals(&ue_ul); -} - -bool ul_buffer::generate_ack(bool ack, dl_sched_grant *last_dl_grant) -{ - uci_data.uci_ack_len = 1; - uci_data.uci_ack = ack?1:0; - uci_pending = true; - last_n_cce = last_dl_grant->get_ncce(); -} - -bool ul_buffer::generate_ack(bool ack[2]) -{ - uci_data.uci_ack_len = 2; - uci_data.uci_ack = ack[0]?1:0; - uci_data.uci_ack_2 = ack[1]?1:0; - uci_pending = true; -} - -void ul_buffer::set_current_tx_nb(uint32_t current_tx_nb_) -{ - current_tx_nb = current_tx_nb_; -} - -bool ul_buffer::generate_cqi_report() -{ - uci_data.uci_cqi_len = 4; - uint8_t cqi[4] = {1, 1, 1, 1}; - uci_data.uci_cqi = cqi; - return true; -} - -bool ul_buffer::generate_sr() { - uci_data.scheduling_request = true; - uci_pending = true; - return true; -} - -bool ul_buffer::uci_ready() { - return uci_pending; -} - -bool ul_buffer::generate_data() { - return generate_data(NULL, NULL); -} - -bool ul_buffer::generate_data(ul_sched_grant *grant, - uint8_t *payload) -{ - return generate_data(grant, &ue_ul.softbuffer, payload); -} -//int nof_tx=0; - - -bool ul_buffer::srs_is_ready_to_send() { - if (params_db->get_param(phy_params::SRS_IS_CONFIGURED)) - { - if (srslte_refsignal_srs_send_cs(params_db->get_param(phy_params::SRS_CS_SFCFG), tti%10) == 1 && - srslte_refsignal_srs_send_ue(params_db->get_param(phy_params::SRS_UE_CONFIGINDEX), tti) == 1) - { - return true; - } - } - return false; -} - -int srspkt = 0; - -bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload) -{ - if (is_ready()) { - - bzero(signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); - - srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg; - bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - dmrs_cfg.beta_pusch = (float) params_db->get_param(phy_params::PUSCH_BETA)/10; - bool group_hopping_en = params_db->get_param(phy_params::DMRS_GROUP_HOPPING_EN); - bool sequence_hopping_en = params_db->get_param(phy_params::DMRS_SEQUENCE_HOPPING_EN); - dmrs_cfg.cyclic_shift = params_db->get_param(phy_params::PUSCH_RS_CYCLIC_SHIFT); - dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT); - - srslte_pusch_hopping_cfg_t pusch_hopping; - if (grant) { - bzero(&pusch_hopping, sizeof(srslte_pusch_hopping_cfg_t)); - pusch_hopping.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB); - pusch_hopping.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ? - pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTRA_SF : - pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTER_SF; - pusch_hopping.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET); - pusch_hopping.current_tx_nb = grant->get_current_tx_nb(); - } - - srslte_pucch_cfg_t pucch_cfg; - bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); - pucch_cfg.beta_pucch = (float) params_db->get_param(phy_params::PUCCH_BETA)/10; - pucch_cfg.delta_pucch_shift = params_db->get_param(phy_params::PUCCH_DELTA_SHIFT); - pucch_cfg.N_cs = params_db->get_param(phy_params::PUCCH_CYCLIC_SHIFT); - pucch_cfg.n_rb_2 = params_db->get_param(phy_params::PUCCH_N_RB_2); - pucch_cfg.srs_configured = params_db->get_param(phy_params::SRS_IS_CONFIGURED)?true:false; - pucch_cfg.srs_cs_subf_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG); - pucch_cfg.srs_simul_ack = params_db->get_param(phy_params::SRS_CS_ACKNACKSIMUL)?true:false; - - srslte_pucch_sched_t pucch_sched; - bzero(&pucch_sched, sizeof(srslte_pucch_sched_t)); - pucch_sched.n_cce = last_n_cce; - pucch_sched.n_pucch_1[0] = params_db->get_param(phy_params::PUCCH_N_PUCCH_1_0); - pucch_sched.n_pucch_1[1] = params_db->get_param(phy_params::PUCCH_N_PUCCH_1_1); - pucch_sched.n_pucch_1[2] = params_db->get_param(phy_params::PUCCH_N_PUCCH_1_2); - pucch_sched.n_pucch_1[3] = params_db->get_param(phy_params::PUCCH_N_PUCCH_1_3); - pucch_sched.N_pucch_1 = params_db->get_param(phy_params::PUCCH_N_PUCCH_1); - pucch_sched.n_pucch_2 = params_db->get_param(phy_params::PUCCH_N_PUCCH_2); - pucch_sched.n_pucch_sr = params_db->get_param(phy_params::PUCCH_N_PUCCH_SR); - - srslte_refsignal_srs_cfg_t srs_cfg; - bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); - srs_cfg.configured = params_db->get_param(phy_params::SRS_IS_CONFIGURED)?true:false; - srs_cfg.subframe_config = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG); - srs_cfg.bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG); - srs_cfg.I_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX); - srs_cfg.B = (uint32_t) params_db->get_param(phy_params::SRS_UE_BW); - srs_cfg.b_hop = (uint32_t) params_db->get_param(phy_params::SRS_UE_HOP); - srs_cfg.n_rrc = (uint32_t) params_db->get_param(phy_params::SRS_UE_NRRC); - srs_cfg.k_tc = (uint32_t) params_db->get_param(phy_params::SRS_UE_TXCOMB); - srs_cfg.n_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CYCLICSHIFT); - srs_cfg.beta_srs = ((float) params_db->get_param(phy_params::SRS_BETA))/10; - - srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &pucch_cfg, &srs_cfg, &pucch_sched, - group_hopping_en, sequence_hopping_en); - - uci_data.I_offset_ack = params_db->get_param(phy_params::UCI_I_OFFSET_ACK); - uci_data.I_offset_cqi = params_db->get_param(phy_params::UCI_I_OFFSET_CQI); - uci_data.I_offset_ri = params_db->get_param(phy_params::UCI_I_OFFSET_RI); - - srslte_ue_ul_set_cfo(&ue_ul, cfo); - - int n = 0; - // Transmit on PUSCH if UL grant available, otherwise in PUCCH - if (grant) { - - if (params_db->get_param(phy_params::CQI_PERIODIC_CONFIGURED)) { - if (srslte_cqi_send(params_db->get_param(phy_params::CQI_PERIODIC_PMI_IDX), tti)) { - generate_cqi_report(); - } - } - - srslte_pusch_hopping_cfg_t pusch_hopping_cfg; - bzero(&pusch_hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); - - pusch_hopping_cfg.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB); - pusch_hopping_cfg.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ? - srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTRA_SF : - srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTER_SF; - pusch_hopping_cfg.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET); - pusch_hopping_cfg.current_tx_nb = grant->get_current_tx_nb(); - - grant->to_pusch_cfg(&pusch_hopping_cfg, &srs_cfg, tti, &ue_ul); - - n = srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul, - payload, uci_data, - softbuffer, - grant->get_rnti(), - signal_buffer); - - if (ue_ul.pusch.shortened) { - Info("PUSCH shortened on tti=%d\n", tti); - } - - Info("PUSCH: TTI=%d, CFO= %.1f KHz TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n", - tti, cfo*15e3, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0], - ue_ul.pusch_cfg.grant.L_prb, - uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", - grant->get_rnti(), ue_ul.pusch.shortened?"yes":"no"); - - - } else if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len) { - n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti, signal_buffer); - - Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, cfo*15e3, last_n_cce, - uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", - ue_ul.pucch.shortened?"yes":"no"); - } else { - n = srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer); - - Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti, cfo*15e3); - } - - // Reset UCI data - bzero(&uci_data, sizeof(srslte_uci_data_t)); - uci_pending = false; - - // Compute peak - float max = 0; - if (normalize_amp) { - float *t = (float*) signal_buffer; - for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) { - if (fabsf(t[i]) > max) { - max = fabsf(t[i]); - } - } - - // Normalize before TX - srslte_vec_sc_prod_cfc(signal_buffer, 0.9/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); - } - - release(); - - if (n < 0) { - fprintf(stderr, "Error in UL buffer: Error encoding %s\n", signal_buffer?"PUSCH":"PUCCH"); - return false; - } else { - return true; - } - } else { - fprintf(stderr, "Error in UL buffer: buffer not released\n"); - return false; - } -} - -int nof_tx = 0; - -void ul_buffer::set_tx_params(float cfo_, float time_adv_sec, srslte_timestamp_t tx_time_) -{ - cfo = cfo_; - srslte_timestamp_copy(&tx_time, &tx_time_); - srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec); // UL buffer is configured for tti+4 -} - -void ul_buffer::send() { - radio_h->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); - Info("TX TTI=%d\n", tti); -} - -void ul_buffer::send_end_of_burst() -{ - Info("TTI %d sending end of burst\n", tti); - radio_h->tx_end(); -} - - -} // namespace ue -} // namespace srslte - diff --git a/srsapps/ue/phy/test/CMakeLists.txt b/srsapps/ue/phy/test/CMakeLists.txt index d5cc0af97..fd74ce209 100644 --- a/srsapps/ue/phy/test/CMakeLists.txt +++ b/srsapps/ue/phy/test/CMakeLists.txt @@ -24,6 +24,6 @@ IF(UHD_FOUND) ADD_EXECUTABLE(ue_itf_test_sib1 ue_itf_test_sib1.cc) TARGET_LINK_LIBRARIES(ue_itf_test_sib1 srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) - ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc) - TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) +# ADD_EXECUTABLE(ue_itf_test_prach ue_itf_test_prach.cc) +# TARGET_LINK_LIBRARIES(ue_itf_test_prach srsapps_common srsapps_ue_phy srsapps_radio srslte srslte_uhd) ENDIF(UHD_FOUND) diff --git a/srsapps/ue/phy/test/ue_itf_test_sib1.cc b/srsapps/ue/phy/test/ue_itf_test_sib1.cc index d77972d27..97d1d94ca 100644 --- a/srsapps/ue/phy/test/ue_itf_test_sib1.cc +++ b/srsapps/ue/phy/test/ue_itf_test_sib1.cc @@ -30,18 +30,21 @@ #include "srslte/utils/debug.h" #include "srsapps/ue/phy/phy.h" #include "srsapps/common/log_stdout.h" -#include "srsapps/common/tti_sync_cv.h" +#include "srsapps/common/mac_interface.h" #include "srsapps/radio/radio_uhd.h" /********************************************************************** * Program arguments processing ***********************************************************************/ + typedef struct { float uhd_freq; float uhd_gain; }prog_args_t; +prog_args_t prog_args; + void args_default(prog_args_t *args) { args->uhd_freq = -1.0; args->uhd_gain = -1.0; @@ -79,13 +82,37 @@ void parse_args(prog_args_t *args, int argc, char **argv) { } +/******** MAC Interface implementation */ +class testmac : public srslte::ue::mac_interface_phy +{ +public: + void new_grant_ul(mac_grant_t grant, uint8_t *payload_ptr, tb_action_ul_t *action) { + printf("New grant UL\n"); + } + void new_grant_ul_ack(mac_grant_t grant, uint8_t *payload_ptr, bool ack, tb_action_ul_t *action) { + printf("New grant UL ACK\n"); + } + void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) { + printf("harq recv\n"); + } + + void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) { + printf("New grant DL\n"); + } + + void tb_decoded_ok(uint32_t harq_pid) { + printf("TB decoded OK\n"); + } + void bch_decoded_ok(uint8_t *payload) { + printf("BCH decoded\n"); + } +}; -srslte::ue::phy phy; -prog_args_t prog_args; +#ifdef kk uint32_t total_pkts=0; uint32_t total_dci=0; @@ -94,7 +121,6 @@ uint8_t payload[1024]; // This is the MAC implementation void run_tti(uint32_t tti) { - srslte::ue::dl_sched_grant grant(SRSLTE_SIRNTI); INFO("MAC running tti: %d\n", tti); // SIB1 is scheduled in subframe #5 of even frames @@ -127,12 +153,14 @@ void run_tti(uint32_t tti) { total_pkts, gain); } } +#endif int main(int argc, char *argv[]) { + srslte::ue::phy phy; + testmac mac; srslte_cell_t cell; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - srslte::ue::tti_sync_cv ttisync(10240); srslte::radio_uhd radio_uhd; srslte::log_stdout log("PHY"); @@ -142,46 +170,28 @@ int main(int argc, char *argv[]) if (prog_args.uhd_gain > 0) { radio_uhd.init(); radio_uhd.set_rx_gain(prog_args.uhd_gain); - phy.init(&radio_uhd, &ttisync, &log); + phy.init(&radio_uhd, &mac, &log); } else { radio_uhd.init_agc(); - phy.init_agc(&radio_uhd, &ttisync, &log); + phy.init_agc(&radio_uhd, &mac, &log); } // Give it time to create thread sleep(1); // Set default parameters - phy.set_param(srslte::ue::phy_params::PRACH_CONFIG_INDEX, 0); - phy.set_param(srslte::ue::phy_params::PRACH_ROOT_SEQ_IDX, 0); - phy.set_param(srslte::ue::phy_params::PRACH_HIGH_SPEED_FLAG, 0); - phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1); + phy.set_param(srslte::ue::phy_interface_params::PRACH_CONFIG_INDEX, 0); + phy.set_param(srslte::ue::phy_interface_params::PRACH_ROOT_SEQ_IDX, 0); + phy.set_param(srslte::ue::phy_interface_params::PRACH_HIGH_SPEED_FLAG, 0); + phy.set_param(srslte::ue::phy_interface_params::PRACH_ZC_CONFIG, 1); // Set RX freq and gain - phy.get_radio()->set_rx_freq(prog_args.uhd_freq); - phy.get_radio()->set_rx_gain(prog_args.uhd_gain); - - /* Instruct the PHY to decode BCH */ - if (!phy.decode_mib_best(&cell, bch_payload)) { - exit(-1); - } - // Print MIB - srslte_cell_fprint(stdout, &cell, phy.get_current_tti()/10); - - // Set the current PHY cell to the detected cell - if (!phy.set_cell(cell)) { - printf("Error setting cell\n"); - exit(-1); - } + radio_uhd.set_rx_freq(prog_args.uhd_freq); + radio_uhd.set_rx_gain(prog_args.uhd_gain); + + phy.sync_start(); - /* Instruct the PHY to start RX streaming and synchronize */ - if (!phy.start_rxtx()) { - printf("Could not start RX\n"); - exit(-1); - } - /* go to idle and process each tti */ while(1) { - uint32_t tti = ttisync.wait(); - run_tti(tti); + usleep(1000); } } \ No newline at end of file diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index 17d6800a1..5d77ee9d0 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -576,8 +576,9 @@ int main(int argc, char **argv) { } /* Configure pdsch_cfg parameters */ - srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, true, &pdsch_cfg.grant); - if (srslte_pdsch_cfg(&pdsch_cfg, cell, NULL, cfi, sf_idx, UE_CRNTI, 0)) { + srslte_ra_dl_grant_t grant; + srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, true, &grant); + if (srslte_pdsch_cfg(&pdsch_cfg, cell, &grant, cfi, sf_idx, UE_CRNTI, 0)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } diff --git a/srslte/examples/prach_ue.c b/srslte/examples/prach_ue.c index e4bb96bb6..6b1929541 100644 --- a/srslte/examples/prach_ue.c +++ b/srslte/examples/prach_ue.c @@ -385,12 +385,12 @@ cell.nof_ports = 1; srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg; bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - dmrs_cfg.beta_pusch = 1.0; - bool group_hopping_en = false; - bool sequence_hopping_en = false; + + dmrs_cfg.group_hopping_en = false; + dmrs_cfg.sequence_hopping_en = false; dmrs_cfg.delta_ss = 0; dmrs_cfg.cyclic_shift = 0; - srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, NULL, NULL, group_hopping_en, sequence_hopping_en); + srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, NULL, NULL, NULL, NULL); cf_t *ul_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (!ul_signal) { @@ -518,8 +518,7 @@ cell.nof_ports = 1; printf("Setting CFO: %f (%f)\n", cfo, cfo*15000); srslte_ue_ul_set_cfo(&ue_ul, cfo); - memcpy(&ue_ul.pusch_cfg.grant, &ra_grant, sizeof(srslte_ra_ul_grant_t)); - srslte_ue_ul_cfg_grant(&ue_ul, NULL, 0, 0, ul_sf_idx, 0, 0); + srslte_ue_ul_cfg_grant(&ue_ul, &ra_grant, ul_sf_idx, 0, 0); n = srslte_ue_ul_pusch_encode_rnti(&ue_ul, data, rar_msg.temp_c_rnti, ul_signal); if (n < 0) { diff --git a/srslte/include/srslte/ch_estimation/refsignal_ul.h b/srslte/include/srslte/ch_estimation/refsignal_ul.h index 05021c32c..ae67c6edd 100644 --- a/srslte/include/srslte/ch_estimation/refsignal_ul.h +++ b/srslte/include/srslte/ch_estimation/refsignal_ul.h @@ -48,11 +48,11 @@ typedef struct SRSLTE_API { uint32_t cyclic_shift; uint32_t delta_ss; - float beta_pusch; + bool group_hopping_en; + bool sequence_hopping_en; }srslte_refsignal_dmrs_pusch_cfg_t; typedef struct SRSLTE_API { - float beta_srs; uint32_t subframe_config; uint32_t I_srs; uint32_t bw_cfg; @@ -67,8 +67,6 @@ typedef struct SRSLTE_API { /** Uplink DeModulation Reference Signal (DMRS) */ typedef struct SRSLTE_API { srslte_cell_t cell; - bool group_hopping_en; - bool sequence_hopping_en; srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; srslte_pucch_cfg_t pucch_cfg; srslte_refsignal_srs_cfg_t srs_cfg; @@ -97,9 +95,7 @@ SRSLTE_API void srslte_refsignal_ul_free(srslte_refsignal_ul_t *q); SRSLTE_API void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_pucch_cfg_t *pucch_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, - bool group_hopping_en, - bool sequence_hopping_en); + srslte_refsignal_srs_cfg_t *srs_cfg); SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u); diff --git a/srslte/include/srslte/common/phy_common.h b/srslte/include/srslte/common/phy_common.h index 799f434ce..b993bed6e 100644 --- a/srslte/include/srslte/common/phy_common.h +++ b/srslte/include/srslte/common/phy_common.h @@ -139,6 +139,16 @@ typedef enum SRSLTE_API { } srslte_phich_resources_t; +typedef enum { + SRSLTE_RNTI_USER = 0, + SRSLTE_RNTI_SI, + SRSLTE_RNTI_RAR, + SRSLTE_RNTI_TEMP, + SRSLTE_RNTI_SPS, + SRSLTE_RNTI_PCH, + SRSLTE_RNTI_NOF_TYPES +} srslte_rnti_type_t; + typedef struct SRSLTE_API { uint32_t nof_prb; uint32_t nof_ports; diff --git a/srslte/include/srslte/phch/cqi.h b/srslte/include/srslte/phch/cqi.h index 6c4eb9ce4..8135f2678 100644 --- a/srslte/include/srslte/phch/cqi.h +++ b/srslte/include/srslte/phch/cqi.h @@ -41,7 +41,11 @@ #include "srslte/config.h" #include "srslte/common/phy_common.h" - +typedef struct { + bool configured; + uint32_t pmi_idx; +} srslte_cqi_cfg_t; + /* Table 5.2.2.6.2-1: Fields for channel quality information feedback for higher layer configured subband CQI reports (transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and diff --git a/srslte/include/srslte/phch/pdsch.h b/srslte/include/srslte/phch/pdsch.h index ffec63e17..62c2b4b76 100644 --- a/srslte/include/srslte/phch/pdsch.h +++ b/srslte/include/srslte/phch/pdsch.h @@ -84,7 +84,7 @@ SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, - srslte_dci_msg_t *dci_msg, + srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index b156151aa..13f541aef 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -55,7 +55,6 @@ typedef enum SRSLTE_API { } srslte_pucch_format_t; typedef struct SRSLTE_API { - uint32_t n_cce; bool sps_enabled; uint32_t tpc_for_pucch; uint32_t N_pucch_1; @@ -65,7 +64,6 @@ typedef struct SRSLTE_API { }srslte_pucch_sched_t; typedef struct SRSLTE_API { - float beta_pucch; uint32_t delta_pucch_shift; uint32_t n_rb_2; uint32_t N_cs; diff --git a/srslte/include/srslte/phch/pusch.h b/srslte/include/srslte/phch/pusch.h index f195eb6c2..cbd6505af 100644 --- a/srslte/include/srslte/phch/pusch.h +++ b/srslte/include/srslte/phch/pusch.h @@ -60,7 +60,6 @@ typedef struct { SRSLTE_PUSCH_HOP_MODE_INTER_SF = 1, SRSLTE_PUSCH_HOP_MODE_INTRA_SF = 0 } hop_mode; - uint32_t current_tx_nb; uint32_t hopping_offset; uint32_t n_sb; } srslte_pusch_hopping_cfg_t; @@ -103,14 +102,15 @@ SRSLTE_API int srslte_pusch_init(srslte_pusch_t *q, SRSLTE_API void srslte_pusch_free(srslte_pusch_t *q); -SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q, - srslte_pusch_cfg_t *cfg, - srslte_dci_msg_t *dci_msg, - srslte_pusch_hopping_cfg_t *hopping_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, +SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q, + srslte_pusch_cfg_t *cfg, + srslte_ra_ul_grant_t *grant, + srslte_uci_cfg_t *uci_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg, uint32_t tti, - uint32_t cyclic_shift_for_dmrs, - uint32_t rvidx); + uint32_t rv_idx, + uint32_t current_tx_nb); SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q, uint16_t rnti); diff --git a/srslte/include/srslte/phch/pusch_cfg.h b/srslte/include/srslte/phch/pusch_cfg.h index 7d886f29c..3b1fa1855 100644 --- a/srslte/include/srslte/phch/pusch_cfg.h +++ b/srslte/include/srslte/phch/pusch_cfg.h @@ -40,11 +40,17 @@ #include "srslte/fec/softbuffer.h" #include "srslte/fec/cbsegm.h" +typedef struct SRSLTE_API { + uint32_t I_offset_cqi; + uint32_t I_offset_ri; + uint32_t I_offset_ack; +} srslte_uci_cfg_t; + typedef struct SRSLTE_API { srslte_cbsegm_t cb_segm; srslte_ra_ul_grant_t grant; srslte_ra_nbits_t nbits; - uint32_t cyclic_shift_for_dmrs; + srslte_uci_cfg_t uci_cfg; uint32_t rv; uint32_t sf_idx; uint32_t tti; diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 508714ba5..0f2f78254 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -145,6 +145,7 @@ typedef struct SRSLTE_API { uint32_t M_sc_init; uint32_t Qm; srslte_ra_mcs_t mcs; + uint32_t ncs_dmrs; } srslte_ra_ul_grant_t; /** Unpacked DCI Format0 message */ @@ -172,12 +173,19 @@ typedef struct SRSLTE_API { } srslte_ra_ul_dci_t; +typedef union { + srslte_ra_ul_grant_t ul; + srslte_ra_dl_grant_t dl; +} srslte_phy_grant_t; + +#define SRSLTE_PHY_GRANT_LEN sizeof(srslte_phy_grant_t) /************************************************** * Functions **************************************************/ +SRSLTE_API char* srslte_ra_dl_dci_string(srslte_ra_dl_dci_t *dci); SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, uint32_t nof_prb, diff --git a/srslte/include/srslte/phch/uci.h b/srslte/include/srslte/phch/uci.h index 8c78674ba..a9762c534 100644 --- a/srslte/include/srslte/phch/uci.h +++ b/srslte/include/srslte/phch/uci.h @@ -54,14 +54,11 @@ typedef struct SRSLTE_API { typedef struct SRSLTE_API { uint8_t *uci_cqi; uint32_t uci_cqi_len; - uint32_t I_offset_cqi; uint8_t uci_ri; // Only 1-bit supported for RI uint32_t uci_ri_len; - uint32_t I_offset_ri; uint8_t uci_ack; // 1st codeword bit for HARQ-ACK uint8_t uci_ack_2; // 2st codeword bit for HARQ-ACK uint32_t uci_ack_len; - uint32_t I_offset_ack; bool scheduling_request; bool channel_selection; } srslte_uci_data_t; diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 605c8cf7f..fbd02cd0d 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -98,20 +98,12 @@ SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, uint32_t *cfi); SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, - srslte_dci_msg_t *dci_msg, + srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx); -SRSLTE_API int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, - srslte_dci_msg_t *dci_msg, - uint8_t *data, - uint32_t cfi, - uint32_t sf_idx, - uint16_t rnti, - uint32_t rvidx); - SRSLTE_API int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, @@ -124,6 +116,13 @@ SRSLTE_API int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, uint32_t sf_idx, uint16_t rnti); +SRSLTE_API int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, + srslte_dci_msg_t *dci_msg, + uint32_t cfi, + uint32_t sf_idx, + uint16_t rnti, + srslte_rnti_type_t rnti_type); + SRSLTE_API uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q); SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q, diff --git a/srslte/include/srslte/ue/ue_sync.h b/srslte/include/srslte/ue/ue_sync.h index 3d4f4b243..586cc5dfe 100644 --- a/srslte/include/srslte/ue/ue_sync.h +++ b/srslte/include/srslte/ue/ue_sync.h @@ -136,6 +136,10 @@ SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q); SRSLTE_API int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols); +/* CAUTION: input_buffer MUST have space for 2 subframes */ +SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, + cf_t *input_buffer); + SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, float cfo); diff --git a/srslte/include/srslte/ue/ue_ul.h b/srslte/include/srslte/ue/ue_ul.h index 260a36de1..2062081e3 100644 --- a/srslte/include/srslte/ue/ue_ul.h +++ b/srslte/include/srslte/ue/ue_ul.h @@ -77,7 +77,10 @@ typedef struct SRSLTE_API { srslte_pusch_t pusch; srslte_pucch_t pucch; - srslte_pucch_sched_t pucch_sched; + srslte_pucch_sched_t pucch_sched; + srslte_refsignal_srs_cfg_t srs_cfg; + srslte_uci_cfg_t uci_cfg; + srslte_pusch_hopping_cfg_t hopping_cfg; cf_t *refsignal; cf_t *srs_signal; @@ -104,22 +107,21 @@ SRSLTE_API void srslte_ue_ul_set_normalization(srslte_ue_ul_t *q, SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, - srslte_pucch_cfg_t *pucch_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, - srslte_pucch_sched_t *pucch_sched, - bool group_hopping_en, - bool sequence_hopping_en); + srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_pucch_cfg_t *pucch_cfg, + srslte_pucch_sched_t *pucch_sched, + srslte_uci_cfg_t *uci_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg); SRSLTE_API int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, - srslte_dci_msg_t *dci_msg, - srslte_pusch_hopping_cfg_t *hopping_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_ra_ul_grant_t *grant, uint32_t tti, - uint32_t cyclic_shift_for_dmrs, - uint32_t rvidx); + uint32_t rvidx, + uint32_t current_tx_nb); SRSLTE_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, + uint32_t pdcch_n_cce, /* Ncce of the last PDCCH message received */ uint32_t tti, cf_t *output_signal); diff --git a/srslte/include/srslte/utils/vector.h b/srslte/include/srslte/utils/vector.h index cdf49ff06..b09c4c6ee 100644 --- a/srslte/include/srslte/utils/vector.h +++ b/srslte/include/srslte/utils/vector.h @@ -100,6 +100,9 @@ SRSLTE_API void srslte_vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len); SRSLTE_API void srslte_vec_sc_prod_ccc(cf_t *x, cf_t h, cf_t *z, uint32_t len); SRSLTE_API void srslte_vec_sc_prod_fff(float *x, float h, float *z, uint32_t len); +/* Normalization */ +SRSLTE_API void srslte_vec_norm_cfc(cf_t *x, float amplitude, cf_t *y, uint32_t len); + SRSLTE_API void srslte_vec_convert_fi(float *x, int16_t *z, float scale, uint32_t len); SRSLTE_API void srslte_vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len); diff --git a/srslte/lib/ch_estimation/src/refsignal_ul.c b/srslte/lib/ch_estimation/src/refsignal_ul.c index 603d0efda..b3c159a8b 100644 --- a/srslte/lib/ch_estimation/src/refsignal_ul.c +++ b/srslte/lib/ch_estimation/src/refsignal_ul.c @@ -228,12 +228,8 @@ void srslte_refsignal_ul_free(srslte_refsignal_ul_t * q) { void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_pucch_cfg_t *pucch_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, - bool group_hopping_en, - bool sequence_hopping_en) + srslte_refsignal_srs_cfg_t *srs_cfg) { - q->group_hopping_en = group_hopping_en; - q->sequence_hopping_en = sequence_hopping_en; if (pusch_cfg) { memcpy(&q->pusch_cfg, pusch_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); } @@ -335,14 +331,14 @@ void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q, cf_t *r_pusch, ui void compute_r(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t ns, uint32_t delta_ss) { // Get group hopping number u uint32_t f_gh=0; - if (q->group_hopping_en) { + if (q->pusch_cfg.group_hopping_en) { f_gh = q->f_gh[ns]; } uint32_t u = (f_gh + (q->cell.id%30)+delta_ss)%30; // Get sequence hopping number v uint32_t v = 0; - if (nof_prb >= 6 && q->sequence_hopping_en) { + if (nof_prb >= 6 && q->pusch_cfg.sequence_hopping_en) { v = q->v_pusch[ns][q->pusch_cfg.delta_ss]; } @@ -433,7 +429,7 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb, // Do complex exponential and adjust amplitude for (int i=0;ipusch_cfg.beta_pusch * cexpf(I*(q->tmp_arg[i] + alpha*i)); + r_pusch[(ns%2)*SRSLTE_NRE*nof_prb+i] = cexpf(I*(q->tmp_arg[i] + alpha*i)); } } ret = 0; @@ -517,7 +513,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { // Get group hopping number u uint32_t f_gh=0; - if (q->group_hopping_en) { + if (q->pusch_cfg.group_hopping_en) { f_gh = q->f_gh[ns]; } uint32_t u = (f_gh + (q->cell.id%30))%30; @@ -566,7 +562,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma } if (w) { for (uint32_t n=0;npucch_cfg.beta_pucch*z_m*cexpf(I*(w[m]+q->tmp_arg[n]+alpha*n)); + r_pucch[(ns%2)*SRSLTE_NRE*N_rs+m*SRSLTE_NRE+n] = z_m*cexpf(I*(w[m]+q->tmp_arg[n]+alpha*n)); } } else { return SRSLTE_ERROR; @@ -846,7 +842,7 @@ int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t sf_idx, cf_t *r_ // Do complex exponential and adjust amplitude for (int i=0;isrs_cfg.beta_srs * cexpf(I*(q->tmp_arg[i] + alpha*i)); + r_srs[(ns%2)*M_sc+i] = cexpf(I*(q->tmp_arg[i] + alpha*i)); } } ret = SRSLTE_SUCCESS; diff --git a/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c b/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c index a4f65b33b..829f2bda7 100644 --- a/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c +++ b/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c @@ -76,14 +76,14 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) bzero(&pusch_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - bool group_hopping_en = false; - bool sequence_hopping_en = false; + pusch_cfg.group_hopping_en = false; + pusch_cfg.sequence_hopping_en = false; char *tmp = mexutils_get_char_struct(UECFG, "Hopping"); if (tmp) { if (!strcmp(tmp, "Group")) { - group_hopping_en = true; + pusch_cfg.group_hopping_en = true; } else if (!strcmp(tmp, "Sequence")) { - sequence_hopping_en = true; + pusch_cfg.sequence_hopping_en = true; } mxFree(tmp); } @@ -109,8 +109,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) cyclic_shift_for_dmrs = 0; } - pusch_cfg.beta_pusch = 1.0; - if (srslte_refsignal_ul_init(&refs, cell)) { mexErrMsgTxt("Error initiating srslte_refsignal_ul\n"); return; @@ -133,7 +131,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } bzero(sf_symbols, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t)); - srslte_refsignal_ul_set_cfg(&refs, &pusch_cfg, NULL, NULL, group_hopping_en, sequence_hopping_en); + srslte_refsignal_ul_set_cfg(&refs, &pusch_cfg, NULL, NULL); //mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb); srslte_refsignal_dmrs_pusch_gen(&refs, nof_prb, sf_idx, cyclic_shift_for_dmrs, signal); diff --git a/srslte/lib/ch_estimation/test/refsignal_srs_mex.c b/srslte/lib/ch_estimation/test/refsignal_srs_mex.c index 71a414d7e..86828b150 100644 --- a/srslte/lib/ch_estimation/test/refsignal_srs_mex.c +++ b/srslte/lib/ch_estimation/test/refsignal_srs_mex.c @@ -78,7 +78,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) srslte_refsignal_srs_cfg_t srs_cfg; bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); - srs_cfg.beta_srs = 1.0; + if (mexutils_read_uint32_struct(SRSCFG, "BWConfig", &srs_cfg.bw_cfg)) { mexErrMsgTxt("Field BWConfig not found in SRSCFG\n"); return; @@ -133,8 +133,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error initiating UL refsignal\n"); return; } - - srslte_refsignal_ul_set_cfg(&refsignal, NULL, NULL, &srs_cfg, group_hopping_en, false); + srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; + pusch_cfg.group_hopping_en = group_hopping_en; + pusch_cfg.sequence_hopping_en = false; + srslte_refsignal_ul_set_cfg(&refsignal, &pusch_cfg, NULL, &srs_cfg); if (srslte_refsignal_srs_gen(&refsignal, sf_idx, r_srs)) { mexErrMsgTxt("Error generating SRS\n"); diff --git a/srslte/lib/ch_estimation/test/refsignal_ul_test.c b/srslte/lib/ch_estimation/test/refsignal_ul_test.c index 0b1da233a..97b9c33bd 100644 --- a/srslte/lib/ch_estimation/test/refsignal_ul_test.c +++ b/srslte/lib/ch_estimation/test/refsignal_ul_test.c @@ -100,7 +100,7 @@ int main(int argc, char **argv) { for (int h=0;h<3;h++) { for (int sf_idx=0;sf_idxdft_plan[i], true); + srslte_dft_plan_set_norm(&q->dft_plan[i], false); if (srslte_dft_plan_c(&q->idft_plan[i], i*SRSLTE_NRE, SRSLTE_DFT_BACKWARD)) { fprintf(stderr, "Error: Creating DFT plan %d\n",i); goto clean_exit; } - srslte_dft_plan_set_norm(&q->idft_plan[i], true); + srslte_dft_plan_set_norm(&q->idft_plan[i], false); } } q->max_prb = max_prb; diff --git a/srslte/lib/dft/src/ofdm.c b/srslte/lib/dft/src/ofdm.c index d8069005e..2a60b92e5 100644 --- a/srslte/lib/dft/src/ofdm.c +++ b/srslte/lib/dft/src/ofdm.c @@ -99,7 +99,7 @@ int srslte_ofdm_tx_init(srslte_ofdm_t *q, srslte_cp_t cp, uint32_t nof_prb) { ret = srslte_ofdm_init_(q, cp, nof_prb, SRSLTE_DFT_BACKWARD); if (ret == SRSLTE_SUCCESS) { - srslte_dft_plan_set_norm(&q->fft_plan, true); + srslte_dft_plan_set_norm(&q->fft_plan, false); /* set now zeros at CP */ for (i=0;inof_symbols;i++) { diff --git a/srslte/lib/phch/src/pdsch.c b/srslte/lib/phch/src/pdsch.c index 893e7a1d8..137d340a1 100644 --- a/srslte/lib/phch/src/pdsch.c +++ b/srslte/lib/phch/src/pdsch.c @@ -305,21 +305,11 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { /* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg. * If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant */ -int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) +int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { - if (dci_msg) { - srslte_ra_dl_dci_t dl_dci; - if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, cell.nof_prb, &dl_dci, &cfg->grant)) { - fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); - return SRSLTE_ERROR; - } - if (rnti == SRSLTE_SIRNTI) { - cfg->rv = rvidx; - } else { - cfg->rv = dl_dci.rv_idx; - } - } else { - cfg->rv = rvidx; + + if (cfg && grant) { + memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t)); } if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); @@ -327,6 +317,7 @@ int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_dci_msg } srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits); cfg->sf_idx = sf_idx; + cfg->rv = rvidx; return SRSLTE_SUCCESS; } diff --git a/srslte/lib/phch/src/pucch.c b/srslte/lib/phch/src/pucch.c index 3d16c0123..4e6f0eaa6 100644 --- a/srslte/lib/phch/src/pucch.c +++ b/srslte/lib/phch/src/pucch.c @@ -65,8 +65,7 @@ float w_n_oc[2][3][4] = { /* Verify PUCCH configuration as given in Section 5.4 36.211 */ bool srslte_pucch_cfg_isvalid(srslte_pucch_cfg_t *cfg, uint32_t nof_prb) { - if (cfg->beta_pucch > 0 && - cfg->delta_pucch_shift > 0 && cfg->delta_pucch_shift < 4 && + if (cfg->delta_pucch_shift > 0 && cfg->delta_pucch_shift < 4 && cfg->N_cs < 8 && (cfg->N_cs%cfg->delta_pucch_shift) == 0 && cfg->n_rb_2 < nof_prb) { return true; @@ -85,7 +84,6 @@ bool srslte_pucch_n2_isvalid(srslte_pucch_cfg_t *cfg, uint32_t n_pucch_2) { } void srslte_pucch_cfg_default(srslte_pucch_cfg_t *cfg) { - cfg->beta_pucch = 1.0; cfg->delta_pucch_shift = 1; } @@ -522,8 +520,7 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, if (format >= SRSLTE_PUCCH_FORMAT_2) { alpha = srslte_pucch_alpha_format2(q->n_cs_cell, &q->pucch_cfg, n_pucch, ns, l); for (uint32_t n=0;nz[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->pucch_cfg.beta_pucch - *q->d[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n)); + q->z[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n)); } } else { alpha = srslte_pucch_alpha_format1(q->n_cs_cell, &q->pucch_cfg, n_pucch, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns); @@ -534,8 +531,7 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n", __real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2); for (uint32_t n=0;nz[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->pucch_cfg.beta_pucch - *q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns)); + q->z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns)); } } } diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index 8e1428221..ae2cf308f 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -73,10 +73,10 @@ static int f_hop(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, int i) } } -static int f_m(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, uint32_t i) { +static int f_m(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, uint32_t i, uint32_t current_tx_nb) { if (hopping->n_sb == 1) { if (hopping->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) { - return hopping->current_tx_nb%2; + return current_tx_nb%2; } else { return i%2; } @@ -88,7 +88,7 @@ static int f_m(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, uint32_t /* Computes PUSCH frequency hopping as defined in Section 8.4 of 36.213 */ void compute_freq_hopping(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, srslte_pusch_hopping_cfg_t *hopping, - uint32_t sf_idx) + uint32_t sf_idx, uint32_t current_tx_nb) { for (uint32_t slot=0;slot<2;slot++) { @@ -98,7 +98,7 @@ void compute_freq_hopping(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, if (grant->freq_hopping == 1) { if (hopping->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) { - n_prb_tilde = grant->n_prb[hopping->current_tx_nb%2]; + n_prb_tilde = grant->n_prb[current_tx_nb%2]; } else { n_prb_tilde = grant->n_prb[slot]; } @@ -120,7 +120,7 @@ void compute_freq_hopping(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, n_rb_sb = (n_rb_sb-hopping->hopping_offset-hopping->hopping_offset%2)/hopping->n_sb; } n_prb_tilde = (n_vrb_tilde+f_hop(q, hopping, i)*n_rb_sb+ - (n_rb_sb-1)-2*(n_vrb_tilde%n_rb_sb)*f_m(q, hopping, i))%(n_rb_sb*hopping->n_sb); + (n_rb_sb-1)-2*(n_vrb_tilde%n_rb_sb)*f_m(q, hopping, i, current_tx_nb))%(n_rb_sb*hopping->n_sb); INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping->n_sb); @@ -305,79 +305,85 @@ void srslte_pusch_free(srslte_pusch_t *q) { /* Configures the structure srslte_pusch_cfg_t from the UL DCI allocation dci_msg. * If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant */ -int srslte_pusch_cfg(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_dci_msg_t *dci_msg, - srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg, - uint32_t tti, uint32_t cyclic_shift_for_dmrs, uint32_t rvidx) +int srslte_pusch_cfg(srslte_pusch_t *q, + srslte_pusch_cfg_t *cfg, + srslte_ra_ul_grant_t *grant, + srslte_uci_cfg_t *uci_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg, + uint32_t tti, + uint32_t rv_idx, + uint32_t current_tx_nb) { - if (dci_msg) { - srslte_ra_ul_dci_t ul_dci; - if (srslte_dci_msg_to_ul_grant(dci_msg, q->cell.nof_prb, hopping_cfg->hopping_offset, &ul_dci, &cfg->grant)) { - fprintf(stderr, "Error unpacking UL grant from DCI message\n"); + if (q && cfg && grant) { + memcpy(&cfg->grant, grant, sizeof(srslte_ra_ul_grant_t)); + + if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { + fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); return SRSLTE_ERROR; } - } - if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) { - fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs); - return SRSLTE_ERROR; - } - - cfg->cyclic_shift_for_dmrs = cyclic_shift_for_dmrs; - - /* Compute PUSCH frequency hopping */ - if (hopping_cfg) { - compute_freq_hopping(q, &cfg->grant, hopping_cfg, tti%10); - } else { - cfg->grant.n_prb_tilde[0] = cfg->grant.n_prb[0]; - cfg->grant.n_prb_tilde[1] = cfg->grant.n_prb[1]; - } - if (srs_cfg) { - q->shortened = false; - if (srs_cfg->configured) { - // If UE-specific SRS is configured, PUSCH is shortened every time UE transmits SRS even if overlaping in the same RB or not - if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1 && - srslte_refsignal_srs_send_ue(srs_cfg->I_srs, tti) == 1) - { - q->shortened = true; - /* If RBs are contiguous, PUSCH is not shortened */ - uint32_t k0_srs = srslte_refsignal_srs_rb_start_cs(srs_cfg->bw_cfg, q->cell.nof_prb); - uint32_t nrb_srs = srslte_refsignal_srs_rb_L_cs(srs_cfg->bw_cfg, q->cell.nof_prb); - for (uint32_t ns=0;ns<2 && q->shortened;ns++) { - if (cfg->grant.n_prb_tilde[ns] != k0_srs + nrb_srs || // If grant allocation starts when SRS ends - cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb != k0_srs) // or SRS allocation starts when grant ends - { - q->shortened = false; - } - } - } - // If not coincides with UE transmission. PUSCH shall be shortened if cell-specific SRS transmission RB - //coincides with PUSCH allocated RB - if (!q->shortened) { - if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1) { + + /* Compute PUSCH frequency hopping */ + if (hopping_cfg) { + compute_freq_hopping(q, &cfg->grant, hopping_cfg, tti%10, current_tx_nb); + } else { + cfg->grant.n_prb_tilde[0] = cfg->grant.n_prb[0]; + cfg->grant.n_prb_tilde[1] = cfg->grant.n_prb[1]; + } + if (srs_cfg) { + q->shortened = false; + if (srs_cfg->configured) { + // If UE-specific SRS is configured, PUSCH is shortened every time UE transmits SRS even if overlaping in the same RB or not + if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1 && + srslte_refsignal_srs_send_ue(srs_cfg->I_srs, tti) == 1) + { + q->shortened = true; + /* If RBs are contiguous, PUSCH is not shortened */ uint32_t k0_srs = srslte_refsignal_srs_rb_start_cs(srs_cfg->bw_cfg, q->cell.nof_prb); uint32_t nrb_srs = srslte_refsignal_srs_rb_L_cs(srs_cfg->bw_cfg, q->cell.nof_prb); - for (uint32_t ns=0;ns<2 && !q->shortened;ns++) { - if ((cfg->grant.n_prb_tilde[ns] >= k0_srs && cfg->grant.n_prb_tilde[ns] < k0_srs + nrb_srs) || - (cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb >= k0_srs && - cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb < k0_srs + nrb_srs) || - (cfg->grant.n_prb_tilde[ns] <= k0_srs && cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb >= k0_srs + nrb_srs)) - { - q->shortened = true; + for (uint32_t ns=0;ns<2 && q->shortened;ns++) { + if (cfg->grant.n_prb_tilde[ns] != k0_srs + nrb_srs || // If grant allocation starts when SRS ends + cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb != k0_srs) // or SRS allocation starts when grant ends + { + q->shortened = false; } } } - } - } - } - - /* Compute final number of bits and RE */ - srslte_ra_ul_grant_to_nbits(&cfg->grant, q->cell.cp, q->shortened?1:0, &cfg->nbits); + // If not coincides with UE transmission. PUSCH shall be shortened if cell-specific SRS transmission RB + //coincides with PUSCH allocated RB + if (!q->shortened) { + if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1) { + uint32_t k0_srs = srslte_refsignal_srs_rb_start_cs(srs_cfg->bw_cfg, q->cell.nof_prb); + uint32_t nrb_srs = srslte_refsignal_srs_rb_L_cs(srs_cfg->bw_cfg, q->cell.nof_prb); + for (uint32_t ns=0;ns<2 && !q->shortened;ns++) { + if ((cfg->grant.n_prb_tilde[ns] >= k0_srs && cfg->grant.n_prb_tilde[ns] < k0_srs + nrb_srs) || + (cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb >= k0_srs && + cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb < k0_srs + nrb_srs) || + (cfg->grant.n_prb_tilde[ns] <= k0_srs && cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb >= k0_srs + nrb_srs)) + { + q->shortened = true; + } + } + } + } + } + } + + /* Compute final number of bits and RE */ + srslte_ra_ul_grant_to_nbits(&cfg->grant, q->cell.cp, q->shortened?1:0, &cfg->nbits); - cfg->sf_idx = tti%10; - cfg->tti = tti; - cfg->rv = rvidx; - cfg->cp = q->cell.cp; - - return SRSLTE_SUCCESS; + cfg->sf_idx = tti%10; + cfg->tti = tti; + cfg->rv = rv_idx; + cfg->cp = q->cell.cp; + + // Save UCI configuration + memcpy(&cfg->uci_cfg, uci_cfg, sizeof(srslte_uci_cfg_t)); + + return SRSLTE_SUCCESS; + } else { + return SRSLTE_ERROR_INVALID_INPUTS; + } } /* Precalculate the PUSCH scramble sequences for a given RNTI. This function takes a while diff --git a/srslte/lib/phch/src/ra.c b/srslte/lib/phch/src/ra.c index f6a5d9c6a..63ae13ee0 100644 --- a/srslte/lib/phch/src/ra.c +++ b/srslte/lib/phch/src/ra.c @@ -111,6 +111,8 @@ uint32_t ra_re_x_prb(uint32_t subframe, uint32_t slot, uint32_t prb_idx, uint32_ int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t n_rb_ho, uint32_t nof_prb) { bzero(grant, sizeof(srslte_ra_ul_grant_t)); + + grant->ncs_dmrs = dci->n_dmrs; grant->L_prb = dci->type2_alloc.L_crb; uint32_t n_prb_1 = dci->type2_alloc.RB_start; uint32_t n_rb_pusch = 0; @@ -256,6 +258,18 @@ uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t ce return nof_re; } +char* srslte_ra_dl_dci_string(srslte_ra_dl_dci_t *dci) { + switch(dci->dci_format) { + case SRSLTE_RA_DCI_FORMAT1: + return "1"; + case SRSLTE_RA_DCI_FORMAT1A: + return "1A"; + case SRSLTE_RA_DCI_FORMAT1C: + return "1C"; + default: + return ""; + } +} /** Compute PRB allocation for Downlink as defined in 7.1.6 of 36.213 */ static int dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, uint32_t nof_prb) { diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index d262ffed2..9e683fbc6 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -521,9 +521,9 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, // Encode RI if (uci_data.uci_ri_len > 0) { - float beta = beta_ri_offset[uci_data.I_offset_ri]; + float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri]; if (cfg->cb_segm.tbs == 0) { - beta /= beta_cqi_offset[uci_data.I_offset_cqi]; + beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi]; } ret = srslte_uci_encode_ri(cfg, uci_data.uci_ri, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits); if (ret < 0) { @@ -536,7 +536,7 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, if (uci_data.uci_cqi_len > 0) { ret = srslte_uci_encode_cqi_pusch(&q->uci_cqi, cfg, uci_data.uci_cqi, uci_data.uci_cqi_len, - beta_cqi_offset[uci_data.I_offset_cqi], + beta_cqi_offset[cfg->uci_cfg.I_offset_cqi], Q_prime_ri, g_bits); if (ret < 0) { return ret; @@ -562,9 +562,9 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, // Encode (and interleave) ACK if (uci_data.uci_ack_len > 0) { - float beta = beta_harq_offset[uci_data.I_offset_ack]; + float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack]; if (cfg->cb_segm.tbs == 0) { - beta /= beta_cqi_offset[uci_data.I_offset_cqi]; + beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi]; } ret = srslte_uci_encode_ack(cfg, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits); if (ret < 0) { diff --git a/srslte/lib/phch/test/pdsch_test.c b/srslte/lib/phch/test/pdsch_test.c index 066377f15..d580ff278 100644 --- a/srslte/lib/phch/test/pdsch_test.c +++ b/srslte/lib/phch/test/pdsch_test.c @@ -137,17 +137,18 @@ int main(int argc, char **argv) { bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); - pdsch_cfg.grant.mcs.tbs = tbs; - pdsch_cfg.grant.mcs.mod = modulation; - pdsch_cfg.grant.Qm = srslte_mod_bits_x_symbol(pdsch_cfg.grant.mcs.mod); - pdsch_cfg.grant.nof_prb = cell.nof_prb; // Allocate all PRB - for (i=0;i= 2) { - mexutils_write_uint8(data, &plhs[1], cfg.grant.mcs.tbs, 1); + mexutils_write_uint8(data, &plhs[1], grant.mcs.tbs, 1); } if (nlhs >= 3) { mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.nbits.nof_re, 1); diff --git a/srslte/lib/phch/test/pucch_encode_test_mex.c b/srslte/lib/phch/test/pucch_encode_test_mex.c index 1e774778f..d547feb2c 100644 --- a/srslte/lib/phch/test/pucch_encode_test_mex.c +++ b/srslte/lib/phch/test/pucch_encode_test_mex.c @@ -91,7 +91,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } srslte_pucch_cfg_t pucch_cfg; bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); - pucch_cfg.beta_pucch = 1.0; + if (mexutils_read_uint32_struct(PUCCHCFG, "DeltaShift", &pucch_cfg.delta_pucch_shift)) { mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n"); return; @@ -190,7 +190,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } bzero(dmrs_pucch, sizeof(cf_t)*SRSLTE_NRE*3*2); - srslte_refsignal_ul_set_cfg(&pucch_dmrs, NULL, &pucch_cfg, NULL, group_hopping_en, false); + srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; + pusch_cfg.group_hopping_en = group_hopping_en; + pusch_cfg.sequence_hopping_en = false; + srslte_refsignal_ul_set_cfg(&pucch_dmrs, &pusch_cfg, &pucch_cfg, NULL); if (srslte_refsignal_dmrs_pucch_gen(&pucch_dmrs, format, n_pucch, sf_idx, pucch2_bits, dmrs_pucch)) { mexErrMsgTxt("Error generating PUCCH DMRS\n"); diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index 858ecf478..5ced3eae8 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -124,7 +124,7 @@ int main(int argc, char **argv) { for (uint32_t n_pucch=1;n_pucch<130;n_pucch++) { struct timeval t[3]; - pucch_cfg.beta_pucch = 1.0; + pucch_cfg.delta_pucch_shift = d; bool group_hopping_en = false; pucch_cfg.N_cs = ncs; @@ -140,7 +140,11 @@ int main(int argc, char **argv) { fprintf(stderr, "Error encoding PUCCH\n"); goto quit; } - srslte_refsignal_ul_set_cfg(&dmrs, NULL, &pucch_cfg, NULL, group_hopping_en, false); + + srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; + pusch_cfg.group_hopping_en = group_hopping_en; + pusch_cfg.sequence_hopping_en = false; + srslte_refsignal_ul_set_cfg(&dmrs, &pusch_cfg, &pucch_cfg, NULL); if (srslte_refsignal_dmrs_pucch_gen(&dmrs, format, n_pucch, subframe, pucch2_bits, pucch_dmrs)) { fprintf(stderr, "Error encoding PUCCH\n"); diff --git a/srslte/lib/phch/test/pusch_encode_test_mex.c b/srslte/lib/phch/test/pusch_encode_test_mex.c index 8b1aa02fa..9e63a73ea 100644 --- a/srslte/lib/phch/test/pusch_encode_test_mex.c +++ b/srslte/lib/phch/test/pusch_encode_test_mex.c @@ -86,13 +86,17 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Field NSubframe not found in UE config\n"); return; } + + srslte_ra_ul_grant_t grant; + bzero(&grant, sizeof(srslte_ra_ul_grant_t)); + char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation"); if (!strcmp(mod_str, "QPSK")) { - cfg.grant.mcs.mod = SRSLTE_MOD_QPSK; + grant.mcs.mod = SRSLTE_MOD_QPSK; } else if (!strcmp(mod_str, "16QAM")) { - cfg.grant.mcs.mod = SRSLTE_MOD_16QAM; + grant.mcs.mod = SRSLTE_MOD_16QAM; } else if (!strcmp(mod_str, "64QAM")) { - cfg.grant.mcs.mod = SRSLTE_MOD_64QAM; + grant.mcs.mod = SRSLTE_MOD_64QAM; } else { mexErrMsgTxt("Unknown modulation\n"); return; @@ -113,33 +117,33 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (N_srs == 1) { pusch.shortened = true; } - cfg.grant.L_prb = mexutils_read_f(p, &prbset); - cfg.grant.n_prb[0] = prbset[0]; - cfg.grant.n_prb[1] = prbset[0]; - cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE; - cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be? - cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod); - if (srslte_pusch_cfg(&pusch, &cfg, NULL, NULL, NULL, cfg.sf_idx, 0, cfg.rv)) { + + grant.L_prb = mexutils_read_f(p, &prbset); + grant.n_prb[0] = prbset[0]; + grant.n_prb[1] = prbset[0]; + free(prbset); + + uint8_t *trblkin = NULL; + grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin); + + grant.M_sc = grant.L_prb*SRSLTE_NRE; + grant.M_sc_init = grant.M_sc; // FIXME: What should M_sc_init be? + grant.Qm = srslte_mod_bits_x_symbol(grant.mcs.mod); + + if (srslte_pusch_cfg(&pusch, &cfg, &grant, NULL, NULL, NULL, cfg.sf_idx, cfg.rv, 0)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } - free(prbset); - - mexPrintf("L_prb: %d, n_prb: %d\n", cfg.grant.L_prb, cfg.grant.n_prb[0]); + mexPrintf("L_prb: %d, n_prb: %d\n", grant.L_prb, grant.n_prb[0]); - uint8_t *trblkin = NULL; - cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin); srslte_softbuffer_tx_t softbuffer; if (srslte_softbuffer_tx_init(&softbuffer, cell)) { mexErrMsgTxt("Error initiating soft buffer\n"); return; } - if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) { - mexErrMsgTxt("Error computing CB segmentation\n"); - return; - } + uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp); cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re); @@ -168,26 +172,26 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) float beta; if (mexutils_read_float_struct(PUSCHCFG, "BetaCQI", &beta)) { - uci_data.I_offset_cqi = 7; + cfg.uci_cfg.I_offset_cqi = 7; } else { - uci_data.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta); + cfg.uci_cfg.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta); } if (mexutils_read_float_struct(PUSCHCFG, "BetaRI", &beta)) { - uci_data.I_offset_ri = 2; + cfg.uci_cfg.I_offset_ri = 2; } else { - uci_data.I_offset_ri = srslte_sch_find_Ioffset_ri(beta); + cfg.uci_cfg.I_offset_ri = srslte_sch_find_Ioffset_ri(beta); } if (mexutils_read_float_struct(PUSCHCFG, "BetaACK", &beta)) { - uci_data.I_offset_ack = 0; + cfg.uci_cfg.I_offset_ack = 0; } else { - uci_data.I_offset_ack = srslte_sch_find_Ioffset_ack(beta); + cfg.uci_cfg.I_offset_ack = srslte_sch_find_Ioffset_ack(beta); } - mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", cfg.grant.mcs.tbs, + mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", grant.mcs.tbs, uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ack, uci_data.uci_ri_len, uci_data.uci_ri); - mexPrintf("I_cqi: %d, I_ri: %d, I_ack=%d\n", uci_data.I_offset_cqi, uci_data.I_offset_ri, uci_data.I_offset_ack); + mexPrintf("I_cqi: %d, I_ri: %d, I_ack=%d\n", cfg.uci_cfg.I_offset_cqi, cfg.uci_cfg.I_offset_ri, cfg.uci_cfg.I_offset_ack); - mexPrintf("NofRE: %d, NofBits: %d, TBS: %d, N_srs=%d\n", cfg.nbits.nof_re, cfg.nbits.nof_bits, cfg.grant.mcs.tbs, N_srs); + mexPrintf("NofRE: %d, NofBits: %d, TBS: %d, N_srs=%d\n", cfg.nbits.nof_re, cfg.nbits.nof_bits, grant.mcs.tbs, N_srs); int r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols); if (r < 0) { mexErrMsgTxt("Error encoding PUSCH\n"); diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index 748facfcc..a9943324c 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -135,11 +135,15 @@ int main(int argc, char **argv) { srslte_dci_msg_t dci_msg; srslte_dci_msg_pack_pusch(&dci, &dci_msg, cell.nof_prb); + srslte_ra_ul_grant_t grant; + if (srslte_dci_msg_to_ul_grant(&dci_msg, cell.nof_prb, 0, NULL, &grant)) { + return false; + } + srslte_pusch_hopping_cfg_t ul_hopping; ul_hopping.n_sb = 1; ul_hopping.hopping_offset = 0; ul_hopping.hop_mode = SRSLTE_PUSCH_HOP_MODE_INTER_SF; - ul_hopping.current_tx_nb = 0; if (srslte_pusch_init(&pusch, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); @@ -147,35 +151,38 @@ int main(int argc, char **argv) { } /* Configure PUSCH */ - if (srslte_pusch_cfg(&pusch, &cfg, &dci_msg, &ul_hopping, NULL, subframe, 0, 0)) { + + printf("Encoding rv_idx=%d\n",rv_idx); + + srslte_uci_cfg_t uci_cfg; + uci_cfg.I_offset_cqi = 7; + uci_cfg.I_offset_ri = 2; + uci_cfg.I_offset_ack = 4; + + if (srslte_pusch_cfg(&pusch, &cfg, &grant, &uci_cfg, &ul_hopping, NULL, subframe, 0, 0)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } srslte_pusch_set_rnti(&pusch, 1234); - - printf("Encoding rv_idx=%d\n",rv_idx); - cfg.rv = 0; - cfg.sf_idx = subframe; - uint8_t tmp[20]; - for (uint32_t i=0;i<20;i++) { - tmp[i] = 1; - } srslte_uci_data_t uci_data; bzero(&uci_data, sizeof(srslte_uci_data_t)); - uci_data.I_offset_cqi = 7; - uci_data.I_offset_ri = 2; - uci_data.I_offset_ack = 4; - uci_data.uci_cqi_len = 8; uci_data.uci_ri_len = 0; uci_data.uci_ack_len = 1; + uint8_t tmp[20]; + for (uint32_t i=0;i<20;i++) { + tmp[i] = 1; + } + uci_data.uci_cqi = tmp; uci_data.uci_ri = 0; uci_data.uci_ack = 0; - + + + uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp); sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re); if (!sf_symbols) { diff --git a/srslte/lib/phch/test/ulsch_encode_test_mex.c b/srslte/lib/phch/test/ulsch_encode_test_mex.c index 3575e5f4d..4fc054a39 100644 --- a/srslte/lib/phch/test/ulsch_encode_test_mex.c +++ b/srslte/lib/phch/test/ulsch_encode_test_mex.c @@ -99,19 +99,19 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) float beta; if (mexutils_read_float_struct(PUSCHCFG, "BetaCQI", &beta)) { - uci_data.I_offset_cqi = 7; + cfg.uci_cfg.I_offset_cqi = 7; } else { - uci_data.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta); + cfg.uci_cfg.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta); } if (mexutils_read_float_struct(PUSCHCFG, "BetaRI", &beta)) { - uci_data.I_offset_ri = 2; + cfg.uci_cfg.I_offset_ri = 2; } else { - uci_data.I_offset_ri = srslte_sch_find_Ioffset_ri(beta); + cfg.uci_cfg.I_offset_ri = srslte_sch_find_Ioffset_ri(beta); } if (mexutils_read_float_struct(PUSCHCFG, "BetaACK", &beta)) { - uci_data.I_offset_ack = 0; + cfg.uci_cfg.I_offset_ack = 0; } else { - uci_data.I_offset_ack = srslte_sch_find_Ioffset_ack(beta); + cfg.uci_cfg.I_offset_ack = srslte_sch_find_Ioffset_ack(beta); } char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation"); diff --git a/srslte/lib/ue/src/ue_dl.c b/srslte/lib/ue/src/ue_dl.c index c25533fe1..d4fa63960 100644 --- a/srslte/lib/ue/src/ue_dl.c +++ b/srslte/lib/ue/src/ue_dl.c @@ -203,12 +203,12 @@ int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf } } -int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) +int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { - return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, dci_msg, cfi, sf_idx, rnti, rvidx); + return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rnti, rvidx); } -int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint8_t *data, +int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint8_t *data, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { int ret = SRSLTE_ERROR; @@ -216,7 +216,7 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_ q->nof_detected++; /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ - if (srslte_ue_dl_cfg_grant(q, dci_msg, cfi, sf_idx, rnti, rvidx)) { + if (srslte_ue_dl_cfg_grant(q, grant, cfi, sf_idx, rnti, rvidx)) { return SRSLTE_ERROR; } @@ -278,6 +278,22 @@ uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q) { } int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti) +{ + srslte_rnti_type_t rnti_type; + if (rnti == SRSLTE_SIRNTI) { + rnti_type = SRSLTE_RNTI_SI; + } else if (rnti == SRSLTE_PRNTI) { + rnti_type = SRSLTE_RNTI_PCH; + } else if (rnti <= SRSLTE_RARNTI_END) { + rnti_type = SRSLTE_RNTI_RAR; + } else { + rnti_type = SRSLTE_RNTI_USER; + } + return srslte_ue_dl_find_dl_dci_type(q, dci_msg, cfi, sf_idx, rnti, rnti_type); +} + +int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, + uint16_t rnti, srslte_rnti_type_t rnti_type) { srslte_dci_location_t locations[MAX_CANDIDATES]; uint32_t nof_locations; @@ -285,7 +301,7 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 srslte_dci_format_t *formats = NULL; /* Generate PDCCH candidates */ - if (rnti == SRSLTE_SIRNTI) { + if (rnti_type == SRSLTE_RNTI_SI || rnti_type == SRSLTE_RNTI_PCH || rnti_type == SRSLTE_RNTI_RAR) { nof_locations = srslte_pdcch_common_locations(&q->pdcch, locations, MAX_CANDIDATES, q->cfi); formats = common_formats; nof_formats = nof_common_formats; @@ -323,6 +339,8 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint3 int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { srslte_dci_msg_t dci_msg; + srslte_ra_dl_dci_t dci_unpacked; + srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &q->cfi)) < 0) { @@ -337,7 +355,13 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti); if (found_dci == 1) { - ret = srslte_ue_dl_decode_rnti_rv_packet(q, &dci_msg, data, q->cfi, sf_idx, rnti, rvidx); + + if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, &dci_unpacked, &grant)) { + fprintf(stderr, "Error unpacking DCI\n"); + return SRSLTE_ERROR; + } + + ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, q->cfi, sf_idx, rnti, rvidx); } if (found_dci == 1 && ret == SRSLTE_SUCCESS) { diff --git a/srslte/lib/ue/src/ue_sync.c b/srslte/lib/ue/src/ue_sync.c index 5f52d387a..31efbcbe1 100644 --- a/srslte/lib/ue/src/ue_sync.c +++ b/srslte/lib/ue/src/ue_sync.c @@ -183,6 +183,7 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, } + /* FIXME: Go for zerocopy only and eliminate this allocation */ q->input_buffer = srslte_vec_malloc(2*q->frame_len * sizeof(cf_t)); if (!q->input_buffer) { perror("malloc"); @@ -260,7 +261,7 @@ void srslte_ue_sync_set_N_id_2(srslte_ue_sync_t *q, uint32_t N_id_2) { } } -static int find_peak_ok(srslte_ue_sync_t *q) { +static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer) { if (srslte_sync_sss_detected(&q->sfind)) { @@ -278,7 +279,7 @@ static int find_peak_ok(srslte_ue_sync_t *q) { if (q->frame_find_cnt >= q->nof_avg_find_frames || q->peak_idx < 2*q->fft_size) { DEBUG("Realigning frame, reading %d samples\n", q->peak_idx+q->sf_len/2); /* Receive the rest of the subframe so that we are subframe aligned*/ - if (q->recv_callback(q->stream, q->input_buffer, q->peak_idx+q->sf_len/2, &q->last_timestamp) < 0) { + if (q->recv_callback(q->stream, input_buffer, q->peak_idx+q->sf_len/2, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -350,7 +351,7 @@ static int track_peak_no(srslte_ue_sync_t *q) { return 1; } -static int receive_samples(srslte_ue_sync_t *q) { +static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { /* A negative time offset means there are samples in our buffer for the next subframe, because we are sampling too fast. @@ -360,7 +361,7 @@ static int receive_samples(srslte_ue_sync_t *q) { } /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ - if (q->recv_callback(q->stream, &q->input_buffer[q->time_offset], q->frame_len - q->time_offset, &q->last_timestamp) < 0) { + if (q->recv_callback(q->stream, &input_buffer[q->time_offset], q->frame_len - q->time_offset, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -373,16 +374,24 @@ static int receive_samples(srslte_ue_sync_t *q) { bool first_track = true; int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { + int ret = srslte_ue_sync_zerocopy(q, q->input_buffer); + if (sf_symbols) { + *sf_symbols = q->input_buffer; + } + return ret; + +} + +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; if (q != NULL && - sf_symbols != NULL && - q->input_buffer != NULL) + input_buffer != NULL) { if (q->file_mode) { - int n = srslte_filesource_read(&q->file_source, q->input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -390,7 +399,7 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { if (n == 0) { srslte_filesource_seek(&q->file_source, 0); q->sf_idx = 9; - int n = srslte_filesource_read(&q->file_source, q->input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -402,25 +411,24 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { } DEBUG("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); ret = 1; - *sf_symbols = q->input_buffer; } else { - if (receive_samples(q)) { + if (receive_samples(q, input_buffer)) { fprintf(stderr, "Error receiving samples\n"); return SRSLTE_ERROR; } switch (q->state) { case SF_FIND: - ret = srslte_sync_find(&q->sfind, q->input_buffer, 0, &q->peak_idx); + ret = srslte_sync_find(&q->sfind, input_buffer, 0, &q->peak_idx); if (ret < 0) { fprintf(stderr, "Error finding correlation peak (%d)\n", ret); return SRSLTE_ERROR; } if (q->do_agc) { - srslte_agc_process(&q->agc, q->input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer, q->sf_len); } if (ret == 1) { - ret = find_peak_ok(q); + ret = find_peak_ok(q, input_buffer); } break; case SF_TRACK: @@ -434,7 +442,7 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { if (q->sf_idx == 0 || q->sf_idx == 5) { if (q->do_agc) { - srslte_agc_process(&q->agc, q->input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer, q->sf_len); } #ifdef MEASURE_EXEC_TIME @@ -445,7 +453,7 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { track_idx = 0; /* track PSS/SSS around the expected PSS position */ - ret = srslte_sync_find(&q->strack, q->input_buffer, + ret = srslte_sync_find(&q->strack, input_buffer, q->frame_len - q->sf_len/2 - q->fft_size - q->strack.frame_size/2, &track_idx); if (ret < 0) { @@ -476,13 +484,11 @@ int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { /* Do CFO Correction if not done in track and deliver the frame */ if (!q->strack.correct_cfo && q->correct_cfo) { srslte_cfo_correct(&q->sfind.cfocorr, - q->input_buffer, - q->input_buffer, + input_buffer, + input_buffer, -srslte_sync_get_cfo(&q->strack) / q->fft_size); } - *sf_symbols = q->input_buffer; - break; } diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index 983c7b32f..9caf43dd8 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -57,9 +57,9 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q, goto clean_exit; } srslte_ofdm_set_freq_shift(&q->fft, 0.5); - srslte_ofdm_set_normalize(&q->fft, true); + srslte_ofdm_set_normalize(&q->fft, false); - q->normalize_en = true; + q->normalize_en = false; if (srslte_cfo_init(&q->cfo, CURRENT_SFLEN)) { fprintf(stderr, "Error creating CFO object\n"); @@ -182,32 +182,43 @@ int srslte_ue_ul_pregen_signals(srslte_ue_ul_t *q) { return SRSLTE_SUCCESS; } + void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q, - srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, - srslte_pucch_cfg_t *pucch_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, - srslte_pucch_sched_t *pucch_sched, - bool group_hopping_en, - bool sequence_hopping_en) + srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_pucch_cfg_t *pucch_cfg, + srslte_pucch_sched_t *pucch_sched, + srslte_uci_cfg_t *uci_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg) { - srslte_refsignal_ul_set_cfg(&q->signals, pusch_cfg, pucch_cfg, srs_cfg, group_hopping_en, sequence_hopping_en); - srslte_pucch_set_cfg(&q->pucch, pucch_cfg, group_hopping_en); + srslte_refsignal_ul_set_cfg(&q->signals, dmrs_cfg, pucch_cfg, srs_cfg); + if (pucch_cfg && dmrs_cfg) { + srslte_pucch_set_cfg(&q->pucch, pucch_cfg, dmrs_cfg->group_hopping_en); + } if (pucch_sched) { memcpy(&q->pucch_sched, pucch_sched, sizeof(srslte_pucch_sched_t)); } + if (srs_cfg) { + memcpy(&q->srs_cfg, srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + } + if (uci_cfg) { + memcpy(&q->uci_cfg, uci_cfg, sizeof(srslte_uci_cfg_t)); + } + if (hopping_cfg) { + memcpy(&q->hopping_cfg, hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); + } } -int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_dci_msg_t *dci_msg, - srslte_pusch_hopping_cfg_t *hopping_cfg, - srslte_refsignal_srs_cfg_t *srs_cfg, - uint32_t tti, uint32_t cyclic_shift_for_dmrs, uint32_t rvidx) +int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, + uint32_t tti, uint32_t rvidx, uint32_t current_tx_nb) { - return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, dci_msg, hopping_cfg, srs_cfg, tti, cyclic_shift_for_dmrs, rvidx); + return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, &q->uci_cfg, &q->hopping_cfg, &q->srs_cfg, tti, rvidx, current_tx_nb); } /* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal */ -int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, +int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, + uint32_t pdcch_n_cce, uint32_t tti, cf_t *output_signal) { @@ -279,7 +290,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, if (q->pucch_sched.sps_enabled) { n_pucch = q->pucch_sched.n_pucch_1[q->pucch_sched.tpc_for_pucch%4]; } else { - n_pucch = q->pucch_sched.n_cce + q->pucch_sched.N_pucch_1; + n_pucch = pdcch_n_cce + q->pucch_sched.N_pucch_1; } } else { n_pucch = q->pucch_sched.n_pucch_2; @@ -410,13 +421,13 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, srslte_refsignal_dmrs_pusch_pregen_put(&q->signals, &q->pregen_drms, q->pusch_cfg.grant.L_prb, q->pusch_cfg.sf_idx, - q->pusch_cfg.cyclic_shift_for_dmrs, + q->pusch_cfg.grant.ncs_dmrs, q->pusch_cfg.grant.n_prb_tilde, q->sf_symbols); } else { if (srslte_refsignal_dmrs_pusch_gen(&q->signals, q->pusch_cfg.grant.L_prb, q->pusch_cfg.sf_idx, - q->pusch_cfg.cyclic_shift_for_dmrs, + q->pusch_cfg.grant.ncs_dmrs, q->refsignal)) { fprintf(stderr, "Error generating PUSCH DRMS signals\n"); diff --git a/srslte/lib/utils/src/vector.c b/srslte/lib/utils/src/vector.c index 39fe13b98..1f4de7cc4 100644 --- a/srslte/lib/utils/src/vector.c +++ b/srslte/lib/utils/src/vector.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -159,6 +160,22 @@ void srslte_vec_sc_prod_fff(float *x, float h, float *z, uint32_t len) { #endif } +// TODO: Improve this implementation +void srslte_vec_norm_cfc(cf_t *x, float amplitude, cf_t *y, uint32_t len) { + // Compute peak + float max = 0; + float *t = (float*) x; + for (int i=0;i<2*len;i++) { + if (fabsf(t[i]) > max) { + max = fabsf(t[i]); + } + } + + // Normalize before TX + srslte_vec_sc_prod_cfc(x, amplitude/max, y, len); + +} + void srslte_vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len) { #ifndef HAVE_VOLK_MULT_FUNCTION int i;