forked from W4D/soundcube-firmware
91 lines
1.8 KiB
C++
91 lines
1.8 KiB
C++
/*
|
|
I2S bi-directional input and output buffered loopback example
|
|
Released to the Public Domain by Cooper Dalrymple
|
|
*/
|
|
#include <Wire.h>
|
|
#include <I2S.h>
|
|
#include "codec.h"
|
|
|
|
I2S i2s(INPUT_PULLUP);
|
|
|
|
TLV320AIC3204 codec;
|
|
|
|
#define SIZE 16
|
|
#define ECHO 192000
|
|
int16_t buffer[SIZE];
|
|
int16_t buffer2[ECHO];
|
|
|
|
int16_t volume = 0;
|
|
size_t count;
|
|
size_t tape_write = 0;
|
|
|
|
void codec_transmit() {
|
|
for(int i = 0; i < count; i++){
|
|
buffer2[tape_write] = buffer[i];
|
|
tape_write++;
|
|
if(tape_write == ECHO) tape_write = 0;
|
|
|
|
int tape_read = tape_write + 1;
|
|
if(tape_read < 0) tape_read += ECHO;
|
|
buffer[i] += buffer2[tape_read % ECHO];
|
|
}
|
|
i2s.write((const uint8_t *)&buffer, count * sizeof(int16_t));
|
|
}
|
|
|
|
void codec_receive(){
|
|
count = i2s.read((uint8_t *)&buffer, SIZE * sizeof(int16_t)) * sizeof(uint32_t) / sizeof(int16_t);
|
|
for(int i = 0; i < count; i++){
|
|
buffer[i] *= -1;
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
i2s.setSysClk(48000);
|
|
|
|
Serial.begin(115200);
|
|
|
|
delay(2000);
|
|
|
|
Wire1.setSDA(2);
|
|
Wire1.setSCL(3);
|
|
Wire1.begin();
|
|
|
|
delay(100);
|
|
|
|
pinMode(19, OUTPUT); // MCLK enable
|
|
digitalWrite(19, HIGH); // enable MCLK
|
|
|
|
pinMode(20, OUTPUT); // CODEC reset
|
|
digitalWrite(20, HIGH);
|
|
|
|
codec.begin(&Wire1);
|
|
|
|
i2s.onTransmit(codec_transmit);
|
|
i2s.onReceive(codec_receive);
|
|
|
|
i2s.setDOUT(15);
|
|
i2s.setDIN(14);
|
|
i2s.setBCLK(16); // Note: LRCLK = BCLK + 1
|
|
i2s.setMCLK(18);
|
|
i2s.setMCLKmult(256); // 12.288.000Hz
|
|
|
|
i2s.swapClocks();
|
|
i2s.setBitsPerSample(16);
|
|
|
|
i2s.setBuffers(6, SIZE * sizeof(int16_t) / sizeof(uint32_t));
|
|
|
|
if(!i2s.begin(48000)){
|
|
Serial.println("I2S error!");
|
|
while(100);
|
|
}
|
|
|
|
}
|
|
|
|
int32_t last = 0;
|
|
int frame = 0;
|
|
|
|
void loop() {
|
|
frame++;
|
|
if(frame == 48000) frame = 0;
|
|
}
|