앞에서의 플래시 문서를 포함한 전체적인 플래시의 내용을 정리한 문서이다.
데이터 시트가 왜 필요한지 의문을 가질지도 모르겠다. 하지만, 정말 중요하다. 데이터 시트에는 플래시의 동작과 커맨드, Manufactuer Code 등 많은 정보를 가지고 있다.
또한 이 것을 보고, 현재 쓰고 있는 플래시의 방식이 top 또는 bottom 인지 알아야 한다. 아래 표의 정보를 데이터 시트를 통해 알 수 있다.
| 모델명 | M29W160ET(T는 top 방식을 뜻함) |
| 배속 | X16(16bit access) |
| Manufacturer Code | 0020h |
| Device Code | 22C4h |
위의 모델명을 참고하여, top 방식의 블럭을 설정하면 된다. 또한 우리는 16bit access 를 한다. 기본적으로 8bit 도 지원하지만, CPU 칩 회로도 상 불가능하다. Manufacturer, Device Code 는 플래시 테스트 프로그램을 통해서 확인할 수 있다. 데이터 시트에 나온 커맨드(명령을) 특정 번지에 넣어주면, 읽을 수 있다. 이를 통해 초기 플래시 디버깅도 가능하다.
이제 플래시를 read/write 하는 프로그램을 통해 확인해보자!!
일단 가장 기본이 되는 main.c 부터 살펴보자!!
U8 temp[20]; // 플래시에 넣을 Data 를 배열로 정의 temp[0] = 't'; // test 를 data 에 입력 temp[1] = 'e'; temp[2] = 's'; temp[3] = 't'; FLASH_Initx(); // 플래시 디바이스 초기화 FLASH_Open(); // 디바이스 열기 WriteBlock(1, temp, 4); // 1번 블럭에 'test' 를 4 만큼 쓴다.
위의 설명을 봐도 그렇지만, 어떤 디바이스를 사용하려면, 우선 초기화(init) 하고 열기(open)를 해주어야 한다. 이 동작이 끝나면, 이제 사용할 준비가 끝난 것이다. 그리고 나서, 플래시를 읽고 쓸수 있다. 위에서 선언해준 배열은 플래시에 쓸 데이터이다. 여기서는 'test' 라는 문자를 넣었다.
이제 위에서 호출한 함수들을 하나하나 살펴보자!!
ST_ErrorCode_t FLASH_Initx()
{
ST_ErrorCode_t ErrCode;
STFLASH_InitParams_t InitParams;
// partition_init_heap( &TheSystemPartition, (U8 *)SystemMemory, sizeof(SystemMemory));
printf("Start flash init!\n");
InitParams.DeviceType = DEVICE_TYPE; // STFLASH_M29W160BT
// if ( BankNum == BANK0 )
// {
InitParams.BaseAddress = (U32*)0x7f800000;//STFLASH_BANK_0_BASE; 시작 주소
InitParams.VppAddress = (U32*)NULL;
// }
InitParams.MinAccessWidth = MIN_ACCESS_WIDTH; // 16bit
InitParams.MaxAccessWidth = MAX_ACCESS_WIDTH; // 16bit
InitParams.NumberOfBlocks = NUM_BLOCKS;
InitParams.Blocks = BlockData_s; // 35
InitParams.DriverPartition = SystemPartition;
ErrCode = STFLASH_Init(FLASHDeviceName[0], &InitParams ); // ST 에서 제공하는 함수 호출
if(ErrCode!=ST_NO_ERROR)
{
printf("Init Error!\n");
return (ErrCode);
}
else
printf("Flash init sucess!\n");
STTBX_Print(("STFLASH_Init(%s)=%s\n", FLASHDeviceName[0], GetErrorText(ErrCode) ));
return ( ErrCode );
} /* end FLASH_Init */
ST_ErrorCode_t FLASH_Open()
{
ST_ErrorCode_t ErrCode;
STFLASH_OpenParams_t OpenParams;
ErrCode = STFLASH_Open(FLASHDeviceName[0], &OpenParams, &FLASHHnd); // ST 에서 제공하는 함수 호출
STTBX_Print(("STFLASH_Open(%s)=%s\n", FLASHDeviceName[0], GetErrorText(ErrCode) ));
if(ErrCode!=ST_NO_ERROR)
{
GeneralError(ErrCode);
printf("Open Error!\n");
return (ErrCode);
}
return ( ErrCode );
} /* end FLASH_Open */
BOOL WriteBlock(U8 blockId, U8* data, U32 len) // 몇 번째 블럭인지, 배열단위의 데이터, 길이
{
ST_ErrorCode_t errCode;
U32 uWriteLen,re;
errCode = STFLASH_Erase( FLASHHnd, // ST 에서 제공한 지우는 함수
0+(0x00010000*blockId), // 위의 블럭 단위로 되어 있다.
0x00010000);
if(errCode!=ST_NO_ERROR)
{
GeneralError(errCode);
printf("\nRease Error!\n");
return false;
}
else
printf("Rease Sucess Block %d\n",blockId);
errCode = STFLASH_Write( FLASHHnd, // ST 에서 제공하는 쓰는 함수
0+(0x00010000*blockId), // 블럭 단위
data,
len,
&uWriteLen );
if(errCode!=ST_NO_ERROR)
{
GeneralError(errCode);
printf("Write Error!\n");
return false;
}
else
printf("Write Sucess Block %d adress %x offset %x size %d\n",blockId,0x7fe00000+(0x00010000*blockId),0x00010000*blockId,uWriteLen);
for(re=0;re<len;re++)
printf("%x ",data[re]);
printf("\n\n");
return true;
}
위의 프로그램에서 볼 수 있듯이, 플래시는 블럭(block)단위로 access 한다. 그리고 반드시 write 하기 전에는 해당 블럭을 erase 한다. 내가 예전에 쓰던 프로그램은 직접 주소를 넣어서 write 하는 프로그램이다. 그 직접 주소를 넣을 때는 블럭의 맨 처음 주소를 넣어야 한다.
STFLASH_Block_t BlockData_s[NUM_BLOCKS] =
{ { 0x00010000, STFLASH_MAIN_BLOCK },/* 0 */
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },
{ 0x00010000, STFLASH_MAIN_BLOCK },/*64k*/
{ 0x00008000, STFLASH_MAIN_BLOCK },/* 32k*/
{ 0x00002000, STFLASH_PARAMETER_BLOCK },
{ 0x00002000, STFLASH_PARAMETER_BLOCK },/*8k*/
{ 0x00004000, STFLASH_BOOT_BLOCK } }; /* 16k */ /*34*/