96kHz-16bit USB Audio Output interface with UDA1345 and 24.576MHz Xtal.

Dependencies:   I2S USBDevice mbed

Fork of USBAudioPlayback by Samuel Mokrani

main.cpp

Committer:
edy555
Date:
2014-09-16
Revision:
7:cfcf37ea571b
Parent:
6:dc7b32ce4277

File content as of revision 7:cfcf37ea571b:

// Playback example with the USBAUDIO library

#include "mbed.h"
#include "USBAudio.h"
#include "I2S.h"

// frequency: 96 kHz
#define FREQ_SPK 96000
#define FREQ_MIC 8000

// 2channels: stereo
#define NB_CHA_SPK 2
#define NB_CHA_MIC 0

// length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there are two channels, the length will be 48 * 2 * 2
#define LENGTH_AUDIO_PACKET_SPK (FREQ_SPK / 500) * NB_CHA_SPK
#define LENGTH_AUDIO_PACKET_MIC (FREQ_MIC / 500) * NB_CHA_MIC

// USBAudio object
USBAudio audio(FREQ_SPK, NB_CHA_SPK, FREQ_MIC, NB_CHA_MIC, 0xab45, 0x0378);

DigitalOut myled(LED1);

I2S i2s(I2S_TRANSMIT, p5, p6, p7);
I2S i2srx(I2S_RECEIVE, p8, p29, p15);

//SPI spi(p11, p12, p13); // mosi, miso, sclk
DigitalOut mode(p14);
DigitalOut spiout(p11);
DigitalOut spiclk(p13);

#define CHUNKS 8

int buf_out[LENGTH_AUDIO_PACKET_MIC/sizeof(int)];
int16_t buf_in[CHUNKS][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
int16_t * stream_in = NULL;
int16_t * stream_in_tail = NULL;
int read_pos = 0;
int write_pos = 0;

void genwave()
{
    int buf[8];
    if (stream_in == NULL) {
        buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
        i2s.write(buf, 6);
        return;
    }

    myled = 1;
    buf[0] = stream_in[0];
    buf[1] = stream_in[1];
    buf[2] = stream_in[2];
    buf[3] = stream_in[3];
    buf[4] = stream_in[4];
    buf[5] = stream_in[5];
    buf[6] = stream_in[6];
    buf[7] = stream_in[7];
    i2s.write(buf, 8);
    stream_in += 8;
    if (stream_in >= stream_in_tail) {
        int d = read_pos - write_pos;
        if (d < 0)
            d += CHUNKS;
        if (d > CHUNKS/4) {
            write_pos++;
            write_pos %= CHUNKS;
        }    
        stream_in = buf_in[write_pos];
        stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
    }
    myled = 0;
}

void spi_send(int byte)
{
    wait_us(10);
    for (int i = 0; i < 8; i++) {
        if (byte & (1 << i)) 
            spiout = 1;
        else
            spiout = 0;
        spiclk = 0;
        wait_us(10);
        spiclk = 1;
        wait_us(10);
    }
}
    

void init_uda1345() {
    spiclk = 1;
    mode = 1;
    wait_us(100);
    mode = 0;
    spi_send(0x16);
    mode = 1;
    spi_send(0x21);
    mode = 0;
    spi_send(0x14);
    mode = 1;
    spi_send(0x84);
    mode = 0;
    wait_us(10);
    mode = 1;
    spi_send(0x02);
    mode = 0;
    wait_us(10);
    mode = 1;
    spi_send(0xc3);
        
#if 0
    spi.format(8, 3);
    spi.frequency(100000);
    mode = 1;
    wait_us(100);
    mode = 0;
    spi.write(0x68); // 0x16
    wait_us(100);
    mode = 1;
    wait_us(100);
    spi.write(0x84); // 0x21
    wait_us(100);
    mode = 0;
    spi.write(0x28); // 0x14
    wait_us(100);
    mode = 1;
    wait_us(100);
    spi.write(0x21); // 0x84
    wait_us(100);
    mode = 0;
    //spi.write(0x28); // 0x14
    wait_us(100);
    mode = 1;
    wait_us(100);
    spi.write(0x40); // 0x02
    wait_us(100);
    mode = 0;
    //spi.write(0x28); // 0x14
    wait_us(100);
    mode = 1;
    wait_us(100);
    spi.write(0xc3); // 0xc3
    //wait_us(100);
    //mode = 0;
    //wait_us(100);    
    //mode = 1;
#endif
}

int main() {
    init_uda1345();
    i2srx.masterslave(I2S_SLAVE);
    i2srx.frequency(96000);
    i2srx.start();
    i2s.attach(genwave);
    i2s.masterslave(I2S_MASTER);
    i2s.wordsize(16);
    i2s.frequency(96000);
    i2s.set_interrupt_fifo_level(0);
    i2s.start();

    while (1) {
        audio.read((uint8_t *)buf_in[read_pos++]);
        read_pos %= CHUNKS;
        if (stream_in == NULL && read_pos > CHUNKS / 2) {
            stream_in = buf_in[write_pos];
            stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
        }
    }
}