diff options
author | red031000 <rubenru09@aol.com> | 2021-03-09 12:13:21 +0000 |
---|---|---|
committer | red031000 <rubenru09@aol.com> | 2021-03-09 12:13:21 +0000 |
commit | 90f970b74f78ab06162063f1d2b68ee45c7bdf71 (patch) | |
tree | d4786da709936f45d2f17251c254a68d20837ddd /arm9/lib/src | |
parent | acbce1c8be2370e6617cdc74eb658f3f5cf8e1ed (diff) |
finish CTRDG_flash_AT29LV512
Diffstat (limited to 'arm9/lib/src')
-rw-r--r-- | arm9/lib/src/CTRDG_flash_AT29LV512.c | 208 |
1 files changed, 196 insertions, 12 deletions
diff --git a/arm9/lib/src/CTRDG_flash_AT29LV512.c b/arm9/lib/src/CTRDG_flash_AT29LV512.c index 8cd90c31..b1d09738 100644 --- a/arm9/lib/src/CTRDG_flash_AT29LV512.c +++ b/arm9/lib/src/CTRDG_flash_AT29LV512.c @@ -9,22 +9,16 @@ #define CTRDG_BACKUP_COM_ADR1 (CTRDG_AGB_FLASH_ADR+0x00005555) #define CTRDG_BACKUP_COM_ADR2 (CTRDG_AGB_FLASH_ADR+0x00002aaa) +#define FLASH_LOG_SECTOR_COUNT 16 +#define FLASH_SECTOR_LOG_TO_PHYS 32 +#define FLASH_SECTOR_LOG_TO_PHYS_SHIFT 5 + extern u16 ctrdgi_flash_lock_id; extern BOOL ctrdgi_backup_irq; -extern u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData); - -extern u16 CTRDGi_EraseFlashChipAT(void); -extern u16 CTRDGi_EraseFlashSectorAT(u16 p_secNo); -extern u16 CTRDGi_EraseFlash4KBAT(u16 l_secNo); -extern u16 CTRDGi_WriteFlashSectorAT(u16 p_secNo, u8 *src); -extern u16 CTRDGi_WriteFlash4KBAT(u16 l_secNo, u8 *src); +extern void CTRDGi_SetTask(CTRDGTaskInfo * pt, CTRDG_TASK_FUNC task, CTRDG_TASK_FUNC callback); -extern void CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback); -extern void CTRDGi_EraseFlash4KBAsyncAT(u16 secNo, CTRDG_TASK_FUNC callback); -extern void CTRDGi_WriteFlash4KBAsyncAT(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback); -extern void CTRDGi_EraseFlashSectorAsyncAT(u16 secNo, CTRDG_TASK_FUNC callback); -extern void CTRDGi_WriteFlashSectorAsyncAT(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback); +extern u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData); static const u16 atMaxTime[] = { 10, 40, 0, 40 @@ -141,3 +135,193 @@ ARM_FUNC u32 CTRDGi_EraseFlashSectorCoreAT(CTRDGTaskInfo *arg) return result; } + +ARM_FUNC u32 CTRDGi_EraseFlash4KBCoreAT(CTRDGTaskInfo *arg) +{ + u32 result; + u16 i, p_secNo, retry; + CTRDGTaskInfo p = *arg; + u16 l_secNo = p.sec_num; + + if (l_secNo >= FLASH_LOG_SECTOR_COUNT) + { + return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK; + } + + p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT); + for (i = 0; i < FLASH_SECTOR_LOG_TO_PHYS; i++) + { + for (retry = 2; retry > 0; retry--) + { + result = CTRDGi_EraseFlashSectorAT(p_secNo); + if (result == 0) + { + break; + } + } + p_secNo++; + if (result) + { + break; + } + } + + return result; +} + +ARM_FUNC u32 CTRDGi_WriteFlashSectorCoreAT(CTRDGTaskInfo *arg) +{ + u32 i; + u8 *dst; + BOOL shlet_ime; + MICartridgeRamCycle ram_cycle; + u32 result; + CTRDGTaskInfo p = *arg; + u16 p_secNo = p.sec_num; + u8 *src = p.data; + + (void)OS_LockCartridge(ctrdgi_flash_lock_id); + + ram_cycle = MI_GetCartridgeRamCycle(); + MI_SetCartridgeRamCycle(AgbFlash->agbWait[0]); + + dst = (u8 *)(CTRDG_AGB_FLASH_ADR + (p_secNo << AT29LV512_org.type.sector.shift)); + + shlet_ime = OS_DisableIrq(); + + *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa; + *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55; + *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xa0; + + for (i = AT29LV512_org.type.sector.size; i > 0; i--) + { + *dst++ = *src++; + } + dst--; + src--; + + (void)OS_RestoreIrq(shlet_ime); + + result = CTRDGi_PollingSR(CTRDG_BACKUP_PHASE_PROGRAM, dst, *src); + + MI_SetCartridgeRamCycle(ram_cycle); + + (void)OS_UnlockCartridge(ctrdgi_flash_lock_id); + + return result; +} + +ARM_FUNC u32 CTRDGi_WriteFlash4KBCoreAT(CTRDGTaskInfo *arg) +{ + u32 result; + u16 p_secNo, retry; + CTRDGTaskInfo p = *arg; + u16 l_secNo = p.sec_num; + u8 *src = p.data; + + if (l_secNo >= FLASH_LOG_SECTOR_COUNT) + { + return CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_PHASE_PARAMETER_CHECK; + } + + p_secNo = (u16)(l_secNo << FLASH_SECTOR_LOG_TO_PHYS_SHIFT); + ctrdg_flash_remainder = (u16)(AT29LV512_lib.type.sector.size); + while (ctrdg_flash_remainder) + { + for (retry = 2; retry > 0; retry--) + { + result = CTRDGi_WriteFlashSectorAT(p_secNo, src); + if (result == 0) + { + break; + } + } + if (result) + { + break; + } + ctrdg_flash_remainder -= AT29LV512_org.type.sector.size; + src += AT29LV512_org.type.sector.size; + p_secNo++; + } + + return result; +} + +ARM_FUNC u16 CTRDGi_EraseFlashChipAT(void) +{ + CTRDGTaskInfo p; + return (u16)CTRDGi_EraseFlashChipCoreAT(&p); +} + +ARM_FUNC u16 CTRDGi_EraseFlash4KBAT(u16 l_secNo) +{ + CTRDGTaskInfo p; + p.sec_num = l_secNo; + return (u16)CTRDGi_EraseFlash4KBCoreAT(&p); +} + +ARM_FUNC u16 CTRDGi_WriteFlash4KBAT(u16 l_secNo, u8 *src) +{ + CTRDGTaskInfo p; + p.sec_num = l_secNo; + p.data = src; + return (u16)CTRDGi_WriteFlash4KBCoreAT(&p); +} + +ARM_FUNC void CTRDGi_EraseFlashChipAsyncAT(CTRDG_TASK_FUNC callback) +{ + CTRDGTaskInfo p; + + CTRDGi_SetTask(&p, CTRDGi_EraseFlashChipCoreAT, callback); +} + +ARM_FUNC void CTRDGi_EraseFlash4KBAsyncAT(u16 l_secNo, CTRDG_TASK_FUNC callback) +{ + CTRDGTaskInfo p; + + p.sec_num = l_secNo; + CTRDGi_SetTask(&p, CTRDGi_EraseFlash4KBCoreAT, callback); +} + +ARM_FUNC void CTRDGi_WriteFlash4KBAsyncAT(u16 l_secNo, u8 *src, CTRDG_TASK_FUNC callback) +{ + CTRDGTaskInfo p; + + p.sec_num = l_secNo; + p.data = src; + CTRDGi_SetTask(&p, CTRDGi_WriteFlash4KBCoreAT, callback); +} + +ARM_FUNC u16 CTRDGi_EraseFlashSectorAT(u16 p_secNo) +{ + CTRDGTaskInfo p; + p.sec_num = p_secNo; + return (u16)CTRDGi_EraseFlashSectorCoreAT(&p); +} + +ARM_FUNC u16 CTRDGi_WriteFlashSectorAT(u16 p_secNo, u8 *src) +{ + CTRDGTaskInfo p; + + p.sec_num = p_secNo; + p.data = src; + return (u16)CTRDGi_WriteFlashSectorCoreAT(&p); +} + +ARM_FUNC void CTRDGi_EraseFlashSectorAsyncAT(u16 p_secNo, CTRDG_TASK_FUNC callback) +{ + CTRDGTaskInfo p; + + p.sec_num = p_secNo; + CTRDGi_SetTask(&p, CTRDGi_EraseFlashSectorCoreAT, callback); +} + +ARM_FUNC void CTRDGi_WriteFlashSectorAsyncAT(u16 p_secNo, u8 *src, CTRDG_TASK_FUNC callback) +{ + CTRDGTaskInfo p; + + p.sec_num = p_secNo; + p.data = src; + CTRDGi_SetTask(&p, CTRDGi_WriteFlashSectorCoreAT, callback); +} |