📄 sd old.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 : sd.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 "sd.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#include "flagdefine.h"
#if SD_MMC_ENABLE //byAlexWang 24jun2007 m2project
#if (((CHIP_VER & 0xffff0000) == CHIP_VER_600)&&((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600PQFP_2M_SDRAM)))
#define BYTE_MODE
#endif
/*
// Constant declarations
*/
#define HW_SUPPORT_MMC_4_0
#define SDHC_FLAG
#define SD_TYPE 1
#define SDHC_TYPE 2
#define MMC_TYPE 3
#define SDIO_TYPE 4
#define OP_RADTC 0x00000400
#define OP_WADTC 0x00000200
#define OP_NADTC 0x00000100
#define IC_RSPDONE 0x00000001
#define IC_TREND 0x00000002
#define IC_RSPF 0x00000004
#define IC_CRC16F 0x00000008
#define IC_CRC7F 0x00000010
#define IC_PGMF 0x00000020
#define IC_SDTO 0x00000040
#define IC_WXF 0x00000080
#define IM_RSPDONE 0x00000100
#define IM_TREND 0x00000200
#define IM_RSPF 0x00000400
#define IM_CRC16F 0x00000800
#define IM_CRC7F 0x00001000
#define IM_PGMF 0x00002000
#define IM_SDTO 0x00004000
#define IM_WXF 0x00008000
#define IM_ALL 0 /*(IM_RSPDONE | IM_TREND | IM_RSPF | IM_CRC16F | IM_CRC7F | IM_PGMF | IM_SDTO | IM_WXF) */
#define BIG_ENDIAN 0x00000080
#define DISABLE_STOP_BY_CMD_HW 0x00000100
#define FSMBUSY 0x00001000
#define DBUS_1BIT (0x00000000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)
#define DBUS_4BIT (0x00004000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)
#define DBUS_8BIT (0x00008000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)
#define GPIO_DEFINE_0 0x0000ff00
#define GPIO_DEFINE_1 0x00000004
#define GPIO_DEFINE_2 0x00004000
#define GPIO_DEFILE_3 0x00000180
#define WATCHDOG_TIMER 0x003fffff
#define MMC_DEFAULT_ADDR 0x00100000
#ifdef SDHC_FLAG
#define SDHC_CHECK_PATTERN 0xaa
#define NORMAL 1 // 2.7~3.6
#define LOW_VOL 2
#define SDHC_VOLTAGE_SUPPLIED NORMAL
#define HCS 0x40000000
#endif
#define CMD_GO_IDLE_STATE (OP_NADTC + 0)
#define CMD_SEND_OP_COND (OP_NADTC + 1) // only for MMC
#define CMD_ALL_SEND_CID (OP_NADTC + 2)
#define CMD_SEND_RELATIVE_ADDR (OP_NADTC + 3)
#define CMD_SET_DSR (OP_NADTC + 4)
#define CMD_SWITCH (OP_NADTC + 6)
#define CMD_SELECT_CARD (OP_NADTC + 7)
#define CMD_SEND_IF_COND (OP_NADTC + 8)
#define CMD_SEND_EXT_CSD (OP_RADTC + 8)
#define CMD_SEND_CSD (OP_NADTC + 9)
#define CMD_SEND_CID (OP_NADTC + 10)
#define CMD_SEND_DAT_UNTIL_STOP (OP_RADTC + 11) // only for MMC
#define CMD_STOP_TRANSMISSION (OP_NADTC + 12)
#define CMD_SEND_STATUS (OP_NADTC + 13)
#define CMD_GO_INACTIVE_STATE (OP_NADTC + 15)
#define CMD_SET_BLOCKLEN (OP_NADTC + 16)
#define CMD_READ_SINGLE_BLOCK (OP_RADTC + 17)
#define CMD_READ_MULTIPLE_BLOCK (OP_RADTC + 18)
#define CMD_WRITE_DAT_UNTIL_STOP (OP_WADTC + 20)
#define CMD_SET_BLOCK_COUNT (OP_NADTC + 23) // only for MMC
#define CMD_WRITE_SINGLE_BLOCK (OP_WADTC + 24)
#define CMD_WRITE_MULTIPLE_BLOCK (OP_WADTC + 25)
#define CMD_PROGRAM_CID (OP_WADTC + 26) // only for MMC
#define CMD_PROGRAM_CSD (OP_WADTC + 27)
#define CMD_SET_WRITE_PROT (OP_NADTC + 28)
#define CMD_CLR_WRITE_PROT (OP_NADTC + 29)
#define CMD_SEND_WRITE_PROT (OP_RADTC + 30)
#define CMD_ERASE_WR_BLK_START (OP_NADTC + 32) // only for SD
#define CMD_ERASE_WR_BLK_END (OP_NADTC + 33) // only for SD
#define CMD_ERASE_GROUP_START (OP_NADTC + 35) // only for MMC
#define CMD_ERASE_GROUP_END (OP_NADTC + 36) // only for MMC
#define CMD_ERASE (OP_NADTC + 38)
#define CMD_LOCK_UNLOCK (OP_WADTC + 42)
#define CMD_APP_COM (OP_NADTC + 55)
#define CMD_GEN_COM (OP_NADTC + 56)
#define ACMD_SET_BUS_WIDTH (OP_NADTC + 6)
#define ACMD_SD_STATUS (OP_RADTC + 13)
#define ACMD_SEND_NUM_WR_BLOCKS (OP_RADTC + 22)
#define ACMD_SET_WR_BLK_ERASE_COUNT (OP_NADTC + 23)
#define ACMD_SD_APP_OP_COND (OP_NADTC + 41)
#define ACMD_SET_CLR_CARD_DETEC (OP_NADTC + 42)
#define ACMD_SEND_SCR (OP_RADTC + 51)
#define NULL_STATE 0
#define STANDBY_STATE 3
#define TRANSFER_STATE 4
#define RECEIVE_STATE 6
#define PROGRAM_STATE 7
#define HOST_OCR_VALUE 0x00ff8000
#define MMC_VER_4_0 0x4
/*
#ifdef CPU_120M
#define CPU_CLOCK 120000 //120MHz = 120000kHz
#define OPEN_DRAIN_DELAY_1 0x200
#define OPEN_DRAIN_DELAY_2 0x400
#define INITIAL_CLOCK 0x7
#elif defined CPU_108M
#define CPU_CLOCK 108000 //108MHz = 108000kHz
#define OPEN_DRAIN_DELAY_1 0x200
#define OPEN_DRAIN_DELAY_2 0x400
#define INITIAL_CLOCK 0x7
#elif defined CPU_96M
#define CPU_CLOCK 96000 //96MHz = 96000kHz
#define OPEN_DRAIN_DELAY_1 0x200
#define OPEN_DRAIN_DELAY_2 0x400
#define INITIAL_CLOCK 0x7
#elif defined CPU_72M
#define CPU_CLOCK 72000 //72MHz = 72000kHz
#define OPEN_DRAIN_DELAY_1 0x3000
#define OPEN_DRAIN_DELAY_2 0x3000
#define INITIAL_CLOCK 0x7
#elif defined CPU_48M
#define CPU_CLOCK 48000 //48MHz = 48000kHz
#define OPEN_DRAIN_DELAY_1 0x3000
#define OPEN_DRAIN_DELAY_2 0x3000
#define INITIAL_CLOCK 0x6
#elif defined CPU_36M
#define CPU_CLOCK 36000 //36MHz = 36000kHz
#define OPEN_DRAIN_DELAY_1 0x3000
#define OPEN_DRAIN_DELAY_2 0x3000
#define INITIAL_CLOCK 0x6
#endif
#define MCARD_CLOCK_1 CPU_CLOCK
#define MCARD_CLOCK_1_2 (CPU_CLOCK / 2)
#define MCARD_CLOCK_1_3 (CPU_CLOCK / 3)
#define MCARD_CLOCK_1_4 (CPU_CLOCK / 4)
#define MCARD_CLOCK_1_5 (CPU_CLOCK / 5)
#define MCARD_CLOCK_1_6 (CPU_CLOCK / 6)
#define MCARD_CLOCK_1_128 (CPU_CLOCK / 128)
#define MCARD_CLOCK_1_256 (CPU_CLOCK / 256)
enum
{
SD_MMC_MIN_CLOCK = 0,
CPU_CLOCK_1_256 = SD_MMC_MIN_CLOCK,
CPU_CLOCK_1_128,
CPU_CLOCK_1_6,
CPU_CLOCK_1_5,
CPU_CLOCK_1_4,
CPU_CLOCK_1_3,
CPU_CLOCK_1_2,
CPU_CLOCK_1,
SD_MMC_MAX_CLOCK = CPU_CLOCK_1_2
};
*/
///
///@defgroup SD_MMC SD and MMC
///@ingroup CONSTANT
///@{
/// The device's function executes commands without any problem.
#define SD_PASS 0
#define BAD_CRC7 -1
/// Wait for response's signal fail.
#define RES_TIMEOUT -2
/// When reading data, card had no response with previous command.
#define READ_TIMEOUT -3
/// When writing data, card had no response with previous command.
#define WRITE_TIMEOUT -4
#define TRANSFER_FAIL -5
#define PROGRAM_FAIL -6
/// When reading data, the data had failed the CRC examination
#define BAD_CRC16 -7
#define CARD_NOT_SUPPORT -8
/// Unknown or general error encounter.
#define GENERAL_FAIL -9
///@}
//#define ENABLE_CHACK_TACC_MECHANISM
//#define HW_SUPPORT_MMC_4_0
#define MMC_BUS_WIDTH 0x1 // 0: 1 bit, 1: 4bit, 2: 8bit
#define RETRY_TIME 3
#define MULTI_W_SECTOR_NUM 1
/*
// Structure declarations
*/
struct ST_INFO_TAG
{
BYTE bInitFlag;
BYTE bMultiReadFlag;
BYTE bType;
BYTE bSDInit;
DWORD dwBusWidth;
DWORD dwCardTag;
DWORD dwClock;
DWORD dwSpeed;
DWORD dwRelativeCardAddr;
DWORD dwCapacity;
};
struct ST_CLOCK_SPEED_TYPE_TAG
{
BYTE bSettingValue;
DWORD dwClockValue;
};
/*
// Type declarations
*/
typedef struct ST_INFO_TAG ST_INFO;
typedef struct ST_CLOCK_SPEED_TYPE_TAG ST_CLOCK_SPEED_TYPE;
/*
// Variable declarations
*/
static DWORD dwCPU_CLOCK;
static DWORD dwOPEN_DRAIN_DELAY_1;
static DWORD dwOPEN_DRAIN_DELAY_2;
static DWORD dwINITIAL_CLOCK;
static DWORD dwMCARD_CLOCK_1;
static DWORD dwMCARD_CLOCK_1_2;
static DWORD dwMCARD_CLOCK_1_3;
static DWORD dwMCARD_CLOCK_1_4;
static DWORD dwMCARD_CLOCK_1_5;
static DWORD dwMCARD_CLOCK_1_6;
static DWORD dwMCARD_CLOCK_1_128;
static DWORD dwMCARD_CLOCK_1_256;
static DWORD dwSD_MMC_MIN_CLOCK;
static DWORD dwCPU_CLOCK_1_256;
static DWORD dwCPU_CLOCK_1_128;
static DWORD dwCPU_CLOCK_1_6;
static DWORD dwCPU_CLOCK_1_5;
static DWORD dwCPU_CLOCK_1_4;
static DWORD dwCPU_CLOCK_1_3;
static DWORD dwCPU_CLOCK_1_2;
static DWORD dwCPU_CLOCK_1;
static DWORD dwSD_MMC_MAX_CLOCK;
static ST_INFO sInfo;
static volatile BOOL blTimeOutFlag;
static BYTE bDescriptor[6] = "SD_MMC";
static ST_CLOCK_SPEED_TYPE sClockSpeedTable[8];
static BYTE bSlow_Card = 0;
/*
static const ST_CLOCK_SPEED_TYPE sClockSpeedTable[] =
{
{0x7, MCARD_CLOCK_1_256},
{0x6, MCARD_CLOCK_1_128},
{0x5, MCARD_CLOCK_1_6},
{0x4, MCARD_CLOCK_1_5},
{0x3, MCARD_CLOCK_1_4},
{0x2, MCARD_CLOCK_1_3},
{0x1, MCARD_CLOCK_1_2},
{0x0, MCARD_CLOCK_1},
};
*/
static const BYTE bSpeedFactor[] = {
// all parameter X 10
0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
};
static const DWORD dwSpeedUnit[] = {
100, 1000, 10000, 100000, 0, 0, 0, 0
};
#pragma alignvar(4)
/*
// Macro declarations
*/
//#define SD_TIMEOUT_HANDLE
//#define SD_TASK_YIELD
#ifdef SD_TASK_YIELD
#define TASK_YIELD() TaskYield()
#else
#define TASK_YIELD()
#endif
/*
// Static function prototype
*/
static void CommandProcess(void *pMcardDev);
static void DeSelect(void);
static void DeSelectData(void);
static void Select(void);
static BYTE GetWPFlag(void);
static void SetClockSpeed(DWORD dwSpeed);
static SWORD GoTransferMode(void);
static void SetCommand(WORD wCommand, DWORD dwArgument);
static SWORD WaitHostReady(void);
static void OpenDrainDelay(void);
static SWORD WaitResponse(void);
static SWORD SetBlockLen(DWORD dwBlockLen);
static SWORD SelCard(void);
static void TimeoutHandle(void);
static void SetDataDma(DWORD dwBufferAddress, DWORD dwSize, DWORD dwDirection);
static SWORD WaitChannelStop(void);
static void DmaReset(void);
static void DmaReset(void);
static SWORD WaitTranState(void);
static SWORD WaitDataRead(void);
static SWORD WaitDataWrite(void);
static SWORD WaitBusy(void);
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Format(void);
/*
// Definition of internal functions
*/
void SdInitForClk(void)
{
switch (g_dwCpuClk)
{
case CLOCK_96M_PLL1CFG:
{
dwCPU_CLOCK = 96000; //96MHz = 96000kHz
dwOPEN_DRAIN_DELAY_1 = 0x200;
dwOPEN_DRAIN_DELAY_2 = 0x400;
dwINITIAL_CLOCK = 0x7;
}
break;
case CLOCK_108M_PLL1CFG:
case CLOCK_108M_PLL2CFG:
{
dwCPU_CLOCK = 108000; //96MHz = 96000kHz
dwOPEN_DRAIN_DELAY_1 = 0x200;
dwOPEN_DRAIN_DELAY_2 = 0x400;
dwINITIAL_CLOCK = 0x7;
}
break;
default: // 72MHz
{
dwCPU_CLOCK = 72000; //96MHz = 96000kHz
dwOPEN_DRAIN_DELAY_1 = 0x3000;
dwOPEN_DRAIN_DELAY_2 = 0x3000;
dwINITIAL_CLOCK = 0x7;
}
break;
}
dwMCARD_CLOCK_1 = dwCPU_CLOCK;
dwMCARD_CLOCK_1_2 = (dwCPU_CLOCK / 2);
dwMCARD_CLOCK_1_3 = (dwCPU_CLOCK / 3);
dwMCARD_CLOCK_1_4 = (dwCPU_CLOCK / 4);
dwMCARD_CLOCK_1_5 = (dwCPU_CLOCK / 5);
dwMCARD_CLOCK_1_6 = (dwCPU_CLOCK / 6);
dwMCARD_CLOCK_1_128 = (dwCPU_CLOCK / 128);
dwMCARD_CLOCK_1_256 = (dwCPU_CLOCK / 256);
sClockSpeedTable[0].bSettingValue = 0x7;
sClockSpeedTable[0].dwClockValue = dwMCARD_CLOCK_1_256;
sClockSpeedTable[1].bSettingValue = 0x6;
sClockSpeedTable[1].dwClockValue = dwMCARD_CLOCK_1_128;
sClockSpeedTable[2].bSettingValue = 0x5;
sClockSpeedTable[2].dwClockValue = dwMCARD_CLOCK_1_6;
sClockSpeedTable[3].bSettingValue = 0x4;
sClockSpeedTable[3].dwClockValue = dwMCARD_CLOCK_1_5;
sClockSpeedTable[4].bSettingValue = 0x3;
sClockSpeedTable[4].dwClockValue = dwMCARD_CLOCK_1_4;
sClockSpeedTable[5].bSettingValue = 0x2;
sClockSpeedTable[5].dwClockValue = dwMCARD_CLOCK_1_3;
sClockSpeedTable[6].bSettingValue = 0x1;
sClockSpeedTable[6].dwClockValue = dwMCARD_CLOCK_1_2;
sClockSpeedTable[7].bSettingValue = 0x0;
sClockSpeedTable[7].dwClockValue = dwMCARD_CLOCK_1;
dwSD_MMC_MIN_CLOCK = 0;
dwCPU_CLOCK_1_256 = dwSD_MMC_MIN_CLOCK;
dwCPU_CLOCK_1_128 = dwSD_MMC_MIN_CLOCK + 1;
dwCPU_CLOCK_1_6 = dwSD_MMC_MIN_CLOCK + 2;
dwCPU_CLOCK_1_5 = dwSD_MMC_MIN_CLOCK + 3;
dwCPU_CLOCK_1_4 = dwSD_MMC_MIN_CLOCK + 4;
dwCPU_CLOCK_1_3 = dwSD_MMC_MIN_CLOCK + 5;
dwCPU_CLOCK_1_2 = dwSD_MMC_MIN_CLOCK + 6;
dwCPU_CLOCK_1 = dwSD_MMC_MIN_CLOCK + 7;
dwSD_MMC_MAX_CLOCK = dwCPU_CLOCK_1_2;
}
void SdInit(ST_MCARD_DEV * sDev)
{
MP_ASSERT(sDev != NULL);
sDev->pbDescriptor = bDescriptor;
sDev->dwLunNum = SD_MMC_LUN_NUM;
sDev->wMcardType = SD_MMC;
sDev->Flag.Installed = 1;
sDev->CommandProcess = CommandProcess;
sInfo.dwClock = dwINITIAL_CLOCK;
sInfo.bSDInit = 0;
}
static inline BOOL Polling_SD_Status(void)
{
if (!Ui_CheckSdPlugIn())
{
McardIODelay(10);
if (!Ui_CheckSdPlugIn())
return 1;
}
return 0;
}
DWORD SdGetSpeed(void)
{
return sInfo.dwSpeed;
}
/*
// Definition of local functions
*/
static void CommandProcess(void *pMcardDev)
{
ST_MCARD_MAIL *sMcardRMail;
register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);
sMcardRMail = pDev->sMcardRMail;
Select();
switch (sMcardRMail->wCmd)
{
case INIT_CARD_CMD:
pDev->Flag.Detected = Ui_CheckSdPlugIn();
if (pDev->Flag.Detected)
// MP_DEBUG1("COmmandProcess sInfo.bSDInit = %d",sInfo.bSDInit);
// if ((pDev->Flag.Detected) &&(sInfo.bSDInit == 0))
{
MP_DEBUG("-I- SD Cardin & Detected");
//card in
sInfo.bInitFlag = FALSE;
sInfo.dwCardTag = MCARD_DMA_SD;
sInfo.dwBusWidth = DBUS_1BIT;
sInfo.dwClock = dwINITIAL_CLOCK;
McardSetClock(sInfo.dwClock);
pDev->Flag.Detected = 1;
MP_DEBUG("-I- SD GoTransferMode");
if ((pDev->swStatus = GoTransferMode()))
{
//pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
}
else
{
MP_DEBUG("-I- SD GoTransferMode out");
sInfo.bSDInit = 1;
pDev->wRenewCounter++;
pDev->Flag.ReadOnly = GetWPFlag();
pDev->Flag.Present = 1;
pDev->dwCapacity = sInfo.dwCapacity;
pDev->wSectorSize = MCARD_SECTOR_SIZE;
McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
MP_DEBUG("-I- SD init cmd pass");
}
else if (!(pDev->Flag.Detected))
{
//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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -