summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/pcm-coldfire.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/pcm-coldfire.c')
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c63
1 files changed, 21 insertions, 42 deletions
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index f9c0764d64..06f17d1170 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -288,13 +288,14 @@ void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
288void DMA0(void) 288void DMA0(void)
289{ 289{
290 unsigned long res = DSR0; 290 unsigned long res = DSR0;
291 void *start;
292 size_t size;
291 293
292 and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */ 294 and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */
293 DSR0 = 1; /* Clear interrupt and errors */ 295 DSR0 = 1; /* Clear interrupt and errors */
294 296
295 if (res & 0x70) 297 if (res & 0x70)
296 { 298 {
297 /* Stop on error */
298 logf("DMA0 err: %02x", res); 299 logf("DMA0 err: %02x", res);
299#if 0 300#if 0
300 logf(" SAR0: %08x", SAR0); 301 logf(" SAR0: %08x", SAR0);
@@ -303,32 +304,17 @@ void DMA0(void)
303 logf(" DCR0: %08x", DCR0); 304 logf(" DCR0: %08x", DCR0);
304#endif 305#endif
305 } 306 }
306 else 307
308 /* Force stop on error */
309 pcm_play_get_more_callback((res & 0x70) ? NULL : &start, &size);
310
311 if (size != 0)
307 { 312 {
308 pcm_more_callback_type get_more = pcm_callback_for_more; 313 SAR0 = (unsigned long)start; /* Source address */
309 unsigned char *start; 314 BCR0 = size; /* Bytes to transfer */
310 size_t size = 0; 315 or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
311
312 if (get_more)
313 get_more(&start, &size);
314
315 start = (unsigned char *)(((long)start + 3) & ~3);
316 size &= ~3;
317
318 if (size > 0)
319 {
320 SAR0 = (unsigned long)start; /* Source address */
321 BCR0 = size; /* Bytes to transfer */
322 or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */
323 return;
324 }
325 /* Finished playing */
326 } 316 }
327 317 /* else inished playing */
328 /* Stop interrupt and futher transfers */
329 pcm_play_dma_stop();
330 /* Inform PCM that we're done */
331 pcm_play_dma_stopped_callback();
332} /* DMA0 */ 318} /* DMA0 */
333 319
334const void * pcm_play_dma_get_peak_buffer(int *count) 320const void * pcm_play_dma_get_peak_buffer(int *count)
@@ -436,7 +422,8 @@ void DMA1(void)
436{ 422{
437 unsigned long res = DSR1; 423 unsigned long res = DSR1;
438 int status = 0; 424 int status = 0;
439 pcm_more_callback_type2 more_ready; 425 void *start;
426 size_t size;
440 427
441 and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */ 428 and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */
442 DSR1 = 1; /* Clear interrupt and errors */ 429 DSR1 = 1; /* Clear interrupt and errors */
@@ -465,25 +452,17 @@ void DMA1(void)
465 } 452 }
466#endif 453#endif
467 454
468 more_ready = pcm_callback_more_ready; 455 /* Inform PCM we have more data (or error) */
469 456 pcm_rec_more_ready_callback(status, &start, &size);
470 if (more_ready != NULL && more_ready(status) >= 0)
471 return;
472 457
473 /* Finished recording */ 458 if (size != 0)
474 pcm_rec_dma_stop(); 459 {
475 /* Inform PCM that we're done */ 460 DAR1 = (unsigned long)start; /* Destination address */
476 pcm_rec_dma_stopped_callback(); 461 BCR1 = (unsigned long)size; /* Bytes to transfer */
462 or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
463 }
477} /* DMA1 */ 464} /* DMA1 */
478 465
479/* Continue transferring data in - call from interrupt callback */
480void pcm_rec_dma_record_more(void *start, size_t size)
481{
482 DAR1 = (unsigned long)start; /* Destination address */
483 BCR1 = (unsigned long)size; /* Bytes to transfer */
484 or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */
485} /* pcm_record_more */
486
487const void * pcm_rec_dma_get_peak_buffer(void) 466const void * pcm_rec_dma_get_peak_buffer(void)
488{ 467{
489 return (void *)(DAR1 & ~3); 468 return (void *)(DAR1 & ~3);