diff options
| author | Greg White <gwhite@rockbox.org> | 2007-01-06 01:26:36 +0000 |
|---|---|---|
| committer | Greg White <gwhite@rockbox.org> | 2007-01-06 01:26:36 +0000 |
| commit | ebcd762fb24455b58c9aab79a004e93d04a5c6cd (patch) | |
| tree | 3a9e4e84c8533f13771894519b22c176638a9c47 | |
| parent | e370776120cf87e0a92038d3e4399240b2cf2c3d (diff) | |
| download | rockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.zip rockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.tar.gz rockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.tar.bz2 rockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.tar.xz | |
Read byte by byte rather than DMA for unaligned transfer
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11927 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c index 361b9d4..d098d83 100644 --- a/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c +++ b/firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c @@ -54,18 +54,31 @@ void ata_device_init(void) void copy_read_sectors(unsigned char* buf, int wordcount) { + /* Unaligned transfer - slow copy */ + if ( (unsigned long)buf & 1) + { /* not 16-bit aligned, copy byte by byte */ + unsigned short tmp = 0; + unsigned char* bufend = buf + wordcount*2; + do + { + tmp = ATA_DATA; + *buf++ = tmp & 0xff; /* I assume big endian */ + *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */ + } while (buf < bufend); /* tail loop is faster */ + return; + } /* This should never happen, but worth watching for */ if(wordcount > (1 << 18)) panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!"); //#define GIGABEAT_DEBUG_ATA #ifdef GIGABEAT_DEBUG_ATA - static int line = 0; - static char str[256]; - snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); - lcd_puts(10, line, str); - line = (line+1) % 32; - lcd_update(); + static int line = 0; + static char str[256]; + snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); + lcd_puts(10, line, str); + line = (line+1) % 32; + lcd_update(); #endif /* Reset the channel */ DMASKTRIG0 |= 4; @@ -87,17 +100,17 @@ void copy_read_sectors(unsigned char* buf, int wordcount) /* Activate the channel */ DMASKTRIG0 = 0x2; - invalidate_dcache_range((void *)buf, wordcount*2); + invalidate_dcache_range((void *)buf, wordcount*2); - INTMSK &= ~(1<<17); /* unmask the interrupt */ - SRCPND = (1<<17); /* clear any pending interrupts */ + INTMSK &= ~(1<<17); /* unmask the interrupt */ + SRCPND = (1<<17); /* clear any pending interrupts */ /* Start DMA */ DMASKTRIG0 |= 0x1; /* Wait for transfer to complete */ while((DSTAT0 & 0x000fffff)) - CLKCON |= (1 << 2); /* set IDLE bit */ - /* Dump cache for the buffer */ + CLKCON |= (1 << 2); /* set IDLE bit */ + /* Dump cache for the buffer */ } void dma0(void) |