📄 mcp_ctl.c
字号:
/********************************************************************************/
/* */
/* Copyright (C) SEIKO EPSON CORP. 2000 */
/* */
/* File name : smt_ctl.c */
/* This is smart media control driver */
/* */
/* Revision history */
/* 2000.03.16 H.Ogura start */
/* 2002.01.08 A.Saito Append Interrupt disable/enable */
/* processing */
/* 2002.08.05 A.Saito Append Block erase check to each */
/* function */
/* Append function smtEraseChk() */
/* 2003.03.26 A.Saito Modify parameter of smtPageProgram() */
/* Remove definition TIMING_CHG */
/* 2003.04.24 A.Saito Modify Prolix data Read/Write */
/* 2003.06.05 A.Saito Modify Comment */
/* Remove prototype declaration of functions */
/* 2004.03.01 David.ji Rename to mcp_ctl.c support MCP flash */
/********************************************************************************/
/********************************************************************************/
/* The tab size of this file is 4. */
/********************************************************************************/
#include "smt.h"
#include "mcp_ctl.h"
/********************************************************/
/* PROTOTYPE */
/********************************************************/
/********************************************************/
/* GLOBAL */
/********************************************************/
unsigned long mcp_MdaSiz; // Media Size
unsigned char mcp_PatInfo; // Current Patition Info;
unsigned long mcp_offset; // patition offset
typedef struct{
unsigned char patID;
unsigned long patoffset;
}MCP_PATINFO;
typedef struct{
unsigned char bDevice[3];
unsigned long ulSize;
MCP_PATINFO stMCPPatInfo[3]; //3 partition
}MCP_MEDIASIZE;
// Media Size Table
MCP_MEDIASIZE stMCPMdaSiz[2] ={
{ { 0x53, 0x00, 0x00 }, 16, {{0xE3, 0x0}, {0xE3, 0x2000}, {0xE6, 0x4000}}},
{ { 0x55, 0x00, 0x00 }, 32, {{0xE6, 0x0}, {0xE6, 0x4000}, {0x53, 0x8000}}},
};
static unsigned char mcp_EraseFlg = 0;
extern union SMT_PROLIX_BUFF smtProlBuff;
extern unsigned short ulTranBuf[]; // Transfer buffer (char -> short)
/************************************************************************
* mcpCardDetect
* Type : char
* Ret val : Result Code
* 0 ... Not media detect
* 1 ... Media detect
* Argument : None
* Function : Check card detect information
************************************************************************/
char mcpCardDetect(void)
{
return(1); // Card detect signal
}
/************************************************************************
* mcpWriteProtect
* Type : char
* Ret val : Result Code
* 0 ... Not write protect
* 1 ... Write protect
* Argument : None
* Function : Check write protect seal information
************************************************************************/
char mcpWriteProtect(void)
{
// alway return 0
return(0); // Write protect seal signal
}
/************************************************************************
* mcpMediaReset
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : None
* Function : Smart media reset function
************************************************************************/
int mcpMediaReset(void)
{
int iRetVal;
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
MCP_R_WP = SMT_BYTE0; // WP is set up in low
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
*MCP_R_DATAIO = SMT_C_MDRESET; // Reset command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
iRetVal = mcpReadyCheck(SMT_M_MS2CNT(6));
return(iRetVal); // Ready check (6mS) routine is call
}
/************************************************************************
* mcpStatusRead
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned char *pStatus ... Status store buffer
* Function : Smart media status read
************************************************************************/
int mcpStatusRead(unsigned char *pStatus)
{
int iRetVal; // Return Value
iRetVal = SMT_E_SUCCESS; // Initialize return value
smtErrInf.iSmtErr = SMT_E_SUCCESS; // Initialize error structure
if(MCP_R_RB == SMT_BYTE1)
{
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_STSREAD; // Status read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
// SMT_M_INTDISABLE; // Interrupt disable
*(unsigned short *)pStatus = *MCP_R_DATAIO;// Read status information
// SMT_M_INTENABLE; // Interrupt enable
}
else
{
smtErrInf.iSmtErr = SMT_E_STSBUSY; // ERROR : Status busy error !!
iRetVal = SMT_E_FAILURE;
}
return(iRetVal);
}
/************************************************************************
* mcpIdRead
* Type : void
* Ret val : None
* Argument : unsigned char *pbMaker ... Maker code store buffer
* unsigned char *pbDevice ... Device code store buffer
* Function : MCP media ID read command sequence
************************************************************************/
int mcpIdRead(unsigned char *pbMaker, unsigned char *pbDevice)
{
long lLoop1, lLoop2;
unsigned char pTempDevID;
if(mcp_EraseFlg)
{
mcpEraseChk();
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_MIDREAD; // ID read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
MCP_R_ALE = SMT_BYTE1; // ALE is set up in high
*MCP_R_DATAIO = SMT_C_DMYADDR; // Dummy address
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
asm("nop"); // Waited for 200nS
*pbMaker = *MCP_R_DATAIO; // Read maker code
pTempDevID = *MCP_R_DATAIO; // Read device code
for(lLoop1 = 0; lLoop1 < 2; lLoop1++)
{
for(lLoop2 = 0; (lLoop2 < 3)&&(stMCPMdaSiz[lLoop1].bDevice[lLoop2] != 0x00); lLoop2++)
{
if(stMCPMdaSiz[lLoop1].bDevice[lLoop2] == pTempDevID)
{
mcp_MdaSiz = stMCPMdaSiz[lLoop1].ulSize;
*pbDevice= stMCPMdaSiz[lLoop1].stMCPPatInfo[mcp_PatInfo].patID;
mcp_offset = stMCPMdaSiz[lLoop1].stMCPPatInfo[mcp_PatInfo].patoffset;
return;
}
}
}
}
/************************************************************************
* mcpBlockErase
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned long ulMediaSize ... Media size information
* unsigned long ulBlock ... Physical block address
* Function : Block erase command
************************************************************************/
int mcpBlockErase(unsigned long ulBlock)
{
int iRetVal; // Return value
union SMT_STATUS uStatus; // Status code
if(mcp_EraseFlg)
{
mcpEraseChk();
}
ulBlock += mcp_offset;
MCP_R_WP = SMT_BYTE1; // WP is set up in high
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_ERASE_1; // Block erase command (1st)
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
MCP_R_ALE = SMT_BYTE1; // ALE is set up in high
*MCP_R_DATAIO = SMT_M_BYTE(ulBlock, SMT_BYTE0); // Block address
*MCP_R_DATAIO = SMT_M_BYTE(ulBlock, SMT_BYTE1);
if(mcp_MdaSiz > 32)
{
*MCP_R_DATAIO = SMT_M_BYTE(ulBlock, SMT_BYTE2);
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
// SMT_M_INTDISABLE; // Interrupt disable
*MCP_R_DATAIO = SMT_C_ERASE_2; // Block erase command (2st)
// SMT_M_INTENABLE; // Interrupt enable
mcp_EraseFlg = 1; // Block erasing flag set
return(SMT_E_SUCCESS);
}
/************************************************************************
* mcpPageRead
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned char bCommand ... Read command
* unsigned long ulColumn ... Column address
* unsigned long ulPage ... Page address
* char *pBuffer ... Read data buffer
* Function : Page read command
************************************************************************/
int mcpPageRead(unsigned char bCommand, unsigned long ulColumn, unsigned long ulPage, char *pBuffer)
{
int iRetVal; // Return value
int iLoop; // Loop Counter
int iLoopMax; // Loop Max Counter
unsigned long uTimeLoop;
if(mcp_EraseFlg)
{
mcpEraseChk();
}
ulPage += mcp_offset;
if((bCommand != SMT_C_DREAD_1) // Read command check
&& (bCommand != SMT_C_DREAD_3))
{
bCommand = SMT_C_DREAD_1; // >>> DEFAULT = Read(1)
}
//DMA setting
*(volatile unsigned long*)0x48240 = 0x0; // clear DmaReg
*(volatile unsigned short*)0x48240 = SMT_S_DATA/2; // transfer count
*(volatile unsigned char*)0x48243 = 0x80; // dual transfer mode
*(volatile unsigned long*)0x48244 = SMT_R_AREA15; // source address
*(volatile unsigned char*)0x48247 &=0xcf; // 16bits transfer, address fixed
*(volatile unsigned char*)0x48247 |=0x40;
*(volatile unsigned long*)0x48248 = (unsigned long)pBuffer; // dest address
*(volatile unsigned char*)0x4824b &=0x7f; // successive transfer mode, dest inc
*(volatile unsigned char*)0x4824b |=0x70;
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = bCommand; // Read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
MCP_R_ALE = SMT_BYTE1; // ALE is set up in high
*MCP_R_DATAIO = SMT_M_BYTE(ulColumn, SMT_BYTE0); // Column address
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE0); // Page address (LOW)
// if(mcp_MdaSiz <= 32)
// {
// SMT_M_INTDISABLE; // Interrupt disable
// }
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE1); // (HIGH)
if(mcp_MdaSiz > 32)
{
// SMT_M_INTDISABLE; // Interrupt disable
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE2);
}
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
asm("nop");
iRetVal = mcpReadyCheck(SMT_M_US2CNT(100)); // Ready check (100uS) routine is call
if(iRetVal == SMT_E_SUCCESS)
{
// SMT_M_INTENABLE; // Interrupt enable
if(bCommand == SMT_C_DREAD_1) // Set read data count
{
SMT_ECC_RST;
SMT_ECC_EN;
SMT_DMA_ENABLE;
SMT_DMA_TRG;
/* for(iLoop = 0; iLoop < SMT_S_DATA; iLoop+=2)
{
*(unsigned short*)pBuffer = *MCP_R_DATAIO; // Read data area
pBuffer+=2;
}
*/
for(uTimeLoop = 0; uTimeLoop<SMT_M_US2CNT(10); uTimeLoop++)
{
if(!SMT_DMA_FLAG)
break;
}
SMT_ECC_DIS;
// check ECC ready
for(uTimeLoop = 0; uTimeLoop <SMT_M_MS2CNT(5); uTimeLoop++)
{
if(SMT_ECC_RDY)
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -