1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CTRDG - libraries - ARM9
3 File: ctrdg_flash_MX29L010.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 // Extern data declaration----------------------
21 extern u16 CTRDGi_PollingSR1MCOMMON(u16 phase, u8 *adr, u16 lastData);
22
23 // Function's prototype declaration-------------
24 u16 CTRDGi_EraseFlashChipMX(void);
25 u16 CTRDGi_EraseFlashSectorMX(u16 secNo);
26 u16 CTRDGi_WriteFlashSectorMX(u16 secNo, u8 *src);
27
28 u32 CTRDGi_EraseFlashChipCoreMX(CTRDGTaskInfo * arg);
29 u32 CTRDGi_EraseFlashSectorCoreMX(CTRDGTaskInfo * arg);
30 u32 CTRDGi_WriteFlashSectorCoreMX(CTRDGTaskInfo * arg);
31
32 void CTRDGi_EraseFlashChipAsyncMX(CTRDG_TASK_FUNC callback);
33 void CTRDGi_EraseFlashSectorAsyncMX(u16 secNo, CTRDG_TASK_FUNC callback);
34 void CTRDGi_WriteFlashSectorAsyncMX(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback);
35
36 // Const data-----------------------------------
37 static const u16 MxMaxTime[] = {
38 10, // Common 10ms
39 10, // Program 10ms(exactly:20usec)
40 2000, // Sector erase 2s
41 2000, // Chip erase 2s
42 };
43
44 const CTRDGiFlashTypePlus MX29L010 = {
45 CTRDGi_WriteFlashSectorMX,
46 CTRDGi_EraseFlashChipMX,
47 CTRDGi_EraseFlashSectorMX,
48 CTRDGi_WriteFlashSectorAsyncMX,
49 CTRDGi_EraseFlashChipAsyncMX,
50 CTRDGi_EraseFlashSectorAsyncMX,
51 CTRDGi_PollingSR1MCOMMON,
52 MxMaxTime,
53 {
54 /* For debugging */
55 //#ifndef __FLASH_DEBUG
56 0x00020000, // ROM size
57 {0x00001000, 12, 32, 0}, // Sector size, shift, count, top
58 //#else
59 // 0x00004000,
60 // {0x00000200, 9, 32, 0},
61 //#endif
62 {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_8}, // agb read cycle=8, write cycle=3
63 0xc2, // Maker ID
64 0x09, // Device ID
65 },
66 };
67
68 const CTRDGiFlashTypePlus defaultFlash1M = {
69 CTRDGi_WriteFlashSectorMX,
70 CTRDGi_EraseFlashChipMX,
71 CTRDGi_EraseFlashSectorMX,
72 CTRDGi_WriteFlashSectorAsyncMX,
73 CTRDGi_EraseFlashChipAsyncMX,
74 CTRDGi_EraseFlashSectorAsyncMX,
75 CTRDGi_PollingSR1MCOMMON,
76 MxMaxTime,
77 {
78 /* For debugging */
79 //#ifndef __FLASH_DEBUG
80 0x00020000, // ROM size
81 {0x00001000, 12, 32, 0}, // Sector size, shift, count, top
82 //#else
83 // 0x00004000,
84 // {0x00000200, 9, 32, 0},
85 //#endif
86 {MI_CTRDG_RAMCYCLE_18, MI_CTRDG_RAMCYCLE_8}, // agb read cycle=8, write cycle=3
87 0x00, // Maker ID
88 0x00, // Device ID
89 },
90 };
91
92 /*Exclusive control*/
93 extern u16 ctrdgi_flash_lock_id;
94 extern BOOL ctrdgi_backup_irq;
95
96 /*******************************************************
97
98 Function's description
99
100 ********************************************************/
CTRDGi_EraseFlashChipCoreMX(CTRDGTaskInfo * arg)101 u32 CTRDGi_EraseFlashChipCoreMX(CTRDGTaskInfo * arg)
102 {
103 /* For debugging */
104 //#ifdef __FLASH_DEBUG
105 // u32 i;
106 //#endif
107 MICartridgeRamCycle ram_cycle;
108 u32 result;
109 (void)arg;
110
111 /*Exclusive control (lock) */
112 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
113 /*Access cycle settings */
114 ram_cycle = MI_GetCartridgeRamCycle();
115 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
116
117 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
118 ctrdgi_backup_irq = OS_DisableIrq();
119
120 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
121 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
122 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
123 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
124 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
125 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x10;
126 /* For debugging */
127 //#ifdef __FLASH_DEBUG
128 // adr=(u8 *)CTRDG_AGB_FLASH_ADR;
129 // for(i=0;i<AgbFlash->romSize;i++)
130 // *adr++=0xff;
131 //#endif
132 (void)OS_RestoreIrq(ctrdgi_backup_irq);
133
134 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_CHIP_ERASE, (u8 *)CTRDG_AGB_FLASH_ADR, 0xff);
135 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)| 1;
136
137 /*Access cycle settings */
138 MI_SetCartridgeRamCycle(ram_cycle);
139 /*Exclusive control (unlock) */
140 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
141
142 return result;
143 }
144
CTRDGi_EraseFlashSectorCoreMX(CTRDGTaskInfo * arg)145 u32 CTRDGi_EraseFlashSectorCoreMX(CTRDGTaskInfo * arg)
146 {
147 u8 *adr;
148 u16 retry;
149 MICartridgeRamCycle ram_cycle;
150 u32 result;
151 CTRDGTaskInfo p = *arg;
152 u16 secNo = p.sec_num;
153
154 if (secNo >= AgbFlash->sector.count)
155 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
156
157 /*Exclusive control (lock) */
158 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
159 /*Access cycle settings */
160 ram_cycle = MI_GetCartridgeRamCycle();
161 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
162
163 // Bank set
164 CTRDGi_SetFlashBankMx((u16)(secNo >> 4));
165 secNo &= 0x0f;
166
167 retry = 0;
168
169 erase_again:
170 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
171 adr = (u8 *)(CTRDG_AGB_FLASH_ADR + (secNo << AgbFlash->sector.shift));
172 ctrdgi_backup_irq = OS_DisableIrq();
173
174 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
175 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
176 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x80;
177 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
178 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
179 *(vu8 *)adr = 0x30;
180 /* For debugging */
181 //#ifdef __FLASH_DEBUG
182 // for(i=0;i<AgbFlash->sector.size;i++)
183 // *adr++=0xff;
184 // adr=(u8 *)(CTRDG_AGB_FLASH_ADR+(secNo<<AgbFlash->sector.shift));
185 //#endif
186 (void)OS_RestoreIrq(ctrdgi_backup_irq);
187
188 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_SECTOR_ERASE, adr, 0xff);
189 if (((result & (CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_RESULT_Q5TIMEOUT)) != 0) &&
190 (retry == 0))
191 {
192 retry++;
193 goto erase_again;
194 }
195
196 /*Access cycle settings */
197 MI_SetCartridgeRamCycle(ram_cycle);
198 /*Exclusive control (unlock) */
199 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
200
201 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)| 1;
202 return result;
203 }
204
CTRDGi_ProgramFlashByteMX(u8 * src,u8 * dst)205 static u16 CTRDGi_ProgramFlashByteMX(u8 *src, u8 *dst)
206 {
207 u16 result;
208
209 /*Exclusive control (lock) */
210 // OS_LockCartridge(ctrdgi_flash_lock_id);
211
212 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
213 *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
214 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0;
215 *dst = *src;
216
217 result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, *src);
218
219 /*Exclusive control (unlock) */
220 // OS_UnlockCartridge(ctrdgi_flash_lock_id);
221
222 return result;
223 }
224
CTRDGi_WriteFlashSectorCoreMX(CTRDGTaskInfo * arg)225 u32 CTRDGi_WriteFlashSectorCoreMX(CTRDGTaskInfo * arg)
226 {
227 u8 *tgt;
228 //,readFuncBuff[32];
229 MICartridgeRamCycle ram_cycle;
230 u32 result;
231 CTRDGTaskInfo p = *arg;
232 u16 secNo = p.sec_num;
233 u8 *src = p.data;
234
235 if (secNo >= AgbFlash->sector.count)
236 return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK;
237
238 // Erase
239 result = CTRDGi_EraseFlashSectorMX(secNo);
240 if (result)
241 {
242 return result;
243 }
244
245 /*Exclusive control (lock) */
246 (void)OS_LockCartridge(ctrdgi_flash_lock_id);
247 /*Access cycle settings */
248 ram_cycle = MI_GetCartridgeRamCycle();
249 MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]);
250
251 // Program
252
253 // Bank set
254 CTRDGi_SetFlashBankMx((u16)(secNo >> 4));
255 secNo &= 0x0f;
256
257
258 // *(vu16 *)REG_EXMEMCNT_ADDR=(*(vu16 *)REG_EXMEMCNT_ADDR & 0xfffc)|AgbFlash->agbWait[0]; // read 3cycles wait
259 ctrdg_flash_remainder = (u16)AgbFlash->sector.size;
260 tgt = (u8 *)(CTRDG_AGB_FLASH_ADR + (secNo << AgbFlash->sector.shift));
261 ctrdgi_backup_irq = OS_DisableIrq();
262 while (ctrdg_flash_remainder)
263 {
264 result = CTRDGi_ProgramFlashByteMX(src, tgt);
265 if (result)
266 break;
267 ctrdg_flash_remainder--;
268 src++;
269 tgt++;
270 }
271 (void)OS_RestoreIrq(ctrdgi_backup_irq);
272
273 /*Access cycle settings */
274 MI_SetCartridgeRamCycle(ram_cycle);
275 /*Exclusive control (unlock) */
276 (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
277
278 return result;
279 }
280
CTRDGi_EraseFlashChipMX(void)281 u16 CTRDGi_EraseFlashChipMX(void)
282 {
283 u16 result;
284 CTRDGTaskInfo p;
285 result = (u16)CTRDGi_EraseFlashChipCoreMX(&p);
286
287 return result;
288 }
289
CTRDGi_EraseFlashSectorMX(u16 secNo)290 u16 CTRDGi_EraseFlashSectorMX(u16 secNo)
291 {
292 u16 result;
293 CTRDGTaskInfo p;
294 p.sec_num = secNo;
295 result = (u16)CTRDGi_EraseFlashSectorCoreMX(&p);
296
297 return result;
298 }
299
CTRDGi_WriteFlashSectorMX(u16 secNo,u8 * src)300 u16 CTRDGi_WriteFlashSectorMX(u16 secNo, u8 *src)
301 {
302 u16 result;
303 CTRDGTaskInfo p;
304 p.sec_num = secNo;
305 p.data = src;
306 result = (u16)CTRDGi_WriteFlashSectorCoreMX(&p);
307
308 return result;
309 }
310
CTRDGi_EraseFlashChipAsyncMX(CTRDG_TASK_FUNC callback)311 void CTRDGi_EraseFlashChipAsyncMX(CTRDG_TASK_FUNC callback)
312 {
313 CTRDGTaskInfo p;
314
315 CTRDGi_SetTask(&p, CTRDGi_EraseFlashChipCoreMX, callback);
316 }
317
CTRDGi_EraseFlashSectorAsyncMX(u16 secNo,CTRDG_TASK_FUNC callback)318 void CTRDGi_EraseFlashSectorAsyncMX(u16 secNo, CTRDG_TASK_FUNC callback)
319 {
320 CTRDGTaskInfo p;
321
322 p.sec_num = secNo;
323 CTRDGi_SetTask(&p, CTRDGi_EraseFlashSectorCoreMX, callback);
324 }
325
CTRDGi_WriteFlashSectorAsyncMX(u16 secNo,u8 * src,CTRDG_TASK_FUNC callback)326 void CTRDGi_WriteFlashSectorAsyncMX(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback)
327 {
328 CTRDGTaskInfo p;
329
330 p.sec_num = secNo;
331 p.data = src;
332 CTRDGi_SetTask(&p, CTRDGi_WriteFlashSectorCoreMX, callback);
333 }
334