Added NR-PUCCH encode/decode format2 skeleton

This commit is contained in:
Xavier Arteaga 2021-01-20 10:04:53 +01:00 committed by Xavier Arteaga
parent 4d96cf4a41
commit 1ee4d84f80
6 changed files with 192 additions and 19 deletions

View File

@ -83,4 +83,11 @@ SRSLTE_API int srslte_pucch_nr_format0_resource_valid(const srslte_pucch_nr_reso
*/
SRSLTE_API int srslte_pucch_nr_format1_resource_valid(const srslte_pucch_nr_resource_t* resource);
/**
* @brief Validates a PUCCH format 2 resource configuration provided by upper layers
* @param resource Resource configuration to validate
* @return SRSLTE_SUCCESS if valid, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int srslte_pucch_nr_format2_resource_valid(const srslte_pucch_nr_resource_t* resource);
#endif // SRSLTE_PUCCH_CFG_NR_H

View File

@ -13,14 +13,11 @@
#ifndef SRSLTE_PUCCH_NR_H
#define SRSLTE_PUCCH_NR_H
#include "srslte/config.h"
#include "srslte/phy/ch_estimation/chest_ul.h"
#include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/modem/modem_table.h"
#include "srslte/phy/phch/uci_nr.h"
#include <srslte/srslte.h>
#include <stdbool.h>
#include <stdint.h>
/**
* @brief Maximum number of symbols (without DMRS) that NR-PUCCH format 1 can transmit
@ -109,8 +106,8 @@ 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
* @remark Described in TS 38.211 clause 6.3.2.3 PUCCH format 0
* @param[in] q NR-PUCCH encoder/decoder object
* @param[in] carrier Carrier configuration
* @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] slot slot configuration
* @param[in] resource PUCCH format 0 resource
@ -128,8 +125,8 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t*
/**
* @brief Measures PUCCH format 0 in the resource grid
* @param[in] q NR-PUCCH encoder/decoder object
* @param[in] carrier Carrier configuration
* @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] slot slot configuration
* @param[in] resource PUCCH format 0 resource
@ -150,7 +147,7 @@ SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t*
/**
* @brief Get NR-PUCCH orthogonal sequence w
* @remark Defined by TS 38.211 Table 6.3.2.4.1-2: Orthogonal sequences ... for PUCCH format 1
* @param[in] q NR-PUCCH encoder/decoder object
* @param[in,out] q NR-PUCCH encoder/decoder object
* @param[in] n_pucch Number of PUCCH symbols
* @param[in] i sequence index
* @param m OFDM symbol index
@ -161,8 +158,8 @@ 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
* @remark Described in TS 38.211 clause 6.3.2.4 PUCCH format 1
* @param[in] q NR-PUCCH encoder/decoder object
* @param[in] carrier Carrier configuration
* @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] slot slot configuration
* @param[in] resource PUCCH format 1 resource
@ -182,11 +179,11 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t*
/**
* @brief Decodes NR-PUCCH format 1
* @param[in] q NR-PUCCH encoder/decoder object
* @param[in] carrier Carrier configuration
* @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] slot slot configuration
* @param[in] resource PUCCH format 1 resource
* @param[in] resource PUCCH format 2-4 resource
* @param[in] chest_res Channel estimator result
* @param[in] slot_symbols Resource grid of the given slot
* @param[out] b Bits to decode
@ -203,4 +200,48 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t*
uint8_t b[SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS],
uint32_t nof_bits);
/**
* @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] carrier Serving cell and Uplink BWP configuration
* @param[in] cfg PUCCH common configuration
* @param[in] slot slot configuration
* @param[in] resource PUCCH format 1 resource
* @param[in] uci_cfg Uplink Control Information configuration
* @param[in] uci_value Uplink Control Information data
* @param[out] slot_symbols Resource grid of the given slot
* @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,
const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg,
const srslte_uci_value_nr_t* uci_value,
cf_t* slot_symbols);
/**
* @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[in] carrier Serving cell and Uplink BWP configuration
* @param[in] cfg PUCCH common configuration
* @param[in] slot slot configuration
* @param[in] resource PUCCH format 2-4 resource
* @param[in] uci_cfg Uplink Control Information configuration
* @param[in] chest_res Channel estimator result
* @param[in] slot_symbols Resource grid of the given slot
* @param[out] uci_value Uplink Control Information data
* @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,
const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg,
srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols,
srslte_uci_value_nr_t* uci_value);
#endif // SRSLTE_PUCCH_NR_H

View File

@ -75,4 +75,22 @@ SRSLTE_API int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q,
const srslte_uci_value_nr_t* value,
uint8_t* o);
/**
* @brief Decoder UCI bits
*
* @attention Compatible only with PUCCH formats 2, 3 and 4
*
* @param[in,out] q NR-UCI object
* @param[in] pucch_resource_cfg
* @param[in] uci_cfg
* @param[in] llr
* @param[out] value
* @return SRSLTE_SUCCESSFUL if it is successful, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
const srslte_pucch_nr_resource_t* pucch_resource_cfg,
const srslte_uci_cfg_nr_t* uci_cfg,
const int8_t* llr,
srslte_uci_value_nr_t* value);
#endif // SRSLTE_UCI_NR_H

View File

@ -78,5 +78,34 @@ int srslte_pucch_nr_format1_resource_valid(const srslte_pucch_nr_resource_t* res
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int srslte_pucch_nr_format2_resource_valid(const srslte_pucch_nr_resource_t* resource)
{
if (resource == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (resource->format != SRSLTE_PUCCH_NR_FORMAT_2) {
ERROR("Invalid format (%d)\n", resource->format);
return SRSLTE_ERROR;
}
if (resource->nof_symbols < 1 || resource->nof_symbols > 2) {
ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols);
return SRSLTE_ERROR;
}
if (resource->nof_prb < 1 || resource->nof_prb > 16) {
ERROR("Invalid number of prb (%d)\n", resource->nof_prb);
return SRSLTE_ERROR;
}
if (resource->start_symbol_idx > 13) {
ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}

View File

@ -14,11 +14,12 @@
#include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/common/sequence.h"
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/mimo/precoding.h"
#include "srslte/phy/modem/demod_soft.h"
#include "srslte/phy/modem/mod.h"
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/vector.h"
#include <complex.h>
#include <srslte/srslte.h>
int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg,
@ -500,6 +501,25 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
return SRSLTE_SUCCESS;
}
static int pucch_nr_format2_encode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg,
cf_t* slot_symbols)
{
// Validate configuration
if (srslte_pucch_nr_format2_resource_valid(resource) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Implement encode here
// ...
return SRSLTE_SUCCESS;
}
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,
@ -509,20 +529,22 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
const srslte_uci_value_nr_t* uci_value,
cf_t* slot_symbols)
{
// Validate input pointers
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL ||
uci_value == NULL || slot_symbols == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Encode PUCCH message
if (srslte_uci_nr_encode_pucch(&q->uci, resource, uci_cfg, uci_value, q->b) < SRSLTE_SUCCESS) {
ERROR("Error encoding UCI\n");
return SRSLTE_ERROR;
}
// Encode PUCCH
// Modulate PUCCH
switch (resource->format) {
case SRSLTE_PUCCH_NR_FORMAT_2:
break;
return pucch_nr_format2_encode(q, carrier, cfg, slot, resource, uci_cfg, slot_symbols);
case SRSLTE_PUCCH_NR_FORMAT_3:
case SRSLTE_PUCCH_NR_FORMAT_4:
ERROR("Not implemented\n");
@ -530,7 +552,65 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
default:
case SRSLTE_PUCCH_NR_FORMAT_ERROR:
ERROR("Invalid format\n");
}
return SRSLTE_ERROR;
}
static int pucch_nr_format2_decode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource,
srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols,
int8_t* llr)
{
// Validate configuration
if (srslte_pucch_nr_format2_resource_valid(resource) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Implement decode here
// ...
return SRSLTE_SUCCESS;
}
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_dl_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg,
srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols,
srslte_uci_value_nr_t* uci_value)
{
// Validate input pointers
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || uci_cfg == NULL ||
chest_res == NULL || uci_value == NULL || slot_symbols == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Demodulate PUCCH message
int8_t* llr = (int8_t*)q->b;
switch (resource->format) {
case SRSLTE_PUCCH_NR_FORMAT_2:
return pucch_nr_format2_decode(q, carrier, cfg, slot, resource, chest_res, slot_symbols, llr);
case SRSLTE_PUCCH_NR_FORMAT_3:
case SRSLTE_PUCCH_NR_FORMAT_4:
ERROR("Not implemented\n");
return SRSLTE_ERROR;
default:
case SRSLTE_PUCCH_NR_FORMAT_ERROR:
ERROR("Invalid format\n");
}
// Decode PUCCH message
if (srslte_uci_nr_decode_pucch(&q->uci, resource, uci_cfg, llr, uci_value) < SRSLTE_SUCCESS) {
ERROR("Error encoding UCI\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;

View File

@ -682,7 +682,6 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q,
const srslte_uci_value_nr_t* value,
uint8_t* o)
{
int E_tot = uci_nr_pucch_E_tot(pucch_resource_cfg, uci_cfg);
if (E_tot < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
@ -702,7 +701,6 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q,
const int8_t* llr,
srslte_uci_value_nr_t* value)
{
int E_tot = uci_nr_pucch_E_tot(pucch_resource_cfg, uci_cfg);
if (E_tot < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;