diff --git a/lib/include/srslte/phy/phch/uci.h b/lib/include/srslte/phy/phch/uci.h index bad87866e..c49df67f2 100644 --- a/lib/include/srslte/phy/phch/uci.h +++ b/lib/include/srslte/phy/phch/uci.h @@ -130,7 +130,8 @@ SRSLTE_API int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg, uint32_t H_prime_total, uint32_t O_cqi, srslte_uci_bit_t *ack_bits, - uint8_t *data); + uint8_t acks[2], + uint32_t nof_acks); SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg, uint8_t data, diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index 72ee50ee9..02ec906ff 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -657,14 +657,17 @@ int srslte_ulsch_uci_decode_ri_ack(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srs // Deinterleave and decode HARQ bits if (uci_data->uci_ack_len > 0) { + uint8_t acks[2] = {0, 0}; float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack]; if (cfg->cb_segm.tbs == 0) { beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi]; } - ret = srslte_uci_decode_ack(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, &uci_data->uci_ack); + ret = srslte_uci_decode_ack(cfg, q_bits, c_seq, beta, nb_q/Qm, uci_data->uci_cqi_len, q->ack_ri_bits, acks, uci_data->uci_ack_len); if (ret < 0) { return ret; } + uci_data->uci_ack = acks[0]; + uci_data->uci_ack_2 = acks[1]; Q_prime_ack = (uint32_t) ret; // Set zeros to HARQ bits diff --git a/lib/src/phy/phch/test/pusch_test.c b/lib/src/phy/phch/test/pusch_test.c index 0cb2847b7..3434fac72 100644 --- a/lib/src/phy/phch/test/pusch_test.c +++ b/lib/src/phy/phch/test/pusch_test.c @@ -172,14 +172,15 @@ int main(int argc, char **argv) { bzero(&uci_data_tx, sizeof(srslte_uci_data_t)); uci_data_tx.uci_cqi_len = 4; uci_data_tx.uci_ri_len = 0; - uci_data_tx.uci_ack_len = 0; + uci_data_tx.uci_ack_len = 2; memcpy(&uci_data_rx, &uci_data_tx, sizeof(srslte_uci_data_t)); for (uint32_t i=0;i<20;i++) { uci_data_tx.uci_cqi [i] = 1; } - uci_data_tx.uci_ri = 1; - uci_data_tx.uci_ack = 1; + uci_data_tx.uci_ri = 1; + uci_data_tx.uci_ack = 1; + uci_data_tx.uci_ack_2 = 1; uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp); sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re); @@ -250,11 +251,19 @@ int main(int argc, char **argv) { if (uci_data_tx.uci_ack_len) { if (uci_data_tx.uci_ack != uci_data_rx.uci_ack) { printf("UCI ACK bit error: %d != %d\n", uci_data_tx.uci_ack, uci_data_rx.uci_ack); + ret = SRSLTE_ERROR; + } + } + if (uci_data_tx.uci_ack_len > 1) { + if (uci_data_tx.uci_ack_2 != uci_data_rx.uci_ack_2) { + printf("UCI ACK 2 bit error: %d != %d\n", uci_data_tx.uci_ack_2, uci_data_rx.uci_ack_2); + ret = SRSLTE_ERROR; } } if (uci_data_tx.uci_ri_len) { if (uci_data_tx.uci_ri != uci_data_rx.uci_ri) { printf("UCI RI bit error: %d != %d\n", uci_data_tx.uci_ri, uci_data_rx.uci_ri); + ret = SRSLTE_ERROR; } } if (uci_data_tx.uci_cqi_len) { diff --git a/lib/src/phy/phch/uci.c b/lib/src/phy/phch/uci.c index 5bf40cc17..cb274bb83 100644 --- a/lib/src/phy/phch/uci.c +++ b/lib/src/phy/phch/uci.c @@ -545,15 +545,35 @@ static void encode_ri_ack(uint8_t data, srslte_uci_bit_type_t q_encoded_bits[6], } } -static int32_t decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos) +static void decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t *pos, uint32_t Qm, int32_t data[2], uint32_t nof_data) { - uint32_t p0 = pos[0].position; - uint32_t p1 = pos[1].position; - - uint32_t q0 = c_seq[p0]?q_bits[p0]:-q_bits[p0]; - uint32_t q1 = c_seq[p0]?q_bits[p1]:-q_bits[p1]; + if (nof_data == 1) { + uint32_t p0 = pos[0].position; + uint32_t p1 = pos[1].position; - return -(q0+q1); + int32_t q0 = c_seq[p0] ? q_bits[p0] : -q_bits[p0]; + int32_t q1 = c_seq[p0] ? q_bits[p1] : -q_bits[p1]; + + data[0] -= q0 + q1; + } else { + uint32_t p0 = pos[Qm * 0 + 0].position; + uint32_t p1 = pos[Qm * 0 + 1].position; + uint32_t p2 = pos[Qm * 1 + 6].position; + uint32_t p3 = pos[Qm * 1 + 7].position; + uint32_t p4 = pos[Qm * 2 + 12].position; + uint32_t p5 = pos[Qm * 2 + 13].position; + + int32_t q0 = c_seq[p0] ? q_bits[p0] : -q_bits[p0]; + int32_t q1 = c_seq[p1] ? q_bits[p1] : -q_bits[p1]; + int32_t q2 = c_seq[p2] ? q_bits[p2] : -q_bits[p2]; + int32_t q3 = c_seq[p3] ? q_bits[p3] : -q_bits[p3]; + int32_t q4 = c_seq[p4] ? q_bits[p4] : -q_bits[p4]; + int32_t q5 = c_seq[p5] ? q_bits[p5] : -q_bits[p5]; + + data[0] -= q0 + q3; + data[1] -= q1 + q4; + data[2] -= q2 + q5; + } } @@ -562,25 +582,27 @@ static int32_t decode_ri_ack(int16_t *q_bits, uint8_t *c_seq, srslte_uci_bit_t * */ int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_seq, float beta, uint32_t H_prime_total, - uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t *data) + uint32_t O_cqi, srslte_uci_bit_t *ack_bits, uint8_t acks[2], uint32_t nof_acks) { - int32_t rx_ack = 0; - + int32_t acks_sum[3] = {0, 0, 0}; + if (beta < 0) { fprintf(stderr, "Error beta is reserved\n"); return -1; } - uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta); + uint32_t Qprime = Q_prime_ri_ack(cfg, nof_acks, O_cqi, beta); // Use the same interleaver function to get the HARQ bit position - for (uint32_t i=0;i 1) ? 3 : 1) { uci_ulsch_interleave_ack_gen(i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]); - rx_ack += (int32_t) decode_ri_ack(q_bits, c_seq, ack_bits); + decode_ri_ack(q_bits, c_seq, ack_bits, cfg->grant.Qm, acks_sum, nof_acks); } - - if (data) { - *data = rx_ack>0; + + if (acks) { + acks[0] = (uint8_t)(acks_sum[0] > 0); + acks[1] = (uint8_t)(acks_sum[1] > 0); + // TODO: Do something with acks_sum[2] } return (int) Qprime; } @@ -629,7 +651,7 @@ int srslte_uci_decode_ri(srslte_pusch_cfg_t *cfg, int16_t *q_bits, uint8_t *c_se // Use the same interleaver function to get the HARQ bit position for (uint32_t i=0;igrant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ri_bits[cfg->grant.Qm*i]); - rx_ri += (int32_t) decode_ri_ack(q_bits, c_seq, ri_bits); + decode_ri_ack(q_bits, c_seq, ri_bits, cfg->grant.Qm, &rx_ri, 1); } if (data) {