summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/iriver_flash.c104
1 files changed, 38 insertions, 66 deletions
diff --git a/apps/plugins/iriver_flash.c b/apps/plugins/iriver_flash.c
index 37bb3b3847..e33e422d01 100644
--- a/apps/plugins/iriver_flash.c
+++ b/apps/plugins/iriver_flash.c
@@ -49,9 +49,9 @@ ssize_t audiobuf_size;
49 49
50struct flash_info 50struct flash_info
51{ 51{
52 uint8_t manufacturer; 52 uint16_t manufacturer;
53 uint8_t id; 53 uint16_t id;
54 int size; 54 uint32_t size;
55 char name[32]; 55 char name[32];
56}; 56};
57 57
@@ -67,36 +67,20 @@ static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */
67#endif 67#endif
68 68
69/* read the manufacturer and device ID */ 69/* read the manufacturer and device ID */
70static bool cfi_read_id(uint8_t* pManufacturerID, uint8_t* pDeviceID) 70static void cfi_read_id(struct flash_info* pInfo)
71{ 71{
72 uint8_t not_manu, not_id; /* read values before switching to ID mode */
73 uint8_t manu, id; /* read values when in ID mode */
74
75 /* read the normal content */
76 not_manu = FB[0]; /* should be 'A' (0x41) and 'R' (0x52) */
77 not_id = FB[1]; /* from the "ARCH" marker */
78
79 FB[0x5555] = 0xAA; /* enter command mode */ 72 FB[0x5555] = 0xAA; /* enter command mode */
80 FB[0x2AAA] = 0x55; 73 FB[0x2AAA] = 0x55;
81 FB[0x5555] = 0x90; /* ID command */ 74 FB[0x5555] = 0x90; /* enter ID mode */
82 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ 75 rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */
83 76
84 manu = FB[0]; 77 pInfo->manufacturer = FB[0];
85 id = FB[1]; 78 pInfo->id = FB[1];
86 79
87 FB[0] = 0xF0; /* reset flash (back to normal read mode) */ 80 FB[0x5555] = 0xAA; /* enter command mode */
88 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ 81 FB[0x2AAA] = 0x55;
89 82 FB[0x5555] = 0xF0; /* exit ID mode */
90 /* I assume success if the obtained values are different from 83 rb->sleep(HZ/100); /* we only need to sleep 150ns but 10ms is the minimum */
91 the normal flash content. This is not perfectly bulletproof, they
92 could theoretically be the same by chance, causing us to fail. */
93 if (not_manu != manu || not_id != id) /* a value has changed */
94 {
95 *pManufacturerID = manu; /* return the results */
96 *pDeviceID = id;
97 return true; /* success */
98 }
99 return false; /* fail */
100} 84}
101 85
102/* wait until the rom signals completion of an operation */ 86/* wait until the rom signals completion of an operation */
@@ -148,44 +132,34 @@ static bool cfi_program_word(volatile uint16_t* pAddr, uint16_t data)
148 return cfi_wait_for_rom(pAddr); 132 return cfi_wait_for_rom(pAddr);
149} 133}
150 134
151/* this returns true if supported and fills the info struct */ 135/* fills in the struct with data about the flash rom */
152bool cfi_get_flash_info(struct flash_info* pInfo) 136static void cfi_get_flash_info(struct flash_info* pInfo)
153{ 137{
154 rb->memset(pInfo, 0, sizeof(struct flash_info)); 138 uint32_t size = 0;
139 const char* name = "";
155 140
156 if (!cfi_read_id(&pInfo->manufacturer, &pInfo->id)) 141 cfi_read_id(pInfo);
157 return false;
158 142
159 if (pInfo->manufacturer == 0xBF) /* SST */ 143 switch (pInfo->manufacturer)
160 { 144 {
161 if (pInfo->id == 0xD6) 145 /* SST */
162 { 146 case 0x00BF:
163 pInfo->size = 256* 1024; /* 256k */ 147 switch (pInfo->id)
164 rb->strcpy(pInfo->name, "SST39VF020"); 148 {
165 return true; 149 case 0x2782:
166 } 150 size = 2048 * 1024; /* 2 MiB */
167 else if (pInfo->id == 0xD7) 151 name = "SST39VF160";
168 { 152 break;
169 pInfo->size = 512* 1024; /* 512k */ 153 case 0x235B:
170 rb->strcpy(pInfo->name, "SST39VF040"); 154 size = 4096 * 1024; /* 4 MiB */
171 return true; 155 name = "SST39VF3201";
172 } 156 break;
173 else if (pInfo->id == 0x82) 157 }
174 { 158 break;
175 pInfo->size = 2048* 1024; /* 2 MiB */
176 rb->strcpy(pInfo->name, "SST39VF160");
177 return true;
178 }
179 else if (pInfo->id == 0x5B)
180 {
181 pInfo->size = 4096* 1024; /* 4 MiB */
182 rb->strcpy(pInfo->name, "SST39VF3201");
183 return true;
184 }
185 else
186 return false;
187 } 159 }
188 return false; 160
161 pInfo->size = size;
162 rb->strcpy(pInfo->name, name);
189} 163}
190 164
191/***************** User Interface Functions *****************/ 165/***************** User Interface Functions *****************/
@@ -206,25 +180,23 @@ void ShowFlashInfo(struct flash_info* pInfo)
206{ 180{
207 if (!pInfo->manufacturer) 181 if (!pInfo->manufacturer)
208 { 182 {
209 rb->lcd_puts(0, 0, "Flash: M=?? D=??"); 183 rb->lcd_puts(0, 0, "Flash: M=???? D=????");
210 rb->lcd_puts(0, 1, "Impossible to program"); 184 rb->lcd_puts(0, 1, "Impossible to program");
211 } 185 }
212 else 186 else
213 { 187 {
214 rb->lcd_putsf(0, 0, "Flash: M=%02x D=%02x", 188 rb->lcd_putsf(0, 0, "Flash: M=%04x D=%04x",
215 pInfo->manufacturer, pInfo->id); 189 pInfo->manufacturer, pInfo->id);
216 190
217
218 if (pInfo->size) 191 if (pInfo->size)
219 { 192 {
220 rb->lcd_puts(0, 1, pInfo->name); 193 rb->lcd_puts(0, 1, pInfo->name);
221 rb->lcd_putsf(0, 2, "Size: %d KB", pInfo->size / 1024); 194 rb->lcd_putsf(0, 2, "Size: %u KB", pInfo->size / 1024);
222 } 195 }
223 else 196 else
224 { 197 {
225 rb->lcd_puts(0, 1, "Unsupported chip"); 198 rb->lcd_puts(0, 1, "Unsupported chip");
226 } 199 }
227
228 } 200 }
229 201
230 rb->lcd_update(); 202 rb->lcd_update();