diff --git a/include/gint/dma.h b/include/gint/dma.h index be8528b..bae3909 100644 --- a/include/gint/dma.h +++ b/include/gint/dma.h @@ -57,7 +57,7 @@ void dma_transfer(int channel, dma_size_t size, uint length, void const *src, dma_address_t src_mode, void *dst, dma_address_t dst_mode); -/* dma_transfer_wait() - Wait for a transfer on channel 0 to finish +/* dma_transfer_wait() - Wait for a transfer to finish You should call this function when you need to transfer to be complete before continuing execution. If you are sure that the transfer is finished, diff --git a/src/dma/dma.c b/src/dma/dma.c index 195dae0..1d51c6e 100644 --- a/src/dma/dma.c +++ b/src/dma/dma.c @@ -41,7 +41,7 @@ static uint32_t dma_translate(void const *address) return a; /* First additional on-chip memory area (XRAM) */ - if(a >= 0xe5007000 && a < 0xE5009000) + if(a >= 0xe5007000 && a < 0xe5009000) return a; /* Second on-chip memory area (YRAM) */ @@ -123,8 +123,18 @@ void dma_transfer_wait(int channel) channel_t *ch = dma_channel(channel); if(!ch) return; - /* Wait for the channel to be disabled by the interrupt handler */ - while(ch->CHCR.DE) sleep(); + /* Wait for the channel to be disabled by the interrupt handler. + When the source or the destination of the transfer is X, Y or IL + memory, refrain from sleeping as this also stops the transfer. */ + int onchip = 0; + + if(ch->SAR >= 0xe5007000 && ch->SAR < 0xe5204000) onchip = 1; + if(ch->DAR >= 0xe5007000 && ch->DAR < 0xe5204000) onchip = 1; + + while(ch->CHCR.DE) + { + if(!onchip) sleep(); + } } /* dma_transfer_noint(): Perform a data transfer without interruptions */ diff --git a/src/dma/memset.c b/src/dma/memset.c index 2d5aff2..a903e6d 100644 --- a/src/dma/memset.c +++ b/src/dma/memset.c @@ -7,6 +7,7 @@ void *dma_memset(void *dst, uint32_t l, size_t size) uint32_t *IL = (void *)0xe5200000; for(int i = 0; i < 8; i++) IL[i] = l; - dma_transfer_noint(1, DMA_32B, size >> 5, IL, DMA_FIXED, dst, DMA_INC); + dma_transfer(1, DMA_32B, size >> 5, IL, DMA_FIXED, dst, DMA_INC); + dma_transfer_wait(1); return dst; }