mirror of https://github.com/PentHertz/srsLTE.git
Initial HARQ-ACK multiplex in PUSCH
This commit is contained in:
parent
7b588eafec
commit
f4e9d00ea8
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "srslte/phy/common/phy_common_nr.h"
|
#include "srslte/phy/common/phy_common_nr.h"
|
||||||
#include "srslte/phy/phch/sch_cfg_nr.h"
|
#include "srslte/phy/phch/sch_cfg_nr.h"
|
||||||
|
#include "srslte/phy/phch/uci_cfg_nr.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PDSCH DMRS type
|
* @brief PDSCH DMRS type
|
||||||
|
@ -201,8 +202,12 @@ typedef struct SRSLTE_API {
|
||||||
|
|
||||||
srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters
|
srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters
|
||||||
|
|
||||||
/// Uplink params
|
/// PUSCH only parameters
|
||||||
|
srslte_uci_cfg_nr_t uci; ///< Uplink Control Information configuration
|
||||||
bool enable_transform_precoder;
|
bool enable_transform_precoder;
|
||||||
|
float beta_harq_ack_offset;
|
||||||
|
float beta_csi_part1_offset;
|
||||||
|
float scaling;
|
||||||
} srslte_sch_cfg_nr_t;
|
} srslte_sch_cfg_nr_t;
|
||||||
|
|
||||||
#endif // SRSLTE_PHCH_CFG_NR_H
|
#endif // SRSLTE_PHCH_CFG_NR_H
|
||||||
|
|
|
@ -42,6 +42,7 @@ typedef struct SRSLTE_API {
|
||||||
*/
|
*/
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint32_t max_prb;
|
uint32_t max_prb;
|
||||||
|
srslte_carrier_nr_t carrier;
|
||||||
srslte_zc_sequence_lut_t r_uv_1prb;
|
srslte_zc_sequence_lut_t r_uv_1prb;
|
||||||
cf_t format1_w_i_m[SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX];
|
cf_t format1_w_i_m[SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX][SRSLTE_PUCCH_NR_FORMAT1_N_MAX];
|
||||||
srslte_modem_table_t bpsk;
|
srslte_modem_table_t bpsk;
|
||||||
|
@ -55,10 +56,19 @@ typedef struct SRSLTE_API {
|
||||||
/**
|
/**
|
||||||
* @brief Initialises an NR-PUCCH encoder/decoder object
|
* @brief Initialises an NR-PUCCH encoder/decoder object
|
||||||
* @param q Object
|
* @param q Object
|
||||||
|
* @param args PUCCH configuration arguments
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* args);
|
SRSLTE_API int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialises an NR-PUCCH encoder/decoder object
|
||||||
|
* @param q Object
|
||||||
|
* @param carrier
|
||||||
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_pucch_nr_set_carrier(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deallocates an NR-PUCCH encoder/decoder object
|
* @brief Deallocates an NR-PUCCH encoder/decoder object
|
||||||
* @param q Object
|
* @param q Object
|
||||||
|
@ -104,7 +114,6 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car
|
||||||
* @brief Encode and writes NR-PUCCH format 0 in the resource grid
|
* @brief Encode and writes NR-PUCCH format 0 in the resource grid
|
||||||
* @remark Described in TS 38.211 clause 6.3.2.3 PUCCH format 0
|
* @remark Described in TS 38.211 clause 6.3.2.3 PUCCH format 0
|
||||||
* @param[in,out] q NR-PUCCH encoder/decoder object
|
* @param[in,out] q NR-PUCCH encoder/decoder object
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 0 resource
|
* @param[in] resource PUCCH format 0 resource
|
||||||
|
@ -113,7 +122,6 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
srslte_pucch_nr_resource_t* resource,
|
srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -123,7 +131,6 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t*
|
||||||
/**
|
/**
|
||||||
* @brief Measures PUCCH format 0 in the resource grid
|
* @brief Measures PUCCH format 0 in the resource grid
|
||||||
* @param[in,out] q NR-PUCCH encoder/decoder object
|
* @param[in,out] q NR-PUCCH encoder/decoder object
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 0 resource
|
* @param[in] resource PUCCH format 0 resource
|
||||||
|
@ -133,7 +140,6 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t*
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
srslte_pucch_nr_resource_t* resource,
|
srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -156,7 +162,6 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n
|
||||||
* @brief Encodes and puts NR-PUCCH format 1 in the resource grid
|
* @brief Encodes and puts NR-PUCCH format 1 in the resource grid
|
||||||
* @remark Described in TS 38.211 clause 6.3.2.4 PUCCH format 1
|
* @remark Described in TS 38.211 clause 6.3.2.4 PUCCH format 1
|
||||||
* @param[in,out] q NR-PUCCH encoder/decoder object
|
* @param[in,out] q NR-PUCCH encoder/decoder object
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 1 resource
|
* @param[in] resource PUCCH format 1 resource
|
||||||
|
@ -166,7 +171,6 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -177,7 +181,6 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t*
|
||||||
/**
|
/**
|
||||||
* @brief Decodes NR-PUCCH format 1
|
* @brief Decodes NR-PUCCH format 1
|
||||||
* @param[in,out] q NR-PUCCH encoder/decoder object
|
* @param[in,out] q NR-PUCCH encoder/decoder object
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 2-4 resource
|
* @param[in] resource PUCCH format 2-4 resource
|
||||||
|
@ -188,7 +191,6 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t*
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -200,7 +202,6 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t*
|
||||||
/**
|
/**
|
||||||
* @brief Encoder NR-PUCCH formats 2, 3 and 4. The NR-PUCCH format is selected by resource->format.
|
* @brief Encoder NR-PUCCH formats 2, 3 and 4. The NR-PUCCH format is selected by resource->format.
|
||||||
* @param[in,out] q NR-PUCCH encoder/decoder object
|
* @param[in,out] q NR-PUCCH encoder/decoder object
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 1 resource
|
* @param[in] resource PUCCH format 1 resource
|
||||||
|
@ -210,7 +211,6 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t*
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -221,7 +221,6 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t*
|
||||||
/**
|
/**
|
||||||
* @brief Decode NR-PUCCH format 2, 3, and 4. The NR-PUCCH format is selected by resource->format.
|
* @brief Decode NR-PUCCH format 2, 3, and 4. The NR-PUCCH format is selected by resource->format.
|
||||||
* @param q[in,out] q NR-PUCCH encoder/decoder
|
* @param q[in,out] q NR-PUCCH encoder/decoder
|
||||||
* @param[in] carrier Serving cell and Uplink BWP configuration
|
|
||||||
* @param[in] cfg PUCCH common configuration
|
* @param[in] cfg PUCCH common configuration
|
||||||
* @param[in] slot slot configuration
|
* @param[in] slot slot configuration
|
||||||
* @param[in] resource PUCCH format 2-4 resource
|
* @param[in] resource PUCCH format 2-4 resource
|
||||||
|
@ -232,7 +231,6 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t*
|
||||||
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "srslte/phy/phch/phch_cfg_nr.h"
|
#include "srslte/phy/phch/phch_cfg_nr.h"
|
||||||
#include "srslte/phy/phch/regs.h"
|
#include "srslte/phy/phch/regs.h"
|
||||||
#include "srslte/phy/phch/sch_nr.h"
|
#include "srslte/phy/phch/sch_nr.h"
|
||||||
|
#include "srslte/phy/phch/uci_nr.h"
|
||||||
#include "srslte/phy/scrambling/scrambling.h"
|
#include "srslte/phy/scrambling/scrambling.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
srslte_sch_nr_args_t sch;
|
srslte_sch_nr_args_t sch;
|
||||||
|
srslte_uci_nr_args_t uci;
|
||||||
bool measure_evm;
|
bool measure_evm;
|
||||||
bool measure_time;
|
bool measure_time;
|
||||||
} srslte_pusch_nr_args_t;
|
} srslte_pusch_nr_args_t;
|
||||||
|
@ -40,6 +42,7 @@ typedef struct SRSLTE_API {
|
||||||
uint32_t max_cw; ///< Maximum number of allocated code words
|
uint32_t max_cw; ///< Maximum number of allocated code words
|
||||||
srslte_carrier_nr_t carrier; ///< NR carrier configuration
|
srslte_carrier_nr_t carrier; ///< NR carrier configuration
|
||||||
srslte_sch_nr_t sch; ///< SCH Encoder/Decoder Object
|
srslte_sch_nr_t sch; ///< SCH Encoder/Decoder Object
|
||||||
|
srslte_uci_nr_t uci; ///< UCI Encoder/Decoder Object
|
||||||
uint8_t* b[SRSLTE_MAX_CODEWORDS]; ///< SCH Encoded and scrambled data
|
uint8_t* b[SRSLTE_MAX_CODEWORDS]; ///< SCH Encoded and scrambled data
|
||||||
cf_t* d[SRSLTE_MAX_CODEWORDS]; ///< PDSCH modulated bits
|
cf_t* d[SRSLTE_MAX_CODEWORDS]; ///< PDSCH modulated bits
|
||||||
cf_t* x[SRSLTE_MAX_LAYERS_NR]; ///< PDSCH modulated bits
|
cf_t* x[SRSLTE_MAX_LAYERS_NR]; ///< PDSCH modulated bits
|
||||||
|
@ -47,15 +50,26 @@ typedef struct SRSLTE_API {
|
||||||
srslte_evm_buffer_t* evm_buffer;
|
srslte_evm_buffer_t* evm_buffer;
|
||||||
bool meas_time_en;
|
bool meas_time_en;
|
||||||
uint32_t meas_time_us;
|
uint32_t meas_time_us;
|
||||||
|
uint8_t* uci_ack;
|
||||||
|
uint8_t* uci_csi;
|
||||||
} srslte_pusch_nr_t;
|
} srslte_pusch_nr_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @brief Groups NR-PUSCH data for transmission
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* payload;
|
uint8_t* payload; ///< SCH payload
|
||||||
bool crc;
|
srslte_uci_value_nr_t uci; ///< UCI payload
|
||||||
float evm;
|
} srslte_pusch_data_nr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Groups NR-PUSCH data for reception
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t* payload; ///< SCH payload
|
||||||
|
srslte_uci_value_nr_t uci; ///< UCI payload
|
||||||
|
bool crc; ///< CRC match
|
||||||
|
float evm; ///< EVM measurement if configured through arguments
|
||||||
} srslte_pusch_res_nr_t;
|
} srslte_pusch_res_nr_t;
|
||||||
|
|
||||||
SRSLTE_API int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args);
|
SRSLTE_API int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args);
|
||||||
|
@ -69,7 +83,7 @@ SRSLTE_API int srslte_pusch_nr_set_carrier(srslte_pusch_nr_t* q, const srslte_ca
|
||||||
SRSLTE_API int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
|
SRSLTE_API int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
|
||||||
const srslte_sch_cfg_nr_t* cfg,
|
const srslte_sch_cfg_nr_t* cfg,
|
||||||
const srslte_sch_grant_nr_t* grant,
|
const srslte_sch_grant_nr_t* grant,
|
||||||
uint8_t* data[SRSLTE_MAX_TB],
|
const srslte_pusch_data_nr_t* data,
|
||||||
cf_t* sf_symbols[SRSLTE_MAX_PORTS]);
|
cf_t* sf_symbols[SRSLTE_MAX_PORTS]);
|
||||||
|
|
||||||
SRSLTE_API int srslte_pusch_nr_decode(srslte_pusch_nr_t* q,
|
SRSLTE_API int srslte_pusch_nr_decode(srslte_pusch_nr_t* q,
|
||||||
|
|
|
@ -86,10 +86,7 @@ typedef struct {
|
||||||
bool mask[SRSLTE_SCH_NR_MAX_NOF_CB_LDPC]; ///< Indicates what codeblocks shall be encoded/decoded
|
bool mask[SRSLTE_SCH_NR_MAX_NOF_CB_LDPC]; ///< Indicates what codeblocks shall be encoded/decoded
|
||||||
uint32_t C; ///< Number of codeblocks
|
uint32_t C; ///< Number of codeblocks
|
||||||
uint32_t Cp; ///< Number of codeblocks that are actually transmitted
|
uint32_t Cp; ///< Number of codeblocks that are actually transmitted
|
||||||
srslte_crc_t* crc_tb; ///< Selected CRC for transport block
|
} srslte_sch_nr_tb_info_t;
|
||||||
srslte_ldpc_encoder_t* encoder; ///< @brief Points to the selected encoder (if valid)
|
|
||||||
srslte_ldpc_decoder_t* decoder; ///< @brief Points to the selected decoder (if valid)
|
|
||||||
} srslte_sch_nr_common_cfg_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Base graph selection from a provided transport block size and target rate
|
* @brief Base graph selection from a provided transport block size and target rate
|
||||||
|
@ -110,10 +107,10 @@ SRSLTE_API srslte_basegraph_t srslte_sch_nr_select_basegraph(uint32_t tbs, doubl
|
||||||
* @param cfg SCH object
|
* @param cfg SCH object
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q,
|
SRSLTE_API int srslte_sch_nr_fill_cfg(const srslte_carrier_nr_t* carrier,
|
||||||
const srslte_sch_cfg_t* sch_cfg,
|
const srslte_sch_cfg_t* sch_cfg,
|
||||||
const srslte_sch_tb_t* tb,
|
const srslte_sch_tb_t* tb,
|
||||||
srslte_sch_nr_common_cfg_t* cfg);
|
srslte_sch_nr_tb_info_t* cfg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialises an SCH object as transmitter
|
* @brief Initialises an SCH object as transmitter
|
||||||
|
|
|
@ -29,23 +29,12 @@
|
||||||
*/
|
*/
|
||||||
#define SRSLTE_UCI_NR_MAX_ACK_BITS 360
|
#define SRSLTE_UCI_NR_MAX_ACK_BITS 360
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum number of Scheduling Request (SR) bits that can be carried in Uplink Control Information (UCI) message
|
|
||||||
*/
|
|
||||||
#define SRSLTE_UCI_NR_MAX_SR_BITS 10
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum number of Channel State Information part 1 (CSI1) bits that can be carried in Uplink Control
|
* @brief Maximum number of Channel State Information part 1 (CSI1) bits that can be carried in Uplink Control
|
||||||
* Information (UCI) message
|
* Information (UCI) message
|
||||||
*/
|
*/
|
||||||
#define SRSLTE_UCI_NR_MAX_CSI1_BITS 10
|
#define SRSLTE_UCI_NR_MAX_CSI1_BITS 10
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum number of Channel State Information part 2 (CSI2) bits that can be carried in Uplink Control
|
|
||||||
* Information (UCI) message
|
|
||||||
*/
|
|
||||||
#define SRSLTE_UCI_NR_MAX_CSI2_BITS 10
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uplink Control Information (UCI) message configuration
|
* @brief Uplink Control Information (UCI) message configuration
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +46,8 @@ typedef struct SRSLTE_API {
|
||||||
uint32_t nof_csi; ///< Number of CSI reports
|
uint32_t nof_csi; ///< Number of CSI reports
|
||||||
|
|
||||||
/// PUSCH only parameters
|
/// PUSCH only parameters
|
||||||
srslte_mod_t modulation; ///< Modulation
|
bool without_ul_sch; ///< Set to true if no UL-SCH data is scheduled
|
||||||
|
bool has_csi_part2; ///< Set to true if the CSI reports have part 2
|
||||||
|
|
||||||
/// PUCCH only parameters
|
/// PUCCH only parameters
|
||||||
uint16_t rnti; ///< RNTI
|
uint16_t rnti; ///< RNTI
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
#ifndef SRSLTE_UCI_NR_H
|
#ifndef SRSLTE_UCI_NR_H
|
||||||
#define SRSLTE_UCI_NR_H
|
#define SRSLTE_UCI_NR_H
|
||||||
|
|
||||||
|
#include "srslte/phy/common/phy_common_nr.h"
|
||||||
#include "srslte/phy/fec/crc.h"
|
#include "srslte/phy/fec/crc.h"
|
||||||
#include "srslte/phy/fec/polar/polar_code.h"
|
#include "srslte/phy/fec/polar/polar_code.h"
|
||||||
#include "srslte/phy/fec/polar/polar_decoder.h"
|
#include "srslte/phy/fec/polar/polar_decoder.h"
|
||||||
#include "srslte/phy/fec/polar/polar_encoder.h"
|
#include "srslte/phy/fec/polar/polar_encoder.h"
|
||||||
#include "srslte/phy/fec/polar/polar_rm.h"
|
#include "srslte/phy/fec/polar/polar_rm.h"
|
||||||
|
#include "srslte/phy/phch/phch_cfg_nr.h"
|
||||||
#include "srslte/phy/phch/pucch_cfg_nr.h"
|
#include "srslte/phy/phch/pucch_cfg_nr.h"
|
||||||
#include "uci_cfg.h"
|
|
||||||
#include "uci_cfg_nr.h"
|
#include "uci_cfg_nr.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -33,6 +34,7 @@ typedef struct {
|
||||||
} srslte_uci_nr_args_t;
|
} srslte_uci_nr_args_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
srslte_carrier_nr_t carrier;
|
||||||
srslte_polar_rm_t rm_tx;
|
srslte_polar_rm_t rm_tx;
|
||||||
srslte_polar_rm_t rm_rx;
|
srslte_polar_rm_t rm_rx;
|
||||||
srslte_polar_encoder_t encoder;
|
srslte_polar_encoder_t encoder;
|
||||||
|
@ -70,6 +72,14 @@ SRSLTE_API uint32_t srslte_uci_nr_crc_len(uint32_t A);
|
||||||
*/
|
*/
|
||||||
SRSLTE_API int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args);
|
SRSLTE_API int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets NR carrier
|
||||||
|
* @param[in,out] q NR-UCI object
|
||||||
|
* @param carrier Provides carrier configuration
|
||||||
|
* @return SRSLTE_SUCCESS if successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_uci_nr_set_carrier(srslte_uci_nr_t* q, const srslte_carrier_nr_t* carrier);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deallocates NR-UCI encoder/decoder object
|
* @brief Deallocates NR-UCI encoder/decoder object
|
||||||
* @param[in,out] q NR-UCI object
|
* @param[in,out] q NR-UCI object
|
||||||
|
@ -114,6 +124,27 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
|
||||||
int8_t* llr,
|
int8_t* llr,
|
||||||
srslte_uci_value_nr_t* value);
|
srslte_uci_value_nr_t* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates the total number of encoded bits for HARQ-ACK
|
||||||
|
* @param[in,out] q NR-UCI object
|
||||||
|
* @param[in] cfg PUSCH transmission configuration
|
||||||
|
* @return The number of encoded bits if successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_uci_nr_pusch_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encodes HARQ-ACK bits for PUSCH transmission
|
||||||
|
* @param[in,out] q NR-UCI object
|
||||||
|
* @param[in] cfg PUSCH transmission configuration
|
||||||
|
* @param[in] value UCI value
|
||||||
|
* @param[out] o_ack Encoded ack bits
|
||||||
|
* @return The number of encoded bits if successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q,
|
||||||
|
const srslte_sch_cfg_nr_t* cfg,
|
||||||
|
const srslte_uci_value_nr_t* value,
|
||||||
|
uint8_t* o_ack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculates the total number of UCI bits
|
* @brief Calculates the total number of UCI bits
|
||||||
* @param uci_cfg UCI configuration
|
* @param uci_cfg UCI configuration
|
||||||
|
|
|
@ -57,7 +57,7 @@ SRSLTE_API int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_ca
|
||||||
SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
|
SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
|
||||||
const srslte_slot_cfg_t* slot_cfg,
|
const srslte_slot_cfg_t* slot_cfg,
|
||||||
const srslte_sch_cfg_nr_t* pusch_cfg,
|
const srslte_sch_cfg_nr_t* pusch_cfg,
|
||||||
uint8_t* data_);
|
const srslte_pusch_data_nr_t* data);
|
||||||
|
|
||||||
SRSLTE_API int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q,
|
SRSLTE_API int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q,
|
||||||
const srslte_slot_cfg_t* slot_cfg,
|
const srslte_slot_cfg_t* slot_cfg,
|
||||||
|
|
|
@ -174,6 +174,17 @@ int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* arg
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_pucch_nr_set_carrier(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier)
|
||||||
|
{
|
||||||
|
if (q == NULL || carrier == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->carrier = *carrier;
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void srslte_pucch_nr_free(srslte_pucch_nr_t* q)
|
void srslte_pucch_nr_free(srslte_pucch_nr_t* q)
|
||||||
{
|
{
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
|
@ -201,14 +212,13 @@ void srslte_pucch_nr_free(srslte_pucch_nr_t* q)
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
srslte_pucch_nr_resource_t* resource,
|
srslte_pucch_nr_resource_t* resource,
|
||||||
uint32_t m_cs,
|
uint32_t m_cs,
|
||||||
cf_t* slot_symbols)
|
cf_t* slot_symbols)
|
||||||
{
|
{
|
||||||
if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) {
|
if (cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +229,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
|
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
uint32_t v = 0;
|
uint32_t v = 0;
|
||||||
if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error getting group sequence");
|
ERROR("Error getting group sequence");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -228,8 +238,8 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
for (uint32_t l = 0; l < resource->nof_symbols; l++) {
|
for (uint32_t l = 0; l < resource->nof_symbols; l++) {
|
||||||
// Get Alpha index
|
// Get Alpha index
|
||||||
uint32_t alpha_idx = 0;
|
uint32_t alpha_idx = 0;
|
||||||
if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) <
|
if (srslte_pucch_nr_alpha_idx(
|
||||||
SRSLTE_SUCCESS) {
|
&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +251,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get start of the sequence in resource grid
|
// Get start of the sequence in resource grid
|
||||||
cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
||||||
|
|
||||||
// Copy sequence in grid
|
// Copy sequence in grid
|
||||||
srslte_vec_cf_copy(slot_symbols_ptr, r_uv, SRSLTE_NRE);
|
srslte_vec_cf_copy(slot_symbols_ptr, r_uv, SRSLTE_NRE);
|
||||||
|
@ -251,7 +261,6 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
srslte_pucch_nr_resource_t* resource,
|
srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -259,7 +268,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
const cf_t* slot_symbols,
|
const cf_t* slot_symbols,
|
||||||
srslte_pucch_nr_measure_t* measure)
|
srslte_pucch_nr_measure_t* measure)
|
||||||
{
|
{
|
||||||
if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || measure == NULL) {
|
if (cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || measure == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +279,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
|
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
uint32_t v = 0;
|
uint32_t v = 0;
|
||||||
if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error getting group sequence");
|
ERROR("Error getting group sequence");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -281,8 +290,8 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
for (uint32_t l = 0; l < resource->nof_symbols; l++) {
|
for (uint32_t l = 0; l < resource->nof_symbols; l++) {
|
||||||
// Get Alpha index
|
// Get Alpha index
|
||||||
uint32_t alpha_idx = 0;
|
uint32_t alpha_idx = 0;
|
||||||
if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) <
|
if (srslte_pucch_nr_alpha_idx(
|
||||||
SRSLTE_SUCCESS) {
|
&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +304,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
|
||||||
|
|
||||||
// Get start of the sequence in resource grid
|
// Get start of the sequence in resource grid
|
||||||
const cf_t* slot_symbols_ptr =
|
const cf_t* slot_symbols_ptr =
|
||||||
&slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
&slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
||||||
|
|
||||||
// Measure EPRE and average
|
// Measure EPRE and average
|
||||||
epre += srslte_vec_avg_power_cf(slot_symbols_ptr, SRSLTE_NRE) / resource->nof_symbols;
|
epre += srslte_vec_avg_power_cf(slot_symbols_ptr, SRSLTE_NRE) / resource->nof_symbols;
|
||||||
|
@ -360,7 +369,6 @@ cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n_pucch, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -368,7 +376,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
uint32_t nof_bits,
|
uint32_t nof_bits,
|
||||||
cf_t* slot_symbols)
|
cf_t* slot_symbols)
|
||||||
{
|
{
|
||||||
if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || b == NULL || slot_symbols == NULL) {
|
if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || b == NULL || slot_symbols == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +401,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
// Get group sequence
|
// Get group sequence
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
uint32_t v = 0;
|
uint32_t v = 0;
|
||||||
if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error getting group sequence");
|
ERROR("Error getting group sequence");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -404,11 +412,11 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
uint32_t l_prime = resource->start_symbol_idx;
|
uint32_t l_prime = resource->start_symbol_idx;
|
||||||
for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) {
|
for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) {
|
||||||
// Get start of the sequence in resource grid
|
// Get start of the sequence in resource grid
|
||||||
cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
||||||
|
|
||||||
// Get Alpha index
|
// Get Alpha index
|
||||||
uint32_t alpha_idx = 0;
|
uint32_t alpha_idx = 0;
|
||||||
if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) <
|
if (srslte_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) <
|
||||||
SRSLTE_SUCCESS) {
|
SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -439,7 +447,6 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -450,6 +457,11 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
{
|
{
|
||||||
uint32_t m_cs = 0;
|
uint32_t m_cs = 0;
|
||||||
|
|
||||||
|
if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || chest_res == NULL || b == NULL ||
|
||||||
|
slot_symbols == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) {
|
if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Invalid PUCCH format 1 resource");
|
ERROR("Invalid PUCCH format 1 resource");
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
|
@ -466,7 +478,7 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
// Get group sequence
|
// Get group sequence
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
uint32_t v = 0;
|
uint32_t v = 0;
|
||||||
if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
if (srslte_pucch_nr_group_sequence(&q->carrier, cfg, &u, &v) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error getting group sequence");
|
ERROR("Error getting group sequence");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -477,8 +489,8 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
uint32_t l_prime = resource->start_symbol_idx;
|
uint32_t l_prime = resource->start_symbol_idx;
|
||||||
for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) {
|
for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) {
|
||||||
// Get start of the sequence in resource grid
|
// Get start of the sequence in resource grid
|
||||||
cf_t* slot_symbols_ptr = &slot_symbols[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
||||||
cf_t* ce_ptr = &chest_res->ce[(carrier->nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
cf_t* ce_ptr = &chest_res->ce[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSLTE_NRE];
|
||||||
|
|
||||||
// Equalise x = w(i) * d' * r_uv(n)
|
// Equalise x = w(i) * d' * r_uv(n)
|
||||||
cf_t x[SRSLTE_NRE];
|
cf_t x[SRSLTE_NRE];
|
||||||
|
@ -486,8 +498,8 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
|
||||||
|
|
||||||
// Get Alpha index
|
// Get Alpha index
|
||||||
uint32_t alpha_idx = 0;
|
uint32_t alpha_idx = 0;
|
||||||
if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) <
|
if (srslte_pucch_nr_alpha_idx(
|
||||||
SRSLTE_SUCCESS) {
|
&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,7 +642,6 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -639,8 +650,8 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
||||||
cf_t* slot_symbols)
|
cf_t* slot_symbols)
|
||||||
{
|
{
|
||||||
// Validate input pointers
|
// Validate input pointers
|
||||||
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL ||
|
if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || uci_value == NULL ||
|
||||||
uci_value == NULL || slot_symbols == NULL) {
|
slot_symbols == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,7 +664,7 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
||||||
// Modulate PUCCH
|
// Modulate PUCCH
|
||||||
switch (resource->format) {
|
switch (resource->format) {
|
||||||
case SRSLTE_PUCCH_NR_FORMAT_2:
|
case SRSLTE_PUCCH_NR_FORMAT_2:
|
||||||
return pucch_nr_format2_encode(q, carrier, cfg, resource, uci_cfg, slot_symbols);
|
return pucch_nr_format2_encode(q, &q->carrier, cfg, resource, uci_cfg, slot_symbols);
|
||||||
case SRSLTE_PUCCH_NR_FORMAT_3:
|
case SRSLTE_PUCCH_NR_FORMAT_3:
|
||||||
case SRSLTE_PUCCH_NR_FORMAT_4:
|
case SRSLTE_PUCCH_NR_FORMAT_4:
|
||||||
ERROR("Not implemented");
|
ERROR("Not implemented");
|
||||||
|
@ -667,7 +678,6 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
||||||
const srslte_carrier_nr_t* carrier,
|
|
||||||
const srslte_pucch_nr_common_cfg_t* cfg,
|
const srslte_pucch_nr_common_cfg_t* cfg,
|
||||||
const srslte_slot_cfg_t* slot,
|
const srslte_slot_cfg_t* slot,
|
||||||
const srslte_pucch_nr_resource_t* resource,
|
const srslte_pucch_nr_resource_t* resource,
|
||||||
|
@ -677,8 +687,8 @@ int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
||||||
srslte_uci_value_nr_t* uci_value)
|
srslte_uci_value_nr_t* uci_value)
|
||||||
{
|
{
|
||||||
// Validate input pointers
|
// Validate input pointers
|
||||||
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL ||
|
if (q == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL || chest_res == NULL ||
|
||||||
chest_res == NULL || uci_value == NULL || slot_symbols == NULL) {
|
uci_value == NULL || slot_symbols == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +696,8 @@ int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
|
||||||
int8_t* llr = (int8_t*)q->b;
|
int8_t* llr = (int8_t*)q->b;
|
||||||
switch (resource->format) {
|
switch (resource->format) {
|
||||||
case SRSLTE_PUCCH_NR_FORMAT_2:
|
case SRSLTE_PUCCH_NR_FORMAT_2:
|
||||||
if (pucch_nr_format2_decode(q, carrier, cfg, resource, uci_cfg, chest_res, slot_symbols, llr) < SRSLTE_SUCCESS) {
|
if (pucch_nr_format2_decode(q, &q->carrier, cfg, resource, uci_cfg, chest_res, slot_symbols, llr) <
|
||||||
|
SRSLTE_SUCCESS) {
|
||||||
ERROR("Demodulating PUCCH format 2");
|
ERROR("Demodulating PUCCH format 2");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_uci_nr_init(&q->uci, &args->uci) < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Initialising UCI");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +64,7 @@ int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t*
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srslte_sch_nr_init_rx(&q->sch, &args->sch)) {
|
if (srslte_sch_nr_init_rx(&q->sch, &args->sch) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Initialising SCH");
|
ERROR("Initialising SCH");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -415,10 +420,19 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf
|
||||||
return cinit;
|
return cinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int pusch_nr_mux_uci(srslte_pusch_nr_t* q) {
|
||||||
|
// uint8_t *g_ul_sch; // coded bits for UL-SCH
|
||||||
|
// uint8_t *g_ack; // coded bits for HARQ-ACK
|
||||||
|
// uint8_t *g_csi_p1; // coded bits for CSI part 1
|
||||||
|
// uint8_t *g_csi_p2; // coded bits for CSI part 2
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q,
|
static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q,
|
||||||
const srslte_sch_cfg_nr_t* cfg,
|
const srslte_sch_cfg_nr_t* cfg,
|
||||||
const srslte_sch_tb_t* tb,
|
const srslte_sch_tb_t* tb,
|
||||||
const uint8_t* data,
|
const uint8_t* data,
|
||||||
|
const srslte_uci_value_nr_t* uci,
|
||||||
uint16_t rnti)
|
uint16_t rnti)
|
||||||
{
|
{
|
||||||
// Early return if TB is not enabled
|
// Early return if TB is not enabled
|
||||||
|
@ -467,7 +481,7 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q,
|
||||||
int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
|
int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
|
||||||
const srslte_sch_cfg_nr_t* cfg,
|
const srslte_sch_cfg_nr_t* cfg,
|
||||||
const srslte_sch_grant_nr_t* grant,
|
const srslte_sch_grant_nr_t* grant,
|
||||||
uint8_t* data[SRSLTE_MAX_TB],
|
const srslte_pusch_data_nr_t* data,
|
||||||
cf_t* sf_symbols[SRSLTE_MAX_PORTS])
|
cf_t* sf_symbols[SRSLTE_MAX_PORTS])
|
||||||
{
|
{
|
||||||
// Check input pointers
|
// Check input pointers
|
||||||
|
@ -486,12 +500,20 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode HARQ-ACK bits
|
||||||
|
int E_uci_ack = srslte_uci_nr_encode_pusch_ack(&q->uci, cfg, &data[0].uci, q->uci_ack);
|
||||||
|
if (E_uci_ack < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Error encoding HARQ-ACK bits");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// 7.3.1.1 and 7.3.1.2
|
// 7.3.1.1 and 7.3.1.2
|
||||||
uint32_t nof_cw = 0;
|
uint32_t nof_cw = 0;
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
||||||
nof_cw += grant->tb[tb].enabled ? 1 : 0;
|
nof_cw += grant->tb[tb].enabled ? 1 : 0;
|
||||||
|
|
||||||
if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb], grant->rnti) < SRSLTE_SUCCESS) {
|
if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb].payload, &data[0].uci, grant->rnti) <
|
||||||
|
SRSLTE_SUCCESS) {
|
||||||
ERROR("Error encoding TB %d", tb);
|
ERROR("Error encoding TB %d", tb);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,10 @@ uint32_t sch_nr_n_prb_lbrm(uint32_t nof_prb)
|
||||||
return 273;
|
return 273;
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q,
|
int srslte_sch_nr_fill_cfg(const srslte_carrier_nr_t* carrier,
|
||||||
const srslte_sch_cfg_t* sch_cfg,
|
const srslte_sch_cfg_t* sch_cfg,
|
||||||
const srslte_sch_tb_t* tb,
|
const srslte_sch_tb_t* tb,
|
||||||
srslte_sch_nr_common_cfg_t* cfg)
|
srslte_sch_nr_tb_info_t* cfg)
|
||||||
{
|
{
|
||||||
if (!sch_cfg || !tb || !cfg) {
|
if (!sch_cfg || !tb || !cfg) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
@ -111,10 +111,10 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q,
|
||||||
cfg->Nl = tb->N_L;
|
cfg->Nl = tb->N_L;
|
||||||
|
|
||||||
// Calculate Nref
|
// Calculate Nref
|
||||||
uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(q->carrier.nof_prb);
|
uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(carrier->nof_prb);
|
||||||
double TCR_lbrm = 948.0 / 1024.0;
|
double TCR_lbrm = 948.0 / 1024.0;
|
||||||
uint32_t Qm_lbrm = (sch_cfg->mcs_table == srslte_mcs_table_256qam) ? 8 : 6;
|
uint32_t Qm_lbrm = (sch_cfg->mcs_table == srslte_mcs_table_256qam) ? 8 : 6;
|
||||||
uint32_t TBS_LRBM = srslte_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, q->carrier.max_mimo_layers);
|
uint32_t TBS_LRBM = srslte_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, carrier->max_mimo_layers);
|
||||||
double R = 2.0 / 3.0;
|
double R = 2.0 / 3.0;
|
||||||
cfg->Nref = ceil(TBS_LRBM / (cbsegm.C * R));
|
cfg->Nref = ceil(TBS_LRBM / (cbsegm.C * R));
|
||||||
|
|
||||||
|
@ -128,22 +128,13 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q,
|
||||||
cfg->C = cbsegm.C;
|
cfg->C = cbsegm.C;
|
||||||
cfg->Cp = cbsegm.C;
|
cfg->Cp = cbsegm.C;
|
||||||
|
|
||||||
// Select encoder
|
|
||||||
cfg->encoder = (bg == BG1) ? q->encoder_bg1[cfg->Z] : q->encoder_bg2[cfg->Z];
|
|
||||||
|
|
||||||
// Select decoder
|
|
||||||
cfg->decoder = (bg == BG1) ? q->decoder_bg1[cfg->Z] : q->decoder_bg2[cfg->Z];
|
|
||||||
|
|
||||||
// Select CRC for TB
|
|
||||||
cfg->crc_tb = (cbsegm.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16;
|
|
||||||
|
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN))
|
#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN))
|
||||||
#define MOD(NUM, DEN) ((NUM) % (DEN))
|
#define MOD(NUM, DEN) ((NUM) % (DEN))
|
||||||
|
|
||||||
static inline uint32_t sch_nr_get_E(const srslte_sch_nr_common_cfg_t* cfg, uint32_t j)
|
static inline uint32_t sch_nr_get_E(const srslte_sch_nr_tb_info_t* cfg, uint32_t j)
|
||||||
{
|
{
|
||||||
if (cfg->Nl == 0 || cfg->Qm == 0 || cfg->Cp == 0) {
|
if (cfg->Nl == 0 || cfg->Qm == 0 || cfg->Cp == 0) {
|
||||||
ERROR("Invalid Nl (%d), Qm (%d) or Cp (%d)", cfg->Nl, cfg->Qm, cfg->Cp);
|
ERROR("Invalid Nl (%d), Qm (%d) or Cp (%d)", cfg->Nl, cfg->Qm, cfg->Cp);
|
||||||
|
@ -380,19 +371,23 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q,
|
||||||
const uint8_t* input_ptr = data;
|
const uint8_t* input_ptr = data;
|
||||||
uint8_t* output_ptr = e_bits;
|
uint8_t* output_ptr = e_bits;
|
||||||
|
|
||||||
srslte_sch_nr_common_cfg_t cfg = {};
|
srslte_sch_nr_tb_info_t cfg = {};
|
||||||
if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) {
|
if (srslte_sch_nr_fill_cfg(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select encoder and CRC
|
||||||
|
srslte_ldpc_encoder_t* encoder = (cfg.bg == BG1) ? q->encoder_bg1[cfg.Z] : q->encoder_bg2[cfg.Z];
|
||||||
|
srslte_crc_t* crc_tb = (cfg.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16;
|
||||||
|
|
||||||
// Check encoder
|
// Check encoder
|
||||||
if (cfg.encoder == NULL) {
|
if (encoder == NULL) {
|
||||||
ERROR("Error: encoder for lifting size Z=%d not found (tbs=%d)", cfg.Z, tb->tbs);
|
ERROR("Error: encoder for lifting size Z=%d not found (tbs=%d)", cfg.Z, tb->tbs);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check CRC for TB
|
// Check CRC for TB
|
||||||
if (cfg.crc_tb == NULL) {
|
if (crc_tb == NULL) {
|
||||||
ERROR("Error: CRC for TB not found");
|
ERROR("Error: CRC for TB not found");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -406,16 +401,16 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb->softbuffer.tx->max_cb_size < (cfg.encoder->liftN - 2 * cfg.Z)) {
|
if (tb->softbuffer.tx->max_cb_size < (encoder->liftN - 2 * cfg.Z)) {
|
||||||
ERROR("Soft-buffer code-block maximum size insufficient (max_cb_size=%d) for a TBS=%d, requires %d.",
|
ERROR("Soft-buffer code-block maximum size insufficient (max_cb_size=%d) for a TBS=%d, requires %d.",
|
||||||
tb->softbuffer.tx->max_cb_size,
|
tb->softbuffer.tx->max_cb_size,
|
||||||
tb->tbs,
|
tb->tbs,
|
||||||
(cfg.encoder->liftN - 2 * cfg.Z));
|
(encoder->liftN - 2 * cfg.Z));
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate TB CRC
|
// Calculate TB CRC
|
||||||
uint32_t checksum_tb = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs);
|
uint32_t checksum_tb = srslte_crc_checksum_byte(crc_tb, data, tb->tbs);
|
||||||
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("tb=");
|
DEBUG("tb=");
|
||||||
srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
|
srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
|
||||||
|
@ -470,11 +465,11 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode code block
|
// Encode code block
|
||||||
srslte_ldpc_encoder_encode(cfg.encoder, q->temp_cb, rm_buffer, cfg.Kr);
|
srslte_ldpc_encoder_encode(encoder, q->temp_cb, rm_buffer, cfg.Kr);
|
||||||
|
|
||||||
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("encoded=");
|
DEBUG("encoded=");
|
||||||
srslte_vec_fprint_b(stdout, rm_buffer, cfg.encoder->liftN - 2 * cfg.encoder->ls);
|
srslte_vec_fprint_b(stdout, rm_buffer, encoder->liftN - 2 * encoder->ls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,25 +513,29 @@ int sch_nr_decode(srslte_sch_nr_t* q,
|
||||||
|
|
||||||
int8_t* input_ptr = e_bits;
|
int8_t* input_ptr = e_bits;
|
||||||
|
|
||||||
srslte_sch_nr_common_cfg_t cfg = {};
|
srslte_sch_nr_tb_info_t cfg = {};
|
||||||
if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) {
|
if (srslte_sch_nr_fill_cfg(&q->carrier, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select encoder and CRC
|
||||||
|
srslte_ldpc_decoder_t* decoder = (cfg.bg == BG1) ? q->decoder_bg1[cfg.Z] : q->decoder_bg2[cfg.Z];
|
||||||
|
srslte_crc_t* crc_tb = (cfg.L_tb == 24) ? &q->crc_tb_24 : &q->crc_tb_16;
|
||||||
|
|
||||||
// Check decoder
|
// Check decoder
|
||||||
if (cfg.decoder == NULL) {
|
if (decoder == NULL) {
|
||||||
ERROR("Error: decoder for lifting size Z=%d not found", cfg.Z);
|
ERROR("Error: decoder for lifting size Z=%d not found", cfg.Z);
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check CRC for TB
|
// Check CRC for TB
|
||||||
if (cfg.crc_tb == NULL) {
|
if (crc_tb == NULL) {
|
||||||
ERROR("Error: CRC for TB not found");
|
ERROR("Error: CRC for TB not found");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Soft-buffer number of code-block protection
|
// Soft-buffer number of code-block protection
|
||||||
if (tb->softbuffer.rx->max_cb < cfg.Cp || tb->softbuffer.rx->max_cb_size < (cfg.decoder->liftN - 2 * cfg.Z)) {
|
if (tb->softbuffer.rx->max_cb < cfg.Cp || tb->softbuffer.rx->max_cb_size < (decoder->liftN - 2 * cfg.Z)) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +585,7 @@ int sch_nr_decode(srslte_sch_nr_t* q,
|
||||||
srslte_ldpc_rm_rx_c(&q->rx_rm, input_ptr, rm_buffer, E, cfg.F, cfg.bg, cfg.Z, tb->rv, tb->mod, cfg.Nref);
|
srslte_ldpc_rm_rx_c(&q->rx_rm, input_ptr, rm_buffer, E, cfg.F, cfg.bg, cfg.Z, tb->rv, tb->mod, cfg.Nref);
|
||||||
|
|
||||||
// Decode
|
// Decode
|
||||||
srslte_ldpc_decoder_decode_c(cfg.decoder, rm_buffer, q->temp_cb);
|
srslte_ldpc_decoder_decode_c(decoder, rm_buffer, q->temp_cb);
|
||||||
|
|
||||||
// Compute CB CRC
|
// Compute CB CRC
|
||||||
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
||||||
|
@ -650,7 +649,7 @@ int sch_nr_decode(srslte_sch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate TB CRC from packed data
|
// Calculate TB CRC from packed data
|
||||||
uint32_t checksum1 = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs);
|
uint32_t checksum1 = srslte_crc_checksum_byte(crc_tb, data, tb->tbs);
|
||||||
*crc_ok = (checksum1 == checksum2 && !all_zeros);
|
*crc_ok = (checksum1 == checksum2 && !all_zeros);
|
||||||
|
|
||||||
SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2);
|
SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2);
|
||||||
|
|
|
@ -53,15 +53,14 @@ static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_co
|
||||||
for (resource.initial_cyclic_shift = 0; resource.initial_cyclic_shift <= 11;
|
for (resource.initial_cyclic_shift = 0; resource.initial_cyclic_shift <= 11;
|
||||||
resource.initial_cyclic_shift++) {
|
resource.initial_cyclic_shift++) {
|
||||||
for (uint32_t m_cs = 0; m_cs <= 6; m_cs += 2) {
|
for (uint32_t m_cs = 0; m_cs <= 6; m_cs += 2) {
|
||||||
TESTASSERT(srslte_pucch_nr_format0_encode(pucch, &carrier, cfg, &slot, &resource, m_cs, slot_symbols) ==
|
TESTASSERT(srslte_pucch_nr_format0_encode(pucch, cfg, &slot, &resource, m_cs, slot_symbols) ==
|
||||||
SRSLTE_SUCCESS);
|
SRSLTE_SUCCESS);
|
||||||
|
|
||||||
// Measure PUCCH format 0 for all possible values of m_cs
|
// Measure PUCCH format 0 for all possible values of m_cs
|
||||||
for (uint32_t m_cs_test = 0; m_cs_test <= 6; m_cs_test += 2) {
|
for (uint32_t m_cs_test = 0; m_cs_test <= 6; m_cs_test += 2) {
|
||||||
srslte_pucch_nr_measure_t measure = {};
|
srslte_pucch_nr_measure_t measure = {};
|
||||||
TESTASSERT(srslte_pucch_nr_format0_measure(
|
TESTASSERT(srslte_pucch_nr_format0_measure(
|
||||||
pucch, &carrier, cfg, &slot, &resource, m_cs_test, slot_symbols, &measure) ==
|
pucch, cfg, &slot, &resource, m_cs_test, slot_symbols, &measure) == SRSLTE_SUCCESS);
|
||||||
SRSLTE_SUCCESS);
|
|
||||||
|
|
||||||
if (m_cs == m_cs_test) {
|
if (m_cs == m_cs_test) {
|
||||||
TESTASSERT(fabsf(measure.epre - 1) < 0.001);
|
TESTASSERT(fabsf(measure.epre - 1) < 0.001);
|
||||||
|
@ -115,8 +114,8 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode PUCCH
|
// Encode PUCCH
|
||||||
TESTASSERT(srslte_pucch_nr_format1_encode(
|
TESTASSERT(srslte_pucch_nr_format1_encode(pucch, cfg, &slot, &resource, b, nof_bits, slot_symbols) ==
|
||||||
pucch, &carrier, cfg, &slot, &resource, b, nof_bits, slot_symbols) == SRSLTE_SUCCESS);
|
SRSLTE_SUCCESS);
|
||||||
|
|
||||||
// Put DMRS
|
// Put DMRS
|
||||||
TESTASSERT(srslte_dmrs_pucch_format1_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) ==
|
TESTASSERT(srslte_dmrs_pucch_format1_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) ==
|
||||||
|
@ -137,7 +136,7 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch,
|
||||||
// Decode PUCCH
|
// Decode PUCCH
|
||||||
uint8_t b_rx[SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS];
|
uint8_t b_rx[SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS];
|
||||||
TESTASSERT(srslte_pucch_nr_format1_decode(
|
TESTASSERT(srslte_pucch_nr_format1_decode(
|
||||||
pucch, &carrier, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits) ==
|
pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits) ==
|
||||||
SRSLTE_SUCCESS);
|
SRSLTE_SUCCESS);
|
||||||
|
|
||||||
// Check received bits
|
// Check received bits
|
||||||
|
@ -202,8 +201,7 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch,
|
||||||
|
|
||||||
// Encode PUCCH
|
// Encode PUCCH
|
||||||
TESTASSERT(srslte_pucch_nr_format_2_3_4_encode(
|
TESTASSERT(srslte_pucch_nr_format_2_3_4_encode(
|
||||||
pucch, &carrier, cfg, &slot, &resource, &uci_cfg, &uci_value, slot_symbols) ==
|
pucch, cfg, &slot, &resource, &uci_cfg, &uci_value, slot_symbols) == SRSLTE_SUCCESS);
|
||||||
SRSLTE_SUCCESS);
|
|
||||||
|
|
||||||
// Put DMRS
|
// Put DMRS
|
||||||
TESTASSERT(srslte_dmrs_pucch_format2_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) ==
|
TESTASSERT(srslte_dmrs_pucch_format2_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) ==
|
||||||
|
@ -226,9 +224,8 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch,
|
||||||
|
|
||||||
// Decode PUCCH
|
// Decode PUCCH
|
||||||
srslte_uci_value_nr_t uci_value_rx = {};
|
srslte_uci_value_nr_t uci_value_rx = {};
|
||||||
TESTASSERT(
|
TESTASSERT(srslte_pucch_nr_format_2_3_4_decode(
|
||||||
srslte_pucch_nr_format_2_3_4_decode(
|
pucch, cfg, &slot, &resource, &uci_cfg, chest_res, slot_symbols, &uci_value_rx) ==
|
||||||
pucch, &carrier, cfg, &slot, &resource, &uci_cfg, chest_res, slot_symbols, &uci_value_rx) ==
|
|
||||||
SRSLTE_SUCCESS);
|
SRSLTE_SUCCESS);
|
||||||
|
|
||||||
TESTASSERT(uci_value_rx.valid == true);
|
TESTASSERT(uci_value_rx.valid == true);
|
||||||
|
@ -311,6 +308,11 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_pucch_nr_set_carrier(&pucch, &carrier) < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("PUCCH set carrier");
|
||||||
|
goto clean_exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_chest_ul_res_init(&chest_res, carrier.nof_prb)) {
|
if (srslte_chest_ul_res_init(&chest_res, carrier.nof_prb)) {
|
||||||
ERROR("Chest UL");
|
ERROR("Chest UL");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
|
|
|
@ -32,6 +32,8 @@ static uint32_t mcs = 30; // Set to 30 for steering
|
||||||
static srslte_sch_cfg_nr_t pusch_cfg = {};
|
static srslte_sch_cfg_nr_t pusch_cfg = {};
|
||||||
static srslte_sch_grant_nr_t pusch_grant = {};
|
static srslte_sch_grant_nr_t pusch_grant = {};
|
||||||
static uint16_t rnti = 0x1234;
|
static uint16_t rnti = 0x1234;
|
||||||
|
static uint32_t nof_ack_bits = 0;
|
||||||
|
static uint32_t nof_csi_bits = 0;
|
||||||
|
|
||||||
void usage(char* prog)
|
void usage(char* prog)
|
||||||
{
|
{
|
||||||
|
@ -41,13 +43,15 @@ void usage(char* prog)
|
||||||
printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n",
|
printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n",
|
||||||
srslte_mcs_table_to_str(pusch_cfg.sch_cfg.mcs_table));
|
srslte_mcs_table_to_str(pusch_cfg.sch_cfg.mcs_table));
|
||||||
printf("\t-L Provide number of layers [Default %d]\n", carrier.max_mimo_layers);
|
printf("\t-L Provide number of layers [Default %d]\n", carrier.max_mimo_layers);
|
||||||
|
printf("\t-A Provide a number of HARQ-ACK bits [Default %d]\n", nof_ack_bits);
|
||||||
|
printf("\t-C Provide a number of CSI bits [Default %d]\n", nof_csi_bits);
|
||||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_args(int argc, char** argv)
|
int parse_args(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "pmTLv")) != -1) {
|
while ((opt = getopt(argc, argv, "pmTLACv")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'p':
|
case 'p':
|
||||||
n_prb = (uint32_t)strtol(argv[optind], NULL, 10);
|
n_prb = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
|
@ -61,6 +65,12 @@ int parse_args(int argc, char** argv)
|
||||||
case 'L':
|
case 'L':
|
||||||
carrier.max_mimo_layers = (uint32_t)strtol(argv[optind], NULL, 10);
|
carrier.max_mimo_layers = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
break;
|
break;
|
||||||
|
case 'A':
|
||||||
|
nof_ack_bits = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
nof_csi_bits = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
srslte_verbose++;
|
srslte_verbose++;
|
||||||
break;
|
break;
|
||||||
|
@ -79,11 +89,10 @@ int main(int argc, char** argv)
|
||||||
srslte_pusch_nr_t pusch_tx = {};
|
srslte_pusch_nr_t pusch_tx = {};
|
||||||
srslte_pusch_nr_t pusch_rx = {};
|
srslte_pusch_nr_t pusch_rx = {};
|
||||||
srslte_chest_dl_res_t chest = {};
|
srslte_chest_dl_res_t chest = {};
|
||||||
srslte_pusch_res_nr_t pusch_res[SRSLTE_MAX_TB] = {};
|
|
||||||
srslte_random_t rand_gen = srslte_random_init(1234);
|
srslte_random_t rand_gen = srslte_random_init(1234);
|
||||||
|
|
||||||
uint8_t* data_tx[SRSLTE_MAX_TB] = {};
|
srslte_pusch_data_nr_t data_tx[SRSLTE_MAX_TB] = {};
|
||||||
uint8_t* data_rx[SRSLTE_MAX_CODEWORDS] = {};
|
srslte_pusch_res_nr_t data_rx[SRSLTE_MAX_CODEWORDS] = {};
|
||||||
cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {};
|
cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {};
|
||||||
|
|
||||||
// Set default PUSCH configuration
|
// Set default PUSCH configuration
|
||||||
|
@ -126,14 +135,12 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pusch_tx.max_cw; i++) {
|
for (uint32_t i = 0; i < pusch_tx.max_cw; i++) {
|
||||||
data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
|
data_tx[i].payload = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
|
||||||
data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
|
data_rx[i].payload = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
|
||||||
if (data_tx[i] == NULL || data_rx[i] == NULL) {
|
if (data_tx[i].payload == NULL || data_rx[i].payload == NULL) {
|
||||||
ERROR("Error malloc");
|
ERROR("Error malloc");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pusch_res[i].payload = data_rx[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srslte_softbuffer_tx_t softbuffer_tx = {};
|
srslte_softbuffer_tx_t softbuffer_tx = {};
|
||||||
|
@ -198,18 +205,39 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate SCH payload
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
||||||
// Skip TB if no allocated
|
// Skip TB if no allocated
|
||||||
if (data_tx[tb] == NULL) {
|
if (data_tx[tb].payload == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pusch_grant.tb[tb].tbs; i++) {
|
for (uint32_t i = 0; i < pusch_grant.tb[tb].tbs; i++) {
|
||||||
data_tx[tb][i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX);
|
data_tx[tb].payload[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX);
|
||||||
}
|
}
|
||||||
pusch_grant.tb[tb].softbuffer.tx = &softbuffer_tx;
|
pusch_grant.tb[tb].softbuffer.tx = &softbuffer_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate HARQ ACK bits
|
||||||
|
if (nof_ack_bits > 0) {
|
||||||
|
pusch_cfg.uci.o_ack = nof_ack_bits;
|
||||||
|
for (uint32_t i = 0; i < nof_ack_bits; i++) {
|
||||||
|
data_tx->uci.ack[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate CSI report bits
|
||||||
|
uint8_t csi_report[SRSLTE_UCI_NR_MAX_CSI1_BITS];
|
||||||
|
if (nof_csi_bits > 0) {
|
||||||
|
pusch_cfg.uci.csi[0].quantity = SRSLTE_CSI_REPORT_QUANTITY_NONE;
|
||||||
|
pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits;
|
||||||
|
pusch_cfg.uci.nof_csi = 1;
|
||||||
|
data_tx->uci.csi[0].none = csi_report;
|
||||||
|
for (uint32_t i = 0; i < nof_csi_bits; i++) {
|
||||||
|
csi_report[i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) {
|
if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error encoding");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
|
@ -225,13 +253,13 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
chest.nof_re = pusch_grant.tb->nof_re;
|
chest.nof_re = pusch_grant.tb->nof_re;
|
||||||
|
|
||||||
if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_grant, &chest, sf_symbols, pusch_res) < SRSLTE_SUCCESS) {
|
if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_grant, &chest, sf_symbols, data_rx) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Error encoding");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pusch_res->evm > 0.001f) {
|
if (data_rx[0].evm > 0.001f) {
|
||||||
ERROR("Error PUSCH EVM is too high %f", pusch_res->evm);
|
ERROR("Error PUSCH EVM is too high %f", data_rx[0].evm);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,21 +284,21 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pusch_res[0].crc) {
|
if (!data_rx[0].crc) {
|
||||||
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs);
|
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(data_tx[0], data_rx[0], pusch_grant.tb[0].tbs / 8) != 0) {
|
if (memcmp(data_tx[0].payload, data_rx[0].payload, pusch_grant.tb[0].tbs / 8) != 0) {
|
||||||
ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs);
|
ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs);
|
||||||
printf("Tx data: ");
|
printf("Tx data: ");
|
||||||
srslte_vec_fprint_byte(stdout, data_tx[0], pusch_grant.tb[0].tbs / 8);
|
srslte_vec_fprint_byte(stdout, data_tx[0].payload, pusch_grant.tb[0].tbs / 8);
|
||||||
printf("Rx data: ");
|
printf("Rx data: ");
|
||||||
srslte_vec_fprint_byte(stdout, data_rx[0], pusch_grant.tb[0].tbs / 8);
|
srslte_vec_fprint_byte(stdout, data_tx[0].payload, pusch_grant.tb[0].tbs / 8);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_grant.tb[0].tbs, pusch_res[0].evm);
|
printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_grant.tb[0].tbs, data_rx[0].evm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +310,11 @@ clean_exit:
|
||||||
srslte_pusch_nr_free(&pusch_tx);
|
srslte_pusch_nr_free(&pusch_tx);
|
||||||
srslte_pusch_nr_free(&pusch_rx);
|
srslte_pusch_nr_free(&pusch_rx);
|
||||||
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||||
if (data_tx[i]) {
|
if (data_tx[i].payload) {
|
||||||
free(data_tx[i]);
|
free(data_tx[i].payload);
|
||||||
}
|
}
|
||||||
if (data_rx[i]) {
|
if (data_rx[i].payload) {
|
||||||
free(data_rx[i]);
|
free(data_rx[i].payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) {
|
for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) {
|
||||||
|
|
|
@ -11,13 +11,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "srslte/phy/phch/uci_nr.h"
|
#include "srslte/phy/phch/uci_nr.h"
|
||||||
|
#include "srslte/phy/ch_estimation/dmrs_sch.h"
|
||||||
#include "srslte/phy/fec/block/block.h"
|
#include "srslte/phy/fec/block/block.h"
|
||||||
#include "srslte/phy/fec/polar/polar_chanalloc.h"
|
#include "srslte/phy/fec/polar/polar_chanalloc.h"
|
||||||
#include "srslte/phy/phch/csi.h"
|
#include "srslte/phy/phch/csi.h"
|
||||||
|
#include "srslte/phy/phch/sch_nr.h"
|
||||||
#include "srslte/phy/phch/uci_cfg.h"
|
#include "srslte/phy/phch/uci_cfg.h"
|
||||||
#include "srslte/phy/utils/bit.h"
|
#include "srslte/phy/utils/bit.h"
|
||||||
#include "srslte/phy/utils/vector.h"
|
#include "srslte/phy/utils/vector.h"
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#define UCI_NR_INFO_TX(...) INFO("UCI-NR Tx: " __VA_ARGS__)
|
#define UCI_NR_INFO_TX(...) INFO("UCI-NR Tx: " __VA_ARGS__)
|
||||||
#define UCI_NR_INFO_RX(...) INFO("UCI-NR Rx: " __VA_ARGS__)
|
#define UCI_NR_INFO_RX(...) INFO("UCI-NR Rx: " __VA_ARGS__)
|
||||||
|
@ -118,6 +119,17 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args)
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_uci_nr_set_carrier(srslte_uci_nr_t* q, const srslte_carrier_nr_t* carrier)
|
||||||
|
{
|
||||||
|
if (q == NULL || carrier == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->carrier = *carrier;
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void srslte_uci_nr_free(srslte_uci_nr_t* q)
|
void srslte_uci_nr_free(srslte_uci_nr_t* q)
|
||||||
{
|
{
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
|
@ -207,7 +219,7 @@ static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg)
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uci_nr_packing(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* sequence)
|
static int uci_nr_pack_pucch(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value_nr_t* value, uint8_t* sequence)
|
||||||
{
|
{
|
||||||
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
||||||
|
|
||||||
|
@ -226,7 +238,7 @@ static int uci_nr_packing(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uci_nr_unpacking(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, srslte_uci_value_nr_t* value)
|
static int uci_nr_unpack_pucch(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, srslte_uci_value_nr_t* value)
|
||||||
{
|
{
|
||||||
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
int o_csi = srslte_csi_nof_bits(cfg->csi, cfg->nof_csi);
|
||||||
|
|
||||||
|
@ -246,12 +258,13 @@ static int uci_nr_unpacking(const srslte_uci_cfg_nr_t* cfg, uint8_t* sequence, s
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E)
|
static int
|
||||||
|
uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, uint8_t* o, uint32_t E)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
||||||
|
|
||||||
switch (cfg->modulation) {
|
switch (modulation) {
|
||||||
case SRSLTE_MOD_BPSK:
|
case SRSLTE_MOD_BPSK:
|
||||||
while (i < E) {
|
while (i < E) {
|
||||||
o[i++] = c0;
|
o[i++] = c0;
|
||||||
|
@ -304,14 +317,15 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg
|
||||||
return E;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, uint8_t* o, uint32_t E)
|
static int
|
||||||
|
uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, srslte_mod_t modulation, uint8_t* o, uint32_t E)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
srslte_uci_bit_type_t c0 = (q->bit_sequence[0] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
||||||
srslte_uci_bit_type_t c1 = (q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
srslte_uci_bit_type_t c1 = (q->bit_sequence[1] == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
||||||
srslte_uci_bit_type_t c2 = ((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
srslte_uci_bit_type_t c2 = ((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1;
|
||||||
|
|
||||||
switch (cfg->modulation) {
|
switch (modulation) {
|
||||||
case SRSLTE_MOD_BPSK:
|
case SRSLTE_MOD_BPSK:
|
||||||
case SRSLTE_MOD_QPSK:
|
case SRSLTE_MOD_QPSK:
|
||||||
while (i < E) {
|
while (i < E) {
|
||||||
|
@ -631,29 +645,19 @@ static int uci_nr_decode_11_1706_bit(srslte_uci_nr_t* q,
|
||||||
|
|
||||||
static int uci_nr_encode(srslte_uci_nr_t* q,
|
static int uci_nr_encode(srslte_uci_nr_t* q,
|
||||||
const srslte_uci_cfg_nr_t* uci_cfg,
|
const srslte_uci_cfg_nr_t* uci_cfg,
|
||||||
const srslte_uci_value_nr_t* uci_value,
|
srslte_mod_t mod,
|
||||||
|
uint32_t A,
|
||||||
uint8_t* o,
|
uint8_t* o,
|
||||||
uint32_t E_uci)
|
uint32_t E_uci)
|
||||||
{
|
{
|
||||||
if (q == NULL || uci_cfg == NULL || uci_value == NULL || o == NULL) {
|
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6.3.1.1 UCI bit sequence generation
|
|
||||||
int A = uci_nr_packing(uci_cfg, uci_value, q->bit_sequence);
|
|
||||||
if (A < SRSLTE_SUCCESS) {
|
|
||||||
ERROR("Generating bit sequence");
|
|
||||||
return SRSLTE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5.3.3.1 Encoding of 1-bit information
|
// 5.3.3.1 Encoding of 1-bit information
|
||||||
if (A == 1) {
|
if (A == 1) {
|
||||||
return uci_nr_encode_1bit(q, uci_cfg, o, E_uci);
|
return uci_nr_encode_1bit(q, uci_cfg, mod, o, E_uci);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.3.3.2 Encoding of 2-bit information
|
// 5.3.3.2 Encoding of 2-bit information
|
||||||
if (A == 2) {
|
if (A == 2) {
|
||||||
return uci_nr_encode_2bit(q, uci_cfg, o, E_uci);
|
return uci_nr_encode_2bit(q, uci_cfg, mod, o, E_uci);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.3.3.3 Encoding of other small block lengths
|
// 5.3.3.3 Encoding of other small block lengths
|
||||||
|
@ -704,7 +708,7 @@ static int uci_nr_decode(srslte_uci_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack bits
|
// Unpack bits
|
||||||
if (uci_nr_unpacking(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) {
|
if (uci_nr_unpack_pucch(uci_cfg, q->bit_sequence, uci_value) < SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,7 +774,14 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uci_nr_encode(q, uci_cfg, value, o, E_uci);
|
// 6.3.1.1 UCI bit sequence generation
|
||||||
|
int A = uci_nr_pack_pucch(uci_cfg, value, q->bit_sequence);
|
||||||
|
if (A < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Generating bit sequence");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uci_nr_encode(q, uci_cfg, SRSLTE_MOD_NITEMS, A, o, E_uci);
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
|
int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
|
||||||
|
@ -823,3 +834,115 @@ uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uin
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int uci_nr_Q_ack_prime(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* sch_cfg, uint32_t A)
|
||||||
|
{
|
||||||
|
// Get UL-SCH TB information
|
||||||
|
srslte_sch_nr_tb_info_t tb_info = {};
|
||||||
|
if (srslte_sch_nr_fill_cfg(&q->carrier, &sch_cfg->sch_cfg, &sch_cfg->grant.tb[0], &tb_info) < SRSLTE_SUCCESS) {
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get DMRS symbol indexes
|
||||||
|
uint32_t nof_dmrs_l = 0;
|
||||||
|
uint32_t dmrs_l[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {};
|
||||||
|
int n = srslte_dmrs_sch_get_symbols_idx(&sch_cfg->dmrs, &sch_cfg->grant, dmrs_l);
|
||||||
|
if (n < SRSLTE_SUCCESS) {
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
nof_dmrs_l = (uint32_t)n;
|
||||||
|
|
||||||
|
uint32_t O_ack = A; // Number of HARQ-ACK bits
|
||||||
|
uint32_t L_ack = srslte_uci_nr_crc_len(A); // Number of CRC bits
|
||||||
|
float beta_pusch_offset = sch_cfg->beta_harq_ack_offset; // Beta offset given by higher layers
|
||||||
|
uint32_t C_ulsch = tb_info.C; // number of code blocks for UL-SCH of the PUSCH
|
||||||
|
float alpha = sch_cfg->scaling; // Higher layer parameter scaling
|
||||||
|
float R = (float)sch_cfg->grant.tb[0].R; // code rate of the PUSCH
|
||||||
|
float Qm = srslte_mod_bits_x_symbol(sch_cfg->grant.tb[0].mod); // modulation order of the PUSCH
|
||||||
|
|
||||||
|
uint32_t K_sum = 0;
|
||||||
|
for (uint32_t i = 0; i < SRSLTE_MIN(C_ulsch, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC); i++) {
|
||||||
|
K_sum += tb_info.mask[i] ? 0 : tb_info.Kr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t dmrs_l_idx = 0;
|
||||||
|
uint32_t M_uci_sum = 0;
|
||||||
|
uint32_t M_uci_l0_sum = 0;
|
||||||
|
for (uint32_t l = sch_cfg->grant.S; l < sch_cfg->grant.S + sch_cfg->grant.L; l++) {
|
||||||
|
uint32_t M_ptrs_sc = 0; // Not implemented yet
|
||||||
|
uint32_t M_pusch_sc = sch_cfg->grant.nof_prb * SRSLTE_NRE;
|
||||||
|
uint32_t M_uci_sc = M_pusch_sc - M_ptrs_sc;
|
||||||
|
|
||||||
|
// If the OFDM symbol contains DMRS, no UCI is mapped
|
||||||
|
if (l == dmrs_l[dmrs_l_idx] && dmrs_l_idx < nof_dmrs_l) {
|
||||||
|
M_uci_sc = 0;
|
||||||
|
dmrs_l_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add subcarriers that can contain UCI RE
|
||||||
|
M_uci_sum += M_uci_sc;
|
||||||
|
|
||||||
|
// Start adding after the first DMRS symbol
|
||||||
|
if (dmrs_l_idx > 0) {
|
||||||
|
M_uci_l0_sum += M_uci_sc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sch_cfg->uci.without_ul_sch) {
|
||||||
|
return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset) / (Qm * R)), alpha * M_uci_l0_sum);
|
||||||
|
}
|
||||||
|
return (int)SRSLTE_MIN(ceilf(((O_ack + L_ack) * beta_pusch_offset * M_uci_sum) / (float)K_sum), alpha * M_uci_l0_sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_uci_nr_pusch_E_uci_ack(srslte_uci_nr_t* q, const srslte_sch_cfg_nr_t* cfg)
|
||||||
|
{
|
||||||
|
int A = cfg->uci.o_ack;
|
||||||
|
|
||||||
|
// Check inputs
|
||||||
|
if (q == NULL || cfg == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) {
|
||||||
|
A = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Q_ack_prime = uci_nr_Q_ack_prime(q, cfg, A);
|
||||||
|
if (Q_ack_prime < SRSLTE_SUCCESS) {
|
||||||
|
return Q_ack_prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)(Q_ack_prime * cfg->grant.nof_layers * srslte_mod_bits_x_symbol(cfg->grant.tb[0].mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_uci_nr_encode_pusch_ack(srslte_uci_nr_t* q,
|
||||||
|
const srslte_sch_cfg_nr_t* cfg,
|
||||||
|
const srslte_uci_value_nr_t* value,
|
||||||
|
uint8_t* o)
|
||||||
|
{
|
||||||
|
int A = cfg->uci.o_ack;
|
||||||
|
|
||||||
|
// Check inputs
|
||||||
|
if (q == NULL || cfg == NULL || value == NULL || o == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6.3.2.1 UCI bit sequence generation
|
||||||
|
// 6.3.2.1.1 HARQ-ACK
|
||||||
|
if (cfg->uci.without_ul_sch && cfg->uci.nof_csi > 1 && !cfg->uci.has_csi_part2 && cfg->uci.o_ack < 2) {
|
||||||
|
A = 2;
|
||||||
|
q->bit_sequence[0] = (cfg->uci.o_ack == 0) ? 0 : value->ack[0];
|
||||||
|
q->bit_sequence[1] = 0;
|
||||||
|
} else {
|
||||||
|
srslte_vec_u8_copy(q->bit_sequence, value->ack, cfg->uci.o_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute total of encoded bits according to 6.3.2.4 Rate matching
|
||||||
|
int E_uci = srslte_uci_nr_pusch_E_uci_ack(q, cfg);
|
||||||
|
if (E_uci < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Error calculating number of encoded bits");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uci_nr_encode(q, &cfg->uci, cfg->grant.tb[0].mod, A, o, E_uci);
|
||||||
|
}
|
|
@ -82,6 +82,11 @@ int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t*
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srslte_pucch_nr_set_carrier(&q->pucch, carrier) < SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Setting PUSCH carrier");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier)) {
|
if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier)) {
|
||||||
ERROR("Setting DMRS carrier");
|
ERROR("Setting DMRS carrier");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
@ -93,13 +98,10 @@ int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t*
|
||||||
int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
|
int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
|
||||||
const srslte_slot_cfg_t* slot_cfg,
|
const srslte_slot_cfg_t* slot_cfg,
|
||||||
const srslte_sch_cfg_nr_t* pusch_cfg,
|
const srslte_sch_cfg_nr_t* pusch_cfg,
|
||||||
uint8_t* data_)
|
const srslte_pusch_data_nr_t* data)
|
||||||
{
|
{
|
||||||
uint8_t* data[SRSLTE_MAX_TB] = {};
|
|
||||||
data[0] = data_;
|
|
||||||
|
|
||||||
// Check inputs
|
// Check inputs
|
||||||
if (q == NULL || pusch_cfg == NULL || data_ == NULL) {
|
if (q == NULL || pusch_cfg == NULL || data == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +160,7 @@ static int ue_ul_nr_encode_pucch_format1(srslte_ue_ul_nr_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return srslte_pucch_nr_format1_encode(&q->pucch, &q->carrier, cfg, slot, resource, b, nof_bits, q->sf_symbols[0]);
|
return srslte_pucch_nr_format1_encode(&q->pucch, cfg, slot, resource, b, nof_bits, q->sf_symbols[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q,
|
int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q,
|
||||||
|
@ -192,7 +194,7 @@ int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q,
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
if (srslte_pucch_nr_format_2_3_4_encode(
|
if (srslte_pucch_nr_format_2_3_4_encode(
|
||||||
&q->pucch, &q->carrier, cfg, slot_cfg, resource, &uci_data->cfg, &uci_data->value, q->sf_symbols[0]) <
|
&q->pucch, cfg, slot_cfg, resource, &uci_data->cfg, &uci_data->value, q->sf_symbols[0]) <
|
||||||
SRSLTE_SUCCESS) {
|
SRSLTE_SUCCESS) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,8 +288,11 @@ bool cc_worker::work_ul()
|
||||||
// Assignning MAC provided values to PUSCH config structs
|
// Assignning MAC provided values to PUSCH config structs
|
||||||
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
|
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
|
||||||
|
|
||||||
|
srslte_pusch_data_nr_t data = {};
|
||||||
|
data.payload = ul_action.tb.payload->msg;
|
||||||
|
|
||||||
// Encode PUSCH transmission
|
// Encode PUSCH transmission
|
||||||
if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, ul_action.tb.payload->msg) < SRSLTE_SUCCESS) {
|
if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, &data) < SRSLTE_SUCCESS) {
|
||||||
ERROR("Encoding PUSCH");
|
ERROR("Encoding PUSCH");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue