From f47ecb1014f6a95fc5920c892026ca730919597a Mon Sep 17 00:00:00 2001 From: Theodor Chikin Date: Thu, 13 Nov 2025 20:55:53 +0300 Subject: [PATCH] removed old unacessible code from the end. Implemented main_state struct, filling it from the CLI arg file. Also implemented FINITE_RUNS mode. --- main.c | 354 ++++++++++++++++++++++++--------------------------------- 1 file changed, 151 insertions(+), 203 deletions(-) diff --git a/main.c b/main.c index 5f5c11b..51d58a6 100644 --- a/main.c +++ b/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 - // получаем версию библиотеки // - ver = X502_GetLibraryVersion(); - printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF); + // читаем имя командного файла из аргументов 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 */ @@ -698,9 +807,7 @@ int main(int argc, char** argv) { printf("\n\n\n"); - //setup ADC: - /* Removed unused TX data buffer */ - + //setup ADC: @@ -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); @@ -891,192 +1025,6 @@ 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; }