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

Dependencies:   I2S USBDevice mbed

Fork of USBAudioPlayback by Samuel Mokrani

Committer:
edy555
Date:
Tue Sep 16 23:24:18 2014 +0000
Revision:
7:cfcf37ea571b
Parent:
6:dc7b32ce4277
first publish

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 0:eb53799c0b97 1 // Playback example with the USBAUDIO library
samux 0:eb53799c0b97 2
samux 0:eb53799c0b97 3 #include "mbed.h"
samux 0:eb53799c0b97 4 #include "USBAudio.h"
edy555 3:44343b9dd8b6 5 #include "I2S.h"
samux 0:eb53799c0b97 6
edy555 6:dc7b32ce4277 7 // frequency: 96 kHz
edy555 3:44343b9dd8b6 8 #define FREQ_SPK 96000
edy555 3:44343b9dd8b6 9 #define FREQ_MIC 8000
samux 0:eb53799c0b97 10
samux 0:eb53799c0b97 11 // 2channels: stereo
samux 0:eb53799c0b97 12 #define NB_CHA_SPK 2
edy555 4:a3aee5fc768a 13 #define NB_CHA_MIC 0
samux 0:eb53799c0b97 14
samux 0:eb53799c0b97 15 // length computed: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there are two channels, the length will be 48 * 2 * 2
samux 0:eb53799c0b97 16 #define LENGTH_AUDIO_PACKET_SPK (FREQ_SPK / 500) * NB_CHA_SPK
samux 0:eb53799c0b97 17 #define LENGTH_AUDIO_PACKET_MIC (FREQ_MIC / 500) * NB_CHA_MIC
samux 0:eb53799c0b97 18
samux 0:eb53799c0b97 19 // USBAudio object
samux 0:eb53799c0b97 20 USBAudio audio(FREQ_SPK, NB_CHA_SPK, FREQ_MIC, NB_CHA_MIC, 0xab45, 0x0378);
samux 0:eb53799c0b97 21
edy555 3:44343b9dd8b6 22 DigitalOut myled(LED1);
edy555 3:44343b9dd8b6 23
edy555 3:44343b9dd8b6 24 I2S i2s(I2S_TRANSMIT, p5, p6, p7);
edy555 3:44343b9dd8b6 25 I2S i2srx(I2S_RECEIVE, p8, p29, p15);
edy555 3:44343b9dd8b6 26
edy555 6:dc7b32ce4277 27 //SPI spi(p11, p12, p13); // mosi, miso, sclk
edy555 6:dc7b32ce4277 28 DigitalOut mode(p14);
edy555 6:dc7b32ce4277 29 DigitalOut spiout(p11);
edy555 6:dc7b32ce4277 30 DigitalOut spiclk(p13);
edy555 6:dc7b32ce4277 31
edy555 5:ca2316551f3d 32 #define CHUNKS 8
edy555 3:44343b9dd8b6 33
edy555 3:44343b9dd8b6 34 int buf_out[LENGTH_AUDIO_PACKET_MIC/sizeof(int)];
edy555 3:44343b9dd8b6 35 int16_t buf_in[CHUNKS][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
edy555 3:44343b9dd8b6 36 int16_t * stream_in = NULL;
edy555 3:44343b9dd8b6 37 int16_t * stream_in_tail = NULL;
edy555 3:44343b9dd8b6 38 int read_pos = 0;
edy555 3:44343b9dd8b6 39 int write_pos = 0;
edy555 3:44343b9dd8b6 40
edy555 3:44343b9dd8b6 41 void genwave()
edy555 3:44343b9dd8b6 42 {
edy555 3:44343b9dd8b6 43 int buf[8];
edy555 3:44343b9dd8b6 44 if (stream_in == NULL) {
edy555 3:44343b9dd8b6 45 buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
edy555 3:44343b9dd8b6 46 i2s.write(buf, 6);
edy555 3:44343b9dd8b6 47 return;
edy555 3:44343b9dd8b6 48 }
edy555 3:44343b9dd8b6 49
edy555 3:44343b9dd8b6 50 myled = 1;
edy555 3:44343b9dd8b6 51 buf[0] = stream_in[0];
edy555 3:44343b9dd8b6 52 buf[1] = stream_in[1];
edy555 3:44343b9dd8b6 53 buf[2] = stream_in[2];
edy555 3:44343b9dd8b6 54 buf[3] = stream_in[3];
edy555 3:44343b9dd8b6 55 buf[4] = stream_in[4];
edy555 3:44343b9dd8b6 56 buf[5] = stream_in[5];
edy555 3:44343b9dd8b6 57 buf[6] = stream_in[6];
edy555 3:44343b9dd8b6 58 buf[7] = stream_in[7];
edy555 3:44343b9dd8b6 59 i2s.write(buf, 8);
edy555 3:44343b9dd8b6 60 stream_in += 8;
edy555 3:44343b9dd8b6 61 if (stream_in >= stream_in_tail) {
edy555 5:ca2316551f3d 62 int d = read_pos - write_pos;
edy555 5:ca2316551f3d 63 if (d < 0)
edy555 5:ca2316551f3d 64 d += CHUNKS;
edy555 5:ca2316551f3d 65 if (d > CHUNKS/4) {
edy555 5:ca2316551f3d 66 write_pos++;
edy555 5:ca2316551f3d 67 write_pos %= CHUNKS;
edy555 5:ca2316551f3d 68 }
edy555 3:44343b9dd8b6 69 stream_in = buf_in[write_pos];
edy555 3:44343b9dd8b6 70 stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
edy555 3:44343b9dd8b6 71 }
edy555 3:44343b9dd8b6 72 myled = 0;
edy555 3:44343b9dd8b6 73 }
edy555 3:44343b9dd8b6 74
edy555 6:dc7b32ce4277 75 void spi_send(int byte)
edy555 6:dc7b32ce4277 76 {
edy555 6:dc7b32ce4277 77 wait_us(10);
edy555 6:dc7b32ce4277 78 for (int i = 0; i < 8; i++) {
edy555 6:dc7b32ce4277 79 if (byte & (1 << i))
edy555 6:dc7b32ce4277 80 spiout = 1;
edy555 6:dc7b32ce4277 81 else
edy555 6:dc7b32ce4277 82 spiout = 0;
edy555 6:dc7b32ce4277 83 spiclk = 0;
edy555 6:dc7b32ce4277 84 wait_us(10);
edy555 6:dc7b32ce4277 85 spiclk = 1;
edy555 6:dc7b32ce4277 86 wait_us(10);
edy555 6:dc7b32ce4277 87 }
edy555 6:dc7b32ce4277 88 }
edy555 6:dc7b32ce4277 89
edy555 6:dc7b32ce4277 90
edy555 6:dc7b32ce4277 91 void init_uda1345() {
edy555 6:dc7b32ce4277 92 spiclk = 1;
edy555 6:dc7b32ce4277 93 mode = 1;
edy555 6:dc7b32ce4277 94 wait_us(100);
edy555 6:dc7b32ce4277 95 mode = 0;
edy555 6:dc7b32ce4277 96 spi_send(0x16);
edy555 6:dc7b32ce4277 97 mode = 1;
edy555 6:dc7b32ce4277 98 spi_send(0x21);
edy555 6:dc7b32ce4277 99 mode = 0;
edy555 6:dc7b32ce4277 100 spi_send(0x14);
edy555 6:dc7b32ce4277 101 mode = 1;
edy555 6:dc7b32ce4277 102 spi_send(0x84);
edy555 6:dc7b32ce4277 103 mode = 0;
edy555 6:dc7b32ce4277 104 wait_us(10);
edy555 6:dc7b32ce4277 105 mode = 1;
edy555 6:dc7b32ce4277 106 spi_send(0x02);
edy555 6:dc7b32ce4277 107 mode = 0;
edy555 6:dc7b32ce4277 108 wait_us(10);
edy555 6:dc7b32ce4277 109 mode = 1;
edy555 6:dc7b32ce4277 110 spi_send(0xc3);
edy555 6:dc7b32ce4277 111
edy555 6:dc7b32ce4277 112 #if 0
edy555 6:dc7b32ce4277 113 spi.format(8, 3);
edy555 6:dc7b32ce4277 114 spi.frequency(100000);
edy555 6:dc7b32ce4277 115 mode = 1;
edy555 6:dc7b32ce4277 116 wait_us(100);
edy555 6:dc7b32ce4277 117 mode = 0;
edy555 6:dc7b32ce4277 118 spi.write(0x68); // 0x16
edy555 6:dc7b32ce4277 119 wait_us(100);
edy555 6:dc7b32ce4277 120 mode = 1;
edy555 6:dc7b32ce4277 121 wait_us(100);
edy555 6:dc7b32ce4277 122 spi.write(0x84); // 0x21
edy555 6:dc7b32ce4277 123 wait_us(100);
edy555 6:dc7b32ce4277 124 mode = 0;
edy555 6:dc7b32ce4277 125 spi.write(0x28); // 0x14
edy555 6:dc7b32ce4277 126 wait_us(100);
edy555 6:dc7b32ce4277 127 mode = 1;
edy555 6:dc7b32ce4277 128 wait_us(100);
edy555 6:dc7b32ce4277 129 spi.write(0x21); // 0x84
edy555 6:dc7b32ce4277 130 wait_us(100);
edy555 6:dc7b32ce4277 131 mode = 0;
edy555 6:dc7b32ce4277 132 //spi.write(0x28); // 0x14
edy555 6:dc7b32ce4277 133 wait_us(100);
edy555 6:dc7b32ce4277 134 mode = 1;
edy555 6:dc7b32ce4277 135 wait_us(100);
edy555 6:dc7b32ce4277 136 spi.write(0x40); // 0x02
edy555 6:dc7b32ce4277 137 wait_us(100);
edy555 6:dc7b32ce4277 138 mode = 0;
edy555 6:dc7b32ce4277 139 //spi.write(0x28); // 0x14
edy555 6:dc7b32ce4277 140 wait_us(100);
edy555 6:dc7b32ce4277 141 mode = 1;
edy555 6:dc7b32ce4277 142 wait_us(100);
edy555 6:dc7b32ce4277 143 spi.write(0xc3); // 0xc3
edy555 6:dc7b32ce4277 144 //wait_us(100);
edy555 6:dc7b32ce4277 145 //mode = 0;
edy555 6:dc7b32ce4277 146 //wait_us(100);
edy555 6:dc7b32ce4277 147 //mode = 1;
edy555 6:dc7b32ce4277 148 #endif
edy555 6:dc7b32ce4277 149 }
edy555 6:dc7b32ce4277 150
samux 0:eb53799c0b97 151 int main() {
edy555 6:dc7b32ce4277 152 init_uda1345();
edy555 3:44343b9dd8b6 153 i2srx.masterslave(I2S_SLAVE);
edy555 3:44343b9dd8b6 154 i2srx.frequency(96000);
edy555 3:44343b9dd8b6 155 i2srx.start();
edy555 3:44343b9dd8b6 156 i2s.attach(genwave);
edy555 3:44343b9dd8b6 157 i2s.masterslave(I2S_MASTER);
edy555 3:44343b9dd8b6 158 i2s.wordsize(16);
edy555 3:44343b9dd8b6 159 i2s.frequency(96000);
edy555 3:44343b9dd8b6 160 i2s.set_interrupt_fifo_level(0);
edy555 3:44343b9dd8b6 161 i2s.start();
samux 0:eb53799c0b97 162
samux 0:eb53799c0b97 163 while (1) {
edy555 4:a3aee5fc768a 164 audio.read((uint8_t *)buf_in[read_pos++]);
edy555 3:44343b9dd8b6 165 read_pos %= CHUNKS;
edy555 3:44343b9dd8b6 166 if (stream_in == NULL && read_pos > CHUNKS / 2) {
edy555 3:44343b9dd8b6 167 stream_in = buf_in[write_pos];
edy555 3:44343b9dd8b6 168 stream_in_tail = &buf_in[write_pos][LENGTH_AUDIO_PACKET_SPK/sizeof(int16_t)];
edy555 3:44343b9dd8b6 169 }
samux 0:eb53799c0b97 170 }
samux 0:eb53799c0b97 171 }