23 Commits

Author SHA1 Message Date
awe
4eb2da17ab data path upd 2025-12-04 18:48:10 +03:00
awe
c8dd8553ba add firmware file 2025-12-04 16:21:24 +03:00
awe
21038c1f8e gitignore upd 2025-12-04 16:21:06 +03:00
awe
11cf03910b remobe build from git 2025-12-04 16:20:33 +03:00
awe
613fdb998f gitignore upd 2025-12-04 16:19:59 +03:00
awe
d0578a0c0d remove build files 2025-12-04 16:19:41 +03:00
d979f45179 implemented cleanup of streams every 10 run. Now it works stable and fast. Next step -- adjust runs_since_streams_clean max value 2025-11-14 02:03:37 +03:00
a726babc1c implemented BF mode switching 2025-11-14 00:18:15 +03:00
4e2d8d4b22 examples of cmd files. If it is provided via CLI arg -- it sets run mode 2025-11-13 22:49:51 +03:00
bec5e29e2c implemented atomary writing to the output files (by creating tmp file and renaming it). 2025-11-13 22:47:40 +03:00
a1c727c71f now chart is saved before showing. Because showing may be long 2025-11-13 22:45:41 +03:00
9ad09ee77b uncommented chart.show() at the end 2025-11-13 22:30:41 +03:00
87954d40d9 now path to data storage is configurable by .cmd file 2025-11-13 22:30:17 +03:00
e2eac4dd48 implemented configuring at startup via cfg file. Implemented RUN_FINITE, RUN_INFINITE, RUN_TEST modes. 2025-11-13 21:36:49 +03:00
850a66e620 compiles 2025-11-13 21:00:42 +03:00
d1bd233399 removed old unacessible code from the end. Implemented main_state struct, filling it from the CLI arg file. Also implemented FINITE_RUNS mode. 2025-11-13 20:55:53 +03:00
b7eae9d469 cleaned more unused code (by codex) 2025-11-13 19:31:56 +03:00
b80ad585da moved libs to the lib directory 2025-11-13 18:40:06 +03:00
4d1f7fdbe9 added run_cyclic script. It mounts tmpfs in ./tmp, runs BF_companion for some cycles, cleans ./tmp 2025-11-13 18:22:38 +03:00
a44043593c deleted unused funcs and commented outdated code 2025-11-13 18:20:19 +03:00
b7ba42765b manually merged with ARM version 2025-11-13 17:43:55 +03:00
77005d7863 included SDK folder and included it to the git three 2025-10-30 21:53:19 +03:00
bf25bed9aa just save 2025-10-30 19:57:30 +03:00
33 changed files with 516 additions and 317 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.csv
*.tmp
build
BF_companion

9
1000sec_finite.cmd Normal file
View File

@ -0,0 +1,9 @@
// Default configuration for BF_companion main_state
// Format: field value // optional comment
run_mode FINITE_RUN // TEST | FINITE_RUN | INF_RUN
BF_mode TRANSPARENT // TRANSPARENT | AVG
run_length 100 // milliseconds
runs_N 10000 // total runs (used in FINITE_RUN)
run_I 0 // starting run index
data_path /home/feda/MIPT/RadioPhotonic_Subserface_radar/Receiver_GUI/data // base directory for output files

9
100sec_finite.cmd Normal file
View File

@ -0,0 +1,9 @@
// Default configuration for BF_companion main_state
// Format: field value // optional comment
run_mode FINITE_RUN // TEST | FINITE_RUN | INF_RUN
BF_mode TRANSPARENT // TRANSPARENT | AVG
run_length 100 // milliseconds
runs_N 1000 // total runs (used in FINITE_RUN)
run_I 0 // starting run index
data_path /home/feda/MIPT/RadioPhotonic_Subserface_radar/Receiver_GUI/data // base directory for output files

Binary file not shown.

Binary file not shown.

10
default.cmd Normal file
View File

@ -0,0 +1,10 @@
// Default configuration for BF_companion main_state
// Format: field value // optional comment
run_mode TEST // TEST | FINITE_RUN | INF_RUN
BF_mode TRANSPARENT // TRANSPARENT | AVG
BlackFin_mode TRANSPARENT // TRANSPARENT | AVG | FFT
run_length 100 // milliseconds
runs_N 10 // total runs (used in FINITE_RUN)
run_I 0 // starting run index
data_path data // base directory for output files

9
finite.cmd Normal file
View File

@ -0,0 +1,9 @@
// Default configuration for BF_companion main_state
// Format: field value // optional comment
run_mode FINITE_RUN // TEST | FINITE_RUN | INF_RUN
BF_mode TRANSPARENT // TRANSPARENT | AVG
run_length 100 // milliseconds
runs_N 10 // total runs (used in FINITE_RUN)
run_I 0 // starting run index
data_path /home/feda/MIPT/RadioPhotonic_Subserface_radar/Receiver_GUI/data // base directory for output files

