diff options
Diffstat (limited to 'firmware/target/coldfire/pcm-coldfire.c')
-rw-r--r-- | firmware/target/coldfire/pcm-coldfire.c | 68 |
1 files changed, 30 insertions, 38 deletions
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index 917800d0b8..4e4e557d9b 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c | |||
@@ -287,7 +287,7 @@ void DMA0(void) | |||
287 | /**************************************************************************** | 287 | /**************************************************************************** |
288 | ** Recording DMA transfer | 288 | ** Recording DMA transfer |
289 | **/ | 289 | **/ |
290 | void pcm_rec_dma_start(const void *addr, size_t size) | 290 | void pcm_rec_dma_start(void *addr, size_t size) |
291 | { | 291 | { |
292 | logf("pcm_rec_dma_start"); | 292 | logf("pcm_rec_dma_start"); |
293 | 293 | ||
@@ -296,12 +296,6 @@ void pcm_rec_dma_start(const void *addr, size_t size) | |||
296 | 296 | ||
297 | pcm_recording = true; | 297 | pcm_recording = true; |
298 | 298 | ||
299 | DAR1 = (unsigned long)addr; /* Destination address */ | ||
300 | SAR1 = (unsigned long)&PDIR2; /* Source address */ | ||
301 | BCR1 = size; /* Bytes to transfer */ | ||
302 | |||
303 | rec_peak_addr = (unsigned long *)addr; | ||
304 | |||
305 | pcm_apply_settings(false); | 299 | pcm_apply_settings(false); |
306 | 300 | ||
307 | /* Start the DMA transfer.. */ | 301 | /* Start the DMA transfer.. */ |
@@ -309,18 +303,22 @@ void pcm_rec_dma_start(const void *addr, size_t size) | |||
309 | INTERRUPTCLEAR = 0x03c00000; | 303 | INTERRUPTCLEAR = 0x03c00000; |
310 | #endif | 304 | #endif |
311 | 305 | ||
312 | DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC | | 306 | SAR1 = (unsigned long)&PDIR2; /* Source address */ |
313 | DMA_DSIZE(3) | DMA_START; | 307 | DCR1 = DMA_INT | DMA_CS | DMA_AA | DMA_DINC | DMA_DSIZE(3); |
308 | |||
309 | pcm_record_more(addr, size); | ||
310 | |||
311 | DCR1 |= DMA_START; | ||
314 | } /* pcm_dma_start */ | 312 | } /* pcm_dma_start */ |
315 | 313 | ||
316 | void pcm_rec_dma_stop(void) | 314 | void pcm_rec_dma_stop(void) |
317 | { | 315 | { |
318 | logf("pcm_rec_dma_stop"); | 316 | logf("pcm_rec_dma_stop"); |
319 | 317 | ||
320 | pcm_recording = false; | ||
321 | |||
322 | DCR1 = 0; | ||
323 | DSR1 = 1; /* Clear interrupt */ | 318 | DSR1 = 1; /* Clear interrupt */ |
319 | DCR1 = 0; | ||
320 | |||
321 | pcm_recording = false; | ||
324 | } /* pcm_dma_stop */ | 322 | } /* pcm_dma_stop */ |
325 | 323 | ||
326 | void pcm_init_recording(void) | 324 | void pcm_init_recording(void) |
@@ -338,7 +336,7 @@ void pcm_init_recording(void) | |||
338 | 336 | ||
339 | pcm_rec_dma_stop(); | 337 | pcm_rec_dma_stop(); |
340 | 338 | ||
341 | ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */ | 339 | ICR7 = (6 << 2); /* Enable interrupt at level 6, priority 0 */ |
342 | IMR &= ~(1 << 15); /* bit 15 is DMA1 */ | 340 | IMR &= ~(1 << 15); /* bit 15 is DMA1 */ |
343 | } /* pcm_init_recording */ | 341 | } /* pcm_init_recording */ |
344 | 342 | ||
@@ -359,17 +357,15 @@ void DMA1(void) __attribute__ ((interrupt_handler, section(".icode"))); | |||
359 | void DMA1(void) | 357 | void DMA1(void) |
360 | { | 358 | { |
361 | int res = DSR1; | 359 | int res = DSR1; |
362 | pcm_more_callback_type more_ready; | 360 | int status = 0; |
363 | unsigned char *next_start; | 361 | pcm_more_callback_type2 more_ready; |
364 | ssize_t next_size = 0; /* passing <> 0 is indicates | ||
365 | an error condition */ | ||
366 | 362 | ||
367 | DSR1 = 1; /* Clear interrupt */ | 363 | DSR1 = 1; /* Clear interrupt */ |
368 | DCR1 &= ~DMA_EEXT; | 364 | DCR1 &= ~DMA_EEXT; /* Disable peripheral request */ |
369 | 365 | ||
370 | if (res & 0x70) | 366 | if (res & 0x70) |
371 | { | 367 | { |
372 | next_size = DMA_REC_ERROR_DMA; | 368 | status = DMA_REC_ERROR_DMA; |
373 | logf("DMA1 err: 0x%x", res); | 369 | logf("DMA1 err: 0x%x", res); |
374 | } | 370 | } |
375 | #ifdef HAVE_SPDIF_IN | 371 | #ifdef HAVE_SPDIF_IN |
@@ -377,37 +373,33 @@ void DMA1(void) | |||
377 | (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */ | 373 | (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */ |
378 | { | 374 | { |
379 | INTERRUPTCLEAR = 0x03c00000; | 375 | INTERRUPTCLEAR = 0x03c00000; |
380 | next_size = DMA_REC_ERROR_SPDIF; | 376 | status = DMA_REC_ERROR_SPDIF; |
381 | logf("spdif err"); | 377 | logf("spdif err"); |
382 | } | 378 | } |
383 | #endif | 379 | #endif |
384 | 380 | ||
385 | more_ready = pcm_callback_more_ready; | 381 | more_ready = pcm_callback_more_ready; |
386 | 382 | ||
387 | if (more_ready) | 383 | if (more_ready != NULL && more_ready(status) >= 0) |
388 | more_ready(&next_start, &next_size); | ||
389 | |||
390 | if (next_size > 0) | ||
391 | { | ||
392 | /* Start peaking at dest */ | ||
393 | rec_peak_addr = (unsigned long *)next_start; | ||
394 | DAR1 = (unsigned long)next_start; /* Destination address */ | ||
395 | BCR1 = (unsigned long)next_size; /* Bytes to transfer */ | ||
396 | DCR1 |= DMA_EEXT; | ||
397 | return; | 384 | return; |
398 | } | 385 | |
399 | else | ||
400 | { | ||
401 | #if 0 | 386 | #if 0 |
402 | /* int. logfs can trash the display */ | 387 | /* int. logfs can trash the display */ |
403 | logf("DMA1 No Data:0x%04x", res); | 388 | logf("DMA1 done:%04x %d", res, status); |
404 | #endif | 389 | #endif |
405 | } | ||
406 | |||
407 | /* Finished recording */ | 390 | /* Finished recording */ |
408 | pcm_rec_dma_stop(); | 391 | pcm_rec_dma_stop(); |
409 | } /* DMA1 */ | 392 | } /* DMA1 */ |
410 | 393 | ||
394 | /* Continue transferring data in */ | ||
395 | void pcm_record_more(void *start, size_t size) | ||
396 | { | ||
397 | rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */ | ||
398 | DAR1 = (unsigned long)start; /* Destination address */ | ||
399 | BCR1 = (unsigned long)size; /* Bytes to transfer */ | ||
400 | DCR1 |= DMA_EEXT; | ||
401 | } | ||
402 | |||
411 | void pcm_mute(bool mute) | 403 | void pcm_mute(bool mute) |
412 | { | 404 | { |
413 | ac_mute(mute); | 405 | ac_mute(mute); |