diff --git a/firmware/export/config.h b/firmware/export/config.h index 7f72cde7d4..221e9a8124 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -434,7 +434,7 @@ #endif /* BOOTLOADER */ -#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) +#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) || (CONFIG_CPU == AS3525) #define HAVE_WAKEUP_OBJECTS #endif diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 2437faf76c..726dffc6ab 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c @@ -553,8 +553,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, (1<<3) /* DMA */ | (9<<4) /* 2^9 = 512 */ ; - while(!dma_finished) - yield(); + dma_wait_transfer(0); buf += transfer * SECTOR_SIZE; start += transfer; diff --git a/firmware/target/arm/as3525/dma-pl081.c b/firmware/target/arm/as3525/dma-pl081.c index 31021e1560..fbe488ce05 100644 --- a/firmware/target/arm/as3525/dma-pl081.c +++ b/firmware/target/arm/as3525/dma-pl081.c @@ -19,21 +19,30 @@ * ****************************************************************************/ +#include #include "as3525.h" #include "pl081.h" #include "dma-target.h" -#include #include "panic.h" +#include "kernel.h" -volatile bool dma_finished; +static struct wakeup transfer_completion_signal[2]; /* 2 channels */ + +inline void dma_wait_transfer(int channel) +{ + wakeup_wait(&transfer_completion_signal[channel], TIMEOUT_BLOCK); +} void dma_init(void) { /* Enable DMA controller */ CGU_PERI |= CGU_DMA_CLOCK_ENABLE; - DMAC_CONFIGURATION |= (1<<0); + DMAC_CONFIGURATION |= (1<<0); /* TODO: disable controller when not used */ DMAC_SYNC = 0; VIC_INT_ENABLE |= INTERRUPT_DMAC; + + wakeup_init(&transfer_completion_signal[0]); + wakeup_init(&transfer_completion_signal[1]); } void dma_enable_channel(int channel, void *src, void *dst, int peri, @@ -65,8 +74,6 @@ void dma_enable_channel(int channel, void *src, void *dst, int peri, DMAC_CH_CONTROL(channel) = control; - dma_finished = false; - /* only needed if DMAC and Peripheral do not run at the same clock speed */ DMAC_SYNC |= (1<