diff --git a/Desktop_Interface/genericusbdriver.cpp b/Desktop_Interface/genericusbdriver.cpp index 1f1d42933..1d864eda4 100644 --- a/Desktop_Interface/genericusbdriver.cpp +++ b/Desktop_Interface/genericusbdriver.cpp @@ -253,6 +253,7 @@ void genericUsbDriver::sendFunctionGenData(functionGen::ChannelID channelID) usbSendControl(0x40, 0xb2, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data()); } + this->sigGenFreqUpdated(channelID, clkSetting, timerPeriod, channelData.samples.size()); return; } diff --git a/Desktop_Interface/genericusbdriver.h b/Desktop_Interface/genericusbdriver.h index 95dcc7a57..a3807b99d 100644 --- a/Desktop_Interface/genericusbdriver.h +++ b/Desktop_Interface/genericusbdriver.h @@ -121,6 +121,7 @@ class genericUsbDriver : public QLabel void initialConnectComplete(void); void signalFirmwareFlash(void); void calibrateMe(void); + void sigGenFreqUpdated(functionGen::ChannelID channelID, int newClkSetting, int newTimerPeriod, int wfSize); public slots: void setPsu(double voltage); void setFunctionGen(functionGen::ChannelID channelID, functionGen::SingleChannelController *fGenControl); diff --git a/Desktop_Interface/isobuffer.cpp b/Desktop_Interface/isobuffer.cpp index 2243f7444..0f0bd6e54 100644 --- a/Desktop_Interface/isobuffer.cpp +++ b/Desktop_Interface/isobuffer.cpp @@ -426,8 +426,10 @@ void isoBuffer::serialManage(double baudRate, UartParity parity, bool hexDisplay void isoBuffer::setTriggerType(TriggerType newType) { qDebug() << "Trigger Type: " << (uint8_t)newType; - m_triggerType = newType; - m_lastTriggerDetlaT = 0; + if(newType != m_triggerType){ + m_triggerType = newType; + m_lastTriggerDeltaT = 0; + } } void isoBuffer::setTriggerLevel(double voltageLevel, uint16_t top, bool acCoupled) @@ -436,29 +438,63 @@ void isoBuffer::setTriggerLevel(double voltageLevel, uint16_t top, bool acCouple m_triggerSensitivity = static_cast(1 + abs(voltageLevel * kTriggerSensitivityMultiplier * static_cast(top) / 128.)); qDebug() << "Trigger Level: " << m_triggerLevel; qDebug() << "Trigger sensitivity:" << m_triggerSensitivity; - m_lastTriggerDetlaT = 0; + m_lastTriggerDeltaT = 0; +} + +void isoBuffer::setSigGenTriggerFreq(functionGen::ChannelID channelID, int clkSetting, int timerPeriod, int wfSize) +{ + int validClockDivs[7] = {1, 2, 4, 8, 64, 256, 1024}; + + double freq_ratio = ((double) (CLOCK_FREQ/m_samplesPerSecond))/validClockDivs[clkSetting-1]; // a power 2**n, n possibly < 0 + + double bufferSamplesPerWfCycle = wfSize * (timerPeriod+1) / freq_ratio; + + if(channelID==functionGen::ChannelID::CH1) + bufferSamplesPerCH1WfCycle = bufferSamplesPerWfCycle; + else if (channelID==functionGen::ChannelID::CH2) + bufferSamplesPerCH2WfCycle = bufferSamplesPerWfCycle; } // TODO: Clear trigger // FIXME: AC changes will not be reflected here void isoBuffer::checkTriggered() { + static uint32_t s_lastPosition = 0; if (m_triggerType == TriggerType::Disabled) return; - if ((bufferAt(0) >= (m_triggerLevel + m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::BelowTriggerLevel)) - { - // Rising Edge - m_triggerSeekState = TriggerSeekState::AboveTriggerLevel; - if (m_triggerType == TriggerType::Rising) - addTriggerPosition(m_back - 1); - } - else if ((bufferAt(0) < (m_triggerLevel - m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::AboveTriggerLevel)) + if((m_triggerType == TriggerType::CH1SigGen)||(m_triggerType == TriggerType::CH2SigGen)) { - // Falling Edge - m_triggerSeekState = TriggerSeekState::BelowTriggerLevel; - if (m_triggerType == TriggerType::Falling) - addTriggerPosition(m_back - 1); + float bufferSamplesPerWfCycle = m_triggerType == TriggerType::CH1SigGen ? bufferSamplesPerCH1WfCycle : bufferSamplesPerCH2WfCycle; + int32_t diff = m_back-s_lastPosition; + if(diff < 0) { + diff += m_bufferLen; + } + int n_cycles = diff/bufferSamplesPerWfCycle; + if( (m_triggerPositionList.size()==0) || (diff-n_cycles*bufferSamplesPerWfCycle == 0) ) { + addTriggerPosition(m_back, s_lastPosition, n_cycles); + s_lastPosition=m_back; + } + + } else { + if ((bufferAt(0) >= (m_triggerLevel + m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::BelowTriggerLevel)) + { + // Rising Edge + m_triggerSeekState = TriggerSeekState::AboveTriggerLevel; + if (m_triggerType == TriggerType::Rising){ + addTriggerPosition(m_back, s_lastPosition, 1); + s_lastPosition=m_back; + } + } + else if ((bufferAt(0) < (m_triggerLevel - m_triggerSensitivity)) && (m_triggerSeekState == TriggerSeekState::AboveTriggerLevel)) + { + // Falling Edge + m_triggerSeekState = TriggerSeekState::BelowTriggerLevel; + if (m_triggerType == TriggerType::Falling){ + addTriggerPosition(m_back, s_lastPosition, 1); + s_lastPosition=m_back; + } + } } } @@ -515,16 +551,14 @@ double isoBuffer::getDelayedTriggerPoint(double delay) double isoBuffer::getTriggerFrequencyHz() { - return (m_lastTriggerDetlaT == 0) ? -1. : static_cast(m_samplesPerSecond) / static_cast(m_lastTriggerDetlaT); + return (m_lastTriggerDeltaT == 0) ? -1. : 1. / (m_lastTriggerDeltaT); } -void isoBuffer::addTriggerPosition(uint32_t position) +void isoBuffer::addTriggerPosition(uint32_t position, uint32_t s_lastPosition, int n_cycles) { - static uint32_t s_lastPosition = 0; m_triggerPositionList.push_back(m_back - 1); - m_lastTriggerDetlaT = (position > s_lastPosition) ? (position - s_lastPosition) : position + m_bufferLen - s_lastPosition; - - s_lastPosition = position; + uint32_t delta_samples = (position > s_lastPosition) ? (position - s_lastPosition) : position + m_bufferLen - s_lastPosition; + m_lastTriggerDeltaT = delta_samples / static_cast(m_samplesPerSecond) / n_cycles; - //qDebug() << position << s_lastPosition << static_cast(m_samplesPerSecond) / static_cast(m_lastTriggerDetlaT) << "Hz"; + //qDebug() << position << s_lastPosition << static_cast(m_samplesPerSecond) / static_cast(m_lastTriggerDeltaT) << "Hz"; } diff --git a/Desktop_Interface/isobuffer.h b/Desktop_Interface/isobuffer.h index 4950dae77..a3baa202d 100644 --- a/Desktop_Interface/isobuffer.h +++ b/Desktop_Interface/isobuffer.h @@ -27,7 +27,9 @@ enum class TriggerType : uint8_t { Disabled, Rising, - Falling + Falling, + CH1SigGen, + CH2SigGen }; enum class TriggerSeekState : uint8_t @@ -99,6 +101,7 @@ class isoBuffer : public QWidget void setTriggerLevel(double voltageLevel, uint16_t top, bool acCoupled); double getDelayedTriggerPoint(double delay); double getTriggerFrequencyHz(); + void setSigGenTriggerFreq(functionGen::ChannelID channelID, int clkSetting, int timerPeriod, int wfSize); // ---- MEMBER VARIABLES ---- @@ -154,11 +157,13 @@ class isoBuffer : public QWidget qulonglong m_fileIO_maxFileSize; qulonglong m_fileIO_numBytesWritten; unsigned int m_currentColumn = 0; - uint32_t m_lastTriggerDetlaT = 0; + double m_lastTriggerDeltaT = 0.0; + float bufferSamplesPerCH1WfCycle; + float bufferSamplesPerCH2WfCycle; isoDriver* m_virtualParent; - void addTriggerPosition(uint32_t position); + void addTriggerPosition(uint32_t m_back, uint32_t position, int n_cycles); signals: void fileIOinternalDisable(); public slots: diff --git a/Desktop_Interface/isodriver.cpp b/Desktop_Interface/isodriver.cpp index 6e8ceb17c..256e06e4a 100644 --- a/Desktop_Interface/isodriver.cpp +++ b/Desktop_Interface/isodriver.cpp @@ -806,6 +806,13 @@ void isoDriver::setTriggerLevel(double level) triggerStateChanged(); } +// channel ID here refers to the wf gen channels +void isoDriver::newSigGenTriggerFreq(functionGen::ChannelID channelID, int clkSetting, int timerPeriod, int wfSize) { + internalBuffer375_CH1->setSigGenTriggerFreq(channelID, clkSetting, timerPeriod, wfSize); + internalBuffer750->setSigGenTriggerFreq(channelID, clkSetting, timerPeriod, wfSize); +} + + void isoDriver::setSingleShotEnabled(bool enabled) { singleShotEnabled = enabled; @@ -868,8 +875,10 @@ void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) double triggerDelay = 0; if (triggerEnabled) { - triggerDelay = (triggerMode < 2) ? internalBuffer_CH1->getDelayedTriggerPoint(display->window) - display->window - : internalBuffer_CH2->getDelayedTriggerPoint(display->window) - display->window; + if((triggerMode<2)||(triggerMode>=4)) + triggerDelay = internalBuffer_CH1->getDelayedTriggerPoint(display->window) - display->window; + else + triggerDelay = internalBuffer_CH2->getDelayedTriggerPoint(display->window) - display->window; if (triggerDelay < 0) triggerDelay = 0; @@ -1728,7 +1737,7 @@ void isoDriver::slowTimerTick(){ update_CH1 = true; update_CH2 = true; - bool frequencyLabelVisible = false; + bool frequencyLabelValid = false; if (triggerEnabled) { @@ -1744,11 +1753,15 @@ void isoDriver::slowTimerTick(){ case 3: triggerFrequency = internalBuffer375_CH2->getTriggerFrequencyHz(); break; + case 4: + case 5: + triggerFrequency = (driver->deviceMode == 6) ? internalBuffer750->getTriggerFrequencyHz() : internalBuffer375_CH1->getTriggerFrequencyHz(); + break; } if (triggerFrequency > 0.) { - frequencyLabelVisible = true; + frequencyLabelValid = true; siprint triggerFreqSiprint("Hz", triggerFrequency); siprint periodSiprint("s", 1. / triggerFrequency); @@ -1758,7 +1771,7 @@ void isoDriver::slowTimerTick(){ qDebug() << triggerFrequency << "Hz"; } - triggerFrequencyLabel->setVisible(frequencyLabelVisible); + triggerFrequencyLabel->setVisible(showTriggerFrequencyLabel&&frequencyLabelValid); } void isoDriver::setTopRange(double newTop) @@ -2047,6 +2060,7 @@ void isoDriver::triggerStateChanged() { if (!triggerEnabled) { + internalBuffer375_CH1->setTriggerType(TriggerType::Disabled); internalBuffer375_CH2->setTriggerType(TriggerType::Disabled); internalBuffer750->setTriggerType(TriggerType::Disabled); @@ -2085,6 +2099,23 @@ void isoDriver::triggerStateChanged() internalBuffer750->setTriggerType(TriggerType::Disabled); break; } + // use the CH1 buffer to do the sig gen trigger timekeeping. If there were a Ch. 2-only mode for the device, + // this practice could be problematic, but at present there is no Ch. 2-only mode. + // Also, in CH#SigGen below, the channel number refers to the sig gen channel + case 4: + { + internalBuffer375_CH1->setTriggerType(TriggerType::CH1SigGen); + internalBuffer375_CH2->setTriggerType(TriggerType::Disabled); + internalBuffer750->setTriggerType(TriggerType::CH1SigGen); + break; + } + case 5: + { + internalBuffer375_CH1->setTriggerType(TriggerType::CH2SigGen); + internalBuffer375_CH2->setTriggerType(TriggerType::Disabled); + internalBuffer750->setTriggerType(TriggerType::CH2SigGen); + } + } } diff --git a/Desktop_Interface/isodriver.h b/Desktop_Interface/isodriver.h index 1cce763c6..e706a841e 100644 --- a/Desktop_Interface/isodriver.h +++ b/Desktop_Interface/isodriver.h @@ -7,6 +7,7 @@ #include #include "qcustomplot.h" #include "genericusbdriver.h" +#include "functiongencontrol.h" #include "desktop_settings.h" #include "siprint.h" #include "i2cdecoder.h" @@ -54,6 +55,7 @@ class DisplayControl : public QObject void botRangeUpdated(double); void timeWindowUpdated(double); void delayUpdated(double); + }; class isoDriver : public QLabel @@ -71,6 +73,7 @@ class isoDriver : public QLabel QCPItemText *cursorLabel; QCPItemText *fSpaceLabel; QCPItemText *triggerFrequencyLabel; + bool showTriggerFrequencyLabel = true; #endif genericUsbDriver *driver; bool doNotTouchGraph = true; @@ -154,7 +157,6 @@ class isoDriver : public QLabel bool hexDisplay_CH1 = false; bool hexDisplay_CH2 = false; - //Generic Functions QVector analogConvert(std::vector &in, int TOP, bool AC, int channel); QVector digitalConvert(std::vector &in); @@ -330,6 +332,8 @@ public slots: void attenuationChanged_CH2(int attenuationIndex); void setHexDisplay_CH1(bool enabled); void setHexDisplay_CH2(bool enabled); + + void newSigGenTriggerFreq(functionGen::ChannelID channelID, int clkSetting, int timerPeriod, int wfSize); #ifndef DISABLE_SPECTRUM void setWindowingType(int windowing); void setMinFreqResp(double minFreqResp); diff --git a/Desktop_Interface/mainwindow.cpp b/Desktop_Interface/mainwindow.cpp index 5f0e26505..c3a7895e1 100644 --- a/Desktop_Interface/mainwindow.cpp +++ b/Desktop_Interface/mainwindow.cpp @@ -166,6 +166,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->psuSlider, SIGNAL(voltageChanged(double)), ui->controller_iso->driver, SLOT(setPsu(double))); connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double))); connect(ui->controller_fg, &functionGenControl::functionGenToUpdate, ui->controller_iso->driver, &genericUsbDriver::setFunctionGen); + connect(ui->controller_iso->driver, &genericUsbDriver::sigGenFreqUpdated, ui->controller_iso, &isoDriver::newSigGenTriggerFreq); connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int))); connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){ // Force a trigger refresh @@ -1525,6 +1526,7 @@ void MainWindow::reinitUsbStage2(void){ connect(ui->psuSlider, SIGNAL(voltageChanged(double)), ui->controller_iso->driver, SLOT(setPsu(double))); connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double))); connect(ui->controller_fg, &functionGenControl::functionGenToUpdate, ui->controller_iso->driver, &genericUsbDriver::setFunctionGen); + connect(ui->controller_iso->driver, &genericUsbDriver::sigGenFreqUpdated, ui->controller_iso, &isoDriver::newSigGenTriggerFreq); connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int))); connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){ // Force a trigger refresh @@ -2771,10 +2773,13 @@ void MainWindow::on_actionFrequency_Spectrum_triggered(bool checked) ui->scopeAxes->xAxis->setNumberFormat(defaultNumberFormat); } - if (checked == true) + if (checked == true) { MAX_WINDOW_SIZE = 1<<17; - else + ui->controller_iso->showTriggerFrequencyLabel = false; + } else { MAX_WINDOW_SIZE = 10; + ui->controller_iso->showTriggerFrequencyLabel = true; + } } void MainWindow::on_actionFrequency_Response_triggered(bool checked) @@ -2808,6 +2813,7 @@ void MainWindow::on_actionFrequency_Response_triggered(bool checked) ui->cursorHoriCheck->setChecked(ui->controller_iso->horiCursorEnabled2); ui->cursorVertCheck->setChecked(ui->controller_iso->vertCursorEnabled2); ui->controller_iso->retickXAxis(); + ui->controller_iso->showTriggerFrequencyLabel = false; }else{ ui->cursorHoriCheck->setChecked(ui->controller_iso->horiCursorEnabled0); ui->cursorVertCheck->setChecked(ui->controller_iso->vertCursorEnabled0); @@ -2817,6 +2823,7 @@ void MainWindow::on_actionFrequency_Response_triggered(bool checked) ui->scopeAxes->xAxis->setNumberPrecision(defaultNumberPrecision); ui->scopeAxes->xAxis->setAutoTickCount(defaultAutoTickCount); ui->scopeAxes->xAxis->setNumberFormat(defaultNumberFormat); + ui->controller_iso->showTriggerFrequencyLabel = true; } } @@ -2847,9 +2854,11 @@ void MainWindow::on_actionEye_Diagram_triggered(bool checked) if(checked){ ui->cursorHoriCheck->setChecked(ui->controller_iso->horiCursorEnabled3); ui->cursorVertCheck->setChecked(ui->controller_iso->vertCursorEnabled3); + ui->controller_iso->showTriggerFrequencyLabel = false; }else{ ui->cursorHoriCheck->setChecked(ui->controller_iso->horiCursorEnabled0); ui->cursorVertCheck->setChecked(ui->controller_iso->vertCursorEnabled0); + ui->controller_iso->showTriggerFrequencyLabel = true; } } #endif @@ -2946,6 +2955,25 @@ void MainWindow::on_serialEncodingCheck_CH1_toggled(bool checked) } } +void MainWindow::triggerChannelChanged(int newTriggerChannel){ + if((newTriggerChannel==4)||(newTriggerChannel==5)) { + ui->triggerLevelValue->setEnabled(false); + ui->singleShotCheckBox->setEnabled(false); + ui->singleShotCheckBox->setChecked(false); +#ifndef PLATFORM_ANDROID + ui->label_6->setEnabled(false); +#endif + } else { + ui->triggerLevelValue->setEnabled(true); + ui->singleShotCheckBox->setEnabled(true); +#ifndef PLATFORM_ANDROID + ui->label_6->setEnabled(true); +#endif + } +} + + + void MainWindow::on_txuart_textChanged() { QString text, new_char; diff --git a/Desktop_Interface/mainwindow.h b/Desktop_Interface/mainwindow.h index fcd36233e..9121a28f7 100644 --- a/Desktop_Interface/mainwindow.h +++ b/Desktop_Interface/mainwindow.h @@ -66,6 +66,8 @@ private slots: void on_actionSnap_to_Cursors_triggered(); void on_actionEnter_Manually_triggered(); + void triggerChannelChanged(int newTriggerChannel); + void connectDisplaySignals(); void calibrateStage2(); void calibrateStage3(); diff --git a/Desktop_Interface/ui_files_desktop/mainwindow.ui b/Desktop_Interface/ui_files_desktop/mainwindow.ui index 300b70155..9ed885377 100644 --- a/Desktop_Interface/ui_files_desktop/mainwindow.ui +++ b/Desktop_Interface/ui_files_desktop/mainwindow.ui @@ -691,6 +691,16 @@ CH2 (Falling) + + + Sig. Gen. CH1 + + + + + Sig. Gen. CH2 + + @@ -3643,6 +3653,12 @@ + + triggerChannelSelect + currentIndexChanged(int) + MainWindow + triggerChannelChanged(int) + acCoupledLabel_CH1 toggled(bool) diff --git a/Desktop_Interface/ui_files_mobile/mainwindow.ui b/Desktop_Interface/ui_files_mobile/mainwindow.ui index 1b6224adf..9c3e46671 100644 --- a/Desktop_Interface/ui_files_mobile/mainwindow.ui +++ b/Desktop_Interface/ui_files_mobile/mainwindow.ui @@ -576,6 +576,16 @@ CH2 (Falling) + + + Sig. Gen. CH1 + + + + + Sig. Gen. CH2 + + @@ -3627,6 +3637,12 @@ + + triggerChannelSelect + currentIndexChanged(int) + MainWindow + triggerChannelChanged(int) + acCoupledLabel_CH1 toggled(bool)