From f176495e0d72bae4e2e7faf2130f0f48a39a50dd Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 7 Mar 2016 19:01:09 +0100 Subject: [PATCH] l1/conv: Add all convolutional codes used in GMR-1 3G Signed-off-by: Sylvain Munaut --- include/osmocom/gmr1/l1/conv.h | 14 +- src/l1/bcch.c | 2 +- src/l1/ccch.c | 2 +- src/l1/conv.c | 429 ++++++++++++++++++++++++++++++--- src/l1/facch3.c | 2 +- src/l1/facch9.c | 2 +- src/l1/rach.c | 2 +- src/l1/tch9.c | 6 +- 8 files changed, 419 insertions(+), 40 deletions(-) diff --git a/include/osmocom/gmr1/l1/conv.h b/include/osmocom/gmr1/l1/conv.h index bc630ff..6a79a22 100644 --- a/include/osmocom/gmr1/l1/conv.h +++ b/include/osmocom/gmr1/l1/conv.h @@ -1,5 +1,5 @@ /* GMR-1 convolutional coding */ -/* See GMR-1 05.003 (ETSI TS 101 376-5-3 V1.2.1) - Section 4.4 */ +/* See GMR-1 05.003 (ETSI TS 101 376-5-3 V3.3.1) - Section 4.4 */ /* (C) 2011-2019 by Sylvain Munaut * All Rights Reserved @@ -33,10 +33,14 @@ #include -extern const struct osmo_conv_code gmr1_conv_12; -extern const struct osmo_conv_code gmr1_conv_13; -extern const struct osmo_conv_code gmr1_conv_14; -extern const struct osmo_conv_code gmr1_conv_15; +extern const struct osmo_conv_code gmr1_conv_k5_12; +extern const struct osmo_conv_code gmr1_conv_k5_13; +extern const struct osmo_conv_code gmr1_conv_k5_14; +extern const struct osmo_conv_code gmr1_conv_k5_15; +extern const struct osmo_conv_code gmr1_conv_k6_14; +extern const struct osmo_conv_code gmr1_conv_k9_12; +extern const struct osmo_conv_code gmr1_conv_k9_13; +extern const struct osmo_conv_code gmr1_conv_k9_14; extern const struct osmo_conv_code gmr1_conv_tch3; diff --git a/src/l1/bcch.c b/src/l1/bcch.c index 76def25..b02818d 100644 --- a/src/l1/bcch.c +++ b/src/l1/bcch.c @@ -45,7 +45,7 @@ static void __attribute__ ((constructor)) gmr1_bcch_init(void) { /* Init convolutional coder */ - memcpy(&gmr1_conv_bcch, &gmr1_conv_12, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_bcch, &gmr1_conv_k5_12, sizeof(struct osmo_conv_code)); gmr1_conv_bcch.len = 208; } diff --git a/src/l1/ccch.c b/src/l1/ccch.c index c52fd64..3ed3167 100644 --- a/src/l1/ccch.c +++ b/src/l1/ccch.c @@ -45,7 +45,7 @@ static void __attribute__ ((constructor)) gmr1_ccch_init(void) { /* Init convolutional coder */ - memcpy(&gmr1_conv_ccch, &gmr1_conv_12, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_ccch, &gmr1_conv_k5_12, sizeof(struct osmo_conv_code)); gmr1_conv_ccch.len = 208; } diff --git a/src/l1/conv.c b/src/l1/conv.c index 7ff49b5..dba9566 100644 --- a/src/l1/conv.c +++ b/src/l1/conv.c @@ -1,5 +1,5 @@ /* GMR-1 convolutional coding */ -/* See GMR-1 05.003 (ETSI TS 101 376-5-3 V1.2.1) - Section 4.4 */ +/* See GMR-1 05.003 (ETSI TS 101 376-5-3 V3.3.1) - Section 4.4 */ /* (C) 2011-2019 by Sylvain Munaut * All Rights Reserved @@ -31,66 +31,148 @@ #include -/* All codes are K=5 and share the same next_state table */ -static const uint8_t gmr1_conv_next_state[][2] = { +/* All K=5 codes share the same next_state table */ +static const uint8_t gmr1_conv_k5_next_state[][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, }; +/* All K=6 codes share the same next_state table */ +static const uint8_t gmr1_conv_k6_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, +}; + +/* All K=9 codes share the same next_state table */ +static const uint8_t gmr1_conv_k9_next_state[][2] = { + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 64, 65 }, { 66, 67 }, { 68, 69 }, { 70, 71 }, + { 72, 73 }, { 74, 75 }, { 76, 77 }, { 78, 79 }, + { 80, 81 }, { 82, 83 }, { 84, 85 }, { 86, 87 }, + { 88, 89 }, { 90, 91 }, { 92, 93 }, { 94, 95 }, + { 96, 97 }, { 98, 99 }, { 100, 101 }, { 102, 103 }, + { 104, 105 }, { 106, 107 }, { 108, 109 }, { 110, 111 }, + { 112, 113 }, { 114, 115 }, { 116, 117 }, { 118, 119 }, + { 120, 121 }, { 122, 123 }, { 124, 125 }, { 126, 127 }, + { 128, 129 }, { 130, 131 }, { 132, 133 }, { 134, 135 }, + { 136, 137 }, { 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, 165 }, { 166, 167 }, + { 168, 169 }, { 170, 171 }, { 172, 173 }, { 174, 175 }, + { 176, 177 }, { 178, 179 }, { 180, 181 }, { 182, 183 }, + { 184, 185 }, { 186, 187 }, { 188, 189 }, { 190, 191 }, + { 192, 193 }, { 194, 195 }, { 196, 197 }, { 198, 199 }, + { 200, 201 }, { 202, 203 }, { 204, 205 }, { 206, 207 }, + { 208, 209 }, { 210, 211 }, { 212, 213 }, { 214, 215 }, + { 216, 217 }, { 218, 219 }, { 220, 221 }, { 222, 223 }, + { 224, 225 }, { 226, 227 }, { 228, 229 }, { 230, 231 }, + { 232, 233 }, { 234, 235 }, { 236, 237 }, { 238, 239 }, + { 240, 241 }, { 242, 243 }, { 244, 245 }, { 246, 247 }, + { 248, 249 }, { 250, 251 }, { 252, 253 }, { 254, 255 }, + { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 }, + { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 }, + { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 }, + { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 }, + { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 }, + { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 }, + { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 }, + { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 }, + { 64, 65 }, { 66, 67 }, { 68, 69 }, { 70, 71 }, + { 72, 73 }, { 74, 75 }, { 76, 77 }, { 78, 79 }, + { 80, 81 }, { 82, 83 }, { 84, 85 }, { 86, 87 }, + { 88, 89 }, { 90, 91 }, { 92, 93 }, { 94, 95 }, + { 96, 97 }, { 98, 99 }, { 100, 101 }, { 102, 103 }, + { 104, 105 }, { 106, 107 }, { 108, 109 }, { 110, 111 }, + { 112, 113 }, { 114, 115 }, { 116, 117 }, { 118, 119 }, + { 120, 121 }, { 122, 123 }, { 124, 125 }, { 126, 127 }, + { 128, 129 }, { 130, 131 }, { 132, 133 }, { 134, 135 }, + { 136, 137 }, { 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, 165 }, { 166, 167 }, + { 168, 169 }, { 170, 171 }, { 172, 173 }, { 174, 175 }, + { 176, 177 }, { 178, 179 }, { 180, 181 }, { 182, 183 }, + { 184, 185 }, { 186, 187 }, { 188, 189 }, { 190, 191 }, + { 192, 193 }, { 194, 195 }, { 196, 197 }, { 198, 199 }, + { 200, 201 }, { 202, 203 }, { 204, 205 }, { 206, 207 }, + { 208, 209 }, { 210, 211 }, { 212, 213 }, { 214, 215 }, + { 216, 217 }, { 218, 219 }, { 220, 221 }, { 222, 223 }, + { 224, 225 }, { 226, 227 }, { 228, 229 }, { 230, 231 }, + { 232, 233 }, { 234, 235 }, { 236, 237 }, { 238, 239 }, + { 240, 241 }, { 242, 243 }, { 244, 245 }, { 246, 247 }, + { 248, 249 }, { 250, 251 }, { 252, 253 }, { 254, 255 }, +}; + /* - * GMR-1 Rate 1/2 convolutional code + * GMR-1 Constraint length 5, Rate 1/2 convolutional code * * g0(D) = 1 + D^3 + D^4 * g1(D) = 1 + D + D^2 + D^4 */ -static const uint8_t gmr1_conv_12_next_output[][2] = { +static const uint8_t gmr1_conv_k5_12_next_output[][2] = { { 0, 3 }, { 1, 2 }, { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 }, { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, { 0, 3 }, { 1, 2 }, }; -/*! \brief GMR-1 rate 1/2 convolutional code */ -const struct osmo_conv_code gmr1_conv_12 = { +/*! \brief GMR-1 constraint length 5, rate 1/2 convolutional code */ +const struct osmo_conv_code gmr1_conv_k5_12 = { .N = 2, .K = 5, .len = 0, /* to be filled during specialization */ - .next_output = gmr1_conv_12_next_output, - .next_state = gmr1_conv_next_state, + .next_output = gmr1_conv_k5_12_next_output, + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_state = gmr1_conv_k5_next_state, }; /* - * GMR-1 Rate 1/3 convolutional code + * GMR-1 Constraint length 5, Rate 1/3 convolutional code * * g0(D) = 1 + D^2 + D^4 * g1(D) = 1 + D + D^3 + D^4 * g2(D) = 1 + D + D^2 + D^3 + D^4 */ -static const uint8_t gmr1_conv_13_next_output[][2] = { +static const uint8_t gmr1_conv_k5_13_next_output[][2] = { { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, }; -/*! \brief GMR-1 rate 1/3 convolutional code */ -const struct osmo_conv_code gmr1_conv_13 = { +/*! \brief GMR-1 constraint length 5, rate 1/3 convolutional code */ +const struct osmo_conv_code gmr1_conv_k5_13 = { .N = 3, .K = 5, .len = 0, /* to be filled during specialization */ - .next_output = gmr1_conv_13_next_output, - .next_state = gmr1_conv_next_state, + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k5_13_next_output, + .next_state = gmr1_conv_k5_next_state, }; /* - * GMR-1 Rate 1/4 convolutional code + * GMR-1 Constraint length 5, Rate 1/4 convolutional code * * g0(D) = 1 + D^3 + D^4 * g1(D) = 1 + D + D^2 + D^4 @@ -98,25 +180,26 @@ const struct osmo_conv_code gmr1_conv_13 = { * g3(D) = 1 + D + D^2 + D^3 + D^4 */ -static const uint8_t gmr1_conv_14_next_output[][2] = { +static const uint8_t gmr1_conv_k5_14_next_output[][2] = { { 0, 15 }, { 5, 10 }, { 7, 8 }, { 2, 13 }, { 9, 6 }, { 12, 3 }, { 14, 1 }, { 11, 4 }, { 15, 0 }, { 10, 5 }, { 8, 7 }, { 13, 2 }, { 6, 9 }, { 3, 12 }, { 1, 14 }, { 4, 11 }, }; -/*! \brief GMR-1 rate 1/4 convolutional code */ -const struct osmo_conv_code gmr1_conv_14 = { +/*! \brief GMR-1 constraint length 5, rate 1/4 convolutional code */ +const struct osmo_conv_code gmr1_conv_k5_14 = { .N = 4, .K = 5, .len = 0, /* to be filled during specialization */ - .next_output = gmr1_conv_14_next_output, - .next_state = gmr1_conv_next_state, + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k5_14_next_output, + .next_state = gmr1_conv_k5_next_state, }; /* - * GMR-1 Rate 1/5 convolutional code + * GMR-1 Constraint length 5, Rate 1/5 convolutional code * * g0(D) = 1 + D^2 + D^4 * g1(D) = 1 + D + D^3 + D^4 @@ -125,20 +208,310 @@ const struct osmo_conv_code gmr1_conv_14 = { * g4(D) = 1 + D + D^2 + D^4 */ -static const uint8_t gmr1_conv_15_next_output[][2] = { +static const uint8_t gmr1_conv_k5_15_next_output[][2] = { { 0, 31 }, { 13, 18 }, { 23, 8 }, { 26, 5 }, { 14, 17 }, { 3, 28 }, { 25, 6 }, { 20, 11 }, { 31, 0 }, { 18, 13 }, { 8, 23 }, { 5, 26 }, { 17, 14 }, { 28, 3 }, { 6, 25 }, { 11, 20 }, }; -/*! \brief GMR-1 rate 1/5 convolutional code */ -const struct osmo_conv_code gmr1_conv_15 = { +/*! \brief GMR-1 constraint length 5, rate 1/5 convolutional code */ +const struct osmo_conv_code gmr1_conv_k5_15 = { .N = 5, .K = 5, .len = 0, /* to be filled during specialization */ - .next_output = gmr1_conv_15_next_output, - .next_state = gmr1_conv_next_state, + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k5_15_next_output, + .next_state = gmr1_conv_k5_next_state, +}; + + +/* + * GMR-1 Constraint length 6, Rate 1/4 convolutional code + * + * g0(D) = 1 + D^2 + D^5 + * g1(D) = 1 + D^2 + D^3 D^5 + * g2(D) = 1 + D + D^3 + D^4 + D^5 + * g3(D) = 1 + D + D^2 + D^3 + D^4 + D^5 + */ + +static const uint8_t gmr1_conv_k6_14_next_output[][2] = { + { 0, 15 }, { 3, 12 }, { 13, 2 }, { 14, 1 }, + { 7, 8 }, { 4, 11 }, { 10, 5 }, { 9, 6 }, + { 3, 12 }, { 0, 15 }, { 14, 1 }, { 13, 2 }, + { 4, 11 }, { 7, 8 }, { 9, 6 }, { 10, 5 }, + { 15, 0 }, { 12, 3 }, { 2, 13 }, { 1, 14 }, + { 8, 7 }, { 11, 4 }, { 5, 10 }, { 6, 9 }, + { 12, 3 }, { 15, 0 }, { 1, 14 }, { 2, 13 }, + { 11, 4 }, { 8, 7 }, { 6, 9 }, { 5, 10 }, +}; + +/*! \brief GMR-1 constraint length 6, rate 1/4 convolutional code */ +const struct osmo_conv_code gmr1_conv_k6_14 = { + .N = 4, + .K = 6, + .len = 0, /* to be filled during specialization */ + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k6_14_next_output, + .next_state = gmr1_conv_k6_next_state, +}; + + +/* + * GMR-1 Constraint length 9, Rate 1/2 convolutional code + * + * g0(D) = 1 + D^2 + D^3 + D^4 + D^8 + * g1(D) = 1 + D + D^2 + D^3 + D^5 + D^7 + D^8 + */ + +static const uint8_t gmr1_conv_k9_12_next_output[][2] = { + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 }, + { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 }, + { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 }, + { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 }, +}; + +/*! \brief GMR-1 constraint length 9, rate 1/2 convolutional code */ +const struct osmo_conv_code gmr1_conv_k9_12 = { + .N = 2, + .K = 9, + .len = 0, /* to be filled during specialization */ + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k9_12_next_output, + .next_state = gmr1_conv_k9_next_state, +}; + + +/* + * GMR-1 Constraint length 9, Rate 1/3 convolutional code + * + * g0(D) = 1 + D^2 + D^3 D^5 + D^6 + D^7 + D^8 + * g1(D) = 1 + D D^3 + D^4 + D^7 + D^8 + * g2(D) = 1 + D + D^2 D^5 + D^8 + */ + +static const uint8_t gmr1_conv_k9_13_next_output[][2] = { + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 5, 2 }, { 6, 1 }, { 0, 7 }, { 3, 4 }, + { 3, 4 }, { 0, 7 }, { 6, 1 }, { 5, 2 }, + { 7, 0 }, { 4, 3 }, { 2, 5 }, { 1, 6 }, + { 1, 6 }, { 2, 5 }, { 4, 3 }, { 7, 0 }, + { 0, 7 }, { 3, 4 }, { 5, 2 }, { 6, 1 }, + { 6, 1 }, { 5, 2 }, { 3, 4 }, { 0, 7 }, + { 2, 5 }, { 1, 6 }, { 7, 0 }, { 4, 3 }, + { 4, 3 }, { 7, 0 }, { 1, 6 }, { 2, 5 }, +}; + +/*! \brief GMR-1 constraint length 9, rate 1/3 convolutional code */ +const struct osmo_conv_code gmr1_conv_k9_13 = { + .N = 3, + .K = 9, + .len = 0, /* to be filled during specialization */ + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k9_13_next_output, + .next_state = gmr1_conv_k9_next_state, +}; + + +/* + * GMR-1 Constraint length 9, Rate 1/4 convolutional code + * + * g0(D) = 1 + D^3 + D^4 + D^5 + D^7 + D^8 + * g1(D) = 1 + D^2 + D^5 + D^7 + D^8 + * g2(D) = 1 + D + D^3 + D^4 + D^5 + D^8 + * g3(D) = 1 + D + D^2 + D^3 + D^4 + D^5 + D^6 + D^8 + */ + +static const uint8_t gmr1_conv_k9_14_next_output[][2] = { + { 0, 15 }, { 3, 12 }, { 5, 10 }, { 6, 9 }, + { 11, 4 }, { 8, 7 }, { 14, 1 }, { 13, 2 }, + { 11, 4 }, { 8, 7 }, { 14, 1 }, { 13, 2 }, + { 0, 15 }, { 3, 12 }, { 5, 10 }, { 6, 9 }, + { 14, 1 }, { 13, 2 }, { 11, 4 }, { 8, 7 }, + { 5, 10 }, { 6, 9 }, { 0, 15 }, { 3, 12 }, + { 5, 10 }, { 6, 9 }, { 0, 15 }, { 3, 12 }, + { 14, 1 }, { 13, 2 }, { 11, 4 }, { 8, 7 }, + { 1, 14 }, { 2, 13 }, { 4, 11 }, { 7, 8 }, + { 10, 5 }, { 9, 6 }, { 15, 0 }, { 12, 3 }, + { 10, 5 }, { 9, 6 }, { 15, 0 }, { 12, 3 }, + { 1, 14 }, { 2, 13 }, { 4, 11 }, { 7, 8 }, + { 15, 0 }, { 12, 3 }, { 10, 5 }, { 9, 6 }, + { 4, 11 }, { 7, 8 }, { 1, 14 }, { 2, 13 }, + { 4, 11 }, { 7, 8 }, { 1, 14 }, { 2, 13 }, + { 15, 0 }, { 12, 3 }, { 10, 5 }, { 9, 6 }, + { 12, 3 }, { 15, 0 }, { 9, 6 }, { 10, 5 }, + { 7, 8 }, { 4, 11 }, { 2, 13 }, { 1, 14 }, + { 7, 8 }, { 4, 11 }, { 2, 13 }, { 1, 14 }, + { 12, 3 }, { 15, 0 }, { 9, 6 }, { 10, 5 }, + { 2, 13 }, { 1, 14 }, { 7, 8 }, { 4, 11 }, + { 9, 6 }, { 10, 5 }, { 12, 3 }, { 15, 0 }, + { 9, 6 }, { 10, 5 }, { 12, 3 }, { 15, 0 }, + { 2, 13 }, { 1, 14 }, { 7, 8 }, { 4, 11 }, + { 13, 2 }, { 14, 1 }, { 8, 7 }, { 11, 4 }, + { 6, 9 }, { 5, 10 }, { 3, 12 }, { 0, 15 }, + { 6, 9 }, { 5, 10 }, { 3, 12 }, { 0, 15 }, + { 13, 2 }, { 14, 1 }, { 8, 7 }, { 11, 4 }, + { 3, 12 }, { 0, 15 }, { 6, 9 }, { 5, 10 }, + { 8, 7 }, { 11, 4 }, { 13, 2 }, { 14, 1 }, + { 8, 7 }, { 11, 4 }, { 13, 2 }, { 14, 1 }, + { 3, 12 }, { 0, 15 }, { 6, 9 }, { 5, 10 }, + { 15, 0 }, { 12, 3 }, { 10, 5 }, { 9, 6 }, + { 4, 11 }, { 7, 8 }, { 1, 14 }, { 2, 13 }, + { 4, 11 }, { 7, 8 }, { 1, 14 }, { 2, 13 }, + { 15, 0 }, { 12, 3 }, { 10, 5 }, { 9, 6 }, + { 1, 14 }, { 2, 13 }, { 4, 11 }, { 7, 8 }, + { 10, 5 }, { 9, 6 }, { 15, 0 }, { 12, 3 }, + { 10, 5 }, { 9, 6 }, { 15, 0 }, { 12, 3 }, + { 1, 14 }, { 2, 13 }, { 4, 11 }, { 7, 8 }, + { 14, 1 }, { 13, 2 }, { 11, 4 }, { 8, 7 }, + { 5, 10 }, { 6, 9 }, { 0, 15 }, { 3, 12 }, + { 5, 10 }, { 6, 9 }, { 0, 15 }, { 3, 12 }, + { 14, 1 }, { 13, 2 }, { 11, 4 }, { 8, 7 }, + { 0, 15 }, { 3, 12 }, { 5, 10 }, { 6, 9 }, + { 11, 4 }, { 8, 7 }, { 14, 1 }, { 13, 2 }, + { 11, 4 }, { 8, 7 }, { 14, 1 }, { 13, 2 }, + { 0, 15 }, { 3, 12 }, { 5, 10 }, { 6, 9 }, + { 3, 12 }, { 0, 15 }, { 6, 9 }, { 5, 10 }, + { 8, 7 }, { 11, 4 }, { 13, 2 }, { 14, 1 }, + { 8, 7 }, { 11, 4 }, { 13, 2 }, { 14, 1 }, + { 3, 12 }, { 0, 15 }, { 6, 9 }, { 5, 10 }, + { 13, 2 }, { 14, 1 }, { 8, 7 }, { 11, 4 }, + { 6, 9 }, { 5, 10 }, { 3, 12 }, { 0, 15 }, + { 6, 9 }, { 5, 10 }, { 3, 12 }, { 0, 15 }, + { 13, 2 }, { 14, 1 }, { 8, 7 }, { 11, 4 }, + { 2, 13 }, { 1, 14 }, { 7, 8 }, { 4, 11 }, + { 9, 6 }, { 10, 5 }, { 12, 3 }, { 15, 0 }, + { 9, 6 }, { 10, 5 }, { 12, 3 }, { 15, 0 }, + { 2, 13 }, { 1, 14 }, { 7, 8 }, { 4, 11 }, + { 12, 3 }, { 15, 0 }, { 9, 6 }, { 10, 5 }, + { 7, 8 }, { 4, 11 }, { 2, 13 }, { 1, 14 }, + { 7, 8 }, { 4, 11 }, { 2, 13 }, { 1, 14 }, + { 12, 3 }, { 15, 0 }, { 9, 6 }, { 10, 5 }, +}; + +/*! \brief GMR-1 constraint length 9, rate 1/4 convolutional code */ +const struct osmo_conv_code gmr1_conv_k9_14 = { + .N = 4, + .K = 9, + .len = 0, /* to be filled during specialization */ + .term = CONV_TERM_FLUSH, /* to be overriden during specialization */ + .next_output = gmr1_conv_k9_14_next_output, + .next_state = gmr1_conv_k9_next_state, }; @@ -191,9 +564,11 @@ static const uint8_t gmr1_conv_tch3_next_state[][2] = { const struct osmo_conv_code gmr1_conv_tch3 = { .N = 2, .K = 7, + .len = 0, /* to be filled during specialization */ .term = CONV_TERM_TAIL_BITING, .next_output = gmr1_conv_tch3_next_output, .next_state = gmr1_conv_tch3_next_state, }; + /*! @} */ diff --git a/src/l1/facch3.c b/src/l1/facch3.c index 80a5f36..999a26f 100644 --- a/src/l1/facch3.c +++ b/src/l1/facch3.c @@ -45,7 +45,7 @@ static void __attribute__ ((constructor)) gmr1_facch3_init(void) { /* Init convolutional coder */ - memcpy(&gmr1_conv_facch3, &gmr1_conv_14, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_facch3, &gmr1_conv_k5_14, sizeof(struct osmo_conv_code)); gmr1_conv_facch3.len = 92; } diff --git a/src/l1/facch9.c b/src/l1/facch9.c index 91c5464..6b26aa7 100644 --- a/src/l1/facch9.c +++ b/src/l1/facch9.c @@ -45,7 +45,7 @@ static void __attribute__ ((constructor)) gmr1_facch9_init(void) { /* Init convolutional coder */ - memcpy(&gmr1_conv_facch9, &gmr1_conv_12, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_facch9, &gmr1_conv_k5_12, sizeof(struct osmo_conv_code)); gmr1_conv_facch9.len = 316; } diff --git a/src/l1/rach.c b/src/l1/rach.c index ed5aa4e..659367a 100644 --- a/src/l1/rach.c +++ b/src/l1/rach.c @@ -47,7 +47,7 @@ gmr1_rach_init(void) int i, *p; /* Init convolutional coder */ - memcpy(&gmr1_conv_rach, &gmr1_conv_14, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_rach, &gmr1_conv_k5_14, sizeof(struct osmo_conv_code)); gmr1_conv_rach.len = 159; /* Generate puncturer (only b[0] .. b[539] punctured) */ diff --git a/src/l1/tch9.c b/src/l1/tch9.c index 08978b8..75a4c9f 100644 --- a/src/l1/tch9.c +++ b/src/l1/tch9.c @@ -56,21 +56,21 @@ static void __attribute__ ((constructor)) gmr1_tch9_init(void) { /* Init convolutional coders */ - memcpy(&gmr1_conv_tch9_24, &gmr1_conv_15, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_tch9_24, &gmr1_conv_k5_15, sizeof(struct osmo_conv_code)); gmr1_conv_tch9_24.len = 144; gmr1_puncturer_generate( &gmr1_conv_tch9_24, &gmr1_punct15_P53, &gmr1_punct15_P23, &gmr1_punct15_Ps53, 41 ); - memcpy(&gmr1_conv_tch9_48, &gmr1_conv_13, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_tch9_48, &gmr1_conv_k5_13, sizeof(struct osmo_conv_code)); gmr1_conv_tch9_48.len = 240; gmr1_puncturer_generate( &gmr1_conv_tch9_48, &gmr1_punct13_P15, &gmr1_punct13_P25, &gmr1_punct13_Ps15, 41 ); - memcpy(&gmr1_conv_tch9_96, &gmr1_conv_12, sizeof(struct osmo_conv_code)); + memcpy(&gmr1_conv_tch9_96, &gmr1_conv_k5_12, sizeof(struct osmo_conv_code)); gmr1_conv_tch9_96.len = 480; gmr1_puncturer_generate( &gmr1_conv_tch9_96,