2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 #include <ao_profile.h>
29 uint32_t ao_fec_decode_start, ao_fec_decode_end;
33 * byte order repeats through 3 2 1 0
35 * bit-pair order repeats through
39 * So, the over all order is:
41 * 3,1/0 2,1/0 1,1/0 0,1/0
42 * 3,3/2 2,3/2 1,3/2 0,3/2
43 * 3,5/4 2,5/4 1,5/4 0,5/4
44 * 3,7/6 2,7/6 1,7/6 0,7/6
46 * The raw bit order is thus
48 * 1e/1f 16/17 0e/0f 06/07
49 * 1c/1d 14/15 0c/0d 04/05
50 * 1a/1b 12/13 0a/0b 02/03
51 * 18/19 10/11 08/09 00/01
54 static const uint8_t ao_interleave_order[] = {
55 0x1e, 0x16, 0x0e, 0x06,
56 0x1c, 0x14, 0x0c, 0x04,
57 0x1a, 0x12, 0x0a, 0x02,
58 0x18, 0x10, 0x08, 0x00
61 static inline uint16_t ao_interleave_index(uint16_t i) {
62 return (i & ~0x1e) | ao_interleave_order[(i & 0x1e) >> 1];
68 typedef uint32_t bits_t;
74 * These are just the 'zero' states; the 'one' states mirror them
76 static const uint8_t ao_fec_decode_table[NUM_STATE*2] = {
88 ao_next_state(uint8_t state, uint8_t bit)
90 return ((state << 1) | bit) & 0x7;
94 * 'in' is 8-bits per symbol soft decision data
95 * 'len' is input byte length. 'out' must be
100 ao_fec_decode(const uint8_t *in, uint16_t len, uint8_t *out, uint8_t out_len, uint16_t (*callback)(void))
102 static uint32_t cost[2][NUM_STATE]; /* path cost */
103 static bits_t bits[2][NUM_STATE]; /* save bits to quickly output them */
105 uint16_t i; /* input byte index */
106 uint16_t b; /* encoded symbol index (bytes/2) */
107 uint16_t o; /* output bit index */
108 uint8_t p; /* previous cost/bits index */
109 uint8_t n; /* next cost/bits index */
110 uint8_t state; /* state index */
111 const uint8_t *whiten = ao_fec_whiten_table;
112 uint16_t interleave; /* input byte array index */
115 uint16_t crc = AO_FEC_CRC_INIT;
121 for (state = 0; state < NUM_STATE; state++) {
122 cost[0][state] = 0x7fffffff;
138 start_tick = ao_profile_tick();
141 for (i = 0; i < len; i += 2) {
151 /* Fetch one pair of input bytes, de-interleaving
154 interleave = ao_interleave_index(i);
156 s1 = in[interleave+1];
160 /* Compute path costs and accumulate output bit path
161 * for each state and encoded bit value. Unrolling
162 * this loop is worth about > 30% performance boost.
163 * Decoding 76-byte remote access packets is reduced
164 * from 14.700ms to 9.3ms. Redoing the loop to
165 * directly compare the two pasts for each future state
166 * reduces this down to 5.7ms
169 /* Ok, of course this is tricky, it's optimized.
171 * First, it's important to realize that we have 8
172 * states representing the combinations of the three
173 * most recent bits from the encoder. Flipping any
174 * of these three bits flips both output bits.
176 * 'state<<1' represents the target state for a new
177 * bit value of 0. '(state<<1)+1' represents the
178 * target state for a new bit value of 1.
180 * 'state' is the previous state with an oldest bit
181 * value of 0. 'state + 4' is the previous state with
182 * an oldest bit value of 1. These two states will
183 * either lead to 'state<<1' or '(state<<1)+1', depending
184 * on whether the next encoded bit was a zero or a one.
186 * m0 and m1 are the cost of coming to 'state<<1' from
187 * one of the two possible previous states 'state' and
190 * Because we know the expected values of each
191 * received bit are flipped between these two previous
194 * bitcost(state+4) = 510 - bitcost(state)
196 * With those two total costs in hand, we then pick
197 * the lower as the cost of the 'state<<1', and compute
198 * the path of bits leading to that state.
200 * Then, do the same for '(state<<1) + 1'. This time,
201 * instead of computing the m0 and m1 values from
202 * scratch, because the only difference is that we're
203 * expecting a one bit instead of a zero bit, we just
204 * flip the bitcost values around to match the
205 * expected transmitted bits with some tricky
206 * arithmetic which is equivalent to:
208 * m0 = cost[p][state] + (510 - bitcost);
209 * m1 = cost[p][state+4] + bitcost
211 * Then, the lowest cost and bit trace of the new state
215 #define DO_STATE(state) { \
222 bitcost = ((uint32_t) (s0 ^ ao_fec_decode_table[(state<<1)]) + \
223 (uint32_t) (s1 ^ ao_fec_decode_table[(state<<1)|1])); \
225 m0 = cost[p][state] + bitcost; \
226 m1 = cost[p][state+4] + (510 - bitcost); \
228 cost[n][state<<1] = bit ? m1 : m0; \
229 bits[n][state<<1] = (bits[p][state + (bit<<2)] << 1) | (state&1); \
231 m0 -= (bitcost+bitcost-510); \
232 m1 += (bitcost+bitcost-510); \
234 cost[n][(state<<1)+1] = bit ? m1 : m0; \
235 bits[n][(state<<1)+1] = (bits[p][state + (bit<<2)] << 1) | (state&1); \
244 printf ("bit %3d symbol %2x %2x:", i/2, s0, s1);
245 for (state = 0; state < NUM_STATE; state++) {
246 printf (" %8u(%08x)", cost[n][state], bits[n][state]);
252 /* A loop is needed to handle the last output byte. It
253 * won't have any bits of future data to perform full
254 * error correction, but we might as well give the
255 * best possible answer anyways.
257 while ((b - o) >= (8 + NUM_HIST) || (i + 2 >= len && b > o)) {
259 /* Compute number of bits to the end of the
260 * last full byte of data. This is generally
261 * NUM_HIST, unless we've reached
262 * the end of the input, in which case
265 int8_t dist = b - (o + 8); /* distance to last ready-for-writing bit */
266 uint32_t min_cost; /* lowest cost */
267 uint8_t min_state; /* lowest cost state */
270 /* Find the best fit at the current point
273 min_cost = cost[p][0];
275 for (state = 1; state < NUM_STATE; state++) {
276 if (cost[p][state] < min_cost) {
277 min_cost = cost[p][state];
282 /* The very last byte of data has the very last bit
283 * of data left in the state value; just smash the
284 * bits value in place and reset the 'dist' from
285 * -1 to 0 so that the full byte is read out
288 bits[p][min_state] = (bits[p][min_state] << 1) | (min_state & 1);
293 printf ("\tbit %3d min_cost %5d old bit %3d old_state %x bits %02x whiten %0x\n",
294 i/2, min_cost, o + 8, min_state, (bits[p][min_state] >> dist) & 0xff, *whiten);
296 byte = (bits[p][min_state] >> dist) ^ *whiten++;
299 crc = ao_fec_crc_byte(byte, crc);
302 if ((out[-2] == (uint8_t) (crc >> 8)) &&
303 out[-1] == (uint8_t) crc)
304 out[-1] = AO_FEC_DECODE_CRC_OK;
315 ao_fec_decode_start = start_tick;
316 ao_fec_decode_end = ao_profile_tick();