dlsch_coding_NB_IoT.c 8.41 KB
Newer Older
Matthieu Kanj's avatar
Matthieu Kanj committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
Matthieu Kanj's avatar
Matthieu Kanj committed
21 22 23 24 25 26 27 28 29 30 31

/*! \file PHY/LTE_TRANSPORT/dlsch_coding_NB_IoT.c
* \brief Top-level routines for implementing Tail-biting convolutional coding for transport channels (NPDSCH) for NB_IoT,	 TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
32
#include <string.h>
33
//#include "PHY/defs.h"
34 35
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
36
#include "PHY/CODING/defs_NB_IoT.h"
37 38
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
39
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
40 41
//#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
//#include "SCHED/defs_NB_IoT.h"
42
//#include "defs_nb_iot.h"
43
//#include "UTIL/LOG/vcd_signal_dumper.h"
44
#include "PHY/TOOLS/time_meas_NB_IoT.h" 
45 46

unsigned char  ccodelte_table2_NB_IoT[128];
47
unsigned short glte2_NB_IoT[] = { 0133, 0171, 0165 }; 
Matthieu Kanj's avatar
Matthieu Kanj committed
48

49 50 51 52
void ccode_encode_npdsch_NB_IoT (int32_t   numbits,
								 uint8_t   *inPtr,
								 uint8_t   *outPtr,
								 uint32_t  crc)
Matthieu Kanj's avatar
Matthieu Kanj committed
53
{
54 55
	uint32_t  	state;
	uint8_t  	c, out, first_bit;
56
	int8_t 		shiftbit = 0;
57
    /* The input bit is shifted in position 8 of the state.
Matthieu Kanj's avatar
Matthieu Kanj committed
58
	Shiftbit will take values between 1 and 8 */
59 60 61
	state 		= 0;
	first_bit   = 2;
	c 			= ((uint8_t*)&crc)[0];
Matthieu Kanj's avatar
Matthieu Kanj committed
62 63 64 65
	// Perform Tail-biting
	// get bits from last byte of input (or crc)
	for (shiftbit = 0 ; shiftbit <(8-first_bit) ; shiftbit++) {
		if ((c&(1<<(7-first_bit-shiftbit))) != 0)
66
			state |= (1<<shiftbit);
Matthieu Kanj's avatar
Matthieu Kanj committed
67
	}
68 69
	state = state & 0x3f;   			  // true initial state of Tail-biting CCode
	state<<=1;            				  // because of loop structure in CCode
Matthieu Kanj's avatar
Matthieu Kanj committed
70 71 72 73 74 75 76
		while (numbits > 0) {											// Tail-biting is applied to input bits , input 34 bits , output 102 bits
			c = *inPtr++;
			for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
				state >>= 1;
				if ((c&(1<<shiftbit)) != 0) {
					state |= 64;
				}
77
				out = ccodelte_table2_NB_IoT[state];
Matthieu Kanj's avatar
Matthieu Kanj committed
78 79 80 81 82 83 84 85

				*outPtr++ = out  & 1;
				*outPtr++ = (out>>1)&1;
				*outPtr++ = (out>>2)&1;
			}
		}
}

86
int dlsch_encoding_NB_IoT(unsigned char      			*a,
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
87 88
			              NB_IoT_DL_eNB_SIB_t 			*dlsch, //NB_IoT_eNB_NDLSCH_t
			              uint8_t 			 	Nsf,       // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
Matthieu Kanj's avatar
Matthieu Kanj committed
89 90
			              unsigned int 		 		G,
			              uint8_t option) 		    // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
