Updates to the production examples

master
Steve Lascos 6 years ago
parent a4f9f19f7a
commit 86e764eba3
  1. 11
      examples/Tests/TGA_PRO_MEM2/PhysicalControls.cpp
  2. 18
      examples/Tests/TGA_PRO_MEM2/TGA_PRO_MEM2.ino
  3. 79
      examples/Tests/TGA_PRO_MEM2_EXP/PhysicalControls.cpp
  4. 71
      examples/Tests/TGA_PRO_MEM2_EXP/TGA_PRO_MEM2_EXP.ino
  5. 86
      examples/Tests/TGA_PRO_MEM2_EXP/UartTest.cpp
  6. 125
      examples/Tests/TGA_PRO_MEM2_EXP/spiTest.cpp
  7. 25
      src/BAPhysicalControls.h
  8. 14
      src/peripherals/BAPhysicalControls.cpp

@ -72,15 +72,8 @@ void checkSwitch(unsigned id)
ledHandle = led1Handle; ledHandle = led1Handle;
} }
if (controlPtr->isSwitchToggled(swHandle)) { bool pressed = controlPtr->isSwitchHeld(swHandle);
Serial.println(String("SW ") + swHandle + String("Pushed")); controlPtr->setOutput(ledHandle, pressed);
mute = !mute;
if (mute) { codecPtr->setHeadphoneVolume(0.0f); }
else { codecPtr->setHeadphoneVolume(0.8f); }
}
bool pressed = controlPtr->isSwitchHeld(swHandle);
controlPtr->setOutput(ledHandle, pressed);
} }

@ -1,3 +1,12 @@
/*************************************************************************
* This demo is used for manufacturing tests on the TGA Pro Expansion
* Control Board. Pushing the buttons turns on the LEDs. Adjusting
* any know will adjust the volume.
*
* The latest copy of the BA Guitar library can be obtained from
* https://github.com/Blackaddr/BALibrary
*
*/
#include <Wire.h> #include <Wire.h>
#include <Audio.h> #include <Audio.h>
#include <SPI.h> #include <SPI.h>
@ -38,14 +47,16 @@ void setup() {
// Disable the audio codec first // Disable the audio codec first
codec.disable(); codec.disable();
delay(100);
AudioMemory(128); AudioMemory(128);
codec.enable(); codec.enable();
codec.setHeadphoneVolume(0.8f); // Set headphone volume codec.setHeadphoneVolume(0.8f); // Set headphone volume
configPhysicalControls(controls, codec); configPhysicalControls(controls, codec);
// if (uartTest()) { Serial.println("MIDI Ports testing PASSED!"); } // Run the initial Midi connectivity and SPI memory tests.
// if (spiTest(&spiMem0)) { Serial.println("SPI0 testing PASSED!");} if (uartTest()) { Serial.println("MIDI Ports testing PASSED!"); }
// if (spiTest(&spiMem1)) { Serial.println("SPI1 testing PASSED!");} if (spiTest(&spiMem0)) { Serial.println("SPI0 testing PASSED!");}
if (spiTest(&spiMem1)) { Serial.println("SPI1 testing PASSED!");}
} }
void loop() { void loop() {
@ -55,5 +66,6 @@ void loop() {
checkPot(2); checkPot(2);
checkSwitch(0); checkSwitch(0);
checkSwitch(1); checkSwitch(1);
delay(10); delay(10);
} }

@ -0,0 +1,79 @@
#define TGA_PRO_EXPAND_REV2
#include "BALibrary.h"
using namespace BALibrary;
constexpr int potCalibMin = 1;
constexpr int potCalibMax = 1018;
constexpr bool potSwapDirection = true;
int pot1Handle, pot2Handle, pot3Handle, sw1Handle, sw2Handle, led1Handle, led2Handle;
bool mute = false;
BAAudioControlWM8731 *codecPtr = nullptr;
BAPhysicalControls *controlPtr = nullptr;
void configPhysicalControls(BAPhysicalControls &controls, BAAudioControlWM8731 &codec)
{
// Setup the controls. The return value is the handle to use when checking for control changes, etc.
// pushbuttons
sw1Handle = controls.addSwitch(BA_EXPAND_SW1_PIN);
sw2Handle = controls.addSwitch(BA_EXPAND_SW2_PIN);
// pots
pot1Handle = controls.addPot(BA_EXPAND_POT1_PIN, potCalibMin, potCalibMax, potSwapDirection);
pot2Handle = controls.addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection);
pot3Handle = controls.addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection);
// leds
led1Handle = controls.addOutput(BA_EXPAND_LED1_PIN);
led2Handle = controls.addOutput(BA_EXPAND_LED2_PIN); // will illuminate when pressing SW2
controlPtr = &controls;
codecPtr = &codec;
}
void checkPot(unsigned id)
{
float potValue;
unsigned handle;
switch(id) {
case 0 :
handle = pot1Handle;
break;
case 1 :
handle = pot2Handle;
break;
case 2 :
handle = pot3Handle;
break;
default :
handle = pot1Handle;
}
if (controlPtr->checkPotValue(handle, potValue)) {
// Pot has changed
codecPtr->setHeadphoneVolume(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;
}
bool pressed = controlPtr->isSwitchHeld(swHandle);
controlPtr->setOutput(ledHandle, pressed);
}

@ -0,0 +1,71 @@
/*************************************************************************
* This demo is used for manufacturing tests on the TGA Pro Expansion
* Control Board. Pushing the buttons turns on the LEDs. Adjusting
* any know will adjust the volume.
*
* The latest copy of the BA Guitar library can be obtained from
* https://github.com/Blackaddr/BALibrary
*
*/
#include <Wire.h>
#include <Audio.h>
#include <SPI.h>
#define TGA_PRO_EXPAND_REV2
#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
BASpiMemoryDMA spiMem0(SpiDeviceId::SPI_DEVICE0);
BASpiMemoryDMA spiMem1(SpiDeviceId::SPI_DEVICE1);
// Create a control object using the number of switches, pots, encoders and outputs on the
// Blackaddr Audio Expansion Board.
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);
bool spiTest(BASpiMemoryDMA *mem); // returns true if passed
bool uartTest(); // returns true if passed
void setup() {
Serial.begin(57600);
spiMem0.begin();
spiMem1.begin();
// Disable the audio codec first
codec.disable();
delay(100);
AudioMemory(128);
codec.enable();
codec.setHeadphoneVolume(0.8f); // Set headphone volume
configPhysicalControls(controls, codec);
// Run the initial Midi connectivity and SPI memory tests.
if (uartTest()) { Serial.println("MIDI Ports testing PASSED!"); }
if (spiTest(&spiMem0)) { Serial.println("SPI0 testing PASSED!");}
if (spiTest(&spiMem1)) { Serial.println("SPI1 testing PASSED!");}
}
void loop() {
// put your main code here, to run repeatedly:
checkPot(0);
checkPot(1);
checkPot(2);
checkSwitch(0);
checkSwitch(1);
delay(10);
}

