summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/pcm_playback.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 9a261dbf77..58d68cadbd 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -83,6 +83,8 @@ static void (*pcm_event_handler)(void);
83static unsigned char *next_start; 83static unsigned char *next_start;
84static long next_size; 84static long next_size;
85 85
86static int last_chunksize = 0;
87
86struct pcmbufdesc 88struct pcmbufdesc
87{ 89{
88 void *addr; 90 void *addr;
@@ -107,7 +109,7 @@ static void dma_start(const void *addr, long size)
107 /* Reset the audio FIFO */ 109 /* Reset the audio FIFO */
108 IIS2CONFIG = 0x800; 110 IIS2CONFIG = 0x800;
109 EBU1CONFIG = 0x800; 111 EBU1CONFIG = 0x800;
110 112
111 /* Set up DMA transfer */ 113 /* Set up DMA transfer */
112 SAR0 = ((unsigned long)addr); /* Source address */ 114 SAR0 = ((unsigned long)addr); /* Source address */
113 DAR0 = (unsigned long)&PDOR3; /* Destination address */ 115 DAR0 = (unsigned long)&PDOR3; /* Destination address */
@@ -144,6 +146,18 @@ static void dma_stop(void)
144 /* Reset the FIFO */ 146 /* Reset the FIFO */
145 IIS2CONFIG = 0x800; 147 IIS2CONFIG = 0x800;
146 EBU1CONFIG = 0x800; 148 EBU1CONFIG = 0x800;
149
150 pcmbuf_unplayed_bytes = 0;
151 last_chunksize = 0;
152 audiobuffer_pos = 0;
153 audiobuffer_fillpos = 0;
154 audiobuffer_free = PCMBUF_SIZE;
155 pcmbuf_read_index = 0;
156 pcmbuf_write_index = 0;
157 next_start = NULL;
158 next_size = 0;
159 crossfade_init = 0;
160 pcm_paused = false;
147} 161}
148 162
149/* sets frequency of input to DAC */ 163/* sets frequency of input to DAC */
@@ -175,8 +189,6 @@ int pcm_play_num_used_buffers(void)
175 return (pcmbuf_write_index - pcmbuf_read_index) & NUM_PCM_BUFFERS_MASK; 189 return (pcmbuf_write_index - pcmbuf_read_index) & NUM_PCM_BUFFERS_MASK;
176} 190}
177 191
178static int last_chunksize = 0;
179
180static void pcm_play_callback(unsigned char** start, long* size) 192static void pcm_play_callback(unsigned char** start, long* size)
181{ 193{
182 struct pcmbufdesc *desc = &pcmbuffers[pcmbuf_read_index]; 194 struct pcmbufdesc *desc = &pcmbuffers[pcmbuf_read_index];
@@ -232,9 +244,8 @@ void pcm_play_data(const unsigned char* start, int size,
232 void (*get_more)(unsigned char** start, long* size)) 244 void (*get_more)(unsigned char** start, long* size))
233{ 245{
234 callback_for_more = get_more; 246 callback_for_more = get_more;
235 dma_start(start, size);
236
237 get_more(&next_start, &next_size); 247 get_more(&next_start, &next_size);
248 dma_start(start, size);
238 249
239 /* Sleep a while, then power on audio output */ 250 /* Sleep a while, then power on audio output */
240 sleep(HZ/16); 251 sleep(HZ/16);
@@ -251,15 +262,6 @@ void pcm_play_stop(void)
251 sleep(HZ/16); 262 sleep(HZ/16);
252 dma_stop(); 263 dma_stop();
253 } 264 }
254 pcmbuf_unplayed_bytes = 0;
255 last_chunksize = 0;
256 audiobuffer_pos = 0;
257 audiobuffer_fillpos = 0;
258 audiobuffer_free = PCMBUF_SIZE;
259 pcmbuf_read_index = 0;
260 pcmbuf_write_index = 0;
261 next_start = NULL;
262 next_size = 0;
263} 265}
264 266
265void pcm_play_pause(bool play) 267void pcm_play_pause(bool play)
@@ -298,11 +300,13 @@ void DMA0(void)
298 int res = DSR0; 300 int res = DSR0;
299 301
300 DSR0 = 1; /* Clear interrupt */ 302 DSR0 = 1; /* Clear interrupt */
303 DCR0 &= ~DMA_EEXT;
301 304
302 /* Stop on error */ 305 /* Stop on error */
303 if(res & 0x70) 306 if(res & 0x70)
304 { 307 {
305 dma_stop(); 308 dma_stop();
309 logf("DMA Error");
306 } 310 }
307 else 311 else
308 { 312 {
@@ -310,6 +314,7 @@ void DMA0(void)
310 { 314 {
311 SAR0 = (unsigned long)next_start; /* Source address */ 315 SAR0 = (unsigned long)next_start; /* Source address */
312 BCR0 = next_size; /* Bytes to transfer */ 316 BCR0 = next_size; /* Bytes to transfer */
317 DCR0 |= DMA_EEXT;
313 if (callback_for_more) 318 if (callback_for_more)
314 callback_for_more(&next_start, &next_size); 319 callback_for_more(&next_start, &next_size);
315 } 320 }
@@ -317,6 +322,7 @@ void DMA0(void)
317 { 322 {
318 /* Finished playing */ 323 /* Finished playing */
319 dma_stop(); 324 dma_stop();
325 logf("DMA No Data");
320 } 326 }
321 } 327 }
322 328
@@ -442,7 +448,11 @@ void pcm_flush_fillpos(void)
442 if (audiobuffer_fillpos) { 448 if (audiobuffer_fillpos) {
443 while (!pcm_play_add_chunk(&audiobuffer[audiobuffer_pos], 449 while (!pcm_play_add_chunk(&audiobuffer[audiobuffer_pos],
444 audiobuffer_fillpos, pcm_event_handler)) { 450 audiobuffer_fillpos, pcm_event_handler)) {
451 pcm_boost(false);
445 yield(); 452 yield();
453 /* This is a fatal error situation that should never happen. */
454 if (!pcm_playing)
455 break ;
446 } 456 }
447 pcm_event_handler = NULL; 457 pcm_event_handler = NULL;
448 audiobuffer_pos += audiobuffer_fillpos; 458 audiobuffer_pos += audiobuffer_fillpos;
@@ -527,7 +537,7 @@ inline static bool prepare_insert(long length)
527 return false; 537 return false;
528 } 538 }
529 539
530 if (!pcm_is_playing() && !pcm_paused) { 540 if (!pcm_is_playing()) {
531 pcm_boost(true); 541 pcm_boost(true);
532 crossfade_active = false; 542 crossfade_active = false;
533 if (audiobuffer_free < PCMBUF_SIZE - CHUNK_SIZE*4) 543 if (audiobuffer_free < PCMBUF_SIZE - CHUNK_SIZE*4)
@@ -659,7 +669,7 @@ bool pcm_insert_buffer(char *buf, long length)
659 length -= copy_n; 669 length -= copy_n;
660 670
661 /* Pre-buffer to meet CHUNK_SIZE requirement */ 671 /* Pre-buffer to meet CHUNK_SIZE requirement */
662 if (copy_n + audiobuffer_fillpos < CHUNK_SIZE && length == 0) { 672 if (audiobuffer_fillpos < CHUNK_SIZE && length == 0) {
663 return true; 673 return true;
664 } 674 }
665 675