/* Computes PUSCH frequency hopping as defined in Section 8.4 of 36.213 */ static void compute_freq_hopping(srslte_ra_ul_pusch_hopping_t* q, srslte_ul_sf_cfg_t* sf, srslte_pusch_hopping_cfg_t* hopping_cfg, srslte_pusch_grant_t* grant) { if (q->cell.frame_type == SRSLTE_TDD) { ERROR("Error frequency hopping for TDD not implemented (c_init for each subframe, see end of 5.3.4 36.211)\n"); } for (uint32_t slot = 0; slot < 2; slot++) { INFO("PUSCH Freq hopping: %d\n", grant->freq_hopping); uint32_t n_prb_tilde = grant->n_prb[slot]; if (grant->freq_hopping == 1) { if (hopping_cfg->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) { n_prb_tilde = grant->n_prb[hopping_cfg->current_tx_nb % 2]; } else { n_prb_tilde = grant->n_prb[slot]; } } if (grant->freq_hopping == 2) { /* Freq hopping type 2 as defined in 5.3.4 of 36.211 */ uint32_t n_vrb_tilde = grant->n_prb[0]; if (hopping_cfg->n_sb > 1) { n_vrb_tilde -= (hopping_cfg->hopping_offset - 1) / 2 + 1; } int i = 0; if (hopping_cfg->hop_mode == SRSLTE_PUSCH_HOP_MODE_INTER_SF) { i = sf->tti % 10; } else { i = 2 * sf->tti % 10 + slot; } uint32_t n_rb_sb = q->cell.nof_prb; if (hopping_cfg->n_sb > 1) { n_rb_sb = (n_rb_sb - hopping_cfg->hopping_offset - hopping_cfg->hopping_offset % 2) / hopping_cfg->n_sb; } n_prb_tilde = (n_vrb_tilde + f_hop(q, hopping_cfg, i) * n_rb_sb + (n_rb_sb - 1) - 2 * (n_vrb_tilde % n_rb_sb) * f_m(q, hopping_cfg, i, hopping_cfg->current_tx_nb)) % (n_rb_sb * hopping_cfg->n_sb); INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping_cfg->n_sb); if (hopping_cfg->n_sb > 1) { n_prb_tilde += (hopping_cfg->hopping_offset - 1) / 2 + 1; } } grant->n_prb_tilde[slot] = n_prb_tilde; } }
result_type operator()(first_argument_type x, second_argument_type y, third_argument_type z) const { return f_m(x, y, z); }
void display(const model_type& x) { f_m(x); }
inline dest_type convert(const source_type& x) const { return f_m(x); }