/*
was:
I2S digital audio demonstrator for Teensy 3.0
Interfaces using Wolfson WM8731 codec.
now: experimental code for prototype development nixie, teensy 3.1 <> INMP 441
*/
/*
pins:
Rx pin 11 : I2S0_RX_BCLK <--> "CLK", Output
Rx pin 12 : I2S0_RX_FS <--> originally to WS, but due to board error: "SD" on affected boards, output
Rx pin 13 : RX pin <--> originally to SD, but due to board error: "WS" on affected boards, input
*/
// aim at 48kHz sampling rate
#define CLOCK_TYPE (I2S_CLOCK_48K_INTERNAL)
#include <Wire.h>
/* I2S digital audio */
#include <i2s.h>
/* Circular buffer for audio samples, interleaved left & right channel */
/*const uint16_t buffersize = DMA_BUFFER_SIZE; // must be a multiple of DMA_BUFFER_SIZE
volatile int16_t buffer[buffersize];
uint16_t nTX = 0;
uint16_t nRX = 0;*/
// allocate 32kB of data buffer
const uint16_t buffersize = 1024; // 2048;
volatile int32_t buffer[buffersize];
uint32_t nTX = 0;
uint32_t nRX = 0;
// added during debugging, neccessary?
uint32_t counter = 0;
/* --------------------- Direct I2S Receive, we get callback to read 2 words from the FIFO ----- */
void i2s_rx_callback( int32_t *pBuf )
{
// Read the data
buffer[nRX++] = pBuf[0];
buffer[nRX++] = pBuf[1];
if( nRX>=buffersize ) {
nRX=0;
counter++;
}
}
/* --------------------- Direct I2S Transmit, we get callback to put 2 words into the FIFO ----- */
void i2s_tx_callback( int32_t *pBuf )
{
// Send the data
pBuf[0] = buffer[nTX++];
pBuf[1] = buffer[nTX++];
if( nTX>=buffersize ) nTX=0;
}
/* ----------------------- begin -------------------- */
void setup()
{
// << nothing before the first delay will be printed to the serial
Serial.begin(9600);
delay(1500);
Serial.print("Pin configuration: ");
Serial.println( I2S_PIN_PATTERN , HEX );
Serial.println( "Initializing." );
delay(100);
Serial.println( "Initialized I2C Codec" );
delay(100);
I2SRx0.begin( CLOCK_TYPE, i2s_rx_callback );
Serial.println( "Initialized I2S RX without DMA" );
// I2STx0.begin( CLOCK_TYPE, i2s_tx_callback );
// Serial.println( "Initialized I2S TX without DMA" );
// Before starting tx/rx, set the buffer pointers
nRX = 0;
nTX = 0;
// fill the buffer with something to see if the RX callback is activated at all
buffer[0] = 0x42424242;
//I2STx0.start();
// enable I2S RX
I2SRx0.start();
Serial.println( "Started I2S RX" );
// quick check how often the callback will be called, we expect 48000 times per second
// but: this is no gurantee for correct output clocks / presence of input data (!)
// counter = 0;
// delay(1000);
// Serial.println(counter * buffersize / 2);
}
/* --------------------- main loop ------------------ */
void loop()
{
/* quick debug print */
delay(1000);
Serial.print(buffer[0], HEX);
Serial.print(" ");
Serial.print(buffer[1], HEX);
/* debugging: print RX counters for sec and sef FIFO errors
Serial.print(" c:");
Serial.print(I2SRx0.fec_counter);
Serial.print("-");
Serial.print(I2SRx0.sef_counter); */
Serial.print("\r\n");
}