removed old unacessible code from the end. Implemented main_state struct, filling it from the CLI arg file. Also implemented FINITE_RUNS mode.
This commit is contained in:
346
main.c
346
main.c
@ -143,6 +143,95 @@ typedef struct {
|
||||
} ip_dev_list_t;
|
||||
|
||||
|
||||
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_t;
|
||||
|
||||
typedef struct main_state_typedef{
|
||||
run_mode_t run_mode; // TEST, FINITE_RUN, INF_RUN
|
||||
bf_mode_t BF_mode; // TRANSPARENT, AVG
|
||||
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
|
||||
} main_state;
|
||||
|
||||
static void main_state_set_defaults(main_state* st) {
|
||||
st->run_mode = RUN_MODE_TEST;
|
||||
st->BF_mode = BF_MODE_TRANSPARENT;
|
||||
st->run_length = 1000;
|
||||
st->run_I = 0;
|
||||
st->runs_N = 1;
|
||||
}
|
||||
|
||||
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 {
|
||||
st->BF_mode = BF_MODE_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;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* Unused SIGINT handler and flag removed */
|
||||
|
||||
|
||||
@ -578,23 +667,26 @@ void insert_marker_to_file(char* logfilename, char* marker_text){
|
||||
fclose(logfile_ptr);
|
||||
}
|
||||
|
||||
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words){
|
||||
|
||||
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words, uint32_t timeout){
|
||||
FILE* logfile_ptr = fopen(logfilename, "a");
|
||||
|
||||
// fprintf(logfile_ptr, "0xFF00000 \n");
|
||||
// fprintf(logfile_ptr, "0xFFFFFFF \n");
|
||||
// fprintf(logfile_ptr, "0xFF00000 \n");
|
||||
|
||||
uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, 20000);
|
||||
// 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]);
|
||||
}
|
||||
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);
|
||||
printf("receive error: %d\n======================\n", recv_Err_code);
|
||||
}
|
||||
fclose(logfile_ptr);
|
||||
}
|
||||
@ -604,6 +696,8 @@ void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int32_t err = X502_ERR_OK;
|
||||
uint32_t ver;
|
||||
@ -622,9 +716,24 @@ int main(int argc, char** argv) {
|
||||
// для вывода русских букв в консоль для ОС Windows в CP1251 без перевода в OEM //
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
// читаем имя командного файла из аргументов CLI
|
||||
const char* cmd_filename = "default.cmd";
|
||||
if (argc > 1 && argv[1] != NULL && argv[1][0] != '\0') {
|
||||
cmd_filename = argv[1];
|
||||
}
|
||||
|
||||
// получаем версию библиотеки //
|
||||
ver = X502_GetLibraryVersion();
|
||||
printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
|
||||
printf("Command file: %s\n", cmd_filename);
|
||||
|
||||
// загружаем состояние из командного файла
|
||||
main_state state;
|
||||
main_state_set_defaults(&state);
|
||||
parse_cmd_file(cmd_filename, &state);
|
||||
// отладочный вывод принятых значений
|
||||
printf("Parsed state: run_mode=%d, BF_mode=%d, run_length=%u, runs_N=%u, run_I=%u\n",
|
||||
(int)state.run_mode, (int)state.BF_mode, state.run_length, state.runs_N, state.run_I);
|
||||
|
||||
/* Removed unused temporary buffers and FFT/LFSM placeholders */
|
||||
|
||||
@ -699,8 +808,6 @@ int main(int argc, char** argv) {
|
||||
printf("\n\n\n");
|
||||
|
||||
//setup ADC:
|
||||
/* Removed unused TX data buffer */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -712,6 +819,33 @@ int main(int argc, char** argv) {
|
||||
printf("Streams start err: %d \n", streams_start_Err);
|
||||
|
||||
|
||||
if (main_state.run_mode == RUN_MODE_FINITE){
|
||||
main_state.run_I = 0;
|
||||
char tmp_data_filename[] = " ";
|
||||
struct timespec ts;
|
||||
while(main_state.run_I < main_state.runs_N){
|
||||
max_total_words = 10000000;
|
||||
time(&seconds);
|
||||
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), "tmp/received_data_%ld.%ld.csv", ts.tv_sec, ts.tv_nsec);
|
||||
printf("%ld/%ld dumping to file: %s\n", main_state.run_I - main_state.runs_N, argv_runs, tmp_data_filename);
|
||||
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, main_state.run_length);
|
||||
|
||||
main_state.run_I++;
|
||||
}
|
||||
X502_Close(hnd);
|
||||
// освобождаем описатель
|
||||
X502_Free(hnd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
time_t seconds;
|
||||
time(&seconds);
|
||||
char logfilename[] = " ";
|
||||
@ -776,7 +910,7 @@ int main(int argc, char** argv) {
|
||||
// BF_exec_cmd_simple(hnd, 0x8010, 10, 1);
|
||||
|
||||
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words);
|
||||
// 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");
|
||||
@ -833,7 +967,7 @@ int main(int argc, char** argv) {
|
||||
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);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
|
||||
clock_gettime(CLOCK_MONOTONIC, &time_receive_ended);
|
||||
|
||||
|
||||
@ -869,7 +1003,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// printf("\n dbg value: ");
|
||||
// BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
|
||||
printf("\n dbg value: ");
|
||||
BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
|
||||
|
||||
@ -892,191 +1026,5 @@ int main(int argc, char** argv) {
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user