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