alpha build

This commit is contained in:
2025-05-27 13:13:29 +02:00
parent 468fa022e6
commit 559d92e526
3 changed files with 316 additions and 310 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

View File

@ -1,186 +1,191 @@
#include <TCA9555.h> #include <TCA9555.h>
#include <AS5600.h> #include <AS5600.h>
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
#include <PWMAudio.h> #include <PWMAudio.h>
#include <I2S.h> #include <I2S.h>
#define HAPTIC 0 #define HAPTIC 1
#define AURAL 0 #define AURAL 1
#define UI_SAMPLERATE 22050 #define UI_SAMPLERATE 22050
I2S i2s(INPUT_PULLUP); I2S i2s(INPUT_PULLUP);
TCA9555 TCA(0x20, &Wire1); TCA9555 TCA(0x20, &Wire1);
AS5600 ENC(&Wire1); AS5600 ENC(&Wire1);
PWMAudio ui_snd(8); PWMAudio ui_snd(8);
enum BUTTON {CVINL, CVINR, INL, INR, OUTR, OUTL, CVOUTR, CVOUTL, RIGHT, LEFT, SELECT, DEBUG1, DEBUG2, DEBUG3}; enum BUTTON {CVINL, CVINR, INL, INR, OUTR, OUTL, CVOUTR, CVOUTL, RIGHT, LEFT, SELECT, DEBUG1, DEBUG2, DEBUG3};
Adafruit_NeoPixel edge_pixels(8, 4, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel edge_pixels(8, 4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ui_pixels(72, 5, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel ui_pixels(72, 5, NEO_GRB + NEO_KHZ800);
volatile bool flag = false; volatile bool flag = false;
volatile bool click = false; volatile bool click = false;
volatile bool amp = false; volatile bool amp = false;
int counter = 0; int counter = 0;
bool buttons[16] = {false}; bool buttons[16] = {false};
int16_t beep[UI_SAMPLERATE]; int16_t beep[UI_SAMPLERATE];
void pwm_audio_callback() { void pwm_audio_callback() {
while (ui_snd.availableForWrite()) { while (ui_snd.availableForWrite()) {
if(click) { if(click) {
ui_snd.write(beep[counter]); ui_snd.write(beep[counter]);
} else { } else {
ui_snd.write(0); ui_snd.write(0);
} }
counter++; counter++;
if(counter == UI_SAMPLERATE) counter = 0; if(counter == UI_SAMPLERATE) counter = 0;
} }
} }
void tca_irq() { void tca_irq() {
flag = true; flag = true;
} }
void setup() { void setup() {
for(int i = 0; i < UI_SAMPLERATE; i++){ for(int i = 0; i < UI_SAMPLERATE; i++){
float sine_pos = (2.0f * M_PI * 8000.0f * (float)i) / (float)UI_SAMPLERATE; float sine_pos = (2.0f * M_PI * 8000.0f * (float)i) / (float)UI_SAMPLERATE;
beep[i] = (int16_t)(sin(sine_pos) * 8000.0f); beep[i] = (int16_t)(sin(sine_pos) * 8000.0f);
} }
Serial.begin(); Serial.begin();
delay(2000); delay(2000);
Serial.println("INIT WIRE"); Serial.println("INIT WIRE");
Wire1.setSDA(2); Wire1.setSDA(2);
Wire1.setSCL(3); Wire1.setSCL(3);
Wire1.begin(); Wire1.begin();
Serial.println("SUCCESS"); Serial.println("SUCCESS");
Serial.println("INIT TCA"); Serial.println("INIT TCA");
TCA.begin(); TCA.begin();
TCA.pinMode16(0xFFFF); TCA.pinMode16(0xFFFF);
TCA.setPolarity16(0x0000); TCA.setPolarity16(0x0000);
Serial.println("SUCCESS"); Serial.println("SUCCESS");
Serial.println("INIT INTERRUPT"); Serial.println("INIT INTERRUPT");
pinMode(1, INPUT_PULLUP); pinMode(1, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(1), tca_irq, FALLING); attachInterrupt(digitalPinToInterrupt(1), tca_irq, FALLING);
Serial.println("SUCCESS"); Serial.println("SUCCESS");
// Rotary Encoder // Rotary Encoder
ENC.begin(4); // set direction pin. ENC.begin(); // set direction pin.
ENC.setDirection(AS5600_COUNTERCLOCK_WISE);
pinMode(6, OUTPUT); // Vibration Motor
pinMode(7, OUTPUT); // UI Amp Enable pinMode(6, OUTPUT); // Vibration Motor
pinMode(7, OUTPUT); // UI Amp Enable
ui_snd.onTransmit(pwm_audio_callback);
ui_snd.begin(UI_SAMPLERATE); ui_snd.onTransmit(pwm_audio_callback);
ui_snd.begin(UI_SAMPLERATE);
digitalWrite(7, LOW);
digitalWrite(7, LOW);
edge_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
ui_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) edge_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
ui_pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
// i2s.setDOUT(14);
// i2s.setDIN(15); // i2s.setDOUT(14);
// i2s.setBCLK(16); // // i2s.setDIN(15);
// i2s.swapClocks(); // i2s.setBCLK(16); //
// i2s.setMCLK(18); // i2s.swapClocks();
// i2s.setBitsPerSample(16); // i2s.setMCLK(18);
// i2s.setFrequency(48000); // i2s.setBitsPerSample(16);
// i2s.setSysClk(48000); // i2s.setFrequency(48000);
// i2s.begin(); // i2s.setSysClk(48000);
// i2s.begin();
// while (1) {
// int16_t l, r; // while (1) {
// i2s.read16(&l, &r); // int16_t l, r;
// i2s.write16(l, r); // i2s.read16(&l, &r);
// } // i2s.write16(l, r);
} // }
int active = 0; }
uint32_t lastTime = 0; int active = 0;
int32_t position = 0; int active_led_ring = 0;
void loop() { uint32_t lastTime = 0;
edge_pixels.clear(); // Set all pixel colors to 'off' int32_t position = 0;
ui_pixels.clear(); // Set all pixel colors to 'off'
void loop() {
position = ENC.getCumulativePosition(); edge_pixels.clear(); // Set all pixel colors to 'off'
ui_pixels.clear(); // Set all pixel colors to 'off'
// if (millis() - lastTime >= 100)
// { position = ENC.getCumulativePosition();
// lastTime = millis();
// Serial.print(ENC.getCumulativePosition()); // if (millis() - lastTime >= 100)
// Serial.print("\t"); // {
// Serial.println(ENC.getRevolutions()); // lastTime = millis();
// } // Serial.print(ENC.getCumulativePosition());
// Serial.print("\t");
for (int i = 0; i < 48; i++) { // Serial.println(ENC.getRevolutions());
ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 0, 0)); // }
}
for (int i = 0; i < 48; i++) {
if (flag) { ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 0, 0));
int val = TCA.read16(); }
Serial.println(val, BIN);
if (flag) {
for(int i = 0; i < 16; i++){ int val = TCA.read16();
buttons[i] = ~(val >> i) & 0x01; Serial.println(val, BIN);
Serial.print(buttons[i]);
Serial.print(" "); for(int i = 0; i < 16; i++){
} buttons[i] = ~(val >> i) & 0x01;
Serial.println(); Serial.print(buttons[i]);
Serial.print(" ");
flag = false; }
if (HAPTIC) { Serial.println();
digitalWrite(6, HIGH);
} flag = false;
if (AURAL) { if (HAPTIC) {
digitalWrite(7, HIGH); digitalWrite(6, HIGH);
click = true; }
delay(50); if (AURAL) {
click = false; digitalWrite(7, HIGH);
digitalWrite(7, LOW); click = true;
} delay(50);
if(HAPTIC){ click = false;
if(!AURAL) delay(50); digitalWrite(7, LOW);
digitalWrite(6, LOW); }
} if(HAPTIC){
for (int i = 0; i < 48; i++) { if(!AURAL) delay(50);
ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 15, 0)); digitalWrite(6, LOW);
} }
if(buttons[RIGHT]) active++; for (int i = 0; i < 48; i++) {
if(buttons[LEFT]) active--; ui_pixels.setPixelColor(i + 3, edge_pixels.Color(0, 15, 0));
if(active == 13) active = 0; }
if(active == -1) active = 12; if(buttons[RIGHT]) active++;
} if(buttons[LEFT]) active--;
// 11111110 11111111 button right if(active == 13) active = 0;
if(active == -1) active = 12;
// EDGE LEDs }
for (int i = 0; i < 8; i++) { // 11111110 11111111 button right
edge_pixels.setPixelColor(i, edge_pixels.Color(15, 15, 15));
} // EDGE LEDs
for (int i = 0; i < 8; i++) {
// Rotary button LEDs edge_pixels.setPixelColor(i, edge_pixels.Color(15, 15, 15));
ui_pixels.setPixelColor(0, edge_pixels.Color(0, 0, 15)); }
ui_pixels.setPixelColor(1, edge_pixels.Color(0, 0, 15));
ui_pixels.setPixelColor(2, edge_pixels.Color(0, 0, 15)); // Rotary button LEDs
ui_pixels.setPixelColor(0, edge_pixels.Color(0, 0, 15));
for (int i = 0; i < 13; i++) { ui_pixels.setPixelColor(1, edge_pixels.Color(0, 0, 15));
ui_pixels.setPixelColor(i + 3 + 48 + 4, edge_pixels.Color(0, 0, 0)); ui_pixels.setPixelColor(2, edge_pixels.Color(0, 0, 15));
}
for (int i = 0; i < 13; i++) {
ui_pixels.setPixelColor(active + 3 + 48 + 4, edge_pixels.Color(255, 255, 255)); ui_pixels.setPixelColor(i + 3 + 48 + 4, edge_pixels.Color(0, 0, 0));
}
// put your main code here, to run repeatedly:
ui_pixels.setPixelColor(active + 3 + 48 + 4, edge_pixels.Color(255, 255, 255));
edge_pixels.show(); // Set all pixel colors to 'off'
ui_pixels.show(); // Set all pixel colors to 'off' active_led_ring = abs((position / 256) % 48);
ui_pixels.setPixelColor(active_led_ring + 3, edge_pixels.Color(255, 255, 255));
delay(1); // put your main code here, to run repeatedly:
edge_pixels.show(); // Set all pixel colors to 'off'
ui_pixels.show(); // Set all pixel colors to 'off'
delay(1);
} }