@ -0,0 +1,86 @@
#include "BAHardware.h"
#include "BASpiMemory.h"
using namespace BALibrary;
constexpr unsigned LOW_RATE = 2400;
constexpr unsigned MIDI_RATE = 31250;
constexpr unsigned HIGH_RATE = 250000;
constexpr unsigned TEST_TIME = 5; // 5 second test each
static unsigned baudRate = LOW_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 low speed, 1 for MIDI speed, 2 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 = MIDI_RATE;
break;
case 1 :
baudRate = HIGH_RATE;
break;
case 2 :
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("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;
}

@ -0,0 +1,125 @@
#include <cstddef>
#include <cstdint>
#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 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(BASpiMemoryDMA *mem)
{
int spiAddress = 0;
int spiErrorCount = 0;
int maskPhase = 0;
int loopPhase = 0;
uint16_t memBlock[NUM_BLOCK_WORDS];
uint16_t goldData[NUM_BLOCK_WORDS];
Serial.println("Starting SPI MEM Test");
for (int cnt = 0; cnt < NUM_TESTS; cnt++) {
// Zero check
mem->zero16(0, SPI_MEM0_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<NUM_BLOCK_WORDS; i++) {
if (memBlock[i] != 0) {
spiErrorCount++;
if (spiErrorCount >= 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; i<NUM_BLOCK_WORDS; i++) {
memBlock[i] = calcData(spiAddress+i, loopPhase, maskPhase);
maskPhase = (maskPhase+1) % 2;
}
mem->write16(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; i<NUM_BLOCK_WORDS; i++) {
goldData[i] = calcData(spiAddress+i, loopPhase, maskPhase);
maskPhase = (maskPhase+1) % 2;
}
while (mem->isReadBusy()) {} // wait for the read to finish
for (int i=0; i<NUM_BLOCK_WORDS; i++) {
if (goldData[i] != memBlock[i]) {
Serial.println(String("ERROR@ ") + i + String(": ") + goldData[i] + String("!=") + memBlock[i]);
spiErrorCount++;
if (spiErrorCount >= 10) break;
}
#ifdef SANITY_CHECK
else {
if ((spiAddress == 0) && (i<10) && (cnt == 0) ){
Serial.println(String("SHOW@ ") + i + String(": ") + goldData[i] + String("==") + memBlock[i]);
}
}
#endif
}
if (spiErrorCount >= 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;
}

@ -24,7 +24,7 @@
#include <vector> #include <vector>
#include <Encoder.h> #include <Encoder.h>
#include <Bounce.h> #include <Bounce2.h>
namespace BALibrary { namespace BALibrary {
@ -52,6 +52,27 @@ private:
int m_val = 0; ///< store the value to support toggling int m_val = 0; ///< store the value to support toggling
}; };
/// Convenience class for handling digital inputs. This wraps Bounce with the abilty
/// to invert the polarity of the pin.
class DigitalInput : public Bounce {
public:
/// Create an input where digital low is return true. Most switches ground when pressed.
DigitalInput() : m_isPolarityInverted(true) {}
/// Create an input and specify if input polarity is inverted.
/// @param isPolarityInverted when false, a high voltage on the pin returns true, 0V returns false.
DigitalInput(bool isPolarityInverted) : m_isPolarityInverted(isPolarityInverted) {}
/// Read the state of the pin according to the polarity
/// @returns true when the input should be interpreted as the switch is closed, else false.
bool read() { return Bounce::read() != m_isPolarityInverted; } // logical XOR to conditionally invert polarity
/// Set whether the input pin polarity
/// @param polarity when true, a low voltage on the pin is considered true by read(), else false.
void setPolarityInverted(bool polarity) { m_isPolarityInverted = polarity; }
private:
bool m_isPolarityInverted;
};
/// Convenience class for handling an analog pot as a control. When calibrated, /// Convenience class for handling an analog pot as a control. When calibrated,
/// returns a float between 0.0 and 1.0. /// returns a float between 0.0 and 1.0.
class Potentiometer { class Potentiometer {
@ -238,7 +259,7 @@ public:
private: private:
std::vector<Potentiometer> m_pots; ///< a vector of all added pots std::vector<Potentiometer> m_pots; ///< a vector of all added pots
std::vector<RotaryEncoder> m_encoders; ///< a vector of all added encoders std::vector<RotaryEncoder> m_encoders; ///< a vector of all added encoders
std::vector<Bounce> m_switches; ///< a vector of all added switches std::vector<DigitalInput> m_switches; ///< a vector of all added switches
std::vector<DigitalOutput> m_outputs; ///< a vector of all added outputs std::vector<DigitalOutput> m_outputs; ///< a vector of all added outputs
}; };

@ -57,7 +57,10 @@ unsigned BAPhysicalControls::addRotary(uint8_t pin1, uint8_t pin2, bool swapDire
} }
unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMilliseconds) { unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMilliseconds) {
m_switches.emplace_back(pin, intervalMilliseconds); //m_switches.emplace_back(pin, intervalMilliseconds);'
m_switches.emplace_back();
m_switches.back().attach(pin);
m_switches.back().interval(10);
pinMode(pin, INPUT); pinMode(pin, INPUT);
return m_switches.size()-1; return m_switches.size()-1;
} }
@ -87,7 +90,7 @@ void BAPhysicalControls::setOutput(unsigned handle, int val) {
void BAPhysicalControls::setOutput(unsigned handle, bool val) { void BAPhysicalControls::setOutput(unsigned handle, bool val) {
if (handle >= m_outputs.size()) { return; } if (handle >= m_outputs.size()) { return; }
unsigned value = val ? true : false; unsigned value = val ? 1 : 0;
m_outputs[handle].set(value); m_outputs[handle].set(value);
} }
@ -116,7 +119,7 @@ bool BAPhysicalControls::checkPotValue(unsigned handle, float &value) {
bool BAPhysicalControls::isSwitchToggled(unsigned handle) { bool BAPhysicalControls::isSwitchToggled(unsigned handle) {
if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches
Bounce &sw = m_switches[handle]; DigitalInput &sw = m_switches[handle];
if (sw.update() && sw.fallingEdge()) { if (sw.update() && sw.fallingEdge()) {
return true; return true;
@ -128,8 +131,9 @@ bool BAPhysicalControls::isSwitchToggled(unsigned handle) {
bool BAPhysicalControls::isSwitchHeld(unsigned handle) bool BAPhysicalControls::isSwitchHeld(unsigned handle)
{ {
if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches
Bounce &sw = m_switches[handle]; DigitalInput &sw = m_switches[handle];
sw.update();
if (sw.read()) { if (sw.read()) {
return true; return true;
} else { } else {
@ -140,7 +144,7 @@ bool BAPhysicalControls::isSwitchHeld(unsigned handle)
int BAPhysicalControls::getSwitchValue(unsigned handle) int BAPhysicalControls::getSwitchValue(unsigned handle)
{ {
if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches if (handle >= m_switches.size()) { return 0; } // handle is greater than number of switches
Bounce &sw = m_switches[handle]; DigitalInput &sw = m_switches[handle];
return sw.read(); return sw.read();
} }

Loading…
Cancel
Save