| User | Revision | Line number | New contents of line |
| vcazan |
0:143457f10e26
|
1
|
//todo red button and light sensor
|
| vcazan |
0:143457f10e26
|
2
|
|
| vcazan |
0:143457f10e26
|
3
|
|
| vcazan |
0:143457f10e26
|
4
|
#include "mbed.h"
|
| vcazan |
0:143457f10e26
|
5
|
#include "SDFileSystem.h"
|
| vcazan |
0:143457f10e26
|
6
|
|
| vcazan |
0:143457f10e26
|
7
|
AnalogOut DACout(p18);
|
| vcazan |
0:143457f10e26
|
8
|
DigitalOut led1(LED1);
|
| vcazan |
0:143457f10e26
|
9
|
DigitalOut led2(LED2);
|
| vcazan |
0:143457f10e26
|
10
|
DigitalOut led3(LED3);
|
| vcazan |
0:143457f10e26
|
11
|
DigitalOut led4(LED4);
|
| vcazan |
0:143457f10e26
|
12
|
DigitalOut digout(p8);
|
| vcazan |
0:143457f10e26
|
13
|
Ticker tick;
|
| vcazan |
0:143457f10e26
|
14
|
SDFileSystem sd(p5, p6, p7, p13, "sd");
|
| vcazan |
0:143457f10e26
|
15
|
|
| vcazan |
0:143457f10e26
|
16
|
#define SAMPLE_FREQ 40000
|
| vcazan |
0:143457f10e26
|
17
|
#define BUF_SIZE (SAMPLE_FREQ/10)
|
| vcazan |
0:143457f10e26
|
18
|
#define SLICE_BUF_SIZE 1
|
| vcazan |
0:143457f10e26
|
19
|
|
| vcazan |
0:143457f10e26
|
20
|
void dac_out(void);
|
| vcazan |
0:143457f10e26
|
21
|
void play_wave(char *);
|
| vcazan |
0:143457f10e26
|
22
|
void cleanup(char *);
|
| vcazan |
0:143457f10e26
|
23
|
void fill_adc_buf(short *, unsigned);
|
| vcazan |
0:143457f10e26
|
24
|
void swapword(unsigned *);
|
| vcazan |
0:143457f10e26
|
25
|
|
| vcazan |
0:143457f10e26
|
26
|
// a FIFO for the DAC
|
| vcazan |
0:143457f10e26
|
27
|
short DAC_fifo[256];
|
| vcazan |
0:143457f10e26
|
28
|
short DAC_wptr;
|
| vcazan |
0:143457f10e26
|
29
|
short DAC_rptr;
|
| vcazan |
0:143457f10e26
|
30
|
short DAC_on;
|
| vcazan |
0:143457f10e26
|
31
|
|
| vcazan |
0:143457f10e26
|
32
|
typedef struct uFMT_STRUCT {
|
| vcazan |
0:143457f10e26
|
33
|
short comp_code;
|
| vcazan |
0:143457f10e26
|
34
|
short num_channels;
|
| vcazan |
0:143457f10e26
|
35
|
unsigned sample_rate;
|
| vcazan |
0:143457f10e26
|
36
|
unsigned avg_Bps;
|
| vcazan |
0:143457f10e26
|
37
|
short block_align;
|
| vcazan |
0:143457f10e26
|
38
|
short sig_bps;
|
| vcazan |
0:143457f10e26
|
39
|
} FMT_STRUCT;
|
| vcazan |
0:143457f10e26
|
40
|
|
| vcazan |
0:143457f10e26
|
41
|
|
| vcazan |
0:143457f10e26
|
42
|
int main() {
|
| vcazan |
0:143457f10e26
|
43
|
led1=0; wait(.5); led1=1; wait(.5); led1=0;
|
| vcazan |
0:143457f10e26
|
44
|
printf("Hello, world!\n");
|
| vcazan |
0:143457f10e26
|
45
|
play_wave("/sd/baddonut.wav");
|
| vcazan |
0:143457f10e26
|
46
|
printf("Back from play_wave()\n");
|
| vcazan |
0:143457f10e26
|
47
|
play_wave("/sd/clint16.wav");
|
| vcazan |
0:143457f10e26
|
48
|
printf("Back from play_wave()\n");
|
| vcazan |
0:143457f10e26
|
49
|
printf("Goodbye, world!\n");
|
| vcazan |
0:143457f10e26
|
50
|
}
|
| vcazan |
0:143457f10e26
|
51
|
|
| vcazan |
0:143457f10e26
|
52
|
void play_wave(char *wavname)
|
| vcazan |
0:143457f10e26
|
53
|
{
|
| vcazan |
0:143457f10e26
|
54
|
unsigned chunk_id,chunk_size,channel;
|
| vcazan |
0:143457f10e26
|
55
|
unsigned *data_wptr,data,samp_int,i;
|
| vcazan |
0:143457f10e26
|
56
|
short dac_data;
|
| vcazan |
0:143457f10e26
|
57
|
char *slice_buf;
|
| vcazan |
0:143457f10e26
|
58
|
short *data_sptr;
|
| vcazan |
0:143457f10e26
|
59
|
char *data_bptr;
|
| vcazan |
0:143457f10e26
|
60
|
FMT_STRUCT wav_format;
|
| vcazan |
0:143457f10e26
|
61
|
FILE *wavfile;
|
| vcazan |
0:143457f10e26
|
62
|
long slice,num_slices;
|
| vcazan |
0:143457f10e26
|
63
|
DAC_wptr=0;
|
| vcazan |
0:143457f10e26
|
64
|
DAC_rptr=0;
|
| vcazan |
0:143457f10e26
|
65
|
for (i=0;i<256;i+=2) {
|
| vcazan |
0:143457f10e26
|
66
|
DAC_fifo[i]=0;
|
| vcazan |
0:143457f10e26
|
67
|
DAC_fifo[i+1]=3000;
|
| vcazan |
0:143457f10e26
|
68
|
}
|
| vcazan |
0:143457f10e26
|
69
|
DAC_wptr=4;
|
| vcazan |
0:143457f10e26
|
70
|
DAC_on=0;
|
| vcazan |
0:143457f10e26
|
71
|
|
| vcazan |
0:143457f10e26
|
72
|
led1=led2=led3=led4=0;
|
| vcazan |
0:143457f10e26
|
73
|
|
| vcazan |
0:143457f10e26
|
74
|
printf("Playing wave file '%s'\n",wavname);
|
| vcazan |
0:143457f10e26
|
75
|
|
| vcazan |
0:143457f10e26
|
76
|
wavfile=fopen(wavname,"rb");
|
| vcazan |
0:143457f10e26
|
77
|
if (!wavfile) {
|
| vcazan |
0:143457f10e26
|
78
|
printf("Unable to open wav file '%s'\n",wavname);
|
| vcazan |
0:143457f10e26
|
79
|
exit(1);
|
| vcazan |
0:143457f10e26
|
80
|
}
|
| vcazan |
0:143457f10e26
|
81
|
|
| vcazan |
0:143457f10e26
|
82
|
fread(&chunk_id,4,1,wavfile);
|
| vcazan |
0:143457f10e26
|
83
|
fread(&chunk_size,4,1,wavfile);
|
| vcazan |
0:143457f10e26
|
84
|
while (!feof(wavfile)) {
|
| vcazan |
0:143457f10e26
|
85
|
printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size);
|
| vcazan |
0:143457f10e26
|
86
|
switch (chunk_id) {
|
| vcazan |
0:143457f10e26
|
87
|
case 0x46464952:
|
| vcazan |
0:143457f10e26
|
88
|
fread(&data,4,1,wavfile);
|
| vcazan |
0:143457f10e26
|
89
|
printf("RIFF chunk\n");
|
| vcazan |
0:143457f10e26
|
90
|
printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
|
| vcazan |
0:143457f10e26
|
91
|
printf(" RIFF type 0x%x\n",data);
|
| vcazan |
0:143457f10e26
|
92
|
break;
|
| vcazan |
0:143457f10e26
|
93
|
case 0x20746d66:
|
| vcazan |
0:143457f10e26
|
94
|
fread(&wav_format,sizeof(wav_format),1,wavfile);
|
| vcazan |
0:143457f10e26
|
95
|
printf("FORMAT chunk\n");
|
| vcazan |
0:143457f10e26
|
96
|
printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
|
| vcazan |
0:143457f10e26
|
97
|
printf(" compression code %d\n",wav_format.comp_code);
|
| vcazan |
0:143457f10e26
|
98
|
printf(" %d channels\n",wav_format.num_channels);
|
| vcazan |
0:143457f10e26
|
99
|
printf(" %d samples/sec\n",wav_format.sample_rate);
|
| vcazan |
0:143457f10e26
|
100
|
printf(" %d bytes/sec\n",wav_format.avg_Bps);
|
| vcazan |
0:143457f10e26
|
101
|
printf(" block align %d\n",wav_format.block_align);
|
| vcazan |
0:143457f10e26
|
102
|
printf(" %d bits per sample\n",wav_format.sig_bps);
|
| vcazan |
0:143457f10e26
|
103
|
if (chunk_size > sizeof(wav_format))
|
| vcazan |
0:143457f10e26
|
104
|
fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
|
| vcazan |
0:143457f10e26
|
105
|
// create a slice buffer large enough to hold multiple slices
|
| vcazan |
0:143457f10e26
|
106
|
slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
|
| vcazan |
0:143457f10e26
|
107
|
if (!slice_buf) {
|
| vcazan |
0:143457f10e26
|
108
|
printf("Unable to malloc slice buffer");
|
| vcazan |
0:143457f10e26
|
109
|
exit(1);
|
| vcazan |
0:143457f10e26
|
110
|
}
|
| vcazan |
0:143457f10e26
|
111
|
break;
|
| vcazan |
0:143457f10e26
|
112
|
case 0x61746164:
|
| vcazan |
0:143457f10e26
|
113
|
slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
|
| vcazan |
0:143457f10e26
|
114
|
if (!slice_buf) {
|
| vcazan |
0:143457f10e26
|
115
|
printf("Unable to malloc slice buffer");
|
| vcazan |
0:143457f10e26
|
116
|
exit(1);
|
| vcazan |
0:143457f10e26
|
117
|
} num_slices=chunk_size/wav_format.block_align;
|
| vcazan |
0:143457f10e26
|
118
|
printf("DATA chunk\n");
|
| vcazan |
0:143457f10e26
|
119
|
printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
|
| vcazan |
0:143457f10e26
|
120
|
printf(" %d slices\n",num_slices);
|
| vcazan |
0:143457f10e26
|
121
|
printf(" Ideal sample interval=%d\n",(unsigned)(1000000.0/wav_format.sample_rate));
|
| vcazan |
0:143457f10e26
|
122
|
samp_int=1000000/(wav_format.sample_rate);
|
| vcazan |
0:143457f10e26
|
123
|
printf(" programmed interrupt tick interval=%d\n",samp_int);
|
| vcazan |
0:143457f10e26
|
124
|
|
| vcazan |
0:143457f10e26
|
125
|
// starting up ticker to write samples out -- no printfs until tick.detach is called
|
| vcazan |
0:143457f10e26
|
126
|
tick.attach_us(&dac_out, samp_int);
|
| vcazan |
0:143457f10e26
|
127
|
DAC_on=1;
|
| vcazan |
0:143457f10e26
|
128
|
led2=1;
|
| vcazan |
0:143457f10e26
|
129
|
for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
|
| vcazan |
0:143457f10e26
|
130
|
fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
|
| vcazan |
0:143457f10e26
|
131
|
if (feof(wavfile)) {
|
| vcazan |
0:143457f10e26
|
132
|
printf("Oops -- not enough slices in the wave file\n");
|
| vcazan |
0:143457f10e26
|
133
|
exit(1);
|
| vcazan |
0:143457f10e26
|
134
|
}
|
| vcazan |
0:143457f10e26
|
135
|
data_sptr=(short *)slice_buf;
|
| vcazan |
0:143457f10e26
|
136
|
for (i=0;i<SLICE_BUF_SIZE;i++) {
|
| vcazan |
0:143457f10e26
|
137
|
dac_data=0;
|
| vcazan |
0:143457f10e26
|
138
|
|
| vcazan |
0:143457f10e26
|
139
|
// for a stereo wave file average the two channels.
|
| vcazan |
0:143457f10e26
|
140
|
for (channel=0;channel<wav_format.num_channels;channel++) {
|
| vcazan |
0:143457f10e26
|
141
|
switch (wav_format.sig_bps) {
|
| vcazan |
0:143457f10e26
|
142
|
case 16:
|
| vcazan |
0:143457f10e26
|
143
|
dac_data+=( ((int)(*data_sptr++)) +32768)>>5;
|
| vcazan |
0:143457f10e26
|
144
|
break;
|
| vcazan |
0:143457f10e26
|
145
|
}
|
| vcazan |
0:143457f10e26
|
146
|
}
|
| vcazan |
0:143457f10e26
|
147
|
dac_data>>=1;
|
| vcazan |
0:143457f10e26
|
148
|
DAC_fifo[DAC_wptr]=dac_data;
|
| vcazan |
0:143457f10e26
|
149
|
DAC_wptr=(DAC_wptr+1) & 0xff;
|
| vcazan |
0:143457f10e26
|
150
|
while (DAC_wptr==DAC_rptr) {
|
| vcazan |
0:143457f10e26
|
151
|
led1=1;
|
| vcazan |
0:143457f10e26
|
152
|
}
|
| vcazan |
0:143457f10e26
|
153
|
led1=0;
|
| vcazan |
0:143457f10e26
|
154
|
}
|
| vcazan |
0:143457f10e26
|
155
|
}
|
| vcazan |
0:143457f10e26
|
156
|
DAC_on=0;
|
| vcazan |
0:143457f10e26
|
157
|
led2=0;
|
| vcazan |
0:143457f10e26
|
158
|
tick.detach();
|
| vcazan |
0:143457f10e26
|
159
|
printf("Ticker detached\n");
|
| vcazan |
0:143457f10e26
|
160
|
led3=1;
|
| vcazan |
0:143457f10e26
|
161
|
free(slice_buf);
|
| vcazan |
0:143457f10e26
|
162
|
break;
|
| vcazan |
0:143457f10e26
|
163
|
case 0x5453494c:
|
| vcazan |
0:143457f10e26
|
164
|
printf("INFO chunk, size %d\n",chunk_size);
|
| vcazan |
0:143457f10e26
|
165
|
fseek(wavfile,chunk_size,SEEK_CUR);
|
| vcazan |
0:143457f10e26
|
166
|
break;
|
| vcazan |
0:143457f10e26
|
167
|
default:
|
| vcazan |
0:143457f10e26
|
168
|
printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size);
|
| vcazan |
0:143457f10e26
|
169
|
data=fseek(wavfile,chunk_size,SEEK_CUR);
|
| vcazan |
0:143457f10e26
|
170
|
break;
|
| vcazan |
0:143457f10e26
|
171
|
}
|
| vcazan |
0:143457f10e26
|
172
|
fread(&chunk_id,4,1,wavfile);
|
| vcazan |
0:143457f10e26
|
173
|
fread(&chunk_size,4,1,wavfile);
|
| vcazan |
0:143457f10e26
|
174
|
}
|
| vcazan |
0:143457f10e26
|
175
|
printf("Done with wave file\n");
|
| vcazan |
0:143457f10e26
|
176
|
fclose(wavfile);
|
| vcazan |
0:143457f10e26
|
177
|
led1=0;
|
| vcazan |
0:143457f10e26
|
178
|
}
|
| vcazan |
0:143457f10e26
|
179
|
|
| vcazan |
0:143457f10e26
|
180
|
|
| vcazan |
0:143457f10e26
|
181
|
void dac_out()
|
| vcazan |
0:143457f10e26
|
182
|
{
|
| vcazan |
0:143457f10e26
|
183
|
if (DAC_on) {
|
| vcazan |
0:143457f10e26
|
184
|
digout=1;
|
| vcazan |
0:143457f10e26
|
185
|
DACout.write(DAC_fifo[DAC_rptr]);
|
| vcazan |
0:143457f10e26
|
186
|
DAC_rptr=(DAC_rptr+1) & 0xff;
|
| vcazan |
0:143457f10e26
|
187
|
digout=0;
|
| vcazan |
0:143457f10e26
|
188
|
}
|
| vcazan |
0:143457f10e26
|
189
|
}
|
| vcazan |
0:143457f10e26
|
190
|
|
| vcazan |
0:143457f10e26
|
191
|
|