📄 cf.c
字号:
/*
*******************************************************************************
* Magic Pixel
* 5F, No.3, Creation Road III, Science_Based
* Industrial Park, Hsinchu, Taiwan, R.O.C
* (c) Copyright 2004, Magic Pixel Inc, Hsinchu, Taiwan
*
* All rights reserved. Magic Pixel's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code contains
* confidential, trad secret material. Any attempt or participation in
* deciphering, decoding, reverse engineering or in ay way altering the source
* code is strictly prohibited, unless the prior written consent of Magic
* Pixel is obtained.
*
* Filename : cf.c
* Programmer(s) :
* Created :
* Descriptions :
*******************************************************************************
*/
/*
// define this module show debug message or not, 0 : disable, 1 : enable
*/
#define LOCAL_DEBUG_ENABLE 0
/*
// Include section
*/
#include "global612.h"
#include "mpTrace.h"
#include "uti.h"
#include "Mcard.h"
#include "cf.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#if CF_ENABLE //byAlexWang 24jun2007 m2project
/*
// Constant declarations
*/
#define MEMORY_MODE 0x00000000
#define IO_MODE 0x00000004
#define TRUE_IDE_MODE 0x00000008
#define ADR_NORMAL 0x00000000
#define ADR_PRIMARY 0x00000010
#define ADR_SECONDARY 0x00000020
#define WIDTH_8BIT 0x00000040
#define WIDTH_16BIT 0x00000000
#define SINGLE_SECTOR 0x00000000
#define MULTI_SECTOR 0x00000100
#define MULTI_SECTOR_WAIT_EDGE 0x00000000
#define MULTI_SECTOR_WAIT_TIME 0x00000200
#define RESET_ENABLE 0x00010000
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#define MEMORY_SETTING (MEMORY_MODE | ADR_NORMAL | WIDTH_8BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#else
#define MEMORY_SETTING (MEMORY_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#endif
#define TRUE_IDE_SETTING (TRUE_IDE_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR | RESET_ENABLE)
#define IO_SETTING (IO_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#define IC_CD1 0x00000001
#define IC_CD2 0x00000002
#define IC_FRDY 0x00000004
#define IC_FVS1 0x00000008
#define IC_FVS2 0x00000010
#define IC_ACSER 0x00000020
#define IC_CFTCE 0x00000040
#define IC_CFTO 0x00000080
#define IC_CD_ALL (IC_CD1 | IC_CD2)
#define IM_CD1 0x00000100
#define IM_CD2 0x00000200
#define IM_FRDY 0x00000400
#define IM_FVS1 0x00000800
#define IM_FVS2 0x00001000
#define IM_ACSER 0x00002000
#define IM_CFTCE 0x00004000
#define IM_CFTO 0x00008000
#define IM_ALL 0 /*(IM_FRDY | IM_ACSER | IM_CFTCE | IM_CFTO) */
#define PL_HIGH_CD1 0x00010000
#define PL_HIGH_CD2 0x00020000
#define PL_HIGH_FRDY 0x00040000
#define PL_HIGH_FVS1 0x00080000
#define PL_HIGH_FVS2 0x00100000
#define PL_HIGH_ACSER 0x00200000
#define PL_HIGH_CFTCE 0x00400000
#define PL_HIGH_CFTO 0x00800000
#define MD_EDGE_CD1 0x01000000
#define MD_EDGE_CD2 0x02000000
#define MD_EDGE_FRDY 0x04000000
#define MD_EDGE_FVS1 0x08000000
#define MD_EDGE_FVS2 0x10000000
#define MD_EDGE_ACSER 0x20000000
#define MD_EDGE_CFTCE 0x40000000
#define MD_EDGE_CFTO 0x80000000
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
#define GPIO_DEFINE_0 0x00003bff
#define GPIO_DEFINE_1 0x00001ff1
#define GPIO_DEFINE_2 0x00000000
#define H_GPIO_DEFINE_0 0x3bff0000
#define H_GPIO_DEFINE_1 0x1ff10000
#define H_GPIO_DEFINE_2 0x00000000
#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
#define GPIO_DEFINE_0 0x00003bff
#define GPIO_DEFINE_1 0x00000fd0 // rick for backlight(FGPIO 28 FREG) not be affect by CF
#define GPIO_DEFINE_2 0x00000000
#define H_GPIO_DEFINE_0 0x3bff0000
#define H_GPIO_DEFINE_1 0x0fd00000 // rick for backlight(FGPIO 28 FREG) not be affect by CF
#define H_GPIO_DEFINE_2 0x00000000
#endif
#else
#define GPIO_DEFINE_0 0x0000ffff
#define GPIO_DEFINE_1 0x0000ffff
#define GPIO_DEFINE_2 0x0000007f
#define H_GPIO_DEFINE_0 0xffff0000
#define H_GPIO_DEFINE_1 0xffff0000
#define H_GPIO_DEFINE_2 0x007f0000
#endif
#define MEMORY_READ_TIMMING1 0x02020701 // for video play lag but command may fail when mmc plug out
#define MEMORY_READ_TIMMING 0x04020702
#define MEMORY_WRITE_TIMMING 0x04030d02
#define IDE_READ_TIMMING 0x02010804
#define IDE_WRITE_TIMMING 0x02010804
#define I_O_READ_TIMMING 0x00010201
#define I_O_WRITE_TIMMING 0x00010201
#define INITIAL_MEMORY 0x0
#define INITIAL_TRUE_IDE 0x1
#define INITIAL_IO 0x2
#define COMMAND_IDENTIFY_DRIVE 0xec
#define COMMAND_READ_SECTOR 0x20
#define COMMAND_WRITE_SECTOR 0x30
#define COMMAND_TOTAL 0x03
#define DRIVE_PROPERTY 0xe0
#define IDENTIFY_ID 0x848a
#define ERR 0x01
#define CORR 0x04
#define DRQ 0x08
#define DSC 0x10
#define DWF 0x20
#define RDY 0x40
#define BUSY 0x80
#define TIMEOUT_COUNT 1200000
#define CF_CLOCK 0x1
///
///@defgroup CF CompactFlash
///@ingroup CONSTANT
///@{
/// Wait for CompactFlash's ready signal fail.
#define TIMEOUT -2
/// Wait for FIFO transaction end Fail.
#define IC_SFTCE_TIMEOUT -3
/// Wait for DMA end Fail.
#define DMA_TIMEOUT -4
///@}
/*
// Variable declarations
*/
static BYTE bDescriptor[2] = "CF";
static volatile BOOL blTimeOutFlag;
#pragma alignvar(4)
/*
// Macro declarations
*/
//#define CF_TIMEOUT_HANDLE
//#define CF_TASK_YIELD
#ifdef CF_TASK_YIELD
#define TASK_YIELD() TaskYield()
#else
#define TASK_YIELD()
#endif
/*
// Static function prototype
*/
static void CommandProcess(void *McardDev);
static SWORD WaitReady(void);
static SWORD CommandReady(void);
static void TimeoutHandle(void);
static SWORD LogicalRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Identify(DWORD * pdwTotalSector);
static SWORD WriteSector(DWORD dwBufferAdress, WORD wSize);
static SWORD ReadSector(DWORD dwBufferAdress, WORD wSize);
static void SetCommand(BYTE bCommand);
static void SetParameter(DWORD dwSectorCount, DWORD dwLogAddr);
static void Select(BYTE bMode);
static void DeSelect(void);
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Format(void);
/*
// Definition of internal functions
*/
void CfInit(ST_MCARD_DEV * sDev)
{
sDev->pbDescriptor = bDescriptor;
sDev->dwLunNum = CF_LUN_NUM;
sDev->wMcardType = CF;
sDev->Flag.Installed = 1;
sDev->CommandProcess = CommandProcess;
}
/*
// Definition of local functions
*/
static void CommandProcess(void *pMcardDev)
{
ST_MCARD_MAIL *sMcardRMail;
register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);
McardSetClock(CF_CLOCK);
sMcardRMail = pDev->sMcardRMail;
Select(INITIAL_MEMORY);
switch (sMcardRMail->wCmd)
{
case INIT_CARD_CMD:
pDev->Flag.Detected = Ui_CheckCfPlugIn();
if (pDev->Flag.Detected)
{
//card in
McardIODelay(0x500);
pDev->Flag.Detected = 1;
if ((pDev->swStatus = Identify(&(pDev->dwCapacity))))
{
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->wSectorSize = 0;
pDev->dwCapacity = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
}
else
{
pDev->wRenewCounter++;
pDev->Flag.ReadOnly = 0;
pDev->Flag.Present = 1;
pDev->wSectorSize = MCARD_SECTOR_SIZE;
McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
}
else
{
//card out
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
break;
case REMOVE_CARD_CMD: //Athena 03.11.2006 seperate card in & out
//card out
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
break;
case READ_PAGE_CMD:
pDev->swStatus =
FlatRead(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case WRITE_PAGE_CMD:
pDev->swStatus =
FlatWrite(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case FORMAT_CMD:
pDev->swStatus = Format();
break;
default:
MP_DEBUG1("-E- INVALID CMD %d", sMcardRMail->wCmd);
break;
}
DeSelect();
}
//==========================================================================
static inline BOOL Polling_CF_Status(void)
{
extern BYTE g_bCfCardFlag;
register MCARD *sMcard;
sMcard = (MCARD *) MCARD_BASE;
#if((CHIP_VER == (CHIP_VER_600 |CHIP_VER_B))||(CHIP_VER == (CHIP_VER_600 | CHIP_VER_C)))
if ((sMcard->McCfIc & 0x1) != 0x1)
#else
if ((sMcard->McCfIc & 0x3) != 0x3)
#endif
{
McardIODelay(10);
#if((CHIP_VER == (CHIP_VER_600 |CHIP_VER_B))||(CHIP_VER == (CHIP_VER_600 | CHIP_VER_C)))
return ((sMcard->McCfIc & 0x1) != 0x1);
#else
return ((sMcard->McCfIc & 0x3) != 0x3);
#endif
}
return 0;
}
static SWORD WaitReady(void)
{
register CFATA *sCfata;
DWORD dwTimeCount;
sCfata = (CFATA *) (MC_CFCOM_BASE);
dwTimeCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>4):TIMEOUT_COUNT;
while (dwTimeCount)
{
if (Polling_CF_Status())
return FAIL;
if (sCfata->StatusCommand == (DSC | RDY))
{
return PASS;
}
dwTimeCount--;
TASK_YIELD();
}
return TIMEOUT;
}
static SWORD CommandReady(void)
{
register CFATA *sCfata;
DWORD dwTimeCount;
sCfata = (CFATA *) (MC_CFCOM_BASE);
dwTimeCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>4):TIMEOUT_COUNT;
while ((sCfata->StatusCommand & (BUSY | DRQ)) != DRQ)
{
if (Polling_CF_Status())
return FAIL;
if (dwTimeCount == 0)
{
MP_DEBUG1("-E- command FAIL (status: %x)", sCfata->StatusCommand);
return TIMEOUT;
}
dwTimeCount--;
TASK_YIELD();
McardIODelay(5);
}
return PASS;
}
static void TimeoutHandle(void)
{
register CHANNEL *sChannel;
sChannel = (CHANNEL *) (DMA_MC_BASE);
sChannel->Control = 0;
DmaIntDis(IM_MCRDDM);
blTimeOutFlag = 1;
TaskWakeup(MCARD_TASK);
}
static SWORD LogicalRead(register DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
register DWORD dwCount, dwTempSectorCount;
register SWORD swRetValue;
register BYTE *pbBuffer;
pbBuffer = (BYTE *) dwBufferAddress;
while (dwSectorCount)
{
if (dwSectorCount >= 256)
{
dwTempSectorCount = 256;
dwCount = 0;
}
else
{
dwTempSectorCount = dwSectorCount;
dwCount = dwSectorCount;
}
//if (Polling_CF_Status())
// return FAIL;
SetParameter(dwCount, dwLogAddr);
SetCommand(COMMAND_READ_SECTOR);
dwCount = dwTempSectorCount;
while (dwCount)
{
//if (Polling_CF_Status())
// return FAIL;
if ((swRetValue = CommandReady()))
{
MP_DEBUG1("-E- Read command FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
{
MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
pbBuffer += MCARD_SECTOR_SIZE;
dwCount--;
}
dwSectorCount = dwSectorCount - dwTempSectorCount;
dwLogAddr = dwLogAddr + dwTempSectorCount;
if ((swRetValue = WaitReady()))
{
MP_DEBUG1("-E- Ready FAIL(swRetValue: %d)", swRetValue);
return swRetValue;
}
}
return PASS;
}
static SWORD LogicalWrite(DWORD dwBufferAddress, volatile DWORD dwSectorCount,
volatile DWORD dwLogAddr)
{
DWORD dwCount, dwTempSectorCount;
SWORD swRetValue;
BYTE *pbBuffer;
pbBuffer = (BYTE *) dwBufferAddress;
while (dwSectorCount)
{
if (Polling_CF_Status())
return FAIL;
if (dwSectorCount >= 256)
{
dwTempSectorCount = 256;
dwCount = 0;
}
else
{
dwTempSectorCount = dwSectorCount;
dwCount = dwSectorCount;
}
SetParameter(dwCount, dwLogAddr);
SetCommand(COMMAND_WRITE_SECTOR);
dwCount = dwTempSectorCount;
while (dwCount)
{
if ((swRetValue = CommandReady()))
{
MP_DEBUG1("-E- Write command FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
if ((swRetValue = WriteSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
{
MP_DEBUG1("-E- DMA Write FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -