UoS³ Flight Computer Firmware
 All Data Structures Files Functions Groups Pages
ldpc.h
1 /* Labrador-LDPC C API
2  * Copyright 2017 Adam Greig
3  * Licensed under the MIT license, see LICENSE for details.
4  * See README or https://docs.rs/labrador-ldpc-capi for documentation.
5  */
6 
7 #ifndef LABRADOR_LDPC_CAPI
8 #define LABRADOR_LDPC_CAPI
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <stdbool.h>
13 
14 /* Available LDPC codes.
15  *
16  * For further details refer to:
17  * https://docs.rs/labrador-ldpc/1.0.0/labrador_ldpc/codes/enum.LDPCCode.html
18  */
19 enum labrador_ldpc_code {
20  LABRADOR_LDPC_CODE_TC128,
21  LABRADOR_LDPC_CODE_TC256,
22  LABRADOR_LDPC_CODE_TC512,
23  LABRADOR_LDPC_CODE_TM1280,
24  LABRADOR_LDPC_CODE_TM1536,
25  LABRADOR_LDPC_CODE_TM2048,
26  LABRADOR_LDPC_CODE_TM5120,
27  LABRADOR_LDPC_CODE_TM6144,
28  LABRADOR_LDPC_CODE_TM8192,
29 };
30 
31 /* Useful constants for each code, for statically allocating required memory.
32  *
33  * Each can be accessed directly as `LABRADOR_LDPC_N_TC512`, or with the
34  * code as a constant parameter, as `LABRADOR_LDPC_N(TC512)`, or with the code
35  * as another define, for example:
36  * #define CODE TC512
37  * int n = LABRADOR_LDPC_N(CODE);
38  *
39  * For further details refer to:
40  * https://docs.rs/labrador-ldpc/1.0.0/labrador_ldpc/codes/struct.CodeParams.html
41  */
42 #define LABRADOR_LDPC_CODE_(CODE) LABRADOR_LDPC_CODE_##CODE
43 #define LABRADOR_LDPC_CODE(CODE) LABRADOR_LDPC_CODE_(CODE)
44 
45 #define LABRADOR_LDPC_N_TC128 (128)
46 #define LABRADOR_LDPC_N_TC256 (256)
47 #define LABRADOR_LDPC_N_TC512 (512)
48 #define LABRADOR_LDPC_N_TM1280 (1280)
49 #define LABRADOR_LDPC_N_TM1536 (1536)
50 #define LABRADOR_LDPC_N_TM2048 (2048)
51 #define LABRADOR_LDPC_N_TM5120 (5120)
52 #define LABRADOR_LDPC_N_TM6144 (6140)
53 #define LABRADOR_LDPC_N_TM8192 (8192)
54 #define LABRADOR_LDPC_N_(CODE) LABRADOR_LDPC_N_##CODE
55 #define LABRADOR_LDPC_N(CODE) LABRADOR_LDPC_N_(CODE)
56 
57 #define LABRADOR_LDPC_K_TC128 (64)
58 #define LABRADOR_LDPC_K_TC256 (128)
59 #define LABRADOR_LDPC_K_TC512 (256)
60 #define LABRADOR_LDPC_K_TM1280 (1024)
61 #define LABRADOR_LDPC_K_TM1536 (1024)
62 #define LABRADOR_LDPC_K_TM2048 (1024)
63 #define LABRADOR_LDPC_K_TM5120 (4096)
64 #define LABRADOR_LDPC_K_TM6144 (4096)
65 #define LABRADOR_LDPC_K_TM8192 (4096)
66 #define LABRADOR_LDPC_K_(CODE) LABRADOR_LDPC_K_##CODE
67 #define LABRADOR_LDPC_K(CODE) LABRADOR_LDPC_K_(CODE)
68 
69 #define LABRADOR_LDPC_BF_WORKING_LEN_TC128 (128)
70 #define LABRADOR_LDPC_BF_WORKING_LEN_TC256 (256)
71 #define LABRADOR_LDPC_BF_WORKING_LEN_TC512 (512)
72 #define LABRADOR_LDPC_BF_WORKING_LEN_TM1280 (1408)
73 #define LABRADOR_LDPC_BF_WORKING_LEN_TM1536 (1792)
74 #define LABRADOR_LDPC_BF_WORKING_LEN_TM2048 (2560)
75 #define LABRADOR_LDPC_BF_WORKING_LEN_TM5120 (5632)
76 #define LABRADOR_LDPC_BF_WORKING_LEN_TM6140 (7168)
77 #define LABRADOR_LDPC_BF_WORKING_LEN_TM8192 (10240)
78 #define LABRADOR_LDPC_BF_WORKING_LEN_(CODE) LABRADOR_LDPC_BF_WORKING_LEN_##CODE
79 #define LABRADOR_LDPC_BF_WORKING_LEN(CODE) LABRADOR_LDPC_BF_WORKING_LEN_(CODE)
80 
81 #define LABRADOR_LDPC_MS_WORKING_LEN_TC128 (1280)
82 #define LABRADOR_LDPC_MS_WORKING_LEN_TC256 (2560)
83 #define LABRADOR_LDPC_MS_WORKING_LEN_TC512 (5120)
84 #define LABRADOR_LDPC_MS_WORKING_LEN_TM1280 (12160)
85 #define LABRADOR_LDPC_MS_WORKING_LEN_TM1536 (15104)
86 #define LABRADOR_LDPC_MS_WORKING_LEN_TM2048 (20992)
87 #define LABRADOR_LDPC_MS_WORKING_LEN_TM5120 (48640)
88 #define LABRADOR_LDPC_MS_WORKING_LEN_TM6140 (60416)
89 #define LABRADOR_LDPC_MS_WORKING_LEN_TM8192 (83968)
90 #define LABRADOR_LDPC_MS_WORKING_LEN_(CODE) LABRADOR_LDPC_MS_WORKING_LEN_##CODE
91 #define LABRADOR_LDPC_MS_WORKING_LEN(CODE) LABRADOR_LDPC_MS_WORKING_LEN_(CODE)
92 
93 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TC128 (8)
94 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TC256 (16)
95 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TC512 (32)
96 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM1280 (48)
97 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM1536 (96)
98 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM2048 (192)
99 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM5120 (192)
100 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM6140 (384)
101 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_TM8192 (768)
102 #define LABRADOR_LDPC_MS_WORKING_U8_LEN_(CODE) LABRADOR_LDPC_MS_WORKING_U8_LEN_##CODE
103 #define LABRADOR_LDPC_MS_WORKING_U8_LEN(CODE) LABRADOR_LDPC_MS_WORKING_U8_LEN_(CODE)
104 
105 #define LABRADOR_LDPC_OUTPUT_LEN_TC128 (16)
106 #define LABRADOR_LDPC_OUTPUT_LEN_TC256 (32)
107 #define LABRADOR_LDPC_OUTPUT_LEN_TC512 (64)
108 #define LABRADOR_LDPC_OUTPUT_LEN_TM1280 (176)
109 #define LABRADOR_LDPC_OUTPUT_LEN_TM1536 (224)
110 #define LABRADOR_LDPC_OUTPUT_LEN_TM2048 (320)
111 #define LABRADOR_LDPC_OUTPUT_LEN_TM5120 (704)
112 #define LABRADOR_LDPC_OUTPUT_LEN_TM6140 (896)
113 #define LABRADOR_LDPC_OUTPUT_LEN_TM8192 (1280)
114 #define LABRADOR_LDPC_OUTPUT_LEN_(CODE) LABRADOR_LDPC_OUTPUT_LEN_##CODE
115 #define LABRADOR_LDPC_OUTPUT_LEN(CODE) LABRADOR_LDPC_OUTPUT_LEN_(CODE)
116 
117 /* Returns the code length n (number of codeword bits) for a given code. */
118 size_t labrador_ldpc_code_n(enum labrador_ldpc_code code);
119 
120 /* Returns the code dimension k (number of data bits) for a given code. */
121 size_t labrador_ldpc_code_k(enum labrador_ldpc_code code);
122 
123 /* Returns the required length of the working area for the BF decoder. */
124 size_t labrador_ldpc_bf_working_len(enum labrador_ldpc_code code);
125 
126 /* Returns the required length of the uint8_t working area for the MS decoder.
127  */
128 size_t labrador_ldpc_ms_working_u8_len(enum labrador_ldpc_code code);
129 
130 /* Returns the required length of the LLR-type working area for the MS decoder.
131  */
132 size_t labrador_ldpc_ms_working_len(enum labrador_ldpc_code code);
133 
134 /* Returns the required length for the output of any decoder. */
135 size_t labrador_ldpc_output_len(enum labrador_ldpc_code code);
136 
137 /* Encode the first k/8 bytes of `codeword` into the rest of `codeword`,
138  * using the `code` LDPC code.
139  *
140  * If `codeword` is 4-byte aligned, encoding is performed 32 bits at a time,
141  * which is usually faster than byte at a time.
142  */
143 void labrador_ldpc_encode(enum labrador_ldpc_code code, uint8_t *codeword);
144 
145 /* Encode all of `data` (k/8 bytes long) into `codeword` (n/8 bytes long),
146  * first copying `data` into `codeword`, using the `code` LDPC code.
147  *
148  * If `codeword` is 4-byte aligned, encoding is performed 32 bits at a time,
149  * which is usually faster than byte at a time.
150  */
151 void labrador_ldpc_copy_encode(enum labrador_ldpc_code code,
152  const uint8_t* data, uint8_t* codeword);
153 
154 /* Run the BF decoder:
155  *
156  * `code` is the LDPC code in use.
157  * `input` is a received codeword, with each bit representing one received bit.
158  * `output` is filled with the decoded codeword, and must be the length given
159  * by `labrador_ldpc_output_len`.
160  * `working` is the working area and must be the length given by
161  * `labrador_ldpc_bf_working_len`.
162  * `max_iters` is the maximum number of iterations to run for, e.g. 50.
163  * `iters_run`, if not NULL, is set to the number of iterations actually run.
164  *
165  * Returns true on decoding success or false on failure.
166  */
167 bool labrador_ldpc_decode_bf(enum labrador_ldpc_code code,
168  const uint8_t *input, uint8_t *output,
169  uint8_t *working, size_t max_iters,
170  size_t *iters_run);
171 
172 /* Run the MS decoder:
173  *
174  * `code` is the LDPC code in use.
175  * `llrs` contains n entries, one per received bit, with positive numbers
176  * more likely to be a 0 bit.
177  * `output` is filled with the decoded codeword, and must be the length given
178  * by `labrador_ldpc_output_len`.
179  * `working` is the main working area and must be the length given by
180  * `labrador_ldpc_ms_working_len`.
181  * `working_u8` is the secondary working area and must be the length given by
182  * `labrador_ldpc_ms_u8_working_len`.
183  * `max_iters` is the maximum number of iterations to run for, e.g. 200.
184  * `iters_run`, if not NULL, is set to the number of iterations actually run.
185  *
186  * Returns true on decoding success or false on failure.
187  *
188  * Four variants are provided which use different types for the LLRs.
189  * For details on this choice please refer to:
190  * https://docs.rs/labrador-ldpc/1.0.0/labrador_ldpc/codes/enum.LDPCCode.html,
191  * section "Log Likelihood Ratios and choice of T".
192  */
193 bool labrador_ldpc_decode_ms_i8(enum labrador_ldpc_code code,
194  const int8_t* llrs, uint8_t *output,
195  int8_t* working, uint8_t *working_u8,
196  size_t max_iters, size_t* iters_run);
197 bool labrador_ldpc_decode_ms_i16(enum labrador_ldpc_code code,
198  const int16_t* llrs, uint8_t *output,
199  int16_t* working, uint8_t *working_u8,
200  size_t max_iters, size_t* iters_run);
201 bool labrador_ldpc_decode_ms_f32(enum labrador_ldpc_code code,
202  const float* llrs, uint8_t *output,
203  float* working, uint8_t *working_u8,
204  size_t max_iters, size_t* iters_run);
205 bool labrador_ldpc_decode_ms_f64(enum labrador_ldpc_code code,
206  const double* llrs, uint8_t *output,
207  double* working, uint8_t *working_u8,
208  size_t max_iters, size_t* iters_run);
209 
210 /* Convert hard information into LLRs.
211  *
212  * Assigns -/+ 1 for 1/0 bits.
213  *
214  * `input` must be n/8 bytes long.
215  * `llrs` must be n entries long.
216  *
217  * Available in four variants for different LLR types.
218  */
219 void labrador_ldpc_hard_to_llrs_i8(enum labrador_ldpc_code code,
220  const uint8_t* input, int8_t* llrs);
221 void labrador_ldpc_hard_to_llrs_i16(enum labrador_ldpc_code code,
222  const uint8_t* input, int16_t* llrs);
223 void labrador_ldpc_hard_to_llrs_f32(enum labrador_ldpc_code code,
224  const uint8_t* input, float* llrs);
225 void labrador_ldpc_hard_to_llrs_f64(enum labrador_ldpc_code code,
226  const uint8_t* input, double* llrs);
227 
228 /* Convert LLRs into hard information.
229  *
230  * Assumes positive numbers are more likely to be 0 bits.
231  *
232  * `llrs` must be n entries long.
233  * `output` must be n/8 long.
234  *
235  * Available in four variants for different LLR types.
236  */
237 void labrador_ldpc_llrs_to_hard_i8(enum labrador_ldpc_code code,
238  const int8_t* llrs, uint8_t* output);
239 void labrador_ldpc_llrs_to_hard_i16(enum labrador_ldpc_code code,
240  const int16_t* llrs, uint8_t* output);
241 void labrador_ldpc_llrs_to_hard_f32(enum labrador_ldpc_code code,
242  const float* llrs, uint8_t* output);
243 void labrador_ldpc_llrs_to_hard_f64(enum labrador_ldpc_code code,
244  const double* llrs, uint8_t* output);
245 
246 #endif /* LABRADOR_LDPC_CAPI */