View File

@ -1 +0,0 @@
../BFfirmware_0/build/release/bin/l502-BFfirmware0.ldr

BIN
l502-BFfirmware0.ldr Normal file

Binary file not shown.

10
long_trace_AVG_RPI.cmd Normal file
View File

@ -0,0 +1,10 @@
// Default configuration for BF_companion main_state
// Format: field value // optional comment
run_mode INF_RUN // TEST | FINITE_RUN | INF_RUN
BF_mode FFT // TRANSPARENT | AVG | FFT
run_length 50 // milliseconds
runs_N 1000 // total runs (used in FINITE_RUN)
run_I 0 // starting run index
//data_path /home/feda/MIPT/RadioPhotonic_Subserface_radar/Receiver_GUI/data // base directory for output files
data_path tmp

709
main.c
View File

@ -68,21 +68,21 @@
#include "l502_fpga_regs.h" #include "l502_fpga_regs.h"
/* Remove unused enums/structs and constants that are not referenced anywhere */ /* Remove unused enums/structs and constants that are not referenced anywhere */
// количество используемых логических каналов // // количество используемых логических каналов //
#define ADC_LCH_CNT 1 #define ADC_LCH_CNT 1
/* Unused frequency/timing defines removed */ /* Unused frequency/timing defines removed */
// сколько отсчетов считываем за блок // // сколько отсчетов считываем за блок //
#define READ_BLOCK_SIZE 4096*200 #define READ_BLOCK_SIZE 4096*200
// таймаут на прием блока (мс) // // таймаут на прием блока (мс) //
#define READ_TIMEOUT 2000 #define READ_TIMEOUT 2000
/* Unused BF user command define removed */ /* Unused BF user command define removed */
// номера используемых физических каналов // // номера используемых физических каналов //
@ -125,7 +125,7 @@ static uint32_t f_ch_ranges[ADC_LCH_CNT] = {X502_ADC_RANGE_02, X502_ADC_RANGE_5,
// признак необходимости завершить сбор данных // // признак необходимости завершить сбор данных //
static int f_out = 0; static int f_out = 0;
#ifndef _WIN32 #ifndef _WIN32
// Обработчик сигнала завершения для Linux // // Обработчик сигнала завершения для Linux //
@ -143,7 +143,123 @@ typedef struct {
} ip_dev_list_t; } ip_dev_list_t;
/* Unused SIGINT handler and flag removed */ typedef enum {
RUN_MODE_TEST = 0,
RUN_MODE_FINITE = 1,
RUN_MODE_INF = 2
} run_mode_t;
typedef enum {
BF_MODE_TRANSPARENT = 0,
BF_MODE_AVG = 1,
BF_MODE_FFT = 2
} bf_mode_t;
typedef enum {
BFMODE_TRANSPARENT = 0,
BFMODE_AVG = 1,
BFMODE_FFT = 2
} blackfin_mode_t;
typedef struct main_state_typedef{
run_mode_t run_mode; // TEST, FINITE_RUN, INF_RUN
bf_mode_t BF_mode; // TRANSPARENT, AVG
blackfin_mode_t BlackFin_mode; // TRANSPARENT, AVG, FFT
uint32_t run_length; // in ms. Used as timeout for receive_to_file
uint32_t run_I; // № current run
uint32_t runs_N; // total number of runs
char data_path[200]; // base directory for data files
} main_state;
static void main_state_set_defaults(main_state* st) {
st->run_mode = RUN_MODE_TEST;
st->BF_mode = BF_MODE_TRANSPARENT;
st->BlackFin_mode = BFMODE_TRANSPARENT;
st->run_length = 1000;
st->run_I = 0;
st->runs_N = 1;
strncpy(st->data_path, "data", sizeof(st->data_path));
st->data_path[sizeof(st->data_path)-1] = '\0';
}
static char* f_trim(char* s) {
char* end;
while (*s==' ' || *s=='\t' || *s=='\r' || *s=='\n') s++;
if (*s == 0) return s;
end = s + strlen(s) - 1;
while (end > s && (*end==' ' || *end=='\t' || *end=='\r' || *end=='\n')) end--;
end[1] = '\0';
return s;
}
static void parse_cmd_file(const char* filename, main_state* st) {
FILE* f = fopen(filename, "r");
if (f == NULL) {
printf("Command file '%s' not found. Using defaults.\n", filename);
return;
}
char line[512];
while (fgets(line, sizeof(line), f)) {
char* p = line;
char* comment = strstr(p, "//");
if (comment) *comment = '\0';
p = f_trim(p);
if (*p == '\0') continue;
char* field = strtok(p, "\t \r\n");
char* value = strtok(NULL, "\t \r\n");
if (!field || !value) continue;
if (strcmp(field, "run_mode") == 0) {
if (strcmp(value, "FINITE_RUN") == 0) {
st->run_mode = RUN_MODE_FINITE;
} else if (strcmp(value, "INF_RUN") == 0) {
st->run_mode = RUN_MODE_INF;
} else if (strcmp(value, "TEST") == 0) {
st->run_mode = RUN_MODE_TEST;
} else {
st->run_mode = RUN_MODE_TEST; // default on mismatch
}
} else if (strcmp(field, "BF_mode") == 0) {
if (strcmp(value, "TRANSPARENT") == 0) {
st->BF_mode = BF_MODE_TRANSPARENT;
} else if (strcmp(value, "AVG") == 0) {
st->BF_mode = BF_MODE_AVG;
} else if (strcmp(value, "FFT") == 0) {
st->BF_mode = BF_MODE_FFT;
} else {
st->BF_mode = BF_MODE_TRANSPARENT; // default on mismatch
}
} else if (strcmp(field, "BlackFin_mode") == 0) {
if (strcmp(value, "TRANSPARENT") == 0) {
st->BlackFin_mode = BFMODE_TRANSPARENT;
} else if (strcmp(value, "AVG") == 0) {
st->BlackFin_mode = BFMODE_AVG;
} else if (strcmp(value, "FFT") == 0) {
st->BlackFin_mode = BFMODE_FFT;
} else {
st->BlackFin_mode = BFMODE_TRANSPARENT; // default on mismatch
}
} else if (strcmp(field, "run_length") == 0) {
char* endp = NULL;
unsigned long v = strtoul(value, &endp, 0);
if (endp != value) st->run_length = (uint32_t)v;
} else if (strcmp(field, "runs_N") == 0) {
char* endp = NULL;
unsigned long v = strtoul(value, &endp, 0);
if (endp != value) st->runs_N = (uint32_t)v;
} else if (strcmp(field, "run_I") == 0) {
char* endp = NULL;
unsigned long v = strtoul(value, &endp, 0);
if (endp != value) st->run_I = (uint32_t)v;
} else if (strcmp(field, "data_path") == 0) {
strncpy(st->data_path, value, sizeof(st->data_path));
st->data_path[sizeof(st->data_path)-1] = '\0';
}
}
fclose(f);
}
/* Unused SIGINT handler and flag removed */
/* Функция находит все подключенные модули по интерфейсам PCI-Express и USB и /* Функция находит все подключенные модули по интерфейсам PCI-Express и USB и
@ -578,55 +694,107 @@ void insert_marker_to_file(char* logfilename, char* marker_text){
fclose(logfile_ptr); fclose(logfile_ptr);
} }
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words){
FILE* logfile_ptr = fopen(logfilename, "a");
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words, uint32_t timeout){
// fprintf(logfile_ptr, "0xFF00000 \n"); // fprintf(logfile_ptr, "0xFF00000 \n");
// fprintf(logfile_ptr, "0xFFFFFFF \n"); // fprintf(logfile_ptr, "0xFFFFFFF \n");
// fprintf(logfile_ptr, "0xFF00000 \n"); // fprintf(logfile_ptr, "0xFF00000 \n");
uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, 20000); // uint32_t timeout = 100;
int32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, timeout);
printf("receive code: %d\n", recv_Err_code);
if (recv_Err_code > 0){ if (recv_Err_code > 0){
uint32_t received_words = recv_Err_code; char logfilename_tmp[300];
for (uint32_t word_I = 0; word_I < received_words; word_I ++){ snprintf(logfilename_tmp, sizeof(logfilename_tmp), "%s.tmp", logfilename);
printf("tmp file: %s ",logfilename_tmp);
FILE* logfile_ptr = fopen(logfilename_tmp, "a");
//uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, 20000);
uint32_t received_words = recv_Err_code;
for (uint32_t word_I = 0; word_I < received_words; word_I ++){
//printf("%06d 0x%08X\n", word_I, inp_buff[word_I]); //printf("%06d 0x%08X\n", word_I, inp_buff[word_I]);
fprintf(logfile_ptr, "0x%08X \n", inp_buff[word_I]); fprintf(logfile_ptr, "0x%08X \n", inp_buff[word_I]);
} }
printf("received %ld words\n", received_words); printf("received %ld words\n", received_words);
fclose(logfile_ptr);
rename(logfilename_tmp, logfilename);
}else if (recv_Err_code == 0){
printf("no data received. timeout\n");
}else{ }else{
printf("receive error: %d\n======================\n", recv_Err_code); sleep(1);
printf("receive error: %d\n======================\n", recv_Err_code);
} }
fclose(logfile_ptr);
} }
/*
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words, uint32_t timeout){
char logfilename_tmp[300];
snprintf(logfilename_tmp, sizeof(logfilename_tmp), "%s.tmp", logfilename);
printf("tmp file: %s ",logfilename_tmp);
FILE* logfile_ptr = fopen(logfilename_tmp, "a");
// fprintf(logfile_ptr, "0xFF00000 \n");
// fprintf(logfile_ptr, "0xFFFFFFF \n");
// fprintf(logfile_ptr, "0xFF00000 \n");
// uint32_t timeout = 100;
uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, timeout);
//uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, 20000);
if (recv_Err_code > 0){
uint32_t received_words = recv_Err_code;
for (uint32_t word_I = 0; word_I < received_words; word_I ++){
//printf("%06d 0x%08X\n", word_I, inp_buff[word_I]);
fprintf(logfile_ptr, "0x%08X \n", inp_buff[word_I]);
}
printf("received %ld words\n", received_words);
}else{
printf("receive error: %d\n======================\n", recv_Err_code);
}
fclose(logfile_ptr);
rename(logfilename_tmp, logfilename);
}
*/
int main(int argc, char** argv) {
int main(int argc, char** argv) {
int32_t err = X502_ERR_OK; int32_t err = X502_ERR_OK;
uint32_t ver; uint32_t ver;
t_x502_hnd hnd = NULL; t_x502_hnd hnd = NULL;
#ifndef _WIN32
struct sigaction sa;
memset(&sa, 0, sizeof(sa)); // читаем имя командного файла из аргументов CLI
// В ОС Linux устанавливаем свой обработчик на сигнал закрытия, const char* cmd_filename = "default.cmd";
// чтобы завершить сбор корректно // if (argc > 1 && argv[1] != NULL && argv[1][0] != '\0') {
sa.sa_handler = f_abort_handler; cmd_filename = argv[1];
sigaction(SIGTERM, &sa, NULL); }
sigaction(SIGINT, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
#endif
#ifdef _WIN32
// для вывода русских букв в консоль для ОС Windows в CP1251 без перевода в OEM //
setlocale(LC_CTYPE, "");
#endif
// получаем версию библиотеки // // получаем версию библиотеки //
ver = X502_GetLibraryVersion(); ver = X502_GetLibraryVersion();
printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF); printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
printf("Command file: %s\n", cmd_filename);
/* Removed unused temporary buffers and FFT/LFSM placeholders */ // загружаем состояние из командного файла
main_state state;
main_state_set_defaults(&state);
parse_cmd_file(cmd_filename, &state);
// отладочный вывод принятых значений
printf("Parsed state: run_mode=%d, BF_mode=%d, BlackFin_mode=%d, run_length=%u, runs_N=%u, run_I=%u, data_path=%s\n",
(int)state.run_mode, (int)state.BF_mode, (int)state.BlackFin_mode,
state.run_length, state.runs_N, state.run_I, state.data_path);
/* Removed unused temporary buffers and FFT/LFSM placeholders */
@ -696,11 +864,9 @@ int main(int argc, char** argv) {
} }
printf("\n\n\n"); printf("\n\n\n");
//setup ADC:
/* Removed unused TX data buffer */
//setup ADC:
@ -712,85 +878,182 @@ int main(int argc, char** argv) {
printf("Streams start err: %d \n", streams_start_Err); printf("Streams start err: %d \n", streams_start_Err);
time_t seconds; if (state.run_mode == RUN_MODE_FINITE){
time(&seconds); if (state.BF_mode == BF_MODE_TRANSPARENT){
char logfilename[] = " "; printf("\nStart transparent mode\n");
sprintf(&logfilename, "data/received_data_%ld.csv", seconds); BF_exec_cmd_simple(hnd, 0x8007, 10, 1); //start transparent
//logfile_ptr = fopen(logfilename, "w"); }else if(state.BF_mode == BF_MODE_FFT){
FILE *logfile_ptr; printf("\nStart FFt mode\n");
logfile_ptr = fopen(logfilename, "a"); BF_exec_cmd_simple(hnd, 0x8008, 2, 1); //start averaging
}else if(state.BF_mode == BF_MODE_AVG){
printf("\nStart AVG mode\n");
BF_exec_cmd_simple(hnd, 0x8009, 2, 1); //start averaging
}
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
// for(uint32_t wait_i = 1e6; wait_i; --wait_i){;}
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
state.run_I = 0;
char tmp_data_filename[256];
struct timespec ts;
uint32_t max_total_words = 1000000;
uint32_t *inp_buff = malloc(1024*100*1024*2*4);
uint32_t runs_since_streams_clean = 0;
while(state.run_I < state.runs_N){
max_total_words = 10000000;
timespec_get(&ts, TIME_UTC);
// sprintf(&tmp_data_filename, "tmp/received_data_%ld.%ld.csv", ts.tv_sec, ts.tv_nsec);
// sprintf(&logfilename, "tmp/received_data_%ld.%ld.csv", ts.tv_sec, ts.tv_nsec);
//sprintf(&logfilename, "data/received_data_%ld.csv", seconds);
snprintf(tmp_data_filename, sizeof(tmp_data_filename), "%s/received_data_%ld.%ld.csv", state.data_path, ts.tv_sec, ts.tv_nsec);
printf("%u/%u dumping to file: %s\n", (unsigned)state.run_I, (unsigned)state.runs_N, tmp_data_filename);
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length);
if (runs_since_streams_clean >= 10){
runs_since_streams_clean = 0;
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
}
state.run_I++;
runs_since_streams_clean++; }
free(inp_buff);
X502_Close(hnd);
// освобождаем описатель
X502_Free(hnd);
return 0;
}else if (state.run_mode == RUN_MODE_INF){
if (state.BF_mode == BF_MODE_TRANSPARENT){
printf("\nStart transparent mode\n");
BF_exec_cmd_simple(hnd, 0x8007, 10, 1); //start transparent
}else if(state.BF_mode == BF_MODE_FFT){
printf("\nStart FFt mode\n");
BF_exec_cmd_simple(hnd, 0x8008, 2, 1); //start averaging
}else if(state.BF_mode == BF_MODE_AVG){
printf("\nStart AVG mode\n");
BF_exec_cmd_simple(hnd, 0x8009, 2, 1); //start averaging
}
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
// for(uint32_t wait_i = 1e6; wait_i; --wait_i){;}
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
state.run_I = 0;
char tmp_data_filename[256];
struct timespec ts;
uint32_t max_total_words = 10000000;
uint32_t *inp_buff = malloc(1024*100*1024*2*4);
uint32_t runs_since_streams_clean = 0;
while (1){ //should be infinite. because it is RUN_MODE_INF
//while(state.run_I < state.runs_N){
max_total_words = 10000000;
timespec_get(&ts, TIME_UTC);
// sprintf(&tmp_data_filename, "tmp/received_data_%ld.%ld.csv", ts.tv_sec, ts.tv_nsec);
// sprintf(&logfilename, "tmp/received_data_%ld.%ld.csv", ts.tv_sec, ts.tv_nsec);
//sprintf(&logfilename, "data/received_data_%ld.csv", seconds);
snprintf(tmp_data_filename, sizeof(tmp_data_filename), "%s/received_data_%ld.%ld.csv", state.data_path, ts.tv_sec, ts.tv_nsec);
printf("%u dumping to file: %s\n", (unsigned)state.run_I, tmp_data_filename);
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length);
if (runs_since_streams_clean >= 10){
runs_since_streams_clean = 0;
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
}
state.run_I++;
runs_since_streams_clean++;
}
free(inp_buff);
X502_Close(hnd);
// освобождаем описатель
X502_Free(hnd);
return 0;
fprintf(logfile_ptr, "sync_frec_source: %d \nsync_start_source: %d \n", SYNC_FREC_SOURCE, SYNC_START_SOURCE); }else{ //TEST mode as default
for (int chan_I = 0; chan_I < ADC_LCH_CNT; chan_I++){
fprintf(logfile_ptr, "chan: %d, mode: %d, range: %d \n", chan_I, f_ch_modes[chan_I], f_ch_ranges[chan_I]);
}
fclose(logfile_ptr);
// printf("dumping to file: %s\n", logfilename);
printf("\n"); time_t seconds;
//printf("start streams sampling\n"); time(&seconds);
//BF_exec_cmd_with_arr(hnd, 0x8004U, 0, NULL, 0, 1); //setup and start streams char logfilename[256];
snprintf(logfilename, sizeof(logfilename), "%s/received_data_%ld.csv", state.data_path, (long)seconds);
//logfile_ptr = fopen(logfilename, "w");
FILE *logfile_ptr;
logfile_ptr = fopen(logfilename, "a");
fprintf(logfile_ptr, "sync_frec_source: %d \nsync_start_source: %d \n", SYNC_FREC_SOURCE, SYNC_START_SOURCE);
for (int chan_I = 0; chan_I < ADC_LCH_CNT; chan_I++){
fprintf(logfile_ptr, "chan: %d, mode: %d, range: %d \n", chan_I, f_ch_modes[chan_I], f_ch_ranges[chan_I]);
}
fclose(logfile_ptr);
uint32_t waiting_cnt = 1;
waiting_cnt = 100000;
printf("\nwaiting %d ...", waiting_cnt);
while(--waiting_cnt){;}
//for(uint32_t timeout = 100000000; timeout; --timeout){;}
printf("done\n");
printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n"); // printf("dumping to file: %s\n", logfilename);
BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
printf("\n");
//printf("start streams sampling\n");
//BF_exec_cmd_with_arr(hnd, 0x8004U, 0, NULL, 0, 1); //setup and start streams
// printf("\n\nget a some data made by sport isr handler\n");
// BF_exec_cmd_with_arr(hnd, 0x8006U, 100, NULL, 0, 1);
//BF_exec_cmd_with_arr(hnd, 0x8006U, 100, NULL, 0, 3);
uint32_t *inp_buff = malloc(1024*100*1024*2*4); uint32_t waiting_cnt = 1;
double *adc_data = malloc(1024*1024*sizeof(double)); waiting_cnt = 100000;
//uint32_t inp_buff[1024*2048] = {0,}; printf("\nwaiting %d ...", waiting_cnt);
/* Removed unused counters */ while(--waiting_cnt){;}
//for(uint32_t timeout = 100000000; timeout; --timeout){;}
printf("done\n");
printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n");
BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
insert_marker_to_file(logfilename, "start transparent");
printf("\nStart transparent mode\n"); // printf("\n\nget a some data made by sport isr handler\n");
BF_exec_cmd_simple(hnd, 0x8007, 10, 1); //start transparent // BF_exec_cmd_with_arr(hnd, 0x8006U, 100, NULL, 0, 1);
//BF_exec_cmd_with_arr(hnd, 0x8006U, 100, NULL, 0, 3);
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
printf("receiving data...\n"); uint32_t *inp_buff = malloc(1024*100*1024*2*4);
double *adc_data = malloc(1024*1024*sizeof(double));
//uint32_t inp_buff[1024*2048] = {0,};
/* Removed unused counters */
/* Removed unused readiness checks */ insert_marker_to_file(logfilename, "start transparent");
uint32_t max_total_words = 100000; printf("\nStart transparent mode\n");
/* Removed unused data_receive_trys_counter */ BF_exec_cmd_simple(hnd, 0x8007, 10, 1); //start transparent
// printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
// BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
receive_to_file(hnd, logfilename, inp_buff, max_total_words); printf("receiving data...\n");
printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n"); /* Removed unused readiness checks */
BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
uint32_t max_total_words = 100000;
/* Removed unused data_receive_trys_counter */
// printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
// BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
// receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
//*
printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n");
BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
//*
@ -799,284 +1062,104 @@ int main(int argc, char** argv) {
insert_marker_to_file(logfilename, "start AVG");
printf("\nStart AVG mode\n");
BF_exec_cmd_simple(hnd, 0x8008, 2, 1); //start averaging
// printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
// BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
// for(uint32_t wait_i = 1e6; wait_i; --wait_i){;} insert_marker_to_file(logfilename, "start AVG");
printf("\nStart AVG mode\n");
BF_exec_cmd_simple(hnd, 0x8008, 2, 1); //start averaging
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
// printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
// BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
// printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n"); // for(uint32_t wait_i = 1e6; wait_i; --wait_i){;}
// BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
//fprintf(logfile_ptr, "value number; time, sec; adc_value, V\n");
max_total_words = 100000;
//printf("\n dbg value: "); // printf("\n\nget counters of calls of SPORT_RX, SPORT_TX, HDMA_RX, HDMA_TX\n");
//BF_exec_cmd_simple(hnd, 0x800A, 10, 1); // BF_exec_cmd_with_arr(hnd, 0x8005U, 100, NULL, 0, 1);
struct timespec time_receive_started, time_receive_ended;
clock_gettime(CLOCK_MONOTONIC, &time_receive_started); //fprintf(logfile_ptr, "value number; time, sec; adc_value, V\n");
receive_to_file(hnd, logfilename, inp_buff, max_total_words);
clock_gettime(CLOCK_MONOTONIC, &time_receive_ended);
double receive_time = (time_receive_ended.tv_sec - time_receive_started.tv_sec); max_total_words = 100000;
receive_time += time_receive_ended.tv_nsec*1e-9;
receive_time += time_receive_started.tv_nsec*1e-9;
//printf("\n dbg value: ");
//BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
printf("\n Receive time: %g, %g sec/value \n", receive_time, receive_time/max_total_words); struct timespec time_receive_started, time_receive_ended;
clock_gettime(CLOCK_MONOTONIC, &time_receive_started);
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
clock_gettime(CLOCK_MONOTONIC, &time_receive_ended);
double receive_time = (time_receive_ended.tv_sec - time_receive_started.tv_sec);
receive_time += time_receive_ended.tv_nsec*1e-9;
receive_time += time_receive_started.tv_nsec*1e-9;
printf("\n Receive time: %g, %g sec/value \n", receive_time, receive_time/max_total_words);
insert_marker_to_file(logfilename, "start transparent");
printf("\nStart transparent mode\n");
BF_exec_cmd_simple(hnd, 0x8007, 2, 1); //start transparent
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
// printf("\n dbg value: "); insert_marker_to_file(logfilename, "start transparent");
// BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
receive_to_file(hnd, logfilename, inp_buff, max_total_words);
printf("\n dbg value: ");
BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
//*/ printf("\nStart transparent mode\n");
BF_exec_cmd_simple(hnd, 0x8007, 2, 1); //start transparent
X502_StreamsStop(hnd);
X502_StreamsStart(hnd);
printf("\nflush TX buff. \n Number of free TX descriptors before flushing:");
BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
printf("\nFlushed from receiving buff: %d\n", X502_FlushRcv_buff(hnd));
printf("\n\nreceive done. Exiting...\n\n\n"); // printf("\n dbg value: ");
//logfile_ptr = fopen(logfilename, "w"); // BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
printf("dumped to file: %s\n", logfilename); receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
fprintf(stderr, "%s\n", logfilename); printf("\n dbg value: ");
BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
X502_Close(hnd); //*/
// освобождаем описатель
X502_Free(hnd);
return 0;
printf("\n\nreceive done. Exiting...\n\n\n");
//logfile_ptr = fopen(logfilename, "w");
printf("dumped to file: %s\n", logfilename);
fprintf(stderr, "%s\n", logfilename);
X502_Close(hnd);
// освобождаем описатель
X502_Free(hnd);
return 0;
}
f_out = 1;
struct timespec time_started;
struct timespec time_ended;
timespec_get(&time_started, TIME_UTC);
float total_runs = 0.0;
long double delta_time = 0.0;
while(f_out != 1){
total_runs += 1.0;
X502_StreamsStart(hnd); //wait for trigger and start sampling
int32_t rcv_size;
uint32_t adc_size, din_size;
// массив для приема необработанных данных //
static uint32_t rcv_buf[READ_BLOCK_SIZE];
static double adc_data[READ_BLOCK_SIZE];
static uint32_t din_data[READ_BLOCK_SIZE];
// принимаем данные (по таймауту) //
rcv_size = X502_Recv(hnd, rcv_buf, READ_BLOCK_SIZE, READ_TIMEOUT);
timespec_get(&time_ended, TIME_UTC);
// результат меньше нуля означает ошибку //
if (rcv_size < 0) {
err = rcv_size;
fprintf(stderr, "Ошибка приема данных: %s\n", X502_GetErrorString(err));
} else if (rcv_size > 0) {
uint32_t first_lch;
// получаем номер логического канала, которому соответствует первый отсчет АЦП в массиве //
X502_GetNextExpectedLchNum(hnd, &first_lch);
adc_size = sizeof(adc_data)/sizeof(adc_data[0]);
din_size = sizeof(din_data)/sizeof(din_data[0]);
// обрабатываем принятые данные, распределяя их на данные АЦП и цифровых входов //
err = X502_ProcessData(hnd, rcv_buf, rcv_size, X502_PROC_FLAGS_VOLT,
adc_data, &adc_size, din_data, &din_size);
if (err != X502_ERR_OK) {
fprintf(stderr, "Ошибка обработки данных: %s\n", X502_GetErrorString(err));
} else {
uint32_t lch;
printf("Обработано данных АЦП = %d, цифровых входов = %d\n",
adc_size, din_size);
long double t_started = (long double)time_started.tv_sec + 1e-9*(long double)time_started.tv_nsec;
printf("started at %jd.%09ld or %Lg\n", (intmax_t)time_started.tv_sec, time_started.tv_nsec, t_started);
printf("received at %jd.%09ld \n", (intmax_t)time_ended.tv_sec, time_ended.tv_nsec);
delta_time = ((long double) time_ended.tv_sec - time_started.tv_sec ) + (((long double) time_ended.tv_nsec) * 1e-9 ) - (((long double) time_started.tv_nsec) * 1e-9 );
printf("delta time %Lg sec\n", delta_time);
// если приняли цифровые данные - выводим первый отсчет //
if (din_size != 0)
printf(" din_data = 0x%05X\n", din_data[0]);
// выводим по одному отсчету на канал. если обработанный блок
// начинается не с начала кадра, то в данном примере для
// вывода берем конец неполного кадра и начало следующего
for (lch=0; lch < ADC_LCH_CNT; lch++) {
// определяем позицию первого отсчета, соответствующего заданному логическому каналу:
// либо с конца не полного кадра, либо из начала следующего //
uint32_t pos = lch >= first_lch ? lch - first_lch : ADC_LCH_CNT-first_lch + lch;
if (pos <= adc_size) {
printf(" lch[%d]=%6.4f\n, pos=%d, adc_size=%d", lch, adc_data[pos], pos, adc_size);
time_t seconds;
time(&seconds);
FILE *fptr;
char filename[] = " ";
sprintf(&filename, "adc data %ld.csv", seconds);
fptr = fopen(filename, "w");
fprintf(fptr, "value number; time, sec; adc_value, V\n");
for (uint32_t data_pos; data_pos < adc_size; ++data_pos){
fprintf(fptr, "%d %6.7f %6.7f \n", data_pos, (double)data_pos / X502_REF_FREQ_2000KHZ , adc_data[data_pos]); //print whole data
//printf("%d %6.7f %6.7f \n", data_pos, (double)data_pos / X502_REF_FREQ_2000KHZ , adc_data[data_pos]); //print whole data
}
fclose(fptr);
} else {
printf(" lch[%d]= ---- \n", lch);
}
}
printf("\n");
fflush(stdout);
}
}
X502_StreamsStop(hnd);
/*
xray =
//plot results. plotter code from: https://www.mps.mpg.de/1757268/exa_c#section_1
metafl ("cons");
scrmod ("revers");
disini ();
pagera ();
complx ();
axspos (450, 1800);
axslen (2200, 1200);
name ("X-axis", "x");
name ("Y-axis", "y");
labdig (-1, "x");
ticks (9, "x");
ticks (10, "y");
titlin ("Demonstration of CURVE", 1);
titlin ("SIN(X), COS(X)", 3);
ic = intrgb (0.95,0.95,0.95);
axsbgd (ic);
graf (0.0, 360.0, 0.0, 90.0, -1.0, 1.0, -1.0, 0.5);
setrgb (0.7, 0.7, 0.7);
grid (1, 1);
color ("fore");
height (50);
title ();
color ("red");
curve (xray, y1ray, n);
color ("green");
curve (xray, y2ray, n);
disfin ();
*/
--f_out;
#ifdef _WIN32
/* проверка нажатия клавиши для выхода */
if (err == X502_ERR_OK) {
if (_kbhit())
f_out = 1;
}
#else
{
// по нажатию Enter включаем/выключаем поток ADC
fd_set fds;
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
if (select(1, &fds, NULL, NULL, &tv) == 1) {
static int adc_disabled = 0;
int ch;
if (adc_disabled) {
X502_StreamsEnable(hnd, X502_STREAM_ADC);
} else {
X502_StreamsDisable(hnd, X502_STREAM_ADC);
}
adc_disabled = !adc_disabled;
while(select(1, &fds, NULL, NULL, &tv) == 1) {
read(STDIN_FILENO, &ch, 1);
}
}
}
#endif
}
printf("delta time %Lg sec\n", delta_time);
printf("average run time %Lg sec\n", delta_time/total_runs);
// закрываем связь с модулем
X502_Close(hnd);
// освобождаем описатель
X502_Free(hnd);
} }
return err; return -1;
} }

