From 009f300c5ebdecf5cfc70aa4048be98e2a1b8721 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 16 Oct 2020 15:18:24 +0200 Subject: [PATCH] Initial PHY Data procedures --- .../srslte/phy/ch_estimation/dmrs_pdsch.h | 22 ++-- lib/include/srslte/phy/common/phy_common_nr.h | 73 +++++++---- lib/include/srslte/phy/phch/pdsch_cfg_nr.h | 70 +++++++++++ lib/include/srslte/phy/ue/ue_dl_nr_data.h | 72 +++++++++++ lib/src/phy/ch_estimation/dmrs_pdsch.c | 6 +- .../phy/ch_estimation/test/dmrs_pdsch_test.c | 20 +-- lib/src/phy/ue/ue_dl_nr_data.c | 115 ++++++++++++++++++ 7 files changed, 326 insertions(+), 52 deletions(-) create mode 100644 lib/include/srslte/phy/phch/pdsch_cfg_nr.h create mode 100644 lib/include/srslte/phy/ue/ue_dl_nr_data.h create mode 100644 lib/src/phy/ue/ue_dl_nr_data.c diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h b/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h index d79a22f3d..dd599565f 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h @@ -26,7 +26,7 @@ extern "C" { #endif -#include "srslte/phy/common/phy_common.h" +#include "srslte/phy/common/phy_common_nr.h" #include "srslte/srslte.h" #include @@ -62,18 +62,16 @@ typedef enum { srslte_dmrs_pdsch_add_pos_3 } srslte_dmrs_pdsch_add_pos_t; -typedef enum { - srslte_dmrs_pdsch_mapping_type_A = 0, - srslte_dmrs_pdsch_mapping_type_B -} srslte_dmrs_pdsch_mapping_type_t; - typedef struct { - srslte_dmrs_pdsch_type_t type; - srslte_dmrs_pdsch_typeA_pos_t typeA_pos; - srslte_dmrs_pdsch_add_pos_t additional_pos; - srslte_dmrs_pdsch_len_t length; - srslte_dmrs_pdsch_mapping_type_t mapping_type; - uint32_t duration; + /// Parameters provided by DMRS-DownlinkConfig + srslte_dmrs_pdsch_type_t type; + srslte_dmrs_pdsch_typeA_pos_t typeA_pos; + srslte_dmrs_pdsch_add_pos_t additional_pos; + srslte_dmrs_pdsch_len_t length; + uint32_t duration; + + /// Parameters provided by PDSCH-TimeDomainResourceAllocation + srslte_pdsch_mapping_type_t mapping_type; bool lte_CRS_to_match_around; bool additional_DMRS_DL_Alt; diff --git a/lib/include/srslte/phy/common/phy_common_nr.h b/lib/include/srslte/phy/common/phy_common_nr.h index 6b17abd8d..f8efeda93 100644 --- a/lib/include/srslte/phy/common/phy_common_nr.h +++ b/lib/include/srslte/phy/common/phy_common_nr.h @@ -70,25 +70,26 @@ extern "C" { */ #define SRSLTE_MAX_PRB_NR 275 +/** + * @brief Maximum start sub-carrier index for the carrier relative point + */ #define SRSLTE_MAX_START_NR 2199 /** - * @brief NR carrier parameters + * @brief defines the maximum number of Aggregation levels: 1, 2, 4, 8 and 16 */ -typedef struct { - uint32_t id; - uint32_t numerology; - uint32_t nof_prb; - uint32_t start; -} srslte_carrier_nr_t; +#define SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS 5 /** - * CORESET related constants + * @brief defines the maximum number of candidates for a given Aggregation level */ -#define SRSLTE_CORESET_DURATION_MIN 1 -#define SRSLTE_CORESET_DURATION_MAX 3 -#define SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE 45 -#define SRSLTE_CORESET_SHIFT_INDEX_MAX (SRSLTE_CORESET_NOF_PRB_MAX - 1) +#define SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES 8 + +/** + * @brief Maximum number of PDSCH time domain resource allocations. This is defined by TS 38.331 v15.10.0 + * as maxNrofDL-Allocations + */ +#define SRSLTE_MAX_NOF_DL_ALLOCATION 16 typedef enum SRSLTE_API { srslte_coreset_mapping_type_interleaved = 0, @@ -106,6 +107,39 @@ typedef enum SRSLTE_API { srslte_coreset_precoder_granularity_reg_bundle } srslte_coreset_precoder_granularity_t; +/** + * @brief PDSCH mapping type + * @remark Described in TS 38.331 V15.10.0 Section PDSCH-TimeDomainResourceAllocationList + */ +typedef enum SRSLTE_API { + /// Type A allocation is relative to the + srslte_pdsch_mapping_type_A = 0, + srslte_pdsch_mapping_type_B +} srslte_pdsch_mapping_type_t; + +typedef enum SRSLTE_API { + srslte_search_space_type_common = 0, + srslte_search_space_type_ue, +} srslte_search_space_type_t; + +/** + * @brief NR carrier parameters + */ +typedef struct { + uint32_t id; + uint32_t numerology; + uint32_t nof_prb; + uint32_t start; +} srslte_carrier_nr_t; + +/** + * CORESET related constants + */ +#define SRSLTE_CORESET_DURATION_MIN 1 +#define SRSLTE_CORESET_DURATION_MAX 3 +#define SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE 45 +#define SRSLTE_CORESET_SHIFT_INDEX_MAX (SRSLTE_CORESET_NOF_PRB_MAX - 1) + /** * CORESET structure * @@ -127,21 +161,6 @@ typedef struct SRSLTE_API { /** Missing TCI parameters */ } srslte_coreset_t; -typedef enum SRSLTE_API { - srslte_search_space_type_common = 0, - srslte_search_space_type_ue, -} srslte_search_space_type_t; - -/** - * @brief defines the maximum number of Aggregation levels: 1, 2, 4, 8 and 16 - */ -#define SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS 5 - -/** - * @brief defines the maximum number of candidates for a given Aggregation level - */ -#define SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES 8 - /** * @brief SearchSpace parameters as defined in TS 38.331 v15.10.0 SearchSpace sequence */ diff --git a/lib/include/srslte/phy/phch/pdsch_cfg_nr.h b/lib/include/srslte/phy/phch/pdsch_cfg_nr.h new file mode 100644 index 000000000..cc7028648 --- /dev/null +++ b/lib/include/srslte/phy/phch/pdsch_cfg_nr.h @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: pdsch_cfg_nr.h + * + * Description: Physical downlink shared channel configuration + * + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_PDSCH_CFG_NR_H +#define SRSLTE_PDSCH_CFG_NR_H + +#include "srslte/phy/ch_estimation/dmrs_pdsch.h" +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/phy/fec/cbsegm.h" +#include "srslte/phy/fec/softbuffer.h" +#include "srslte/phy/phch/ra.h" + +/** + * @brief flatten PDSCH time domain allocation parameters + * @remark Described in TS 38.331 V15.10.0 Section PDSCH-TimeDomainResourceAllocationList + */ +typedef struct SRSLTE_API { + /// Slot offset between DCI and its scheduled PDSCH + uint32_t k0; + + /// PDSCH mapping type + srslte_pdsch_mapping_type_t mapping_type; + + /// An index giving valid combinations of start symbol and length (jointly encoded) as start and length indicator + /// (SLIV). The network configures the field so that the allocation does not cross the slot boundary + uint32_t sliv; + +} srslte_pdsch_allocation_t; + +typedef struct SRSLTE_API { + /// TBD +} srslte_pdsch_grant_nr_t; + +typedef struct SRSLTE_API { + srslte_pdsch_allocation_t allocation; + + /// PDSCH Start symbol index + uint32_t S; + + /// PDSCH length in number of symbols + uint32_t L; +} srslte_pdsch_cfg_nr_t; + +#endif // SRSLTE_PDSCH_CFG_NR_H diff --git a/lib/include/srslte/phy/ue/ue_dl_nr_data.h b/lib/include/srslte/phy/ue/ue_dl_nr_data.h new file mode 100644 index 000000000..cefdb9c35 --- /dev/null +++ b/lib/include/srslte/phy/ue/ue_dl_nr_data.h @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * @file ue_dl_nr.h + * + * Description: UE downlink object for NR dataplane. + * + * This module is a frontend to all the downlink data channel processing modules. + * + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_UE_DL_NR_DATA_H +#define SRSLTE_UE_DL_NR_DATA_H + +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/phy/phch/pdsch_cfg_nr.h" + +/** + * @brief Calculates the PDSCH time resource provided by higher layers + * + * @remark Defined by TS 36.214 V15.10.0 section 5.1.2.1.1 Determination of the resource allocation table to be used for + * PDSCH + * + * @param pdsch_alloc Flattened PHY PDSCH allocation configuration provided from higher layers + * @param[out] S Start symbol + * @param[out] L PDSCH transmission length in symbols + * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int +srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, uint32_t* S, uint32_t* L); + +/** + * @brief Calculates the PDSCH time resource default A. This can be used by SI-RNTI, RA-RNTI, P-RNTI and C-RNTI. See + * Table 5.1.2.1.1-1 for more details about the usage. + * + * @remark Defined by TS 36.214 V15.10.0 Table 5.1.2.1.1-2: Default PDSCH time domain resource allocation A for normal + * CP + * + * @attention k0 shall be zero. + * + * @param m Time domain resource assignment field value m of the DCI + * @param dmrs_typeA_pos DMRS TypeA position provided by higher layers + * @param[out] S Start symbol + * @param[out] L PDSCH transmission length in symbols + * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, + srslte_dmrs_pdsch_typeA_pos_t dmrs_typeA_pos, + uint32_t* S, + uint32_t* L); + +#endif // SRSLTE_UE_DL_NR_DATA_H diff --git a/lib/src/phy/ch_estimation/dmrs_pdsch.c b/lib/src/phy/ch_estimation/dmrs_pdsch.c index 37fc9206c..dbac44555 100644 --- a/lib/src/phy/ch_estimation/dmrs_pdsch.c +++ b/lib/src/phy/ch_estimation/dmrs_pdsch.c @@ -32,7 +32,7 @@ int srslte_dmrs_pdsch_cfg_to_str(const srslte_dmrs_pdsch_cfg_t* cfg, char* msg, ? 1 : cfg->additional_pos == srslte_dmrs_pdsch_add_pos_2 ? 2 : 3; const char* len = cfg->length == srslte_dmrs_pdsch_len_1 ? "single" : "double"; - const char* mapping = cfg->mapping_type == srslte_dmrs_pdsch_mapping_type_A ? "A" : "B"; + const char* mapping = cfg->mapping_type == srslte_pdsch_mapping_type_A ? "A" : "B"; return srslte_print_check(msg, max_len, @@ -174,7 +174,7 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_ static int srslte_dmrs_pdsch_get_symbols_idx(const srslte_dmrs_pdsch_cfg_t* cfg, uint32_t* symbols) { switch (cfg->mapping_type) { - case srslte_dmrs_pdsch_mapping_type_A: + case srslte_pdsch_mapping_type_A: // The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal to 'pos2' if (cfg->typeA_pos != srslte_dmrs_pdsch_typeA_pos_2 && cfg->additional_pos == srslte_dmrs_pdsch_add_pos_3) { ERROR("The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal " @@ -194,7 +194,7 @@ static int srslte_dmrs_pdsch_get_symbols_idx(const srslte_dmrs_pdsch_cfg_t* cfg, return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(cfg, symbols); } return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(cfg, symbols); - case srslte_dmrs_pdsch_mapping_type_B: + case srslte_pdsch_mapping_type_B: ERROR("Error PDSCH mapping type B not supported\n"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c index 03311c060..2f426a30d 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c @@ -37,7 +37,7 @@ static srslte_cell_t cell = {50, // nof_prb SRSLTE_FDD}; typedef struct { - srslte_dmrs_pdsch_mapping_type_t mapping_type; + srslte_pdsch_mapping_type_t mapping_type; srslte_dmrs_pdsch_typeA_pos_t typeA_pos; srslte_dmrs_pdsch_len_t max_length; srslte_dmrs_pdsch_add_pos_t additional_pos; @@ -49,7 +49,7 @@ typedef struct { } golden_t; // Golden values extracted from https://www.sharetechnote.com/html/5G/5G_PDSCH_DMRS.html -static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_type_A, +static const golden_t gold[] = {{.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_0, @@ -58,7 +58,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_3, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_0, @@ -67,7 +67,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {3}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_2, .additional_pos = srslte_dmrs_pdsch_add_pos_0, @@ -76,7 +76,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2, 3}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_1, @@ -85,7 +85,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_2, @@ -94,7 +94,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2, 7, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_3, @@ -103,7 +103,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2, 5, 8, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_0, @@ -112,7 +112,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2}, .nof_sc = 6, .sc_idx = {0, 2, 4, 6, 8, 10}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_2, .additional_pos = srslte_dmrs_pdsch_add_pos_0, @@ -121,7 +121,7 @@ static const golden_t gold[] = {{.mapping_type = srslte_dmrs_pdsch_mapping_typ .symbol_idx = {2, 3}, .nof_sc = 6, .sc_idx = {0, 2, 4, 6, 8, 10}}, - {.mapping_type = srslte_dmrs_pdsch_mapping_type_A, + {.mapping_type = srslte_pdsch_mapping_type_A, .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, .max_length = srslte_dmrs_pdsch_len_1, .additional_pos = srslte_dmrs_pdsch_add_pos_3, diff --git a/lib/src/phy/ue/ue_dl_nr_data.c b/lib/src/phy/ue/ue_dl_nr_data.c new file mode 100644 index 000000000..2f12e9216 --- /dev/null +++ b/lib/src/phy/ue/ue_dl_nr_data.c @@ -0,0 +1,115 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ +#include "srslte/phy/ue/ue_dl_nr_data.h" + +static int srslte_ue_dl_nr_pdsch_time_resource_hl_A(uint32_t sliv, uint32_t* S, uint32_t* L) +{ + // S values can be 0 to 3 + uint32_t low = sliv % 14; + if (low < 7) { + *S = low; + *L = sliv / 14 + 1; + } else { + *S = 14 - 1 - low; + *L = 14 - sliv / 14 + 1; + } + + // Check values using Table 5.1.2.1-1 + if (*S > 3) { + ERROR("Invalid SLIV %d. S (%d) is out-of-range {0,1,2,3}\n", sliv, *S); + return SRSLTE_ERROR; + } + + if (*L < 3 || *L > 14) { + ERROR("Invalid SLIV %d. L (%d) is out-of-range {3,...,14}\n", sliv, *L); + return SRSLTE_ERROR; + } + + uint32_t sum = *S + *L; + if (sum < 3) { + ERROR("Invalid SLIV %d. The sum of S (%d) and L (%d) is lower than 3\n", sliv, *S, *L); + return SRSLTE_ERROR; + } + + if (sum > 14) { + ERROR("Invalid SLIV %d. The sum of S (%d) and L (%d) is greater than 14\n", sliv, *S, *L); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +static int srslte_ue_dl_nr_pdsch_time_resource_hl_B(uint32_t sliv, uint32_t* S, uint32_t* L) +{ + ERROR("Not implemented\n"); + return SRSLTE_ERROR; +} + +int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, uint32_t* S, uint32_t* L) +{ + + if (pdsch_alloc == NULL || S == NULL || L == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (pdsch_alloc->mapping_type == srslte_pdsch_mapping_type_A) { + return srslte_ue_dl_nr_pdsch_time_resource_hl_A(pdsch_alloc->sliv, S, L); + } + + return srslte_ue_dl_nr_pdsch_time_resource_hl_B(pdsch_alloc->sliv, S, L); +} + +int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, + srslte_dmrs_pdsch_typeA_pos_t dmrs_typeA_pos, + uint32_t* S, + uint32_t* L) +{ + if (S == NULL || L == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (m >= 16) { + ERROR("m (%d) is out-of-range\n", m); + return SRSLTE_ERROR_INVALID_INPUTS; + } + + static uint32_t S_pos2[16] = {2, 2, 2, 2, 2, 9, 4, 5, 5, 9, 12, 1, 1, 2, 4, 8}; + static uint32_t L_pos2[16] = {12, 10, 9, 7, 5, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4}; + static uint32_t S_pos3[16] = {3, 3, 3, 3, 3, 10, 6, 5, 5, 9, 12, 1, 1, 2, 4, 8}; + static uint32_t L_pos3[16] = {11, 9, 8, 6, 4, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4}; + + switch (dmrs_typeA_pos) { + + case srslte_dmrs_pdsch_typeA_pos_2: + *S = S_pos2[m]; + *L = L_pos2[m]; + break; + case srslte_dmrs_pdsch_typeA_pos_3: + *S = S_pos3[m]; + *L = L_pos3[m]; + break; + default: + ERROR("Undefined case (%d)\n", dmrs_typeA_pos); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} \ No newline at end of file