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プログラミング跡地