From caa7c1675f72305c0a146c0931fc21e90f97419b Mon Sep 17 00:00:00 2001 From: Mark Zakharyan Date: Tue, 8 Oct 2024 15:40:07 -0700 Subject: [PATCH] cleanup + multiple SPI support --- m4/src/Peripherals/ADC/ADCBoard.h | 2 +- m4/src/Peripherals/DAC/DACChannel.h | 2 +- m4/src/Peripherals/God.h | 55 ----------- m4/src/Peripherals/God2D.h | 92 +------------------ .../Peripherals/PeripheralCommsController.h | 28 +++--- 5 files changed, 20 insertions(+), 159 deletions(-) diff --git a/m4/src/Peripherals/ADC/ADCBoard.h b/m4/src/Peripherals/ADC/ADCBoard.h index 050bc7c..55f500a 100644 --- a/m4/src/Peripherals/ADC/ADCBoard.h +++ b/m4/src/Peripherals/ADC/ADCBoard.h @@ -82,7 +82,7 @@ class ADCBoard { public: inline static PeripheralCommsController commsController = - PeripheralCommsController(ADC_SPI_SETTINGS); + PeripheralCommsController(ADC_SPI_SETTINGS, &SPI1); ADCBoard(int cs_pin, int data_ready_pin, int reset_pin) : cs_pin(cs_pin), data_ready_pin(data_ready_pin), reset_pin(reset_pin) {} diff --git a/m4/src/Peripherals/DAC/DACChannel.h b/m4/src/Peripherals/DAC/DACChannel.h index 6bec9b6..8f8e3d7 100644 --- a/m4/src/Peripherals/DAC/DACChannel.h +++ b/m4/src/Peripherals/DAC/DACChannel.h @@ -19,7 +19,7 @@ class DACChannel { public: inline static PeripheralCommsController commsController = - PeripheralCommsController(DAC_SPI_SETTINGS); + PeripheralCommsController(DAC_SPI_SETTINGS, &SPI); DACChannel(int cs_pin) { this->cs_pin = cs_pin; offset_error = 0.0; diff --git a/m4/src/Peripherals/God.h b/m4/src/Peripherals/God.h index 71f0f99..0a71620 100644 --- a/m4/src/Peripherals/God.h +++ b/m4/src/Peripherals/God.h @@ -39,19 +39,16 @@ class God { uint32_t dac_interval_us = static_cast(args[3]); uint32_t adc_interval_us = static_cast(args[4]); - // Check if we have enough arguments for all DAC and ADC channels if (args.size() != static_cast(5 + numDacChannels * 3 + numAdcChannels)) { return OperationResult::Failure("Incorrect number of arguments"); } - // Allocate memory for DAC and ADC channel information int* dacChannels = new int[numDacChannels]; float* dacV0s = new float[numDacChannels]; float* dacVfs = new float[numDacChannels]; int* adcChannels = new int[numAdcChannels]; - // Parse DAC channel information for (int i = 0; i < numDacChannels; ++i) { int baseIndex = 5 + i * 3; dacChannels[i] = static_cast(args[baseIndex]); @@ -59,7 +56,6 @@ class God { dacVfs[i] = static_cast(args[baseIndex + 2]); } - // Parse ADC channel information for (int i = 0; i < numAdcChannels; ++i) { adcChannels[i] = static_cast(args[5 + numDacChannels * 3 + i]); } @@ -82,32 +78,12 @@ class God { if (numDacChannels < 1 || numAdcChannels < 1) { return OperationResult::Failure("Invalid number of channels"); } - // uint32_t adc_comms_period_us = (1.0/SPI_SPEED)*1e6*8*4; // 8 bits per - // byte, 4 bytes per ADC conversion if (adc_interval_us < - // adc_comms_period_us*numAdcChannels) { - // return OperationResult::Failure("ADC interval too short"); - // } - // uint32_t dac_comms_period_us = (1.0/SPI_SPEED)*1e6*8*3; // 8 bits per - // byte, 3 bytes per DAC update if (dac_interval_us < - // dac_comms_period_us*numDacChannels) { - // return OperationResult::Failure("DAC interval too short"); - // } int steps = 0; int x = 0; const int saved_data_size = numSteps * dac_interval_us / adc_interval_us; - // float** voltSetpoints = new float*[numDacChannels]; - - // for (int i = 0; i < numDacChannels; i++) { - // voltSetpoints[i] = new float[numSteps]; - // for (int j = 0; j < numSteps; j++) { - // voltSetpoints[i][j] = - // dacV0s[i] + (dacVfs[i] - dacV0s[i]) * j / (numSteps - 1); - // } - // } - float* voltageStepSize = new float[numDacChannels]; for (int i = 0; i < numDacChannels; i++) { @@ -208,19 +184,16 @@ class God { uint32_t dac_interval_us = static_cast(args[4]); uint32_t dac_settling_time_us = static_cast(args[5]); - // Check if we have enough arguments for all DAC and ADC channels if (args.size() != static_cast(6 + numDacChannels * 3 + numAdcChannels)) { return OperationResult::Failure("Incorrect number of arguments"); } - // Allocate memory for DAC and ADC channel information int* dacChannels = new int[numDacChannels]; float* dacV0s = new float[numDacChannels]; float* dacVfs = new float[numDacChannels]; int* adcChannels = new int[numAdcChannels]; - // Parse DAC channel information for (int i = 0; i < numDacChannels; ++i) { int baseIndex = 6 + i * 3; dacChannels[i] = static_cast(args[baseIndex]); @@ -228,7 +201,6 @@ class God { dacVfs[i] = static_cast(args[baseIndex + 2]); } - // Parse ADC channel information for (int i = 0; i < numAdcChannels; ++i) { adcChannels[i] = static_cast(args[6 + numDacChannels * 3 + i]); } @@ -263,27 +235,10 @@ class God { "DAC settling time too short for ADC conversion time"); } } - // uint32_t adc_comms_period_us = (1.0/SPI_SPEED)*1e6*8*4; // 8 bits per - // byte, 4 bytes per ADC conversion if - // (numAdcChannels*numAdcAverages*adc_comms_period_us > dac_interval_us - - // dac_settling_time_us) { - // return OperationResult::Failure("Buffer Ramp limited by ADC SPI - // comms"); - // } int steps = 0; int x = 0; - // float** voltSetpoints = new float*[numDacChannels]; - - // for (int i = 0; i < numDacChannels; i++) { - // voltSetpoints[i] = new float[numSteps]; - // for (int j = 0; j < numSteps; j++) { - // voltSetpoints[i][j] = - // dacV0s[i] + (dacVfs[i] - dacV0s[i]) * j / (numSteps - 1); - // } - // } - float* voltageStepSize = new float[numDacChannels]; for (int i = 0; i < numDacChannels; i++) { @@ -400,7 +355,6 @@ class God { const 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++]); @@ -468,15 +422,6 @@ class God { int total_data_size = (totalSteps-1) * numAdcMeasuresPerDacStep; int adcGetsSinceLastDacSet = 0; - // float thing = static_cast(total_data_size * numAdcChannels * 4); - // m4SendFloat(&thing, 1); - - // 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]); } diff --git a/m4/src/Peripherals/God2D.h b/m4/src/Peripherals/God2D.h index 0c8a3d8..5b7e724 100644 --- a/m4/src/Peripherals/God2D.h +++ b/m4/src/Peripherals/God2D.h @@ -38,7 +38,6 @@ class God2D { size_t currentIndex = 0; - // Parse initial parameters int numDacChannels = static_cast(args[currentIndex++]); int numAdcChannels = static_cast(args[currentIndex++]); int numStepsFast = static_cast(args[currentIndex++]); @@ -48,7 +47,6 @@ class God2D { bool retrace = static_cast(args[currentIndex++]); // 0.0f = false, 1.0f = true - // Parse Fast DAC Channels if (currentIndex >= args.size()) { return OperationResult::Failure( "Unexpected end of arguments while parsing fast DAC channels"); @@ -69,9 +67,7 @@ class God2D { fastDacVfs[i] = args[currentIndex++]; } - // Parse Slow DAC Channels if (currentIndex >= args.size()) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -80,7 +76,6 @@ class God2D { } int numSlowDacChannels = static_cast(args[currentIndex++]); if (args.size() < currentIndex + numSlowDacChannels * 3) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -98,9 +93,7 @@ class God2D { slowDacVfs[i] = args[currentIndex++]; } - // Parse ADC Channels if (args.size() < currentIndex + numAdcChannels) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -115,9 +108,7 @@ class God2D { adcChannels[i] = static_cast(args[currentIndex++]); } - // Validate total number of DAC channels if (numFastDacChannels + numSlowDacChannels != numDacChannels) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -129,17 +120,6 @@ class God2D { "Sum of fast and slow DAC channels does not match numDacChannels"); } - // Allocate memory for slow DAC voltage setpoints - // float **slowVoltSetpoints = new float *[numSlowDacChannels]; - // for (int i = 0; i < numSlowDacChannels; ++i) { - // slowVoltSetpoints[i] = new float[numStepsSlow]; - // for (int j = 0; j < numStepsSlow; ++j) { - // slowVoltSetpoints[i][j] = - // slowDacV0s[i] + - // (slowDacVfs[i] - slowDacV0s[i]) * j / (numStepsSlow - 1); - // } - // } - float *voltageStepSize = new float[numDacChannels]; for (int i = 0; i < numDacChannels; i++) { @@ -155,15 +135,12 @@ class God2D { setStopFlag(false); PeripheralCommsController::dataLedOn(); - // Start continuous ADC conversions for (int i = 0; i < numAdcChannels; i++) { ADCController::startContinuousConversion(adcChannels[i]); } - // Iterate over slow steps with optional retrace for (int slowStep = 0; slowStep < numStepsSlow && !getStopFlag(); ++slowStep) { - // Set slow DAC channels to the current slow step voltages DACChannel::commsController.beginTransaction(); for (int i = 0; i < numSlowDacChannels; ++i) { DACController::setVoltageNoTransactionNoLdac(slowDacChannels[i], @@ -173,17 +150,14 @@ class God2D { DACController::toggleLdac(); DACChannel::commsController.endTransaction(); - // Determine ramp direction based on retrace flag bool isReverse = false; if (retrace) { - isReverse = (slowStep % 2 != 0); // Reverse on odd slow steps + isReverse = (slowStep % 2 != 0); } - // Prepare ramp voltages float *currentV0s = fastDacV0s; float *currentVfs = fastDacVfs; if (isReverse) { - // Swap V0 and Vf for reverse ramp currentV0s = new float[numFastDacChannels]; currentVfs = new float[numFastDacChannels]; for (int i = 0; i < numFastDacChannels; ++i) { @@ -192,13 +166,11 @@ class God2D { } } - // Call the base ramp function for fast channels OperationResult rampResult = timeSeriesBufferRampBaseNoConversionSetup( numFastDacChannels, numAdcChannels, numStepsFast, dac_interval_us, adc_interval_us, fastDacChannels, currentV0s, currentVfs, adcChannels); - // If reverse ramp was performed, clean up the temporary arrays if (isReverse) { delete[] currentV0s; delete[] currentVfs; @@ -214,18 +186,16 @@ class God2D { delete[] adcChannels; delete[] voltageStepSize; delete[] previousVoltageSet; - return rampResult; // Return the failure reason + return rampResult; } } - // Set ADC channels to idle mode for (int i = 0; i < numAdcChannels; i++) { ADCController::idleMode(adcChannels[i]); } PeripheralCommsController::dataLedOff(); - // Clean up allocated memory delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -254,16 +224,6 @@ class God2D { const int saved_data_size = numSteps * dac_interval_us / adc_interval_us; - // float **voltSetpoints = new float *[numDacChannels]; - - // for (int i = 0; i < numDacChannels; i++) { - // voltSetpoints[i] = new float[numSteps]; - // for (int j = 0; j < numSteps; j++) { - // voltSetpoints[i][j] = - // dacV0s[i] + (dacVfs[i] - dacV0s[i]) * j / (numSteps - 1); - // } - // } - float *voltageStepSize = new float[numDacChannels]; for (int i = 0; i < numDacChannels; i++) { @@ -352,7 +312,6 @@ class God2D { size_t currentIndex = 0; - // Parse initial parameters int numDacChannels = static_cast(args[currentIndex++]); int numAdcChannels = static_cast(args[currentIndex++]); int numStepsFast = static_cast(args[currentIndex++]); @@ -363,7 +322,6 @@ class God2D { static_cast(args[currentIndex++]); // 0.0f = false, 1.0f = true int numAdcAverages = static_cast(args[currentIndex++]); - // Parse Fast DAC Channels if (currentIndex >= args.size()) { return OperationResult::Failure( "Unexpected end of arguments while parsing fast DAC channels"); @@ -384,9 +342,7 @@ class God2D { fastDacVfs[i] = args[currentIndex++]; } - // Parse Slow DAC Channels if (currentIndex >= args.size()) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -395,7 +351,6 @@ class God2D { } int numSlowDacChannels = static_cast(args[currentIndex++]); if (args.size() < currentIndex + numSlowDacChannels * 3) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -413,9 +368,7 @@ class God2D { slowDacVfs[i] = args[currentIndex++]; } - // Parse ADC Channels if (args.size() < currentIndex + numAdcChannels) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -438,9 +391,7 @@ class God2D { } } - // Validate total number of DAC channels if (numFastDacChannels + numSlowDacChannels != numDacChannels) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -452,17 +403,6 @@ class God2D { "Sum of fast and slow DAC channels does not match numDacChannels"); } - // Allocate memory for slow DAC voltage setpoints - // float **slowVoltSetpoints = new float *[numSlowDacChannels]; - // for (int i = 0; i < numSlowDacChannels; ++i) { - // slowVoltSetpoints[i] = new float[numStepsSlow]; - // for (int j = 0; j < numStepsSlow; ++j) { - // slowVoltSetpoints[i][j] = - // slowDacV0s[i] + - // (slowDacVfs[i] - slowDacV0s[i]) * j / (numStepsSlow - 1); - // } - // } - float *voltageStepSize = new float[numDacChannels]; for (int i = 0; i < numDacChannels; i++) { @@ -478,15 +418,12 @@ class God2D { setStopFlag(false); PeripheralCommsController::dataLedOn(); - // Start continuous ADC conversions for (int i = 0; i < numAdcChannels; i++) { ADCController::startContinuousConversion(adcChannels[i]); } - // Iterate over slow steps with optional retrace for (int slowStep = 0; slowStep < numStepsSlow && !getStopFlag(); ++slowStep) { - // Set slow DAC channels to the current slow step voltages DACChannel::commsController.beginTransaction(); for (int i = 0; i < numSlowDacChannels; ++i) { DACController::setVoltageNoTransactionNoLdac(slowDacChannels[i], @@ -496,17 +433,14 @@ class God2D { DACController::toggleLdac(); DACChannel::commsController.endTransaction(); - // Determine ramp direction based on retrace flag bool isReverse = false; if (retrace) { - isReverse = (slowStep % 2 != 0); // Reverse on odd slow steps + isReverse = (slowStep % 2 != 0); } - // Prepare ramp voltages float *currentV0s = fastDacV0s; float *currentVfs = fastDacVfs; if (isReverse) { - // Swap V0 and Vf for reverse ramp currentV0s = new float[numFastDacChannels]; currentVfs = new float[numFastDacChannels]; for (int i = 0; i < numFastDacChannels; ++i) { @@ -515,20 +449,17 @@ class God2D { } } - // Call the base ramp function for fast channels OperationResult rampResult = dacLedBufferRampBaseNoConversionSetup( numFastDacChannels, numAdcChannels, numStepsFast, numAdcAverages, dac_interval_us, dac_settling_time_us, fastDacChannels, currentV0s, currentVfs, adcChannels); - // If reverse ramp was performed, clean up the temporary arrays if (isReverse) { delete[] currentV0s; delete[] currentVfs; } if (!rampResult.isSuccess()) { - // Clean up allocated memory before returning delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -538,18 +469,16 @@ class God2D { delete[] adcChannels; delete[] voltageStepSize; delete[] previousVoltageSet; - return rampResult; // Return the failure reason + return rampResult; } } - // Set ADC channels to idle mode for (int i = 0; i < numAdcChannels; i++) { ADCController::idleMode(adcChannels[i]); } PeripheralCommsController::dataLedOff(); - // Clean up allocated memory delete[] fastDacChannels; delete[] fastDacV0s; delete[] fastDacVfs; @@ -575,18 +504,6 @@ class God2D { int steps = 0; int x = 0; - // float **voltSetpoints = new float *[numDacChannels]; - - // for (int i = 0; i < numDacChannels; i++) - // { - // voltSetpoints[i] = new float[numSteps]; - // for (int j = 0; j < numSteps; j++) - // { - // voltSetpoints[i][j] = - // dacV0s[i] + (dacVfs[i] - dacV0s[i]) * j / (numSteps - 1); - // } - // } - float numAdcAveragesInv = 1.0 / static_cast(numAdcAverages); float *voltageStepSize = new float[numDacChannels]; @@ -601,7 +518,6 @@ class God2D { previousVoltageSet[i] = dacV0s[i]; } - // Set up timers with the same period but phase shifted TimingUtil::setupTimersDacLed(dac_interval_us, dac_settling_time_us); while (x < numSteps && !getStopFlag()) { diff --git a/m4/src/Peripherals/PeripheralCommsController.h b/m4/src/Peripherals/PeripheralCommsController.h index b7ec401..56b4e23 100644 --- a/m4/src/Peripherals/PeripheralCommsController.h +++ b/m4/src/Peripherals/PeripheralCommsController.h @@ -1,51 +1,51 @@ #pragma once #include - #include "SPI.h" class PeripheralCommsController { private: SPISettings spiSettings; + SPIClass* spi; public: static bool spiInitialized; - PeripheralCommsController(SPISettings spi_s) : spiSettings(spi_s) {} + + PeripheralCommsController(SPISettings spi_s, SPIClass* spi_p) : spiSettings(spi_s), spi(spi_p) {} static void setup() { if (!spiInitialized) { SPI.begin(); + SPI1.begin(); spiInitialized = true; } } void beginSingleTransaction() { digitalWrite(led, HIGH); - SPI.beginTransaction(spiSettings); + spi->beginTransaction(spiSettings); } void endSingleTransaction() { - SPI.endTransaction(); + spi->endTransaction(); digitalWrite(led, LOW); } - static void dataLedOn() { digitalWrite(led, HIGH); } + static void dataLedOn() { /*digitalWrite(led, HIGH);*/ } - static void dataLedOff() { digitalWrite(led, LOW); } + static void dataLedOff() { /*digitalWrite(led, LOW);*/ } - void beginTransaction() { SPI.beginTransaction(spiSettings); } + void beginTransaction() { spi->beginTransaction(spiSettings); } - void endTransaction() { SPI.endTransaction(); } + void endTransaction() { spi->endTransaction(); } byte receiveByte() { - return SPI.transfer(0); + return spi->transfer(0); } + void transfer(void* buf, size_t count) { spi->transfer(buf, count); } - void transfer(void* buf, size_t count) { SPI.transfer(buf, count); } - - uint8_t transfer(uint8_t data) { return SPI.transfer(data); } - + uint8_t transfer(uint8_t data) { return spi->transfer(data); } }; -bool PeripheralCommsController::spiInitialized = false; \ No newline at end of file +bool PeripheralCommsController::spiInitialized = false;