From 349f9f7f7b442c8241e649a59c1b351b19a61d58 Mon Sep 17 00:00:00 2001
From: Steve Lascos <steve@blackaddr.com>
Date: Sun, 27 Oct 2019 15:57:51 -0400
Subject: [PATCH] Final checkin for T4 support before hardware release

---
 .../BA1_TGA_Pro_NOMEM_demo.ino                |  4 +-
 .../BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino     | 11 ++---
 .../BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino     | 14 ++++---
 .../Delay/AnalogDelayDemo/AnalogDelayDemo.ino |  1 +
 .../AnalogDelayDemoExpansion.ino              |  6 +--
 .../ExternalDelayDemo/ExternalDelayDemo.ino   |  9 +++-
 .../SoundOnSoundDemo/SoundOnSoundDemo.ino     |  5 ++-
 .../SoundOnSoundExpansionDemo.ino             |  6 ++-
 examples/Modulation/TemoloDemo/TemoloDemo.ino |  1 -
 .../TremoloDemoExpansion.ino                  |  4 +-
 examples/Tests/BaudrateTest/BaudrateTest.ino  |  2 +-
 .../Tests/DMA_MEM0_test/DMA_MEM0_test.ino     | 25 ++++++-----
 .../Tests/DMA_MEM1_test/DMA_MEM1_test.ino     | 24 ++++++-----
 .../TGA_PRO_MEM2_EXP/PhysicalControls.cpp     |  7 ++--
 .../TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino     | 19 +++++----
 examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp  |  5 +--
 examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp   | 10 +++--
 src/BAAudioEffectDelayExternal.h              | 10 +++--
 src/BASpiMemory.h                             |  5 ++-
 src/effects/AudioEffectDelayExternal.cpp      | 42 +++++++++++++------
 src/peripherals/BASpiMemory.cpp               |  1 -
 21 files changed, 125 insertions(+), 86 deletions(-)

diff --git a/examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino b/examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino
index 8eb459f..292c871 100644
--- a/examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino
+++ b/examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino
@@ -8,8 +8,6 @@
  * This demo will provide an audio passthrough, as well as exercise the
  * MIDI interface.
  * 
- * It can optionally exercise the SPI MEM0 if installed on the TGA Pro board.
- * 
  */
 #include <Wire.h>
 #include <Audio.h>
