/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2015 - 2023 Teunis van Beelen * * Email: teuniz@protonmail.com * *************************************************************************** * * 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 3 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, see . * *************************************************************************** */ #include "screen_thread.h" #define SPECT_LOG_MINIMUM (0.00000001) #define SPECT_LOG_MINIMUM_LOG (-80) void screen_thread::set_device(struct tmcdev *tmdev) { params.cmd_cue_idx_in = 0; params.cmd_cue_idx_out = 0; params.connected = 0; device = tmdev; } screen_thread::screen_thread() { int i; device = NULL; h_busy = 0; for(i=0; iconnected; params.modelserie = deviceparms->modelserie; params.chandisplay[0] = deviceparms->chandisplay[0]; params.chandisplay[1] = deviceparms->chandisplay[1]; params.chandisplay[2] = deviceparms->chandisplay[2]; params.chandisplay[3] = deviceparms->chandisplay[3]; params.chanscale[0] = deviceparms->chanscale[0]; params.chanscale[1] = deviceparms->chanscale[1]; params.chanscale[2] = deviceparms->chanscale[2]; params.chanscale[3] = deviceparms->chanscale[3]; params.countersrc = deviceparms->countersrc; params.cmd_cue_idx_in = deviceparms->cmd_cue_idx_in; params.math_fft_src = deviceparms->math_fft_src; params.math_fft = deviceparms->math_fft; params.math_fft_unit = deviceparms->math_fft_unit; params.fftbuf_in = deviceparms->fftbuf_in; params.fftbuf_out = deviceparms->fftbuf_out; params.fftbufsz = deviceparms->fftbufsz; params.k_cfg = deviceparms->k_cfg; params.kiss_fftbuf = deviceparms->kiss_fftbuf; params.current_screen_sf = deviceparms->current_screen_sf; params.debug_str[0] = 0; params.func_wrec_enable = deviceparms->func_wrec_enable; params.func_wrec_operate = deviceparms->func_wrec_operate; params.func_wplay_operate = deviceparms->func_wplay_operate; params.func_wplay_fcur = deviceparms->func_wplay_fcur; params.func_wrec_fmax = deviceparms->func_wrec_fmax; params.func_wrep_fmax = deviceparms->func_wplay_fmax; } void screen_thread::get_params(struct device_settings *dev_parms) { int i; dev_parms->connected = params.connected; dev_parms->triggerstatus = params.triggerstatus; dev_parms->triggersweep = params.triggersweep; dev_parms->samplerate = params.samplerate; dev_parms->acquirememdepth = params.memdepth; dev_parms->counterfreq = params.counterfreq; dev_parms->wavebufsz = params.wavebufsz; for(i=0; iwavebuf[i], params.wavebuf[i], params.wavebufsz * sizeof(short)); dev_parms->xorigin[i] = params.xorigin[i]; } } dev_parms->thread_error_stat = params.error_stat; dev_parms->thread_error_line = params.error_line; dev_parms->cmd_cue_idx_out = params.cmd_cue_idx_out; dev_parms->thread_result = params.result; dev_parms->thread_job = params.job; if(dev_parms->thread_job == TMC_THRD_JOB_TRIGEDGELEV) { dev_parms->thread_value = params.triggeredgelevel; } if(dev_parms->thread_job == TMC_THRD_JOB_TIMDELAY) { dev_parms->timebasedelayoffset = params.timebasedelayoffset; dev_parms->timebasedelayscale = params.timebasedelayscale; } if(dev_parms->thread_job == TMC_THRD_JOB_FFTHZDIV) { dev_parms->math_fft_hscale = params.math_fft_hscale; dev_parms->math_fft_hcenter = params.math_fft_hcenter; } if(dev_parms->func_wrec_enable) { dev_parms->func_wrec_operate = params.func_wrec_operate; dev_parms->func_wplay_operate = params.func_wplay_operate; deviceparms->func_wplay_fcur = params.func_wplay_fcur; deviceparms->func_wrec_fmax = params.func_wrec_fmax; deviceparms->func_wplay_fmax = params.func_wrep_fmax; } if(params.debug_str[0]) { params.debug_str[1023] = 0; printf("params.debug_str: ->%s<-\n", params.debug_str); } } int screen_thread::get_devicestatus() { int line; usleep(TMC_GDS_DELAY); if(tmc_write(":TRIG:STAT?") != 11) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } if(!strcmp(device->buf, "TD")) { params.triggerstatus = 0; } else if(!strcmp(device->buf, "WAIT")) { params.triggerstatus = 1; } else if(!strcmp(device->buf, "RUN")) { params.triggerstatus = 2; } else if(!strcmp(device->buf, "AUTO")) { params.triggerstatus = 3; } else if(!strcmp(device->buf, "FIN")) { params.triggerstatus = 4; } else if(!strcmp(device->buf, "STOP")) { params.triggerstatus = 5; } else { line = __LINE__; goto OUT_ERROR; } usleep(TMC_GDS_DELAY); if(tmc_write(":TRIG:SWE?") != 10) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } if(!strcmp(device->buf, "AUTO")) { params.triggersweep = 0; } else if(!strcmp(device->buf, "NORM")) { params.triggersweep = 1; } else if(!strcmp(device->buf, "SING")) { params.triggersweep = 2; } else { line = __LINE__; goto OUT_ERROR; } usleep(TMC_GDS_DELAY); if(tmc_write(":ACQ:SRAT?") != 10) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.samplerate = atof(device->buf); usleep(TMC_GDS_DELAY); if(tmc_write(":ACQ:MDEP?") != 10) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.memdepth = atoi(device->buf); if(params.countersrc) { usleep(TMC_GDS_DELAY); if(tmc_write(":MEAS:COUN:VAL?") != 15) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.counterfreq = atof(device->buf); } if(params.func_wrec_enable) { usleep(TMC_GDS_DELAY); if(tmc_write(":FUNC:WREC:OPER?") != 16) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } if(params.modelserie == 6) { if(!strcmp(device->buf, "REC")) { params.func_wrec_operate = 1; } else if(!strcmp(device->buf, "STOP")) { params.func_wrec_operate = 0; } else { line = __LINE__; goto OUT_ERROR; } } else { if(!strcmp(device->buf, "RUN")) { params.func_wrec_operate = 1; } else if(!strcmp(device->buf, "STOP")) { params.func_wrec_operate = 0; } else { line = __LINE__; goto OUT_ERROR; } } usleep(TMC_GDS_DELAY); if(tmc_write(":FUNC:WREP:OPER?") != 16) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } if(!strcmp(device->buf, "PLAY")) { params.func_wplay_operate = 1; } else if(!strcmp(device->buf, "STOP")) { params.func_wplay_operate = 0; } else if(!strcmp(device->buf, "PAUS")) { params.func_wplay_operate = 2; } else { line = __LINE__; goto OUT_ERROR; } usleep(TMC_GDS_DELAY); if(tmc_write(":FUNC:WREP:FCUR?") != 16) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.func_wplay_fcur = atoi(device->buf); usleep(TMC_GDS_DELAY); if(tmc_write(":FUNC:WREC:FMAX?") != 16) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.func_wrec_fmax = atoi(device->buf); usleep(TMC_GDS_DELAY); if(tmc_write(":FUNC:WREP:FMAX?") != 16) { line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { line = __LINE__; goto OUT_ERROR; } params.func_wrep_fmax = atoi(device->buf); } params.debug_str[0] = 0; return 0; OUT_ERROR: strlcpy(params.debug_str, device->hdrbuf, 1024); params.error_line = line; return -1; } void screen_thread::run() { int i, j, k, n=0, chns=0, line, cmd_sent=0; char str[512]; double y_incr, binsz; params.error_stat = 0; params.result = TMC_THRD_RESULT_NONE; params.job = TMC_THRD_JOB_NONE; params.wavebufsz = 0; if(device == NULL) { return; } if(h_busy) { return; } if(!params.connected) { h_busy = 0; return; } h_busy = 1; while(params.cmd_cue_idx_out != params.cmd_cue_idx_in) { usleep(TMC_GDS_DELAY); tmc_write(deviceparms->cmd_cue[params.cmd_cue_idx_out]); if(deviceparms->cmd_cue_resp[params.cmd_cue_idx_out] != NULL) { usleep(TMC_GDS_DELAY); if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } strlcpy(deviceparms->cmd_cue_resp[params.cmd_cue_idx_out], device->buf, 128); } if((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TLHA", 5)) || ((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":CHAN", 5)) && (!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out] + 6, ":SCAL ", 6)))) { usleep(TMC_GDS_DELAY); if(tmc_write(":TRIG:EDG:LEV?") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.triggeredgelevel = atof(device->buf); params.job = TMC_THRD_JOB_TRIGEDGELEV; } else if(!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TIM:DEL:ENAB 1", 15)) { usleep(TMC_GDS_DELAY); if(tmc_write(":TIM:DEL:OFFS?") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.timebasedelayoffset = atof(device->buf); usleep(TMC_GDS_DELAY); if(tmc_write(":TIM:DEL:SCAL?") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.timebasedelayscale = atof(device->buf); params.job = TMC_THRD_JOB_TIMDELAY; } if(params.math_fft) { if((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TIM:SCAL ", 10)) || (!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":MATH:OPER FFT", 14)) || (!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":CALC:MODE FFT", 14))) { usleep(TMC_GDS_DELAY * 10); if(params.modelserie != 1) { if(tmc_write(":CALC:FFT:HSP?") != 14) { line = __LINE__; goto OUT_ERROR; } } else { if(tmc_write(":MATH:FFT:HSC?") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.math_fft_hscale = atof(device->buf); usleep(TMC_GDS_DELAY); if(params.modelserie != 1) { if(tmc_write(":CALC:FFT:HCEN?") != 15) { line = __LINE__; goto OUT_ERROR; } } else { if(tmc_write(":MATH:FFT:HCEN?") != 15) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.math_fft_hcenter = atof(device->buf); params.job = TMC_THRD_JOB_FFTHZDIV; } } params.cmd_cue_idx_out++; params.cmd_cue_idx_out %= TMC_CMD_CUE_SZ; cmd_sent = 1; } if(cmd_sent) { h_busy = 0; params.result = TMC_THRD_RESULT_CMD; return; } params.error_stat = get_devicestatus(); if(params.error_stat) { h_busy = 0; return; } if(!params.connected) { h_busy = 0; return; } for(i=0; ibuf); // // if(parse_preamble(device->buf, device->sz, &wfp, i)) // { // strlcpy(str, "Preamble parsing error.", 512); // goto OUT_ERROR; // } // // printf("waveform preamble:\n" // "format: %i\n" // "type: %i\n" // "points: %i\n" // "count: %i\n" // "xincrement: %e\n" // "xorigin: %e\n" // "xreference: %e\n" // "yincrement: %e\n" // "yorigin: %e\n" // "yreference: %i\n", // wfp.format, wfp.type, wfp.points, wfp.count, // wfp.xincrement[i], wfp.xorigin[i], wfp.xreference[i], // wfp.yincrement[i], wfp.yorigin[i], wfp.yreference[i]); // // printf("chanoffset[] is %e\n", params.chanoffset[i]); // rec_len = wfp.xincrement[i] * wfp.points; /////////////////////////////////////////////////////////// snprintf(str, 512, ":WAV:SOUR CHAN%i", i + 1); if(tmc_write(str) != 15) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_write(":WAV:FORM BYTE") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_write(":WAV:MODE NORM") != 14) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_write(":WAV:XOR?") != 9) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } if(tmc_read() < 1) { printf("Can not read from device.\n"); line = __LINE__; goto OUT_ERROR; } params.xorigin[i] = atof(device->buf); if(tmc_write(":WAV:DATA?") != 10) { printf("Can not write to device.\n"); line = __LINE__; goto OUT_ERROR; } n = tmc_read(); if(n < 0) { printf("Can not read from device. (n is %i)\n", n); line = __LINE__; goto OUT_ERROR; } if(n > WAVFRM_MAX_BUFSZ) { printf("Datablock too big for buffer.\n"); line = __LINE__; goto OUT_ERROR; } if(n < 32) { n = 0; } for(j=0; jbuf)[j]) - 127; } if((n == (params.fftbufsz * 2)) && (params.math_fft == 1) && (i == params.math_fft_src)) { if(params.modelserie == 6) { y_incr = params.chanscale[i] / 32.0; } else { y_incr = params.chanscale[i] / 25.0; } binsz = (double)params.current_screen_sf / (params.fftbufsz * 2.0); for(j=0; j