あーさん日記

https://akkera102.sakura.ne.jp/gbadev/ の中の人

FLASH(SST39VF040)メモ

9/27 少しコードを直しました。
f:id:akkera102:20180925224857p:plain
・書き込みコマンドに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プログラミング跡地