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