parent
129e3a3e3b
commit
701a7cc1a5
@ -0,0 +1,9 @@ |
|||||||
|
#ifndef DEBUG_PRINTF_H_ |
||||||
|
#define DEBUG_PRINTF_H_ |
||||||
|
|
||||||
|
// Make a safe call to Serial where it checks if the object is valid first. This allows your
|
||||||
|
// program to work even when no USB serial is connected. Printing to the Serial object when
|
||||||
|
// no valid connection is present will crash the CPU.
|
||||||
|
#define DEBUG_PRINT(x) {if (Serial) {x;}} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,276 @@ |
|||||||
|
/***********************************************************************************
|
||||||
|
* MULTIVERSE DEMO |
||||||
|
*
|
||||||
|
* This demo program shows how to use BALibrary to access the hardware |
||||||
|
* features of the Aviate Audio Multiverse effects processor. |
||||||
|
*
|
||||||
|
* The following are demonstrated in this programming using BALibrary: |
||||||
|
* - WM8731 stereo audio codec in master mode (NOTE: not slave mode like TGA Pro |
||||||
|
* - Interact with all physical controls |
||||||
|
* - Control the 128x64 pixel OLED display (connected to SPI0) |
||||||
|
* - Use the 8MB external SRAM (simple memory test) |
||||||
|
*
|
||||||
|
* USAGE INSTRUCTIONS |
||||||
|
* - Use the 'Gain' knob to control the input gain on the codec. See checkPot(). |
||||||
|
* - Use the 'Level' knob to control output volume with an AudioMixer4 object. |
||||||
|
* - Stomp switches S1 and S2 will write status to display, and turn on LED |
||||||
|
* - Encoder push-button switches will write status to display when pressed/released |
||||||
|
* - Encoder rotary control will adjust a positive/negative count and update display |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Audio.h> |
||||||
|
#include <SPI.h> |
||||||
|
#include "BALibrary.h" |
||||||
|
|
||||||
|
#include "DebugPrintf.h" |
||||||
|
#include "PhysicalControls.h" |
||||||
|
|
||||||
|
using namespace BALibrary; |
||||||
|
|
||||||
|
// OLED display stuff
|
||||||
|
#include "Adafruit_SH1106.h" |
||||||
|
#include "Adafruit_GFX.h" |
||||||
|
#include "Fonts/FreeSansBold9pt7b.h" |
||||||
|
constexpr unsigned SCREEN_WIDTH = 128; // OLED display width, in pixels
|
||||||
|
constexpr unsigned SCREEN_HEIGHT = 64; // OLED display height, in pixels
|
||||||
|
Adafruit_SH1106 display(37, 35, 10); |
||||||
|
|
||||||
|
// External SPI RAM
|
||||||
|
ExternalSramManager sramManager; |
||||||
|
ExtMemSlot memSlot; |
||||||
|
BASpiMemory spiMem1(SpiDeviceId::SPI_DEVICE1); |
||||||
|
unsigned spiAddress = 0; |
||||||
|
unsigned spiAddressMax; |
||||||
|
unsigned sramStage = 0; // stage 0 is zero, 1 is write, 2 is read
|
||||||
|
volatile float sramCompletion = 0.0f; |
||||||
|
volatile unsigned errorCount = 0; |
||||||
|
|
||||||
|
AudioInputI2Sslave i2sIn; |
||||||
|
AudioOutputI2Sslave i2sOut; |
||||||
|
AudioMixer4 volumeOut; |
||||||
|
|
||||||
|
// i2sIn --> volumeOut(Mixer) --> i2sOut
|
||||||
|
AudioConnection patchIn0(i2sIn, 0, volumeOut, 0); |
||||||
|
AudioConnection patchIn1(i2sIn, 1, volumeOut, 1); |
||||||
|
AudioConnection patchOut0(volumeOut,0, i2sOut, 0); |
||||||
|
AudioConnection patchOut1(volumeOut,0, i2sOut, 1); |
||||||
|
|
||||||
|
BAAudioControlWM8731master codec; |
||||||
|
elapsedMillis timer; |
||||||
|
|
||||||
|
// Create a control object using the number of switches, pots, encoders and outputs on the
|
||||||
|
// Multiverse pedal
|
||||||
|
BAPhysicalControls controls(6, 4, 4, 2); // (SW, POT, ENC, LED)
|
||||||
|
|
||||||
|
unsigned loopCounter = 0; |
||||||
|
|
||||||
|
void drawProgressBar(float completion); // declaration
|
||||||
|
|
||||||
|
void drawBlackaddrAudio() { |
||||||
|
display.setCursor(0, 24); // (x,y)
|
||||||
|
display.printf(" Blackaddr"); |
||||||
|
display.setCursor(0, 40); // (x,y)
|
||||||
|
display.printf(" Audio"); |
||||||
|
} |
||||||
|
|
||||||
|
void setup() { |
||||||
|
|
||||||
|
codec.disable(); // this will reset the codec
|
||||||
|
|
||||||
|
// wait up for the serial to appear for up to 1 second
|
||||||
|
Serial.begin(57600); |
||||||
|
unsigned serialLoopCount = 10; |
||||||
|
while (!Serial && (serialLoopCount > 0)) { |
||||||
|
delay(100); |
||||||
|
serialLoopCount--; |
||||||
|
} |
||||||
|
|
||||||
|
MULTIVERSE(); // constants defined in BALibrary become valid only after this call
|
||||||
|
SPI_MEM1_64M(); // Declare the correct memory size
|
||||||
|
|
||||||
|
// Init the display
|
||||||
|
display.begin(SH1106_SWITCHCAPVCC, SH1106_I2C_ADDRESS, true); |
||||||
|
display.clearDisplay(); |
||||||
|
display.display(); |
||||||
|
display.setTextColor(WHITE); // Draw white text
|
||||||
|
display.setFont(&FreeSansBold9pt7b); |
||||||
|
drawBlackaddrAudio(); |
||||||
|
display.display(); |
||||||
|
|
||||||
|
configPhysicalControls(&controls, &codec);
|
||||||
|
|
||||||
|
// Request a memory slot from the external RAM
|
||||||
|
size_t numBytes = BAHardwareConfig.getSpiMemSizeBytes(MemSelect::MEM1); |
||||||
|
spiAddressMax = BAHardwareConfig.getSpiMemMaxAddr(1)/4; // test the first 25% of memory
|
||||||
|
bool success = sramManager.requestMemory(&memSlot, numBytes, MemSelect::MEM1, /* no DMA */ false); |
||||||
|
if (!success && Serial) { printf("Request for memory slot failed\n\r"); }
|
||||||
|
|
||||||
|
// Allocated audio buffers and enable codec
|
||||||
|
AudioMemory(64); |
||||||
|
codec.enable(); |
||||||
|
delay(100); |
||||||
|
|
||||||
|
// Mixer at full volume
|
||||||
|
volumeOut.gain(0,1.0f); |
||||||
|
volumeOut.gain(1,1.0f); |
||||||
|
|
||||||
|
// flush the pot filters. The analog measurement of the analog pots is averaged (filtered)
|
||||||
|
// over time, so at startup you will see a bunch of false changes detected as the filter
|
||||||
|
// settles. We can force this with a few dozen repeated calls.
|
||||||
|
for (unsigned i=0; i < 50; i++) { |
||||||
|
float potValue; |
||||||
|
for (unsigned j=0; j < BA_EXPAND_NUM_POT; j++) { |
||||||
|
controls.checkPotValue(j, potValue);
|
||||||
|
} |
||||||
|
delay(10); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void loop() { |
||||||
|
|
||||||
|
// Check all the physical controls for updates
|
||||||
|
checkPot(0); |
||||||
|
checkPot(1); |
||||||
|
checkPot(2); |
||||||
|
checkPot(3); |
||||||
|
|
||||||
|
checkSwitch(0); |
||||||
|
checkSwitch(1); |
||||||
|
checkSwitch(2); |
||||||
|
checkSwitch(3); |
||||||
|
checkSwitch(4); |
||||||
|
checkSwitch(5); |
||||||
|
|
||||||
|
checkEncoder(0); |
||||||
|
checkEncoder(1); |
||||||
|
checkEncoder(2); |
||||||
|
checkEncoder(3);
|
||||||
|
|
||||||
|
// If the SRAM test is not complete, run the next block
|
||||||
|
if (sramCompletion < 1.0f) { |
||||||
|
nextSpiMemTestBlock();
|
||||||
|
} |
||||||
|
|
||||||
|
// Adjusting one of the knobs/switches will result in its value being display for
|
||||||
|
// 2 seconds in the check*() functions.
|
||||||
|
if (timer > 2000) { |
||||||
|
loopCounter++;
|
||||||
|
display.clearDisplay(); |
||||||
|
drawBlackaddrAudio(); |
||||||
|
drawSramProgress(sramCompletion);
|
||||||
|
display.display();
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// This function will draw on the display which stage the memory test is in, and
|
||||||
|
// the percentage complete for that stage.
|
||||||
|
void drawSramProgress(float completion) |
||||||
|
{ |
||||||
|
if (errorCount > 0) { // If errors, print the error count
|
||||||
|
display.setCursor(0, SCREEN_HEIGHT-1); |
||||||
|
display.printf("Errors: %d", errorCount);
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Draw the SRAM test progress at the bottom of the screen
|
||||||
|
display.setCursor(0, SCREEN_HEIGHT-1); |
||||||
|
switch(sramStage) {
|
||||||
|
case 0 : display.printf("0 mem:"); break; |
||||||
|
case 1 : display.printf("0 chk:"); break; |
||||||
|
case 2 : display.printf("wr mem:"); break; |
||||||
|
case 3 : display.printf("rd mem:"); break; |
||||||
|
case 4 : // same as default
|
||||||
|
default: display.printf("Done"); break; |
||||||
|
} |
||||||
|
display.setCursor(SCREEN_WIDTH*0.63f, SCREEN_HEIGHT-1); // position to lower right corner
|
||||||
|
display.printf("%0.f%%", 100.0f * completion); |
||||||
|
} |
||||||
|
|
||||||
|
// Create a predictable data pattern based on address.
|
||||||
|
constexpr int mask0 = 0x5555; |
||||||
|
constexpr int mask1 = 0xaaaa; |
||||||
|
int calcNextData(int spiAddress, int loopPhase, int maskPhase) |
||||||
|
{ |
||||||
|
int data; |
||||||
|
|
||||||
|
int phase = ((loopPhase << 1) + maskPhase) & 0x3; |
||||||
|
switch(phase) |
||||||
|
{ |
||||||
|
case 0 : |
||||||
|
data = spiAddress ^ mask0; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
data = spiAddress ^ mask1; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
data = ~spiAddress ^ mask0; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
data = ~spiAddress ^ mask1; |
||||||
|
|
||||||
|
} |
||||||
|
return (data & 0xffff); |
||||||
|
} |
||||||
|
|
||||||
|
// Process the next block of data in the memory test
|
||||||
|
void nextSpiMemTestBlock() |
||||||
|
{ |
||||||
|
constexpr unsigned BLOCK_SIZE_BYTES = 256; // transfer 256 bytes (arbitrary) per transaction
|
||||||
|
constexpr unsigned NUM_BLOCK_WORDS = BLOCK_SIZE_BYTES; |
||||||
|
static uint8_t buffer[BLOCK_SIZE_BYTES]; |
||||||
|
static int16_t buffer16a[NUM_BLOCK_WORDS]; |
||||||
|
static int16_t buffer16b[NUM_BLOCK_WORDS]; |
||||||
|
static int maskPhase = 0; |
||||||
|
|
||||||
|
if (sramStage == 0) { // Zero write
|
||||||
|
// zero the memory
|
||||||
|
while (spiMem1.isWriteBusy()) {} // wait for DMA write to complete
|
||||||
|
memSlot.zero(spiAddress, BLOCK_SIZE_BYTES); |
||||||
|
spiAddress += BLOCK_SIZE_BYTES;
|
||||||
|
|
||||||
|
} else if (sramStage == 1) { // Zero check
|
||||||
|
memSlot.read(spiAddress, buffer, BLOCK_SIZE_BYTES); |
||||||
|
while (spiMem1.isReadBusy()) {} // wait for DMA read results
|
||||||
|
for (unsigned i=0; i < BLOCK_SIZE_BYTES; i++) { |
||||||
|
if (buffer[i] != 0) { errorCount++; } |
||||||
|
} |
||||||
|
spiAddress += BLOCK_SIZE_BYTES; |
||||||
|
|
||||||
|
} |
||||||
|
else if (sramStage == 2) { // write test
|
||||||
|
// Calculate the data for a block
|
||||||
|
for (unsigned i=0; i<NUM_BLOCK_WORDS; i++) { |
||||||
|
buffer16a[i] = calcNextData(spiAddress+i, 0, 0); |
||||||
|
maskPhase = (maskPhase+1) % 2; |
||||||
|
} |
||||||
|
memSlot.write16(spiAddress, buffer16a, NUM_BLOCK_WORDS); |
||||||
|
while (memSlot.isWriteBusy()) {} // wait for DMA write to complete
|
||||||
|
spiAddress += BLOCK_SIZE_BYTES; |
||||||
|
|
||||||
|
} |
||||||
|
else if (sramStage == 3) { // read test
|
||||||
|
// Calculate the data for a block
|
||||||
|
for (unsigned i=0; i<NUM_BLOCK_WORDS; i++) { |
||||||
|
buffer16a[i] = calcNextData(spiAddress+i, 0, 0); |
||||||
|
maskPhase = (maskPhase+1) % 2; |
||||||
|
} |
||||||
|
memSlot.read16(spiAddress, buffer16b, NUM_BLOCK_WORDS); |
||||||
|
while (memSlot.isReadBusy()) {} // wait for DMA read results
|
||||||
|
for (unsigned i=0; i < NUM_BLOCK_WORDS; i++) { |
||||||
|
if (buffer16a[i] != buffer16b[i]) { errorCount++; } |
||||||
|
}
|
||||||
|
spiAddress += BLOCK_SIZE_BYTES; |
||||||
|
} |
||||||
|
|
||||||
|
else if (sramStage == 4) { |
||||||
|
sramCompletion = 1.0f; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (spiAddress > spiAddressMax && sramStage < 4) {
|
||||||
|
spiAddress = 0; sramStage++; sramCompletion = 0.0f; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sramCompletion = (float)spiAddress / (float)spiAddressMax ; |
||||||
|
} |
@ -0,0 +1,222 @@ |
|||||||
|
#include <cmath> |
||||||
|
#include "Adafruit_SH1106.h" |
||||||
|
#include "BALibrary.h" |
||||||
|
#include "DebugPrintf.h" |
||||||
|
|
||||||
|
using namespace BALibrary; |
||||||
|
|
||||||
|
// Declare the externally shared variables from the main .ino
|
||||||
|
extern Adafruit_SH1106 display; |
||||||
|
extern BAAudioControlWM8731master codec; |
||||||
|
extern AudioMixer4 volumeOut; |
||||||
|
extern elapsedMillis timer; |
||||||
|
|
||||||
|
constexpr int displayRow = 36; // Row to start OLED display updates on
|
||||||
|
constexpr int potCalibMin = 8; |
||||||
|
constexpr int potCalibMax = 1016; |
||||||
|
constexpr bool potSwapDirection = true; |
||||||
|
constexpr bool encSwapDirection = true; |
||||||
|
int pot1Handle= -1, pot2Handle = -1, pot3Handle = -1, pot4Handle = -1; |
||||||
|
int sw1Handle = -1, sw2Handle = -1, sw3Handle = -1, sw4Handle = -1, sw5Handle = -1, sw6Handle = -1; |
||||||
|
int enc1Handle = -1, enc2Handle = -1, enc3Handle = -1, enc4Handle = -1; |
||||||
|
int led1Handle = -1, led2Handle = -1; |
||||||
|
|
||||||
|
BAAudioControlWM8731master *codecPtr = nullptr; |
||||||
|
BAPhysicalControls *controlPtr = nullptr; |
||||||
|
|
||||||
|
// Configure and setup the physical controls
|
||||||
|
void configPhysicalControls(BAPhysicalControls* controls, BAAudioControlWM8731master* codec) |
||||||
|
{ |
||||||
|
// Setup the controls. The return value is the handle to use when checking for control changes, etc.
|
||||||
|
controlPtr = controls; |
||||||
|
codecPtr = codec; |
||||||
|
|
||||||
|
if (!controlPtr) { DEBUG_PRINT(Serial.printf("ERROR: controlPtr is invalid\n\r")); return; } |
||||||
|
if (!codecPtr) { DEBUG_PRINT(Serial.printf("ERROR: codecPtr is invalid\n\r")); return; } |
||||||
|
|
||||||
|
// pushbuttons
|
||||||
|
sw1Handle = controlPtr->addSwitch(BA_EXPAND_SW1_PIN); |
||||||
|
sw2Handle = controlPtr->addSwitch(BA_EXPAND_SW2_PIN); |
||||||
|
sw3Handle = controlPtr->addSwitch(BA_EXPAND_SW3_PIN); |
||||||
|
sw4Handle = controlPtr->addSwitch(BA_EXPAND_SW4_PIN); |
||||||
|
sw5Handle = controlPtr->addSwitch(BA_EXPAND_SW5_PIN); |
||||||
|
sw6Handle = controlPtr->addSwitch(BA_EXPAND_SW6_PIN); |
||||||
|
// pots
|
||||||
|
pot1Handle = controlPtr->addPot(BA_EXPAND_POT1_PIN, potCalibMin, potCalibMax, potSwapDirection); |
||||||
|
pot2Handle = controlPtr->addPot(BA_EXPAND_POT2_PIN, potCalibMin, potCalibMax, potSwapDirection);
|
||||||
|
pot3Handle = controlPtr->addPot(BA_EXPAND_POT3_PIN, potCalibMin, potCalibMax, potSwapDirection); |
||||||
|
pot4Handle = controlPtr->addPot(BA_EXPAND_POT4_PIN, potCalibMin, potCalibMax, potSwapDirection); |
||||||
|
|
||||||
|
// encoders
|
||||||
|
enc1Handle = controlPtr->addRotary(BA_EXPAND_ENC1_A_PIN, BA_EXPAND_ENC1_B_PIN, encSwapDirection); |
||||||
|
enc2Handle = controlPtr->addRotary(BA_EXPAND_ENC2_A_PIN, BA_EXPAND_ENC2_B_PIN, encSwapDirection);
|
||||||
|
enc3Handle = controlPtr->addRotary(BA_EXPAND_ENC3_A_PIN, BA_EXPAND_ENC3_B_PIN, encSwapDirection); |
||||||
|
enc4Handle = controlPtr->addRotary(BA_EXPAND_ENC4_A_PIN, BA_EXPAND_ENC4_B_PIN, encSwapDirection); |
||||||
|
|
||||||
|
// leds
|
||||||
|
led1Handle = controlPtr->addOutput(BA_EXPAND_LED1_PIN); |
||||||
|
led2Handle = controlPtr->addOutput(BA_EXPAND_LED2_PIN); // will illuminate when pressing SW2
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void checkPot(unsigned id) |
||||||
|
{ |
||||||
|
float potValue; |
||||||
|
unsigned handle; |
||||||
|
switch(id) { |
||||||
|
case 0 : |
||||||
|
handle = pot1Handle; |
||||||
|
break; |
||||||
|
case 1 : |
||||||
|
handle = pot2Handle; |
||||||
|
break; |
||||||
|
case 2 : |
||||||
|
handle = pot3Handle; |
||||||
|
break; |
||||||
|
case 3 : |
||||||
|
handle = pot4Handle; |
||||||
|
break; |
||||||
|
default : |
||||||
|
handle = pot1Handle; |
||||||
|
} |
||||||
|
|
||||||
|
if ((handle < 0) || (handle >= controlPtr->getNumPots())) { |
||||||
|
DEBUG_PRINT(Serial.printf("ILLEGAL POT HANDLE: %d for id %d\n\r", handle, id)); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (controlPtr->checkPotValue(handle, potValue)) { |
||||||
|
// Pot has changed
|
||||||
|
DEBUG_PRINT(Serial.println(String("POT") + id + String(" value: ") + potValue)); |
||||||
|
|
||||||
|
timer = 0; |
||||||
|
display.clearDisplay(); |
||||||
|
display.setCursor(0,displayRow); |
||||||
|
switch(id) { |
||||||
|
case 0 : |
||||||
|
{ |
||||||
|
display.printf("Gain: %0.f\n", potValue * 100.0f); |
||||||
|
int gain = static_cast<int>(std::roundf(31.0f * potValue)); |
||||||
|
codecPtr->setLeftInputGain(gain); |
||||||
|
codecPtr->setRightInputGain(gain); |
||||||
|
yield(); // give time for i2C transfers to complete
|
||||||
|
break; |
||||||
|
} |
||||||
|
case 1 :
|
||||||
|
{ |
||||||
|
display.printf("Level: %0.f\n", potValue * 100.0f); |
||||||
|
volumeOut.gain(0, potValue); |
||||||
|
volumeOut.gain(1, potValue); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 2 : display.printf("Exp T: %0.f\n", potValue * 100.0f); break; |
||||||
|
case 3 : display.printf("Exp R: %0.f\n", potValue * 100.0f); break; |
||||||
|
} |
||||||
|
display.display(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
int checkSwitch(unsigned id, bool getValueOnly=false) |
||||||
|
{ |
||||||
|
unsigned swHandle = -1; |
||||||
|
unsigned ledHandle = -1; |
||||||
|
switch(id) { |
||||||
|
case 0 : |
||||||
|
swHandle = sw1Handle; |
||||||
|
ledHandle = led1Handle; |
||||||
|
break; |
||||||
|
case 1 : |
||||||
|
swHandle = sw2Handle; |
||||||
|
ledHandle = led2Handle; |
||||||
|
break; |
||||||
|
case 2 : |
||||||
|
swHandle = sw3Handle; |
||||||
|
break; |
||||||
|
case 3 : |
||||||
|
swHandle = sw4Handle; |
||||||
|
break; |
||||||
|
case 4 : |
||||||
|
swHandle = sw5Handle; |
||||||
|
break; |
||||||
|
case 5 : |
||||||
|
swHandle = sw6Handle; |
||||||
|
break; |
||||||
|
default : |
||||||
|
swHandle = sw1Handle; |
||||||
|
ledHandle = led1Handle; |
||||||
|
} |
||||||
|
|
||||||
|
if ((swHandle < 0) || (swHandle >= controlPtr->getNumSwitches())) { |
||||||
|
DEBUG_PRINT(Serial.printf("ILLEGAL SWITCH HANDLE: %d for id %d\n\r", swHandle, id); Serial.flush()); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
bool switchValue; |
||||||
|
bool changed = controlPtr->hasSwitchChanged(swHandle, switchValue); |
||||||
|
if (getValueOnly) { return controlPtr->getSwitchValue(swHandle); } |
||||||
|
|
||||||
|
if (changed) { |
||||||
|
DEBUG_PRINT(Serial.println(String("Button ") + id + String(" pressed"))); |
||||||
|
timer = 0; |
||||||
|
display.clearDisplay(); |
||||||
|
display.setCursor(0, displayRow); |
||||||
|
switch(id) { |
||||||
|
case 0 : display.printf("S1: %d\n", switchValue); break; |
||||||
|
case 1 : display.printf("S2: %d\n", switchValue); break; |
||||||
|
case 2 : display.printf("EncSw A: %d\n", switchValue); break; |
||||||
|
case 3 : display.printf("EncSw B: %d\n", switchValue); break; |
||||||
|
case 4 : display.printf("EncSw C: %d\n", switchValue); break; |
||||||
|
case 5 : display.printf("EncSw D: %d\n", switchValue); break; |
||||||
|
} |
||||||
|
display.display(); |
||||||
|
} |
||||||
|
|
||||||
|
if (swHandle < 2) { // these SWs map to LEDs
|
||||||
|
bool pressed = controlPtr->isSwitchHeld(swHandle); |
||||||
|
controlPtr->setOutput(ledHandle, pressed); |
||||||
|
} |
||||||
|
return controlPtr->getSwitchValue(swHandle); |
||||||
|
} |
||||||
|
|
||||||
|
void checkEncoder(unsigned id) |
||||||
|
{ |
||||||
|
unsigned encHandle; |
||||||
|
static int enc1 = 0, enc2 = 0, enc3 = 0, enc4 = 0; |
||||||
|
switch(id) { |
||||||
|
case 0 : |
||||||
|
encHandle = enc1Handle; |
||||||
|
break; |
||||||
|
case 1 : |
||||||
|
encHandle = enc2Handle; |
||||||
|
break; |
||||||
|
case 2 : |
||||||
|
encHandle = enc3Handle; |
||||||
|
break; |
||||||
|
case 3 : |
||||||
|
encHandle = enc4Handle; |
||||||
|
break; |
||||||
|
default : |
||||||
|
encHandle = enc1Handle; |
||||||
|
} |
||||||
|
|
||||||
|
if ((encHandle < 0) || (encHandle >= controlPtr->getNumRotary())) { |
||||||
|
DEBUG_PRINT(Serial.printf("ILLEGAL ENCODER HANDLE: %d for id %d\n\r", encHandle, id); Serial.flush()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
int adj= controlPtr->getRotaryAdjustUnit(encHandle); |
||||||
|
if (adj != 0) {
|
||||||
|
DEBUG_PRINT(Serial.printf("Enc %d: %d\n\r", id, adj); Serial.flush());
|
||||||
|
display.clearDisplay(); |
||||||
|
display.setCursor(0, displayRow); |
||||||
|
switch(id) { |
||||||
|
case 0 : enc1 += adj; display.printf("Enc A: %d", enc1); break; |
||||||
|
case 1 : enc2 += adj; display.printf("Enc B: %d", enc2); break; |
||||||
|
case 2 : enc3 += adj; display.printf("Enc C: %d", enc3); break; |
||||||
|
case 3 : enc4 += adj; display.printf("Enc D: %d", enc4); break; |
||||||
|
} |
||||||
|
display.display(); |
||||||
|
timer = 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
#ifndef PHYSICAL_CONTROLS_H_ |
||||||
|
#define PHYSICAL_CONTROLS_H_ |
||||||
|
|
||||||
|
#include "BALibrary.h" |
||||||
|
|
||||||
|
void configPhysicalControls(BALibrary::BAPhysicalControls* controls, BALibrary::BAAudioControlWM8731master* codec); |
||||||
|
void checkPot(unsigned id); |
||||||
|
int checkSwitch(unsigned id, bool getValueOnly=false); |
||||||
|
void checkEncoder(unsigned id); |
||||||
|
|
||||||
|
#endif |
@ -1,15 +1,19 @@ |
|||||||
#include "DmaSpi.h" |
#include "DmaSpi.h" |
||||||
|
|
||||||
#if defined(__IMXRT1062__) // T4.0
|
#if defined(__IMXRT1062__) // T4.X
|
||||||
DmaSpi0 DMASPI0; |
DmaSpi0 DMASPI0; |
||||||
|
#if defined(ARDUINO_TEENSY_MICROMOD) || defined (ARDUINO_TEENSY41) |
||||||
|
DmaSpi1 DMASPI1; |
||||||
|
#endif |
||||||
|
|
||||||
#elif defined(KINETISK) |
#elif defined(KINETISK) |
||||||
DmaSpi0 DMASPI0; |
DmaSpi0 DMASPI0; |
||||||
#if defined(__MK66FX1M0__) |
#if defined(__MK66FX1M0__) |
||||||
DmaSpi1 DMASPI1; |
DmaSpi1 DMASPI1; |
||||||
//DmaSpi2 DMASPI2;
|
//DmaSpi2 DMASPI2;
|
||||||
#endif |
#endif |
||||||
#elif defined (KINETISL) |
#elif defined (KINETISL) |
||||||
DmaSpi0 DMASPI0; |
DmaSpi0 DMASPI0; |
||||||
DmaSpi1 DMASPI1; |
DmaSpi1 DMASPI1; |
||||||
#else |
#else |
||||||
#endif // defined
|
#endif // defined
|
||||||
|
Loading…
Reference in new issue