From 8bb56adfd3b072ba8ac47818e9efc7c4dd3b3dcc Mon Sep 17 00:00:00 2001 From: Blackaddr Audio Date: Sat, 10 Apr 2021 19:49:35 -0400 Subject: [PATCH] Update to support TGA Pro MKII (#14) * Cleanup and fix issue with DMA transfers on T4 (#13) * Fix issue with max delay on external memory in AudioEffectAnalogDelay * Cleanup of tremolo and analog delay effects * Improved potentiometer getValue() function * Updated and tested examples with T4.0 --- .../BA0_HelloAudioWorld.ino | 54 ++++ .../BA1_DelayAndReverb.ino} | 29 +- .../BA1_TGA_Pro_NOMEM_demo.ino | 106 ------- .../BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino | 209 -------------- .../BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino | 271 ------------------ .../Delay/AnalogDelayDemo/AnalogDelayDemo.ino | 94 +++--- .../AnalogDelayDemoExpansion.ino | 40 ++- .../ExternalDelayDemo/ExternalDelayDemo.ino | 12 +- .../SoundOnSoundDemo/SoundOnSoundDemo.ino | 99 +++---- .../SoundOnSoundExpansionDemo.ino | 53 ++-- examples/Modulation/TemoloDemo/TemoloDemo.ino | 85 +++--- .../TremoloDemoExpansion.ino | 43 ++- .../BAExpansionCalibrate.ino | 9 +- examples/Tests/MeasureNoise/MeasureNoise.ino | 5 + .../PhysicalControls.cpp | 0 .../TGA_PRO_Basic_Test.ino} | 62 ++-- .../UartTest.cpp | 0 .../spiTest.cpp | 0 src/BAGpio.h | 5 + src/BAHardware.h | 231 ++++++--------- src/BALibrary.h | 6 +- src/common/AudioDelay.cpp | 7 +- src/common/BAHardware.cpp | 264 ++++++++++++++++- src/common/ExtMemSlot.cpp | 6 + src/effects/AudioEffectAnalogDelay.cpp | 121 ++++---- src/effects/AudioEffectSOS.cpp | 22 +- src/effects/AudioEffectTremolo.cpp | 15 +- src/peripherals/BAGpio.cpp | 51 ++-- src/peripherals/BAPhysicalControls.cpp | 19 +- src/peripherals/BASpiMemory.cpp | 80 +++--- 30 files changed, 910 insertions(+), 1088 deletions(-) create mode 100644 examples/Basic/BA0_HelloAudioWorld/BA0_HelloAudioWorld.ino rename examples/Basic/{BA4_TGA_Pro_delay_reverb/BA4_TGA_Pro_delay_reverb.ino => BA1_DelayAndReverb/BA1_DelayAndReverb.ino} (62%) delete mode 100644 examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino delete mode 100644 examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino delete mode 100644 examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino rename examples/{ => Tests}/BAExpansionCalibrate/BAExpansionCalibrate.ino (90%) rename examples/Tests/{TGA_PRO_MEM2_EXP => TGA_PRO_Basic_Test}/PhysicalControls.cpp (100%) rename examples/Tests/{TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino => TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino} (76%) rename examples/Tests/{TGA_PRO_MEM2_EXP => TGA_PRO_Basic_Test}/UartTest.cpp (100%) rename examples/Tests/{TGA_PRO_MEM2_EXP => TGA_PRO_Basic_Test}/spiTest.cpp (100%) diff --git a/examples/Basic/BA0_HelloAudioWorld/BA0_HelloAudioWorld.ino b/examples/Basic/BA0_HelloAudioWorld/BA0_HelloAudioWorld.ino new file mode 100644 index 0000000..b993f23 --- /dev/null +++ b/examples/Basic/BA0_HelloAudioWorld/BA0_HelloAudioWorld.ino @@ -0,0 +1,54 @@ +/************************************************************************* + * 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 provides a very simple pass-through, clean audio example. + * This can be used to double checking everything is hooked up and working correctly. + * + * This example also demonstrates the bare minimum code necessary to pass audio + * through the TGA Pro: + * - BAAudioControlWM8731 to enable and control the CODEC + * - AudioInputI2S to receive input audio from the CODEC (it's ADC) + * - AudioOutputI2S to send output audio to the CODEC (it's DAC) + * + */ +#include +#include "BALibrary.h" + +using namespace BALibrary; // This prevents us having to put BALibrary:: in front of all the Blackaddr Audio components + +BAAudioControlWM8731 codecControl; +AudioInputI2S i2sIn; +AudioOutputI2S i2sOut; + +// Audio Connections: name(channel) +// - Setup a mono signal chain, send the mono signal to both output channels in case you are using headphone +// i2sIn(0) --> i2sOut(0) +// i2sIn(1) --> i2sOut(1) +AudioConnection patch0(i2sIn, 0, i2sOut, 0); // connect the cab filter to the output. +AudioConnection patch1(i2sIn, 0, i2sOut, 1); // connect the cab filter to the output. + +void setup() { + + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + + delay(5); // wait a few ms to make sure the GTA Pro is fully powered up + AudioMemory(48); // Provide an arbitrarily large number of audio buffers (48 blocks) for the effects (delays use a lot more than others) + + // If the codec was already powered up (due to reboot) power it down first + codecControl.disable(); + delay(100); + codecControl.enable(); + delay(100); +} + +void loop() { + + // The audio flows automatically through the Teensy Audio Library + +} diff --git a/examples/Basic/BA4_TGA_Pro_delay_reverb/BA4_TGA_Pro_delay_reverb.ino b/examples/Basic/BA1_DelayAndReverb/BA1_DelayAndReverb.ino similarity index 62% rename from examples/Basic/BA4_TGA_Pro_delay_reverb/BA4_TGA_Pro_delay_reverb.ino rename to examples/Basic/BA1_DelayAndReverb/BA1_DelayAndReverb.ino index e6ca5d2..a168655 100644 --- a/examples/Basic/BA4_TGA_Pro_delay_reverb/BA4_TGA_Pro_delay_reverb.ino +++ b/examples/Basic/BA1_DelayAndReverb/BA1_DelayAndReverb.ino @@ -7,7 +7,12 @@ * * This demo provides an example guitar tone consisting of some slap-back delay, * followed by a reverb and a low-pass cabinet filter. + * + * This example uses very simple versions of these effects in the PJRC Audio + * Library to make it a bit easier to learn how all this stuff works. More advanced + * and better sounding effects are available from the Teensy Audio community. * + * A mild cab filter is used in case you are using headphones. */ #include #include @@ -28,28 +33,39 @@ AudioMixer4 mixer; // Used to mix the original dry with the wet (ef AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. -// Audio Connections +// Audio Connections: name(channel) +// - Setup a mono signal chain, send the mono signal to both output channels +// - The reverb effect doesn't mix the dry signal, so we'll do that ourselves with the mixer effect. +// - We need to reduce the gain into the reverb to prevent it's filters clipping +// - mix the wet and the dry together, then send to a cabFilter then to the output. +// i2sIn(0) --> mixer(0) +// i2sIn(0) --> delayModule(0) --> gainModule(0) --> reverb(0) --> mixer(1) +// mixer(0) --> cabFilter(0) --> i2sOut(1) AudioConnection patchIn(i2sIn,0, delayModule, 0); // route the input to the delay AudioConnection patch2(delayModule,0, gainModule, 0); // send the delay to the gain module -AudioConnection patch2b(gainModule, 0, reverb, 0); // then to the reverb +AudioConnection patch2b(gainModule, 0, reverb, 0); // then to the reverb -AudioConnection patch1(i2sIn,0, mixer,0); // mixer input 0 is our original dry signal +AudioConnection patch1(i2sIn,0, mixer,0); // mixer input 0 is our original dry signal AudioConnection patch3(reverb, 0, mixer, 1); // mixer input 1 is our wet AudioConnection patch4(mixer, 0, cabFilter, 0); // mixer outpt to the cabinet filter -AudioConnection patch5(cabFilter, 0, i2sOut, 0); // connect the cab filter to the output. +AudioConnection patch5(cabFilter, 0, i2sOut, 0); // connect the cab filter to the output. AudioConnection patch5b(cabFilter, 0, i2sOut, 1); // connect the cab filter to the output. void setup() { + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + delay(5); // wait a few ms to make sure the GTA Pro is fully powered up - AudioMemory(48); + AudioMemory(48); // Provide an arbitrarily large number of audio buffers (48 blocks) for the effects (delays use a lot more than others) - // If the codec was already powered up (due to reboot) power itd own first + // If the codec was already powered up (due to reboot) power it down first codecControl.disable(); delay(100); codecControl.enable(); @@ -73,4 +89,3 @@ void loop() { // The audio flows automatically through the Teensy Audio Library } - 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 deleted file mode 100644 index 292c871..0000000 --- a/examples/Basic/BA1_TGA_Pro_NOMEM_demo/BA1_TGA_Pro_NOMEM_demo.ino +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************* - * 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 will provide an audio passthrough, as well as exercise the - * MIDI interface. - * - */ -#include -#include -#include -#include "BALibrary.h" - -MIDI_CREATE_DEFAULT_INSTANCE(); -using namespace midi; -using namespace BALibrary; - -AudioInputI2S i2sIn; -AudioOutputI2S i2sOut; - -// Audio Thru Connection -AudioConnection patch0(i2sIn,0, i2sOut, 0); -AudioConnection patch1(i2sIn,1, i2sOut, 1); - -BAAudioControlWM8731 codecControl; -BAGpio gpio; // access to User LED - -unsigned long t=0; - -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(); - delay(100); - AudioMemory(24); - - Serial.println("Enabling codec...\n"); - codecControl.enable(); - delay(100); - -} - -void loop() { - - /////////////////////////////////////////////////////////////////////// - // MIDI TESTING - // Connect a loopback cable between the MIDI IN and MIDI OUT on the - // GTA Pro. This test code will periodically send MIDI events which - // will loop back and get printed in the Serial Monitor. - /////////////////////////////////////////////////////////////////////// - DataByte note, velocity, channel, d1, d2; - - // Send MIDI OUT - int cc, val=0xA, channelSend = 1; - for (cc=32; cc<40; cc++) { - MIDI.sendControlChange(cc, val, channelSend); val++; channelSend++; - delay(100); - MIDI.sendNoteOn(10, 100, channelSend); - delay(100); - } - - if (MIDI.read()) { // Is there a MIDI message incoming ? - MidiType type = MIDI.getType(); - Serial.println(String("MIDI IS WORKING!!!")); - switch (type) { - case NoteOn: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - if (velocity > 0) { - Serial.println(String("Note On: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - } else { - Serial.println(String("Note Off: ch=") + channel + ", note=" + note); - } - break; - case NoteOff: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - Serial.println(String("Note Off: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - break; - default: - d1 = MIDI.getData1(); - d2 = MIDI.getData2(); - Serial.println(String("Message, type=") + type + ", data = " + d1 + " " + d2); - } - t = millis(); - } - - if (millis() - t > 10000) { - t += 10000; - Serial.println("(no MIDI activity, check cables)"); - } - - // Toggle the USR LED state - 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 deleted file mode 100644 index 09481d7..0000000 --- a/examples/Basic/BA2_TGA_Pro_1MEM/BA2_TGA_Pro_1MEM.ino +++ /dev/null @@ -1,209 +0,0 @@ -/************************************************************************* - * 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 will provide an audio passthrough, as well as exercise the - * MIDI interface. - * - * It will also peform a sweep of SPI MEM0. - * - * NOTE: SPI MEM0 can be used by a Teensy 3.1/3.2/3.5/3.6. - * pins. - * - */ -#include -#include -#include -#include "BALibrary.h" - -MIDI_CREATE_DEFAULT_INSTANCE(); -using namespace midi; - -using namespace BALibrary; - -AudioInputI2S i2sIn; -AudioOutputI2S i2sOut; - -// Audio Thru Connection -AudioConnection patch0(i2sIn,0, i2sOut, 0); -AudioConnection patch1(i2sIn,1, i2sOut, 1); - -BAAudioControlWM8731 codecControl; -BAGpio gpio; // access to User LED -BASpiMemory spiMem0(SpiDeviceId::SPI_DEVICE0); - -unsigned long t=0; - -// SPI stuff -unsigned spiAddress0 = 0; -uint16_t spiData0 = 0xABCD; -int spiErrorCount0 = 0; - -constexpr int mask0 = 0x5555; -constexpr int mask1 = 0xaaaa; - -int maskPhase = 0; -int loopPhase = 0; - -void setup() { - - MIDI.begin(MIDI_CHANNEL_OMNI); - Serial.begin(57600); - 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); - AudioMemory(24); - - Serial.println("Sketch: Enabling codec...\n"); - codecControl.enable(); - delay(100); - - Serial.println("Enabling SPI"); - spiMem0.begin(); - -} - -int calcData(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); -} - -void loop() { - - ////////////////////////////////////////////////////////////////// - // Write test data to the SPI Memory 0 - ////////////////////////////////////////////////////////////////// - maskPhase = 0; - for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) { - if ((spiAddress0 % 32768) == 0) { - //Serial.print("Writing to "); - //Serial.println(spiAddress0, HEX); - } - - spiData0 = calcData(spiAddress0, loopPhase, maskPhase); - spiMem0.write16(spiAddress0, spiData0); - maskPhase = (maskPhase+1) % 2; - } - Serial.println("SPI0 writing DONE!"); - - /////////////////////////////////////////////////////////////////// - // Read back from the SPI Memory 0 - /////////////////////////////////////////////////////////////////// - spiErrorCount0 = 0; - spiAddress0 = 0; - maskPhase = 0; - - for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) { - if ((spiAddress0 % 32768) == 0) { -// Serial.print("Reading "); -// Serial.print(spiAddress0, HEX); - } - - spiData0 = calcData(spiAddress0, loopPhase, maskPhase); - int data = spiMem0.read16(spiAddress0); - if (data != spiData0) { - spiErrorCount0++; - Serial.println(""); - Serial.print("ERROR MEM0: (expected) (actual):"); - Serial.print(spiData0, HEX); Serial.print(":"); - Serial.print(data, HEX); - - delay(100); - } - maskPhase = (maskPhase+1) % 2; - - if ((spiAddress0 % 32768) == 0) { -// Serial.print(", data = "); -// Serial.println(data, HEX); -// Serial.println(String(" loopPhase: ") + loopPhase + String(" maskPhase: ") + maskPhase); - } - - // Break out of test once the error count reaches 10 - if (spiErrorCount0 > 10) { break; } - - } - - if (spiErrorCount0 == 0) { Serial.println("SPI0 TEST PASSED!!!"); } - - loopPhase = (loopPhase+1) % 2; - - /////////////////////////////////////////////////////////////////////// - // MIDI TESTING - // Connect a loopback cable between the MIDI IN and MIDI OUT on the - // GTA Pro. This test code will periodically send MIDI events which - // will loop back and get printed in the Serial Monitor. - /////////////////////////////////////////////////////////////////////// - DataByte note, velocity, channel, d1, d2; - - // Send MIDI OUT - int cc, val=0xA, channelSend = 1; - for (cc=32; cc<40; cc++) { - MIDI.sendControlChange(cc, val, channelSend); val++; channelSend++; - delay(100); - MIDI.sendNoteOn(10, 100, channelSend); - delay(100); - } - - if (MIDI.read()) { // Is there a MIDI message incoming ? - MidiType type = MIDI.getType(); - Serial.println(String("MIDI IS WORKING!!!")); - switch (type) { - case NoteOn: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - if (velocity > 0) { - Serial.println(String("Note On: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - } else { - Serial.println(String("Note Off: ch=") + channel + ", note=" + note); - } - break; - case NoteOff: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - Serial.println(String("Note Off: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - break; - default: - d1 = MIDI.getData1(); - d2 = MIDI.getData2(); - Serial.println(String("Message, type=") + type + ", data = " + d1 + " " + d2); - } - t = millis(); - } - - if (millis() - t > 10000) { - t += 10000; - Serial.println("(no MIDI activity, check cables)"); - } - - // Toggle the USR LED state - 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 deleted file mode 100644 index 5f570a7..0000000 --- a/examples/Basic/BA3_TGA_Pro_2MEM/BA3_TGA_Pro_2MEM.ino +++ /dev/null @@ -1,271 +0,0 @@ -/************************************************************************* - * 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 will provide an audio passthrough, as well as exercise the - * MIDI interface. - * - * It will also peform a sweep of SPI MEM0 and MEM1. - * - * NOTE: SPI MEM0 can be used by a Teensy 3.1/3.2/3.5/3.6. SPI MEM1 - * can only be used by a Teensy 3.5/3.6 since it is mapped to the extended - * pins. - * - */ -#include -#include -#include -#include "BALibrary.h" - -MIDI_CREATE_DEFAULT_INSTANCE(); -using namespace midi; -using namespace BALibrary; - -AudioInputI2S i2sIn; -AudioOutputI2S i2sOut; - -// Audio Thru Connection -AudioConnection patch0(i2sIn,0, i2sOut, 0); -AudioConnection patch1(i2sIn,1, i2sOut, 1); - -BAAudioControlWM8731 codecControl; -BAGpio gpio; // access to User LED -BASpiMemory spiMem0(SpiDeviceId::SPI_DEVICE0); -BASpiMemory spiMem1(SpiDeviceId::SPI_DEVICE1); - -unsigned long t=0; - -// SPI stuff -int spiAddress0 = 0; -uint16_t spiData0 = 0xABCD; -int spiErrorCount0 = 0; - -int spiAddress1 = 0; -uint16_t spiData1 = 0xDCBA; -int spiErrorCount1 = 0; - -constexpr int mask0 = 0x5555; -constexpr int mask1 = 0xaaaa; - -int maskPhase = 0; -int loopPhase = 0; - -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); - AudioMemory(24); - - Serial.println("Sketch: Enabling codec...\n"); - codecControl.enable(); - delay(100); - - Serial.println("Enabling SPI"); - spiMem0.begin(); - spiMem1.begin(); - -} - -int calcData(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); -} - -void loop() { - - ////////////////////////////////////////////////////////////////// - // Write test data to the SPI Memory 0 - ////////////////////////////////////////////////////////////////// - maskPhase = 0; - for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) { - if ((spiAddress0 % 32768) == 0) { - //Serial.print("Writing to "); - //Serial.println(spiAddress0, HEX); - } - - spiData0 = calcData(spiAddress0, loopPhase, maskPhase); - spiMem0.write16(spiAddress0, spiData0); - maskPhase = (maskPhase+1) % 2; - } - Serial.println("SPI0 writing DONE!"); - - /////////////////////////////////////////////////////////////////// - // Read back from the SPI Memory 0 - /////////////////////////////////////////////////////////////////// - spiErrorCount0 = 0; - spiAddress0 = 0; - maskPhase = 0; - - for (spiAddress0=0; spiAddress0 <= BAHardwareConfig.getSpiMemMaxAddr(0); spiAddress0=spiAddress0+2) { - if ((spiAddress0 % 32768) == 0) { -// Serial.print("Reading "); -// Serial.print(spiAddress0, HEX); - } - - spiData0 = calcData(spiAddress0, loopPhase, maskPhase); - int data = spiMem0.read16(spiAddress0); - if (data != spiData0) { - spiErrorCount0++; - Serial.println(""); - Serial.print("ERROR MEM0: (expected) (actual):"); - Serial.print(spiData0, HEX); Serial.print(":"); - Serial.print(data, HEX); - - delay(100); - } - maskPhase = (maskPhase+1) % 2; - - if ((spiAddress0 % 32768) == 0) { -// Serial.print(", data = "); -// Serial.println(data, HEX); -// Serial.println(String(" loopPhase: ") + loopPhase + String(" maskPhase: ") + maskPhase); - } - - // Break out of test once the error count reaches 10 - if (spiErrorCount0 > 10) { break; } - - } - - if (spiErrorCount0 == 0) { Serial.println("SPI0 TEST PASSED!!!"); } - - - ////////////////////////////////////////////////////////////////// - // Write test data to the SPI Memory 1 - ////////////////////////////////////////////////////////////////// - maskPhase = 0; - for (spiAddress1=0; spiAddress1 <= BAHardwareConfig.getSpiMemMaxAddr(1); spiAddress1+=2) { - if ((spiAddress1 % 32768) == 0) { - //Serial.print("Writing to "); - //Serial.println(spiAddress1, HEX); - } - - spiData1 = calcData(spiAddress1, loopPhase, maskPhase); - spiMem1.write16(spiAddress1, spiData1); - maskPhase = (maskPhase+1) % 2; - } - Serial.println("SPI1 writing DONE!"); - - /////////////////////////////////////////////////////////////////// - // Read back from the SPI Memory 1 - /////////////////////////////////////////////////////////////////// - spiErrorCount1 = 0; - spiAddress1 = 0; - - maskPhase = 0; - for (spiAddress1=0; spiAddress1 <= BAHardwareConfig.getSpiMemMaxAddr(1); spiAddress1+=2) { - if ((spiAddress1 % 32768) == 0) { - //Serial.print("Reading "); - //Serial.print(spiAddress1, HEX); - } - - spiData1 = calcData(spiAddress1, loopPhase, maskPhase); - uint16_t data = spiMem1.read16(spiAddress1); - if (data != spiData1) { - spiErrorCount1++; - Serial.println(""); - Serial.print("ERROR MEM1: (expected) (actual):"); - Serial.print(spiData1, HEX); Serial.print(":"); - Serial.println(data, HEX); - delay(100); - } - maskPhase = (maskPhase+1) % 2; - - if ((spiAddress1 % 32768) == 0) { - //Serial.print(", data = "); - //Serial.println(data, HEX); - } - - // Break out of test once the error count reaches 10 - if (spiErrorCount1 > 10) { break; } - - } - - if (spiErrorCount1 == 0) { Serial.println("SPI1 TEST PASSED!!!"); } - - loopPhase = (loopPhase+1) % 2; - - /////////////////////////////////////////////////////////////////////// - // MIDI TESTING - // Connect a loopback cable between the MIDI IN and MIDI OUT on the - // GTA Pro. This test code will periodically send MIDI events which - // will loop back and get printed in the Serial Monitor. - /////////////////////////////////////////////////////////////////////// - DataByte note, velocity, channel, d1, d2; - - // Send MIDI OUT - int cc, val=0xA, channelSend = 1; - for (cc=32; cc<40; cc++) { - MIDI.sendControlChange(cc, val, channelSend); val++; channelSend++; - delay(100); - MIDI.sendNoteOn(10, 100, channelSend); - delay(100); - } - - if (MIDI.read()) { // Is there a MIDI message incoming ? - MidiType type = MIDI.getType(); - Serial.println(String("MIDI IS WORKING!!!")); - switch (type) { - case NoteOn: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - if (velocity > 0) { - Serial.println(String("Note On: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - } else { - Serial.println(String("Note Off: ch=") + channel + ", note=" + note); - } - break; - case NoteOff: - note = MIDI.getData1(); - velocity = MIDI.getData2(); - channel = MIDI.getChannel(); - Serial.println(String("Note Off: ch=") + channel + ", note=" + note + ", velocity=" + velocity); - break; - default: - d1 = MIDI.getData1(); - d2 = MIDI.getData2(); - Serial.println(String("Message, type=") + type + ", data = " + d1 + " " + d2); - } - t = millis(); - } - - if (millis() - t > 10000) { - t += 10000; - Serial.println("(no MIDI activity, check cables)"); - } - - // Toggle the USR LED state - gpio.toggleLed(); - -} diff --git a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino index 2340fb9..f339351 100644 --- a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino +++ b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino @@ -15,11 +15,14 @@ * 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" */ - #include +#include +#include #include "BALibrary.h" #include "BAEffects.h" using namespace midi; +MIDI_CREATE_DEFAULT_INSTANCE(); + using namespace BAEffects; using namespace BALibrary; @@ -31,6 +34,7 @@ BAAudioControlWM8731 codec; // YOU MUST USE TEENSYDUINO 1.41 or greater // YOU MUST COMPILE THIS DEMO USING Serial + Midi +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones //#define USE_EXT // uncomment this line to use External MEM0 #define MIDI_DEBUG // uncomment to see raw MIDI info in terminal @@ -53,18 +57,45 @@ AudioEffectAnalogDelay analogDelay(200.0f); // max delay of 200 ms or internal. // If you use external SPI memory you can get up to 1485.0f ms of delay! #endif +#if defined(USE_CAB_FILTER) AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif -// Simply connect the input to the delay, and the output -// to both i2s channels AudioConnection input(i2sIn,0, analogDelay,0); +#if defined(USE_CAB_FILTER) AudioConnection delayOut(analogDelay, 0, cabFilter, 0); AudioConnection leftOut(cabFilter,0, i2sOut, 0); AudioConnection rightOut(cabFilter,0, i2sOut, 1); +#else +AudioConnection leftOut(analogDelay,0, i2sOut, 0); +AudioConnection rightOut(analogDelay,0, i2sOut, 1); +#endif + +elapsedMillis timer; -int loopCount = 0; +void OnControlChange(byte channel, byte control, byte value) { + analogDelay.processMidi(channel-1, control, value); + #ifdef MIDI_DEBUG + Serial.print("Control Change, ch="); + Serial.print(channel, DEC); + Serial.print(", control="); + Serial.print(control, DEC); + Serial.print(", value="); + Serial.print(value, DEC); + Serial.println(); + #endif +} 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_4M(); + //SPI_MEM0_1M(); // use this line instead of you have the older 1Mbit memory + #endif + delay(100); Serial.begin(57600); // Start the serial port @@ -82,7 +113,6 @@ 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); @@ -90,6 +120,12 @@ void setup() { Serial.println("Using INTERNAL memory"); #endif + // Setup MIDI + MIDI.begin(MIDI_CHANNEL_OMNI); + 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); @@ -116,53 +152,25 @@ void setup() { //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) +#if defined(USE_CAB_FILTER) + // Guitar cabinet: 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 OnControlChange(byte channel, byte control, byte value) { - analogDelay.processMidi(channel, control, value); - #ifdef MIDI_DEBUG - Serial.print("Control Change, ch="); - Serial.print(channel, DEC); - Serial.print(", control="); - Serial.print(control, DEC); - Serial.print(", value="); - Serial.print(value, DEC); - Serial.println(); - #endif +#endif } void loop() { - // usbMIDI.read() needs to be called rapidly from loop(). When - // each MIDI messages arrives, it return true. The message must - // be fully processed before usbMIDI.read() is called again. - - if (loopCount % 524288 == 0) { + // usbMIDI.read() needs to be called rapidly from loop(). + + if (timer > 1000) { + timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); Serial.print("% "); Serial.print(" analogDelay: "); Serial.print(analogDelay.processorUsage()); Serial.println("%"); } - loopCount++; - - // check for new MIDI from USB - if (usbMIDI.read()) { - // this code entered only if new MIDI received - byte type, channel, data1, data2, cable; - type = usbMIDI.getType(); // which MIDI message, 128-255 - channel = usbMIDI.getChannel(); // which MIDI channel, 1-16 - data1 = usbMIDI.getData1(); // first data byte of message, 0-127 - data2 = usbMIDI.getData2(); // second data byte of message, 0-127 - Serial.println(String("Received a MIDI message on channel ") + channel); - - if (type == MidiType::ControlChange) { - // if type is 3, it's a CC MIDI Message - // Note: the Arduino MIDI library encodes channels as 1-16 instead - // of 0 to 15 as it should, so we must subtract one. - OnControlChange(channel-1, data1, data2); - } - } + + MIDI.read(); + usbMIDI.read(); } diff --git a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino index 6b04677..e05f632 100644 --- a/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino +++ b/examples/Delay/AnalogDelayDemoExpansion/AnalogDelayDemoExpansion.ino @@ -28,12 +28,13 @@ using namespace BAEffects; using namespace BALibrary; +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones +//#define USE_EXT // uncomment this line to use External MEM0 + 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 instantiate a SRAM // manager and create an external memory slot to use as the memory @@ -53,15 +54,19 @@ AudioEffectAnalogDelay analogDelay(200.0f); // set the max delay of 200 ms. // If you use external SPI memory you can get up to 1485.0f ms of delay! #endif +#if defined(USE_CAB_FILTER) AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif -// Simply connect the input to the delay, and the output -// to both i2s channels AudioConnection input(i2sIn,0, analogDelay,0); +#if defined(USE_CAB_FILTER) AudioConnection delayOut(analogDelay, 0, cabFilter, 0); AudioConnection leftOut(cabFilter,0, i2sOut, 0); AudioConnection rightOut(cabFilter,0, i2sOut, 1); - +#else +AudioConnection leftOut(analogDelay,0, i2sOut, 0); +AudioConnection rightOut(analogDelay,0, i2sOut, 1); +#endif ////////////////////////////////////////// // SETUP PHYSICAL CONTROLS @@ -83,7 +88,7 @@ constexpr bool potSwapDirection = true; // Blackaddr Audio Expansion Board. BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, BA_EXPAND_NUM_ENC, BA_EXPAND_NUM_LED); -int loopCount = 0; +elapsedMillis timer; unsigned filterIndex = 0; // variable for storing which analog filter we're currently using. constexpr unsigned MAX_HEADPHONE_VOL = 10; unsigned headphoneVolume = 8; // control headphone volume from 0 to 10. @@ -92,13 +97,21 @@ unsigned headphoneVolume = 8; // control headphone volume from 0 to 10. int bypassHandle, filterHandle, delayHandle, feedbackHandle, mixHandle, led1Handle, led2Handle; // Handles for the various controls 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_4M(); + //SPI_MEM0_1M(); // use this line instead of you have the older 1Mbit memory + #endif + delay(100); // wait a bit for serial to be available 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 @@ -137,6 +150,7 @@ void setup() { // 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 analogDelay.mix(0.5f); analogDelay.feedback(0.0f); @@ -147,9 +161,11 @@ void setup() { //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 +#if defined(USE_CAB_FILTER) // Guitar cabinet: 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); +#endif } void loop() { @@ -213,14 +229,14 @@ void loop() { } } - // Use the loopCounter to roughly measure human timescales. Every few seconds, print the CPU usage - // to the serial port. About 500,000 loops! - if (loopCount % 524288 == 0) { + 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()); Serial.print("% "); Serial.print(" analogDelay: "); Serial.print(analogDelay.processorUsage()); Serial.println("%"); } - loopCount++; } diff --git a/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino b/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino index 1d4ef97..093fb78 100644 --- a/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino +++ b/examples/Delay/ExternalDelayDemo/ExternalDelayDemo.ino @@ -49,17 +49,21 @@ AudioConnection outputRight(delayMixer, 0, i2sOut, 1); void setup() { + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + + SPI_MEM0_4M(); + //SPI_MEM0_1M(); // use this line instead of you have the older 1Mbit memory + Serial.begin(57600); - while(!Serial) { yield(); } + delay(200); AudioMemory(64); 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 820642d..1251fdd 100644 --- a/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino +++ b/examples/Delay/SoundOnSoundDemo/SoundOnSoundDemo.ino @@ -11,32 +11,29 @@ * the BAMidiTester to control the effect but it's best to use external MIDI footswitch * or the Blackaddr Audio Expansion Control Board. * - * Use must set the Arduino IDE USB-Type to "Serial + MIDI" in the Tools menu. + * 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 #include -#include + #include "BALibrary.h" #include "BAEffects.h" -#include -static const unsigned sUsbTransportBufferSize = 16; -typedef midi::UsbTransport UsbTransport; - -UsbTransport sUsbTransport; - -MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, uMIDI); +/// IMPORTANT ///// +// YOU MUST USE TEENSYDUINO 1.41 or greater +// YOU MUST COMPILE THIS DEMO USING Serial + Midi +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones +#define MIDI_DEBUG -MIDI_CREATE_DEFAULT_INSTANCE(); using namespace midi; +MIDI_CREATE_DEFAULT_INSTANCE(); using namespace BAEffects; - -#define MIDI_DEBUG - using namespace BALibrary; AudioInputI2S i2sIn; @@ -54,9 +51,12 @@ AudioEffectSOS sos(&delaySlot); AudioEffectDelay delayModule; // we'll add a little slapback echo AudioMixer4 gainModule; // This will be used simply to reduce the gain before the reverb AudioEffectReverb reverb; // Add a bit of 'verb to our tone -AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. AudioMixer4 mixer; +#if defined(USE_CAB_FILTER) +AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif + // Connect the input AudioConnection inputToSos(i2sIn, 0, sos, 0); AudioConnection inputToSolo(i2sIn, 0, delayModule, 0); @@ -69,13 +69,17 @@ AudioConnection inputToReverb(gainModule, 0, reverb, 0); AudioConnection mixer0input(i2sIn, 0, mixer, 0); // SOLO Dry Channel AudioConnection mixer1input(reverb, 0, mixer, 1); // SOLO Wet Channel AudioConnection mixer2input(sos, 0, mixer, 2); // SOS Channel -AudioConnection inputToCab(mixer, 0, cabFilter, 0); -// CODEC Outputs +#if defined(USE_CAB_FILTER) +AudioConnection inputToCab(mixer, 0, cabFilter, 0); AudioConnection outputLeft(cabFilter, 0, i2sOut, 0); AudioConnection outputRight(cabFilter, 0, i2sOut, 1); +#else +AudioConnection outputLeft(mixer, 0, i2sOut, 0); +AudioConnection outputRight(mixer, 0, i2sOut, 1); +#endif -int loopCount = 0; +elapsedMillis timer; void OnControlChange(byte channel, byte control, byte value) { sos.processMidi(channel-1, control, value); @@ -92,7 +96,14 @@ void OnControlChange(byte channel, byte control, byte value) { void setup() { -delay(100); + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + + SPI_MEM0_4M(); + //SPI_MEM0_1M(); // use this line instead of you have the older 1Mbit memory + + delay(100); Serial.begin(57600); // Start the serial port // Disable the codec first @@ -115,20 +126,19 @@ delay(100); // Setup MIDI MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.setHandleControlChange(OnControlChange); - uMIDI.begin(MIDI_CHANNEL_OMNI); - uMIDI.setHandleControlChange(OnControlChange); + usbMIDI.setHandleControlChange(OnControlChange); // 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::CLEAR_FEEDBACK_TRIGGER,22); - sos.mapMidiControl(AudioEffectSOS::GATE_TRIGGER,23); + //sos.mapMidiControl(AudioEffectSOS::BYPASS,16); + sos.mapMidiControl(AudioEffectSOS::GATE_TRIGGER,16); + sos.mapMidiControl(AudioEffectSOS::CLEAR_FEEDBACK_TRIGGER,17); sos.mapMidiControl(AudioEffectSOS::GATE_OPEN_TIME,20); sos.mapMidiControl(AudioEffectSOS::GATE_CLOSE_TIME,21); - sos.mapMidiControl(AudioEffectSOS::FEEDBACK,24); - sos.mapMidiControl(AudioEffectSOS::VOLUME,17); + sos.mapMidiControl(AudioEffectSOS::VOLUME,22); + //sos.mapMidiControl(AudioEffectSOS::FEEDBACK,24); // Besure to enable the delay. When disabled, audio is is completely blocked // to minimize resources to nearly zero. @@ -146,51 +156,34 @@ delay(100); gainModule.gain(0, 0.25); // the reverb unit clips easily if the input is too high delayModule.delay(0, 50.0f); // 50 ms slapback delay +#if defined(USE_CAB_FILTER) // 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); +#endif // Setup the Mixer mixer.gain(0, 0.5f); // SOLO Dry gain mixer.gain(1, 0.5f); // SOLO Wet gain mixer.gain(1, 1.0f); // SOS gain + + delay(1000); + sos.clear(); } - - void loop() { - // usbMIDI.read() needs to be called rapidly from loop(). When - // each MIDI messages arrives, it return true. The message must - // be fully processed before usbMIDI.read() is called again. + // usbMIDI.read() needs to be called rapidly from loop(). - if (loopCount % 524288 == 0) { + if (timer > 1000) { + timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); Serial.print("% "); - Serial.print(" sos: "); Serial.print(sos.processorUsage()); + Serial.print(" SOS: "); Serial.print(sos.processorUsage()); Serial.println("%"); } - loopCount++; MIDI.read(); - uMIDI.read(); - -// // check for new MIDI from USB -// if (usbMIDI.read()) { -// // this code entered only if new MIDI received -// byte type, channel, data1, data2, cable; -// type = usbMIDI.getType(); // which MIDI message, 128-255 -// channel = usbMIDI.getChannel(); // which MIDI channel, 1-16 -// data1 = usbMIDI.getData1(); // first data byte of message, 0-127 -// data2 = usbMIDI.getData2(); // second data byte of message, 0-127 -// Serial.println(String("Received a MIDI message on channel ") + channel); -// -// if (type == MidiType::ControlChange) { -// // if type is 3, it's a CC MIDI Message -// // Note: the Arduino MIDI library encodes channels as 1-16 instead -// // of 0 to 15 as it should, so we must subtract one. -// OnControlChange(channel-1, data1, data2); -// } -// } + usbMIDI.read(); } diff --git a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino index 85c26e6..3ae018f 100644 --- a/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino +++ b/examples/Delay/SoundOnSoundExpansionDemo/SoundOnSoundExpansionDemo.ino @@ -13,6 +13,9 @@ * * 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 @@ -20,12 +23,15 @@ * SW2 - Push this button to clear out the sound circulating in the delay. * */ +#include #include "BALibrary.h" #include "BAEffects.h" using namespace BAEffects; using namespace BALibrary; +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones + AudioInputI2S i2sIn; AudioOutputI2S i2sOut; BAAudioControlWM8731 codec; @@ -41,9 +47,12 @@ AudioEffectSOS sos(&delaySlot); AudioEffectDelay delayModule; // we'll add a little slapback echo AudioMixer4 gainModule; // This will be used simply to reduce the gain before the reverb AudioEffectReverb reverb; // Add a bit of 'verb to our tone -AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. AudioMixer4 mixer; +#if defined(USE_CAB_FILTER) +AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif + // Connect the input AudioConnection inputToSos(i2sIn, 0, sos, 0); AudioConnection inputToSolo(i2sIn, 0, delayModule, 0); @@ -56,11 +65,15 @@ AudioConnection inputToReverb(gainModule, 0, reverb, 0); AudioConnection mixer0input(i2sIn, 0, mixer, 0); // SOLO Dry Channel AudioConnection mixer1input(reverb, 0, mixer, 1); // SOLO Wet Channel AudioConnection mixer2input(sos, 0, mixer, 2); // SOS Channel -AudioConnection inputToCab(mixer, 0, cabFilter, 0); -// CODEC Outputs +#if defined(USE_CAB_FILTER) +AudioConnection inputToCab(mixer, 0, cabFilter, 0); AudioConnection outputLeft(cabFilter, 0, i2sOut, 0); AudioConnection outputRight(cabFilter, 0, i2sOut, 1); +#else +AudioConnection outputLeft(mixer, 0, i2sOut, 0); +AudioConnection outputRight(mixer, 0, i2sOut, 1); +#endif ////////////////////////////////////////// // SETUP PHYSICAL CONTROLS @@ -82,7 +95,7 @@ constexpr bool potSwapDirection = true; // Blackaddr Audio Expansion Board. BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, BA_EXPAND_NUM_ENC, BA_EXPAND_NUM_LED); -int loopCount = 0; +elapsedMillis timer; constexpr unsigned MAX_HEADPHONE_VOL = 10; unsigned headphoneVolume = MAX_HEADPHONE_VOL; // control headphone volume from 0 to 10. constexpr float MAX_GATE_TIME_MS = 4000.0f; // set maximum gate time of 4 seconds. @@ -93,11 +106,17 @@ int gateHandle, clearHandle, openHandle, closeHandle, volumeHandle, led1Handle, void setup() { -delay(100); + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + + SPI_MEM0_4M(); + //SPI_MEM0_1M(); // use this line instead of you have the older 1Mbit memory + + 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 @@ -115,9 +134,6 @@ delay(100); codec.disable(); AudioMemory(128); - TGA_PRO_EXPAND_REV2(); // Set the expansion board revision - SPI_MEM0_1M(); // set the Spi memory size - // Enable the codec Serial.println("Enabling codec...\n"); codec.enable(); @@ -130,7 +146,7 @@ delay(100); // by BAPhysicalControls sos.setGateLedGpio(BA_EXPAND_LED1_PIN); - // Besure to enable the delay. When disabled, audio is is completely blocked + // Besure to enable the SOS. When disabled, audio is is completely blocked // to minimize resources to nearly zero. sos.enable(); @@ -146,19 +162,22 @@ delay(100); gainModule.gain(0, 0.25); // the reverb unit clips easily if the input is too high delayModule.delay(0, 50.0f); // 50 ms slapback delay +#if defined(USE_CAB_FILTER) // 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); +#endif // Setup the Mixer mixer.gain(0, 0.5f); // SOLO Dry gain mixer.gain(1, 0.5f); // SOLO Wet gain mixer.gain(1, 1.0f); // SOS gain + + delay(1000); + sos.clear(); } - - void loop() { float potValue; @@ -215,12 +234,14 @@ void loop() { } } } - if (loopCount % 524288 == 0) { + + 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()); Serial.print("% "); - Serial.print(" sos: "); Serial.print(sos.processorUsage()); + Serial.print(" SOS: "); Serial.print(sos.processorUsage()); Serial.println("%"); } - loopCount++; - } diff --git a/examples/Modulation/TemoloDemo/TemoloDemo.ino b/examples/Modulation/TemoloDemo/TemoloDemo.ino index 014ecc2..a9f4097 100644 --- a/examples/Modulation/TemoloDemo/TemoloDemo.ino +++ b/examples/Modulation/TemoloDemo/TemoloDemo.ino @@ -20,6 +20,8 @@ #include "BAEffects.h" using namespace midi; +MIDI_CREATE_DEFAULT_INSTANCE(); + using namespace BAEffects; using namespace BALibrary; @@ -31,22 +33,46 @@ BAAudioControlWM8731 codec; // YOU MUST USE TEENSYDUINO 1.41 or greater // YOU MUST COMPILE THIS DEMO USING Serial + Midi +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones #define MIDI_DEBUG // uncomment to see raw MIDI info in terminal AudioEffectTremolo tremolo; +#if defined(USE_CAB_FILTER) AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif -// Simply connect the input to the tremolo, and the output -// to both i2s channels AudioConnection input(i2sIn,0, tremolo,0); -AudioConnection tremoloOut(tremolo, 0, cabFilter, 0); +#if defined(USE_CAB_FILTER) +AudioConnection tremOut(tremolo, 0, cabFilter, 0); AudioConnection leftOut(cabFilter,0, i2sOut, 0); AudioConnection rightOut(cabFilter,0, i2sOut, 1); +#else +AudioConnection leftOut(tremolo,0, i2sOut, 0); +AudioConnection rightOut(tremolo,0, i2sOut, 1); +#endif + +elapsedMillis timer; -int loopCount = 0; +void OnControlChange(byte channel, byte control, byte value) { + tremolo.processMidi(channel-1, control, value); + #ifdef MIDI_DEBUG + Serial.print("Control Change, ch="); + Serial.print(channel, DEC); + Serial.print(", control="); + Serial.print(control, DEC); + Serial.print(", value="); + Serial.print(value, DEC); + Serial.println(); + #endif +} void setup() { + + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + delay(100); Serial.begin(57600); // Start the serial port @@ -61,6 +87,11 @@ void setup() { codec.enable(); delay(100); + // Setup MIDI + MIDI.begin(MIDI_CHANNEL_OMNI); + MIDI.setHandleControlChange(OnControlChange); + usbMIDI.setHandleControlChange(OnControlChange); + // Configure which MIDI CC's will control the effect parameters tremolo.mapMidiControl(AudioEffectTremolo::BYPASS,16); tremolo.mapMidiControl(AudioEffectTremolo::RATE,20); @@ -78,53 +109,25 @@ void setup() { tremolo.bypass(false); tremolo.depth(0.5f); // 50% depth modulation - // Setup 2-stages of LPF, cutoff 4500 Hz, Q-factor 0.7071 (a 'normal' Q-factor) +#if defined(USE_CAB_FILTER) + // Guitar cabinet: 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 OnControlChange(byte channel, byte control, byte value) { - tremolo.processMidi(channel, control, value); - #ifdef MIDI_DEBUG - Serial.print("Control Change, ch="); - Serial.print(channel, DEC); - Serial.print(", control="); - Serial.print(control, DEC); - Serial.print(", value="); - Serial.print(value, DEC); - Serial.println(); - #endif +#endif } void loop() { - // usbMIDI.read() needs to be called rapidly from loop(). When - // each MIDI messages arrives, it return true. The message must - // be fully processed before usbMIDI.read() is called again. + // usbMIDI.read() needs to be called rapidly from loop(). - if (loopCount % 524288 == 0) { + if (timer > 1000) { + timer = 0; Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); Serial.print("% "); Serial.print(" tremolo: "); Serial.print(tremolo.processorUsage()); Serial.println("%"); } - loopCount++; - - // check for new MIDI from USB - if (usbMIDI.read()) { - // this code entered only if new MIDI received - byte type, channel, data1, data2, cable; - type = usbMIDI.getType(); // which MIDI message, 128-255 - channel = usbMIDI.getChannel(); // which MIDI channel, 1-16 - data1 = usbMIDI.getData1(); // first data byte of message, 0-127 - data2 = usbMIDI.getData2(); // second data byte of message, 0-127 - Serial.println(String("Received a MIDI message on channel ") + channel); - - if (type == MidiType::ControlChange) { - // if type is 3, it's a CC MIDI Message - // Note: the Arduino MIDI library encodes channels as 1-16 instead - // of 0 to 15 as it should, so we must subtract one. - OnControlChange(channel-1, data1, data2); - } - } + + MIDI.read(); + usbMIDI.read(); } diff --git a/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino b/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino index fbbcc14..3dcba7e 100644 --- a/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino +++ b/examples/Modulation/TremoloDemoExpansion/TremoloDemoExpansion.ino @@ -8,11 +8,12 @@ * This example demonstrates teh BAAudioEffectsTremolo 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 + * POT1 (left) controls the tremolo RATE + * POT2 (right) controls the tremolo DEPTH + * POT3 (center) controls the output VOLUME * 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. + * SW2 will cycle through the 3 pre-programmed waveforms. NOTE: any waveform other than Sine will cause + * pops/clicks since the waveforms are not bandlimited. * * * Using the Serial Montitor, send 'u' and 'd' characters to increase or decrease @@ -25,20 +26,27 @@ using namespace BAEffects; using namespace BALibrary; +//#define USE_CAB_FILTER // uncomment this line to add a simple low-pass filter to simulate a cabinet if you are going straight to headphones + AudioInputI2S i2sIn; AudioOutputI2S i2sOut; BAAudioControlWM8731 codec; AudioEffectTremolo tremolo; +#if defined(USE_CAB_FILTER) AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. +#endif -// Simply connect the input to the delay, and the output -// to both i2s channels AudioConnection input(i2sIn,0, tremolo,0); -AudioConnection delayOut(tremolo, 0, cabFilter, 0); +#if defined(USE_CAB_FILTER) +AudioConnection tremOut(tremolo, 0, cabFilter, 0); AudioConnection leftOut(cabFilter,0, i2sOut, 0); AudioConnection rightOut(cabFilter,0, i2sOut, 1); +#else +AudioConnection leftOut(tremolo,0, i2sOut, 0); +AudioConnection rightOut(tremolo,0, i2sOut, 1); +#endif ////////////////////////////////////////// @@ -61,7 +69,8 @@ constexpr bool potSwapDirection = true; // Blackaddr Audio Expansion Board. BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, BA_EXPAND_NUM_ENC, BA_EXPAND_NUM_LED); -int loopCount = 0; +elapsedMillis timer; + unsigned waveformIndex = 0; // variable for storing which analog filter we're currently using. constexpr unsigned MAX_HEADPHONE_VOL = 10; unsigned headphoneVolume = 8; // control headphone volume from 0 to 10. @@ -70,12 +79,14 @@ unsigned headphoneVolume = 8; // control headphone volume from 0 to 10. int bypassHandle, waveformHandle, rateHandle, depthHandle, volumeHandle, led1Handle, led2Handle; // Handles for the various controls void setup() { + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + delay(100); // wait a bit for serial to be available 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 @@ -104,6 +115,7 @@ void setup() { // Set some default values. // These can be changed using the controls on the Blackaddr Audio Expansion Board tremolo.bypass(false); + controls.setOutput(led1Handle, !tremolo.isBypass()); // Set the LED when NOT bypassed tremolo.rate(0.0f); tremolo.depth(1.0f); @@ -112,9 +124,11 @@ void setup() { // These are commented out, in this example we'll use SW2 to cycle through the different filters //tremolo.setWaveform(Waveform::SINE); // The default waveform +#if defined(USE_CAB_FILTER) // Guitar cabinet: 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); +#endif } void loop() { @@ -178,15 +192,14 @@ void loop() { } } - // Use the loopCounter to roughly measure human timescales. Every few seconds, print the CPU usage - // to the serial port. About 500,000 loops! - //if (loopCount % 524288 == 0) { - if (loopCount % 25000 == 0) { + 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()); Serial.print("% "); Serial.print(" tremolo: "); Serial.print(tremolo.processorUsage()); Serial.println("%"); } - loopCount++; } diff --git a/examples/BAExpansionCalibrate/BAExpansionCalibrate.ino b/examples/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino similarity index 90% rename from examples/BAExpansionCalibrate/BAExpansionCalibrate.ino rename to examples/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino index 697eee0..6a7f12a 100644 --- a/examples/BAExpansionCalibrate/BAExpansionCalibrate.ino +++ b/examples/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino @@ -8,6 +8,10 @@ * This program can be used to find out the calibration values for each of your POTs * on the Blackaddr Audio Expansion Control Board. * + * Normally the default values used in the BALibrary are appropriate for the Expansion + * Control Board, however you an use this program as a reference for calibrating pots + * in a custom design. + * * USE THE ARDUINO SERIAL MONITOR TO PERFORM THE CALIBRATION * * When prompted turn the appropriate POT in the specified direction and @@ -24,8 +28,11 @@ void setup() { delay(100); Serial.begin(57600); delay(500); // long delay to wait for Serial to init + Serial.flush(); - TGA_PRO_EXPAND_REV2(); // Set the expansion board revision + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); // put your setup code here, to run once: Serial.println("Calibrating POT1"); diff --git a/examples/Tests/MeasureNoise/MeasureNoise.ino b/examples/Tests/MeasureNoise/MeasureNoise.ino index b222ba0..d665d88 100644 --- a/examples/Tests/MeasureNoise/MeasureNoise.ino +++ b/examples/Tests/MeasureNoise/MeasureNoise.ino @@ -15,6 +15,8 @@ * be useful for frequency detection but is not appropriate for when sound quality is desired as * the modulation of the filter will result in audible artifacts. * + * ALLOW THE TEST TO RUN THROUGH SEVERAL CYCLE of toggling the HPF so the CODEC can calibrate correctly. + * */ #include #include @@ -39,6 +41,9 @@ AudioConnection patchOutL(rmsModule, 0, i2sOut, 0); // connect the cab filt AudioConnection patchOutR(rmsModule, 0, i2sOut, 1); // connect the cab filter to the output. void setup() { + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); delay(5); // wait a few ms to make sure the GTA Pro is fully powered up AudioMemory(48); diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp b/examples/Tests/TGA_PRO_Basic_Test/PhysicalControls.cpp similarity index 100% rename from examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp rename to examples/Tests/TGA_PRO_Basic_Test/PhysicalControls.cpp diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino b/examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino similarity index 76% rename from examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino rename to examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino index 0fedcb1..3b1fc55 100644 --- a/examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino +++ b/examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino @@ -7,7 +7,6 @@ * - Audio INPUT and OUTPUT JACKS * - Midi INPUT and Midi OUTPUT jacks * - MEM0 (if installed) - * - MEM1 (if installed) * - User LED * * This will also test the Expansion Control Board (if installed): @@ -42,9 +41,9 @@ * */ -//#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. +//#define RUN_MIDI_TEST // Uncomment this line to run a MIDI test. You must connect a MIDI cable as a loopback between the MIDI input and output jacks. +//#define RUN_MEMO_TEST // Uncomment this line if you purchased the option SPI RAM. +//#define RUN_EXP_TEST // Uncomment if you purchased the Expansion Control Board #include #include "BALibrary.h" @@ -61,6 +60,8 @@ AudioConnection patch1(i2sIn,1, i2sOut, 1); BAAudioControlWM8731 codec; BAGpio gpio; // access to User LED +elapsedMillis timer; + #if defined(RUN_MEMO_TEST) BASpiMemoryDMA spiMem0(SpiDeviceId::SPI_DEVICE0); #endif @@ -71,30 +72,38 @@ BASpiMemoryDMA spiMem1(SpiDeviceId::SPI_DEVICE1); // Create a control object using the number of switches, pots, encoders and outputs on the // Blackaddr Audio Expansion Board. +#ifdef RUN_EXP_TEST BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, BA_EXPAND_NUM_ENC, BA_EXPAND_NUM_LED); - void configPhysicalControls(BAPhysicalControls &controls, BAAudioControlWM8731 &codec); void checkPot(unsigned id); void checkSwitch(unsigned id); +#endif + bool spiTest(BASpiMemory *mem, int id); // returns true if passed bool uartTest(); // returns true if passed unsigned loopCounter = 0; void setup() { + + TGA_PRO_MKII_REV1(); // Declare the version of the TGA Pro you are using. + //TGA_PRO_REVB(x); + //TGA_PRO_REVA(x); + Serial.begin(57600); - while (!Serial) { yield(); } + //while (!Serial) { yield(); } delay(500); // Disable the audio codec first codec.disable(); delay(100); - AudioMemory(128); + AudioMemory(64); codec.enable(); codec.setHeadphoneVolume(0.8f); // Set headphone volume +#if defined(RUN_EXP_TEST) configPhysicalControls(controls, codec); - - TGA_PRO_EXPAND_REV2(); // Macro to declare expansion board revision + Serial.println("Now monitoring for input from Expansion Control Board"); +#endif // Run the initial Midi connectivity and SPI memory tests. #if defined(RUN_MIDI_TEST) @@ -102,33 +111,28 @@ void setup() { #endif #if defined(RUN_MEMO_TEST) - SPI_MEM0_1M(); - //SPI_MEM0_4M(); + SPI_MEM0_4M(); // Declare the correct memory size + // SPI_MEM0_1M(); // older boards only had 1M memories spiMem0.begin(); delay(10); if (spiTest(&spiMem0, 0)) { Serial.println("SPI0 testing PASSED!");} #endif - -#if defined(RUN_MEM1_TEST) && !defined(__IMXRT1062__) - SPI_MEM1_1M(); - //SPI_MEM1_4M(); - spiMem1.begin(); delay(10); - if (spiTest(&spiMem1, 1)) { Serial.println("SPI1 testing PASSED!");} -#endif - - Serial.println("Now monitoring for input from Expansion Control Board"); } void loop() { - - checkPot(0); - checkPot(1); - checkPot(2); - checkSwitch(0); - checkSwitch(1); - delay(20); + #if defined(RUN_EXP_TEST) + checkPot(0); + checkPot(1); + checkPot(2); + checkSwitch(0); + checkSwitch(1); + #endif + + delay(20); // Without some minimal delay here it will be difficult for the pots/switch changes to be detected. + loopCounter++; - if ((loopCounter % 100) == 0) { - gpio.toggleLed(); + if (timer > 1000) { + timer = 0; + gpio.toggleLed(); // toggle the user LED every 1 second } } diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp b/examples/Tests/TGA_PRO_Basic_Test/UartTest.cpp similarity index 100% rename from examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp rename to examples/Tests/TGA_PRO_Basic_Test/UartTest.cpp diff --git a/examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp b/examples/Tests/TGA_PRO_Basic_Test/spiTest.cpp similarity index 100% rename from examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp rename to examples/Tests/TGA_PRO_Basic_Test/spiTest.cpp diff --git a/src/BAGpio.h b/src/BAGpio.h index f7766af..b038c3d 100644 --- a/src/BAGpio.h +++ b/src/BAGpio.h @@ -67,6 +67,11 @@ public: /// @returns the new stage of the user LED. int toggleLed(); + /// Convert the GPIO enum to the underlying logical pin number + /// @param gpio the enum value to convert + /// @returns the logical pin number for the GPIO + uint8_t enumToPinNumber(GPIO gpio); + private: uint8_t m_ledState; }; diff --git a/src/BAHardware.h b/src/BAHardware.h index cb15d61..befe8da 100644 --- a/src/BAHardware.h +++ b/src/BAHardware.h @@ -20,8 +20,8 @@ * along with this program. If not, see . *****************************************************************************/ -#ifndef __BALIBRARY_BAHARDWARE_H -#define __BALIBRARY_BAHARDWARE_H +#ifndef BALIBRARY_BAHARDWARE_H_ +#define BALIBRARY_BAHARDWARE_H_ #include #include @@ -32,30 +32,29 @@ *****************************************************************************/ namespace BALibrary { -// In your Arudino .ino file, use #defines for your TGA Pro revision and options -// to correctly configure your hardware -#define TGA_PRO_REVA(x) BALibrary::BAHardwareConfig.m_tgaBoard = TgaBoard::REV_A ///< Macro for specifying REV A of the TGA Pro -#define TGA_PRO_REVB(x) BALibrary::BAHardwareConfig.m_tgaBoard = TgaBoard::REV_B ///< Macro for specifying REV B of the TGA Pro -#define TGA_PRO_EXPAND_REV2(x) BALibrary::BAHardwareConfig.m_expansionBoard = ExpansionBoard::REV_2 ///< Macro for specifying REV 2 of the Expansion Board -#define SPI_MEM0_1M(x) BALibrary::BAHardwareConfig.m_spiMem0 = SPI_MEMORY_1M ///< Macro for specifying MEM0 is 1Mbit -#define SPI_MEM0_4M(x) BALibrary::BAHardwareConfig.m_spiMem0 = SPI_MEMORY_4M ///< Macro for specifying MEM1 is 4Mbit -#define SPI_MEM1_1M(x) BALibrary::BAHardwareConfig.m_spiMem1 = SPI_MEMORY_1M ///< Macro for specifying MEM0 is 1Mbit -#define SPI_MEM1_4M(x) BALibrary::BAHardwareConfig.m_spiMem1 = SPI_MEMORY_4M ///< Macro for specifying MEM1 is 1Mbit - /****************************************************************************** * Hardware Configuration *****************************************************************************/ /// enum to specify the TGA Board revision enum class TgaBoard : unsigned { REV_A = 0, ///< indicates using REV A of the TGA Pro - REV_B ///< indicates using REV B of the TGA Pro + REV_B, ///< indicates using REV B of the TGA Pro + MKII_REV1, ///< indicates using MKII, Rev 1 of the TGA Pro + AVALON +}; + +/// enum to specify the TGA Board revision +enum class TeensyProcessor : unsigned { + TEENSY3 = 0, ///< indicates using REV A of the TGA Pro + TEENSY4, ///< indicates using REV B of the TGA Pro }; /// enum to specify the TGA Pro Expansion Board revision enum class ExpansionBoard : unsigned { NO_EXPANSION = 0, ///< default, indicates no expansion board is present REV_1, ///< indicates using REV 1 of the Expansion Board - REV_2 ///< indicates using REV 2 of the Expansion Board + REV_2, ///< indicates using REV 2 of the Expansion Board + REV_3 ///< indicates using REV 3 of the Expansion Board (MKII Series) }; /// enum to specify SPI memory dize @@ -66,6 +65,7 @@ enum class SpiMemorySize : unsigned { }; constexpr unsigned NUM_MEM_SLOTS = 2; ///< The TGA Pro has two SPI ports for memory + /// enum to specify MEM0 or MEM1 enum MemSelect : unsigned { MEM0 = 0, ///< SPI RAM MEM0 @@ -108,6 +108,22 @@ enum class SpiDeviceId : unsigned { SPI_DEVICE1 = 1 ///< Arduino SPI1 device }; +// GPIOs and Testpoints are accessed via enumerated class constants. +enum class GPIO { + GPIO0 = 0, + GPIO1 = 1, + GPIO2 = 2, + GPIO3 = 3, + + GPIO4 = 4, + GPIO5 = 5, + GPIO6 = 6, + GPIO7 = 7, + + TP1 = 8, + TP2 = 9 +}; + /**************************************************************************//** * BAHardware is a global object that holds hardware configuration options for * board revisions and ordering options. It is created automatically, and only @@ -116,7 +132,7 @@ enum class SpiDeviceId : unsigned { *****************************************************************************/ class BAHardware { public: - BAHardware() = default; ///< default constructor + BAHardware(); ///< default constructor /// sets the TGA Pro board revision /// @param tgaBoard enum to specify board revision @@ -126,6 +142,10 @@ public: /// @returns enum for the board revision TgaBoard getTgaBoard(void); + /// get the configured Teensy Processor + /// @returns enum for the processor + TeensyProcessor getTeensyProcessor(); + /// sets the Expansion board revision /// @param expansionBoard enum to specify the expansion board revision void set(ExpansionBoard expansionBoard); @@ -163,75 +183,75 @@ public: /// @returns the last valid address location in the memory size_t getSpiMemMaxAddr (unsigned memIndex); - TgaBoard m_tgaBoard = TgaBoard::REV_B; ///< stores the configured TGA Pro revision - ExpansionBoard m_expansionBoard = ExpansionBoard::NO_EXPANSION; ///< stores the configured Expansion Board revision - SpiMemoryDefinition m_spiMem0 = SPI_MEMORY_NONE; ///< stores the definition for MEM0 - SpiMemoryDefinition m_spiMem1 = SPI_MEMORY_NONE; ///< stores the definition for MEM1 + TgaBoard m_tgaBoard = TgaBoard::MKII_REV1; ///< stores the configured TGA Pro revision + TeensyProcessor m_teensyProcessor = TeensyProcessor::TEENSY4; ///< store the processor in use + ExpansionBoard m_expansionBoard = ExpansionBoard::NO_EXPANSION; ///< stores the configured Expansion Board revision + SpiMemoryDefinition m_spiMem0 = SPI_MEMORY_NONE; ///< stores the definition for MEM0 + SpiMemoryDefinition m_spiMem1 = SPI_MEMORY_NONE; ///< stores the definition for MEM1 }; extern BAHardware BAHardwareConfig; ///< external definition of global configuration class object -/**************************************************************************//** - * Teensy 3.6/3.5 Hardware Pinout - *****************************************************************************/ -#if defined(__MK66FX1M0__) || defined(__MK64FX512__) // T3.6 or T3.5 -constexpr uint8_t USR_LED_ID = 16; ///< Teensy IO number for the user LED. +// In your Arudino .ino file, use #defines for your TGA Pro revision and options +// to correctly configure your hardware +#define TGA_PRO_REVA(x) BALibrary::BAHardwareConfig.set(TgaBoard::REV_A) ///< Macro for specifying REV A of the TGA Pro +#define TGA_PRO_REVB(x) BALibrary::BAHardwareConfig.set(TgaBoard::REV_B) ///< Macro for specifying REV B of the TGA Pro +#define TGA_PRO_MKII_REV1(x) BALibrary::BAHardwareConfig.set(TgaBoard::MKII_REV1) ///< Macro for specifying REV B of the TGA Pro + +#define TGA_PRO_EXPAND_REV2(x) BALibrary::BAHardwareConfig.setExpansionBoard(ExpansionBoard::REV_2) ///< Macro for specifying REV 2 of the Expansion Board +#define TGA_PRO_EXPAND_REV3(x) BALibrary::BAHardwareConfig.setExpansionBoard(ExpansionBoard::REV_3) ///< Macro for specifying REV 2 of the Expansion Board + +#define SPI_MEM0_1M(x) BALibrary::BAHardwareConfig.set(MEM0, SPI_MEMORY_1M) ///< Macro for specifying MEM0 is 1Mbit +#define SPI_MEM0_4M(x) BALibrary::BAHardwareConfig.set(MEM0, SPI_MEMORY_4M) ///< Macro for specifying MEM1 is 4Mbit +#define SPI_MEM1_1M(x) BALibrary::BAHardwareConfig.set(MEM1, SPI_MEMORY_1M) ///< Macro for specifying MEM0 is 1Mbit +#define SPI_MEM1_4M(x) BALibrary::BAHardwareConfig.set(MEM1, SPI_MEMORY_4M) ///< Macro for specifying MEM1 is 1Mbit + +extern uint8_t USR_LED_ID; ///< Teensy IO number for the user LED. + +extern unsigned BA_EXPAND_NUM_POT; +extern unsigned BA_EXPAND_NUM_SW; +extern unsigned BA_EXPAND_NUM_LED; +extern unsigned BA_EXPAND_NUM_ENC; + +extern uint8_t BA_EXPAND_POT1_PIN; // 14_A0_TX3_SPDIFOUT +extern uint8_t BA_EXPAND_POT2_PIN; // 15_A1_RX3_SPDIFIN +extern uint8_t BA_EXPAND_POT3_PIN; // 16_A2_RX4_SCL1 + +extern uint8_t BA_EXPAND_SW1_PIN; // 2_OUT2 +extern uint8_t BA_EXPAND_SW2_PIN; // 3_LRCLK2 +extern uint8_t BA_EXPAND_LED1_PIN; // 4_BLCK2 +extern uint8_t BA_EXPAND_LED2_PIN; // 5_IN2 + +extern uint8_t GPIO0; +extern uint8_t GPIO1; +extern uint8_t GPIO2; +extern uint8_t GPIO3; +extern uint8_t GPIO4; +extern uint8_t GPIO5; +extern uint8_t GPIO6; +extern uint8_t GPIO7; +extern uint8_t TP1; +extern uint8_t TP2; // SPI0 and SPI1 pinouts -constexpr uint8_t SPI0_SCK_PIN = 14; -constexpr uint8_t SPI0_CS_PIN = 15; -constexpr uint8_t SPI0_MISO_PIN = 8; -constexpr uint8_t SPI0_MOSI_PIN = 7; +extern uint8_t SPI0_SCK_PIN; +extern uint8_t SPI0_CS_PIN; +extern uint8_t SPI0_MISO_PIN; +extern uint8_t SPI0_MOSI_PIN; -#define SPI1_AVAILABLE -constexpr uint8_t SPI1_SCK_PIN = 20; -constexpr uint8_t SPI1_CS_PIN = 31; -constexpr uint8_t SPI1_MISO_PIN = 5; -constexpr uint8_t SPI1_MOSI_PIN = 21; +extern uint8_t SPI1_SCK_PIN; +extern uint8_t SPI1_CS_PIN; +extern uint8_t SPI1_MISO_PIN; +extern uint8_t SPI1_MOSI_PIN; -// GPIOs and Testpoints are accessed via enumerated class constants. -enum class GPIO : uint8_t { - GPIO0 = 2, - GPIO1 = 3, - GPIO2 = 4, - GPIO3 = 6, - - GPIO4 = 12, - GPIO5 = 32, - GPIO6 = 27, - GPIO7 = 28, - - TP1 = 34, - TP2 = 33 -}; +#if defined(ARDUINO_TEENSY41) || defined(__MK66FX1M0__) || defined(__MK64FX512__) +#define SPI1_AVAILABLE +#endif /**************************************************************************//** * Teensy 4.0 Hardware Settings *****************************************************************************/ -#elif defined(__IMXRT1062__) // T4.0 -constexpr uint8_t USR_LED_ID = 2; ///< Teensy IO number for the user LED. - -// SPI0 pinouts -constexpr uint8_t SPI0_SCK_PIN = 13; -constexpr uint8_t SPI0_CS_PIN = 10; -constexpr uint8_t SPI0_MISO_PIN = 12; -constexpr uint8_t SPI0_MOSI_PIN = 11; - -// GPIOs and Testpoints are accessed via enumerated class constants. -enum class GPIO : uint8_t { - GPIO0 = 3, - GPIO1 = 4, - GPIO2 = 5, - GPIO3 = 6, - - GPIO4 = 17, - GPIO5 = 16, - GPIO6 = 15, - GPIO7 = 14, - - TP1 = 9, - TP2 = 22 -}; +#if defined(__IMXRT1062__) // T4.0 #define SCL_PAD_CTRL IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 #define SDA_PAD_CTRL IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01 @@ -242,75 +262,10 @@ constexpr uint32_t SCL_SDA_PAD_CFG = 0xF808; #define LRCLK_PAD_CTRL IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11 #define DAC_PAD_CTRL IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01 constexpr uint32_t I2S_PAD_CFG = 0x0008; - -/**************************************************************************//** - * DEFAULT Teensy 3.2 Hardware Settings - *****************************************************************************/ -#else -constexpr uint8_t USR_LED_ID = 16; ///< Teensy IO number for the user LED. - -// SPI0 and SPI1 pinouts -constexpr uint8_t SPI0_SCK_PIN = 14; -constexpr uint8_t SPI0_CS_PIN = 15; -constexpr uint8_t SPI0_MISO_PIN = 8; -constexpr uint8_t SPI0_MOSI_PIN = 7; - -// GPIOs and Testpoints are accessed via enumerated class constants. -enum class GPIO : uint8_t { - GPIO0 = 2, - GPIO1 = 3, - GPIO2 = 4, - GPIO3 = 6, - - GPIO4 = 12, - GPIO5 = 32, - GPIO6 = 27, - GPIO7 = 28, - - TP1 = 34, - TP2 = 33 -}; #endif -/**************************************************************************//** - * Blackaddr Audio Expansion Board Pin Configuration - *****************************************************************************/ -#if defined(__MK66FX1M0__) || defined(__MK64FX512__) // T3.6 or T3.5 -// Teensy 3.6 Pinout -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 - -#elif defined(__IMXRT1062__) -// Teensy 4.0 pinout -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 = A0; // 14_A0_TX3_SPDIFOUT -constexpr uint8_t BA_EXPAND_POT2_PIN = A1; // 15_A1_RX3_SPDIFIN -constexpr uint8_t BA_EXPAND_POT3_PIN = A2; // 16_A2_RX4_SCL1 -constexpr uint8_t BA_EXPAND_SW1_PIN = 3; // 3_LRCLK2 -constexpr uint8_t BA_EXPAND_SW2_PIN = 4; // 4_BCLK2 -constexpr uint8_t BA_EXPAND_LED1_PIN = 5; // 5_IN2 -constexpr uint8_t BA_EXPAND_LED2_PIN = 6; // 6_OUT1D - -#else - -#warning Your processor is not yet supported in BALibrary -#endif } // namespace BALibrary -#endif /* __BALIBRARY_BAHARDWARE_H */ +#endif /* BALIBRARY_BAHARDWARE_H_ */ diff --git a/src/BALibrary.h b/src/BALibrary.h index 9a0a3d3..d56fd30 100644 --- a/src/BALibrary.h +++ b/src/BALibrary.h @@ -17,8 +17,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#ifndef __BALIBRARY_H -#define __BALIBRARY_H +#ifndef BALIBRARY_H_ +#define BALIBRARY_H_ #include "BAHardware.h" // contains the Blackaddr hardware board definitions @@ -31,4 +31,4 @@ #include "BAGpio.h" #include "BAPhysicalControls.h" -#endif /* __BALIBRARY_H */ +#endif /* BALIBRARY_H_ */ diff --git a/src/common/AudioDelay.cpp b/src/common/AudioDelay.cpp index 69a6522..b2e26b7 100644 --- a/src/common/AudioDelay.cpp +++ b/src/common/AudioDelay.cpp @@ -87,7 +87,6 @@ audio_block_t* AudioDelay::addBlock(audio_block_t *block) setSpiDmaCopyBuffer(); #endif - // this causes pops m_slot->writeAdvance16(block->data, AUDIO_BLOCK_SAMPLES); } blockToRelease = block; @@ -115,7 +114,10 @@ size_t AudioDelay::getMaxDelaySamples() bool AudioDelay::getSamples(audio_block_t *dest, size_t offsetSamples, size_t numSamples) { - return m_getSamples(dest->data, offsetSamples, numSamples); + if (!dest) { return false; } + else { + return m_getSamples(dest->data, offsetSamples, numSamples); + } } bool AudioDelay::getSamples(int16_t *dest, size_t offsetSamples, size_t numSamples) @@ -221,6 +223,7 @@ bool AudioDelay::interpolateDelay(int16_t *extendedSourceBuffer, int16_t *destBu bool AudioDelay::setSpiDmaCopyBuffer(void) { bool returnValue = false; + if (m_slot->isUseDma()) { // For DMA use on T4.0 we need this kluge BASpiMemoryDMA * spiDma = static_cast(m_slot->getSpiMemoryHandle()); diff --git a/src/common/BAHardware.cpp b/src/common/BAHardware.cpp index 2ce9eb1..ca01c08 100644 --- a/src/common/BAHardware.cpp +++ b/src/common/BAHardware.cpp @@ -23,15 +23,277 @@ namespace BALibrary { BAHardware BAHardwareConfig; // create the global configuration struct +//////////////////////////////////////////////////////////////////////////////// +// DEFAULT SETTINGS - modified appropriate when user calls BAHardware:set() +// Default settings are currently for TGA PRO MKII & Teensy 4 +//////////////////////////////////////////////////////////////////////////////// +uint8_t USR_LED_ID = 6; ///< Teensy IO number for the user LED. + +unsigned BA_EXPAND_NUM_POT = 3; +unsigned BA_EXPAND_NUM_SW = 2; +unsigned BA_EXPAND_NUM_LED = 2; +unsigned BA_EXPAND_NUM_ENC = 0; + +uint8_t BA_EXPAND_POT1_PIN = A0; // 14_A0_TX3_SPDIFOUT +uint8_t BA_EXPAND_POT2_PIN = A1; // 15_A1_RX3_SPDIFIN +uint8_t BA_EXPAND_POT3_PIN = A2; // 16_A2_RX4_SCL1 + +uint8_t BA_EXPAND_SW1_PIN = 2; // 2_OUT2 +uint8_t BA_EXPAND_SW2_PIN = 3; // 3_LRCLK2 +uint8_t BA_EXPAND_LED1_PIN = 4; // 4_BLCK2 +uint8_t BA_EXPAND_LED2_PIN = 5; // 5_IN2 + +uint8_t GPIO0 = 2; +uint8_t GPIO1 = 3; +uint8_t GPIO2 = 4; +uint8_t GPIO3 = 5; +uint8_t GPIO4 = 255; // Not available on MKII +uint8_t GPIO5 = 16; +uint8_t GPIO6 = 15; +uint8_t GPIO7 = 14; +uint8_t TP1 = 9; +uint8_t TP2 = 22; + +// SPI0 +uint8_t SPI0_SCK_PIN = 13; +uint8_t SPI0_CS_PIN = 10; +uint8_t SPI0_MISO_PIN = 12; +uint8_t SPI0_MOSI_PIN = 11; + +// SPI1 is only available on user breakout board for MKII/T4 +uint8_t SPI1_SCK_PIN = 27; +uint8_t SPI1_CS_PIN = 38; +uint8_t SPI1_MISO_PIN = 39; +uint8_t SPI1_MOSI_PIN = 26; + +BAHardware::BAHardware() +{ +#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY40) // T4.X + m_teensyProcessor = TeensyProcessor::TEENSY4; +#elif defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) + m_teensyProcessor = TeensyProcessor::TEENSY3; +#else +#error "Only Teensy 4.1, 4.0, 3.6, 3.5, 3.2 are supported" +#endif +} + void BAHardware::set(TgaBoard tgaBoard) { - m_tgaBoard = tgaBoard; + m_tgaBoard = tgaBoard; + + //////////////////////////////////////////////////////////////////////////// + // MKII // + //////////////////////////////////////////////////////////////////////////// +#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY40) // T4.X + if (tgaBoard == TgaBoard::MKII_REV1) { + // No change from defaults + } +#endif + +#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2 + if (tgaBoard == TgaBoard::MKII_REV1) { + // Uses TEENSY_ADAPTER_T3 + + USR_LED_ID = 16; + + BA_EXPAND_POT1_PIN = A16; // 14_A0_TX3_SPDIFOUT + BA_EXPAND_POT2_PIN = A17; // 15_A1_RX3_SPDIFIN + BA_EXPAND_POT3_PIN = A18; // 16_A2_RX4_SCL1 + + BA_EXPAND_SW1_PIN = 2; // 2_OUT2 + BA_EXPAND_SW2_PIN = 3; // 3_LRCLK2 + BA_EXPAND_LED1_PIN = 4; // 4_BLCK2 + BA_EXPAND_LED2_PIN = 6; // 5_IN2 + + GPIO0 = 2; + GPIO1 = 3; + GPIO2 = 4; + GPIO3 = 6; + GPIO4 = 255; // Not available on MKII + GPIO5 = 37; + GPIO6 = 36; + GPIO7 = 35; + TP1 = 34; + TP2 = 33; + + SPI0_SCK_PIN = 14; + SPI0_CS_PIN = 15; + SPI0_MISO_PIN = 8; + SPI0_MOSI_PIN = 7; + + SPI1_SCK_PIN = 20; + SPI1_CS_PIN = 31; + SPI1_MISO_PIN = 5; + SPI1_MOSI_PIN = 21; + } +#endif + + //////////////////////////////////////////////////////////////////////////// + // REVB (Original TGA Pro) // + //////////////////////////////////////////////////////////////////////////// +#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY40) // T4.X + if (tgaBoard == TgaBoard::REV_B) { + // Uses TGA_T4_ADAPTER board + + USR_LED_ID = 2; + + BA_EXPAND_POT1_PIN = A0; // 14_A0_TX3_SPDIFOUT + BA_EXPAND_POT2_PIN = A1; // 15_A1_RX3_SPDIFIN + BA_EXPAND_POT3_PIN = A2; // 16_A2_RX4_SCL1 + + BA_EXPAND_SW1_PIN = 3; // 2_OUT2 + BA_EXPAND_SW2_PIN = 4; // 3_LRCLK2 + BA_EXPAND_LED1_PIN = 5; // 4_BLCK2 + BA_EXPAND_LED2_PIN = 6; // 5_IN2 + + GPIO0 = 3; + GPIO1 = 4; + GPIO2 = 5; + GPIO3 = 6; + GPIO4 = 17; + GPIO5 = 16; + GPIO6 = 15; + GPIO7 = 14; + TP1 = 9; + TP2 = 255; // Not available + + SPI0_SCK_PIN = 13; + SPI0_CS_PIN = 10; + SPI0_MISO_PIN = 12; + SPI0_MOSI_PIN = 11; + } +#endif + +#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2 + if (tgaBoard == TgaBoard::REV_B) { + + USR_LED_ID = 16; + + BA_EXPAND_POT1_PIN = A16; // 14_A0_TX3_SPDIFOUT + BA_EXPAND_POT2_PIN = A17; // 15_A1_RX3_SPDIFIN + BA_EXPAND_POT3_PIN = A18; // 16_A2_RX4_SCL1 + + BA_EXPAND_SW1_PIN = 2; // 2_OUT2 + BA_EXPAND_SW2_PIN = 3; // 3_LRCLK2 + BA_EXPAND_LED1_PIN = 4; // 4_BLCK2 + BA_EXPAND_LED2_PIN = 6; // 5_IN2 + + GPIO0 = 2; + GPIO1 = 3; + GPIO2 = 4; + GPIO3 = 6; + GPIO4 = 38; + GPIO5 = 37; + GPIO6 = 36; + GPIO7 = 35; + TP1 = 34; + TP2 = 33; + + SPI0_SCK_PIN = 14; + SPI0_CS_PIN = 15; + SPI0_MISO_PIN = 8; + SPI0_MOSI_PIN = 7; + + SPI1_SCK_PIN = 20; + SPI1_CS_PIN = 31; + SPI1_MISO_PIN = 5; + SPI1_MOSI_PIN = 21; + } +#endif + + //////////////////////////////////////////////////////////////////////////// + // REVA (Original TGA Pro) // + //////////////////////////////////////////////////////////////////////////// +#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY40) // T4.X + if (tgaBoard == TgaBoard::REV_A) { + // Uses TGA_T4_ADAPTER board + + USR_LED_ID = 2; + + GPIO0 = 3; + GPIO1 = 4; + GPIO2 = 5; + GPIO3 = 6; + GPIO4 = 17; + GPIO5 = 16; + GPIO6 = 15; + GPIO7 = 14; + TP1 = 9; + TP2 = 255; // Not available + + SPI0_SCK_PIN = 13; + SPI0_CS_PIN = 10; + SPI0_MISO_PIN = 12; + SPI0_MOSI_PIN = 11; + } +#endif + +#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2 + if (tgaBoard == TgaBoard::REV_A) { + // REVA did not support Expansion board + + USR_LED_ID = 16; + + GPIO0 = 2; + GPIO1 = 3; + GPIO2 = 4; + GPIO3 = 6; + GPIO4 = 12; + GPIO5 = 32; + GPIO6 = 27; + GPIO7 = 29; + TP1 = 34; + TP2 = 33; + + SPI0_SCK_PIN = 14; + SPI0_CS_PIN = 15; + SPI0_MISO_PIN = 8; + SPI0_MOSI_PIN = 7; + + SPI1_SCK_PIN = 20; + SPI1_CS_PIN = 31; + SPI1_MISO_PIN = 5; + SPI1_MOSI_PIN = 21; + } +#endif + + //////////////////////////////////////////////////////////////////////////// + // Avalon // + //////////////////////////////////////////////////////////////////////////// +#if defined(ARDUINO_TEENSY41) // T4.X + if (tgaBoard == TgaBoard::AVALON) { + BA_EXPAND_NUM_POT = 2; + BA_EXPAND_NUM_SW = 6; + BA_EXPAND_NUM_LED = 2; + BA_EXPAND_NUM_ENC = 4; + + BA_EXPAND_POT1_PIN = A0; + BA_EXPAND_POT2_PIN = A1; + BA_EXPAND_POT3_PIN = A13; + + BA_EXPAND_SW1_PIN = 17; + BA_EXPAND_SW2_PIN = 16; + BA_EXPAND_LED1_PIN = 22; + BA_EXPAND_LED2_PIN = 32; + + SPI0_SCK_PIN = 13; + SPI0_CS_PIN = 10; + SPI0_MISO_PIN = 12; + SPI0_MOSI_PIN = 11; + } +#endif } + TgaBoard BAHardware::getTgaBoard(void) { return m_tgaBoard; } +TeensyProcessor BAHardware::getTeensyProcessor(void) +{ + return m_teensyProcessor; +} + void BAHardware::set(ExpansionBoard expansionBoard) { m_expansionBoard = expansionBoard; diff --git a/src/common/ExtMemSlot.cpp b/src/common/ExtMemSlot.cpp index c857cbe..1574126 100644 --- a/src/common/ExtMemSlot.cpp +++ b/src/common/ExtMemSlot.cpp @@ -144,11 +144,17 @@ bool ExtMemSlot::writeAdvance16(int16_t *src, size_t numWords) // this write will wrap the memory slot size_t wrBytes = m_end - m_currentWrPosition + 1; size_t wrDataNum = wrBytes >> 1; // divide by two to get the number of data + m_spi->write16(m_currentWrPosition, reinterpret_cast(src), wrDataNum); size_t remainingData = numWords - wrDataNum; + m_spi->write16(m_start, reinterpret_cast(src + wrDataNum), remainingData); // write remaining bytes are start m_currentWrPosition = m_start + (remainingData*sizeof(int16_t)); } + + // If a write transaction landed exactly on the end of the memory, the next position must be + // manually put back to the start + if (m_currentWrPosition > m_end) { m_currentWrPosition = m_start; } return true; } diff --git a/src/effects/AudioEffectAnalogDelay.cpp b/src/effects/AudioEffectAnalogDelay.cpp index a32fc8b..914c705 100644 --- a/src/effects/AudioEffectAnalogDelay.cpp +++ b/src/effects/AudioEffectAnalogDelay.cpp @@ -36,7 +36,9 @@ AudioEffectAnalogDelay::AudioEffectAnalogDelay(ExtMemSlot *slot) : AudioStream(1, m_inputQueueArray) { m_memory = new AudioDelay(slot); - m_maxDelaySamples = (slot->size() / sizeof(int16_t)); + + // the delay cannot be exactly equal to the slot size, you need at least one sample so the wr/rd are not on top of each other. + m_maxDelaySamples = (slot->size() / sizeof(int16_t))-AUDIO_BLOCK_SAMPLES; m_externalMemory = true; m_constructFilter(); } @@ -77,50 +79,52 @@ void AudioEffectAnalogDelay::setFilter(Filter filter) void AudioEffectAnalogDelay::update(void) { - audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples - - // Check is block is disabled - if (m_enable == false) { - // do not transmit or process any audio, return as quickly as possible. - if (inputAudioBlock) release(inputAudioBlock); - - // release all held memory resources - if (m_previousBlock) { - release(m_previousBlock); m_previousBlock = nullptr; - } - if (!m_externalMemory) { - // when using internal memory we have to release all references in the ring buffer - while (m_memory->getRingBuffer()->size() > 0) { - audio_block_t *releaseBlock = m_memory->getRingBuffer()->front(); - m_memory->getRingBuffer()->pop_front(); - if (releaseBlock) release(releaseBlock); - } - } - return; - } - // Check is block is bypassed, if so either transmit input directly or create silence - if (m_bypass == true) { - // transmit the input directly - if (!inputAudioBlock) { - // create silence - inputAudioBlock = allocate(); - if (!inputAudioBlock) { return; } // failed to allocate - else { - clearAudioBlock(inputAudioBlock); - } - } - transmit(inputAudioBlock, 0); - release(inputAudioBlock); - return; - } + // Check is block is disabled + if (m_enable == false) { + // release all held memory resources + if (m_previousBlock) { + release(m_previousBlock); m_previousBlock = nullptr; + } + if (!m_externalMemory) { + // when using internal memory we have to release all references in the ring buffer + while (m_memory->getRingBuffer()->size() > 0) { + audio_block_t *releaseBlock = m_memory->getRingBuffer()->front(); + m_memory->getRingBuffer()->pop_front(); + if (releaseBlock) release(releaseBlock); + } + } + return; + } + + audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples + + // Check is block is bypassed, if so either transmit input directly or create silence + if ((m_bypass == true) || (!inputAudioBlock)) { + // transmit the input directly + if (!inputAudioBlock) { + // create silence + inputAudioBlock = allocate(); + if (!inputAudioBlock) { return; } // failed to allocate + else { + clearAudioBlock(inputAudioBlock); + } + } + transmit(inputAudioBlock, 0); + release(inputAudioBlock); + return; + } // Otherwise perform normal processing // In order to make use of the SPI DMA, we need to request the read from memory first, // then do other processing while it fills in the back. audio_block_t *blockToOutput = nullptr; // this will hold the output audio blockToOutput = allocate(); - if (!blockToOutput) return; // skip this update cycle due to failure + if (!blockToOutput) { + transmit(inputAudioBlock, 0); + release(inputAudioBlock); + return; // skip this update cycle due to failure + } // get the data. If using external memory with DMA, this won't be filled until // later. @@ -162,21 +166,17 @@ void AudioEffectAnalogDelay::delay(float milliseconds) { size_t delaySamples = calcAudioSamples(milliseconds); - if (delaySamples > m_memory->getMaxDelaySamples()) { - // this exceeds max delay value, limit it. - delaySamples = m_memory->getMaxDelaySamples(); - } - - if (!m_memory) { Serial.println("delay(): m_memory is not valid"); } + if (!m_memory) { Serial.println("delay(): m_memory is not valid"); return; } if (!m_externalMemory) { // internal memory + m_maxDelaySamples = m_memory->getMaxDelaySamples(); //QueuePosition queuePosition = calcQueuePosition(milliseconds); //Serial.println(String("CONFIG: delay:") + delaySamples + String(" queue position ") + queuePosition.index + String(":") + queuePosition.offset); } else { // external memory - //Serial.println(String("CONFIG: delay:") + delaySamples); ExtMemSlot *slot = m_memory->getSlot(); + m_maxDelaySamples = (slot->size() / sizeof(int16_t))-AUDIO_BLOCK_SAMPLES; if (!slot) { Serial.println("ERROR: slot ptr is not valid"); } if (!slot->isEnabled()) { @@ -185,6 +185,10 @@ void AudioEffectAnalogDelay::delay(float milliseconds) } } + if (delaySamples > m_maxDelaySamples) { + // this exceeds max delay value, limit it. + delaySamples = m_maxDelaySamples; + } m_delaySamples = delaySamples; } @@ -194,43 +198,52 @@ void AudioEffectAnalogDelay::delay(size_t delaySamples) if (!m_externalMemory) { // internal memory + m_maxDelaySamples = m_memory->getMaxDelaySamples(); //QueuePosition queuePosition = calcQueuePosition(delaySamples); //Serial.println(String("CONFIG: delay:") + delaySamples + String(" queue position ") + queuePosition.index + String(":") + queuePosition.offset); } else { // external memory //Serial.println(String("CONFIG: delay:") + delaySamples); ExtMemSlot *slot = m_memory->getSlot(); + m_maxDelaySamples = (slot->size() / sizeof(int16_t))-AUDIO_BLOCK_SAMPLES; if (!slot->isEnabled()) { slot->enable(); } } - m_delaySamples = delaySamples; + + if (delaySamples > m_maxDelaySamples) { + // this exceeds max delay value, limit it. + delaySamples = m_maxDelaySamples; + } + m_delaySamples = delaySamples; } void AudioEffectAnalogDelay::delayFractionMax(float delayFraction) { size_t delaySamples = static_cast(static_cast(m_memory->getMaxDelaySamples()) * delayFraction); - if (delaySamples > m_memory->getMaxDelaySamples()) { - // this exceeds max delay value, limit it. - delaySamples = m_memory->getMaxDelaySamples(); - } - if (!m_memory) { Serial.println("delay(): m_memory is not valid"); } if (!m_externalMemory) { // internal memory + m_maxDelaySamples = m_memory->getMaxDelaySamples(); //QueuePosition queuePosition = calcQueuePosition(delaySamples); //Serial.println(String("CONFIG: delay:") + delaySamples + String(" queue position ") + queuePosition.index + String(":") + queuePosition.offset); } else { // external memory //Serial.println(String("CONFIG: delay:") + delaySamples); ExtMemSlot *slot = m_memory->getSlot(); + m_maxDelaySamples = (slot->size() / sizeof(int16_t))-AUDIO_BLOCK_SAMPLES; if (!slot->isEnabled()) { slot->enable(); } } - m_delaySamples = delaySamples; + + if (delaySamples > m_maxDelaySamples) { + // this exceeds max delay value, limit it. + delaySamples = m_maxDelaySamples; + } + m_delaySamples = delaySamples; } void AudioEffectAnalogDelay::m_preProcessing(audio_block_t *out, audio_block_t *dry, audio_block_t *wet) @@ -268,8 +281,8 @@ void AudioEffectAnalogDelay::processMidi(int channel, int control, int value) if ((m_midiConfig[DELAY][MIDI_CHANNEL] == channel) && (m_midiConfig[DELAY][MIDI_CONTROL] == control)) { // Delay - if (m_externalMemory) { m_maxDelaySamples = m_memory->getSlot()->size() / sizeof(int16_t); } - size_t delayVal = (size_t)(val * (float)m_maxDelaySamples); + if (m_externalMemory) { m_maxDelaySamples = (m_memory->getSlot()->size() / sizeof(int16_t))-AUDIO_BLOCK_SAMPLES; } + size_t delayVal = (size_t)(val * (float)(m_maxDelaySamples)); delay(delayVal); Serial.println(String("AudioEffectAnalogDelay::delay (ms): ") + calcAudioTimeMs(delayVal) + String(" (samples): ") + delayVal + String(" out of ") + m_maxDelaySamples); diff --git a/src/effects/AudioEffectSOS.cpp b/src/effects/AudioEffectSOS.cpp index 2512261..61552b5 100644 --- a/src/effects/AudioEffectSOS.cpp +++ b/src/effects/AudioEffectSOS.cpp @@ -62,28 +62,25 @@ void AudioEffectSOS::enable(void) if (m_externalMemory) { // Because we hold the previous output buffer for an update cycle, the maximum delay is actually // 1 audio block mess then the max delay returnable from the memory. - m_maxDelaySamples = m_memory->getMaxDelaySamples(); + m_maxDelaySamples = m_memory->getMaxDelaySamples() - AUDIO_BLOCK_SAMPLES; Serial.println(String("SOS Enabled with delay length ") + m_maxDelaySamples + String(" samples")); } m_delaySamples = m_maxDelaySamples; m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); - m_inputGateAuto.setupParameter(GATE_HOLD_STAGE, 1.0f, 1.0f, m_maxDelaySamples, ParameterAutomation::Function::HOLD); + m_inputGateAuto.setupParameter(GATE_HOLD_STAGE, 1.0f, 1.0f, m_delaySamples, ParameterAutomation::Function::HOLD); m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); m_clearFeedbackAuto.setupParameter(GATE_OPEN_STAGE, 1.0f, 0.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); - m_clearFeedbackAuto.setupParameter(GATE_HOLD_STAGE, 0.0f, 0.0f, m_maxDelaySamples, ParameterAutomation::Function::HOLD); + m_clearFeedbackAuto.setupParameter(GATE_HOLD_STAGE, 0.0f, 0.0f, m_delaySamples, ParameterAutomation::Function::HOLD); m_clearFeedbackAuto.setupParameter(GATE_CLOSE_STAGE, 0.0f, 1.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); } void AudioEffectSOS::update(void) { - audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples // Check is block is disabled if (m_enable == false) { // do not transmit or process any audio, return as quickly as possible. - if (inputAudioBlock) release(inputAudioBlock); - // release all held memory resources if (m_previousBlock) { release(m_previousBlock); m_previousBlock = nullptr; @@ -99,6 +96,8 @@ void AudioEffectSOS::update(void) return; } + audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples + // Check is block is bypassed, if so either transmit input directly or create silence if ( (m_bypass == true) || (!inputAudioBlock) ) { // transmit the input directly @@ -138,11 +137,7 @@ void AudioEffectSOS::update(void) // mix the input with the feedback path in the pre-processing stage m_preProcessing(preProcessed, inputAudioBlock, m_previousBlock); - // consider doing the BBD post processing here to use up more time while waiting - // for the read data to come back audio_block_t *blockToRelease = m_memory->addBlock(preProcessed); - //audio_block_t *blockToRelease = m_memory->addBlock(inputAudioBlock); - //Serial.println("Done adding new block"); // BACK TO OUTPUT PROCESSING @@ -158,15 +153,14 @@ void AudioEffectSOS::update(void) release(inputAudioBlock); - if (m_previousBlock) - release(m_previousBlock); + if (m_previousBlock) { release(m_previousBlock); } m_previousBlock = blockToOutput; if (m_blockToRelease == m_previousBlock) { Serial.println("ERROR: POINTER COLLISION"); } - if (m_blockToRelease) release(m_blockToRelease); + if (m_blockToRelease) { release(m_blockToRelease); } m_blockToRelease = blockToRelease; } @@ -176,14 +170,12 @@ void AudioEffectSOS::gateOpenTime(float milliseconds) // TODO - change the paramter automation to an automation sequence m_openTimeMs = milliseconds; m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, m_openTimeMs, ParameterAutomation::Function::EXPONENTIAL); - //m_clearFeedbackAuto.setupParameter(GATE_OPEN_STAGE, 1.0f, 0.0f, m_openTimeMs, ParameterAutomation::Function::EXPONENTIAL); } void AudioEffectSOS::gateCloseTime(float milliseconds) { m_closeTimeMs = milliseconds; m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, m_closeTimeMs, ParameterAutomation::Function::EXPONENTIAL); - //m_clearFeedbackAuto.setupParameter(GATE_CLOSE_STAGE, 0.0f, 1.0f, m_closeTimeMs, ParameterAutomation::Function::EXPONENTIAL); } //////////////////////////////////////////////////////////////////////// diff --git a/src/effects/AudioEffectTremolo.cpp b/src/effects/AudioEffectTremolo.cpp index 0bb4d67..212f3c3 100644 --- a/src/effects/AudioEffectTremolo.cpp +++ b/src/effects/AudioEffectTremolo.cpp @@ -28,17 +28,16 @@ AudioEffectTremolo::~AudioEffectTremolo() void AudioEffectTremolo::update(void) { - audio_block_t *inputAudioBlock = receiveWritable(); // get the next block of input samples + // Check is block is disabled + if (m_enable == false) { + // do not transmit or process any audio, return as quickly as possible. + return; + } - // Check is block is disabled - if (m_enable == false) { - // do not transmit or process any audio, return as quickly as possible. - if (inputAudioBlock) release(inputAudioBlock); - return; - } + audio_block_t *inputAudioBlock = receiveWritable(); // get the next block of input samples // Check is block is bypassed, if so either transmit input directly or create silence - if (m_bypass == true) { + if ((m_bypass == true) || (!inputAudioBlock)) { // transmit the input directly if (!inputAudioBlock) { // create silence diff --git a/src/peripherals/BAGpio.cpp b/src/peripherals/BAGpio.cpp index e2d3c79..6f15e0e 100644 --- a/src/peripherals/BAGpio.cpp +++ b/src/peripherals/BAGpio.cpp @@ -26,18 +26,18 @@ namespace BALibrary { BAGpio::BAGpio() { // Set all GPIOs to input - pinMode(static_cast(GPIO::GPIO0), INPUT); - pinMode(static_cast(GPIO::GPIO1), INPUT); - pinMode(static_cast(GPIO::GPIO2), INPUT); - pinMode(static_cast(GPIO::GPIO3), INPUT); - pinMode(static_cast(GPIO::GPIO4), INPUT); - pinMode(static_cast(GPIO::GPIO5), INPUT); - pinMode(static_cast(GPIO::GPIO6), INPUT); - pinMode(static_cast(GPIO::GPIO7), INPUT); - pinMode(static_cast(GPIO::TP1), INPUT); - pinMode(static_cast(GPIO::TP2), INPUT); + pinMode(GPIO0, INPUT); + pinMode(GPIO1, INPUT); + pinMode(GPIO2, INPUT); + pinMode(GPIO3, INPUT); + pinMode(GPIO4, INPUT); + pinMode(GPIO5, INPUT); + pinMode(GPIO6, INPUT); + pinMode(GPIO7, INPUT); + pinMode(TP1, INPUT); + pinMode(TP2, INPUT); - // Set the LED ot ouput + // Set the LED to ouput pinMode(USR_LED_ID, OUTPUT); clearLed(); // turn off the LED @@ -49,21 +49,21 @@ BAGpio::~BAGpio() void BAGpio::setGPIODirection(GPIO gpioId, int direction) { - pinMode(static_cast(gpioId), direction); + pinMode(enumToPinNumber(gpioId), direction); } void BAGpio::setGPIO(GPIO gpioId) { - digitalWrite(static_cast(gpioId), 0x1); + digitalWrite(enumToPinNumber(gpioId), 0x1); } void BAGpio::clearGPIO(GPIO gpioId) { - digitalWrite(static_cast(gpioId), 0); + digitalWrite(enumToPinNumber(gpioId), 0); } int BAGpio::toggleGPIO(GPIO gpioId) { - int data = digitalRead(static_cast(gpioId)); - digitalWrite(static_cast(gpioId), ~data); + int data = digitalRead(enumToPinNumber(gpioId)); + digitalWrite(enumToPinNumber(gpioId), ~data); return ~data; } @@ -84,5 +84,24 @@ int BAGpio::toggleLed() return m_ledState; } +uint8_t enumToPinNumber(GPIO gpio) +{ + uint8_t pinNumber; + switch(gpio) { + case GPIO::GPIO0 : pinNumber = GPIO0; break; + case GPIO::GPIO1 : pinNumber = GPIO1; break; + case GPIO::GPIO2 : pinNumber = GPIO2; break; + case GPIO::GPIO3 : pinNumber = GPIO3; break; + case GPIO::GPIO4 : pinNumber = GPIO4; break; + case GPIO::GPIO5 : pinNumber = GPIO5; break; + case GPIO::GPIO6 : pinNumber = GPIO6; break; + case GPIO::GPIO7 : pinNumber = GPIO7; break; + case GPIO::TP1 : pinNumber = TP1; break; + case GPIO::TP2 : pinNumber = TP2; break; + default : pinNumber = 0; break; + } + return pinNumber; +} + } /* namespace BALibrary */ diff --git a/src/peripherals/BAPhysicalControls.cpp b/src/peripherals/BAPhysicalControls.cpp index e479ad3..32c16c3 100644 --- a/src/peripherals/BAPhysicalControls.cpp +++ b/src/peripherals/BAPhysicalControls.cpp @@ -265,12 +265,22 @@ bool Potentiometer::getValue(float &value) { return false; } } - m_lastValidValue = m_lastValue; // Convert the integer reading to a float value range 0.0 to 1.0f - if (valFilter < m_minCalibrationThresholded) { value = 0.0f; } - else if (valFilter > m_maxCalibrationThresholded) { value = 1.0f; } + if (valFilter < m_minCalibrationThresholded) { + m_lastValue = m_minCalibrationThresholded; + if (m_lastValidValue == m_minCalibrationThresholded) { return false; } + m_lastValidValue = m_lastValue; + value = 0.0f; + } + else if (valFilter > m_maxCalibrationThresholded) { + m_lastValue = m_maxCalibrationThresholded; + if (m_lastValidValue == m_maxCalibrationThresholded) { return false; } + m_lastValidValue = m_lastValue; + value = 1.0f; + } else { + m_lastValidValue = m_lastValue; value = static_cast(valFilter - m_minCalibrationThresholded) / static_cast(m_rangeThresholded); } @@ -319,6 +329,9 @@ void Potentiometer::setChangeThreshold(float changeThreshold) Potentiometer::Calib Potentiometer::calibrate(uint8_t pin) { Calib calib; + // Flush the serial port input buffer + while (Serial.available() > 0) {} + 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) { diff --git a/src/peripherals/BASpiMemory.cpp b/src/peripherals/BASpiMemory.cpp index 90ed46d..1c9e702 100644 --- a/src/peripherals/BASpiMemory.cpp +++ b/src/peripherals/BASpiMemory.cpp @@ -24,19 +24,19 @@ namespace BALibrary { -// MEM0 Settings -constexpr int SPI_CS_MEM0 = SPI0_CS_PIN; -constexpr int SPI_MOSI_MEM0 = SPI0_MOSI_PIN; -constexpr int SPI_MISO_MEM0 = SPI0_MISO_PIN; -constexpr int SPI_SCK_MEM0 = SPI0_SCK_PIN; - -#if defined(SPI1_AVAILABLE) -// MEM1 Settings -constexpr int SPI_CS_MEM1 = SPI1_CS_PIN; -constexpr int SPI_MOSI_MEM1 = SPI1_MOSI_PIN; -constexpr int SPI_MISO_MEM1 = SPI1_MISO_PIN; -constexpr int SPI_SCK_MEM1 = SPI1_SCK_PIN; -#endif +//// MEM0 Settings +//int SPI_CS_MEM0 = SPI0_CS_PIN; +//int SPI_MOSI_MEM0 = SPI0_MOSI_PIN; +//int SPI_MISO_MEM0 = SPI0_MISO_PIN; +//int SPI_SCK_MEM0 = SPI0_SCK_PIN; +// +//#if defined(SPI1_AVAILABLE) +//// MEM1 Settings +//int SPI_CS_MEM1 = SPI1_CS_PIN; +//int SPI_MOSI_MEM1 = SPI1_MOSI_PIN; +//int SPI_MISO_MEM1 = SPI1_MISO_PIN; +//int SPI_SCK_MEM1 = SPI1_SCK_PIN; +//#endif // SPI Constants constexpr int SPI_WRITE_MODE_REG = 0x1; @@ -73,22 +73,22 @@ void BASpiMemory::begin() { switch (m_memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - m_csPin = SPI_CS_MEM0; + m_csPin = SPI0_CS_PIN; m_spi = &SPI; - m_spi->setMOSI(SPI_MOSI_MEM0); - m_spi->setMISO(SPI_MISO_MEM0); - m_spi->setSCK(SPI_SCK_MEM0); + m_spi->setMOSI(SPI0_MOSI_PIN); + m_spi->setMISO(SPI0_MISO_PIN); + m_spi->setSCK(SPI0_SCK_PIN); m_spi->begin(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; break; #if defined(__MK64FX512__) || defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - m_csPin = SPI_CS_MEM1; + m_csPin = SPI1_CS_PIN; m_spi = &SPI1; - m_spi->setMOSI(SPI_MOSI_MEM1); - m_spi->setMISO(SPI_MISO_MEM1); - m_spi->setSCK(SPI_SCK_MEM1); + m_spi->setMOSI(SPI1_MOSI_PIN); + m_spi->setMISO(SPI1_MISO_PIN); + m_spi->setSCK(SPI1_SCK_PIN); m_spi->begin(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM1).DIE_BOUNDARY; break; @@ -367,17 +367,17 @@ BASpiMemoryDMA::BASpiMemoryDMA(SpiDeviceId memDeviceId) int cs; switch (memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; m_cs = new ActiveLowChipSelect(cs, m_settings); break; #if defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - cs = SPI_CS_MEM1; + cs = SPI1_CS_PIN; m_cs = new ActiveLowChipSelect1(cs, m_settings); break; #endif default : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; } // add 4 bytes to buffer for SPI CMD and 3 bytes of address @@ -393,17 +393,17 @@ BASpiMemoryDMA::BASpiMemoryDMA(SpiDeviceId memDeviceId, uint32_t speedHz) int cs; switch (memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; m_cs = new ActiveLowChipSelect(cs, m_settings); break; #if defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - cs = SPI_CS_MEM1; + cs = SPI1_CS_PIN; m_cs = new ActiveLowChipSelect1(cs, m_settings); break; #endif default : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; } m_txCommandBuffer = new uint8_t[CMD_ADDRESS_SIZE]; @@ -433,11 +433,11 @@ void BASpiMemoryDMA::begin(void) { switch (m_memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - m_csPin = SPI_CS_MEM0; + m_csPin = SPI0_CS_PIN; m_spi = &SPI; - m_spi->setMOSI(SPI_MOSI_MEM0); - m_spi->setMISO(SPI_MISO_MEM0); - m_spi->setSCK(SPI_SCK_MEM0); + m_spi->setMOSI(SPI0_MOSI_PIN); + m_spi->setMISO(SPI0_MISO_PIN); + m_spi->setSCK(SPI0_SCK_PIN); m_spi->begin(); m_spiDma = new DmaSpiGeneric(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; @@ -445,11 +445,11 @@ void BASpiMemoryDMA::begin(void) #if defined(__MK66FX1M0__) // DMA on SPI1 is only supported on T3.6 case SpiDeviceId::SPI_DEVICE1 : - m_csPin = SPI_CS_MEM1; + m_csPin = SPI1_CS_PIN; m_spi = &SPI1; - m_spi->setMOSI(SPI_MOSI_MEM1); - m_spi->setMISO(SPI_MISO_MEM1); - m_spi->setSCK(SPI_SCK_MEM1); + m_spi->setMOSI(SPI1_MOSI_PIN); + m_spi->setMISO(SPI1_MISO_PIN); + m_spi->setSCK(SPI1_SCK_PIN); m_spi->begin(); m_spiDma = new DmaSpiGeneric(1); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM1).DIE_BOUNDARY; @@ -478,6 +478,8 @@ void BASpiMemoryDMA::write(size_t address, uint8_t *src, size_t numBytes) size_t nextAddress = address; uint8_t *intermediateBuffer = nullptr; + while ( m_txTransfer[1].busy() || m_txTransfer[0].busy()) { yield(); } // wait until not busy + // Check for intermediate buffer use if (m_dmaCopyBufferSize) { // copy to the intermediate buffer; @@ -487,8 +489,6 @@ void BASpiMemoryDMA::write(size_t address, uint8_t *src, size_t numBytes) while (bytesRemaining > 0) { m_txXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary - - while ( m_txTransfer[1].busy() || m_txTransfer[0].busy()) { yield(); } // 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); m_spiDma->registerTransfer(m_txTransfer[1]); @@ -559,14 +559,13 @@ void BASpiMemoryDMA::read(size_t address, uint8_t *dest, size_t numBytes) } while (bytesRemaining > 0) { - m_rxXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary + while ( m_rxTransfer[1].busy() || m_rxTransfer[0].busy()) { yield(); } + m_rxXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary m_setSpiCmdAddr(SPI_READ_CMD, nextAddress, m_rxCommandBuffer); - while ( m_rxTransfer[1].busy() || m_rxTransfer[0].busy()) { yield(); } m_rxTransfer[1] = DmaSpi::Transfer(m_rxCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); m_spiDma->registerTransfer(m_rxTransfer[1]); - while ( m_rxTransfer[0].busy() || m_rxTransfer[1].busy()) { yield(); } m_rxTransfer[0] = DmaSpi::Transfer(nullptr, m_rxXferCount, destPtr, 0, m_cs, TransferType::NO_START_CS, nullptr, intermediateBuffer); m_spiDma->registerTransfer(m_rxTransfer[0]); @@ -615,7 +614,6 @@ bool BASpiMemoryDMA::setDmaCopyBufferSize(size_t numBytes) m_dmaReadCopyBuffer = (volatile uint8_t*)dma_aligned_malloc(MEM_ALIGNED_ALLOC, numBytes); if (!m_dmaReadCopyBuffer) { - // allocate failed m_dmaCopyBufferSize = 0; return false; }