diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 47 |
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) | |||
391 | static void play_stop_pcm(void) | 391 | static 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) | |||
431 | void pcm_play_dma_start(const void *addr, size_t size) | 432 | void 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 |