diff options
Diffstat (limited to 'firmware/target/arm/pcm-pp.c')
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 83 |
1 files changed, 18 insertions, 65 deletions
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e0b603c81f..6289b4c730 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c | |||
@@ -115,7 +115,6 @@ void pcm_dma_apply_settings(void) | |||
115 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ | 115 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ |
116 | void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | 116 | void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) |
117 | { | 117 | { |
118 | register pcm_more_callback_type get_more; | ||
119 | register size_t size; | 118 | register size_t size; |
120 | 119 | ||
121 | DMA0_STATUS; /* Clear any pending interrupt */ | 120 | DMA0_STATUS; /* Clear any pending interrupt */ |
@@ -141,15 +140,12 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | |||
141 | } | 140 | } |
142 | 141 | ||
143 | /* Buffer empty. Try to get more. */ | 142 | /* Buffer empty. Try to get more. */ |
144 | get_more = pcm_callback_for_more; | 143 | pcm_play_get_more_callback((void **)&dma_play_data.addr, |
145 | if (get_more) { | 144 | &dma_play_data.size); |
146 | get_more((unsigned char **)&dma_play_data.addr, &dma_play_data.size); | ||
147 | dma_play_data.addr = (dma_play_data.addr + 2) & ~3; | ||
148 | dma_play_data.size &= ~3; | ||
149 | } | ||
150 | 145 | ||
151 | if (dma_play_data.size == 0) { | 146 | if (dma_play_data.size == 0) { |
152 | break; | 147 | /* No more data */ |
148 | return; | ||
153 | } | 149 | } |
154 | 150 | ||
155 | if (dma_play_data.addr < UNCACHED_BASE_ADDR) { | 151 | if (dma_play_data.addr < UNCACHED_BASE_ADDR) { |
@@ -158,10 +154,6 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | |||
158 | cpucache_flush(); | 154 | cpucache_flush(); |
159 | } | 155 | } |
160 | } | 156 | } |
161 | |||
162 | /* Callback missing or no more DMA to do */ | ||
163 | pcm_play_dma_stop(); | ||
164 | pcm_play_dma_stopped_callback(); | ||
165 | } | 157 | } |
166 | #else | 158 | #else |
167 | /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by | 159 | /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by |
@@ -247,28 +239,16 @@ void fiq_playback(void) | |||
247 | #endif | 239 | #endif |
248 | 240 | ||
249 | ".more_data: \n" | 241 | ".more_data: \n" |
250 | "ldr r2, =pcm_callback_for_more \n" | 242 | "ldr r2, =pcm_play_get_more_callback \n" |
251 | "ldr r2, [r2] \n" /* get callback address */ | ||
252 | "cmp r2, #0 \n" /* check for null pointer */ | ||
253 | "beq .stop \n" /* callback removed, stop */ | ||
254 | "stmia r11, { r8-r9 } \n" /* save internal copies of variables back */ | ||
255 | "mov r0, r11 \n" /* r0 = &p */ | 243 | "mov r0, r11 \n" /* r0 = &p */ |
256 | "add r1, r11, #4 \n" /* r1 = &size */ | 244 | "add r1, r11, #4 \n" /* r1 = &size */ |
257 | "mov lr, pc \n" /* call pcm_callback_for_more */ | 245 | "mov lr, pc \n" /* call pcm_play_get_more_callback */ |
258 | "bx r2 \n" | 246 | "bx r2 \n" |
259 | "ldmia r11, { r8-r9 } \n" /* reload p and size */ | 247 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ |
260 | "cmp r9, #0 \n" /* did we actually get more data? */ | 248 | "cmp r9, #0 \n" |
261 | "bne .check_fifo \n" | 249 | "bne .check_fifo \n" /* size != 0? refill */ |
262 | 250 | ||
263 | ".stop: \n" /* call termination routines */ | 251 | ".exit: \n" /* (r9=0 if stopping, look above) */ |
264 | "ldr r12, =pcm_play_dma_stop \n" | ||
265 | "mov lr, pc \n" | ||
266 | "bx r12 \n" | ||
267 | "ldr r12, =pcm_play_dma_stopped_callback \n" | ||
268 | "mov lr, pc \n" | ||
269 | "bx r12 \n" | ||
270 | |||
271 | ".exit: \n" /* (r8=0 if stopping, look above) */ | ||
272 | "stmia r11, { r8-r9 } \n" /* save p and size */ | 252 | "stmia r11, { r8-r9 } \n" /* save p and size */ |
273 | "ldmfd sp!, { r0-r3, lr } \n" | 253 | "ldmfd sp!, { r0-r3, lr } \n" |
274 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ | 254 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ |
@@ -284,8 +264,6 @@ void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR; | |||
284 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ | 264 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ |
285 | void fiq_playback(void) | 265 | void fiq_playback(void) |
286 | { | 266 | { |
287 | register pcm_more_callback_type get_more; | ||
288 | |||
289 | #if CONFIG_CPU == PP5002 | 267 | #if CONFIG_CPU == PP5002 |
290 | inl(0xcf001040); | 268 | inl(0xcf001040); |
291 | #endif | 269 | #endif |
@@ -305,16 +283,11 @@ void fiq_playback(void) | |||
305 | } | 283 | } |
306 | 284 | ||
307 | /* p is empty, get some more data */ | 285 | /* p is empty, get some more data */ |
308 | get_more = pcm_callback_for_more; | 286 | pcm_play_get_more_callback((void **)&dma_play_data.addr, |
309 | if (get_more) { | 287 | &dma_play_data.size); |
310 | get_more((unsigned char**)&dma_play_data.addr, | ||
311 | &dma_play_data.size); | ||
312 | } | ||
313 | } while (dma_play_data.size); | 288 | } while (dma_play_data.size); |
314 | 289 | ||
315 | /* No more data, so disable the FIFO/interrupt */ | 290 | /* No more data */ |
316 | pcm_play_dma_stop(); | ||
317 | pcm_play_dma_stopped_callback(); | ||
318 | } | 291 | } |
319 | #endif /* ASM / C selection */ | 292 | #endif /* ASM / C selection */ |
320 | #endif /* CPU_PP502x */ | 293 | #endif /* CPU_PP502x */ |
@@ -589,7 +562,6 @@ void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ"))); | |||
589 | #if defined(SANSA_C200) || defined(SANSA_E200) | 562 | #if defined(SANSA_C200) || defined(SANSA_E200) |
590 | void fiq_record(void) | 563 | void fiq_record(void) |
591 | { | 564 | { |
592 | register pcm_more_callback_type2 more_ready; | ||
593 | register int32_t value; | 565 | register int32_t value; |
594 | 566 | ||
595 | if (audio_channels == 2) { | 567 | if (audio_channels == 2) { |
@@ -648,20 +620,13 @@ void fiq_record(void) | |||
648 | } | 620 | } |
649 | } | 621 | } |
650 | 622 | ||
651 | more_ready = pcm_callback_more_ready; | 623 | pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, |
652 | 624 | &dma_rec_data.size); | |
653 | if (more_ready == NULL || more_ready(0) < 0) { | ||
654 | /* Finished recording */ | ||
655 | pcm_rec_dma_stop(); | ||
656 | pcm_rec_dma_stopped_callback(); | ||
657 | } | ||
658 | } | 625 | } |
659 | 626 | ||
660 | #else | 627 | #else |
661 | void fiq_record(void) | 628 | void fiq_record(void) |
662 | { | 629 | { |
663 | register pcm_more_callback_type2 more_ready; | ||
664 | |||
665 | while (dma_rec_data.size > 0) { | 630 | while (dma_rec_data.size > 0) { |
666 | if (IIS_RX_FULL_COUNT < 2) { | 631 | if (IIS_RX_FULL_COUNT < 2) { |
667 | return; | 632 | return; |
@@ -676,24 +641,12 @@ void fiq_record(void) | |||
676 | dma_rec_data.size -= 4; | 641 | dma_rec_data.size -= 4; |
677 | } | 642 | } |
678 | 643 | ||
679 | more_ready = pcm_callback_more_ready; | 644 | pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, |
680 | 645 | &dma_rec_data.size); | |
681 | if (more_ready == NULL || more_ready(0) < 0) { | ||
682 | /* Finished recording */ | ||
683 | pcm_rec_dma_stop(); | ||
684 | pcm_rec_dma_stopped_callback(); | ||
685 | } | ||
686 | } | 646 | } |
687 | 647 | ||
688 | #endif /* SANSA_E200 */ | 648 | #endif /* SANSA_E200 */ |
689 | 649 | ||
690 | /* Continue transferring data in */ | ||
691 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
692 | { | ||
693 | dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */ | ||
694 | dma_rec_data.size = size; /* Bytes to transfer */ | ||
695 | } | ||
696 | |||
697 | void pcm_rec_dma_stop(void) | 650 | void pcm_rec_dma_stop(void) |
698 | { | 651 | { |
699 | /* disable interrupt */ | 652 | /* disable interrupt */ |