1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CTRDG - libraries - ARM9
3 File: ctrdg_flash_LE39FW512.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 //#define __LE_DEBUG
21 /* For debugging */
22 //#ifdef __LE_DEBUG
23 //#include "mylib.h"
24 //#endif
25
26 // Definition data------------------------------
27 /* For debugging */
28 //#ifndef __FLASH_DEBUG
29 #define CTRDG_BACKUP_COM_ADR1 (CTRDG_AGB_FLASH_ADR+0x00005555)
30 #define CTRDG_BACKUP_COM_ADR2 (CTRDG_AGB_FLASH_ADR+0x00002aaa)
31 //#else
32 //#define COM_ADR1 0x02003ffe
33 //#define COM_ADR2 0x02003fff
34 //#endif
35
36 #define FLASH_LOG_SECTOR_COUNT 16
37
38 #define ERASE_RETRY_MAX 0x50
39
40 // Extern data----------------------------------
41 extern const CTRDGFlashType *AgbFlash;
42 extern u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData);
43 /*Exclusive control*/
44 extern u16 ctrdgi_flash_lock_id;
45 extern BOOL ctrdgi_backup_irq;
46
47 // Function's prototype declaration-------------
48 u16 CTRDGi_EraseFlashChipLE(void);
49 u16 CTRDGi_EraseFlashSectorLE(u16 secNo);
50 u16 CTRDGi_ProgramFlashByteLE(u8 *src, u8 *dst);
51 u16 CTRDGi_WriteFlashSectorLE(u16 secNo, u8 *src);
52 u32 CTRDGi_VerifyFlashCoreFF(u8 *adr);
53 u32 CTRDGi_VerifyFlashErase(u8 *tgt, u32 (*func_p) (u8 *));
54 u32 CTRDGi_EraseFlashChipCoreLE(CTRDGTaskInfo * arg);
55 u32 CTRDGi_EraseFlashSectorCoreLE(CTRDGTaskInfo * arg);
56 u32 CTRDGi_WriteFlashSectorCoreLE(CTRDGTaskInfo * arg);
57
58 void CTRDGi_EraseFlashChipAsyncLE(CTRDG_TASK_FUNC callback);
59 void CTRDGi_EraseFlashSectorAsyncLE(u16 secNo, CTRDG_TASK_FUNC callback);
60 void CTRDGi_WriteFlashSectorAsyncLE(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback);
61
62 // Const data-----------------------------------
63 static const u16 leMaxTime[] = {
64 10, // Common 10ms
65 10, // Program 10ms(exactly:20usec)
66 40, // Sector erase 25ms
67 200, // Chip erase 100ms
68 };
69
70 const CTRDGiFlashTypePlus defaultFlash512 = {
71 CTRDGi_WriteFlashSectorLE,
72 CTRDGi_EraseFlashChipLE,
73 CTRDGi_EraseFlashSectorLE,
74 CTRDGi_WriteFlashSectorAsyncLE,
75 CTRDGi_EraseFlashChipAsyncLE,
76 CTRDGi_EraseFlashSectorAsyncLE,
77 CTRDGi_PollingSR512kCOMMON,
78 leMaxTime,
79 {
80 /* For debugging */
81 //#ifndef __FLASH_DEBUG
82 0x00010000, // ROM size
83 {0x00001000, 12, 16, 0}, // Sector size, shift, count
84 //#else
85 // 0x00002000,
86 // {0x00000200, 9, 16, 0},
87 //#endif
88 {MI_CTRDG_RAMCYCLE_8, MI_CTRDG_RAMCYCLE_6}, // agb read cycle=3, write cycle=2
89 0x00, // Maker ID
90 0x00, // Device ID
91 },
92 };
93
94 const CTRDGiFlashTypePlus LE39FW512 = {
95 CTRDGi_WriteFlashSectorLE,
96 CTRDGi_EraseFlashChipLE,
97 CTRDGi_EraseFlashSectorLE,
98 CTRDGi_WriteFlashSectorAsyncLE,
99 CTRDGi_EraseFlashChipAsyncLE,
100 CTRDGi_EraseFlashSectorAsyncLE,
101 CTRDGi_PollingSR512kCOMMON,
102 leMaxTime,
103 {
104 /* For debugging */
105 //#ifndef __FLASH_DEBUG
106 0x00010000, // ROM size
107 {0x00001000, 12, 16, 0}, // Sector size, shift, count, top
108 //#else
109 // 0x00002000,
110 // {0x00000200, 9, 16, 0},
111 //#endif
112 {MI_CTRDG_RAMCYCLE_8, MI_CTRDG_RAMCYCLE_6}, // agb read cycle=3, write cycle=2
113 0xbf, // Maker ID
114 0xd4, // Device ID
115 },
116 };
117
118 // Program description**************************
CTRDGi_EraseFlashChipCoreLE(CTRDGTaskInfo * arg)119 u32 CTRDGi_EraseFlashChipCoreLE(CTRDGTaskInfo * arg)
120 {
121 /* For debugging */
122 //#ifdef __FLASH_DEBUG
123 // u32 i;
124 //#endif
125 MICartridgeRamCycle ram_cycle;
126 u32 result;
127 (void)arg;
128
129 /*Exclusive control (lock) */
130 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
131 /*Access cycle settings */
132 ram_cycle = MI_GetCartridgeRamCycle();
133 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
134 //*(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
135 ctrdgi_backup_irq = OS_DisableIrq();
136
137 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
138 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
139 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
140 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
141 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
142 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x10;
143 /* For debugging */
144 //#ifdef __FLASH_DEBUG
145 // adr=(u8 *)CTRDG_AGB_FLASH_ADR;
146 // for(i=0;i<AgbFlash->romSize;i++)
147 // *adr++=0xff;
148 //#endif
149 (void)OS_RestoreIrq(ctrdgi_backup_irq);
150
151 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_CHIP_ERASE, (u8 *)CTRDG_AGB_FLASH_ADR, 0xff);
152
153 /*Access cycle settings */
154 MI_SetCartridgeRamCycle(ram_cycle);
155 /*Exclusive control (unlock) */
156 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
157 return result;
158 }
159
CTRDGi_EraseFlashSectorCoreLE(CTRDGTaskInfo * arg)160 u32 CTRDGi_EraseFlashSectorCoreLE(CTRDGTaskInfo * arg)
161 {
162 u8 *adr;
163 //u16 readFuncBuff[32];
164 MICartridgeRamCycle ram_cycle;
165 u32 result;
166 CTRDGTaskInfo p = *arg;
167 u16 secNo = p.sec_num;
168
169 if (secNo >= FLASH_LOG_SECTOR_COUNT)
170 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
171
172 /*Exclusive control (lock) */
173 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
174 /*Access cycle settings */
175 ram_cycle = MI_GetCartridgeRamCycle();
176 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
177 //*(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
178
179 adr = (u8 *)(CTRDG_AGB_FLASH_ADR + (secNo << AgbFlash->sector.shift));
180
181 ctrdgi_backup_irq = OS_DisableIrq();
182
183 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
184 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
185 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
186 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
187 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
188 *(vu8 *)adr = 0x30;
189 /* For debugging */
190 //#ifdef __FLASH_DEBUG
191 // for(i=0;i<AgbFlash->sector.size;i++)
192 // *adr++=0xff;
193 // adr=(u8 *)(CTRDG_AGB_FLASH_ADR+(secNo<<AgbFlash->sector.shift));
194 //#endif
195 (void)OS_RestoreIrq(ctrdgi_backup_irq);
196
197 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_SECTOR_ERASE, adr, 0xff);
198
199 /*Access cycle settings */
200 MI_SetCartridgeRamCycle(ram_cycle);
201 /*Exclusive control (unlock) */
202 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
203
204 return result;
205 }
206
CTRDGi_ProgramFlashByteLE(u8 * src,u8 * dst)207 u16 CTRDGi_ProgramFlashByteLE(u8 *src, u8 *dst)
208 {
209 u16 result;
210 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
211 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
212 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
213 *dst = *src;
214
215 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, *src);
216 return result;
217 }
218
CTRDGi_WriteFlashSectorCoreLE(CTRDGTaskInfo * arg)219 u32 CTRDGi_WriteFlashSectorCoreLE(CTRDGTaskInfo * arg)
220 {
221 //u16 funcBuff[48],*func_src,*func_dst
222 u8 *tgt;
223 u16 retry, add_erase, j;
224 MICartridgeRamCycle ram_cycle;
225 u32 result;
226 CTRDGTaskInfo p = *arg;
227 u16 secNo = p.sec_num;
228 u8 *src = p.data;
229
230 /*Check parameters */
231 if (secNo >= FLASH_LOG_SECTOR_COUNT)
232 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
233
234 tgt = (u8 *)(CTRDG_AGB_FLASH_ADR + (secNo << AgbFlash->sector.shift));
235
236 // Erase verify routine transmit
237 // func_src=(u16 *)((u32)VerifyFlashCoreFF & 0xFFFFFFFE);
238 // func_dst=funcBuff;
239 // for(i=(u32)VerifyFlashErase-(u32)VerifyFlashCoreFF;i>0;i-=2)
240 // *func_dst++=*func_src++;
241 retry = 0;
242 // Erase
243 /* For debugging */
244 //++++++++++++++++++++
245 //#ifdef __LE_DEBUG
246 // if(secNo<8)
247 // pos=0x0194+(secNo<<5);
248 // else
249 // pos=0x0199+((secNo-8)<<5);
250 // DrawHexOnBgx(0,pos,BG_PLTT_WHITE,&retry,2);
251 //#endif
252 //++++++++++++++++++++
253 while (1)
254 {
255 result = CTRDGi_EraseFlashSectorLE(secNo);
256 if (result == 0)
257 {
258 result = (u16)CTRDGi_VerifyFlashErase(tgt, CTRDGi_VerifyFlashCoreFF);
259 if (result == 0)
260 break;
261 }
262 if (retry++ == ERASE_RETRY_MAX)
263 return result;
264 /* For debugging */
265 //++++++++++++++++++++
266 //#ifdef __LE_DEBUG
267 // DrawHexOnBgx(0,pos,BG_PLTT_YELLOW,&retry,2);
268 //#endif
269 //++++++++++++++++++++
270 }
271
272 // add Erase
273 add_erase = 1;
274 if (retry > 0)
275 add_erase = 6;
276 for (j = 1; j <= add_erase; j++)
277 {
278 /* For debugging */
279 //++++++++++++++++++++
280 //#ifdef __LE_DEBUG
281 // DrawHexOnBgx(0,pos+3,BG_PLTT_GREEN,&j,1);
282 //#endif
283 //++++++++++++++++++++
284 (void)CTRDGi_EraseFlashSectorLE(secNo);
285 }
286
287 /*Exclusive control (lock) */
288 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
289 /*Access cycle settings */
290 ram_cycle = MI_GetCartridgeRamCycle();
291 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
292 //*(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
293
294 // Program
295
296 ctrdg_flash_remainder = (u16)AgbFlash->sector.size;
297 ctrdgi_backup_irq = OS_DisableIrq();
298 while (ctrdg_flash_remainder)
299 {
300 result = CTRDGi_ProgramFlashByteLE(src, tgt);
301 if (result)
302 break;
303 ctrdg_flash_remainder--;
304 src++;
305 tgt++;
306 }
307 (void)OS_RestoreIrq(ctrdgi_backup_irq);
308
309 /*Access cycle settings */
310 MI_SetCartridgeRamCycle(ram_cycle);
311 /*Exclusive control (unlock) */
312 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
313
314 return result;
315 }
316
CTRDGi_VerifyFlashCoreFF(u8 * adr)317 u32 CTRDGi_VerifyFlashCoreFF(u8 *adr)
318 {
319 u32 count;
320 for (count = AgbFlash->sector.size; count > 0; count--)
321 {
322 if (*adr++ != 0xff)
323 {
324 break;
325 }
326 }
327 return count;
328 }
329
CTRDGi_VerifyFlashErase(u8 * tgt,u32 (* func_p)(u8 *))330 u32 CTRDGi_VerifyFlashErase(u8 *tgt, u32 (*func_p) (u8 *))
331 {
332 u32 result;
333 MICartridgeRamCycle ram_cycle;
334
335 /*Exclusive control (lock) */
336 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
337 /*Access cycle settings */
338 ram_cycle = MI_GetCartridgeRamCycle();
339 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
340
341 result = 0;
342 if (func_p(tgt))
343 {
344 result = (CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_VERIFY_ERASE);
345 }
346
347 /*Access cycle settings */
348 MI_SetCartridgeRamCycle(ram_cycle);
349 /*Exclusive control (unlock) */
350 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
351
352 return result;
353 }
354
355
CTRDGi_EraseFlashChipLE(void)356 u16 CTRDGi_EraseFlashChipLE(void)
357 {
358 u16 result;
359 CTRDGTaskInfo p;
360 result = (u16)CTRDGi_EraseFlashChipCoreLE(&p);
361
362 return result;
363 }
364
CTRDGi_EraseFlashSectorLE(u16 secNo)365 u16 CTRDGi_EraseFlashSectorLE(u16 secNo)
366 {
367 u16 result;
368 CTRDGTaskInfo p;
369 p.sec_num = secNo;
370 result = (u16)CTRDGi_EraseFlashSectorCoreLE(&p);
371
372 return result;
373 }
374
CTRDGi_WriteFlashSectorLE(u16 secNo,u8 * src)375 u16 CTRDGi_WriteFlashSectorLE(u16 secNo, u8 *src)
376 {
377 u16 result;
378 CTRDGTaskInfo p;
379 p.sec_num = secNo;
380 p.data = src;
381 result = (u16)CTRDGi_WriteFlashSectorCoreLE(&p);
382
383 return result;
384 }
385
CTRDGi_EraseFlashChipAsyncLE(CTRDG_TASK_FUNC callback)386 void CTRDGi_EraseFlashChipAsyncLE(CTRDG_TASK_FUNC callback)
387 {
388 CTRDGTaskInfo p;
389
390 CTRDGi_SetTask(&p, CTRDGi_EraseFlashChipCoreLE, callback);
391 }
392
CTRDGi_EraseFlashSectorAsyncLE(u16 secNo,CTRDG_TASK_FUNC callback)393 void CTRDGi_EraseFlashSectorAsyncLE(u16 secNo, CTRDG_TASK_FUNC callback)
394 {
395 CTRDGTaskInfo p;
396
397 p.sec_num = secNo;
398 CTRDGi_SetTask(&p, CTRDGi_EraseFlashSectorCoreLE, callback);
399 }
400
CTRDGi_WriteFlashSectorAsyncLE(u16 secNo,u8 * src,CTRDG_TASK_FUNC callback)401 void CTRDGi_WriteFlashSectorAsyncLE(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback)
402 {
403 CTRDGTaskInfo p;
404
405 p.sec_num = secNo;
406 p.data = src;
407 CTRDGi_SetTask(&p, CTRDGi_WriteFlashSectorCoreLE, callback);
408 }
409