summaryrefslogtreecommitdiff
path: root/src/agb_flash_1m.c
diff options
context:
space:
mode:
authorsceptillion <33798691+sceptillion@users.noreply.github.com>2017-12-10 22:41:46 -0800
committersceptillion <33798691+sceptillion@users.noreply.github.com>2017-12-10 22:41:46 -0800
commitd07afbc0818370f03ef840419e0bf4f654753ab8 (patch)
tree979a30ff1aa62e4135918eed8b57868571a799a2 /src/agb_flash_1m.c
initial commit
Diffstat (limited to 'src/agb_flash_1m.c')
-rw-r--r--src/agb_flash_1m.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/agb_flash_1m.c b/src/agb_flash_1m.c
new file mode 100644
index 0000000..85ee0a2
--- /dev/null
+++ b/src/agb_flash_1m.c
@@ -0,0 +1,85 @@
+#include "gba/gba.h"
+#include "gba/flash_internal.h"
+
+static const char AgbLibFlashVersion[] = "FLASH1M_V102";
+
+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++;
+ }
+
+ 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;
+}