📄 smf_io.c
字号:
/**********
*
* smf_io.c: SmartMedia File System IO part
*
* Portable File System designed for SmartMedia
*
* Created by Kim Hyung Gi (06/99) - kimhg@mmrnd.sec.samsung.co.kr
* Samsung Electronics, M/M R&D Center, Visual Communication Group
*
**********
* Modified by Lee Jin Woo (1999/08/17)
*
**********/
#include "smf_cmn.h"
#include "smf_io.h"
#include "smf_lpt.h"
/**********
* Static Variables
**********/
static bool s_cardInserted[MAX_DRIVE];
static udword s_ioFlag[MAX_DRIVE]; /* IO layer initialization status flag */
static udword s_deviceSize[MAX_DRIVE];
static udword s_pageSize[MAX_DRIVE]; /* page size of the SmartMedia that is inserted */
static ERR_CODE s_smpErr;
/**********
* Global Variables
**********/
ubyte g_mCode[MAX_MI_NUM] = { 0xec, 0x98 };
ubyte g_dCode[MAX_MI_NUM][MAX_DI_NUM][MAX_VI_NUM] = {
/* value from the source code from NVM Product Planning Team (secsm10.c) */
/* MI_SAMSUNG */
{
{ 0x6e, 0x00 }, /* DI_1M */
{ 0xea, 0x64 }, /* DI_2M */
{ 0xe3, 0xe5 }, /* DI_4M */
{ 0xe6, 0x00 }, /* DI_8M */
{ 0x73, 0x00 }, /* DI_16M */
{ 0x75, 0x00 }, /* DI_32M */
{ 0x76, 0x00 }, /* DI_64M */
{ 0x79, 0x00 } /* DI_128M */
},
/* MI_TOSHIBA */
{
{ 0x00, 0x00 }, /* DI_1M */
{ 0xea, 0x64 }, /* DI_2M */
{ 0xe5, 0x6b }, /* DI_4M */
{ 0xe6, 0x00 }, /* DI_8M */
{ 0x73, 0x00 }, /* DI_16M */
{ 0x75, 0x00 }, /* DI_32M */
{ 0x76, 0x00 }, /* DI_64M */
{ 0x79, 0x00 } /* DI_128M */
}
};
/**********/
/* static funtions */
static ERR_CODE sm_IOInit(udword drv_no);
static ERR_CODE sm_PreIO(udword drv_no);
static ERR_CODE sm_PostIO(udword drv_no);
static ERR_CODE sm_StatusCheck(udword drv_no);
static ERR_CODE sm_CheckDevice(udword drv_no);
/**********
* IO API definitions
**********/
SMP_EXPORT ERR_CODE smpFlashWriteSector(udword drv_no, udword sector, const ubyte* p_buf, const ubyte* p_spare)
{
udword addr = sector * SECTOR_SIZE;
s_smpErr = smpFlashWritePage(drv_no, addr, p_buf, p_spare);
if (s_smpErr != SM_OK)
return s_smpErr;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
s_smpErr = smpFlashWritePage(drv_no, addr + PAGE_SIZE_256, p_buf + PAGE_SIZE_256, p_spare + 8);
if (s_smpErr != SM_OK)
return s_smpErr;
}
return SM_OK;
}
SMP_EXPORT ERR_CODE smpFlashReadSector(udword drv_no, udword sector, ubyte* p_buf)
{
udword addr = sector * SECTOR_SIZE;
s_smpErr = smpFlashReadPage(drv_no, addr, p_buf, s_pageSize[drv_no]);
if (s_smpErr != SM_OK)
return s_smpErr;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
s_smpErr = smpFlashReadPage(drv_no, addr + PAGE_SIZE_256, p_buf + PAGE_SIZE_256, PAGE_SIZE_256);
if (s_smpErr != SM_OK)
return s_smpErr;
}
return SM_OK;
}
SMP_EXPORT ERR_CODE smpFlashReadSectorSpare(udword drv_no, udword sector, ubyte* p_buf)
{
udword addr = sector * SECTOR_SIZE;
s_smpErr = smpFlashReadSpare(drv_no, addr, p_buf,
(s_pageSize[drv_no] == PAGE_SIZE_256) ? 8 : 16);
if (s_smpErr != SM_OK)
return s_smpErr;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
s_smpErr = smpFlashReadSpare(drv_no, addr + PAGE_SIZE_256, p_buf + 8, 8);
if (s_smpErr != SM_OK)
return s_smpErr;
}
return SM_OK;
}
/**********
* Function: sm_FlashWritePage
* Notes:
* - write 1 page (maximum)
* - cannot write beyond the page boundary
* - write_size parameter must be given that write ends on the page boundary
* - if status error occurs, it tries one more time
**********/
ERR_CODE smpFlashWritePage(udword drv_no, udword addr, const ubyte* p_buf, const ubyte* p_spare)
{
udword i;
udword addr0, addr1, addr2, addr3;
udword pageSize = s_pageSize[drv_no];
udword spareSize = (pageSize == PAGE_SIZE_256) ? 8 : 16;
s_smpErr = sm_PreIO(drv_no);
if (s_smpErr != SM_OK)
IO_RETURN(drv_no, s_smpErr);
SM_CHIP_EN(drv_no);
SM_CLE_EN(drv_no);
SM_WRITE_EN(drv_no);
SM_WRITE_CMD(drv_no, RESET_PTR_CMD);
SM_WRITE_CMD(drv_no, SEQ_DATA_INPUT_CMD);
SM_WRITE_DIS(drv_no);
SM_CLE_DIS(drv_no);
SM_ALE_EN(drv_no);
addr0 = addr & 0xff;
if (pageSize == PAGE_SIZE_256)
{
addr1 = (addr >> 8) & 0xff;
addr2 = (addr >> 16) & 0xff;
}
else
{
addr1 = (addr >> 9) & 0xff;
addr2 = (addr >> 17) & 0xff;
addr3 = (addr >> 25) & 0x7f;
}
SM_WRITE_EN(drv_no);
SM_WRITE_ADDR(drv_no, addr0);
SM_WRITE_ADDR(drv_no, addr1);
SM_WRITE_ADDR(drv_no, addr2);
if (s_deviceSize[drv_no] >= DI_64M)
{
SM_WRITE_ADDR(drv_no, addr3);
}
SM_WRITE_DIS(drv_no);
SM_ALE_DIS(drv_no);
SM_WRITE_EN(drv_no);
for (i = 0; i < pageSize; ++i, ++p_buf)
{
SM_WRITE_DATA(drv_no, *p_buf);
}
for (i = 0; i < spareSize; ++i, ++p_spare)
{
SM_WRITE_DATA(drv_no, *p_spare);
}
SM_WRITE_DIS(drv_no);
SM_CLE_EN(drv_no);
SM_WRITE_EN(drv_no);
SM_WRITE_CMD(drv_no, PAGE_PROGRAM_CMD);
SM_WRITE_DIS(drv_no);
SM_CLE_DIS(drv_no);
s_smpErr = sm_StatusCheck(drv_no);
SM_CHIP_DIS(drv_no);
IO_RETURN(drv_no, s_smpErr);
}
/**********
* Function: smpFlashReadPage
* Notes:
* - read 1 page (maximum)
* - cannot read beyond the page boundary
**********/
SMP_EXPORT ERR_CODE smpFlashReadPage(udword drv_no, udword addr, ubyte* p_buf, udword read_size)
{
udword i;
udword addr0, addr1, addr2, addr3;
s_smpErr = sm_PreIO(drv_no);
if (s_smpErr != SM_OK)
IO_RETURN(drv_no, s_smpErr);
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
if (read_size > 264 - (addr & 0xff))
IO_RETURN(drv_no, ERR_INVALID_PARAM);
}
else {
if (read_size > 528 - (addr & 0xff))
IO_RETURN(drv_no, ERR_INVALID_PARAM);
}
SM_CHIP_EN(drv_no);
SM_CLE_EN(drv_no);
SM_WRITE_EN(drv_no);
SM_WRITE_CMD(drv_no, READ1_CMD);
SM_WRITE_DIS(drv_no);
SM_CLE_DIS(drv_no);
SM_ALE_EN(drv_no);
addr0 = addr & 0xff;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
addr1 = (addr >> 8) & 0xff;
addr2 = (addr >> 16) & 0xff;
}
else
{
addr1 = (addr >> 9) & 0xff;
addr2 = (addr >> 17) & 0xff;
addr3 = (addr >> 25) & 0x7f;
}
SM_WRITE_EN(drv_no);
SM_WRITE_ADDR(drv_no, addr0);
SM_WRITE_ADDR(drv_no, addr1);
SM_WRITE_ADDR(drv_no, addr2);
if (s_deviceSize[drv_no] >= DI_64M)
{
SM_WRITE_ADDR(drv_no, addr3);
}
SM_WRITE_DIS(drv_no);
SM_ALE_DIS(drv_no);
SM_WAIT_TR(drv_no);
SM_READ_EN(drv_no);
for (i = 0; i < read_size; ++i, ++p_buf)
{
*p_buf = SM_READ_DATA(drv_no);
}
SM_READ_DIS(drv_no);
SM_CHIP_DIS(drv_no);
SM_WAIT_TR(drv_no);
IO_RETURN(drv_no, s_smpErr);
}
/**********
* Function: smpFlashReadPage2
* Remarks:
* - read from the second half page
* Notes:
* - cannot read beyond the page boundary
**********/
SMP_EXPORT ERR_CODE smpFlashReadPage2(udword drv_no, udword addr, ubyte* p_buf, udword read_size)
{
udword i;
udword addr0, addr1, addr2, addr3;
s_smpErr = sm_PreIO(drv_no);
if (s_smpErr != SM_OK)
IO_RETURN(drv_no, s_smpErr);
if (s_pageSize[drv_no] == PAGE_SIZE_256)
IO_RETURN(drv_no, ERR_INVALID_PARAM);
else
{
if (read_size > 264 - (addr & 0xff))
IO_RETURN(drv_no, ERR_INVALID_PARAM);
}
SM_CHIP_EN(drv_no);
SM_CLE_EN(drv_no);
SM_WRITE_EN(drv_no);
SM_WRITE_CMD(drv_no, READ1_1_CMD);
SM_WRITE_DIS(drv_no);
SM_CLE_DIS(drv_no);
SM_ALE_EN(drv_no);
addr0 = addr & 0xff;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
addr1 = (addr >> 8) & 0xff;
addr2 = (addr >> 16) & 0xff;
}
else
{
addr1 = (addr >> 9) & 0xff;
addr2 = (addr >> 17) & 0xff;
addr3 = (addr >> 25) & 0x7f;
}
SM_WRITE_EN(drv_no);
SM_WRITE_ADDR(drv_no, addr0);
SM_WRITE_ADDR(drv_no, addr1);
SM_WRITE_ADDR(drv_no, addr2);
if (s_deviceSize[drv_no] >= DI_64M)
{
SM_WRITE_ADDR(drv_no, addr3);
}
SM_WRITE_DIS(drv_no);
SM_ALE_DIS(drv_no);
SM_WAIT_TR(drv_no);
SM_READ_EN(drv_no);
for (i = 0; i < read_size; ++i, ++p_buf)
{
*p_buf = SM_READ_DATA(drv_no);
}
SM_READ_DIS(drv_no);
SM_CHIP_DIS(drv_no);
SM_WAIT_TR(drv_no);
IO_RETURN(drv_no, s_smpErr);
}
/**********
* Function: smpFlashReadSpare
* Remarks:
* - read from the spare part of the page
* Notes:
* - 8 or 16 bytes maximum
* - cannot read beyond the page boundary
**********/
SMP_EXPORT ERR_CODE smpFlashReadSpare(udword drv_no, udword addr, ubyte* p_buf, udword read_size)
{
udword i;
udword addr0, addr1, addr2, addr3;
s_smpErr = sm_PreIO(drv_no);
if (s_smpErr != SM_OK)
IO_RETURN(drv_no, s_smpErr);
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
if (read_size > 8 - (addr & 0x07))
IO_RETURN(drv_no, ERR_INVALID_PARAM);
}
else
{
if (read_size > 16 - (addr & 0x0f))
IO_RETURN(drv_no, ERR_INVALID_PARAM);
}
SM_CHIP_EN(drv_no);
SM_CLE_EN(drv_no);
SM_WRITE_EN(drv_no);
SM_WRITE_CMD(drv_no, READ2_CMD);
SM_WRITE_DIS(drv_no);
SM_CLE_DIS(drv_no);
SM_ALE_EN(drv_no);
addr0 = addr & 0xff;
if (s_pageSize[drv_no] == PAGE_SIZE_256)
{
addr1 = (addr >> 8) & 0xff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -