From 035a0a027c743c9de103dacde343f4a2cfa3060a Mon Sep 17 00:00:00 2001 From: Mark Zakharyan Date: Sun, 29 Sep 2024 15:14:30 -0700 Subject: [PATCH] voltage packets are now just floats --- m4/src/Peripherals/God.h | 236 +++++++++++++++++++++++++++++++-- m4/src/Peripherals/God2D.h | 10 +- m4/src/Utils/shared_memory.cpp | 12 +- m4/src/Utils/shared_memory.h | 18 +-- m7/src/Utils/shared_memory.cpp | 12 +- m7/src/Utils/shared_memory.h | 18 +-- m7/src/main.cpp | 4 +- 7 files changed, 255 insertions(+), 55 deletions(-) diff --git a/m4/src/Peripherals/God.h b/m4/src/Peripherals/God.h index 5f1e1b5..db111a8 100644 --- a/m4/src/Peripherals/God.h +++ b/m4/src/Peripherals/God.h @@ -20,6 +20,8 @@ class God { "DAC_LED_BUFFER_RAMP"); registerMemberFunction(dacChannelCalibration, "DAC_CH_CAL"); registerMemberFunctionVector(boxcarAverageRamp, "BOXCAR_AVERAGE_RAMP"); + registerMemberFunctionVector(boxcarAverageRampDebug, + "BOXCAR_AVERAGE_RAMP_DEBUG"); } // args: @@ -123,12 +125,11 @@ class God { ADCController::getVoltageDataNoTransaction(adcChannels[i]); } } else { - VoltagePacket* packets = new VoltagePacket[numAdcChannels]; + float* packets = new float[numAdcChannels]; for (int i = 0; i < numAdcChannels; i++) { float v = ADCController::getVoltageDataNoTransaction(adcChannels[i]); - packets[i] = {static_cast(adcChannels[i]), - static_cast(x), v}; + packets[i] = v; } m4SendVoltage(packets, numAdcChannels); delete[] packets; @@ -288,7 +289,7 @@ class God { } } } else { - VoltagePacket* packets = new VoltagePacket[numAdcChannels]; + float* packets = new float[numAdcChannels]; for (int i = 0; i < numAdcChannels; i++) { float total = 0.0; for (int j = 0; j < numAdcAverages; j++) { @@ -296,8 +297,7 @@ class God { ADCController::getVoltageDataNoTransaction(adcChannels[i]); } float v = total / numAdcAverages; - packets[i] = {static_cast(adcChannels[i]), - static_cast(x), v}; + packets[i] = v; } m4SendVoltage(packets, numAdcChannels); delete[] packets; @@ -367,7 +367,8 @@ class God { // numAdcMeasuresPerDacStep, numAdcAverages, numAdcConversionSkips, // adcConversionTime_us, {for each dac channel: dac channel, v0_1, vf_1, v0_2, // vf_2}, {for each adc channel: adc channel} - static OperationResult boxcarAverageRamp(const std::vector& args) { + static OperationResult boxcarAverageRampDebug( + const std::vector& args) { size_t currentIndex = 0; // Parse initial parameters @@ -407,7 +408,7 @@ class God { } uint32_t dacPeriod_us = (numAdcMeasuresPerDacStep + numAdcConversionSkips) * - actualConversionTime_us + 500; + actualConversionTime_us; setStopFlag(false); @@ -455,12 +456,11 @@ class God { } } else { if (adcGetsSinceLastDacSet >= numAdcConversionSkips) { - VoltagePacket* packets = new VoltagePacket[numAdcChannels]; + float* packets = new float[numAdcChannels]; for (int i = 0; i < numAdcChannels; i++) { float v = ADCController::getVoltageDataNoTransaction(adcChannels[i]); - packets[i] = {static_cast(adcChannels[i]), - static_cast(x), v}; + packets[i] = v; } // m4SendVoltage(packets, numAdcChannels); delete[] packets; @@ -500,6 +500,220 @@ class God { ADCController::idleMode(adcChannels[i]); } + delete[] dacChannels; + delete[] dacV0_1; + delete[] dacVf_1; + delete[] dacV0_2; + delete[] dacVf_2; + delete[] adcChannels; + for (int i = 0; i < numDacChannels; i++) { + delete[] voltSetpoints[i]; + } + delete[] voltSetpoints; + + if (getStopFlag()) { + setStopFlag(false); + return OperationResult::Failure("RAMPING_STOPPED"); + } + + return OperationResult::Success(); + } + + // args: numDacChannels, numAdcChannels, numDacSteps, + // numAdcMeasuresPerDacStep, numAdcAverages, numAdcConversionSkips, + // adcConversionTime_us, {for each dac channel: dac channel, v0_1, vf_1, v0_2, + // vf_2}, {for each adc channel: adc channel} + static OperationResult boxcarAverageRamp(std::vector args) { + size_t currentIndex = 0; + + // Parse initial parameters + int numDacChannels = static_cast(args[currentIndex++]); + int numAdcChannels = static_cast(args[currentIndex++]); + int numDacSteps = static_cast(args[currentIndex++]); + int numAdcMeasuresPerDacStep = static_cast(args[currentIndex++]); + int numAdcAverages = static_cast(args[currentIndex++]); + int numAdcConversionSkips = static_cast(args[currentIndex++]); + uint32_t adcConversionTime_us = static_cast(args[currentIndex++]); + + int* dacChannels = new int[numDacChannels]; + float* dacV0_1 = new float[numDacChannels]; + float* dacVf_1 = new float[numDacChannels]; + float* dacV0_2 = new float[numDacChannels]; + float* dacVf_2 = new float[numDacChannels]; + + for (int i = 0; i < numDacChannels; ++i) { + dacChannels[i] = static_cast(args[currentIndex++]); + dacV0_1[i] = args[currentIndex++]; + dacVf_1[i] = args[currentIndex++]; + dacV0_2[i] = args[currentIndex++]; + dacVf_2[i] = args[currentIndex++]; + } + + int* adcChannels = new int[numAdcChannels]; + + for (int i = 0; i < numAdcChannels; ++i) { + adcChannels[i] = static_cast(args[currentIndex++]); + } + + uint32_t actualConversionTime_us = ADCController::presetConversionTime( + adcChannels[0], adcConversionTime_us, numAdcChannels > 1); + for (int i = 1; i < numAdcChannels; ++i) { + ADCController::presetConversionTime(adcChannels[i], adcConversionTime_us, + numAdcChannels > 1); + } + + uint32_t dacPeriod_us = (numAdcMeasuresPerDacStep + numAdcConversionSkips) * + actualConversionTime_us + + 500; + + setStopFlag(false); + + // Calculate voltages + float** voltSetpoints = new float*[numDacChannels]; + + for (int i = 0; i < numDacChannels; i++) { + voltSetpoints[i] = new float[numDacSteps * numAdcAverages]; + int l = 0; + for (int j = 0; j < numDacSteps; j++) { + for (int k = 0; k < numAdcAverages; k++) { + float* dacV0 = l % 2 ? dacV0_1 : dacV0_2; + float* dacVf = l % 2 ? dacVf_1 : dacVf_2; + voltSetpoints[i][l++] = + dacV0[i] + (dacVf[i] - dacV0[i]) * j / (numDacSteps - 1); + } + } + } + + int steps = 0; + int totalSteps = numDacSteps * numAdcAverages + 1; + int x = 0; + int total_data_size = + numDacSteps * numAdcAverages * numAdcMeasuresPerDacStep; + int adcGetsSinceLastDacSet = 0; + + // For averaging + float* adcSums = new float[numAdcChannels](); + float* adcAverageHigh = new float[numAdcChannels](); + float* adcAverageLow = new float[numAdcChannels](); + bool haveHighAverage = false; + bool haveLowAverage = false; + int numReadingsCollected = 0; + bool isHighSet = false; + + // For debugging: + float dacPeriodFloat = static_cast(dacPeriod_us); + m4SendFloat(&dacPeriodFloat, 1); + float adcPeriodFloat = static_cast(actualConversionTime_us); + m4SendFloat(&adcPeriodFloat, 1); + + for (int i = 0; i < numAdcChannels; ++i) { + ADCController::startContinuousConversion(adcChannels[i]); + } + + TimingUtil::setupTimersTimeSeries(dacPeriod_us, actualConversionTime_us); + + while (x < total_data_size && !getStopFlag()) { + if (TimingUtil::adcFlag && x < steps * numAdcMeasuresPerDacStep) { + ADCBoard::commsController.beginTransaction(); + if (steps <= 1) { + for (int i = 0; i < numAdcChannels; i++) { + ADCController::getVoltageDataNoTransaction(adcChannels[i]); + } + } else { + if (adcGetsSinceLastDacSet >= numAdcConversionSkips) { + // Collect ADC readings + for (int i = 0; i < numAdcChannels; i++) { + float v = + ADCController::getVoltageDataNoTransaction(adcChannels[i]); + adcSums[i] += v; + } + numReadingsCollected++; + x++; + if (numReadingsCollected == numAdcMeasuresPerDacStep) { + // We have collected all readings for the current DAC setpoint + // Compute average + for (int i = 0; i < numAdcChannels; i++) { + float avg = adcSums[i] / numAdcMeasuresPerDacStep; + if (isHighSet) { + adcAverageHigh[i] = avg; + haveHighAverage = true; + } else { + adcAverageLow[i] = avg; + haveLowAverage = true; + } + adcSums[i] = 0; // Reset sums for next set + } + numReadingsCollected = 0; + + // If we have both high and low averages, compute difference and + // send + if (haveHighAverage && haveLowAverage) { + float* packets = new float[numAdcChannels]; + for (int i = 0; i < numAdcChannels; i++) { + float diff = adcAverageHigh[i] - adcAverageLow[i]; + packets[i] = diff; //{diff}; + } + // m4SendVoltage(packets, numAdcChannels); + m4SendFloat(packets, numAdcChannels); + delete[] packets; + + haveHighAverage = false; + haveLowAverage = false; + } + } + } + adcGetsSinceLastDacSet++; + } + ADCBoard::commsController.endTransaction(); + TimingUtil::adcFlag = false; + } + if (TimingUtil::dacFlag && steps < totalSteps) { + DACChannel::commsController.beginTransaction(); + if (steps == 0) { + for (int i = 0; i < numDacChannels; i++) { + DACController::setVoltageNoTransactionNoLdac(dacChannels[i], + voltSetpoints[i][0]); + } + } else { + for (int i = 0; i < numDacChannels; i++) { + DACController::setVoltageNoTransactionNoLdac( + dacChannels[i], voltSetpoints[i][steps - 1]); + } + } + DACController::toggleLdac(); + steps++; + isHighSet = ((steps - 1) % 2 == 1); // Update high/low set indicator + + // Reset sums and counters for next DAC setpoint + for (int i = 0; i < numAdcChannels; i++) { + adcSums[i] = 0; + } + numReadingsCollected = 0; + + DACChannel::commsController.endTransaction(); + TimingUtil::dacFlag = false; + adcGetsSinceLastDacSet = 0; + TIM8->CNT = 0; + } + } + + TimingUtil::disableDacInterrupt(); + TimingUtil::disableAdcInterrupt(); + + for (int i = 0; i < numAdcChannels; i++) { + ADCController::idleMode(adcChannels[i]); + } + + // Clean up + delete[] adcSums; + delete[] adcAverageHigh; + delete[] adcAverageLow; + delete[] dacChannels; + delete[] dacV0_1; + delete[] dacVf_1; + delete[] dacV0_2; + delete[] dacVf_2; + delete[] adcChannels; for (int i = 0; i < numDacChannels; i++) { delete[] voltSetpoints[i]; } diff --git a/m4/src/Peripherals/God2D.h b/m4/src/Peripherals/God2D.h index c5a9618..30d855c 100644 --- a/m4/src/Peripherals/God2D.h +++ b/m4/src/Peripherals/God2D.h @@ -298,13 +298,12 @@ class God2D } else { - VoltagePacket *packets = new VoltagePacket[numAdcChannels]; + float *packets = new float[numAdcChannels]; for (int i = 0; i < numAdcChannels; i++) { float v = ADCController::getVoltageDataNoTransaction(adcChannels[i]); - packets[i] = {static_cast(adcChannels[i]), - static_cast(x), v}; + packets[i] = v; } m4SendVoltage(packets, numAdcChannels); delete[] packets; @@ -647,7 +646,7 @@ class God2D } else { - VoltagePacket *packets = new VoltagePacket[numAdcChannels]; + float *packets = new float[numAdcChannels]; for (int i = 0; i < numAdcChannels; i++) { float total = 0.0; @@ -657,8 +656,7 @@ class God2D ADCController::getVoltageDataNoTransaction(adcChannels[i]); } float v = total / numAdcAverages; - packets[i] = {static_cast(adcChannels[i]), - static_cast(x), v}; + packets[i] = v; } m4SendVoltage(packets, numAdcChannels); delete[] packets; diff --git a/m4/src/Utils/shared_memory.cpp b/m4/src/Utils/shared_memory.cpp index e4e5534..21c7df7 100644 --- a/m4/src/Utils/shared_memory.cpp +++ b/m4/src/Utils/shared_memory.cpp @@ -141,7 +141,7 @@ static bool floatBufferHasMessage(FloatCircularBuffer* buffer) { // Voltage buffer operations static bool voltageBufferSend(VoltageCircularBuffer* buffer, - const VoltagePacket* data, size_t length) { + const float* data, size_t length) { if (length > MAX_MESSAGE_SIZE) return false; uint32_t available_space = @@ -158,7 +158,7 @@ static bool voltageBufferSend(VoltageCircularBuffer* buffer, } static bool voltageBufferReceive(VoltageCircularBuffer* buffer, - VoltagePacket* data, size_t& length) { + float* data, size_t& length) { if (buffer->read_index == buffer->write_index) { length = 0; return false; @@ -210,12 +210,12 @@ bool m4HasFloatMessage() { } // M4 voltage functions -bool m4SendVoltage(const VoltagePacket* data, size_t length) { +bool m4SendVoltage(const float* data, size_t length) { return voltageBufferSend(&shared_memory->m4_to_m7_voltage_buffer, data, length); } -bool m4ReceiveVoltage(VoltagePacket* data, size_t& length) { +bool m4ReceiveVoltage(float* data, size_t& length) { return voltageBufferReceive(&shared_memory->m7_to_m4_voltage_buffer, data, length); } @@ -252,12 +252,12 @@ bool m7HasFloatMessage() { } // M7 voltage functions -bool m7SendVoltage(const VoltagePacket* data, size_t length) { +bool m7SendVoltage(const float* data, size_t length) { return voltageBufferSend(&shared_memory->m7_to_m4_voltage_buffer, data, length); } -bool m7ReceiveVoltage(VoltagePacket* data, size_t& length) { +bool m7ReceiveVoltage(float* data, size_t& length) { return voltageBufferReceive(&shared_memory->m4_to_m7_voltage_buffer, data, length); } diff --git a/m4/src/Utils/shared_memory.h b/m4/src/Utils/shared_memory.h index 207dd2f..1597b79 100644 --- a/m4/src/Utils/shared_memory.h +++ b/m4/src/Utils/shared_memory.h @@ -3,7 +3,7 @@ #define CHAR_BUFFER_SIZE 1024 #define FLOAT_BUFFER_SIZE 256 -#define VOLTAGE_BUFFER_SIZE 512 +#define VOLTAGE_BUFFER_SIZE 5120 #define MAX_MESSAGE_SIZE 256 struct CharCircularBuffer { @@ -18,14 +18,8 @@ struct FloatCircularBuffer { volatile uint32_t write_index; }; -struct VoltagePacket { - uint8_t adc_id; - uint32_t setnum; - float voltage; -}; - struct VoltageCircularBuffer { - VoltagePacket buffer[VOLTAGE_BUFFER_SIZE]; + float buffer[VOLTAGE_BUFFER_SIZE]; volatile uint32_t read_index; volatile uint32_t write_index; }; @@ -56,8 +50,8 @@ bool m4ReceiveFloat(float* data, size_t& length); bool m4HasFloatMessage(); // M4 voltage functions -bool m4SendVoltage(const VoltagePacket* data, size_t length); -bool m4ReceiveVoltage(VoltagePacket* data, size_t& length); +bool m4SendVoltage(const float* data, size_t length); +bool m4ReceiveVoltage(float* data, size_t& length); bool m4HasVoltageMessage(); // M7 char functions @@ -71,8 +65,8 @@ bool m7ReceiveFloat(float* data, size_t& length); bool m7HasFloatMessage(); // M7 voltage functions -bool m7SendVoltage(const VoltagePacket* data, size_t length); -bool m7ReceiveVoltage(VoltagePacket* data, size_t& length); +bool m7SendVoltage(const float* data, size_t length); +bool m7ReceiveVoltage(float* data, size_t& length); bool m7HasVoltageMessage(); void setStopFlag(bool value); diff --git a/m7/src/Utils/shared_memory.cpp b/m7/src/Utils/shared_memory.cpp index e4e5534..21c7df7 100644 --- a/m7/src/Utils/shared_memory.cpp +++ b/m7/src/Utils/shared_memory.cpp @@ -141,7 +141,7 @@ static bool floatBufferHasMessage(FloatCircularBuffer* buffer) { // Voltage buffer operations static bool voltageBufferSend(VoltageCircularBuffer* buffer, - const VoltagePacket* data, size_t length) { + const float* data, size_t length) { if (length > MAX_MESSAGE_SIZE) return false; uint32_t available_space = @@ -158,7 +158,7 @@ static bool voltageBufferSend(VoltageCircularBuffer* buffer, } static bool voltageBufferReceive(VoltageCircularBuffer* buffer, - VoltagePacket* data, size_t& length) { + float* data, size_t& length) { if (buffer->read_index == buffer->write_index) { length = 0; return false; @@ -210,12 +210,12 @@ bool m4HasFloatMessage() { } // M4 voltage functions -bool m4SendVoltage(const VoltagePacket* data, size_t length) { +bool m4SendVoltage(const float* data, size_t length) { return voltageBufferSend(&shared_memory->m4_to_m7_voltage_buffer, data, length); } -bool m4ReceiveVoltage(VoltagePacket* data, size_t& length) { +bool m4ReceiveVoltage(float* data, size_t& length) { return voltageBufferReceive(&shared_memory->m7_to_m4_voltage_buffer, data, length); } @@ -252,12 +252,12 @@ bool m7HasFloatMessage() { } // M7 voltage functions -bool m7SendVoltage(const VoltagePacket* data, size_t length) { +bool m7SendVoltage(const float* data, size_t length) { return voltageBufferSend(&shared_memory->m7_to_m4_voltage_buffer, data, length); } -bool m7ReceiveVoltage(VoltagePacket* data, size_t& length) { +bool m7ReceiveVoltage(float* data, size_t& length) { return voltageBufferReceive(&shared_memory->m4_to_m7_voltage_buffer, data, length); } diff --git a/m7/src/Utils/shared_memory.h b/m7/src/Utils/shared_memory.h index 207dd2f..1597b79 100644 --- a/m7/src/Utils/shared_memory.h +++ b/m7/src/Utils/shared_memory.h @@ -3,7 +3,7 @@ #define CHAR_BUFFER_SIZE 1024 #define FLOAT_BUFFER_SIZE 256 -#define VOLTAGE_BUFFER_SIZE 512 +#define VOLTAGE_BUFFER_SIZE 5120 #define MAX_MESSAGE_SIZE 256 struct CharCircularBuffer { @@ -18,14 +18,8 @@ struct FloatCircularBuffer { volatile uint32_t write_index; }; -struct VoltagePacket { - uint8_t adc_id; - uint32_t setnum; - float voltage; -}; - struct VoltageCircularBuffer { - VoltagePacket buffer[VOLTAGE_BUFFER_SIZE]; + float buffer[VOLTAGE_BUFFER_SIZE]; volatile uint32_t read_index; volatile uint32_t write_index; }; @@ -56,8 +50,8 @@ bool m4ReceiveFloat(float* data, size_t& length); bool m4HasFloatMessage(); // M4 voltage functions -bool m4SendVoltage(const VoltagePacket* data, size_t length); -bool m4ReceiveVoltage(VoltagePacket* data, size_t& length); +bool m4SendVoltage(const float* data, size_t length); +bool m4ReceiveVoltage(float* data, size_t& length); bool m4HasVoltageMessage(); // M7 char functions @@ -71,8 +65,8 @@ bool m7ReceiveFloat(float* data, size_t& length); bool m7HasFloatMessage(); // M7 voltage functions -bool m7SendVoltage(const VoltagePacket* data, size_t length); -bool m7ReceiveVoltage(VoltagePacket* data, size_t& length); +bool m7SendVoltage(const float* data, size_t length); +bool m7ReceiveVoltage(float* data, size_t& length); bool m7HasVoltageMessage(); void setStopFlag(bool value); diff --git a/m7/src/main.cpp b/m7/src/main.cpp index 2be6d1f..1721732 100644 --- a/m7/src/main.cpp +++ b/m7/src/main.cpp @@ -124,7 +124,7 @@ void loop() } if (m7HasVoltageMessage()) { - VoltagePacket response[VOLTAGE_BUFFER_SIZE]; + float response[VOLTAGE_BUFFER_SIZE]; size_t size; if (m7ReceiveVoltage(response, size)) { @@ -137,7 +137,7 @@ void loop() // Serial.print(", "); // Serial.print(response[i].voltage, 8); binaryFloat send; - send.floatingPoint = response[i].voltage; + send.floatingPoint = response[i]; Serial.write(send.binary, 4); // Serial.println("V"); }