summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-03-07 05:21:58 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-03-07 05:21:58 +0000
commit44c15ee923d55467027b8b96116ec4c686aefcd1 (patch)
treed8a89db26b405b1055ba4cc929daabfc9bfcaf8f
parentda1ca5177fd1606fe494939e120c5731b4bb5d3f (diff)
downloadrockbox-44c15ee923d55467027b8b96116ec4c686aefcd1.tar.gz
rockbox-44c15ee923d55467027b8b96116ec4c686aefcd1.zip
Fix FS#9949 - Song not playing, noise instead. Stale code was left from before transferring in segments and one calculation was just wrong for limiting trasfer size. Make buffer aligning consistent, change <= 0 on size_t variable to == 0 and remove pointless limit on overall buffer size.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20227 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/pcm-pp.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c
index ce30908b0e..bd12b13032 100644
--- a/firmware/target/arm/pcm-pp.c
+++ b/firmware/target/arm/pcm-pp.c
@@ -144,11 +144,11 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
144 get_more = pcm_callback_for_more; 144 get_more = pcm_callback_for_more;
145 if (get_more) { 145 if (get_more) {
146 get_more((unsigned char **)&dma_play_data.addr, &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 + 3) & ~3; 147 dma_play_data.addr = (dma_play_data.addr + 2) & ~3;
148 dma_play_data.size &= 0xfffc; 148 dma_play_data.size &= ~3;
149 } 149 }
150 150
151 if (dma_play_data.size <= 0) { 151 if (dma_play_data.size == 0) {
152 break; 152 break;
153 } 153 }
154 154
@@ -360,7 +360,7 @@ static void play_start_pcm(void)
360 /* Not at least MAX_DMA_CHUNK_SIZE left or there would be less than a 360 /* Not at least MAX_DMA_CHUNK_SIZE left or there would be less than a
361 * FIFO's worth of data after this transfer? */ 361 * FIFO's worth of data after this transfer? */
362 size_t size = MAX_DMA_CHUNK_SIZE; 362 size_t size = MAX_DMA_CHUNK_SIZE;
363 if (dma_play_data.size + 16*4 < size) 363 if (size + 16*4 > dma_play_data.size)
364 size = dma_play_data.size; 364 size = dma_play_data.size;
365 365
366 DMA0_RAM_ADDR = dma_play_data.addr; 366 DMA0_RAM_ADDR = dma_play_data.addr;
@@ -391,32 +391,33 @@ static void play_start_pcm(void)
391static void play_stop_pcm(void) 391static void play_stop_pcm(void)
392{ 392{
393#ifdef CPU_PP502x 393#ifdef CPU_PP502x
394 size_t status = DMA0_STATUS; 394 unsigned long status = DMA0_STATUS; /* Snapshot- resume from this point */
395 size_t size; 395 unsigned long cmd = DMA0_CMD;
396 size_t size = 0;
396 397
397 /* Stop transfer */ 398 /* Stop transfer */
398 DMA0_CMD &= ~(DMA_CMD_START | DMA_CMD_INTR); 399 DMA0_CMD = cmd & ~(DMA_CMD_START | DMA_CMD_INTR);
399 400
400 /* Wait for not busy + clear int */ 401 /* Wait for not busy + clear int */
401 while (DMA0_STATUS & (DMA_STATUS_BUSY | DMA_STATUS_INTR)); 402 while (DMA0_STATUS & (DMA_STATUS_BUSY | DMA_STATUS_INTR));
402 403
403 size = (status & 0xfffc) + 4; 404 if (status & DMA_STATUS_BUSY) {
404
405 if (status & DMA_STATUS_BUSY)
406 {
407 /* Transfer was interrupted - leave what's left */ 405 /* Transfer was interrupted - leave what's left */
408 dma_play_data.addr += dma_play_data.size - size; 406 size = (cmd & 0xfffc) - (status & 0xfffc);
409 dma_play_data.size = size;
410 } 407 }
411 else if (status & DMA_STATUS_INTR) 408 else if (status & DMA_STATUS_INTR) {
412 { 409 /* Transfer was finished - DMA0_STATUS will have been reloaded
413 /* Tranfer was finished - DMA0_STATUS will have been reloaded 410 * automatically with size in DMA0_CMD. Setup to restart on next
414 * automatically with size in DMA0_CMD. */ 411 * segment. */
415 dma_play_data.addr += size; 412 size = (cmd & 0xfffc) + 4;
416 dma_play_data.size -= size;
417 if (dma_play_data.size <= 0)
418 dma_play_data.addr = 0; /* Entire buffer has completed */
419 } 413 }
414 /* else not an active state - size = 0 */
415
416 dma_play_data.addr += size;
417 dma_play_data.size -= size;
418
419 if (dma_play_data.size == 0)
420 dma_play_data.addr = 0; /* Entire buffer has completed. */
420#else 421#else
421 /* Disable TX interrupt */ 422 /* Disable TX interrupt */
422 IIS_IRQTX_REG &= ~IIS_IRQTX; 423 IIS_IRQTX_REG &= ~IIS_IRQTX;
@@ -431,7 +432,7 @@ static void play_stop_pcm(void)
431void pcm_play_dma_start(const void *addr, size_t size) 432void pcm_play_dma_start(const void *addr, size_t size)
432{ 433{
433 addr = (void *)(((long)addr + 2) & ~3); 434 addr = (void *)(((long)addr + 2) & ~3);
434 size &= 0xfffc; 435 size &= ~3;
435 436
436#if NUM_CORES > 1 437#if NUM_CORES > 1
437 /* This will become more important later - and different ! */ 438 /* This will become more important later - and different ! */
@@ -440,7 +441,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
440 441
441 pcm_play_dma_stop(); 442 pcm_play_dma_stop();
442 443
443 if (size <= 0) 444 if (size == 0)
444 return; 445 return;
445 446
446#ifdef CPU_PP502x 447#ifdef CPU_PP502x