This commit is contained in:
2025-09-16 13:23:11 +03:00
parent 99cc783f82
commit 03cd22ef4b
13 changed files with 5049 additions and 4622 deletions

23
src/complex.c Normal file
View File

@ -0,0 +1,23 @@
#include "complex.h"
#include <math.h>
complex conv_from_polar(double r, double radians) {
complex result;
result.re = r * cos(radians);
result.im = r * sin(radians);
return result;
}
complex add(complex left, complex right) {
complex result;
result.re = left.re + right.re;
result.im = left.im + right.im;
return result;
}
complex multiply(complex left, complex right) {
complex result;
result.re = left.re*right.re - left.im*right.im;
result.im = left.re*right.im + left.im*right.re;
return result;
}

9
src/complex.h Normal file
View File

@ -0,0 +1,9 @@
typedef struct complex_t {
double re;
double im;
} complex;
complex conv_from_polar(double r, double radians);
complex add(complex left, complex right);
complex multiply(complex left, complex right);

BIN
src/complex.o Normal file

Binary file not shown.

147
src/fft.c Normal file
View File

@ -0,0 +1,147 @@
#include "fft.h"
#include <stdlib.h>
#define PI 3.1415926535897932384626434
complex* DFT_naive(complex* x, int N) {
complex* X = (complex*) malloc(sizeof(struct complex_t) * N);
int k, n;
for(k = 0; k < N; k++) {
X[k].re = 0.0;
X[k].im = 0.0;
for(n = 0; n < N; n++) {
X[k] = add(X[k], multiply(x[n], conv_from_polar(1, -2*PI*n*k/N)));
}
}
return X;
}
/** Implements the Good-Thomas FFT algorithm.
*
* @expects: N1 and N2 must be relatively prime
* @expects: N1*N2 = N
*/
complex* FFT_GoodThomas(complex* input, int N, int N1, int N2) {
int k1, k2, z;
/* Allocate columnwise matrix */
complex** columns = (complex**) malloc(sizeof(struct complex_t*) * N1);
for(k1 = 0; k1 < N1; k1++) {
columns[k1] = (complex*) malloc(sizeof(struct complex_t) * N2);
}
/* Allocate rowwise matrix */
complex** rows = (complex**) malloc(sizeof(struct complex_t*) * N2);
for(k2 = 0; k2 < N2; k2++) {
rows[k2] = (complex*) malloc(sizeof(struct complex_t) * N1);
}
/* Reshape input into N1 columns (Using Good-Thomas Indexing) */
for(z = 0; z < 30; z++) {
k1 = z % N1;
k2 = z % N2;
columns[k1][k2] = input[z];
}
/* Compute N1 DFTs of length N2 using naive method */
for (k1 = 0; k1 < N1; k1++) {
columns[k1] = DFT_naive(columns[k1], N2);
}
/* Transpose */
for(k1 = 0; k1 < N1; k1++) {
for (k2 = 0; k2 < N2; k2++) {
rows[k2][k1] = columns[k1][k2];
}
}
/* Compute N2 DFTs of length N1 using naive method */
for (k2 = 0; k2 < N2; k2++) {
rows[k2] = DFT_naive(rows[k2], N1);
}
/* Flatten into single output (Using chinese remainder theorem) */
complex* output = (complex*) malloc(sizeof(struct complex_t) * N);
for(k1 = 0; k1 < N1; k1++) {
for (k2 = 0; k2 < N2; k2++) {
z = N1*k2 + N2*k1;
output[z%N] = rows[k2][k1];
}
}
/* Free all alocated memory except output and input arrays */
for(k1 = 0; k1 < N1; k1++) {
free(columns[k1]);
}
for(k2 = 0; k2 < N2; k2++) {
free(rows[k2]);
}
free(columns);
free(rows);
return output;
}
/** Implements the Cooley-Tukey FFT algorithm.
*
* @expects: N1*N2 = N
*/
complex* FFT_CooleyTukey(complex* input, int N, int N1, int N2) {
int k1, k2;
/* Allocate columnwise matrix */
complex** columns = (complex**) malloc(sizeof(struct complex_t*) * N1);
for(k1 = 0; k1 < N1; k1++) {
columns[k1] = (complex*) malloc(sizeof(struct complex_t) * N2);
}
/* Allocate rowwise matrix */
complex** rows = (complex**) malloc(sizeof(struct complex_t*) * N2);
for(k2 = 0; k2 < N2; k2++) {
rows[k2] = (complex*) malloc(sizeof(struct complex_t) * N1);
}
/* Reshape input into N1 columns */
for (k1 = 0; k1 < N1; k1++) {
for(k2 = 0; k2 < N2; k2++) {
columns[k1][k2] = input[N1*k2 + k1];
}
}
/* Compute N1 DFTs of length N2 using naive method */
for (k1 = 0; k1 < N1; k1++) {
columns[k1] = DFT_naive(columns[k1], N2);
}
/* Multiply by the twiddle factors ( e^(-2*pi*j/N * k1*k2)) and transpose */
for(k1 = 0; k1 < N1; k1++) {
for (k2 = 0; k2 < N2; k2++) {
rows[k2][k1] = multiply(conv_from_polar(1, -2.0*PI*k1*k2/N), columns[k1][k2]);
}
}
/* Compute N2 DFTs of length N1 using naive method */
for (k2 = 0; k2 < N2; k2++) {
rows[k2] = DFT_naive(rows[k2], N1);
}
/* Flatten into single output */
complex* output = (complex*) malloc(sizeof(struct complex_t) * N);
for(k1 = 0; k1 < N1; k1++) {
for (k2 = 0; k2 < N2; k2++) {
output[N2*k1 + k2] = rows[k2][k1];
}
}
/* Free all alocated memory except output and input arrays */
for(k1 = 0; k1 < N1; k1++) {
free(columns[k1]);
}
for(k2 = 0; k2 < N2; k2++) {
free(rows[k2]);
}
free(columns);
free(rows);
return output;
}

