1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CTRDG - libraries - ARM9
3 File: ctrdg_flash_AT29LV512.c
4
5 Copyright 2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2007-11-15#$
14 $Rev: 2414 $
15 $Author: hatamoto_minoru $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro.h>
19
20 // Definition data------------------------------
21 /* For debugging */
22 //#ifndef __FLASH_DEBUG
23 #define CTRDG_BACKUP_COM_ADR1 (CTRDG_AGB_FLASH_ADR+0x00005555)
24 #define CTRDG_BACKUP_COM_ADR2 (CTRDG_AGB_FLASH_ADR+0x00002aaa)
25 //#else
26 //#define COM_ADR1 0x02003ffe
27 //#define COM_ADR2 0x02003fff
28 //#endif
29
30 #define FLASH_LOG_SECTOR_COUNT 16 // 64KB/4KB=16
31 #define FLASH_SECTOR_LOG_TO_PHYS 32 // 4KB/128B=32
32 #define FLASH_SECTOR_LOG_TO_PHYS_SHIFT 5 // 32=2^5
33
34 // Extern data----------------------------------
35 extern u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData);
36 /*Exclusive control*/
37 extern u16 ctrdgi_flash_lock_id;
38 extern BOOL ctrdgi_backup_irq;
39
40 // Function's prototype declaration-------------
41 u16 CTRDGi_EraseFlashChipAT(void);
42 u16 CTRDGi_EraseFlashSectorAT(u16 p_secNo);
43 u16 CTRDGi_EraseFlash4KBAT(u16 l_secNo);
44 u16 CTRDGi_WriteFlashSectorAT(u16 p_secNo, u8 *src);
45 u16 CTRDGi_WriteFlash4KBAT(u16 l_secNo, u8 *src);
46
47 u32 CTRDGi_EraseFlashChipCoreAT(CTRDGTaskInfo * arg);
48 u32 CTRDGi_EraseFlash4KBCoreAT(CTRDGTaskInfo * arg);
49 u32 CTRDGi_WriteFlash4KBCoreAT(CTRDGTaskInfo * arg);
50 u32 CTRDGi_EraseFlashSectorCoreAT(CTRDGTaskInfo * arg);
51 u32 CTRDGi_WriteFlashSectorCoreAT(CTRDGTaskInfo * arg);
52
53 void CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback);
54 void CTRDGi_EraseFlash4KBAsyncAT(u16 secNo, CTRDG_TASK_FUNC callback);
55 void CTRDGi_WriteFlash4KBAsyncAT(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback);
56 void CTRDGi_EraseFlashSectorAsyncAT(u16 secNo, CTRDG_TASK_FUNC callback);
57 void CTRDGi_WriteFlashSectorAsyncAT(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback);
58
59 // Const data-----------------------------------
60 static const u16 atMaxTime[] = {
61 10, // Common 10ms (15.256us*66)*10
62 40, // Program 20ms (15.256us*66)*20
63 0, // Sector erase 0ms
64 40, // Chip erase 20ms
65 };
66
67 const CTRDGiFlashTypePlus AT29LV512_lib = {
68 CTRDGi_WriteFlash4KBAT,
69 CTRDGi_EraseFlashChipAT,
70 CTRDGi_EraseFlash4KBAT,
71 CTRDGi_WriteFlash4KBAsyncAT,
72 CTRDGi_EraseFlashChipAsyncAT,
73 CTRDGi_EraseFlash4KBAsyncAT,
74 CTRDGi_PollingSR512kCOMMON,
75 atMaxTime,
76 {
77 /* For debugging */
78 //#ifndef __FLASH_DEBUG
79 0x00010000, // ROM size
80 {0x00001000, 12, 16, 0}, // Sector
81 //#else
82 // 0x00002000,
83 // {0x00000200, 9, 16, 0},
84 //#endif
85 {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_18}, // agb read cycle=8, write cycle=8
86 0x1f, // Maker ID
87 0x3d, // Device ID
88 },
89 };
90
91 const CTRDGiFlashTypePlus AT29LV512_org = {
92 CTRDGi_WriteFlashSectorAT, // Unusable due to DataPolling routines not being transferred
93 CTRDGi_EraseFlashChipAT,
94 CTRDGi_EraseFlashSectorAT, // Unusable due to DataPolling routines not being transferred
95 CTRDGi_WriteFlashSectorAsyncAT,
96 CTRDGi_EraseFlashChipAsyncAT,
97 CTRDGi_EraseFlashSectorAsyncAT,
98 CTRDGi_PollingSR512kCOMMON,
99 atMaxTime,
100 {
101 /* For debugging */
102 //#ifndef __FLASH_DEBUG
103 0x00010000, // ROM size
104 {0x00000080, 7, 512, 0}, // Sector
105 //#else
106 // 0x00002000,
107 // {0x00000010, 4,256, 0},
108 //#endif
109 {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_18}, // agb read cycle=8, write cycle=8
110 0x1f, // Maker ID
111 0x3d, // Device ID
112 },
113 };
114
115
116 // Program description**************************
CTRDGi_EraseFlashChipCoreAT(CTRDGTaskInfo * arg)117 u32 CTRDGi_EraseFlashChipCoreAT(CTRDGTaskInfo * arg)
118 {
119 MICartridgeRamCycle ram_cycle;
120 u32 result;
121 (void)arg;
122
123 /*Exclusive control (lock) */
124 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
125 /*Access cycle settings */
126 ram_cycle = MI_GetCartridgeRamCycle();
127 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
128 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AT29LV512_org.type.agbWait[0];
129
130 ctrdgi_backup_irq = OS_DisableIrq();
131
132 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
133 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
134 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
135 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
136 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
137 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x10;
138 /* For debugging */
139 //#ifdef __FLASH_DEBUG
140 // adr=(u8 *)CTRDG_AGB_FLASH_ADR;
141 // for(i=0;i<AT29LV512_org.type.romSize;i++)
142 // *adr++=0xff;
143 //#endif
144 (void)OS_RestoreIrq(ctrdgi_backup_irq);
145
146 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_CHIP_ERASE, (u8 *)CTRDG_AGB_FLASH_ADR, 0xff);
147 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)| 3;
148
149 /*Access cycle settings */
150 MI_SetCartridgeRamCycle(ram_cycle);
151 /*Exclusive control (unlock) */
152 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
153
154 return result;
155 }
156
CTRDGi_EraseFlashSectorCoreAT(CTRDGTaskInfo * arg)157 u32 CTRDGi_EraseFlashSectorCoreAT(CTRDGTaskInfo * arg)
158 {
159 u32 i;
160 u8 *dst;
161 BOOL shlet_ime;
162 MICartridgeRamCycle ram_cycle;
163 u32 result;
164 CTRDGTaskInfo p = *arg;
165 u16 p_secNo = p.sec_num;
166
167 // ** This routine cannot be used alone if the DataPolling routine is not transferred
168 //
169
170 // Calculates target address
171 dst = (u8 *)(CTRDG_AGB_FLASH_ADR + (p_secNo << AT29LV512_org.type.sector.shift));
172
173 /*Exclusive control (lock) */
174 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
175 /*Access cycle settings */
176 ram_cycle = MI_GetCartridgeRamCycle();
177 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
178
179 // Prohibit interrupts
180 shlet_ime = OS_DisableIrq();
181
182 // Data program
183 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
184 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
185 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
186 for (i = AT29LV512_org.type.sector.size; i > 0; i--)
187 *dst++ = 0xff;
188 dst--;
189
190 // Resume interrupts
191 (void)OS_RestoreIrq(shlet_ime);
192
193 // Status check
194 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, 0xff);
195 if (result)
196 result = (u16)((result & 0xff00) | CTRDG_BACKUP_PHASE_SECTOR_ERASE);
197
198 /*Access cycle settings */
199 MI_SetCartridgeRamCycle(ram_cycle);
200 /*Exclusive control (unlock) */
201 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
202
203 return result;
204 }
205
CTRDGi_EraseFlash4KBCoreAT(CTRDGTaskInfo * arg)206 u32 CTRDGi_EraseFlash4KBCoreAT(CTRDGTaskInfo * arg)
207 {
208 u32 result;
209 u16 i, p_secNo, retry;
210 CTRDGTaskInfo p = *arg;
211 u16 l_secNo = p.sec_num;
212
213 /*Check parameters */
214 if (l_secNo >= FLASH_LOG_SECTOR_COUNT)
215 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
216
217 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AT29LV512_org.type.agbWait[0];
218 p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT);
219 for (i = 0; i < FLASH_SECTOR_LOG_TO_PHYS; i++)
220 {
221 retry = 2;
222 while (retry)
223 {
224 result = CTRDGi_EraseFlashSectorAT(p_secNo);
225 if (result == 0)
226 break;
227 retry--;
228 }
229 p_secNo++;
230 if (result)
231 break;
232 }
233 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)| 3;
234
235 return result;
236 }
237
CTRDGi_WriteFlashSectorCoreAT(CTRDGTaskInfo * arg)238 u32 CTRDGi_WriteFlashSectorCoreAT(CTRDGTaskInfo * arg)
239 {
240 u32 i;
241 u8 *dst;
242 BOOL shlet_ime;
243 MICartridgeRamCycle ram_cycle;
244 u32 result;
245 CTRDGTaskInfo p = *arg;
246 u16 p_secNo = p.sec_num;
247 u8 *src = p.data;
248
249 // ** This routine cannot be used alone if the DataPolling routine is not transferred
250 //
251
252 /*Exclusive control (lock) */
253 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
254 /*Access cycle settings */
255 ram_cycle = MI_GetCartridgeRamCycle();
256 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
257
258 // Calculates target address
259 dst = (u8 *)(CTRDG_AGB_FLASH_ADR + (p_secNo << AT29LV512_org.type.sector.shift));
260 // Prohibit interrupts
261 shlet_ime = OS_DisableIrq();
262
263 // Data program
264 //*(vu16 *)REG_WAITCNT=(
265 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
266 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
267 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
268 for (i = AT29LV512_org.type.sector.size; i > 0; i--)
269 *dst++ = *src++;
270 dst--;
271 src--;
272 // Resume interrupts
273 (void)OS_RestoreIrq(shlet_ime);
274
275 //*(vu16 *)REG_WAITCNT=(*(vu16 *)REG_WAITCNT & 0xfffc)|AT29LV512_org.type.agbWait[0];
276
277 // Status check
278 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, *src);
279
280 /*Access cycle settings */
281 MI_SetCartridgeRamCycle(ram_cycle);
282 /*Exclusive control (unlock) */
283 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
284
285 return result;
286 }
287
CTRDGi_WriteFlash4KBCoreAT(CTRDGTaskInfo * arg)288 u32 CTRDGi_WriteFlash4KBCoreAT(CTRDGTaskInfo * arg)
289 {
290 u32 result;
291 u16 p_secNo, retry;
292 CTRDGTaskInfo p = *arg;
293 u16 l_secNo = p.sec_num;
294 u8 *src = p.data;
295
296 /*Check parameters */
297 if (l_secNo >= FLASH_LOG_SECTOR_COUNT)
298 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
299
300 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AT29LV512_org.type.agbWait[0];
301 p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT);
302 ctrdg_flash_remainder = (u16)(AT29LV512_lib.type.sector.size);
303 while (ctrdg_flash_remainder)
304 {
305 retry = 2;
306 while (retry)
307 {
308 result = CTRDGi_WriteFlashSectorAT(p_secNo, src);
309 if (result == 0)
310 break;
311 retry--;
312 }
313 if (result)
314 break;
315 ctrdg_flash_remainder -= AT29LV512_org.type.sector.size;
316 src += AT29LV512_org.type.sector.size;
317 p_secNo++;
318 }
319 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)| 3;
320
321 return result;
322 }
323
CTRDGi_EraseFlashChipAT(void)324 u16 CTRDGi_EraseFlashChipAT(void)
325 {
326 u16 result;
327 CTRDGTaskInfo p;
328 result = (u16)CTRDGi_EraseFlashChipCoreAT(&p);
329
330 return result;
331 }
332
CTRDGi_EraseFlash4KBAT(u16 l_secNo)333 u16 CTRDGi_EraseFlash4KBAT(u16 l_secNo)
334 {
335 u16 result;
336 CTRDGTaskInfo p;
337 p.sec_num = l_secNo;
338 result = (u16)CTRDGi_EraseFlash4KBCoreAT(&p);
339
340 return result;
341 }
342
CTRDGi_WriteFlash4KBAT(u16 l_secNo,u8 * src)343 u16 CTRDGi_WriteFlash4KBAT(u16 l_secNo, u8 *src)
344 {
345 u16 result;
346 CTRDGTaskInfo p;
347 p.sec_num = l_secNo;
348 p.data = src;
349 result = (u16)CTRDGi_WriteFlash4KBCoreAT(&p);
350
351 return result;
352 }
353
CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback)354 void CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback)
355 {
356 CTRDGTaskInfo p;
357
358 CTRDGi_SetTask(&p, CTRDGi_EraseFlashChipCoreAT, callback);
359 }
360
CTRDGi_EraseFlash4KBAsyncAT(u16 l_secNo,CTRDG_TASK_FUNC callback)361 void CTRDGi_EraseFlash4KBAsyncAT(u16 l_secNo, CTRDG_TASK_FUNC callback)
362 {
363 CTRDGTaskInfo p;
364
365 p.sec_num = l_secNo;
366 CTRDGi_SetTask(&p, CTRDGi_EraseFlash4KBCoreAT, callback);
367 }
368
CTRDGi_WriteFlash4KBAsyncAT(u16 l_secNo,u8 * src,CTRDG_TASK_FUNC callback)369 void CTRDGi_WriteFlash4KBAsyncAT(u16 l_secNo, u8 *src, CTRDG_TASK_FUNC callback)
370 {
371 CTRDGTaskInfo p;
372
373 p.sec_num = l_secNo;
374 p.data = src;
375 CTRDGi_SetTask(&p, CTRDGi_WriteFlash4KBCoreAT, callback);
376 }
377
CTRDGi_EraseFlashSectorAT(u16 p_secNo)378 u16 CTRDGi_EraseFlashSectorAT(u16 p_secNo)
379 {
380 u16 result;
381 CTRDGTaskInfo p;
382 p.sec_num = p_secNo;
383 result = (u16)CTRDGi_EraseFlashSectorCoreAT(&p);
384
385 return result;
386 }
387
CTRDGi_WriteFlashSectorAT(u16 p_secNo,u8 * src)388 u16 CTRDGi_WriteFlashSectorAT(u16 p_secNo, u8 *src)
389 {
390 u16 result;
391 CTRDGTaskInfo p;
392 p.sec_num = p_secNo;
393 p.data = src;
394 result = (u16)CTRDGi_WriteFlashSectorCoreAT(&p);
395
396 return result;
397 }
398
CTRDGi_EraseFlashSectorAsyncAT(u16 p_secNo,CTRDG_TASK_FUNC callback)399 void CTRDGi_EraseFlashSectorAsyncAT(u16 p_secNo, CTRDG_TASK_FUNC callback)
400 {
401 CTRDGTaskInfo p;
402
403 p.sec_num = p_secNo;
404 CTRDGi_SetTask(&p, CTRDGi_EraseFlashSectorCoreAT, callback);
405 }
406
CTRDGi_WriteFlashSectorAsyncAT(u16 p_secNo,u8 * src,CTRDG_TASK_FUNC callback)407 void CTRDGi_WriteFlashSectorAsyncAT(u16 p_secNo, u8 *src, CTRDG_TASK_FUNC callback)
408 {
409 CTRDGTaskInfo p;
410
411 p.sec_num = p_secNo;
412 p.data = src;
413 CTRDGi_SetTask(&p, CTRDGi_WriteFlashSectorCoreAT, callback);
414 }
415