Add C models for FFT/IFFT and Viterbi decoder

This commit is contained in:
Robert Ghilduta 2021-01-10 21:23:16 -08:00
parent cbcc2c1951
commit ea221d0b3f
5 changed files with 733 additions and 0 deletions

View File

@ -0,0 +1,7 @@
all: dft idft
dft: dft.c
gcc -o dft dft.c -g3 -lm
idft: idft.c
gcc -o idft idft.c -g3 -lm

View File

@ -0,0 +1,173 @@
// This file is part of bladeRF-wiphy.
//
// Copyright (C) 2021 Nuand, LLC.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include <math.h>
#include <stdio.h>
int flip_bits(unsigned in, int bits) {
unsigned ret = 0;
int i;
for (i = 0; i < bits; i++) {
ret |= ( !!(in & (1 << i)) ) << (bits - i - 1);
}
printf("IN %d, OUT %d\n", in, ret);
return ret;
}
unsigned rotate_left(unsigned in, int width, int num) {
unsigned ret = 0;
unsigned bottom = 0;
unsigned mask = 0;
bottom = in;
//printf("#1 = %d\n", bottom);
bottom >>= (width - num);
//printf("#2 = %d\n", bottom);
mask = ((1 << (num+1)) - 1);
//printf("mask = %d\n", mask);
bottom &= mask;
//printf("BOTTOM = %d\n", bottom);
ret = in;
ret <<= num;
ret = ret & ((1 << width) - 1);
//printf("TOP = %d\n", ret);
ret |= bottom;
return(ret);
}
struct c_sample {
float i, q;
};
#define N 64
#define N_POW 6
#define FMT "%f"
struct c_sample rfs_i[] = {
{ 402, 750}, { -439, 700}, { 909, -96}, {-7, -496}, {76, -711}, {764, 601}, {-192, 315}, {411, -633},
{-540, -139}, {-360, -640}, {821, -172}, {160, 291}, {9, -678}, {-679, -241}, {69, -293}, {565, -172},
{-356, 999}, {515, -19}, {438, -498}, {78, 693}, {-276, 209}, {-865, 131}, {465, 487}, {454, 35},
{-480, 437}, {-324, -45}, {-86, -991}, {-471, 2}, {-805, -38}, {543, -621}, {170, 397}, {-797, 606},
{546, 369}, {150, 591}, {-1095, -17}, {109, -684}, {760, -450}, {-573, -478}, {-66, -409}, {682, 484},
{-862, 201}, {-695, -192}, {16, 819}, {-403, 172}, {-342, -660}, {443, 14}, {544, -389}, {-734, -339},
{-366, -141}, {381, -626}, {280, 382}, {624, 235}, {-218, 980}, {333, 54}, {333, 506}, {-944, 114},
{46, 566}, {305, -48}, {457, -20}, {-56, 740}, {-919, 197}, {522, 295}, {-2, 20}, {438, -712}
};
void gen_sample(int n, struct c_sample *ptr) {
int r, idx;
for (r = 0; r < n; r++) {
idx = flip_bits(r, N_POW);
ptr[idx] = rfs_i[r];
printf("Wrote %d to c[%d] = " FMT " + j*" FMT "\n", r, idx, ptr[idx].i, ptr[idx].q);
}
}
void butter_fly(struct c_sample *A, struct c_sample *B, struct c_sample *TW)
{
struct c_sample mix, t_A, t_B;
// A = a_i + j * a_q
// B = b_i + j * b_q
// C = A X B = (a_i * b_i + a_i * j * b_q + j * a_q * b_i + j * a_q * j * b_q)
// C = ( a_i * b_i - a_q * b_q) + j ( a_i * b_q + a_q + b_i )
// C_i = a_i * b_i - a_q * b_q
// C_q = a_i * b_q + a_q * b_i
mix.i = (B->i * TW->i - B->q * TW->q) /(32768);//>> 15;
mix.q = (B->i * TW->q + B->q * TW->i) /(32768);//>> 15;
//A->i *= 1;
//A->q *= 1;
//B->i *= 1;
//B->q *= 1;
t_A.i = A->i + mix.i;
t_A.q = A->q + mix.q;
t_B.i = A->i - mix.i;
t_B.q = A->q - mix.q;
printf("A: " FMT " + j* " FMT " B: " FMT " + j* " FMT " TW: " FMT " + j* " FMT "\n", A->i, A->q, B->i, B->q, TW->i, TW->q);
printf("mix: " FMT " + j* " FMT "\n", mix.i, mix.q);
*A = t_A;
*B = t_B;
printf("A: " FMT " + j* " FMT " B: " FMT " + j* " FMT "\n\n", A->i, A->q, B->i, B->q);
}
int W_i[N/2];
int W_q[N/2];
int main() {
float ti, tq;
int i, j;
struct c_sample s_a[N], s_b[N], s_tw[N];
gen_sample(N, s_a);
#if 0
for (i = 0; i < (N);i++) {
printf("[%d] = " FMT " " FMT "\n", i, s_a[i].i, s_a[i].q);
}
#endif
/*
for (i = 0; i < (N/2);i++) {
printf("%Lf, %Lf\n", sinl((2.0 * M_PI * (float)i) / N), cosl((2.0 * M_PI * (float)i) / N));
}
*/
for (i = 0; i < (N/2); i++) {
ti = cosf((2.0 * M_PI * (float)i) / (float)N);
s_tw[i].i = W_i[i] = ti * ((1<<15)-1);
tq = sinf((2.0 * M_PI * (float)i) / (float)N);
s_tw[i].q = W_q[i] = tq * ((1<<15)-1);
printf("[%.2d] I= %.15f = 0x%.8x Q= %.15f = 0x%.8x\t\t" FMT ", " FMT "\n", i, ti, W_i[i], tq, W_q[i], s_tw[i].i, s_tw[i].q);
}
for (i = 0; i < N_POW; i++) {
for (j = 0; j < (N/2); j++) {
int a, b, tw;
a = rotate_left(j * 2, N_POW, i);
b = rotate_left(j * 2 + 1, N_POW, i);
//tw = (j & ((1<< (i)) - 1)) << (N_POW-1-i); DIF
tw = (j ) & ((1 << (N_POW - 1)) - 1) - ((1 << (N_POW - 1 - i)) -1);
printf("Stage=%d A=%d,%d tw=%d\n", i, a, b, tw);
if ( i == 0) {
printf("\t%d,%d => A is timeidx = %d, B is timeidx = %d\n", a,b, flip_bits(a, N_POW), flip_bits(b, N_POW));
}
butter_fly(s_a + a, s_a + b, s_tw + tw );
}
printf("\n\n");
}
for (i = 0; i < N; i++) {
printf("[%.2d] = " FMT " + j * " FMT "\n", i, s_a[i].i, s_a[i].q);
}
printf("\n\n");
for (i = 0; i < N; i++) {
printf("[%.2d] = %f\n", i, sqrt(s_a[i].i * s_a[i].i + s_a[i].q * s_a[i].q));
}
return 0;
}

