summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorGreg White <gwhite@rockbox.org>2007-01-06 01:26:36 +0000
committerGreg White <gwhite@rockbox.org>2007-01-06 01:26:36 +0000
commitebcd762fb24455b58c9aab79a004e93d04a5c6cd (patch)
tree3a9e4e84c8533f13771894519b22c176638a9c47 /firmware
parente370776120cf87e0a92038d3e4399240b2cf2c3d (diff)
downloadrockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.tar.gz
rockbox-ebcd762fb24455b58c9aab79a004e93d04a5c6cd.zip
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
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/ata-meg-fx.c35
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 361b9d4b6f..d098d83de0 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)
54 54
55void copy_read_sectors(unsigned char* buf, int wordcount) 55void copy_read_sectors(unsigned char* buf, int wordcount)
56{ 56{
57 /* Unaligned transfer - slow copy */
58 if ( (unsigned long)buf & 1)
59 { /* not 16-bit aligned, copy byte by byte */
60 unsigned short tmp = 0;
61 unsigned char* bufend = buf + wordcount*2;
62 do
63 {
64 tmp = ATA_DATA;
65 *buf++ = tmp & 0xff; /* I assume big endian */
66 *buf++ = tmp >> 8; /* and don't use the SWAB16 macro */
67 } while (buf < bufend); /* tail loop is faster */
68 return;
69 }
57 /* This should never happen, but worth watching for */ 70 /* This should never happen, but worth watching for */
58 if(wordcount > (1 << 18)) 71 if(wordcount > (1 << 18))
59 panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!"); 72 panicf("atd-meg-fx.c: copy_read_sectors: too many sectors per read!");
60 73
61//#define GIGABEAT_DEBUG_ATA 74//#define GIGABEAT_DEBUG_ATA
62#ifdef GIGABEAT_DEBUG_ATA 75#ifdef GIGABEAT_DEBUG_ATA
63 static int line = 0; 76 static int line = 0;
64 static char str[256]; 77 static char str[256];
65 snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount); 78 snprintf(str, sizeof(str), "ODD DMA to %08x, %d", buf, wordcount);
66 lcd_puts(10, line, str); 79 lcd_puts(10, line, str);
67 line = (line+1) % 32; 80 line = (line+1) % 32;
68 lcd_update(); 81 lcd_update();
69#endif 82#endif
70 /* Reset the channel */ 83 /* Reset the channel */
71 DMASKTRIG0 |= 4; 84 DMASKTRIG0 |= 4;
@@ -87,17 +100,17 @@ void copy_read_sectors(unsigned char* buf, int wordcount)
87 /* Activate the channel */ 100 /* Activate the channel */
88 DMASKTRIG0 = 0x2; 101 DMASKTRIG0 = 0x2;
89 102
90 invalidate_dcache_range((void *)buf, wordcount*2); 103 invalidate_dcache_range((void *)buf, wordcount*2);
91 104
92 INTMSK &= ~(1<<17); /* unmask the interrupt */ 105 INTMSK &= ~(1<<17); /* unmask the interrupt */
93 SRCPND = (1<<17); /* clear any pending interrupts */ 106 SRCPND = (1<<17); /* clear any pending interrupts */
94 /* Start DMA */ 107 /* Start DMA */
95 DMASKTRIG0 |= 0x1; 108 DMASKTRIG0 |= 0x1;
96 109
97 /* Wait for transfer to complete */ 110 /* Wait for transfer to complete */
98 while((DSTAT0 & 0x000fffff)) 111 while((DSTAT0 & 0x000fffff))
99 CLKCON |= (1 << 2); /* set IDLE bit */ 112 CLKCON |= (1 << 2); /* set IDLE bit */
100 /* Dump cache for the buffer */ 113 /* Dump cache for the buffer */
101} 114}
102 115
103void dma0(void) 116void dma0(void)