66
pipe_reader_test.py Executable file
View File

@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""
Test script to read radar data from named pipe (FIFO)
This script demonstrates how to read binary data from the named pipe
created by the radar acquisition program.
"""
import struct
import sys
import os
def read_from_pipe(pipe_path="/tmp/radar_data_pipe"):
"""
Read uint32_t data from named pipe
Args:
pipe_path: Path to the named pipe (FIFO)
"""
print(f"Opening pipe: {pipe_path}")
print("Waiting for radar data...")
try:
# Open pipe for reading (this will block until writer connects)
with open(pipe_path, 'rb') as pipe:
print("Connected to pipe! Reading data...")
word_count = 0
while True:
# Read 4 bytes (one uint32_t)
data = pipe.read(4)
if not data:
print("\nEnd of stream or pipe closed")
break
if len(data) < 4:
print(f"\nWarning: incomplete data read ({len(data)} bytes)")
break
# Unpack as uint32_t (little-endian)
value = struct.unpack('<I', data)[0]
# Print first 10 values and then every 1000th value
if word_count < 10 or word_count % 1000 == 0:
print(f"Word {word_count}: 0x{value:08X} ({value})")
word_count += 1
# Optional: process the data here
# For example, convert to voltage, apply filters, etc.
print(f"\nTotal words received: {word_count}")
except KeyboardInterrupt:
print("\n\nInterrupted by user")
print(f"Total words received: {word_count}")
except FileNotFoundError:
print(f"Error: Pipe {pipe_path} does not exist")
print("Make sure the radar acquisition program is running first")
except Exception as e:
print(f"Error reading from pipe: {e}")
if __name__ == "__main__":
pipe_path = sys.argv[1] if len(sys.argv) > 1 else "/tmp/radar_data_pipe"
read_from_pipe(pipe_path)

View File

@ -105,6 +105,6 @@ if __name__ == "__main__":
#chart.add_trace(go.Scattergl(x=data[key+"_N"], y=data[key], name=key, mode="markers+lines", text=data[key+"_hex"])) #chart.add_trace(go.Scattergl(x=data[key+"_N"], y=data[key], name=key, mode="markers+lines", text=data[key+"_hex"]))
# chart.add_trace(go.Scattergl(x=data[key+"_N"], y=data[key], name=key, mode="lines+markers", text=data[key+"_hex"])) # chart.add_trace(go.Scattergl(x=data[key+"_N"], y=data[key], name=key, mode="lines+markers", text=data[key+"_hex"]))
# chart.show()
chart.write_html(argv[1] + ".html") chart.write_html(argv[1] + ".html")
chart.show()

View File

@ -1,4 +1,3 @@
#!/usr/bin/bash #!/usr/bin/bash
sudo mount -t tmpfs -o size=1G tmpfs tmp # sudo mount -t tmpfs -o size=1G tmpfs tmp
./BF_companion 100 #should generate approx 500 MB of data by running 10 secs ./BF_companion long_trace_AVG_RPI.cmd
rm tmp/*