5
src/fft.h Normal file
View File

@ -0,0 +1,5 @@
#include "complex.h"
complex* FFT_CooleyTukey(complex* x, int N, int N1, int N2);
complex* FFT_GoodThomas(complex* x, int N, int N1, int N2);
complex* DFT_naive(complex* x, int N);

BIN
src/fft.o Normal file

Binary file not shown.

View File

@ -213,7 +213,7 @@ uint32_t usr_in_proc_data(uint32_t* data, uint32_t size) {
uint8_t header = (uint8_t)(word >> 24);
if (header == 0x00){ //digital_channel. switches LFSM state machine
DY_SYN_2_value_prev = DY_SYN_2_value;
if (word & 0b1 << 17){
if (word & (0b1 << 17)){
DY_SYN_2_value = 1;
}else{
DY_SYN_2_value = 0;
@ -224,8 +224,9 @@ uint32_t usr_in_proc_data(uint32_t* data, uint32_t size) {
Proc_state.average_N ++;
Proc_state.AVG_buff_I = 0;
Proc_state.LFSM_state = CYCLE_STARTED;
//if (Proc_state.average_N >= Proc_state.average_N_max){ //whole average ended
if (1){
if (Proc_state.average_N >= Proc_state.average_N_max){ //whole average ended
Proc_state.average_N = 0;
//if (1){
Proc_state.AVG_state = FULLY_COMPLETED;
//averaging completed => copy average results to TX_buff and start avg again
TX_buff_I = 0;
@ -243,7 +244,7 @@ uint32_t usr_in_proc_data(uint32_t* data, uint32_t size) {
}
TX_buff_state = TODO_TX;
/*
for (uint32_t i = 0; i < TX_BUFF_SIZE; ++i){
TX_buff_shadow[i] = TX_buff[i];
}
@ -254,7 +255,7 @@ uint32_t usr_in_proc_data(uint32_t* data, uint32_t size) {
// hdma_send_req_start(TX_buff, TX_BUFF_SIZE, 0);
//TX_buff_state = TRANSMITTING;
TX_buff_state = TX_DONE;
*/
}else{ //
Proc_state.AVG_state = STEP_RUNNING;
@ -269,8 +270,9 @@ uint32_t usr_in_proc_data(uint32_t* data, uint32_t size) {
if (1){
if (1){
// AVG_buff[Proc_state.AVG_buff_I++] = 0xC0000000 | (0x00FFFFFF & (AVG_buff[Proc_state.AVG_buff_I] + val));
AVG_buff[Proc_state.AVG_buff_I++] = 0xC0000000 | val;
AVG_buff[Proc_state.AVG_buff_I] = 0xC0000000 | ((val + AVG_buff[Proc_state.AVG_buff_I]) & 0xFFFFFF);
//AVG_buff[Proc_state.AVG_buff_I++] = 0xC0000000;
Proc_state.AVG_buff_I++;
if (Proc_state.AVG_buff_I >= AVG_BUFF_SIZE){
Proc_state.AVG_state = STEP_COMPLETED;
}
@ -839,7 +841,7 @@ void usr_cmd_process(t_l502_bf_cmd *cmd) {
Proc_state.mode = AVG;
Proc_state.mode_next = AVG;
Proc_state.LFSM_state = CYCLE_UNKNOWN;
Proc_state.average_N_max = 3;
Proc_state.average_N_max = 30;
// Proc_state.average_N_max = cmd->param;
Proc_state.average_N = 0;
Proc_state.TX_buff_I = 0;