From 10818bcd78d36a9f7baaca1efeca636fa8029087 Mon Sep 17 00:00:00 2001 From: Steve Lascos Date: Mon, 20 Aug 2018 20:29:16 -0400 Subject: [PATCH] Further development, got all controls working, still need to filter pots --- .../BAExpansionCalibrate.ino | 67 ++++++ .../AnalogDelayDemoExpansion.ino | 113 +++++++++ .../Delay/AnalogDelayDemoExpansion/name.c | 19 ++ src/BAGuitar.h | 1 + src/BAHardware.h | 24 +- src/BAPhysicalControls.h | 148 ++++++++++++ src/peripherals/BAPhysicalControls.cpp | 220 ++++++++++++++++++ src/peripherals/BASpiMemory.cpp | 6 +- 8 files changed, 593 insertions(+), 5 deletions(-) create mode 100644 examples/BAExpansionCalibrate/BAExpansionCalibrate.ino create mode 100644 examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino create mode 100644 examples/Delay/AnalogDelayDemoExpansion/name.c create mode 100644 src/BAPhysicalControls.h create mode 100644 src/peripherals/BAPhysicalControls.cpp diff --git a/examples/BAExpansionCalibrate/BAExpansionCalibrate.ino b/examples/BAExpansionCalibrate/BAExpansionCalibrate.ino new file mode 100644 index 0000000..1429183 --- /dev/null +++ b/examples/BAExpansionCalibrate/BAExpansionCalibrate.ino @@ -0,0 +1,67 @@ +#define TGA_PRO_REVB +#define TGA_PRO_EXPAND_REV2 + +#include "BAGuitar.h" + +using namespace BALibrary; + +// Create physical controls for Expansion Board, 2 switches, 3 pots, 0 encoders, 2 LEDs +BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, 0, BA_EXPAND_NUM_LED); + +void setup() { + delay(100); + Serial.begin(57600); + delay(500); // long delay to wait for Serial to init + + // put your setup code here, to run once: + Serial.println("Calibrating POT1"); + Potentiometer::Calib pot1Calib = Potentiometer::calibrate(BA_EXPAND_POT1_PIN); + if (pot1Calib.min == pot1Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + Serial.println("\nCalibrating POT2"); + Potentiometer::Calib pot2Calib = Potentiometer::calibrate(BA_EXPAND_POT2_PIN); + if (pot2Calib.min == pot2Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + Serial.println("\nCalibrating POT3"); + Potentiometer::Calib pot3Calib = Potentiometer::calibrate(BA_EXPAND_POT3_PIN); + if (pot3Calib.min == pot3Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + // Create the controls using the calib values + controls.addPot(BA_EXPAND_POT1_PIN, pot1Calib.min, pot1Calib.max, pot1Calib.swap); + controls.addPot(BA_EXPAND_POT2_PIN, pot2Calib.min, pot2Calib.max, pot2Calib.swap); + controls.addPot(BA_EXPAND_POT3_PIN, pot3Calib.min, pot3Calib.max, pot3Calib.swap); + + // Add the pushbuttons + controls.addSwitch(BA_EXPAND_SW1_PIN); + controls.addSwitch(BA_EXPAND_SW2_PIN); + + // Setup the LEDs + controls.addOutput(BA_EXPAND_LED1_PIN); + controls.setOutput(BA_EXPAND_LED1_PIN, 0); + controls.addOutput(BA_EXPAND_LED2_PIN); + controls.setOutput(BA_EXPAND_LED2_PIN, 0); + + Serial.println("DONE SETUP! Try turning knobs and pushing buttons!\n"); + +} + +void loop() { + // put your main code here, to run repeatedly: + float value; + for (unsigned i=0; i + +#define TGA_PRO_REVB +#define TGA_PRO_EXPAND_REV2 + +#include "BAGuitar.h" + +using namespace midi; +using namespace BAEffects; +using namespace BALibrary; + +AudioInputI2S i2sIn; +AudioOutputI2S i2sOut; +BAAudioControlWM8731 codec; + +//#define USE_EXT // uncomment this line to use External MEM0 + +#ifdef USE_EXT +// If using external SPI memory, we will instantiance an SRAM +// manager and create an external memory slot to use as the memory +// for our audio delay +ExternalSramManager externalSram; +ExtMemSlot delaySlot; // Declare an external memory slot. + +// Instantiate the AudioEffectAnalogDelay to use external memory by +/// passing it the delay slot. +AudioEffectAnalogDelay analogDelay(&delaySlot); +#else +// If using internal memory, we will instantiate the AudioEffectAnalogDelay +// by passing it the maximum amount of delay we will use in millseconds. Note that +// audio delay lengths are very limited when using internal memory due to limited +// internal RAM size. +AudioEffectAnalogDelay analogDelay(200.0f); // max delay of 200 ms. +#endif + +AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. + +// Simply connect the input to the delay, and the output +// to both i2s channels +AudioConnection input(i2sIn,0, analogDelay,0); +AudioConnection delayOut(analogDelay, 0, cabFilter, 0); +AudioConnection leftOut(cabFilter,0, i2sOut, 0); +AudioConnection rightOut(cabFilter,0, i2sOut, 1); + +////////////////////////////////////////// +// SETUP PHYSICAL CONTROLS +////////////////////////////////////////// +BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, 0); + +int loopCount = 0; + +void setup() { + delay(100); + Serial.begin(57600); // Start the serial port + delay(100); + + // Setup the controls + controls.addSwitch(BA_EXPAND_SW1_PIN); + controls.addSwitch(BA_EXPAND_SW2_PIN); + controls.addPot(BA_EXPAND_POT1_PIN, + + // Disable the codec first + codec.disable(); + AudioMemory(128); + + // Enable the codec + Serial.println("Enabling codec...\n"); + codec.enable(); + + // If using external memory request request memory from the manager + // for the slot + #ifdef USE_EXT + Serial.println("Using EXTERNAL memory"); + // We have to request memory be allocated to our slot. + externalSram.requestMemory(&delaySlot, 500.0f, MemSelect::MEM0, true); + #else + Serial.println("Using INTERNAL memory"); + #endif + + // Besure to enable the delay. When disabled, audio is is completely blocked + // to minimize resources to nearly zero. + analogDelay.enable(); + + // Set some default values. + // These can be changed using the controls on the Blackaddr Audio Expansion Board + analogDelay.bypass(false); + analogDelay.mix(0.5f); + analogDelay.feedback(0.0f); + + ////////////////////////////////// + // AnalogDelay filter selection // + // Uncomment to tryout the 3 different built-in filters. + //analogDelay.setFilter(AudioEffectAnalogDelay::Filter::DM3); // The default filter. Naturally bright echo (highs stay, lows fade away) + //analogDelay.setFilter(AudioEffectAnalogDelay::Filter::WARM); // A warm filter with a smooth frequency rolloff above 2Khz + //analogDelay.setFilter(AudioEffectAnalogDelay::Filter::DARK); // A very dark filter, with a sharp rolloff above 1Khz + + // Setup 2-stages of LPF, cutoff 4500 Hz, Q-factor 0.7071 (a 'normal' Q-factor) + cabFilter.setLowpass(0, 4500, .7071); + cabFilter.setLowpass(1, 4500, .7071); +} + +void loop() { + + if (loopCount % 524288 == 0) { + Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); + Serial.print("% "); + Serial.print(" analogDelay: "); Serial.print(analogDelay.processorUsage()); + Serial.println("%"); + } + loopCount++; + + +} diff --git a/examples/Delay/AnalogDelayDemoExpansion/name.c b/examples/Delay/AnalogDelayDemoExpansion/name.c new file mode 100644 index 0000000..5ea00fe --- /dev/null +++ b/examples/Delay/AnalogDelayDemoExpansion/name.c @@ -0,0 +1,19 @@ +// To give your project a unique name, this code must be +// placed into a .c file (its own tab). It can not be in +// a .cpp file or your main sketch (the .ino file). + +#include "usb_names.h" + +// Edit these lines to create your own name. The length must +// match the number of characters in your custom name. + +#define MIDI_NAME {'B','l','a','c','k','a','d','d','r',' ','A','u','d','i','o',' ','T','G','A',' ','P','r','o'} +#define MIDI_NAME_LEN 23 + +// Do not change this part. This exact format is required by USB. + +struct usb_string_descriptor_struct usb_string_product_name = { + 2 + MIDI_NAME_LEN * 2, + 3, + MIDI_NAME +}; diff --git a/src/BAGuitar.h b/src/BAGuitar.h index d4c4622..1abaff0 100644 --- a/src/BAGuitar.h +++ b/src/BAGuitar.h @@ -32,5 +32,6 @@ #include "AudioEffectSOS.h" #include "LibBasicFunctions.h" #include "LibMemoryManagement.h" +#include "BAPhysicalControls.h" #endif /* __BATGUITAR_H */ diff --git a/src/BAHardware.h b/src/BAHardware.h index a609731..232f0dc 100644 --- a/src/BAHardware.h +++ b/src/BAHardware.h @@ -31,10 +31,12 @@ namespace BALibrary { // uncomment the line that corresponds to your hardware +//#define TGA_PRO_REVA +#if (!defined(TGA_PRO_REVA) && !defined(TGA_PRO_REVB)) #define TGA_PRO_REVA -//#define TGA_PRO_REVB // does not exist yet +#endif -#ifdef TGA_PRO_REVA +#if defined(TGA_PRO_REVA) || defined(TGA_PRO_REVB) constexpr uint8_t USR_LED_ID = 16; ///< Teensy IO number for the user LED. @@ -93,6 +95,24 @@ constexpr size_t SPI_MEM1_MAX_AUDIO_SAMPLES = SPI_MEM1_SIZE_BYTES/sizeof(int16_t #endif +#if defined (TGA_PRO_EXPAND_REV2) +/**************************************************************************//** + * Blackaddr Audio Expansion Board + *****************************************************************************/ +constexpr unsigned BA_EXPAND_NUM_POT = 3; +constexpr unsigned BA_EXPAND_NUM_SW = 2; +constexpr unsigned BA_EXPAND_NUM_LED = 2; +constexpr unsigned BA_EXPAND_NUM_ENC = 0; + +constexpr uint8_t BA_EXPAND_POT1_PIN = A16; // 35_A16_PWM +constexpr uint8_t BA_EXPAND_POT2_PIN = A17; // 36_A17_PWM +constexpr uint8_t BA_EXPAND_POT3_PIN = A18; // 37_SCL1_A18_PWM +constexpr uint8_t BA_EXPAND_SW1_PIN = 2; // 2)PWM +constexpr uint8_t BA_EXPAND_SW2_PIN = 3; // 3_SCL2_PWM +constexpr uint8_t BA_EXPAND_LED1_PIN = 4; // 4_SDA2_PWM +constexpr uint8_t BA_EXPAND_LED2_PIN = 6; // 6_PWM +#endif + } // namespace BALibrary diff --git a/src/BAPhysicalControls.h b/src/BAPhysicalControls.h new file mode 100644 index 0000000..a5110d8 --- /dev/null +++ b/src/BAPhysicalControls.h @@ -0,0 +1,148 @@ +/**************************************************************************//** + * @file + * @author Steve Lascos + * @company Blackaddr Audio + * + * BAPhysicalControls is a general purpose class for handling an array of + * pots and switches. + * + * @copyright 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 . + *****************************************************************************/ +#ifndef __BAPHYSICALCONTROLS_H +#define __BAPHYSICALCONTROLS_H + +#include +#include +#include + +namespace BALibrary { + +class DigitalOutput { +public: + DigitalOutput(uint8_t pin) : m_pin(pin) {} + void set(int val); + void toggle(void); + +private: + uint8_t m_pin; + int m_val = 0; +}; + +class Potentiometer { +public: + struct Calib { + unsigned min; + unsigned max; + bool swap; + }; + Potentiometer(uint8_t pin, unsigned minCalibration, unsigned maxCalibration) + : m_pin(pin), m_swapDirection(false), m_minCalibration(minCalibration), m_maxCalibration(maxCalibration) {} + + Potentiometer(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection) + : m_pin(pin), m_swapDirection(swapDirection), m_minCalibration(minCalibration), m_maxCalibration(maxCalibration) {} + + bool getValue(float &value); + int getRawValue(); + void adjustCalibrationThreshold(float thresholdFactor); + static Calib calibrate(uint8_t pin); + +private: + uint8_t m_pin; + bool m_swapDirection; + unsigned m_minCalibration; + unsigned m_maxCalibration; + unsigned m_lastValue = 0; + unsigned m_lastValue2 = 0; +}; + +constexpr bool ENCODER_SWAP = true; +constexpr bool ENCODER_NOSWAP = false; + +class RotaryEncoder : public Encoder { +public: + RotaryEncoder(uint8_t pin1, uint8_t pin2, bool swapDirection = false, int divider = 1) : Encoder(pin1,pin2), m_swapDirection(swapDirection), m_divider(divider) {} + + int getChange(); + void setDivider(int divider); + +private: + bool m_swapDirection; + int32_t m_lastPosition = 0; + int32_t m_divider; +}; + +/// Specifies the type of control +enum class ControlType : unsigned { + SWITCH_MOMENTARY = 0, ///< a momentary switch, which is only on when pressed. + SWITCH_LATCHING = 1, ///< a latching switch, which toggles between on and off with each press and release + ROTARY_KNOB = 2, ///< a rotary encoder knob + POT = 3, ///< an analog potentiometer + UNDEFINED = 255 ///< undefined or uninitialized +}; + +class BAPhysicalControls { +public: + BAPhysicalControls() = delete; + BAPhysicalControls(unsigned numSwitches, unsigned numPots, unsigned numEncoders = 0, unsigned numOutputs = 0); + ~BAPhysicalControls() {} + + /// add a rotary encoders to the controls + /// @param pin1 the pin number corresponding to 'A' on the encoder + /// @param pin2 the pin number corresponding to 'B' on the encoder + /// @param swapDirection When true, reverses which rotation direction is positive, and which is negative + /// @param divider optional, for encoders with high resolution this divides down the rotation measurement. + /// @returns the index in the encoder vector the new encoder was placed at. + unsigned addRotary(uint8_t pin1, uint8_t pin2, bool swapDirection = false, int divider = 1); + + /// add a switch to the controls + /// @param pin the pin number connected to the switch + /// @param intervalMilliseconds, optional, specifies the filtering time to debounce a switch + /// @returns the index in the switch vector the new switch was placed at. + unsigned addSwitch(uint8_t pin, unsigned long intervalMilliseconds = 10); + + /// add a pot to the controls + /// @param pin the pin number connected to the wiper of the pot + /// @param minCalibration the value corresponding to lowest pot setting + /// @param maxCalibration the value corresponding to the highest pot setting + unsigned addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration); + + /// add a pot to the controls + /// @param pin the pin number connected to the wiper of the pot + /// @param minCalibration the value corresponding to lowest pot setting + /// @param maxCalibration the value corresponding to the highest pot setting + /// @param swapDirection reverses the which direction is considered pot minimum value + /// @param range the pot raw value will be mapped into a range of 0 to range + unsigned addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection); + unsigned addOutput(uint8_t pin); + void setOutput(unsigned index, int val); + void toggleOutput(unsigned index); + int getRotaryAdjustUnit(unsigned index); + bool checkPotValue(unsigned index, float &value); + bool isSwitchToggled(unsigned index); + +private: + std::vector m_pots; + std::vector m_encoders; + std::vector m_switches; + std::vector m_outputs; +}; + + + + + +} // BALibrary + + +#endif /* __BAPHYSICALCONTROLS_H */ diff --git a/src/peripherals/BAPhysicalControls.cpp b/src/peripherals/BAPhysicalControls.cpp new file mode 100644 index 0000000..cf91185 --- /dev/null +++ b/src/peripherals/BAPhysicalControls.cpp @@ -0,0 +1,220 @@ +/* + * BAPhysicalControls.cpp + * + * This file provides a class for handling physical controls such as + * switches, pots and rotary encoders. + * + * 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 "BAPhysicalControls.h" + +// These calls must be define in order to get vector to work on arduino +namespace std { +void __throw_bad_alloc() { + Serial.println("Unable to allocate memory"); + abort(); +} +void __throw_length_error( char const*e ) { + Serial.print("Length Error :"); Serial.println(e); + abort(); +} +} + +namespace BALibrary { + +BAPhysicalControls::BAPhysicalControls(unsigned numSwitches, unsigned numPots, unsigned numEncoders, unsigned numOutputs) { + if (numSwitches > 0) { + m_switches.reserve(numSwitches); + } + if (numPots > 0) { + m_pots.reserve(numPots); + } + if (numEncoders > 0) { + m_encoders.reserve(numEncoders); + } + if (numOutputs > 0) { + m_outputs.reserve(numOutputs); + } + +} + +unsigned BAPhysicalControls::addRotary(uint8_t pin1, uint8_t pin2, bool swapDirection, int divider) { + m_encoders.emplace_back(pin1, pin2, swapDirection, divider); + pinMode(pin1, INPUT); + pinMode(pin2, INPUT); + return m_encoders.size()-1; +} + +unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMilliseconds) { + m_switches.emplace_back(pin, intervalMilliseconds); + pinMode(pin, INPUT); + return m_switches.size()-1; +} + +unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration) { + m_pots.emplace_back(pin, minCalibration, maxCalibration); + return m_pots.size()-1; +} + +unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection) { + m_pots.emplace_back(pin, minCalibration, maxCalibration, swapDirection); + return m_pots.size()-1; +} + +unsigned BAPhysicalControls::addOutput(uint8_t pin) { + m_outputs.emplace_back(pin); + pinMode(pin, OUTPUT); + return m_outputs.size()-1; +} + +void BAPhysicalControls::setOutput(unsigned index, int val) { + if (index >= m_outputs.size()) { return; } + m_outputs[index].set(val); +} + +void BAPhysicalControls::toggleOutput(unsigned index) { + if (index >= m_outputs.size()) { return; } + m_outputs[index].toggle(); +} + + +int BAPhysicalControls::getRotaryAdjustUnit(unsigned index) { + if (index >= m_encoders.size()) { return 0; } // index is greater than number of encoders + + int encoderAdjust = m_encoders[index].getChange(); + if (encoderAdjust != 0) { + // clip the adjust to maximum abs value of 1. + int encoderAdjust = (encoderAdjust > 0) ? 1 : -1; + } + + return encoderAdjust; +} + +bool BAPhysicalControls::checkPotValue(unsigned index, float &value) { + if (index >= m_pots.size()) { return false;} // index is greater than number of pots + return m_pots[index].getValue(value); +} + +bool BAPhysicalControls::isSwitchToggled(unsigned index) { + if (index >= m_switches.size()) { return 0; } // index is greater than number of switches + Bounce &sw = m_switches[index]; + + if (sw.update() && sw.fallingEdge()) { + return true; + } else { + return false; + } +} + +/////////////////////////// + +void DigitalOutput::set(int val) { + m_val = val; + digitalWriteFast(m_pin, m_val); +} + +void DigitalOutput::toggle(void) { + m_val = !m_val; + digitalWriteFast(m_pin, m_val); +} + + +bool Potentiometer::getValue(float &value) { + + unsigned val = analogRead(m_pin); // read the raw value + // Return false if the value is the same as the last sample, or 2 samples ago. The second check is to + // prevent oscillating between two values. + if ((val == m_lastValue) || (val == m_lastValue2)) { + return false; + } + + // Otherwise update the last value + m_lastValue = val; + // constrain it within the calibration values, them map it to the desired range. + val = constrain(val, m_minCalibration, m_maxCalibration); + value = static_cast(val - m_minCalibration) / static_cast(m_maxCalibration); + if (m_swapDirection) { + value = 1.0f - value; + } + return true; +} + +int Potentiometer::getRawValue() { + return analogRead(m_pin); +} + +void Potentiometer::adjustCalibrationThreshold(float thresholdFactor) +{ + float threshold = m_maxCalibration * thresholdFactor; + m_maxCalibration -= static_cast(threshold); + m_minCalibration += static_cast(threshold); +} + +Potentiometer::Calib Potentiometer::calibrate(uint8_t pin) { + Calib calib; + + Serial.print("Calibration pin "); Serial.println(pin); + Serial.println("Move the pot fully counter-clockwise to the minimum setting and press any key then ENTER"); + while (true) { + delay(100); + if (Serial.available() > 0) { + calib.min = analogRead(pin); + while (Serial.available()) { Serial.read(); } + break; + } + } + + Serial.println("Move the pot fully clockwise to the maximum setting and press any key then ENTER"); + while (true) { + delay(100); + if (Serial.available() > 0) { + calib.max = analogRead(pin); + while (Serial.available()) { Serial.read(); } + break; + } + } + + if (calib.min > calib.max) { + unsigned tmp = calib.max; + calib.max = calib.min; + calib.min = tmp; + calib.swap = true; + } + + Serial.print("The calibration for pin "); Serial.print(pin); + Serial.print(" is min:"); Serial.print(calib.min); + Serial.print(" max:"); Serial.print(calib.max); + Serial.print(" swap: "); Serial.println(calib.swap); + + return calib; +} + + +int RotaryEncoder::getChange() { + int32_t newPosition = read(); + int delta = newPosition - m_lastPosition; + m_lastPosition = newPosition; + if (m_swapDirection) { delta = -delta; } + return delta/m_divider; +} + +void RotaryEncoder::setDivider(int divider) { + m_divider = divider; +} + +} // BALibrary + + + + diff --git a/src/peripherals/BASpiMemory.cpp b/src/peripherals/BASpiMemory.cpp index d91d7a7..a1fab91 100644 --- a/src/peripherals/BASpiMemory.cpp +++ b/src/peripherals/BASpiMemory.cpp @@ -381,7 +381,7 @@ void BASpiMemoryDMA::write(size_t address, uint8_t *src, size_t numBytes) uint8_t *srcPtr = src; size_t nextAddress = address; while (bytesRemaining > 0) { - m_txXferCount = min(bytesRemaining, MAX_DMA_XFER_SIZE); + m_txXferCount = min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE)); while ( m_txTransfer[1].busy()) {} // wait until not busy m_setSpiCmdAddr(SPI_WRITE_CMD, nextAddress, m_txCommandBuffer); m_txTransfer[1] = DmaSpi::Transfer(m_txCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); @@ -402,7 +402,7 @@ void BASpiMemoryDMA::zero(size_t address, size_t numBytes) size_t bytesRemaining = numBytes; size_t nextAddress = address; while (bytesRemaining > 0) { - m_txXferCount = min(bytesRemaining, MAX_DMA_XFER_SIZE); + m_txXferCount = min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE)); while ( m_txTransfer[1].busy()) {} // wait until not busy m_setSpiCmdAddr(SPI_WRITE_CMD, nextAddress, m_txCommandBuffer); m_txTransfer[1] = DmaSpi::Transfer(m_txCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); @@ -440,7 +440,7 @@ void BASpiMemoryDMA::read(size_t address, uint8_t *dest, size_t numBytes) m_rxTransfer[1] = DmaSpi::Transfer(m_rxCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); m_spiDma->registerTransfer(m_rxTransfer[1]); - m_rxXferCount = min(bytesRemaining, MAX_DMA_XFER_SIZE); + m_rxXferCount = min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE)); while ( m_rxTransfer[0].busy()) {} m_rxTransfer[0] = DmaSpi::Transfer(nullptr, m_rxXferCount, destPtr, 0, m_cs, TransferType::NO_START_CS); m_spiDma->registerTransfer(m_rxTransfer[0]);