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/BA1_DelayAndReverb/BA1_DelayAndReverb.ino b/examples/Basic/BA1_DelayAndReverb/BA1_DelayAndReverb.ino new file mode 100644 index 0000000..a168655 --- /dev/null +++ b/examples/Basic/BA1_DelayAndReverb/BA1_DelayAndReverb.ino @@ -0,0 +1,91 @@ +/************************************************************************* + * 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 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 +#include +#include "BALibrary.h" + +using namespace BALibrary; + +BAAudioControlWM8731 codecControl; + +AudioInputI2S i2sIn; +AudioOutputI2S i2sOut; + +AudioMixer4 gainModule; // This will be used simply to reduce the gain before the reverb +AudioEffectDelay delayModule; // we'll add a little slapback echo +AudioEffectReverb reverb; // Add a bit of 'verb to our tone +AudioMixer4 mixer; // Used to mix the original dry with the wet (effects) path. +AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab. + + +// 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 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 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); // 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); + + // Configure our effects + delayModule.delay(0, 50.0f); // 50 ms slapback delay + gainModule.gain(0, 0.25); // the reverb unit clips easily if the input is too high + mixer.gain(0, 1.0f); // unity gain on the dry + mixer.gain(1, 1.0f); // unity gain on the wet + + // Setup 2-stages of LPF, cutoff 4500 Hz, Q-factor 0.7071 (a 'normal' Q-factor) + cabFilter.setLowpass(0, 4500, .7071); + cabFilter.setLowpass(1, 4500, .7071); + + +} + +void loop() { + + // The audio flows automatically through the Teensy Audio Library + +} diff --git a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino index 2340fb9..72b9dbc 100644 --- a/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino +++ b/examples/Delay/AnalogDelayDemo/AnalogDelayDemo.ino @@ -31,6 +31,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 +54,32 @@ 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 -int loopCount = 0; +elapsedMillis timer; 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 +97,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); @@ -116,9 +130,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 - // 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); +#endif } void OnControlChange(byte channel, byte control, byte value) { @@ -138,14 +154,15 @@ 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) { + + 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()) { 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/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino b/examples/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino new file mode 100644 index 0000000..6a7f12a --- /dev/null +++ b/examples/Tests/BAExpansionCalibrate/BAExpansionCalibrate.ino @@ -0,0 +1,88 @@ +/************************************************************************* + * 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 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 + * enter any character on the terminal input line and press enter to send the character. + */ +#include "BALibrary.h" + +using namespace BALibrary; + +// Create physical controls for Expansion Board, 2 switches, 3 pots, 0 encoders, 2 LEDs +BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, 0, BA_EXPAND_NUM_LED); + +void setup() { + delay(100); + Serial.begin(57600); + delay(500); // long delay to wait for Serial to init + Serial.flush(); + + 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"); + Potentiometer::Calib pot1Calib = Potentiometer::calibrate(BA_EXPAND_POT1_PIN); + if (pot1Calib.min == pot1Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + Serial.println("\nCalibrating POT2"); + Potentiometer::Calib pot2Calib = Potentiometer::calibrate(BA_EXPAND_POT2_PIN); + if (pot2Calib.min == pot2Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + Serial.println("\nCalibrating POT3"); + Potentiometer::Calib pot3Calib = Potentiometer::calibrate(BA_EXPAND_POT3_PIN); + if (pot3Calib.min == pot3Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } + + // Create the controls using the calib values + controls.addPot(BA_EXPAND_POT1_PIN, pot1Calib.min, pot1Calib.max, pot1Calib.swap); + controls.addPot(BA_EXPAND_POT2_PIN, pot2Calib.min, pot2Calib.max, pot2Calib.swap); + controls.addPot(BA_EXPAND_POT3_PIN, pot3Calib.min, pot3Calib.max, pot3Calib.swap); + + // Add the pushbuttons + controls.addSwitch(BA_EXPAND_SW1_PIN); + controls.addSwitch(BA_EXPAND_SW2_PIN); + + // Setup the LEDs + controls.addOutput(BA_EXPAND_LED1_PIN); + controls.setOutput(BA_EXPAND_LED1_PIN, 0); + controls.addOutput(BA_EXPAND_LED2_PIN); + controls.setOutput(BA_EXPAND_LED2_PIN, 0); + + Serial.println("DONE SETUP! Try turning knobs and pushing buttons!\n"); + +} + +void loop() { + // put your main code here, to run repeatedly: + float value; + for (unsigned i=0; icheckPotValue(handle, potValue)) { + // Pot has changed + codecPtr->setHeadphoneVolume(potValue); + Serial.println(String("POT") + id + String(" value: ") + potValue); + } +} + +void checkSwitch(unsigned id) +{ + unsigned swHandle; + unsigned ledHandle; + switch(id) { + case 0 : + swHandle = sw1Handle; + ledHandle = led1Handle; + break; + case 1 : + swHandle = sw2Handle; + ledHandle = led2Handle; + break; + default : + swHandle = sw1Handle; + ledHandle = led1Handle; + } + + if (controlPtr->isSwitchToggled(swHandle)) { + Serial.println(String("Button ") + id + String(" pressed")); + } + + bool pressed = controlPtr->isSwitchHeld(swHandle); + controlPtr->setOutput(ledHandle, pressed); +} diff --git a/examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino b/examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino new file mode 100644 index 0000000..c5dfb4d --- /dev/null +++ b/examples/Tests/TGA_PRO_Basic_Test/TGA_PRO_Basic_Test.ino @@ -0,0 +1,140 @@ +/************************************************************************* + * This demo is used for manufacturing testing on the TGA Pro Expansion + * Control Board. + * + * This will test the following on the TGA Pro: + * + * - 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): + * + * - three POT knobs + * - two pushbutton SWitches + * - two LEDs + * - headphone output + * + * SETUP INSTRUCTIONS: + * + * 1) Connect an audio source to AUDIO INPUT. + * 2) Connect AUDIO OUTPUT to amp, stereo, headphone amplifier, etc. + * 3) if testing the MIDI ports, connect a MIDI cable between MIDI INPUT and MIDI OUTPUT + * 4) comment out any tests you want to skip + * 5) Compile and run the demo on your Teensy with TGA Pro. + * 6) Launch the Arduino Serial Monitor to see results. + * + * TESTING INSTRUCTIONS: + * + * 1) Check the Serial Monitor for the results of the MIDI testing, and external memory testing. + * 2) Confirm that the audio sent to the INPUT is coming out the OUTPUT. + * 3) Confirm the User LED is blinking every 1 or 2 seconds + * + * If using the Expansion Control Board: + * + * 1) Try pushing the pushbuttons. When pushed, they should turn on their corresponding LED. + * 2) Try turn each of the knobs one at a time. They should adjust the volume. + * + * The latest copy of the BA Guitar library can be obtained from + * https://github.com/Blackaddr/BALibrary + * + */ + +#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" + +using namespace BALibrary; + +AudioInputI2S i2sIn; +AudioOutputI2S i2sOut; + +// Audio Thru Connection +AudioConnection patch0(i2sIn,0, i2sOut, 0); +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 + +#if defined(RUN_MEM1_TEST) && !defined(__IMXRT1062__) // SPI1 not supported on T4.0 +BASpiMemoryDMA spiMem1(SpiDeviceId::SPI_DEVICE1); +#endif + +// 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(); } + delay(500); + + // Disable the audio codec first + codec.disable(); + delay(100); + AudioMemory(64); + codec.enable(); + codec.setHeadphoneVolume(0.8f); // Set headphone volume + configPhysicalControls(controls, codec); + + // Run the initial Midi connectivity and SPI memory tests. +#if defined(RUN_MIDI_TEST) + if (uartTest()) { Serial.println("MIDI Ports testing PASSED!"); } +#endif + +#if defined(RUN_MEMO_TEST) + 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_EXP_TEST) + Serial.println("Now monitoring for input from Expansion Control Board"); +#endif +} + +void loop() { + + #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 (timer > 1000) { + timer = 0; + gpio.toggleLed(); // toggle the user LED every 1 second + } +} diff --git a/examples/Tests/TGA_PRO_Basic_Test/UartTest.cpp b/examples/Tests/TGA_PRO_Basic_Test/UartTest.cpp new file mode 100644 index 0000000..3ae3953 --- /dev/null +++ b/examples/Tests/TGA_PRO_Basic_Test/UartTest.cpp @@ -0,0 +1,81 @@ +#include "BAHardware.h" +#include "BASpiMemory.h" + +using namespace BALibrary; + +constexpr unsigned MIDI_RATE = 31250; +constexpr unsigned HIGH_RATE = 230400; +constexpr unsigned TEST_TIME = 5; // 5 second test each + +static unsigned baudRate = MIDI_RATE; // start with low speed +static uint8_t writeData = 0; +static unsigned loopCounter = 0; +static unsigned errorCount = 0; +static bool testFailed = false; +static bool testDone = false; +static unsigned testPhase = 0; // 0 for MIDI speed, 1 for high speed. + +bool uartTest(void) +{ + Serial1.begin(baudRate, SERIAL_8N1); + delay(100); + while(!Serial) {} + Serial.println(String("\nRunning MIDI Port speed test at ") + baudRate); + + // write the first data + Serial1.write(writeData); + + while(!testFailed && !testDone) { + + if (loopCounter >= (baudRate/4)) { // the divisor determines how long the test runs for + // next test + switch (testPhase) { + case 0 : + baudRate = HIGH_RATE; + break; + case 1 : + testDone = true; + } + + if (errorCount == 0) { Serial.println("TEST PASSED!"); } + else { + Serial.println("MIDI PORT TEST FAILED!"); + } + errorCount = 0; + testPhase++; + loopCounter = 0; + + if (!testDone) { + Serial.println(String("\nRunning MIDI Port speed test at ") + baudRate); + Serial1.begin(baudRate, SERIAL_8N1); + while (!Serial1) {} // wait for serial to be ready + } else { + Serial.println("MIDI PORT TEST DONE!\n"); + } + } + + // Wait for read data + if (Serial1.available()) { + uint8_t readData= Serial1.read(); + if (readData != writeData) { + Serial.println(String("MIDI ERROR: readData = ") + readData + String(" writeData = ") + writeData); + errorCount++; + } + + if ((loopCounter % (baudRate/64)) == 0) { // the divisor determines how often the period is printed + Serial.print("."); Serial.flush(); + } + + if (errorCount > 16) { + Serial.println("Halting test"); + testFailed = true; + } + + loopCounter++; + writeData++; + Serial1.write(writeData); + } + } + + return testFailed; +} diff --git a/examples/Tests/TGA_PRO_Basic_Test/spiTest.cpp b/examples/Tests/TGA_PRO_Basic_Test/spiTest.cpp new file mode 100644 index 0000000..cd6475d --- /dev/null +++ b/examples/Tests/TGA_PRO_Basic_Test/spiTest.cpp @@ -0,0 +1,129 @@ +#include +#include +#include "BAHardware.h" +#include "BASpiMemory.h" + +constexpr int NUM_TESTS = 12; +constexpr int NUM_BLOCK_WORDS = 128; +constexpr int mask0 = 0x5555; +constexpr int mask1 = 0xaaaa; + +//#define SANITY_CHECK + +using namespace BALibrary; + +int SPI_MAX_ADDR = 0; + +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); +} + +bool spiTest(BASpiMemory *mem, int id) +{ + int spiAddress = 0; + int spiErrorCount = 0; + + int maskPhase = 0; + int loopPhase = 0; + uint16_t memBlock[NUM_BLOCK_WORDS]; + uint16_t goldData[NUM_BLOCK_WORDS]; + + SPI_MAX_ADDR = BAHardwareConfig.getSpiMemMaxAddr(0); // assume for this test both memories are the same size so use MEM0 + const size_t SPI_MEM_SIZE_BYTES = BAHardwareConfig.getSpiMemSizeBytes(id); + + Serial.println(String("Starting SPI MEM Test of ") + SPI_MEM_SIZE_BYTES + String(" bytes")); + + for (int cnt = 0; cnt < NUM_TESTS; cnt++) { + + // Zero check + mem->zero16(0, SPI_MEM_SIZE_BYTES / sizeof(uint16_t)); + while (mem->isWriteBusy()) {} + + for (spiAddress = 0; spiAddress <= SPI_MAX_ADDR; spiAddress += NUM_BLOCK_WORDS*sizeof(uint16_t)) { + mem->read16(spiAddress, memBlock, NUM_BLOCK_WORDS); + while (mem->isReadBusy()) {} + for (int i=0; i= 10) break; + } + } + if (spiErrorCount >= 10) break; + } + + //if (spiErrorCount == 0) { Serial.println(String("SPI MEMORY(") + cnt + String("): Zero test PASSED!")); } + if (spiErrorCount == 0) { Serial.print("."); Serial.flush(); } + if (spiErrorCount > 0) { Serial.println(String("SPI MEMORY(") + cnt + String("): Zero test FAILED, error count = ") + spiErrorCount); return false;} + + + // Write all test data to the memory + maskPhase = 0; + for (spiAddress = 0; spiAddress <= SPI_MAX_ADDR; spiAddress += NUM_BLOCK_WORDS*sizeof(uint16_t)) { + // Calculate the data for a block + for (int i=0; iwrite16(spiAddress, memBlock, NUM_BLOCK_WORDS); + while (mem->isWriteBusy()) {} + } + + // Read back the test data + spiErrorCount = 0; + spiAddress = 0; + maskPhase = 0; + + for (spiAddress = 0; spiAddress <= SPI_MAX_ADDR; spiAddress += NUM_BLOCK_WORDS*sizeof(uint16_t)) { + + mem->read16(spiAddress, memBlock, NUM_BLOCK_WORDS); + // Calculate the golden data for a block + for (int i=0; iisReadBusy()) {} // wait for the read to finish + + for (int i=0; i= 10) break; + } + + //if (spiErrorCount == 0) { Serial.println(String("SPI MEMORY(") + cnt + String("): Data test PASSED!")); } + if (spiErrorCount == 0) { Serial.print("."); Serial.flush(); } + if (spiErrorCount > 0) { Serial.println(String("SPI MEMORY(") + cnt + String("): Data test FAILED, error count = ") + spiErrorCount); return false;} + + loopPhase = (loopPhase+1) % 2; + } + return true; +}