View File

@ -0,0 +1,166 @@
// This file is part of bladeRF-wiphy.
//
// Copyright (C) 2021 Nuand, LLC.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include <math.h>
#include <stdio.h>
int flip_bits(unsigned in, int bits) {
unsigned ret = 0;
int i;
for (i = 0; i < bits; i++) {
ret |= ( !!(in & (1 << i)) ) << (bits - i - 1);
}
printf("IN %d, OUT %d\n", in, ret);
return ret;
}
int f_s[]= {
0, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1 };
unsigned rotate_left(unsigned in, int width, int num) {
unsigned ret = 0;
unsigned bottom = 0;
unsigned mask = 0;
bottom = in;
//printf("#1 = %d\n", bottom);
bottom >>= (width - num);
//printf("#2 = %d\n", bottom);
mask = ((1 << (num+1)) - 1);
//printf("mask = %d\n", mask);
bottom &= mask;
//printf("BOTTOM = %d\n", bottom);
ret = in;
ret <<= num;
ret = ret & ((1 << width) - 1);
//printf("TOP = %d\n", ret);
ret |= bottom;
return(ret);
}
struct c_sample {
long long int i, q;
};
#define N 64
#define N_POW 6
#define FMT "%lld"
void gen_sample(int n, struct c_sample *ptr) {
int r, idx;
for (r = 0; r < n; r++) {
idx = flip_bits(r, N_POW);
ptr[idx].i = f_s[r] * 4096;
ptr[idx].q = 0;
printf("Wrote %d to c[%d] = " FMT " + j*" FMT "\n", r, idx, ptr[idx].i, ptr[idx].q);
}
}
void butter_fly(struct c_sample *A, struct c_sample *B, struct c_sample *TW)
{
struct c_sample mix, t_A, t_B;
// A = a_i + j * a_q
// B = b_i + j * b_q
// C = A X B = (a_i * b_i + a_i * j * b_q + j * a_q * b_i + j * a_q * j * b_q)
// C = ( a_i * b_i - a_q * b_q) + j ( a_i * b_q + a_q + b_i )
// C_i = a_i * b_i - a_q * b_q
// C_q = a_i * b_q + a_q * b_i
mix.i = (B->i * TW->i - B->q * TW->q) >> 15;
mix.q = (B->i * TW->q + B->q * TW->i) >> 15;
//A->i *= 1;
//A->q *= 1;
//B->i *= 1;
//B->q *= 1;
t_A.i = A->i + mix.i;
t_A.q = A->q + mix.q;
t_B.i = A->i - mix.i;
t_B.q = A->q - mix.q;
printf("A: " FMT " + j* " FMT " B: " FMT " + j* " FMT " TW: " FMT " + j* " FMT "\n", A->i, A->q, B->i, B->q, TW->i, TW->q);
printf("mix: " FMT " + j* " FMT "\n", mix.i, mix.q);
*A = t_A;
*B = t_B;
printf("A: " FMT " + j* " FMT " B: " FMT " + j* " FMT "\n\n", A->i, A->q, B->i, B->q);
}
int W_i[N/2];
int W_q[N/2];
int main() {
float ti, tq;
int i, j;
struct c_sample s_a[N], s_b[N], s_tw[N];
gen_sample(N, s_a);
#if 0
for (i = 0; i < (N);i++) {
printf("[%d] = " FMT " " FMT "\n", i, s_a[i].i, s_a[i].q);
}
#endif
/*
for (i = 0; i < (N/2);i++) {
printf("%Lf, %Lf\n", sinl((2.0 * M_PI * (float)i) / N), cosl((2.0 * M_PI * (float)i) / N));
}
*/
for (i = 0; i < (N/2); i++) {
ti = cosf((2.0 * M_PI * (float)i) / (float)N);
s_tw[i].i = W_i[i] = ti * ((1<<15)-1);
tq = sinf((2.0 * M_PI * (float)i) / (float)N);
s_tw[i].q = W_q[i] = tq * ((1<<15)-1);
printf("[%.2d] I= %.15f = 0x%.8x Q= %.15f = 0x%.8x\t\t" FMT ", " FMT "\n", i, ti, W_i[i], tq, W_q[i], s_tw[i].i, s_tw[i].q);
}
for (i = 0; i < N_POW; i++) {
for (j = 0; j < (N/2); j++) {
int a, b, tw;
a = rotate_left(j * 2, N_POW, i);
b = rotate_left(j * 2 + 1, N_POW, i);
//tw = (j & ((1<< (i)) - 1)) << (N_POW-1-i); DIF
tw = (j) & ((1 << (N_POW - 1)) - 1) - ((1 << (N_POW - 1 - i)) -1);
printf("Stage=%d A=%d,%d tw=%d\n", i, a, b, tw);
if (i == 0) {
printf("\t%d,%d => A is timeidx = %d, B is timeidx = %d\n", a,b, flip_bits(a, N_POW), flip_bits(b, N_POW));
}
butter_fly(s_a + a, s_a + b, s_tw + tw );
}
printf("\n\n");
}
for (i = 0; i < N; i++) {
printf("[%.2d] = " FMT " + j * " FMT "\n", i, s_a[i].i/64, s_a[i].q/64);
}
printf("\n\n");
for (i = 0; i < N; i++) {
printf("[%.2d] = %f\n", i, sqrt(s_a[i].i * s_a[i].i + s_a[i].q * s_a[i].q));
}
return 0;
}