Matthieu Kanj's avatar
Matthieu Kanj committed
91
{
Matthieu Kanj's avatar
Matthieu Kanj committed
92
	uint32_t  crc = 1;
Matthieu Kanj's avatar
Matthieu Kanj committed
93
	//unsigned char harq_pid = dlsch->current_harq_pid;  			// to check during implementation if harq_pid is required in the NB_IoT_eNB_DLSCH_t structure  in defs_NB_IoT.h
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
94
	//uint8_t 	  option1,option2,option3,option4;
95 96
	unsigned int  A;
	uint8_t 	  RCC;
Matthieu Kanj's avatar
Matthieu Kanj committed
97

Matthieu Kanj's avatar
Matthieu Kanj committed
98
    uint8_t       npbch_a[85];
Matthieu Kanj's avatar
Matthieu Kanj committed
99 100 101
    uint8_t       npbch_a_crc[88];
	bzero(npbch_a,85); 
	bzero(npbch_a_crc,88);
Matthieu Kanj's avatar
Matthieu Kanj committed
102 103
  
	 A 							 = 680;
104 105

	dlsch->length_e = G*Nsf;									// G*Nsf (number_of_subframes) = total number of bits to transmit G=236
106

Matthieu Kanj's avatar
Matthieu Kanj committed
107 108
	int32_t numbits = A+24;

Matthieu Kanj's avatar
Matthieu Kanj committed
109 110 111
if(option ==1)
{  
	for (int i=0; i<19; i++) 												
Matthieu Kanj's avatar
Matthieu Kanj committed
112 113 114
	{	
		npbch_a[i] = a[i];    
	}
Matthieu Kanj's avatar
Matthieu Kanj committed
115 116 117 118 119 120 121
} else {
	for (int i=0; i<33; i++) 												
	{	
		npbch_a[i] = a[i];    
	}
}
    
Matthieu Kanj's avatar
Matthieu Kanj committed
122 123 124
     
	crc = crc24a_NB_IoT(npbch_a,A)>>8;
	
Matthieu Kanj's avatar
Matthieu Kanj committed
125

Matthieu Kanj's avatar
Matthieu Kanj committed
126 127 128 129
    for (int j=0; j<85; j++) 												
	{	
		npbch_a_crc[j] = npbch_a[j];    
	}
Matthieu Kanj's avatar
Matthieu Kanj committed
130

Matthieu Kanj's avatar
Matthieu Kanj committed
131 132 133 134
    npbch_a_crc[85] = ((uint8_t*)&crc)[2];
    npbch_a_crc[86] = ((uint8_t*)&crc)[1];
	npbch_a_crc[87] = ((uint8_t*)&crc)[0];
	
135 136 137
		dlsch->B = numbits;			// The length of table b in bits
		//memcpy(dlsch->b,a,numbits/8);        // comment if option 2 
		memset(dlsch->d,LTE_NULL_NB_IoT,96);
Matthieu Kanj's avatar
Matthieu Kanj committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
		ccode_encode_npdsch_NB_IoT(numbits,npbch_a_crc,dlsch->d+96,crc);
		RCC = sub_block_interleaving_cc_NB_IoT(numbits,dlsch->d+96,dlsch->w);		//   step 2 interleaving
		lte_rate_matching_cc_NB_IoT(RCC,dlsch->length_e,dlsch->w,dlsch->e);  // step 3 Rate Matching
				
  return(0);
}

///////////////////////////////////////////////////////////////////////////
////////////////////////////////temp  function////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

