]> git.gag.com Git - fw/altos/blob - src/kernel/ao_fec_rx.c
altos/stmf0: Add a comment about the requirements for using ao_flash_stm
[fw/altos] / src / kernel / ao_fec_rx.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <ao_fec.h>
20 #include <stdio.h>
21
22 #ifdef TELEMEGA
23 #include <ao.h>
24 #endif
25
26 #if AO_PROFILE
27 #include <ao_profile.h>
28
29 uint32_t        ao_fec_decode_start, ao_fec_decode_end;
30 #endif
31
32 /* 
33  * byte order repeats through 3 2 1 0
34  *      
35  * bit-pair order repeats through
36  *
37  *  1/0 3/2 5/4 7/6
38  *
39  * So, the over all order is:
40  *
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
45  *
46  * The raw bit order is thus
47  *
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
52  */
53
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
59 };
60
61 static inline uint16_t ao_interleave_index(uint16_t i) {
62         return (i & ~0x1e) | ao_interleave_order[(i & 0x1e) >> 1];
63 }
64
65 #define NUM_STATE       8
66 #define NUM_HIST        24
67
68 typedef uint32_t        bits_t;
69
70 #define V_0             0xff
71 #define V_1             0x00
72
73 /*
74  * These are just the 'zero' states; the 'one' states mirror them
75  */
76 static const uint8_t ao_fec_decode_table[NUM_STATE*2] = {
77         V_0, V_0,       /* 000 */
78         V_0, V_1,       /* 001 */
79         V_1, V_1,       /* 010 */
80         V_1, V_0,       /* 011 */
81         V_1, V_1,       /* 100 */
82         V_1, V_0,       /* 101 */
83         V_0, V_0,       /* 110 */
84         V_0, V_1        /* 111 */
85 };
86
87 static inline uint8_t
88 ao_next_state(uint8_t state, uint8_t bit)
89 {
90         return ((state << 1) | bit) & 0x7;
91 }
92
93 /*
94  * 'in' is 8-bits per symbol soft decision data
95  * 'len' is input byte length. 'out' must be
96  * 'len'/16 bytes long
97  */
98
99 uint8_t
100 ao_fec_decode(const uint8_t *in, uint16_t len, uint8_t *out, uint8_t out_len, uint16_t (*callback)(void))
101 {
102         static uint32_t cost[2][NUM_STATE];             /* path cost */
103         static bits_t   bits[2][NUM_STATE];             /* save bits to quickly output them */
104
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 */
113         uint8_t         s0, s1;
114         uint16_t        avail;
115         uint16_t        crc = AO_FEC_CRC_INIT;
116 #if AO_PROFILE
117         uint32_t        start_tick;
118 #endif
119
120         p = 0;
121         for (state = 0; state < NUM_STATE; state++) {
122                 cost[0][state] = 0x7fffffff;
123                 bits[0][state] = 0;
124         }
125         cost[0][0] = 0;
126
127         if (callback)
128                 avail = 0;
129         else
130                 avail = len;
131
132 #if AO_PROFILE
133         if (!avail) {
134                 avail = callback();
135                 if (!avail)
136                         return 0;
137         }
138         start_tick = ao_profile_tick();
139 #endif
140         o = 0;
141         for (i = 0; i < len; i += 2) {
142                 b = i/2;
143                 n = p ^ 1;
144
145                 if (!avail) {
146                         avail = callback();
147                         if (!avail)
148                                 return 0;
149                 }
150
151                 /* Fetch one pair of input bytes, de-interleaving
152                  * the input.
153                  */
154                 interleave = ao_interleave_index(i);
155                 s0 = in[interleave];
156                 s1 = in[interleave+1];
157
158                 avail -= 2;
159
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
167                  */
168
169                 /* Ok, of course this is tricky, it's optimized.
170                  *
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.
175                  *
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.
179                  *
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.
185                  *
186                  * m0 and m1 are the cost of coming to 'state<<1' from
187                  * one of the two possible previous states 'state' and
188                  * 'state + 4'.
189                  *
190                  * Because we know the expected values of each
191                  * received bit are flipped between these two previous
192                  * states:
193                  * 
194                  *      bitcost(state+4) = 510 - bitcost(state)
195                  *
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.
199                  *
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:
207                  *
208                  *      m0 = cost[p][state] + (510 - bitcost);
209                  *      m1 = cost[p][state+4] + bitcost
210                  *
211                  * Then, the lowest cost and bit trace of the new state
212                  * is saved.
213                  */
214
215 #define DO_STATE(state) {                                               \
216                         uint32_t        bitcost;                        \
217                                                                         \
218                         uint32_t        m0;                             \
219                         uint32_t        m1;                             \
220                         uint32_t        bit;                            \
221                                                                         \
222                         bitcost = ((uint32_t) (s0 ^ ao_fec_decode_table[(state<<1)]) + \
223                                    (uint32_t) (s1 ^ ao_fec_decode_table[(state<<1)|1])); \
224                                                                         \
225                         m0 = cost[p][state] + bitcost;                  \
226                         m1 = cost[p][state+4] + (510 - bitcost);        \
227                         bit = m0 > m1;                                  \
228                         cost[n][state<<1] = bit ? m1 : m0;              \
229                         bits[n][state<<1] = (bits[p][state + (bit<<2)] << 1) | (state&1); \
230                                                                         \
231                         m0 -= (bitcost+bitcost-510);                    \
232                         m1 += (bitcost+bitcost-510);                    \
233                         bit = m0 > m1;                                  \
234                         cost[n][(state<<1)+1] = bit ? m1 : m0;          \
235                         bits[n][(state<<1)+1] = (bits[p][state + (bit<<2)] << 1) | (state&1); \
236                 }
237
238                 DO_STATE(0);
239                 DO_STATE(1);
240                 DO_STATE(2);
241                 DO_STATE(3);
242
243 #if 0
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]);
247                 }
248                 printf ("\n");
249 #endif
250                 p = n;
251
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.
256                  */
257                 while ((b - o) >= (8 + NUM_HIST) || (i + 2 >= len && b > o)) {
258
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
263                          * it will be seven.
264                          */
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 */
268                         uint8_t         byte;
269
270                         /* Find the best fit at the current point
271                          * of the decode.
272                          */
273                         min_cost = cost[p][0];
274                         min_state = 0;
275                         for (state = 1; state < NUM_STATE; state++) {
276                                 if (cost[p][state] < min_cost) {
277                                         min_cost = cost[p][state];
278                                         min_state = state;
279                                 }
280                         }
281
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
286                          */
287                         if (dist < 0) {
288                                 bits[p][min_state] = (bits[p][min_state] << 1) | (min_state & 1);
289                                 dist = 0;
290                         }
291
292 #if 0
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);
295 #endif
296                         byte = (bits[p][min_state] >> dist) ^ *whiten++;
297                         *out++ = byte;
298                         if (out_len > 2)
299                                 crc = ao_fec_crc_byte(byte, crc);
300
301                         if (!--out_len) {
302                                 if ((out[-2] == (uint8_t) (crc >> 8)) &&
303                                     out[-1] == (uint8_t) crc)
304                                         out[-1] = AO_FEC_DECODE_CRC_OK;
305                                 else
306                                         out[-1] = 0;
307                                 out[-2] = 0;
308                                 goto done;
309                         }
310                         o += 8;
311                 }
312         }
313 done:
314 #if AO_PROFILE
315         ao_fec_decode_start = start_tick;
316         ao_fec_decode_end = ao_profile_tick();
317 #endif
318         return 1;
319 }