View File

@ -0,0 +1,336 @@
// This file is part of bladeRF-wiphy.
//
// Copyright (C) 2021 Nuand, LLC.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#define K 7
#define C_A 91
#define C_B 121
#define NUM_BT 1000
#define BIT(y) ( (state >> y) & 1)
#define T_BIT(y) ( (t_state >> y) & 1)
uint32_t state;
unsigned int byte_a, byte_b ;
struct path {
int32_t cost;
uint32_t from_state[NUM_BT];
uint32_t bits[NUM_BT];
uint32_t bm[NUM_BT];
uint32_t set[NUM_BT];
uint32_t to_state[NUM_BT];
uint32_t win[NUM_BT];
};
uint32_t win_history[100][64];
struct path_metric {
int idx;
struct path paths[ 0x40 ];
};
void branch_metric_loop(struct path_metric *in_path, uint8_t r_a, int erasure_a, uint8_t r_b, int erasure_b) {
// the T_ prefix just means test
unsigned t_state;
uint8_t t_bit_a, t_bit_b;
uint32_t bm;
uint32_t next_state;
uint32_t bm_tbl_cost[0x40]; // idx: the end state
uint32_t bm_tbl_bit[0x40]; // idx: the end state
memset(bm_tbl_cost, 0xff, sizeof(bm_tbl_cost));
memset(bm_tbl_bit, 0xff, sizeof(bm_tbl_bit));
struct path_metric out_path;
memcpy(&out_path, in_path, sizeof(out_path));
out_path.idx = in_path->idx++;
for (t_state = 0; t_state <= 0x3f; t_state++) {
// calculate the branch metric by:
// assuming the trellis at t_state and is about to head to next_state
// the uncoded data bit determines to which one of two states the trellis goes from t_state
// as it goes to next_state from t_state, two coded bits t_bit_a and t_bit_b are output
// the branch metric is the sum of error between the expected value t_bit_a/t_bit_b and the received value r_a/r_b
//
// each "destination state"'s path metric is calculated by adding the current corresponding branch metric to the two possible "source state"'s path metric,
// and selecting the path with the lowest total path cost
//
// each state can only be entered from 2 previous states, so the hardware only has to calculate the branch metric (and total path metric) from 2 previous "source states".
// bit is 0?
t_bit_a = T_BIT(5) ^ T_BIT(4) ^ T_BIT(2) ^ T_BIT(1) ^ 0;
t_bit_b = T_BIT(5) ^ T_BIT(2) ^ T_BIT(1) ^ T_BIT(0) ^ 0;
//bm = (t_bit_a - r_a) + (t_bit_b - r_b);
bm = in_path->paths[t_state].cost;
if (!erasure_a) {
if (t_bit_a > r_a) {
bm += t_bit_a - r_a;
} else {
bm += r_a - t_bit_a;
}
}
if (!erasure_b) {
if (t_bit_b > r_b) {
bm += t_bit_b - r_b;
} else {
bm += r_b - t_bit_b;
}
}
next_state = (t_state << 1) & 0x3f;
if (bm < bm_tbl_cost[next_state]) {
bm_tbl_cost[next_state] = bm;
bm_tbl_bit[next_state] = 0;
out_path.paths[next_state] = in_path->paths[t_state];
out_path.paths[next_state].cost = bm;
out_path.paths[next_state].from_state[out_path.idx] = t_state;
out_path.paths[next_state].bits[out_path.idx] = 0;
out_path.paths[next_state].to_state[out_path.idx] = next_state;
out_path.paths[next_state].bm[out_path.idx] = bm;
out_path.paths[next_state].set[out_path.idx] = 1;
win_history[out_path.idx][next_state] = !!(t_state & (1 << 5));
}
//printf("B=0 COMPUTE S=%.2d TO D=%.2d del=%d\n", t_state, next_state, t_state-next_state);
bm = in_path->paths[t_state].cost;
// bit is 1?
t_bit_a = T_BIT(5) ^ T_BIT(4) ^ T_BIT(2) ^ T_BIT(1) ^ 1;
t_bit_b = T_BIT(5) ^ T_BIT(2) ^ T_BIT(1) ^ T_BIT(0) ^ 1;
if (!erasure_a) {
if (t_bit_a > r_a) {
bm += t_bit_a - r_a;
} else {
bm += r_a - t_bit_a;
}
}
if (!erasure_b) {
if (t_bit_b > r_b) {
bm += t_bit_b - r_b;
} else {
bm += r_b - t_bit_b;
}
}
next_state = ((t_state << 1) & 0x3f) | 1;
if (bm < bm_tbl_cost[next_state]) {
bm_tbl_cost[next_state] = bm;
bm_tbl_bit[next_state] = 0;
out_path.paths[next_state] = in_path->paths[t_state];
out_path.paths[next_state].cost = bm;
out_path.paths[next_state].from_state[out_path.idx] = t_state;
out_path.paths[next_state].bits[out_path.idx] = 1;
out_path.paths[next_state].to_state[out_path.idx] = next_state;
out_path.paths[next_state].bm[out_path.idx] = bm;
out_path.paths[next_state].set[out_path.idx] = 1;
win_history[out_path.idx][next_state] = !!(t_state & (1 << 5));
}
//printf("B=1 COMPUTE S=%.2d TO D=%.2d del=%d\n", t_state, next_state, t_state-next_state);
}
out_path.idx++;
memcpy(in_path, &out_path, sizeof(out_path));
}
uint16_t encode_bit(unsigned char bit, int shift, uint8_t *out_a, uint8_t *out_b) {
uint8_t bit_a, bit_b;
//printf("State before = %x\n", (state & 0x3f));
bit_a = BIT(5) ^ BIT(4) ^ BIT(2) ^ BIT(1) ^ bit;
bit_b = BIT(5) ^ BIT(2) ^ BIT(1) ^ BIT(0) ^ bit;
byte_a |= (bit_a << 7);
byte_b |= (bit_b << 7);
state <<= 1;
state |= bit;
state &= 0x3f;
//printf("State after = %x\n", (state & 0x3f));
if (shift) {
byte_a >>= 1;
byte_b >>= 1;
}
if (out_a)
*out_a = bit_a;
if (out_b)
*out_b = bit_b;
return ((bit_a << 8) + bit_b);
}
void dump_path_metric(struct path_metric *pm_in) {
int j, z;
unsigned min_cost = 0xffff;
unsigned idx = 0;
unsigned c_state;
for (j = 0; j <0x40; j++) {
if (pm_in->paths[j].cost < min_cost) {
min_cost = pm_in->paths[j].cost;
idx = j;
}
printf("[%.2d] = %d\n", j, pm_in->paths[j].cost);
//if (!pm_in->paths[j].cost) {
// printf("%d", pm_in->paths[j].bits[0]);
// break;
//}
}
printf("%d[%d] idx=%d\n", pm_in->paths[idx].bits[0], min_cost, idx);
for (j = 0; j < pm_in->idx; j++) {
for (z = 0; z < 0x40; z++) {
printf("%d", win_history[j][z]);
}
printf("\n");
}
#if 1
for (z = 0; z < pm_in->idx; z++) {
printf("%.3d] SET=%d [%.2d]--> bit=%d/w=%d/bm=%d --> [%.2d]", z,
pm_in->paths[idx].set[z],
pm_in->paths[idx].from_state[z],
pm_in->paths[idx].bits[z],
win_history[z][pm_in->paths[idx].to_state[z]],
pm_in->paths[idx].bm[z],
pm_in->paths[idx].to_state[z]
);
printf(" ");
c_state = pm_in->paths[idx].to_state[z];
for (j = 5; j >= 0; j--)
printf("%d", !!(c_state & (1 << j)));
if (win_history[z][c_state]) {
c_state >>= 1;
c_state |= (1<<5);
} else {
c_state >>= 1;
}
printf(" prev_state_hat: ");
for (j = 5; j >= 0; j--)
printf("%d", !!(c_state & (1 << j)));
printf("\n");
}
#endif
printf("\n");
}
int main(int argc, char *argv[]) {
state = 0;
uint8_t bit_a, bit_b;
struct path_metric *pm_in, *pm_out;
unsigned int tx_bits[] = {1, 1, 1, 0,
0, 1, 0, 1,
0, 1, 1, 0,
0, 1, 1, 1,
0, 1, 1, 0,
0, 0, 1, 0,
0, 0, 0, 0,
0, 1, 0, 1,
0, 1, 1, 0,
0, 1, 1, 1,
0, 1, 1, 0,
0, 0, 1, 0,
0, 0, 0, 0,
0, 1, 0, 1,
0, 1, 1, 0,
0, 1, 1, 1,
0, 1, 1, 0,
0, 0, 1, 0,
0, 0, 0, 0,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
};
unsigned int tx_len = sizeof(tx_bits)/sizeof(tx_bits[0]);
pm_in = (struct path_metric *)malloc(sizeof(struct path_metric));
pm_out = (struct path_metric *)malloc(sizeof(struct path_metric));
int i, j, z;
uint8_t *rx_bits = (uint8_t *)malloc(2 * tx_len * sizeof(uint8_t));
for (i = 0; i < tx_len; i++) {
byte_a = byte_b = 0;
printf("t[%d] = from S[%d] to ", i, state);
encode_bit(tx_bits[i], 1, &bit_a, &bit_b); // 0 -- 1
printf("= D[%d]\n", state);
rx_bits[i*2 + 0] = bit_a;
rx_bits[i*2 + 1] = bit_b;
//if ((i)==4)
// rx_bits[i*2] ^= 1;
}
memset(pm_in, 0, sizeof(pm_in));
for (i = 0; i < 0x40; i++) {
pm_in->paths[i].cost = (i == 0) ? 0 : 0xffffff;
for (z = 0; z < 12; z++) {
pm_in->paths[i].set[z] = 0;
pm_in->paths[i].from_state[z] = 0;
pm_in->paths[i].bits[z] = 0;
pm_in->paths[i].bm[z] = 0;
pm_in->paths[i].to_state[z] = 0;
}
}
int bit;
for (bit = 0; bit < (sizeof(tx_bits)/sizeof(tx_bits[0]))/2 ; bit++) {
bit_a = rx_bits[bit * 2];
bit_b = rx_bits[bit * 2 + 1];
branch_metric_loop(pm_in, bit_a, 0, bit_b, 0);
}
printf("LAST = %d\n", bit);
for (j = 0; j <0x40; j++) {
printf("[%d] ", pm_in->paths[j].from_state[0]);
for (i = bit - 20; i < bit; i++) {
printf(" -> [%d]",
pm_in->paths[j].to_state[i]
);
}
printf("\n");
}
dump_path_metric(pm_in);
printf("\n");
free(pm_in);
free(pm_out);
return 0;
}

