diff options
author | Marcus Huderle <huderlem@gmail.com> | 2017-11-11 15:42:40 -0800 |
---|---|---|
committer | Marcus Huderle <huderlem@gmail.com> | 2017-11-11 16:06:44 -0800 |
commit | 267ada5ce6e2876c4df64275da9ee879a385c6f6 (patch) | |
tree | 559417726bbd5f3b18c153c1435f872decfe18b1 /src/libs/agb_flash_1m.c | |
parent | 20d00c58ef49fa88533fa07ab1801c381f02b7bf (diff) | |
parent | 67ad331441f29545b84d152cbbb4f188098a9c5a (diff) |
Merge remote-tracking branch 'upstream/master' into 80c
Diffstat (limited to 'src/libs/agb_flash_1m.c')
-rw-r--r-- | src/libs/agb_flash_1m.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/libs/agb_flash_1m.c b/src/libs/agb_flash_1m.c new file mode 100644 index 000000000..e249fab9a --- /dev/null +++ b/src/libs/agb_flash_1m.c @@ -0,0 +1,86 @@ +#include "gba/gba.h" +#include "gba/flash_internal.h" + +static const char AgbLibFlashVersion[] = "FLASH1M_V103"; + +const struct FlashSetupInfo * const sSetupInfos[] = +{ + &MX29L010, + &LE26FV10N1TS, + &DefaultFlash +}; + +u16 IdentifyFlash(void) +{ + u16 result; + u16 flashId; + const struct FlashSetupInfo * const *setupInfo; + + REG_WAITCNT = (REG_WAITCNT & ~WAITCNT_SRAM_MASK) | WAITCNT_SRAM_8; + + flashId = ReadFlashId(); + + setupInfo = sSetupInfos; + result = 1; + + for (;;) + { + if ((*setupInfo)->type.ids.separate.makerId == 0) + break; + + if (flashId == (*setupInfo)->type.ids.joined) + { + result = 0; + break; + } + + setupInfo++; + } + + ProgramFlashByte = (*setupInfo)->programFlashByte; + ProgramFlashSector = (*setupInfo)->programFlashSector; + EraseFlashChip = (*setupInfo)->eraseFlashChip; + EraseFlashSector = (*setupInfo)->eraseFlashSector; + WaitForFlashWrite = (*setupInfo)->WaitForFlashWrite; + gFlashMaxTime = (*setupInfo)->maxTime; + gFlash = &(*setupInfo)->type; + + return result; +} + +u16 WaitForFlashWrite_Common(u8 phase, u8 *addr, u8 lastData) +{ + u16 result = 0; + u8 status; + + StartFlashTimer(phase); + + while ((status = PollFlashStatus(addr)) != lastData) + { + if (status & 0x20) + { + // The write operation exceeded the flash chip's time limit. + + if (PollFlashStatus(addr) == lastData) + break; + + FLASH_WRITE(0x5555, 0xF0); + result = phase | 0xA000u; + break; + } + + if (gFlashTimeoutFlag) + { + if (PollFlashStatus(addr) == lastData) + break; + + FLASH_WRITE(0x5555, 0xF0); + result = phase | 0xC000u; + break; + } + } + + StopFlashTimer(); + + return result; +} |