aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2022-05-22 13:29:45 -0400
committerClyne Sullivan <clyne@bitgloo.com>2022-05-22 13:29:45 -0400
commit660d967ec0ac79ea2a43946be4c056ef2d21ffc4 (patch)
tree63bb27d5b762b2a0dc77861a649fe109095a31d7
parent1b176cf6cd75c8031a140961655cdd3c16589a68 (diff)
bug fixes; dynamic time measure; sync sample drawing
-rw-r--r--source/circular.hpp7
-rw-r--r--source/code.cpp19
-rw-r--r--source/device.cpp61
-rw-r--r--source/gui_device.cpp40
-rw-r--r--source/stmdsp/stmdsp.cpp40
-rw-r--r--source/stmdsp/stmdsp.hpp21
6 files changed, 112 insertions, 76 deletions
diff --git a/source/circular.hpp b/source/circular.hpp
index 6b82068..4f49322 100644
--- a/source/circular.hpp
+++ b/source/circular.hpp
@@ -21,7 +21,7 @@ public:
CircularBuffer(Container<T>& container) :
m_begin(std::begin(container)),
m_end(std::end(container)),
- m_current(std::begin(container)) {}
+ m_current(m_begin) {}
void put(const T& value) noexcept {
*m_current = value;
@@ -33,6 +33,11 @@ public:
return std::distance(m_begin, m_end);
}
+ void reset(const T& fill) noexcept {
+ std::fill(m_begin, m_end, fill);
+ m_current = m_begin;
+ }
+
private:
Container<T>::iterator m_begin;
Container<T>::iterator m_end;
diff --git a/source/code.cpp b/source/code.cpp
index 14f603c..8e3bd6c 100644
--- a/source/code.cpp
+++ b/source/code.cpp
@@ -134,18 +134,17 @@ std::string newTempFileName()
bool codeExecuteCommand(const std::string& command, const std::string& file)
{
bool success = system(command.c_str()) == 0;
- if (success) {
- if (std::ifstream output (file); output.good()) {
- std::ostringstream sstr;
- sstr << output.rdbuf();
- log(sstr.str().c_str());
- } else {
- log("Could not read command output!");
- }
-
- std::filesystem::remove(file);
+
+ if (std::ifstream output (file); output.good()) {
+ std::ostringstream sstr;
+ sstr << output.rdbuf();
+ log(sstr.str().c_str());
+ } else {
+ log("Could not read command output!");
}
+ std::filesystem::remove(file);
+
return success;
}
diff --git a/source/device.cpp b/source/device.cpp
index 11e181e..60b1bc9 100644
--- a/source/device.cpp
+++ b/source/device.cpp
@@ -33,6 +33,7 @@
extern void log(const std::string& str);
extern std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string&);
extern std::ifstream compileOpenBinaryFile();
+extern void deviceRenderDisconnect();
std::shared_ptr<stmdsp::device> m_device;
@@ -45,9 +46,15 @@ static std::deque<stmdsp::dacsample_t> drawSamplesInputQueue;
static bool drawSamplesInput = false;
static unsigned int drawSamplesBufferSize = 1;
+bool deviceConnect();
+
void deviceSetInputDrawing(bool enabled)
{
drawSamplesInput = enabled;
+ if (enabled) {
+ drawSamplesQueue.clear();
+ drawSamplesInputQueue.clear();
+ }
}
static void measureCodeTask(std::shared_ptr<stmdsp::device> device)
@@ -55,7 +62,7 @@ static void measureCodeTask(std::shared_ptr<stmdsp::device> device)
std::this_thread::sleep_for(std::chrono::seconds(1));
if (device) {
- const auto cycles = device->continuous_start_get_measurement();
+ const auto cycles = device->measurement_read();
log(std::string("Execution time: ") + std::to_string(cycles) + " cycles.");
}
}
@@ -109,11 +116,21 @@ static void drawSamplesTask(std::shared_ptr<stmdsp::device> device)
const auto next = std::chrono::high_resolution_clock::now() + bufferTime;
if (lockDevice.try_lock_until(next)) {
- const auto chunk = tryReceiveChunk(device,
+ std::vector<stmdsp::dacsample_t> chunk, chunk2;
+
+ chunk = tryReceiveChunk(device,
std::mem_fn(&stmdsp::device::continuous_read));
+ if (drawSamplesInput) {
+ chunk2 = tryReceiveChunk(device,
+ std::mem_fn(&stmdsp::device::continuous_read_input));
+ }
+
lockDevice.unlock();
addToQueue(drawSamplesQueue, chunk);
+ if (drawSamplesInput)
+ addToQueue(drawSamplesInputQueue, chunk2);
+
if (logSamplesFile.is_open()) {
for (const auto& s : chunk)
logSamplesFile << s << '\n';
@@ -123,16 +140,6 @@ static void drawSamplesTask(std::shared_ptr<stmdsp::device> device)
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
- if (drawSamplesInput) {
- if (lockDevice.try_lock_for(std::chrono::milliseconds(1))) {
- const auto chunk2 = tryReceiveChunk(device,
- std::mem_fn(&stmdsp::device::continuous_read_input));
- lockDevice.unlock();
-
- addToQueue(drawSamplesInputQueue, chunk2);
- }
- }
-
std::this_thread::sleep_until(next);
}
}
@@ -193,6 +200,12 @@ static void statusTask(std::shared_ptr<stmdsp::device> device)
case stmdsp::Error::ConversionAborted:
log("Error: Algorithm unloaded, a fault occurred!");
break;
+ case stmdsp::Error::GUIDisconnect:
+ // Do GUI events for disconnect if device was lost.
+ deviceConnect();
+ deviceRenderDisconnect();
+ return;
+ break;
default:
log("Error: Device had an issue...");
break;
@@ -301,7 +314,7 @@ bool deviceConnect()
return false;
}
-void deviceStart(bool measureCodeTime, bool logResults, bool drawSamples)
+void deviceStart(bool logResults, bool drawSamples)
{
if (!m_device) {
log("No device connected.");
@@ -320,18 +333,22 @@ void deviceStart(bool measureCodeTime, bool logResults, bool drawSamples)
}
log("Ready.");
} else {
- if (measureCodeTime) {
- m_device->continuous_start_measure();
- std::thread(measureCodeTask, m_device).detach();
- } else {
- m_device->continuous_start();
- if (drawSamples || logResults || wavOutput.valid())
- std::thread(drawSamplesTask, m_device).detach();
- }
+ m_device->continuous_start();
+ if (drawSamples || logResults || wavOutput.valid())
+ std::thread(drawSamplesTask, m_device).detach();
+
log("Running.");
}
}
+void deviceStartMeasurement()
+{
+ if (m_device && m_device->is_running()) {
+ m_device->measurement_start();
+ std::thread(measureCodeTask, m_device).detach();
+ }
+}
+
void deviceAlgorithmUpload()
{
if (!m_device) {
@@ -387,7 +404,7 @@ void deviceGenLoadList(const std::string_view list)
}
}
- it = itend;
+ it = std::find_if(itend, list.cend(), isdigit);
}
if (it == list.cend()) {
diff --git a/source/gui_device.cpp b/source/gui_device.cpp
index 43c0a58..f846414 100644
--- a/source/gui_device.cpp
+++ b/source/gui_device.cpp
@@ -24,7 +24,8 @@ void deviceLoadAudioFile(const std::string& file);
void deviceLoadLogFile(const std::string& file);
void deviceSetSampleRate(unsigned int index);
void deviceSetInputDrawing(bool enabled);
-void deviceStart(bool measureCodeTime, bool logResults, bool drawSamples);
+void deviceStart(bool logResults, bool drawSamples);
+void deviceStartMeasurement();
void deviceUpdateDrawBufferSize(double timeframe);
std::size_t pullFromDrawQueue(
CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
@@ -47,6 +48,15 @@ static std::string getSampleRatePreview(unsigned int rate)
return std::to_string(rate / 1000) + " kHz";
}
+static std::string connectLabel ("Connect");
+void deviceRenderDisconnect()
+{
+ connectLabel = "Connect";
+ measureCodeTime = false;
+ logResults = false;
+ drawSamples = false;
+}
+
void deviceRenderMenu()
{
auto addMenuItem = [](const std::string& label, bool enable, auto action) {
@@ -56,7 +66,6 @@ void deviceRenderMenu()
};
if (ImGui::BeginMenu("Device")) {
- static std::string connectLabel ("Connect");
addMenuItem(connectLabel, !m_device || !m_device->is_running(), [&] {
if (deviceConnect()) {
connectLabel = "Disconnect";
@@ -64,10 +73,7 @@ void deviceRenderMenu()
getSampleRatePreview(m_device->get_sample_rate());
deviceUpdateDrawBufferSize(drawSamplesTimeframe);
} else {
- connectLabel = "Connect";
- measureCodeTime = false;
- logResults = false;
- drawSamples = false;
+ deviceRenderDisconnect();
}
});
@@ -79,7 +85,7 @@ void deviceRenderMenu()
static std::string startLabel ("Start");
addMenuItem(startLabel, isConnected, [&] {
startLabel = isRunning ? "Start" : "Stop";
- deviceStart(measureCodeTime, logResults, drawSamples);
+ deviceStart(logResults, drawSamples);
if (logResults && isRunning)
logResults = false;
});
@@ -87,28 +93,25 @@ void deviceRenderMenu()
deviceAlgorithmUpload);
addMenuItem("Unload algorithm", isConnected && !isRunning,
deviceAlgorithmUnload);
+ addMenuItem("Measure Code Time", isRunning, deviceStartMeasurement);
ImGui::Separator();
if (!isConnected || isRunning)
- ImGui::PushDisabled();
+ ImGui::PushDisabled(); // Hey, pushing disabled!
- ImGui::Checkbox("Measure Code Time", &measureCodeTime);
ImGui::Checkbox("Draw samples", &drawSamples);
if (ImGui::Checkbox("Log results...", &logResults)) {
if (logResults)
popupRequestLog = true;
}
+ addMenuItem("Set buffer size...", true, [] { popupRequestBuffer = true; });
if (!isConnected || isRunning)
ImGui::PopDisabled();
-
- addMenuItem("Set buffer size...", isConnected && !isRunning,
- [] { popupRequestBuffer = true; });
-
ImGui::Separator();
addMenuItem("Load signal generator",
- isConnected && !m_device->is_siggening(),
+ isConnected && !m_device->is_siggening() && !m_device->is_running(),
[] { popupRequestSiggen = true; });
static std::string startSiggenLabel ("Start signal generator");
@@ -193,7 +196,7 @@ void deviceRenderWidgets()
}
} else {
ImGui::Text(siggenOption == 0 ? "Enter a list of numbers:"
- : "Enter a formula. f(x) = ");
+ : "Enter a formula. x = sample #, y = -1 to 1.\nf(x) = ");
ImGui::PushStyleColor(ImGuiCol_FrameBg, {.8, .8, .8, 1});
ImGui::InputText("", siggenInput.data(), siggenInput.size());
ImGui::PopStyleColor();
@@ -286,8 +289,13 @@ void deviceRenderDraw()
ImGui::Begin("draw", &drawSamples);
ImGui::Text("Draw input ");
ImGui::SameLine();
- if (ImGui::Checkbox("", &drawSamplesInput))
+ if (ImGui::Checkbox("", &drawSamplesInput)) {
deviceSetInputDrawing(drawSamplesInput);
+ if (drawSamplesInput) {
+ bufferCirc.reset(2048);
+ bufferInputCirc.reset(2048);
+ }
+ }
ImGui::SameLine();
ImGui::Text("Time: %0.3f sec", drawSamplesTimeframe);
ImGui::SameLine();
diff --git a/source/stmdsp/stmdsp.cpp b/source/stmdsp/stmdsp.cpp
index 2252364..d7e977b 100644
--- a/source/stmdsp/stmdsp.cpp
+++ b/source/stmdsp/stmdsp.cpp
@@ -90,8 +90,7 @@ namespace stmdsp
m_serial->write(cmd.data(), cmd.size());
success = true;
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
@@ -108,8 +107,7 @@ namespace stmdsp
m_serial->read(dest, dest_size);
success = true;
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
@@ -158,12 +156,11 @@ namespace stmdsp
m_is_running = true;
}
- void device::continuous_start_measure() {
- if (try_command({'M'}))
- m_is_running = true;
+ void device::measurement_start() {
+ try_command({'M'});
}
- uint32_t device::continuous_start_get_measurement() {
+ uint32_t device::measurement_read() {
uint32_t count = 0;
try_read({'m'}, reinterpret_cast<uint8_t *>(&count), sizeof(uint32_t));
return count / 2;
@@ -193,8 +190,7 @@ namespace stmdsp
}
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
@@ -225,8 +221,7 @@ namespace stmdsp
}
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
@@ -251,8 +246,7 @@ namespace stmdsp
m_serial->write(request, 3);
m_serial->write((uint8_t *)buffer, size * sizeof(dacsample_t));
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
} else {
try {
@@ -262,8 +256,7 @@ namespace stmdsp
else
m_serial->write((uint8_t *)buffer, size * sizeof(dacsample_t));
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
@@ -295,8 +288,7 @@ namespace stmdsp
m_serial->write(request, 3);
m_serial->write(buffer, size);
} catch (...) {
- m_serial.release();
- log("Lost connection!");
+ handle_disconnect();
}
}
}
@@ -318,9 +310,19 @@ namespace stmdsp
bool running = ret.first == RunStatus::Running;
if (m_is_running != running)
m_is_running = running;
+ } else if (m_disconnect_error_flag) {
+ m_disconnect_error_flag = false;
+ return {RunStatus::Idle, Error::GUIDisconnect};
}
return ret;
}
-}
+
+ void device::handle_disconnect()
+ {
+ m_disconnect_error_flag = true;
+ m_serial.release();
+ log("Lost connection!");
+ }
+} // namespace stmdsp
diff --git a/source/stmdsp/stmdsp.hpp b/source/stmdsp/stmdsp.hpp
index e0fca90..efed8a3 100644
--- a/source/stmdsp/stmdsp.hpp
+++ b/source/stmdsp/stmdsp.hpp
@@ -63,12 +63,15 @@ namespace stmdsp
*/
enum class Error : char {
None = 0,
- BadParam, /* An invalid parameter was passed for a command. */
- BadParamSize, /* An invaild param. size was given for a command. */
- BadUserCodeLoad, /* Device failed to load the given algorithm. */
- BadUserCodeSize, /* The given algorithm is too large for the device. */
- NotIdle, /* An idle-only command was received while not Idle. */
- ConversionAborted /* A conversion was aborted due to a fault. */
+ BadParam, /* An invalid parameter was passed for a command. */
+ BadParamSize, /* An invaild param. size was given for a command. */
+ BadUserCodeLoad, /* Device failed to load the given algorithm. */
+ BadUserCodeSize, /* The given algorithm is too large for the device. */
+ NotIdle, /* An idle-only command was received while not Idle. */
+ ConversionAborted, /* A conversion was aborted due to a fault. */
+ NotRunning, /* A running-only command was received while not Running. */
+
+ GUIDisconnect = 100 /* The GUI lost connection with the device. */
};
/**
@@ -123,8 +126,8 @@ namespace stmdsp
void continuous_start();
void continuous_stop();
- void continuous_start_measure();
- uint32_t continuous_start_get_measurement();
+ void measurement_start();
+ uint32_t measurement_read();
std::vector<adcsample_t> continuous_read();
std::vector<adcsample_t> continuous_read_input();
@@ -149,11 +152,13 @@ namespace stmdsp
unsigned int m_sample_rate = 0;
bool m_is_siggening = false;
bool m_is_running = false;
+ bool m_disconnect_error_flag = false;
std::mutex m_lock;
bool try_command(std::basic_string<uint8_t> data);
bool try_read(std::basic_string<uint8_t> cmd, uint8_t *dest, unsigned int dest_size);
+ void handle_disconnect();
};
}