9/27 少しコードを直しました。
・書き込みコマンドにnopは必要みたいです。ない場合はうまくいきませんでした。
・EWRAMで作りましたけどIWRAMだとウェイトでうまくいかないかもしれません(特にnop部分)。
ID取得に0xffが帰ってきたらもっとウェイトが必要です。
・セーブ個数はセクタ単位(0x0 - 0xf)なので1+15個(フラグ管理+しおり)が妥当のようです。
・1セクタ0x1000バイト。容量多くて助かります。
・REG_WSCNT = 0x4317(8 cycles)
・データーシート http://ww1.microchip.com/downloads/en/DeviceDoc/20005023B.pdf
宿題ようやく終わりました・・・たぶん。
#include "flash.h" #include "libmy/bg.h" //--------------------------------------------------------------------------- EWRAM_CODE void FlashInit(void) { BgDrawScreen(); BgDrawStrCls(); BgDrawStr(0, 0, "MemoryBackupCubic Test"); } //--------------------------------------------------------------------------- EWRAM_CODE void FlashExec(void) { if(FlashIsExist() == FALSE) { for(;;){} } BgDrawPrintf(2, 1, "Type : Flash"); BgDrawPrintf(2, 2, "Id : %x", FlashGetId()); BgDrawPrintf(2, 4, "Erase 0, 1, 2"); FlashEraseSector(0); FlashEraseSector(1); FlashEraseSector(2); FlashByte(0x0000, 1); FlashByte(0x0001, 2); FlashByte(0x0002, 3); FlashByte(0x1000, 4); FlashByte(0x1001, 5); FlashByte(0x1002, 6); FlashByte(0x2000, 7); FlashByte(0x2001, 8); FlashByte(0x2002, 9); BgDrawPrintf(3, 5, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002)); BgDrawPrintf(3, 6, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002)); BgDrawPrintf(3, 7, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002)); BgDrawPrintf(2, 8, "Erase 1"); FlashEraseSector(1); BgDrawPrintf(3, 9, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002)); BgDrawPrintf(3, 10, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002)); BgDrawPrintf(3, 11, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002)); BgDrawPrintf(2, 12, "Erase Chip"); FlashEraseChip(); BgDrawPrintf(3, 13, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002)); BgDrawPrintf(3, 14, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002)); BgDrawPrintf(3, 15, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002)); BgDrawPrintf(2, 16, "Done"); } //--------------------------------------------------------------------------- EWRAM_CODE void FlashByte(u16 adr, u8 dat) { // Byte-Program FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0xA0); FlashWrite(adr, dat); FlashWait20us(); } //--------------------------------------------------------------------------- EWRAM_CODE void FlashEraseChip(void) { // Chip-Erase FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0x80); FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0x10); FlashWait100ms(); } //--------------------------------------------------------------------------- EWRAM_CODE void FlashEraseSector(u16 sec) { _ASSERT(sec < 0x10); // Sector-Erase FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0x80); FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(sec * 0x1000, 0x30); FlashWait25ms(); } //--------------------------------------------------------------------------- // SST39VF010 : BF D5 // SST39VF020 : BF D6 // SST39VF040 : BF D7 EWRAM_CODE u16 FlashGetId(void) { // ID Entry FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0x90); // Read ID u8 id0 = FlashRead(0x0000); u8 id1 = FlashRead(0x0001); // ID Exit FlashWrite(0x5555, 0xAA); FlashWrite(0x2AAA, 0x55); FlashWrite(0x5555, 0xF0); return id0 | (id1 << 8); } //--------------------------------------------------------------------------- EWRAM_CODE void FlashWrite(u16 adr, u8 cmd) { u8* p = (u8*)SRAM + adr; *p = cmd; __asm("NOP"); } //--------------------------------------------------------------------------- EWRAM_CODE u8 FlashRead(u16 adr) { u8* p = (u8*)SRAM + adr; u8 ret = *p; return ret; } //--------------------------------------------------------------------------- EWRAM_CODE void FlashWait20us(void) { for(vu32 i=0; i<400; i++) { // 1週 大雑把に0.0625us(1clk = 16Mhz) __asm("NOP"); } } //--------------------------------------------------------------------------- EWRAM_CODE void FlashWait25ms(void) { for(vu32 i=0; i<3; i++) { // 1週 16.743ms while(REG_VCOUNT >= 160) {}; while(REG_VCOUNT < 160) {}; } } //--------------------------------------------------------------------------- EWRAM_CODE void FlashWait100ms(void) { for(vu32 i=0; i<10; i++) { // 1週 16.743ms while(REG_VCOUNT >= 160) {}; while(REG_VCOUNT < 160) {}; } } //--------------------------------------------------------------------------- EWRAM_CODE bool FlashIsExist(void) { u8 t1 = FlashRead(0x7FFF); u8 t2 = ~t1; FlashWrite(0x7FFF, t2); if(FlashRead(0x7FFF) != t2) { FlashWrite(0x7FFF, t1); return TRUE; } return FALSE; }
さらに追記:
リハビリ14 - GBAプログラミング跡地