View File

@ -1,125 +1,125 @@
/* /*
I2S bi-directional input and output buffered loopback example I2S bi-directional input and output buffered loopback example
Released to the Public Domain by Cooper Dalrymple Released to the Public Domain by Cooper Dalrymple
*/ */
#include <Wire.h> #include <Wire.h>
#include <I2S.h> #include <I2S.h>
I2S i2s(INPUT_PULLUP); I2S i2s(INPUT_PULLUP);
#define SIZE 256 #define SIZE 256
int16_t buffer[SIZE]; int16_t buffer[SIZE];
void cw(char first, char second){ void cw(char first, char second){
Wire1.beginTransmission(0x18); Wire1.beginTransmission(0x18);
Wire1.write(first); Wire1.write(first);
Wire1.write(second); Wire1.write(second);
Wire1.endTransmission(); Wire1.endTransmission();
delay(5); delay(5);
} }
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
delay(1000); delay(1000);
Wire1.setSDA(2); Wire1.setSDA(2);
Wire1.setSCL(3); Wire1.setSCL(3);
Wire1.begin(); Wire1.begin();
delay(1000); delay(1000);
// GENERAL // GENERAL
cw(0x00, 0x00); cw(0x00, 0x00);
cw(0x01, 0x01); cw(0x01, 0x01);
cw(0x1b, 0x10); // select I2S cw(0x1b, 0x10); // select I2S
// ADC // ADC
cw(0x00, 0x00); // select page 0 cw(0x00, 0x00); // select page 0
//cw(0x01, 0x01); // soft reset //cw(0x01, 0x01); // soft reset
cw(0x12, 0x87); // NADC 7 cw(0x12, 0x87); // NADC 7
cw(0x13, 0x82); // MADC 2 cw(0x13, 0x82); // MADC 2
cw(0x14, 0x80); // OSR ADC 128 cw(0x14, 0x80); // OSR ADC 128
cw(0x3d, 0x01); // ADC PRB_R1 cw(0x3d, 0x01); // ADC PRB_R1
cw(0x00, 0x01); // select page 1 cw(0x00, 0x01); // select page 1
cw(0x01, 0x08); // disable crude AVdd cw(0x01, 0x08); // disable crude AVdd
cw(0x02, 0x01); // enable internal AVdd LDO cw(0x02, 0x01); // enable internal AVdd LDO
cw(0x0a, 0x0B); // set input CM to 0.9V and LO to 1.65V cw(0x0a, 0x0B); // set input CM to 0.9V and LO to 1.65V
cw(0x3d, 0x00); // ADC PTM_R4 cw(0x3d, 0x00); // ADC PTM_R4
cw(0x34, 0x80); // route IN1L to LEFT_P with 20k input impedance cw(0x34, 0x80); // route IN1L to LEFT_P with 20k input impedance
cw(0x36, 0x80); // route CM to LEFT_M with 20k input impedance cw(0x36, 0x80); // route CM to LEFT_M with 20k input impedance
cw(0x37, 0x80); // route IN1R to RIGHT_P with 20k input impedance cw(0x37, 0x80); // route IN1R to RIGHT_P with 20k input impedance
cw(0x39, 0x80); // route CM to RIGHT_M with 20k input impedance cw(0x39, 0x80); // route CM to RIGHT_M with 20k input impedance
cw(0x3b, 0x0c); // unmute left MICPGA cw(0x3b, 0x0c); // unmute left MICPGA
cw(0x3c, 0x0c); // unmute right MICPGA cw(0x3c, 0x0c); // unmute right MICPGA
cw(0x00, 0x00); // select page 0 cw(0x00, 0x00); // select page 0
cw(0x51, 0xc0); // power up ADC cw(0x51, 0xc0); // power up ADC
cw(0x51, 0x00); // unmute ADC digital volume control cw(0x51, 0x00); // unmute ADC digital volume control
// DAC // DAC
cw(0x00, 0x00); // select page 0 cw(0x00, 0x00); // select page 0
//cw(0x01, 0x01); // software reset //cw(0x01, 0x01); // software reset
cw(0x0b, 0x82); // NDAC 2 cw(0x0b, 0x82); // NDAC 2
cw(0x0c, 0x87); // MDAC 7 cw(0x0c, 0x87); // MDAC 7
cw(0x0d, 0x00); // OSR DAC 128 cw(0x0d, 0x00); // OSR DAC 128
cw(0x0e, 0x80); // OSR DAC 128 cw(0x0e, 0x80); // OSR DAC 128
cw(0x1b, 0x10); // world length 20bits PTM_P4 (highest performance) cw(0x1b, 0x10); // world length 20bits PTM_P4 (highest performance)
cw(0x3c, 0x08); // PRB_P8 cw(0x3c, 0x08); // PRB_P8
cw(0x00, 0x01); // select page 1 cw(0x00, 0x01); // select page 1
//cw(0x01, 0x08); // disable internal crude avdd //cw(0x01, 0x08); // disable internal crude avdd
//cw(0x02, 0x01); // enable AVdd LDO //cw(0x02, 0x01); // enable AVdd LDO
cw(0x7b, 0x01); // set REF charging time to 40ms cw(0x7b, 0x01); // set REF charging time to 40ms
//cw(0x14, 0x25); // set HP soft stepping for anti pop //cw(0x14, 0x25); // set HP soft stepping for anti pop
//cw(0x0a, 0x0B); // set input CM to 0.9V and LO to 1.65V //cw(0x0a, 0x0B); // set input CM to 0.9V and LO to 1.65V
cw(0x0e, 0x08); // left DAC reconstruction filter routed to LOL cw(0x0e, 0x08); // left DAC reconstruction filter routed to LOL
cw(0x0f, 0x08); // right DAC reconstruction filter routed to LOR cw(0x0f, 0x08); // right DAC reconstruction filter routed to LOR
cw(0x03, 0x00); // DAC PTM_P3/4 cw(0x03, 0x00); // DAC PTM_P3/4
cw(0x04, 0x00); // DAC PTM_P3/4 cw(0x04, 0x00); // DAC PTM_P3/4
cw(0x12, 0x00); // LOL gain 0dB cw(0x12, 0x00); // LOL gain 0dB
cw(0x13, 0x00); // LOR gain 0dB cw(0x13, 0x00); // LOR gain 0dB
delay(1000); delay(1000);
cw(0x00, 0x00); // select page 0 cw(0x00, 0x00); // select page 0
cw(0x3f, 0xd6); // power up and route left digital audio to left dac channel and right to right cw(0x3f, 0xd6); // power up and route left digital audio to left dac channel and right to right
cw(0x40, 0x00); // unmute DAC digital volume cw(0x40, 0x00); // unmute DAC digital volume
pinMode(19, OUTPUT); // MCLK enable pinMode(19, OUTPUT); // MCLK enable
pinMode(20, OUTPUT); // CODEC reset pinMode(20, OUTPUT); // CODEC reset
i2s.setSysClk(48000); i2s.setSysClk(48000);
i2s.setDOUT(14); i2s.setDOUT(14);
i2s.setDIN(15); i2s.setDIN(15);
i2s.setBCLK(16); // Note: LRCLK = BCLK + 1 i2s.setBCLK(16); // Note: LRCLK = BCLK + 1
i2s.setMCLK(18); i2s.setMCLK(18);
i2s.swapClocks(); i2s.swapClocks();
i2s.setBitsPerSample(16); i2s.setBitsPerSample(16);
i2s.setFrequency(48000); i2s.setFrequency(48000);
i2s.setMCLKmult(128); // 6144000Hz 6.144MHz i2s.setMCLKmult(128); // 6144000Hz 6.144MHz
i2s.setBuffers(6, SIZE * sizeof(int16_t) / sizeof(uint32_t)); i2s.setBuffers(6, SIZE * sizeof(int16_t) / sizeof(uint32_t));
digitalWrite(19, HIGH); // enable MCLK digitalWrite(19, HIGH); // enable MCLK
digitalWrite(20, HIGH); digitalWrite(20, HIGH);
i2s.begin(); i2s.begin();
size_t count, index; size_t count, index;
while (1) { while (1) {
count = i2s.read((uint8_t *)&buffer, SIZE * sizeof(int16_t)) * sizeof(uint32_t) / sizeof(int16_t); count = i2s.read((uint8_t *)&buffer, SIZE * sizeof(int16_t)) * sizeof(uint32_t) / sizeof(int16_t);
index = 0; index = 0;
while (index < count) { while (index < count) {
// Reduce volume by half // Reduce volume by half
buffer[index++] >>= 1; // right buffer[index++] >>= 1; // right
buffer[index++] >>= 1; // left buffer[index++] >>= 1; // left
} }
i2s.write((const uint8_t *)&buffer, count * sizeof(int16_t)); i2s.write((const uint8_t *)&buffer, count * sizeof(int16_t));
} }
} }
void loop() { void loop() {
/* Nothing here */ /* Nothing here */
} }