diff options
Diffstat (limited to 'firmware/target/arm/pcm-telechips.c')
-rw-r--r-- | firmware/target/arm/pcm-telechips.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c index 851ebee7de..aff43171f6 100644 --- a/firmware/target/arm/pcm-telechips.c +++ b/firmware/target/arm/pcm-telechips.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "sound.h" | 27 | #include "sound.h" |
28 | #include "i2s.h" | 28 | #include "i2s.h" |
29 | #include "pcm.h" | 29 | #include "pcm.h" |
30 | #include "pcm-internal.h" | ||
30 | 31 | ||
31 | struct dma_data | 32 | struct dma_data |
32 | { | 33 | { |
@@ -247,6 +248,8 @@ void fiq_handler(void) | |||
247 | * r0-r3 and r12 is a working register. | 248 | * r0-r3 and r12 is a working register. |
248 | */ | 249 | */ |
249 | asm volatile ( | 250 | asm volatile ( |
251 | "stmfd sp!, { r0-r4, lr } \n" /* stack scratch regs and lr */ | ||
252 | "mov r4, #0 \n" /* Was the callback called? */ | ||
250 | #if defined(CPU_TCC780X) | 253 | #if defined(CPU_TCC780X) |
251 | "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ | 254 | "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ |
252 | "ldr r9, =0xf3001004 \n" /* CREQ */ | 255 | "ldr r9, =0xf3001004 \n" /* CREQ */ |
@@ -279,33 +282,41 @@ void fiq_handler(void) | |||
279 | "sub r9, r9, #0x10 \n" /* 4 words written */ | 282 | "sub r9, r9, #0x10 \n" /* 4 words written */ |
280 | "stmia r11, { r8-r9 } \n" /* save p and size */ | 283 | "stmia r11, { r8-r9 } \n" /* save p and size */ |
281 | 284 | ||
285 | "cmp r4, #0 \n" /* Callback called? */ | ||
286 | "beq .exit \n" | ||
287 | /* "mov r4, #0 \n" If get_more could be called multiple times! */ | ||
288 | "ldr r2, =pcm_play_dma_started\n" | ||
289 | "ldr r2, [r2] \n" | ||
290 | "cmp r2, #0 \n" | ||
291 | "blxne r2 \n" | ||
292 | |||
282 | ".exit: \n" | 293 | ".exit: \n" |
294 | "ldmfd sp!, { r0-r4, lr } \n" | ||
283 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ | 295 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ |
284 | 296 | ||
285 | ".more_data: \n" | 297 | ".more_data: \n" |
286 | "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ | 298 | "mov r4, #1 \n" /* Remember we got more data in this FIQ */ |
287 | "ldr r2, =pcm_play_get_more_callback \n" | 299 | "ldr r2, =pcm_play_get_more_callback \n" |
288 | "mov r0, r11 \n" /* r0 = &p */ | 300 | "mov r0, r11 \n" /* r0 = &p */ |
289 | "add r1, r11, #4 \n" /* r1 = &size */ | 301 | "add r1, r11, #4 \n" /* r1 = &size */ |
290 | "blx r2 \n" /* call pcm_play_get_more_callback */ | 302 | "blx r2 \n" /* call pcm_play_get_more_callback */ |
291 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ | 303 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ |
292 | "cmp r9, #0x10 \n" /* did we actually get enough data? */ | 304 | "cmp r9, #0x10 \n" /* did we actually get enough data? */ |
293 | "ldmfd sp!, { r0-r3, lr } \n" | ||
294 | "bpl .fill_fifo \n" /* not stop and enough? refill */ | 305 | "bpl .fill_fifo \n" /* not stop and enough? refill */ |
295 | "b .exit \n" | 306 | "b .exit \n" |
296 | ".ltorg \n" | 307 | ".ltorg \n" |
297 | ); | 308 | ); |
298 | } | 309 | } |
299 | #else /* C version for reference */ | 310 | #else /* C version for reference */ |
300 | void fiq_handler(void) ICODE_ATTR __attribute__((naked)); | 311 | void fiq_handler(void) ICODE_ATTR; |
301 | void fiq_handler(void) | 312 | void fiq_handler(void) |
302 | { | 313 | { |
303 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ | 314 | register bool new_buffer = false; |
304 | "sub sp, sp, #8 \n"); /* Reserve stack */ | ||
305 | 315 | ||
306 | if (dma_play_data.size < 16) | 316 | if (dma_play_data.size < 16) |
307 | { | 317 | { |
308 | /* p is empty, get some more data */ | 318 | /* p is empty, get some more data */ |
319 | new_buffer = true; | ||
309 | pcm_play_get_more_callback((void**)&dma_play_data.p, | 320 | pcm_play_get_more_callback((void**)&dma_play_data.p, |
310 | &dma_play_data.size); | 321 | &dma_play_data.size); |
311 | } | 322 | } |
@@ -327,9 +338,8 @@ void fiq_handler(void) | |||
327 | /* Clear FIQ status */ | 338 | /* Clear FIQ status */ |
328 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; | 339 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; |
329 | 340 | ||
330 | asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ | 341 | if (new_buffer) |
331 | "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ | 342 | pcm_play_dma_started_callback(); |
332 | "subs pc, lr, #4 \n"); /* Return from FIQ */ | ||
333 | } | 343 | } |
334 | #endif | 344 | #endif |
335 | 345 | ||