View File

@ -0,0 +1,51 @@
// This file is part of bladeRF-wiphy.
//
// Copyright (C) 2021 Nuand, LLC.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#define K 7
#define C_A 91
#define C_B 121
#define BIT(y) ( (state >> y) & 1)
#define T_BIT(y) ( (t_state >> y) & 1)
int main(int argc, char *argv[]) {
unsigned t_state;
unsigned next_state;
uint8_t t_bit_a, t_bit_b;
for (t_state = 0; t_state <= 0x3f; t_state++) {
// bit is 0?
t_bit_a = T_BIT(5) ^ T_BIT(4) ^ T_BIT(2) ^ T_BIT(1) ^ 0;
t_bit_b = T_BIT(5) ^ T_BIT(2) ^ T_BIT(1) ^ T_BIT(0) ^ 0;
next_state = (t_state << 1) & 0x3f;
printf("S[%d] -- bit=%d coded=%d,%d -- D[%d]\n", t_state, 0, t_bit_a, t_bit_b, next_state);
// bit is 1?
t_bit_a = T_BIT(5) ^ T_BIT(4) ^ T_BIT(2) ^ T_BIT(1) ^ 1;
t_bit_b = T_BIT(5) ^ T_BIT(2) ^ T_BIT(1) ^ T_BIT(0) ^ 1;
next_state = ((t_state << 1) & 0x3f) | 1;
printf("S[%d] -- bit=%d coded=%d,%d -- D[%d]\n", t_state, 1, t_bit_a, t_bit_b, next_state);
}
return 0;
}