summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pcm-pp.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pcm-pp.c')
-rw-r--r--firmware/target/arm/pcm-pp.c83
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 */
116void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) 116void 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 */
285void fiq_playback(void) 265void 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)
590void fiq_record(void) 563void 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
661void fiq_record(void) 628void 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 */
691void 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
697void pcm_rec_dma_stop(void) 650void pcm_rec_dma_stop(void)
698{ 651{
699 /* disable interrupt */ 652 /* disable interrupt */