@@ -37,6 +35,7 @@ void setup() {
   MIDI.begin(MIDI_CHANNEL_OMNI);
   Serial.begin(57600);
   delay(5);
+  while (!Serial) { yield(); }
 
   // If the codec was already powered up (due to reboot) power itd own first
   codecControl.disable();
@@ -105,4 +104,3 @@ void loop() {
   gpio.toggleLed();
 
 }
-
diff --git a/examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino b/examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino
index 44ceee4..09481d7 100644
--- a/examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino
+++ b/examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino
@@ -38,7 +38,7 @@ BASpiMemory               spiMem0(SpiDeviceId::SPI_DEVICE0);
 unsigned long t=0;
 
 // SPI stuff
-int spiAddress0 = 0;
+unsigned spiAddress0 = 0;
 uint16_t spiData0 = 0xABCD;
 int spiErrorCount0 = 0;
 
@@ -52,9 +52,11 @@ void setup() {
 
   MIDI.begin(MIDI_CHANNEL_OMNI);
   Serial.begin(57600);
-  while (!Serial) {}
+  while (!Serial) { yield(); }
   delay(5);
 
+  SPI_MEM0_1M(); // Set the Spi memory size to 1Mbit
+
   // If the codec was already powered up (due to reboot) power itd own first
   codecControl.disable();
   delay(100);
@@ -98,7 +100,7 @@ void loop() {
   // Write test data to the SPI Memory 0
   //////////////////////////////////////////////////////////////////
   maskPhase = 0;
-  for (spiAddress0=0; spiAddress0 <= SPI_MAX_ADDR; spiAddress0=spiAddress0+2) {
+  for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) {
     if ((spiAddress0 % 32768) == 0) {
       //Serial.print("Writing to ");
       //Serial.println(spiAddress0, HEX);
@@ -117,7 +119,7 @@ void loop() {
   spiAddress0 = 0;
   maskPhase = 0;
 
-  for (spiAddress0=0; spiAddress0 <= SPI_MAX_ADDR; spiAddress0=spiAddress0+2) {
+  for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) {
     if ((spiAddress0 % 32768) == 0) {
 //      Serial.print("Reading ");
 //      Serial.print(spiAddress0, HEX);
@@ -205,4 +207,3 @@ void loop() {
   gpio.toggleLed();
 
 }
-
diff --git a/examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino b/examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino
index 1887512..5f570a7 100644
--- a/examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino
+++ b/examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino
@@ -57,8 +57,13 @@ void setup() {
 
   MIDI.begin(MIDI_CHANNEL_OMNI);
   Serial.begin(57600);
+  while (!Serial) { yield(); }
   delay(5);
 
+  // Set the SPI memory sizes
+  SPI_MEM0_1M();
+  SPI_MEM1_1M();
+
   // If the codec was already powered up (due to reboot) power itd own first
   codecControl.disable();
   delay(100);
@@ -103,7 +108,7 @@ void loop() {
   // Write test data to the SPI Memory 0
   //////////////////////////////////////////////////////////////////
   maskPhase = 0;
-  for (spiAddress0=0; spiAddress0 <= SPI_MAX_ADDR; spiAddress0=spiAddress0+2) {
+  for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) {
     if ((spiAddress0 % 32768) == 0) {
       //Serial.print("Writing to ");
       //Serial.println(spiAddress0, HEX);
@@ -122,7 +127,7 @@ void loop() {
   spiAddress0 = 0;
   maskPhase = 0;
 
-  for (spiAddress0=0; spiAddress0 <= SPI_MAX_ADDR; spiAddress0=spiAddress0+2) {
+  for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) {
     if ((spiAddress0 % 32768) == 0) {
 //      Serial.print("Reading ");
 //      Serial.print(spiAddress0, HEX);
@@ -159,7 +164,7 @@ void loop() {
   // Write test data to the SPI Memory 1
   //////////////////////////////////////////////////////////////////
   maskPhase = 0;
-  for (spiAddress1=0; spiAddress1 <= SPI_MAX_ADDR; spiAddress1+=2) {
+  for (spiAddress1=0; spiAddress1 <= BAHardwareConfig.getSpiMemMaxAddr(1); spiAddress1+=2) {
     if ((spiAddress1 % 32768) == 0) {
       //Serial.print("Writing to ");
       //Serial.println(spiAddress1, HEX);
@@ -178,7 +183,7 @@ void loop() {
   spiAddress1 = 0;
 
   maskPhase = 0;
-  for (spiAddress1=0; spiAddress1 <= SPI_MAX_ADDR; spiAddress1+=2) {
+  for (spiAddress1=0; spiAddress1 <= BAHardwareConfig.getSpiMemMaxAddr(1); spiAddress1+=2) {
     if ((spiAddress1 % 32768) == 0) {
       //Serial.print("Reading ");
       //Serial.print(spiAddress1, HEX);
@@ -264,4 +269,3 @@ void loop() {
   gpio.toggleLed();
 
 }
-
diff --git a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino
index f68612e..2340fb9 100644
--- a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino
+++ b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino
@@ -82,6 +82,7 @@ void setup() {
   // If using external memory request request memory from the manager
   // for the slot
   #ifdef USE_EXT
+  SPI_MEM0_1M();
   Serial.println("Using EXTERNAL memory");
   // We have to request memory be allocated to our slot.
   externalSram.requestMemory(&delaySlot, 500.0f, MemSelect::MEM0, true);
diff --git a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino
index a0fd4ad..6b04677 100644
--- a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino
+++ b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino
@@ -22,9 +22,6 @@
  * Using the Serial Montitor, send 'u' and 'd' characters to increase or decrease
  * the headphone volume between values of 0 and 9.
  */
-#define TGA_PRO_REVB // Set which hardware revision of the TGA Pro we're using
-#define TGA_PRO_EXPAND_REV2 // pull in the pin definitions for the Blackaddr Audio Expansion Board.
-
 #include "BALibrary.h"
 #include "BAEffects.h"
 
@@ -99,6 +96,9 @@ void setup() {
   Serial.begin(57600); // Start the serial port
   delay(100);
 
+  // Configure the hardware
+  SPI_MEM0_1M();
+
   // 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
diff --git a/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino b/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino
index a6a4eac..1d4ef97 100644
--- a/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino
+++ b/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino
@@ -22,6 +22,7 @@ AudioInputI2S            i2sIn;
 AudioOutputI2S           i2sOut;
 
 BAAudioControlWM8731        codecControl;
+//AudioEffectDelayExternal longDelay;
 BAAudioEffectDelayExternal  longDelay(MemSelect::MEM0); // comment this line to use MEM1
 //BAAudioEffectDelayExternal  longDelay(MemSelect::MEM1); // and uncomment this one to use MEM1
 AudioMixer4                 delayOutMixerA, delayOutMixerB, delayMixer;
@@ -49,12 +50,16 @@ AudioConnection  outputRight(delayMixer, 0, i2sOut, 1);
 void setup() {
 
   Serial.begin(57600);
-  AudioMemory(128);
+  while(!Serial) { yield(); }
+  AudioMemory(64);
   
-  delay(100);
+  delay(500);
   Serial.println(String("Starting...\n"));
   delay(100);
 
+  SPI_MEM0_1M(); // set the SPI MEM0 memory size
+  // SPI_MEM1_1M(); // set the MEM1 memory aize
+
   Serial.println("Enabling codec...\n");
   codecControl.enable();
   delay(100);
diff --git a/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino b/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino
index 7209d07..820642d 100644
--- a/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino
+++ b/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino
@@ -101,13 +101,15 @@ delay(100);
   AudioMemory(128);
   delay(5);
 
+  SPI_MEM0_1M(); // Configure the SPI memory size
+
   // Enable the codec
   Serial.println("Enabling codec...\n");
   codec.enable();
   delay(100);
 
   // We have to request memory be allocated to our slot.
-  externalSram.requestMemory(&delaySlot, SPI_MEM0_SIZE_BYTES, MemSelect::MEM0, true);
+  externalSram.requestMemory(&delaySlot, BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM0), MemSelect::MEM0, true);
   //externalSram.requestMemory(&delaySlot, 50.0f, MemSelect::MEM0, true);
 
   // Setup MIDI
@@ -192,4 +194,3 @@ void loop() {
 //  }
 
 }
-
diff --git a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino
index 1be4d60..f9b7e22 100644
--- a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino
+++ b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino
@@ -100,6 +100,7 @@ delay(100);
   delay(100); // wait a bit for serial to be available
   Serial.begin(57600); // Start the serial port
   delay(100); // wait a bit for serial to be available
+  BAHardwareConfig.set(MemSelect::MEM0, SPI_MEMORY_1M);
 
   // Setup the controls. The return value is the handle to use when checking for control changes, etc.
   // pushbuttons
@@ -117,13 +118,15 @@ delay(100);
   codec.disable();
   AudioMemory(128);
 
+  SPI_MEM0_1M(); // set the Spi memory size
+
   // Enable the codec
   Serial.println("Enabling codec...\n");
   codec.enable();
   codec.setHeadphoneVolume(1.0f); // Max headphone volume
 
   // We have to request memory be allocated to our slot.
-  externalSram.requestMemory(&delaySlot, SPI_MEM0_SIZE_BYTES, MemSelect::MEM0, true);
+  externalSram.requestMemory(&delaySlot, BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM0), MemSelect::MEM0, true);
 
   // Configure the LED to indicate the gate status, this is controlled directly by SOS effect, not by
   // by BAPhysicalControls
@@ -223,4 +226,3 @@ void loop() {
   loopCount++;
 
 }
-
diff --git a/examples/Modulation/TemoloDemo/TemoloDemo.ino b/examples/Modulation/TemoloDemo/TemoloDemo.ino
index d20ea2c..014ecc2 100644
--- a/examples/Modulation/TemoloDemo/TemoloDemo.ino
+++ b/examples/Modulation/TemoloDemo/TemoloDemo.ino
@@ -31,7 +31,6 @@ BAAudioControlWM8731 codec;
 // YOU MUST USE TEENSYDUINO 1.41 or greater
 // YOU MUST COMPILE THIS DEMO USING Serial + Midi
 
-//#define USE_EXT // uncomment this line to use External MEM0
 #define MIDI_DEBUG // uncomment to see raw MIDI info in terminal
 
 AudioEffectTremolo tremolo;
diff --git a/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino b/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino
index 6892fe2..fbbcc14 100644
--- a/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino
+++ b/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino
@@ -18,8 +18,6 @@
  * Using the Serial Montitor, send 'u' and 'd' characters to increase or decrease
  * the headphone volume between values of 0 and 9.
  */
-#define TGA_PRO_REVB // Set which hardware revision of the TGA Pro we're using
-#define TGA_PRO_EXPAND_REV2 // pull in the pin definitions for the Blackaddr Audio Expansion Board.
 
 #include "BALibrary.h"
 #include "BAEffects.h"
@@ -76,6 +74,8 @@ void setup() {
   Serial.begin(57600); // Start the serial port
   delay(100);
 
+  TGA_PRO_EXPAND_REV2(); // Configure the expansion board revision
+
   // 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
diff --git a/examples/Tests/BaudrateTest/BaudrateTest.ino b/examples/Tests/BaudrateTest/BaudrateTest.ino
index 6bf83c0..97c9a6c 100644
--- a/examples/Tests/BaudrateTest/BaudrateTest.ino
+++ b/examples/Tests/BaudrateTest/BaudrateTest.ino
@@ -11,7 +11,7 @@
  */
 constexpr unsigned LOW_RATE = 2400;
 constexpr unsigned MIDI_RATE = 31250;
-constexpr unsigned HIGH_RATE = 250000; 
+constexpr unsigned HIGH_RATE = 230400; 
 constexpr unsigned TEST_TIME = 5; // 5 second test each
 
 unsigned baudRate = LOW_RATE; // start with low speed
diff --git a/examples/Tests/DMA_MEM0_test/DMA_MEM0_test.ino b/examples/Tests/DMA_MEM0_test/DMA_MEM0_test.ino
index cedb884..10edd02 100644
--- a/examples/Tests/DMA_MEM0_test/DMA_MEM0_test.ino
+++ b/examples/Tests/DMA_MEM0_test/DMA_MEM0_test.ino
@@ -55,14 +55,18 @@ bool compareBuffers16(uint16_t *a, uint16_t *b, size_t numWords)
   return compareBuffers(reinterpret_cast<uint8_t *>(a), reinterpret_cast<uint8_t*>(b), sizeof(uint16_t)*numWords);
 }
 
-constexpr size_t TEST_END = SPI_MAX_ADDR;
+size_t SPI_MAX_ADDR;
+;
 
 void setup() {
 
   Serial.begin(57600);
-  while (!Serial) {}
+  while (!Serial) { yield(); }
   delay(5);
 
+  SPI_MEM0_1M();
+  SPI_MAX_ADDR = BAHardwareConfig.getSpiMemMaxAddr(MemSelect::MEM0);
+
   Serial.println("Enabling SPI, testing MEM0");
   spiMem0.begin();
 }
@@ -82,7 +86,7 @@ bool spi8BitTest(void) {
   Serial.println("\nStarting 8-bit test Write/Read");
   while (spiPhase < 4) {
     spiAddress = 0;
-    while (spiAddress < TEST_END) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       
       // fill the write data buffer
       switch (spiPhase) {
@@ -117,7 +121,7 @@ bool spi8BitTest(void) {
   
     // Read back the data using 8-bit transfers
     spiAddress = 0;
-    while (spiAddress < TEST_END) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       // generate the golden data
       switch (spiPhase) {
       case 0 :
@@ -165,7 +169,7 @@ bool spi8BitTest(void) {
   // Clear the memory
   spiAddress = 0;
   memset(src8, 0, DMA_SIZE);
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
       // Send the DMA transfer
       spiMem0.zero(spiAddress, DMA_SIZE);
       // wait until write is done
@@ -175,7 +179,7 @@ bool spi8BitTest(void) {
 
   // Check the memory is clear
   spiAddress = 0;
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
     // Read back the DMA data
     spiMem0.read(spiAddress, dest8, DMA_SIZE);
     // wait until read is done
@@ -201,7 +205,7 @@ bool spi16BitTest(void) {
   Serial.println("\nStarting 16-bit test");
   while (spiPhase < 4) {
     spiAddress = 0;
-    while (spiAddress < SPI_MAX_ADDR) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       
       // fill the write data buffer
       switch (spiPhase) {
@@ -236,7 +240,7 @@ bool spi16BitTest(void) {
   
     // Read back the data using 8-bit transfers
     spiAddress = 0;
-    while (spiAddress < SPI_MAX_ADDR) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       // generate the golden data
       switch (spiPhase) {
       case 0 :
@@ -283,7 +287,7 @@ bool spi16BitTest(void) {
   // Clear the memory
   spiAddress = 0;
   memset(src16, 0, DMA_SIZE);
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
       // Send the DMA transfer
       spiMem0.zero16(spiAddress, NUM_DATA);
       // wait until write is done
@@ -293,7 +297,7 @@ bool spi16BitTest(void) {
 
   // Check the memory is clear
   spiAddress = 0;
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
     // Read back the DMA data
     spiMem0.read16(spiAddress, dest16, NUM_DATA);
     // wait until read is done
@@ -313,4 +317,3 @@ void loop() {
   while(true) {}
 
 }
-
diff --git a/examples/Tests/DMA_MEM1_test/DMA_MEM1_test.ino b/examples/Tests/DMA_MEM1_test/DMA_MEM1_test.ino
index a895cfa..953e44a 100644
--- a/examples/Tests/DMA_MEM1_test/DMA_MEM1_test.ino
+++ b/examples/Tests/DMA_MEM1_test/DMA_MEM1_test.ino
@@ -54,14 +54,17 @@ bool compareBuffers16(uint16_t *a, uint16_t *b, size_t numWords)
   return compareBuffers(reinterpret_cast<uint8_t *>(a), reinterpret_cast<uint8_t*>(b), sizeof(uint16_t)*numWords);
 }
 
-constexpr size_t TEST_END = SPI_MAX_ADDR;
+size_t SPI_MAX_ADDR = 0;
 
 void setup() {
 
   Serial.begin(57600);
-  while (!Serial) {}
+  while (!Serial) { yield(); }
   delay(5);
 
+  SPI_MEM1_1M();
+  SPI_MAX_ADDR = BAHardwareConfig.getSpiMemMaxAddr(MemSelect::MEM1);
+
   Serial.println("Enabling SPI, testing MEM1");
   spiMem1.begin();
 }
@@ -81,7 +84,7 @@ bool spi8BitTest(void) {
   Serial.println("\nStarting 8-bit test Write/Read");
   while (spiPhase < 4) {
     spiAddress = 0;
-    while (spiAddress < TEST_END) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       
       // fill the write data buffer
       switch (spiPhase) {
@@ -116,7 +119,7 @@ bool spi8BitTest(void) {
   
     // Read back the data using 8-bit transfers
     spiAddress = 0;
-    while (spiAddress < TEST_END) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       // generate the golden data
       switch (spiPhase) {
       case 0 :
@@ -164,7 +167,7 @@ bool spi8BitTest(void) {
   // Clear the memory
   spiAddress = 0;
   memset(src8, 0, DMA_SIZE);
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
       // Send the DMA transfer
       spiMem1.zero(spiAddress, DMA_SIZE);
       // wait until write is done
@@ -174,7 +177,7 @@ bool spi8BitTest(void) {
 
   // Check the memory is clear
   spiAddress = 0;
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
     // Read back the DMA data
     spiMem1.read(spiAddress, dest8, DMA_SIZE);
     // wait until read is done
@@ -200,7 +203,7 @@ bool spi16BitTest(void) {
   Serial.println("\nStarting 16-bit test");
   while (spiPhase < 4) {
     spiAddress = 0;
-    while (spiAddress < SPI_MAX_ADDR) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       
       // fill the write data buffer
       switch (spiPhase) {
@@ -235,7 +238,7 @@ bool spi16BitTest(void) {
   
     // Read back the data using 8-bit transfers
     spiAddress = 0;
-    while (spiAddress < SPI_MAX_ADDR) {
+    while (spiAddress <= SPI_MAX_ADDR) {
       // generate the golden data
       switch (spiPhase) {
       case 0 :
@@ -282,7 +285,7 @@ bool spi16BitTest(void) {
   // Clear the memory
   spiAddress = 0;
   memset(src16, 0, DMA_SIZE);
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
       // Send the DMA transfer
       spiMem1.zero16(spiAddress, NUM_DATA);
       // wait until write is done
@@ -292,7 +295,7 @@ bool spi16BitTest(void) {
 
   // Check the memory is clear
   spiAddress = 0;
-  while (spiAddress < SPI_MAX_ADDR) {
+  while (spiAddress <= SPI_MAX_ADDR) {
     // Read back the DMA data
     spiMem1.read16(spiAddress, dest16, NUM_DATA);
     // wait until read is done
@@ -312,4 +315,3 @@ void loop() {
   while(true) {}
 
 }
-
diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp b/examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp
index 99fbd0c..51f4c76 100644
--- a/examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp
+++ b/examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp
@@ -3,8 +3,8 @@
 #include "BALibrary.h"
 using namespace BALibrary;
 
-constexpr int  potCalibMin = 1;
-constexpr int  potCalibMax = 1018;
+constexpr int  potCalibMin = 8;
+constexpr int  potCalibMax = 1016;
 constexpr bool potSwapDirection = true;
 int pot1Handle, pot2Handle, pot3Handle, sw1Handle, sw2Handle, led1Handle, led2Handle;
 bool mute = false;
@@ -51,6 +51,7 @@ void checkPot(unsigned id)
   if (controlPtr->checkPotValue(handle, potValue)) {
     // Pot has changed
     codecPtr->setHeadphoneVolume(potValue);
+    Serial.println(String("POT") + id + String(" value: ") + potValue);
   } 
 }
 
@@ -79,5 +80,3 @@ void checkSwitch(unsigned id)
   bool pressed = controlPtr->isSwitchHeld(swHandle);
   controlPtr->setOutput(ledHandle, pressed);
 }
-
-
diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino b/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino
index aacb327..591f5ec 100644
--- a/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino
+++ b/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino
@@ -42,13 +42,11 @@
  * 
  */
 
-//#define RUN_MIDI_TEST // Uncomment this line to skip the MIDI test.
-//#define RUN_MEMO_TEST // Uncomment this line to skip the MEM0 test.
-//#define RUN_MEM1_TEST // (Teensy 3.5/3/6 only!) Comment out or delete this line to skip the MEM1 test.
+#define RUN_MIDI_TEST // Uncomment this line to run the MIDI test.
+#define RUN_MEMO_TEST // Uncomment this line to run the MEM0 test.
+//#define RUN_MEM1_TEST // (Teensy 3.5/3/6 only!) Uncomment this line to run the MEM1 test.
 
 #include <Audio.h>
-
-#define TGA_PRO_EXPAND_REV2
 #include "BALibrary.h"
 
 using namespace BALibrary;
@@ -67,7 +65,7 @@ BAGpio                    gpio;  // access to User LED
 BASpiMemoryDMA spiMem0(SpiDeviceId::SPI_DEVICE0);
 #endif
 
-#if defined(RUN_MEM1_TEST)
+#if defined(RUN_MEM1_TEST) && !defined(__IMXRT1062__) // SPI1 not supported on T4.0
 BASpiMemoryDMA spiMem1(SpiDeviceId::SPI_DEVICE1);
 #endif
 
@@ -78,13 +76,14 @@ BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, BA_EXPAND_NUM_E
 void configPhysicalControls(BAPhysicalControls &controls, BAAudioControlWM8731 &codec);
 void checkPot(unsigned id);
 void checkSwitch(unsigned id);
-bool spiTest(BASpiMemoryDMA *mem); // returns true if passed
+bool spiTest(BASpiMemory *mem); // returns true if passed
 bool uartTest();                   // returns true if passed
 
 unsigned loopCounter = 0;
 
 void setup() {
   Serial.begin(57600);
+  while (!Serial) { yield(); }
   delay(500);
 
   // Disable the audio codec first
@@ -101,11 +100,13 @@ void setup() {
 #endif
 
 #if defined(RUN_MEMO_TEST)
+  SPI_MEM0_1M();
   spiMem0.begin(); delay(10);
   if (spiTest(&spiMem0)) { Serial.println("SPI0 testing PASSED!");}
 #endif
 
-#if defined(RUN_MEM1_TEST)
+#if defined(RUN_MEM1_TEST) && !defined(__IMXRT1062__)
+  SPI_MEM1_1M();
   spiMem1.begin(); delay(10);
   if (spiTest(&spiMem1)) { Serial.println("SPI1 testing PASSED!");}
 #endif
@@ -121,7 +122,7 @@ void loop() {
   checkSwitch(0);
   checkSwitch(1);
 
-  delay(10);
+  delay(20);
   loopCounter++;
   if ((loopCounter % 100) == 0) {
     gpio.toggleLed();
diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp b/examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp
index 0e2602e..3ae3953 100644
--- a/examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp
+++ b/examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp
@@ -4,7 +4,7 @@
 using namespace BALibrary;
 
 constexpr unsigned MIDI_RATE = 31250;
-constexpr unsigned HIGH_RATE = 250000; 
+constexpr unsigned HIGH_RATE = 230400; 
 constexpr unsigned TEST_TIME = 5; // 5 second test each
 
 static unsigned baudRate = MIDI_RATE; // start with low speed
@@ -58,7 +58,7 @@ bool uartTest(void)
     if (Serial1.available()) {  
       uint8_t readData= Serial1.read();
       if (readData != writeData) {
-        Serial.println(String("ERROR: readData = ") + readData + String(" writeData = ") + writeData);
+        Serial.println(String("MIDI ERROR: readData = ") + readData + String(" writeData = ") + writeData);
         errorCount++;
       }
     
@@ -79,4 +79,3 @@ bool uartTest(void)
 
   return testFailed;
 }
-
diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp b/examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp
index fce9b22..25ba45b 100644
--- a/examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp
+++ b/examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp
@@ -12,6 +12,8 @@ constexpr int mask1 = 0xaaaa;
 
 using namespace BALibrary;
 
+size_t SPI_MAX_ADDR = 0;
+
 int calcData(int spiAddress, int loopPhase, int maskPhase)
 {
   int data;
@@ -35,7 +37,7 @@ int calcData(int spiAddress, int loopPhase, int maskPhase)
   return (data & 0xffff);
 }
 
-bool spiTest(BASpiMemoryDMA *mem)
+bool spiTest(BASpiMemory *mem)
 {
   int spiAddress = 0;
   int spiErrorCount = 0;
@@ -45,7 +47,10 @@ bool spiTest(BASpiMemoryDMA *mem)
   uint16_t memBlock[NUM_BLOCK_WORDS];
   uint16_t goldData[NUM_BLOCK_WORDS];
 
-  Serial.println("Starting SPI MEM Test");
+  SPI_MAX_ADDR = BAHardwareConfig.getSpiMemMaxAddr(0); // assume for this test both memories are the same size so use MEM0
+  const size_t SPI_MEM0_SIZE_BYTES = BAHardwareConfig.getSpiMemSizeBytes(0);
+
+  Serial.println(String("Starting SPI MEM Test of ") + SPI_MEM0_SIZE_BYTES + String(" bytes"));
 
   for (int cnt = 0; cnt < NUM_TESTS; cnt++) {
 
@@ -122,4 +127,3 @@ bool spiTest(BASpiMemoryDMA *mem)
   }
   return true;
 }
-
diff --git a/src/BAAudioEffectDelayExternal.h b/src/BAAudioEffectDelayExternal.h
index 9e88b21..574873f 100644
--- a/src/BAAudioEffectDelayExternal.h
+++ b/src/BAAudioEffectDelayExternal.h
@@ -45,12 +45,12 @@ public:
 
 	/// Specifiy which external memory to use
 	/// @param type specify which memory to use
-	BAAudioEffectDelayExternal(BALibrary::MemSelect type);
+	BAAudioEffectDelayExternal(BALibrary::MemSelect mem);
 
 	/// Specify external memory, and how much of the memory to use
 	/// @param type specify which memory to use
 	/// @param delayLengthMs maximum delay length in milliseconds
-	BAAudioEffectDelayExternal(BALibrary::MemSelect type, float delayLengthMs);
+	BAAudioEffectDelayExternal(BALibrary::MemSelect mem, float delayLengthMs);
 	virtual ~BAAudioEffectDelayExternal();
 
 	/// set the actual amount of delay on a given delay tap
@@ -67,7 +67,10 @@ public:
 	static unsigned m_usingSPICount[2]; // internal use for all instances
 
 private:
-	void initialize(BALibrary::MemSelect mem, unsigned delayLength = 1e6);
+	bool m_configured = false;
+	unsigned m_requestedDelayLength = 1e6;
+	BALibrary::MemSelect m_mem = BALibrary::MemSelect::MEM0;
+	void initialize(void);
 	void read(uint32_t address, uint32_t count, int16_t *data);
 	void write(uint32_t address, uint32_t count, const int16_t *data);
 	void zero(uint32_t address, uint32_t count);
@@ -79,7 +82,6 @@ private:
 	static unsigned m_allocated[2];
 	audio_block_t *m_inputQueueArray[1];
 
-	BALibrary::MemSelect m_mem;
 	SPIClass *m_spi = nullptr;
 	int m_spiChannel = 0;
 	int m_misoPin = 0;
diff --git a/src/BASpiMemory.h b/src/BASpiMemory.h
index 7e0c622..f4f5950 100644
--- a/src/BASpiMemory.h
+++ b/src/BASpiMemory.h
@@ -136,7 +136,10 @@ protected:
 
 };
 
-#if !defined (__IMXRT1062__)
+#if defined (__IMXRT1062__)
+//#if 0
+using BASpiMemoryDMA = BASpiMemory;
+#else
 
 /**************************************************************************//**
  *  This wrapper class uses the Arduino SPI (Wire) library to access the SPI ram
diff --git a/src/effects/AudioEffectDelayExternal.cpp b/src/effects/AudioEffectDelayExternal.cpp
index 3d3bd67..f81e16a 100644
--- a/src/effects/AudioEffectDelayExternal.cpp
+++ b/src/effects/AudioEffectDelayExternal.cpp
@@ -31,20 +31,21 @@ unsigned BAAudioEffectDelayExternal::m_usingSPICount[2] = {0,0};
 BAAudioEffectDelayExternal::BAAudioEffectDelayExternal()
 : AudioStream(1, m_inputQueueArray)
 {
-	initialize(MemSelect::MEM0);
+    m_mem = MemSelect::MEM0;
 }
 
 BAAudioEffectDelayExternal::BAAudioEffectDelayExternal(MemSelect mem)
 : AudioStream(1, m_inputQueueArray)
 {
-	initialize(mem);
+    m_mem = mem;
 }
 
-BAAudioEffectDelayExternal::BAAudioEffectDelayExternal(BALibrary::MemSelect type, float delayLengthMs)
+BAAudioEffectDelayExternal::BAAudioEffectDelayExternal(BALibrary::MemSelect mem, float delayLengthMs)
 : AudioStream(1, m_inputQueueArray)
 {
 	unsigned delayLengthInt = (delayLengthMs*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f;
-	initialize(type, delayLengthInt);
+	m_mem = mem;
+	m_requestedDelayLength = delayLengthInt;
 }
 
 BAAudioEffectDelayExternal::~BAAudioEffectDelayExternal()
@@ -54,6 +55,8 @@ BAAudioEffectDelayExternal::~BAAudioEffectDelayExternal()
 
 void BAAudioEffectDelayExternal::delay(uint8_t channel, float milliseconds) {
 
+    if (!m_configured) { initialize(); }
+
 	if (channel >= 8) return;
 	if (milliseconds < 0.0) milliseconds = 0.0;
 	uint32_t n = (milliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f;
@@ -67,6 +70,9 @@ void BAAudioEffectDelayExternal::delay(uint8_t channel, float milliseconds) {
 }
 
 void BAAudioEffectDelayExternal::disable(uint8_t channel) {
+
+    if (!m_configured) { initialize(); }
+
 	if (channel >= 8) return;
 	uint8_t mask = m_activeMask & ~(1<<channel);
 	m_activeMask = mask;
@@ -75,12 +81,21 @@ void BAAudioEffectDelayExternal::disable(uint8_t channel) {
 
 void BAAudioEffectDelayExternal::update(void)
 {
+
 	audio_block_t *block;
 	uint32_t n, channel, read_offset;
 
 	// grab incoming data and put it into the memory
 	block = receiveReadOnly();
 
+	if (!m_configured) {
+	    if (block) {
+	        transmit(block);
+	        release(block);
+	        return;
+	    } else { return; }
+	}
+
 	if (block) {
 		if (m_headOffset + AUDIO_BLOCK_SAMPLES <= m_memoryLength) {
 			// a single write is enough
@@ -135,19 +150,19 @@ void BAAudioEffectDelayExternal::update(void)
 
 unsigned BAAudioEffectDelayExternal::m_allocated[2] = {0, 0};
 
-void BAAudioEffectDelayExternal::initialize(MemSelect mem, unsigned delayLength)
+void BAAudioEffectDelayExternal::initialize(void)
 {
 	unsigned samples = 0;
 	unsigned memsize = 0, avail = 0;
 
 	m_activeMask = 0;
 	m_headOffset = 0;
-	m_mem = mem;
+	//m_mem = mem;
 
-	switch (mem) {
+	switch (m_mem) {
 	case MemSelect::MEM0 :
 	{
-		memsize = BAHardwareConfig.getSpiMemSizeBytes(mem) / sizeof(int16_t);
+		memsize = BAHardwareConfig.getSpiMemSizeBytes(m_mem) / sizeof(int16_t);
 		m_spi = &SPI;
 		m_spiChannel = 0;
 		m_misoPin = SPI0_MISO_PIN;
@@ -164,7 +179,7 @@ void BAAudioEffectDelayExternal::initialize(MemSelect mem, unsigned delayLength)
 	case MemSelect::MEM1 :
 	{
 #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
-		memsize = BAHardwareConfig.getSpiMemSizeBytes(mem) / sizeof(int16_t);
+		memsize = BAHardwareConfig.getSpiMemSizeBytes(m_mem) / sizeof(int16_t);
 		m_spi = &SPI1;
 		m_spiChannel = 1;
 		m_misoPin = SPI1_MISO_PIN;
@@ -185,14 +200,15 @@ void BAAudioEffectDelayExternal::initialize(MemSelect mem, unsigned delayLength)
 	pinMode(m_csPin, OUTPUT);
 	digitalWriteFast(m_csPin, HIGH);
 
-	avail = memsize - m_allocated[mem];
+	avail = memsize - m_allocated[m_mem];
 
-	if (delayLength > avail) samples = avail;
-	m_memoryStart = m_allocated[mem];
-	m_allocated[mem] += samples;
+	if (m_requestedDelayLength > avail) samples = avail;
+	m_memoryStart = m_allocated[m_mem];
+	m_allocated[m_mem] += samples;
 	m_memoryLength = samples;
 
 	zero(0, m_memoryLength);
+	m_configured = true;
 
 }
 
diff --git a/src/peripherals/BASpiMemory.cpp b/src/peripherals/BASpiMemory.cpp
index ecb1d23..143dda2 100644
--- a/src/peripherals/BASpiMemory.cpp
+++ b/src/peripherals/BASpiMemory.cpp
@@ -353,7 +353,6 @@ void BASpiMemory::m_rawRead16(size_t address, uint16_t *dest, size_t numWords)
 
 #if defined (__IMXRT1062__)
 //#if 0
-using BASpiMemoryDMA = BASpiMemory;
 #else
 /////////////////////////////////////////////////////////////////////////////
 // BASpiMemoryDMA