int dlsch_encoding_rar_NB_IoT(unsigned char      			*a,
			              NB_IoT_DL_eNB_RAR_t 			*dlsch, //NB_IoT_eNB_NDLSCH_t
			              uint8_t 			 	Nsf,       // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
			              unsigned int 		 		G,
			              uint8_t option) 		    // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
{
	uint32_t  crc = 1;
	//unsigned char harq_pid = dlsch->current_harq_pid;  			// to check during implementation if harq_pid is required in the NB_IoT_eNB_DLSCH_t structure  in defs_NB_IoT.h
	//uint8_t 	  option1,option2,option3,option4;
	unsigned int  A;
	uint8_t 	  RCC;

    uint8_t       npbch_a[7];
    uint8_t       npbch_a_crc[10];
	bzero(npbch_a,7); 
	bzero(npbch_a_crc,10);
Matthieu Kanj's avatar
Matthieu Kanj committed
165 166 167 168 169

	uint8_t       npbch_a_x[15];
    uint8_t       npbch_a_crc_x[18];
	bzero(npbch_a_x,15); 
	bzero(npbch_a_crc_x,18);
Matthieu Kanj's avatar
Matthieu Kanj committed
170
  
Matthieu Kanj's avatar
Matthieu Kanj committed
171
	 
Matthieu Kanj's avatar
Matthieu Kanj committed
172 173 174

	dlsch->length_e = G;									// G*Nsf (number_of_subframes) = total number of bits to transmit G=236

Matthieu Kanj's avatar
Matthieu Kanj committed
175
	
Matthieu Kanj's avatar
Matthieu Kanj committed
176 177 178

if(option ==1)
{  
Matthieu Kanj's avatar
Matthieu Kanj committed
179
	A 							 = 56;
Matthieu Kanj's avatar
Matthieu Kanj committed
180 181 182 183 184
	for (int i=0; i<7; i++) 												
	{	
		npbch_a[i] = a[i];    
	}
} else {
Matthieu Kanj's avatar
Matthieu Kanj committed
185 186
	A 							 = 120;
	for (int i=0; i<15; i++) 												
Matthieu Kanj's avatar
Matthieu Kanj committed
187
	{	
Matthieu Kanj's avatar
Matthieu Kanj committed
188
		npbch_a_x[i] = a[i];    
Matthieu Kanj's avatar
Matthieu Kanj committed
189 190 191
	}
}
    
Matthieu Kanj's avatar
Matthieu Kanj committed
192
     int32_t numbits = A+24;
Matthieu Kanj's avatar
Matthieu Kanj committed
193 194 195 196 197


	if(option==1)
	{
		crc = crc24a_NB_IoT(npbch_a,A)>>8;
Matthieu Kanj's avatar
Matthieu Kanj committed
198 199
	

Matthieu Kanj's avatar
Matthieu Kanj committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
    	for (int j=0; j<7; j++) 												
		{	
			npbch_a_crc[j] = npbch_a[j];    
		}

	    npbch_a_crc[7] = ((uint8_t*)&crc)[2];
	    npbch_a_crc[8] = ((uint8_t*)&crc)[1];
		npbch_a_crc[9] = ((uint8_t*)&crc)[0];
		
			dlsch->B = numbits;			// The length of table b in bits
			//memcpy(dlsch->b,a,numbits/8);        // comment if option 2 
			memset(dlsch->d,LTE_NULL_NB_IoT,96);
			ccode_encode_npdsch_NB_IoT(numbits,npbch_a_crc,dlsch->d+96,crc);
			RCC = sub_block_interleaving_cc_NB_IoT(numbits,dlsch->d+96,dlsch->w);		//   step 2 interleaving
			lte_rate_matching_cc_NB_IoT(RCC,dlsch->length_e,dlsch->w,dlsch->e);  // step 3 Rate Matching

	} else {

	    crc = crc24a_NB_IoT(npbch_a_x,A)>>8;
		

Matthieu Kanj's avatar
Matthieu Kanj committed
221
	    for (int j=0; j<15; j++) 												
Matthieu Kanj's avatar
Matthieu Kanj committed
222 223 224 225
		{	
			npbch_a_crc_x[j] = npbch_a_x[j];    
		}

Matthieu Kanj's avatar
Matthieu Kanj committed
226 227 228
	    npbch_a_crc_x[15] = ((uint8_t*)&crc)[2];
	    npbch_a_crc_x[16] = ((uint8_t*)&crc)[1];
		npbch_a_crc_x[17] = ((uint8_t*)&crc)[0];
Matthieu Kanj's avatar
Matthieu Kanj committed
229 230 231 232 233 234 235
		
			dlsch->B = numbits;			// The length of table b in bits
			//memcpy(dlsch->b,a,numbits/8);        // comment if option 2 
			memset(dlsch->d_x,LTE_NULL_NB_IoT,96);
			ccode_encode_npdsch_NB_IoT(numbits,npbch_a_crc_x,dlsch->d_x+96,crc);
			RCC = sub_block_interleaving_cc_NB_IoT(numbits,dlsch->d_x+96,dlsch->w_x);		//   step 2 interleaving
			lte_rate_matching_cc_NB_IoT(RCC,dlsch->length_e_x,dlsch->w_x,dlsch->e_x);  // step 3 Rate Matching
Matthieu Kanj's avatar
Matthieu Kanj committed
236 237
	}

238
				
Matthieu Kanj's avatar
Matthieu Kanj committed
239 240
  return(0);
}
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

/*************************************************************************

  Functions to initialize the code tables

*************************************************************************/
/* Basic code table initialization for constraint length 7 */

/* Input in MSB, followed by state in 6 LSBs */
void ccodelte_init2_NB_IoT(void)
{
  unsigned int  i, j, k, sum;

  for (i = 0; i < 128; i++) {

    ccodelte_table2_NB_IoT[i] = 0;

    /* Compute 3 output bits */
    for (j = 0; j < 3; j++) {
      sum = 0;

      for (k = 0; k < 7; k++)
        if ((i & glte2_NB_IoT[j]) & (1 << k))
          sum++;

      /* Write the sum modulo 2 in bit j */
      ccodelte_table2_NB_IoT[i] |= (sum & 1) << j;
    }
  }
}