diff --git a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino index 6127f2c..cae40c4 100644 --- a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino +++ b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino @@ -1,17 +1,17 @@ /************************************************************************* * This demo uses the BALibrary library to provide enhanced control of * the TGA Pro board. - * + * * The latest copy of the BA Guitar library can be obtained from * https://github.com/Blackaddr/BALibrary - * + * * This example demonstrates teh BAAudioEffectsAnalogDelay effect. It can * be controlled using USB MIDI. You can get a free USB MIDI Controller - * appliation at + * appliation at * http://www.blackaddr.com/downloads/BAMidiTester/ * or the source code at * https://github.com/Blackaddr/BAMidiTester - * + * * Even if you don't control the guitar effect with USB MIDI, you must set * the Arduino IDE USB-Type under Tools to "Serial + MIDI" */ @@ -83,7 +83,7 @@ void OnControlChange(byte channel, byte control, byte value) { Serial.print(", value="); Serial.print(value, DEC); Serial.println(); - #endif + #endif } void setup() { @@ -96,7 +96,7 @@ void setup() { //SPI_MEM0_4M(); // Older REVA and REVB boards came with 4M or 1M //SPI_MEM0_1M(); #endif - + delay(100); Serial.begin(57600); // Start the serial port @@ -117,6 +117,7 @@ void setup() { Serial.println("Using EXTERNAL memory"); // We have to request memory be allocated to our slot. externalSram.requestMemory(&delaySlot, 500.0f, MemSelect::MEM0, true); + delaySlot.clear(); #else Serial.println("Using INTERNAL memory"); #endif @@ -126,7 +127,7 @@ void setup() { MIDI.setHandleControlChange(OnControlChange); usbMIDI.setHandleControlChange(OnControlChange); - + // Configure which MIDI CC's will control the effect parameters analogDelay.mapMidiControl(AudioEffectAnalogDelay::BYPASS,16); analogDelay.mapMidiControl(AudioEffectAnalogDelay::DELAY,20); @@ -136,7 +137,7 @@ void setup() { // Besure to enable the delay. When disabled, audio is is completely blocked // to minimize resources to nearly zero. - analogDelay.enable(); + analogDelay.enable(); // Set some default values. // These can be changed by sending MIDI CC messages over the USB using @@ -162,7 +163,7 @@ void setup() { void loop() { // usbMIDI.read() needs to be called rapidly from loop(). - + if (timer > 1000) { timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); diff --git a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino index b12bb23..034d50a 100644 --- a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino +++ b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino @@ -1,24 +1,24 @@ /************************************************************************* * This demo uses the BALibrary library to provide enhanced control of * the TGA Pro board. - * + * * The latest copy of the BA Guitar library can be obtained from * https://github.com/Blackaddr/BALibrary - * + * * This example demonstrates teh BAAudioEffectsAnalogDelay effect. It can * be controlled using the Blackaddr Audio "Expansion Control Board". - * + * * POT1 (left) controls amount of delay * POT2 (right) controls amount of feedback * POT3 (center) controls the wet/dry mix * SW1 will enable/bypass the audio effect. LED1 will be on when effect is enabled. * SW2 will cycle through the 3 pre-programmed analog filters. LED2 will be on when SW2 is pressed. - * + * * !!! SET POTS TO REASONABLE VALUES BEFORE STARTING TO AVOID SCREECHING FEEDBACK!!!! * - set POT1 (delay) fully counter-clockwise then increase it slowly. * - set POT2 (feedback) fully counter-clockwise, then increase it slowly * - set POT3 (wet/dry mix) to half-way at the detent. - * + * * Using the Serial Montitor, send 'u' and 'd' characters to increase or decrease * the headphone volume between values of 0 and 9. */ @@ -79,7 +79,7 @@ AudioConnection rightOut(analogDelay,0, i2sOut, 1); // - LED2 (right) will illuminate when pressing SW2. ////////////////////////////////////////// // To get the calibration values for your particular board, first run the -// BAExpansionCalibrate.ino example and +// BAExpansionCalibrate.ino example and constexpr int potCalibMin = 1; constexpr int potCalibMax = 1018; constexpr bool potSwapDirection = true; @@ -100,27 +100,27 @@ void setup() { TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. //TGA_PRO_REVB(x); //TGA_PRO_REVA(x); - + #ifdef USE_EXT SPI_MEM0_64M(); // Optional 64Mbit SPI RAM //SPI_MEM0_4M(); // Older REVB and REVA boards offered 1M or 4M - //SPI_MEM0_1M(); + //SPI_MEM0_1M(); #endif - + delay(100); // wait a bit for serial to be available Serial.begin(57600); // Start the serial port delay(100); // Configure the hardware - + // Setup the controls. The return value is the handle to use when checking for control changes, etc. // pushbuttons bypassHandle = controls.addSwitch(BA_EXPAND_SW1_PIN); // will be used for bypass control filterHandle = controls.addSwitch(BA_EXPAND_SW2_PIN); // will be used for stepping through filters // pots delayHandle = controls.addPot(BA_EXPAND_POT1_PIN, potCalibMin, potCalibMax, potSwapDirection); // control the amount of delay - feedbackHandle = controls.addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection); - mixHandle = controls.addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); + feedbackHandle = controls.addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection); + mixHandle = controls.addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); // leds led1Handle = controls.addOutput(BA_EXPAND_LED1_PIN); led2Handle = controls.addOutput(BA_EXPAND_LED2_PIN); // will illuminate when pressing SW2 @@ -140,18 +140,19 @@ void setup() { Serial.println("Using EXTERNAL memory"); // We have to request memory be allocated to our slot. externalSram.requestMemory(&delaySlot, 500.0f, MemSelect::MEM0, true); + delaySlot.clear(); #else Serial.println("Using INTERNAL memory"); #endif // Besure to enable the delay. When disabled, audio is is completely blocked by the effect // to minimize resource usage to nearly to nearly zero. - analogDelay.enable(); + analogDelay.enable(); // Set some default values. // These can be changed using the controls on the Blackaddr Audio Expansion Board analogDelay.bypass(false); - controls.setOutput(led1Handle, !analogDelay.isBypass()); // Set the LED when NOT bypassed + controls.setOutput(led1Handle, !analogDelay.isBypass()); // Set the LED when NOT bypassed analogDelay.mix(0.5f); analogDelay.feedback(0.0f); @@ -178,7 +179,7 @@ void loop() { bool bypass = analogDelay.isBypass(); // get the current state bypass = !bypass; // change it analogDelay.bypass(bypass); // set the new state - controls.setOutput(led1Handle, !bypass); // Set the LED when NOT bypassed + controls.setOutput(led1Handle, !bypass); // Set the LED when NOT bypassed Serial.println(String("BYPASS is ") + bypass); } @@ -217,11 +218,11 @@ void loop() { if (Serial.available() > 0) { while (Serial.available()) { char key = Serial.read(); - if (key == 'u') { + if (key == 'u') { headphoneVolume = (headphoneVolume + 1) % MAX_HEADPHONE_VOL; Serial.println(String("Increasing HEADPHONE volume to ") + headphoneVolume); } - else if (key == 'd') { + else if (key == 'd') { headphoneVolume = (headphoneVolume - 1) % MAX_HEADPHONE_VOL; Serial.println(String("Decreasing HEADPHONE volume to ") + headphoneVolume); } @@ -231,7 +232,7 @@ void loop() { } delay(20); // Without some minimal delay here it will be difficult for the pots/switch changes to be detected. - + if (timer > 1000) { timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); diff --git a/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino b/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino index c025600..21cf027 100644 --- a/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino +++ b/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino @@ -1,21 +1,21 @@ /************************************************************************* * This demo uses the BALibrary library to provide enhanced control of * the TGA Pro board. - * + * * The latest copy of the BA Guitar library can be obtained from * https://github.com/Blackaddr/BALibrary - * + * * THIS DEMO REQUIRES THE EXTERNAL SRAM MEM0 - * + * * This demo combines MIDI control with the BAAudioEffectSoundOnSound. You can use * the BAMidiTester to control the effect but it's best to use external MIDI footswitch * or the Blackaddr Audio Expansion Control Board. - * + * * User must set the Arduino IDE USB-Type to "Serial + MIDI" in the Tools menu. - * + * * Afters startup, the effect will spend about 5 seconds clearing the audio delay buffer to prevent * any startup pops or clicks from propagating. - * + * */ #include #include @@ -91,7 +91,7 @@ void OnControlChange(byte channel, byte control, byte value) { Serial.print(", value="); Serial.print(value, DEC); Serial.println(); - #endif + #endif } void setup() { @@ -122,7 +122,7 @@ void setup() { // We have to request memory be allocated to our slot. externalSram.requestMemory(&delaySlot, BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM0), MemSelect::MEM0, true); - //externalSram.requestMemory(&delaySlot, 50.0f, MemSelect::MEM0, true); + delaySlot.clear(); // Setup MIDI MIDI.begin(MIDI_CHANNEL_OMNI); @@ -131,7 +131,7 @@ void setup() { // Configure the LED to indicate the gate status sos.setGateLedGpio(USR_LED_ID); - + // Configure which MIDI CC's will control the effect parameters //sos.mapMidiControl(AudioEffectSOS::BYPASS,16); sos.mapMidiControl(AudioEffectSOS::GATE_TRIGGER,16); @@ -143,7 +143,7 @@ void setup() { // Besure to enable the delay. When disabled, audio is is completely blocked // to minimize resources to nearly zero. - sos.enable(); + sos.enable(); // Set some default values. // These can be changed by sending MIDI CC messages over the USB using @@ -170,7 +170,7 @@ void setup() { delay(1000); sos.clear(); - + } void loop() { diff --git a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino index 0cc2dcd..ee24f83 100644 --- a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino +++ b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino @@ -1,29 +1,29 @@ /************************************************************************* * This demo uses the BALibrary library to provide enhanced control of * the TGA Pro board. - * + * * The latest copy of the BA Guitar library can be obtained from * https://github.com/Blackaddr/BALibrary - * + * * THIS DEMO REQUIRES BOTH THE EXTERNAL SRAM AND EXPANSION BOARD ADD-ONS - * + * * This demo combines the Blackaddr Audio Expansion board with the BAAudioEffectSOS, - * which provides sound-on-sound. The pushbuttons control the opening of the effect + * which provides sound-on-sound. The pushbuttons control the opening of the effect * gate, as well as clearing the sound being held. - * + * * The pots control the feedback, as well as the gate opening and close times. - * + * * Afters startup, the effect will spend about 5 seconds clearing the audio delay buffer to prevent * any startup pops or clicks from propagating. - * + * * POT1 - Gate open time. Middle position (detent) is about 2100 ms. * POT2 - gate close time. Middle position (detent) is about 2100 ms. * POT3 - Effect volume. Controls the volume of the SOS effect separate from the normal volume * SW1 - Strum and hold a chord then push this button. Continue holding the button until the LED1 light goes out. * SW2 - Push this button to clear out the sound circulating in the delay. - * + * */ -#include +#include #include "BALibrary.h" #include "BAEffects.h" @@ -86,7 +86,7 @@ AudioConnection outputRight(mixer, 0, i2sOut, 1); // - LED2 (right) will illuminate when pressing SW2. ////////////////////////////////////////// // To get the calibration values for your particular board, first run the -// BAExpansionCalibrate.ino example and +// BAExpansionCalibrate.ino example and constexpr int potCalibMin = 1; constexpr int potCalibMax = 1018; constexpr bool potSwapDirection = true; @@ -125,8 +125,8 @@ void setup() { clearHandle = controls.addSwitch(BA_EXPAND_SW2_PIN); // will be used for stepping through filters // pots openHandle = controls.addPot(BA_EXPAND_POT1_PIN, potCalibMin, potCalibMax, potSwapDirection); // control the amount of delay - closeHandle = controls.addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection); - volumeHandle = controls.addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); + closeHandle = controls.addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection); + volumeHandle = controls.addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); // leds led1Handle = controls.addOutput(BA_EXPAND_LED1_PIN); led2Handle = controls.addOutput(BA_EXPAND_LED2_PIN); // will illuminate when pressing SW2 @@ -142,6 +142,7 @@ void setup() { // We have to request memory be allocated to our slot. externalSram.requestMemory(&delaySlot, BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM0), MemSelect::MEM0, true); + delaySlot.clear(); // Configure the LED to indicate the gate status, this is controlled directly by SOS effect, not by // by BAPhysicalControls @@ -149,7 +150,7 @@ void setup() { // Besure to enable the SOS. When disabled, audio is is completely blocked // to minimize resources to nearly zero. - sos.enable(); + sos.enable(); // Set some default values. // These can be changed by sending MIDI CC messages over the USB using @@ -176,7 +177,7 @@ void setup() { delay(1000); sos.clear(); - + } void loop() { @@ -186,7 +187,7 @@ void loop() { // Check if SW1 has been toggled (pushed) and trigger the gate // LED1 will be directly control by the SOS effect, not by BAPhysicalControls if (controls.isSwitchToggled(gateHandle)) { - sos.trigger(); + sos.trigger(); Serial.println("GATE OPEN is triggered"); } @@ -223,11 +224,11 @@ void loop() { if (Serial.available() > 0) { while (Serial.available()) { char key = Serial.read(); - if (key == 'u') { + if (key == 'u') { headphoneVolume = (headphoneVolume + 1) % MAX_HEADPHONE_VOL; Serial.println(String("Increasing HEADPHONE volume to ") + headphoneVolume); } - else if (key == 'd') { + else if (key == 'd') { headphoneVolume = (headphoneVolume - 1) % MAX_HEADPHONE_VOL; Serial.println(String("Decreasing HEADPHONE volume to ") + headphoneVolume); } @@ -235,9 +236,9 @@ void loop() { } } } - + delay(20); // Without some minimal delay here it will be difficult for the pots/switch changes to be detected. - + if (timer > 1000) { timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); diff --git a/examples/Tests/Multiverse_BasicDemo/DebugPrintf.h b/examples/Tests/Multiverse_BasicDemo/DebugPrintf.h new file mode 100644 index 0000000..59dfca9 --- /dev/null +++ b/examples/Tests/Multiverse_BasicDemo/DebugPrintf.h @@ -0,0 +1,9 @@ +#ifndef DEBUG_PRINTF_H_ +#define DEBUG_PRINTF_H_ + +// Make a safe call to Serial where it checks if the object is valid first. This allows your +// program to work even when no USB serial is connected. Printing to the Serial object when +// no valid connection is present will crash the CPU. +#define DEBUG_PRINT(x) {if (Serial) {x;}} + +#endif diff --git a/examples/Tests/Multiverse_BasicDemo/Multiverse_BasicDemo.ino b/examples/Tests/Multiverse_BasicDemo/Multiverse_BasicDemo.ino new file mode 100644 index 0000000..743ad49 --- /dev/null +++ b/examples/Tests/Multiverse_BasicDemo/Multiverse_BasicDemo.ino @@ -0,0 +1,276 @@ +/*********************************************************************************** + * MULTIVERSE DEMO + * + * This demo program shows how to use BALibrary to access the hardware + * features of the Aviate Audio Multiverse effects processor. + * + * The following are demonstrated in this programming using BALibrary: + * - WM8731 stereo audio codec in master mode (NOTE: not slave mode like TGA Pro + * - Interact with all physical controls + * - Control the 128x64 pixel OLED display (connected to SPI0) + * - Use the 8MB external SRAM (simple memory test) + * + * USAGE INSTRUCTIONS + * - Use the 'Gain' knob to control the input gain on the codec. See checkPot(). + * - Use the 'Level' knob to control output volume with an AudioMixer4 object. + * - Stomp switches S1 and S2 will write status to display, and turn on LED + * - Encoder push-button switches will write status to display when pressed/released + * - Encoder rotary control will adjust a positive/negative count and update display + */ + +#include +#include +#include "BALibrary.h" + +#include "DebugPrintf.h" +#include "PhysicalControls.h" + +using namespace BALibrary; + +// OLED display stuff +#include "Adafruit_SH1106.h" +#include "Adafruit_GFX.h" +#include "Fonts/FreeSansBold9pt7b.h" +constexpr unsigned SCREEN_WIDTH = 128; // OLED display width, in pixels +constexpr unsigned SCREEN_HEIGHT = 64; // OLED display height, in pixels +Adafruit_SH1106 display(37, 35, 10); + +// External SPI RAM +ExternalSramManager sramManager; +ExtMemSlot memSlot; +BASpiMemory spiMem1(SpiDeviceId::SPI_DEVICE1); +unsigned spiAddress = 0; +unsigned spiAddressMax; +unsigned sramStage = 0; // stage 0 is zero, 1 is write, 2 is read +volatile float sramCompletion = 0.0f; +volatile unsigned errorCount = 0; + +AudioInputI2Sslave i2sIn; +AudioOutputI2Sslave i2sOut; +AudioMixer4 volumeOut; + +// i2sIn --> volumeOut(Mixer) --> i2sOut +AudioConnection patchIn0(i2sIn, 0, volumeOut, 0); +AudioConnection patchIn1(i2sIn, 1, volumeOut, 1); +AudioConnection patchOut0(volumeOut,0, i2sOut, 0); +AudioConnection patchOut1(volumeOut,0, i2sOut, 1); + +BAAudioControlWM8731master codec; +elapsedMillis timer; + +// Create a control object using the number of switches, pots, encoders and outputs on the +// Multiverse pedal +BAPhysicalControls controls(6, 4, 4, 2); // (SW, POT, ENC, LED) + +unsigned loopCounter = 0; + +void drawProgressBar(float completion); // declaration + +void drawBlackaddrAudio() { + display.setCursor(0, 24); // (x,y) + display.printf(" Blackaddr"); + display.setCursor(0, 40); // (x,y) + display.printf(" Audio"); +} + +void setup() { + + codec.disable(); // this will reset the codec + + // wait up for the serial to appear for up to 1 second + Serial.begin(57600); + unsigned serialLoopCount = 10; + while (!Serial && (serialLoopCount > 0)) { + delay(100); + serialLoopCount--; + } + + MULTIVERSE(); // constants defined in BALibrary become valid only after this call + SPI_MEM1_64M(); // Declare the correct memory size + + // Init the display + display.begin(SH1106_SWITCHCAPVCC, SH1106_I2C_ADDRESS, true); + display.clearDisplay(); + display.display(); + display.setTextColor(WHITE); // Draw white text + display.setFont(&FreeSansBold9pt7b); + drawBlackaddrAudio(); + display.display(); + + configPhysicalControls(&controls, &codec); + + // Request a memory slot from the external RAM + size_t numBytes = BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM1); + spiAddressMax = BAHardwareConfig.getSpiMemMaxAddr(1)/4; // test the first 25% of memory + bool success = sramManager.requestMemory(&memSlot, numBytes, MemSelect::MEM1, /* no DMA */ false); + if (!success && Serial) { printf("Request for memory slot failed\n\r"); } + + // Allocated audio buffers and enable codec + AudioMemory(64); + codec.enable(); + delay(100); + + // Mixer at full volume + volumeOut.gain(0,1.0f); + volumeOut.gain(1,1.0f); + + // flush the pot filters. The analog measurement of the analog pots is averaged (filtered) + // over time, so at startup you will see a bunch of false changes detected as the filter + // settles. We can force this with a few dozen repeated calls. + for (unsigned i=0; i < 50; i++) { + float potValue; + for (unsigned j=0; j < BA_EXPAND_NUM_POT; j++) { + controls.checkPotValue(j, potValue); + } + delay(10); + } +} + +void loop() { + + // Check all the physical controls for updates + checkPot(0); + checkPot(1); + checkPot(2); + checkPot(3); + + checkSwitch(0); + checkSwitch(1); + checkSwitch(2); + checkSwitch(3); + checkSwitch(4); + checkSwitch(5); + + checkEncoder(0); + checkEncoder(1); + checkEncoder(2); + checkEncoder(3); + + // If the SRAM test is not complete, run the next block + if (sramCompletion < 1.0f) { + nextSpiMemTestBlock(); + } + + // Adjusting one of the knobs/switches will result in its value being display for + // 2 seconds in the check*() functions. + if (timer > 2000) { + loopCounter++; + display.clearDisplay(); + drawBlackaddrAudio(); + drawSramProgress(sramCompletion); + display.display(); + } +} + +// This function will draw on the display which stage the memory test is in, and +// the percentage complete for that stage. +void drawSramProgress(float completion) +{ + if (errorCount > 0) { // If errors, print the error count + display.setCursor(0, SCREEN_HEIGHT-1); + display.printf("Errors: %d", errorCount); + return; + } + + // Draw the SRAM test progress at the bottom of the screen + display.setCursor(0, SCREEN_HEIGHT-1); + switch(sramStage) { + case 0 : display.printf("0 mem:"); break; + case 1 : display.printf("0 chk:"); break; + case 2 : display.printf("wr mem:"); break; + case 3 : display.printf("rd mem:"); break; + case 4 : // same as default + default: display.printf("Done"); break; + } + display.setCursor(SCREEN_WIDTH*0.63f, SCREEN_HEIGHT-1); // position to lower right corner + display.printf("%0.f%%", 100.0f * completion); +} + +// Create a predictable data pattern based on address. +constexpr int mask0 = 0x5555; +constexpr int mask1 = 0xaaaa; +int calcNextData(int spiAddress, int loopPhase, int maskPhase) +{ + int data; + + int phase = ((loopPhase << 1) + maskPhase) & 0x3; + switch(phase) + { + case 0 : + data = spiAddress ^ mask0; + break; + case 1: + data = spiAddress ^ mask1; + break; + case 2: + data = ~spiAddress ^ mask0; + break; + case 3: + data = ~spiAddress ^ mask1; + + } + return (data & 0xffff); +} + +// Process the next block of data in the memory test +void nextSpiMemTestBlock() +{ + constexpr unsigned BLOCK_SIZE_BYTES = 256; // transfer 256 bytes (arbitrary) per transaction + constexpr unsigned NUM_BLOCK_WORDS = BLOCK_SIZE_BYTES; + static uint8_t buffer[BLOCK_SIZE_BYTES]; + static int16_t buffer16a[NUM_BLOCK_WORDS]; + static int16_t buffer16b[NUM_BLOCK_WORDS]; + static int maskPhase = 0; + + if (sramStage == 0) { // Zero write + // zero the memory + while (spiMem1.isWriteBusy()) {} // wait for DMA write to complete + memSlot.zero(spiAddress, BLOCK_SIZE_BYTES); + spiAddress += BLOCK_SIZE_BYTES; + + } else if (sramStage == 1) { // Zero check + memSlot.read(spiAddress, buffer, BLOCK_SIZE_BYTES); + while (spiMem1.isReadBusy()) {} // wait for DMA read results + for (unsigned i=0; i < BLOCK_SIZE_BYTES; i++) { + if (buffer[i] != 0) { errorCount++; } + } + spiAddress += BLOCK_SIZE_BYTES; + + } + else if (sramStage == 2) { // write test + // Calculate the data for a block + for (unsigned i=0; i spiAddressMax && sramStage < 4) { + spiAddress = 0; sramStage++; sramCompletion = 0.0f; + return; + } + + sramCompletion = (float)spiAddress / (float)spiAddressMax ; +} diff --git a/examples/Tests/Multiverse_BasicDemo/PhysicalControls.cpp b/examples/Tests/Multiverse_BasicDemo/PhysicalControls.cpp new file mode 100644 index 0000000..887b806 --- /dev/null +++ b/examples/Tests/Multiverse_BasicDemo/PhysicalControls.cpp @@ -0,0 +1,222 @@ +#include +#include "Adafruit_SH1106.h" +#include "BALibrary.h" +#include "DebugPrintf.h" + +using namespace BALibrary; + +// Declare the externally shared variables from the main .ino +extern Adafruit_SH1106 display; +extern BAAudioControlWM8731master codec; +extern AudioMixer4 volumeOut; +extern elapsedMillis timer; + +constexpr int displayRow = 36; // Row to start OLED display updates on +constexpr int potCalibMin = 8; +constexpr int potCalibMax = 1016; +constexpr bool potSwapDirection = true; +constexpr bool encSwapDirection = true; +int pot1Handle= -1, pot2Handle = -1, pot3Handle = -1, pot4Handle = -1; +int sw1Handle = -1, sw2Handle = -1, sw3Handle = -1, sw4Handle = -1, sw5Handle = -1, sw6Handle = -1; +int enc1Handle = -1, enc2Handle = -1, enc3Handle = -1, enc4Handle = -1; +int led1Handle = -1, led2Handle = -1; + +BAAudioControlWM8731master *codecPtr = nullptr; +BAPhysicalControls *controlPtr = nullptr; + +// Configure and setup the physical controls +void configPhysicalControls(BAPhysicalControls* controls, BAAudioControlWM8731master* codec) +{ + // Setup the controls. The return value is the handle to use when checking for control changes, etc. + controlPtr = controls; + codecPtr = codec; + + if (!controlPtr) { DEBUG_PRINT(Serial.printf("ERROR: controlPtr is invalid\n\r")); return; } + if (!codecPtr) { DEBUG_PRINT(Serial.printf("ERROR: codecPtr is invalid\n\r")); return; } + + // pushbuttons + sw1Handle = controlPtr->addSwitch(BA_EXPAND_SW1_PIN); + sw2Handle = controlPtr->addSwitch(BA_EXPAND_SW2_PIN); + sw3Handle = controlPtr->addSwitch(BA_EXPAND_SW3_PIN); + sw4Handle = controlPtr->addSwitch(BA_EXPAND_SW4_PIN); + sw5Handle = controlPtr->addSwitch(BA_EXPAND_SW5_PIN); + sw6Handle = controlPtr->addSwitch(BA_EXPAND_SW6_PIN); + // pots + pot1Handle = controlPtr->addPot(BA_EXPAND_POT1_PIN, potCalibMin, potCalibMax, potSwapDirection); + pot2Handle = controlPtr->addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection); + pot3Handle = controlPtr->addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); + pot4Handle = controlPtr->addPot(BA_EXPAND_POT4_PIN, potCalibMin, potCalibMax, potSwapDirection); + + // encoders + enc1Handle = controlPtr->addRotary(BA_EXPAND_ENC1_A_PIN, BA_EXPAND_ENC1_B_PIN, encSwapDirection); + enc2Handle = controlPtr->addRotary(BA_EXPAND_ENC2_A_PIN, BA_EXPAND_ENC2_B_PIN, encSwapDirection); + enc3Handle = controlPtr->addRotary(BA_EXPAND_ENC3_A_PIN, BA_EXPAND_ENC3_B_PIN, encSwapDirection); + enc4Handle = controlPtr->addRotary(BA_EXPAND_ENC4_A_PIN, BA_EXPAND_ENC4_B_PIN, encSwapDirection); + + // leds + led1Handle = controlPtr->addOutput(BA_EXPAND_LED1_PIN); + led2Handle = controlPtr->addOutput(BA_EXPAND_LED2_PIN); // will illuminate when pressing SW2 + +} + +void checkPot(unsigned id) +{ + float potValue; + unsigned handle; + switch(id) { + case 0 : + handle = pot1Handle; + break; + case 1 : + handle = pot2Handle; + break; + case 2 : + handle = pot3Handle; + break; + case 3 : + handle = pot4Handle; + break; + default : + handle = pot1Handle; + } + + if ((handle < 0) || (handle >= controlPtr->getNumPots())) { + DEBUG_PRINT(Serial.printf("ILLEGAL POT HANDLE: %d for id %d\n\r", handle, id)); + return; + } + + if (controlPtr->checkPotValue(handle, potValue)) { + // Pot has changed + DEBUG_PRINT(Serial.println(String("POT") + id + String(" value: ") + potValue)); + + timer = 0; + display.clearDisplay(); + display.setCursor(0,displayRow); + switch(id) { + case 0 : + { + display.printf("Gain: %0.f\n", potValue * 100.0f); + int gain = static_cast(std::roundf(31.0f * potValue)); + codecPtr->setLeftInputGain(gain); + codecPtr->setRightInputGain(gain); + yield(); // give time for i2C transfers to complete + break; + } + case 1 : + { + display.printf("Level: %0.f\n", potValue * 100.0f); + volumeOut.gain(0, potValue); + volumeOut.gain(1, potValue); + break; + } + case 2 : display.printf("Exp T: %0.f\n", potValue * 100.0f); break; + case 3 : display.printf("Exp R: %0.f\n", potValue * 100.0f); break; + } + display.display(); + } + +} + +int checkSwitch(unsigned id, bool getValueOnly=false) +{ + unsigned swHandle = -1; + unsigned ledHandle = -1; + switch(id) { + case 0 : + swHandle = sw1Handle; + ledHandle = led1Handle; + break; + case 1 : + swHandle = sw2Handle; + ledHandle = led2Handle; + break; + case 2 : + swHandle = sw3Handle; + break; + case 3 : + swHandle = sw4Handle; + break; + case 4 : + swHandle = sw5Handle; + break; + case 5 : + swHandle = sw6Handle; + break; + default : + swHandle = sw1Handle; + ledHandle = led1Handle; + } + + if ((swHandle < 0) || (swHandle >= controlPtr->getNumSwitches())) { + DEBUG_PRINT(Serial.printf("ILLEGAL SWITCH HANDLE: %d for id %d\n\r", swHandle, id); Serial.flush()); + return -1; + } + + bool switchValue; + bool changed = controlPtr->hasSwitchChanged(swHandle, switchValue); + if (getValueOnly) { return controlPtr->getSwitchValue(swHandle); } + + if (changed) { + DEBUG_PRINT(Serial.println(String("Button ") + id + String(" pressed"))); + timer = 0; + display.clearDisplay(); + display.setCursor(0, displayRow); + switch(id) { + case 0 : display.printf("S1: %d\n", switchValue); break; + case 1 : display.printf("S2: %d\n", switchValue); break; + case 2 : display.printf("EncSw A: %d\n", switchValue); break; + case 3 : display.printf("EncSw B: %d\n", switchValue); break; + case 4 : display.printf("EncSw C: %d\n", switchValue); break; + case 5 : display.printf("EncSw D: %d\n", switchValue); break; + } + display.display(); + } + + if (swHandle < 2) { // these SWs map to LEDs + bool pressed = controlPtr->isSwitchHeld(swHandle); + controlPtr->setOutput(ledHandle, pressed); + } + return controlPtr->getSwitchValue(swHandle); +} + +void checkEncoder(unsigned id) +{ + unsigned encHandle; + static int enc1 = 0, enc2 = 0, enc3 = 0, enc4 = 0; + switch(id) { + case 0 : + encHandle = enc1Handle; + break; + case 1 : + encHandle = enc2Handle; + break; + case 2 : + encHandle = enc3Handle; + break; + case 3 : + encHandle = enc4Handle; + break; + default : + encHandle = enc1Handle; + } + + if ((encHandle < 0) || (encHandle >= controlPtr->getNumRotary())) { + DEBUG_PRINT(Serial.printf("ILLEGAL ENCODER HANDLE: %d for id %d\n\r", encHandle, id); Serial.flush()); + return; + } + + int adj= controlPtr->getRotaryAdjustUnit(encHandle); + if (adj != 0) { + DEBUG_PRINT(Serial.printf("Enc %d: %d\n\r", id, adj); Serial.flush()); + display.clearDisplay(); + display.setCursor(0, displayRow); + switch(id) { + case 0 : enc1 += adj; display.printf("Enc A: %d", enc1); break; + case 1 : enc2 += adj; display.printf("Enc B: %d", enc2); break; + case 2 : enc3 += adj; display.printf("Enc C: %d", enc3); break; + case 3 : enc4 += adj; display.printf("Enc D: %d", enc4); break; + } + display.display(); + timer = 0; + } +} diff --git a/examples/Tests/Multiverse_BasicDemo/PhysicalControls.h b/examples/Tests/Multiverse_BasicDemo/PhysicalControls.h new file mode 100644 index 0000000..e496388 --- /dev/null +++ b/examples/Tests/Multiverse_BasicDemo/PhysicalControls.h @@ -0,0 +1,11 @@ +#ifndef PHYSICAL_CONTROLS_H_ +#define PHYSICAL_CONTROLS_H_ + +#include "BALibrary.h" + +void configPhysicalControls(BALibrary::BAPhysicalControls* controls, BALibrary::BAAudioControlWM8731master* codec); +void checkPot(unsigned id); +int checkSwitch(unsigned id, bool getValueOnly=false); +void checkEncoder(unsigned id); + +#endif diff --git a/src/BAPhysicalControls.h b/src/BAPhysicalControls.h index eb0201b..31d51b5 100644 --- a/src/BAPhysicalControls.h +++ b/src/BAPhysicalControls.h @@ -238,18 +238,30 @@ public: /// @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); + /// Get the number of registered rotary encoders + /// @returns the number of encoders registered + unsigned getNumRotary(); + /// 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); + /// Get the number of registered switches + /// @returns the number of switches registered + unsigned getNumSwitches(); + /// 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); + /// Get the number of registered pots + /// @returns the number of pots registered + unsigned getNumPots(); + /// 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 @@ -263,6 +275,10 @@ public: /// @returns a handle (unsigned) to the added output. Use this to access the output. unsigned addOutput(uint8_t pin); + /// Get the number of registered outputs + /// @returns the number of outputs registered + unsigned getNumOutputs(); + /// Set the output specified by the provided handle /// @param handle the handle that was provided previously by calling addOutput() /// @param val the value to set the output. 0 is low, not zero is high. diff --git a/src/DmaSpi.h b/src/DmaSpi.h index e7b576e..dfa61c8 100644 --- a/src/DmaSpi.h +++ b/src/DmaSpi.h @@ -114,7 +114,7 @@ class ActiveLowChipSelect : public AbstractChipSelect }; -#if defined(__MK66FX1M0__) +#if defined(__MK66FX1M0__) || (defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)) class ActiveLowChipSelect1 : public AbstractChipSelect { public: @@ -154,7 +154,7 @@ class ActiveLowChipSelect1 : public AbstractChipSelect const SPISettings settings_; }; -#endif +#endif // defined(__MK66FX1M0__) || (defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)) @@ -764,37 +764,8 @@ public: IMXRT_LPSPI4_S.DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE; //enable DMA on both TX and RX IMXRT_LPSPI4_S.SR = 0x3f00; // clear out all of the other status... -// if (m_pCurrentTransfer->m_pSource) { -// arm_dcache_flush((void *)m_pCurrentTransfer->m_pSource, m_pCurrentTransfer->m_transferCount); -// } - } -// static void pre_cs_impl() -// { -// -// //LPSPI4_PARAM = LPSPI4_PARAM; -// //LPSPI4_PARAM = 0x0404; -// //DMASPI_PRINT(("!!!!!!!!!!!!!!!!!!!!!PARAM reg is %08X\n", LPSPI4_PARAM)); -// txChannel_()->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode... -// txChannel_()->TCD->SLAST = 0; // Finish with it pointing to next location -// rxChannel_()->TCD->ATTR_DST = 0; //Make sure set for 8 bit mode... -// rxChannel_()->TCD->DLASTSGA = 0; -// -// //DMASPI_PRINT(("STATUS SR reg is %08X\n", LPSPI4_SR)); -// if (LPSPI4_SR & 0x1800) { -// DMASPI_PRINT(("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ERROR SR reg is %08X\n", LPSPI4_SR)); -// } -// LPSPI4_SR = 0x3f00; // clear various error and status flags -// DMASPI_PRINT(("********************************************CHECK SR reg is %08X\n", LPSPI4_SR)); -// -// LPSPI4_TCR = (LPSPI4_TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7); // Set the FRAMESZ to 7 for 8-bit frame size -// LPSPI4_FCR = 0; // set watermarks to zero, this ensures ready flag is set whenever fifo is not empty -// -// LPSPI4_CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; //enable module and reset both FIFOs -// LPSPI4_DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE; // enable DMA on both TX and RX -// } - static void post_cs_impl() { rxChannel_()->enable(); @@ -810,23 +781,76 @@ public: IMXRT_LPSPI4_S.CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; // actually clear both... IMXRT_LPSPI4_S.SR = 0x3f00; // clear out all of the other status... -// if (m_pCurrentTransfer->m_pDest) { -// arm_dcache_delete((void *)m_pCurrentTransfer->m_pDest, m_pCurrentTransfer->m_transferCount); -// } } -// static void post_finishCurrentTransfer_impl() -// { -// //LPSPI4_FCR = LPSPI_FCR_TXWATER(15); // restore FSR status -// LPSPI4_DER = 0; // DMA no longer doing TX or RX -// LPSPI4_CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; //enable module and reset both FIFOs -// LPSPI4_SR = 0x3f00; // clear out all the other statuses -// } +private: +}; +extern DmaSpi0 DMASPI0; + +#if (defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)) +// On T4.X, SPI1 is LPSPI3 + +class DmaSpi1 : public AbstractDmaSpi +{ +public: + static void begin_setup_txChannel_impl() + { + txChannel_()->disable(); + txChannel_()->destination((volatile uint8_t&)IMXRT_LPSPI3_S.TDR); + txChannel_()->disableOnCompletion(); + txChannel_()->triggerAtHardwareEvent(DMAMUX_SOURCE_LPSPI3_TX); + } + + static void begin_setup_rxChannel_impl() + { + rxChannel_()->disable(); + rxChannel_()->source((volatile uint8_t&)IMXRT_LPSPI3_S.RDR); // POPR is the receive fifo register for the SPI + rxChannel_()->disableOnCompletion(); + rxChannel_()->triggerAtHardwareEvent(DMAMUX_SOURCE_LPSPI3_RX); // The DMA RX id for MT66 is 14 + rxChannel_()->attachInterrupt(rxIsr_); + rxChannel_()->interruptAtCompletion(); + + } + + static void pre_cs_impl() + { + if (LPSPI3_SR & 0x1800) { + DMASPI_PRINT(("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ERROR SR reg is %08X\n\r", LPSPI3_SR)); + } + DMASPI_PRINT(("********************************************CHECK SR reg is %08X\n\r", LPSPI3_SR)); + + IMXRT_LPSPI3_S.TCR = (IMXRT_LPSPI3_S.TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7); + IMXRT_LPSPI3_S.FCR = 0; + + IMXRT_LPSPI3_S.CR = LPSPI_CR_MEN; // I had to add the enable otherwise it wont' work + + // Lets try to output the first byte to make sure that we are in 8 bit mode... + IMXRT_LPSPI3_S.DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE; //enable DMA on both TX and RX + IMXRT_LPSPI3_S.SR = 0x3f00; // clear out all of the other status... + + } + + static void post_cs_impl() + { + rxChannel_()->enable(); + txChannel_()->enable(); + DMASPI_PRINT(("Done post_cs_impl()\n\r")); + } + + static void post_finishCurrentTransfer_impl() + { + IMXRT_LPSPI3_S.FCR = LPSPI_FCR_TXWATER(15); // _spi_fcr_save; // restore the FSR status... + IMXRT_LPSPI3_S.DER = 0; // DMA no longer doing TX (or RX) + + IMXRT_LPSPI3_S.CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; // actually clear both... + IMXRT_LPSPI3_S.SR = 0x3f00; // clear out all of the other status... + } private: }; +extern DmaSpi1 DMASPI1; -extern DmaSpi0 DMASPI0; +#endif // (defined(__IMXRT1062__) && defined(ARDUINO_TEENSY_MICROMOD)) #elif defined(KINETISK) @@ -1050,7 +1074,7 @@ public: // { // DMASPI_PRINT(("%s: %x %x %x %x \n", sz, p[0], p[1], p[2], p[3])); // } - + static void post_cs_impl() { DMASPI_PRINT(("post_cs S C1 C2: %x %x %x\n", SPI1_S, SPI1_C1, SPI1_C2)); diff --git a/src/common/ExternalSramManager.cpp b/src/common/ExternalSramManager.cpp index c4713ab..1de2500 100644 --- a/src/common/ExternalSramManager.cpp +++ b/src/common/ExternalSramManager.cpp @@ -89,7 +89,7 @@ bool ExternalSramManager::requestMemory(ExtMemSlot *slot, size_t sizeBytes, BALi if (!m_memConfig[mem].m_spi) { if (Serial) { Serial.printf("Failed to create SPI for id %d\n\r", (int)mem);} } else { - Serial.println("Calling spi begin()"); + if (Serial) { Serial.println("Calling spi begin()"); } m_memConfig[mem].m_spi->begin(); } } @@ -100,15 +100,14 @@ bool ExternalSramManager::requestMemory(ExtMemSlot *slot, size_t sizeBytes, BALi m_memConfig[mem].totalAvailable -= sizeBytes; slot->m_valid = true; if (!slot->isEnabled()) { slot->enable(); } - Serial.println("Clear the memory\n"); Serial.flush(); - slot->clear(); - Serial.println("Done Request memory\n"); Serial.flush(); + // Note: we no longer auto-clear the slot (on purpose) + if (Serial) { Serial.println("Done Request memory\n"); Serial.flush(); } return true; } else { // there is not enough memory available for the request - Serial.println(String("ExternalSramManager::requestMemory(): Insufficient memory in slot, request/available: ") + if (Serial) { Serial.println(String("ExternalSramManager::requestMemory(): Insufficient memory in slot, request/available: ") + sizeBytes + String(" : ") - + m_memConfig[mem].totalAvailable); + + m_memConfig[mem].totalAvailable); } return false; } } diff --git a/src/peripherals/BAPhysicalControls.cpp b/src/peripherals/BAPhysicalControls.cpp index 32c16c3..1c4c84e 100644 --- a/src/peripherals/BAPhysicalControls.cpp +++ b/src/peripherals/BAPhysicalControls.cpp @@ -56,6 +56,8 @@ unsigned BAPhysicalControls::addRotary(uint8_t pin1, uint8_t pin2, bool swapDire return m_encoders.size()-1; } +unsigned BAPhysicalControls::getNumRotary() { return m_encoders.size(); } + unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMilliseconds) { m_switches.emplace_back(); m_switches.back().attach(pin); @@ -64,6 +66,8 @@ unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMillis return m_switches.size()-1; } +unsigned BAPhysicalControls::getNumSwitches() { return m_switches.size(); } + unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration) { m_pots.emplace_back(pin, minCalibration, maxCalibration); pinMode(pin, INPUT); @@ -76,12 +80,16 @@ unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsign return m_pots.size()-1; } +unsigned BAPhysicalControls::getNumPots() { return m_pots.size(); } + unsigned BAPhysicalControls::addOutput(uint8_t pin) { m_outputs.emplace_back(pin); pinMode(pin, OUTPUT); return m_outputs.size()-1; } +unsigned BAPhysicalControls::getNumOutputs() { return m_outputs.size(); } + void BAPhysicalControls::setOutput(unsigned handle, int val) { if (handle >= m_outputs.size()) { return; } m_outputs[handle].set(val); diff --git a/src/peripherals/BASpiMemory.cpp b/src/peripherals/BASpiMemory.cpp index 290a5b6..b59079e 100644 --- a/src/peripherals/BASpiMemory.cpp +++ b/src/peripherals/BASpiMemory.cpp @@ -82,7 +82,7 @@ void BASpiMemory::begin() m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; break; -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) +#if defined(ARDUINO_TEENSY_MICROMOD) || defined(__MK64FX512__) || defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : m_csPin = SPI1_CS_PIN; m_spi = &SPI1; @@ -400,7 +400,7 @@ void BASpiMemoryDMA::begin(void) cs = SPI0_CS_PIN; m_cs = new ActiveLowChipSelect(cs, m_settings); break; -#if defined(__MK66FX1M0__) +#if defined(ARDUINO_TEENSY_MICROMOD) || defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : cs = SPI1_CS_PIN; m_cs = new ActiveLowChipSelect1(cs, m_settings); @@ -415,8 +415,8 @@ void BASpiMemoryDMA::begin(void) m_rxCommandBuffer = new uint8_t[CMD_ADDRESS_SIZE]; m_txTransfer = new DmaSpi::Transfer[2]; m_rxTransfer = new DmaSpi::Transfer[2]; - - + + switch (m_memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : m_csPin = SPI0_CS_PIN; @@ -429,7 +429,7 @@ void BASpiMemoryDMA::begin(void) m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; break; -#if defined(__MK66FX1M0__) // DMA on SPI1 is only supported on T3.6 +#if defined(ARDUINO_TEENSY_MICROMOD) || defined(__MK66FX1M0__) // DMA on SPI1 is only supported on T3.6 or Micromod case SpiDeviceId::SPI_DEVICE1 : m_csPin = SPI1_CS_PIN; m_spi = &SPI1; diff --git a/src/peripherals/DmaSpi.cpp b/src/peripherals/DmaSpi.cpp index f837ed3..dcc4ccd 100644 --- a/src/peripherals/DmaSpi.cpp +++ b/src/peripherals/DmaSpi.cpp @@ -1,15 +1,19 @@ #include "DmaSpi.h" -#if defined(__IMXRT1062__) // T4.0 -DmaSpi0 DMASPI0; +#if defined(__IMXRT1062__) // T4.X + DmaSpi0 DMASPI0; + #if defined(ARDUINO_TEENSY_MICROMOD) || defined (ARDUINO_TEENSY41) + DmaSpi1 DMASPI1; + #endif + #elif defined(KINETISK) -DmaSpi0 DMASPI0; -#if defined(__MK66FX1M0__) -DmaSpi1 DMASPI1; -//DmaSpi2 DMASPI2; -#endif + DmaSpi0 DMASPI0; + #if defined(__MK66FX1M0__) + DmaSpi1 DMASPI1; + //DmaSpi2 DMASPI2; + #endif #elif defined (KINETISL) -DmaSpi0 DMASPI0; -DmaSpi1 DMASPI1; -#else + DmaSpi0 DMASPI0; + DmaSpi1 DMASPI1; +#else #endif // defined