⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 4 页
字号:
		SetClockSpeed(sInfo.dwSpeed);

		// change to TRANSFER state
		SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
		OpenDrainDelay();
		WaitHostReady();
		if ((swRetValue = WaitResponse()))
		{
			MP_DEBUG1("-E- CMD_SELECT_CARD FAIL (swRetValue: %d)", swRetValue);
			continue;
		}
		if (sInfo.dwCardTag == MCARD_DMA_SD)
		{
			SetCommand(CMD_APP_COM, sInfo.dwRelativeCardAddr);
			OpenDrainDelay();
			if ((swRetValue = WaitResponse()))
			{
				MP_DEBUG1("-E- CMD_APP_COM FAIL (swRetValue: %d)", swRetValue);
				continue;
			}
			WaitHostReady();

			SetCommand(ACMD_SET_BUS_WIDTH, 2);
			OpenDrainDelay();
			WaitHostReady();
			if ((swRetValue = WaitResponse()))
			{
				MP_DEBUG1("-E- ACMD_SET_BUS_WIDTH FAIL (swRetValue: %d)", swRetValue);
				continue;
			}
			sInfo.dwBusWidth = DBUS_4BIT;
		}
		else
		{
#ifdef HW_SUPPORT_MMC_4_0
			if (bVersion == MMC_VER_4_0)
			{
				MP_DEBUG1("MMC_BUS_WIDTH = %d", MMC_BUS_WIDTH);
				//access | index | value | command set
				dwParam = (0x03 << 24) | (0xB7 << 16) | (MMC_BUS_WIDTH << 8) | 0x00;
				SetCommand(CMD_SWITCH, dwParam);
				OpenDrainDelay();
				if ((swRetValue = WaitResponse()))
				{
					MP_DEBUG1("-E- CMD_SWITCH FAIL (swRetValue: %d)", swRetValue);
					continue;
				}
				WaitHostReady();

				OpenDrainDelay();
				OpenDrainDelay();
				OpenDrainDelay();
				OpenDrainDelay();

#if (MMC_BUS_WIDTH == 1)
				sInfo.dwBusWidth = DBUS_4BIT;
				MP_DEBUG("-I- MMC transfer bus width to 4 bit");
#elif (MMC_BUS_WIDTH == 2)
				sInfo.dwBusWidth = DBUS_8BIT;
				MP_DEBUG("-I- MMC transfer bus width to 8 bit");
#else
				sInfo.dwBusWidth = DBUS_1BIT;
				MP_DEBUG("-I- MMC transfer bus width to 1 bit");
#endif
/*
				McardIODelay(500);
				SetBlockLen(MCARD_SECTOR_SIZE);
				bTempMemID0 = OsTempMemAllocateMCARD();
				pbBuffer1 =  GetOsTempMemoryMCARD(bTempMemID0);	
				SetDataDma(pbBuffer1, (1 << MCARD_SECTOR_BIT_OFFSET),MCARD_DMA_DIR_CM);
				SetCommand(CMD_SEND_EXT_CSD, sInfo.dwRelativeCardAddr);
				OpenDrainDelay();
				WaitHostReady();
				if ((swRetValue = WaitResponse()))
				{
					OsTempMemRelease(bTempMemID0);
					MP_DEBUG1("-E- CMD_SEND_EXT_CSD FAIL (swRetValue: %d)", swRetValue);
					continue;
				}
				if ((swRetValue = WaitDataRead()) != SD_PASS) 		
				{
					OsTempMemRelease(bTempMemID0);				
					MP_DEBUG1("-E-EXT_CSD Command Wait Data End FAIL (swRetValue: %d)", swRetValue);
					continue;					
				}
				if(pbBuffer1[183] != MMC_BUS_WIDTH)
				{
					MP_DEBUG1("-E-EXT_CSD Command check bus width FAIL (swRetValue: %d)", swRetValue);					
					OsTempMemRelease(bTempMemID0);	
#if 1
				dwParam = (0x03 << 24) | (0xB7 << 16) | (0 << 8) | 0x00;
				SetCommand(CMD_SWITCH, dwParam);
				OpenDrainDelay();
				if ((swRetValue = WaitResponse()))
				{
					MP_DEBUG1("-E- CMD_SWITCH FAIL (swRetValue: %d)", swRetValue);
					continue;
				}
				WaitHostReady();
				sInfo.dwBusWidth = DBUS_1BIT;
#endif								
				}
					OsTempMemRelease(bTempMemID0);					
*/				
			}
			else
			{
				MP_DEBUG("-I- Only Support MMC 1 bit");
			}
#else
			MP_DEBUG("-I- Only Support MMC 1 bit");
#endif
		}
		// set BLOCK length
		SetBlockLen(MCARD_SECTOR_SIZE);

		#if SD_RW_COMPARE
		if(sInfo.bType  == SD_TYPE)
			SD_READ_WRITE_COMPARE();
		#endif

		if (swRetValue == SD_PASS)
		{		
			sInfo.bInitFlag = TRUE;
			return swRetValue;
		}
	}
	while (bRetryTimes > 0);

	return GENERAL_FAIL;
}


static void SetCommand(WORD wCommand, DWORD dwArgument)
{
	register MCARD *sMcard;
	sMcard = (MCARD *) (MCARD_BASE);	
	sMcard->McSdC = (wCommand & 0x3f) + sInfo.dwBusWidth+BIT8;
	sMcard->McSdArg = dwArgument;
	sMcard->McSdIc = IM_ALL;
	sMcard->McSdOp = (wCommand >> 8);
}

static SWORD WaitHostReady(void)
{
	register MCARD *sMcard;
	DWORD dwTimeOut;

	sMcard = (MCARD *) (MCARD_BASE);
	dwTimeOut = 10000;

	OpenDrainDelay();
	while (dwTimeOut)
	{
		//if (Polling_SD_Status()) return GENERAL_FAIL;
		if (!(sMcard->McSdC & FSMBUSY))
		{
			return SD_PASS;
		}

		TASK_YIELD();
		dwTimeOut--;
	}
	return GENERAL_FAIL;
}

static void OpenDrainDelay(void)
{
	DWORD dwCounter;

	dwCounter = dwOPEN_DRAIN_DELAY_1;
	while (dwCounter)
	{
		dwCounter--;
	}

	if (sInfo.dwClock != dwINITIAL_CLOCK)
	{
		return;
	}

	dwCounter = dwOPEN_DRAIN_DELAY_2;
	while (dwCounter)
	{
		dwCounter--;
	}
}

static SWORD WaitResponse(void)
{
	register MCARD *sMcard;
	DWORD dwTimeOut, dwCause;

	sMcard = (MCARD *) MCARD_BASE;

	dwTimeOut = 10000000;
//	OpenDrainDelay();
	while (!(sMcard->McSdIc & IC_RSPDONE))
	{
		//if (Polling_SD_Status()) return GENERAL_FAIL;
		if (dwTimeOut == 0)
		{
			//MP_DEBUG("-E- IC_RSPDONE fail");
			return RES_TIMEOUT;
		}
		dwTimeOut--;
	}

	dwCause = sMcard->McSdIc;
	if (dwCause & IC_RSPF)
	{
		MP_DEBUG("-E- IC_RSPF fail");
		if (dwCause & IC_CRC16F)
		{
			MP_DEBUG("-E- IC_CRC16F fail");
			return BAD_CRC16;
		}
		else if (dwCause & IC_CRC7F)
		{
			MP_DEBUG("-E- IC_CRC7F fail");
			return BAD_CRC7;
		}
		else if (dwCause & IC_SDTO)
		{
			MP_DEBUG("-E- IC_SDTO fail");
			return RES_TIMEOUT;
		}
		else if ((dwCause & IC_PGMF) || (dwCause & IC_WXF))
		{
			MP_DEBUG("-E- IC_PGMF or IC_WXF fail");
			return PROGRAM_FAIL;
		}
		else
		{
			return PROGRAM_FAIL;
		}
	}
	return SD_PASS;
}

static SWORD SetBlockLen(DWORD dwBlockLen)
{
	register MCARD *sMcard;
	DWORD dwTimeOut, dwCause;

	sMcard = (MCARD *) (MCARD_BASE);
	sMcard->McSdC = (CMD_SET_BLOCKLEN & 0x3f) + sInfo.dwBusWidth+BIT8;	// set command index with current bus width setting
	sMcard->McSdArg = dwBlockLen;	// set argument
	sMcard->McSdOp = CMD_SET_BLOCKLEN >> 8;	// enable operation
	dwTimeOut = 0xf0000000;
	OpenDrainDelay();
	while (dwTimeOut)
	{
		//if (Polling_SD_Status()) return RES_TIMEOUT;
		dwCause = sMcard->McSdIc;
		if (dwCause & IC_RSPDONE)
		{
			return SD_PASS;
		}
		dwTimeOut--;
	}
	MP_DEBUG1("-E- SetBlockLen FAIL (status: %x)", dwCause);
	return RES_TIMEOUT;
}

static SWORD SelCard(void)
{
	register MCARD *sMcard;
	DWORD dwTimeOut, dwCause;

	sMcard = (MCARD *) (MCARD_BASE);
	sMcard->McSdC = (CMD_SELECT_CARD & 0x3f) + sInfo.dwBusWidth+BIT8;	
	sMcard->McSdArg = sInfo.dwRelativeCardAddr;	// set argument
	sMcard->McSdOp = (CMD_SELECT_CARD >> 8);	// enable operation
	dwTimeOut = 1000;

	OpenDrainDelay();
	while (dwTimeOut)
	{
		dwCause = sMcard->McSdIc;
		if (dwCause & IC_RSPDONE)
		{
			return SD_PASS;
		}
		dwTimeOut--;
	}
	MP_DEBUG1("-E- SelCard FAIL (status: %x)", dwCause);
	return RES_TIMEOUT;
}

static void TimeoutHandle(void)
{
	register CHANNEL *sChannel;

	sChannel = (CHANNEL *) (DMA_MC_BASE);
	sChannel->Control = 0;
	DmaIntDis(IM_MCRDDM);
	blTimeOutFlag = 1;
	TaskWakeup(MCARD_TASK);
}


static void SetDataDma(DWORD dwBufferAddress, DWORD dwSize, DWORD dwDirection)
{
	register MCARD *sMcard;
	register CHANNEL *sChannel;
	DWORD dwTimeOut;

	sChannel = (CHANNEL *) (DMA_MC_BASE);
	sMcard = (MCARD *) (MCARD_BASE);
	sMcard->McardC &= ~MCARD_FIFO_ENABLE;

	dwTimeOut = 5000000;
	while (!(sMcard->McardC & 0x400))
	{
		if (dwTimeOut-- == 0)
			break;
		//if (Polling_SD_Status()) return;
	}
	sChannel->Control = 0;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
	sMcard->McardC = (MCARD_ENABLE + sInfo.dwCardTag + dwDirection+BIT11);
#else
	sMcard->McardC = (MCARD_ENABLE + sInfo.dwCardTag + dwDirection);
#endif
	sChannel->StartA = dwBufferAddress;
	sChannel->EndA = dwBufferAddress + dwSize - 1;
	sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (dwSize >> 2);
	sChannel->Control = MCARD_DMA_ENABLE;
	sMcard->McardC |= MCARD_FIFO_ENABLE;
}

static SWORD WaitChannelStop(void)
{
	register CHANNEL *sChannel;
	DWORD dwTimeOut;

	sChannel = (CHANNEL *) (DMA_MC_BASE);
	dwTimeOut = 500000;
	while (dwTimeOut)
	{
		if (!(sChannel->Control & MCARD_DMA_ENABLE))
		{
			return SD_PASS;
		}
		dwTimeOut--;
	}
	MP_DEBUG1("-E- WaitChannelStop FAIL (status: %x)", sChannel->Control);
	return RES_TIMEOUT;
}

static void DmaReset(void)
{
	register CHANNEL *sChannel;
	register MCARD *sMcard;

	sMcard = (MCARD *) (MCARD_BASE);
	sChannel = (CHANNEL *) (DMA_MC_BASE);
	sChannel->Control = 0;
	sMcard->McDmarl = 0;
	sChannel->StartA = 0;
	sChannel->EndA = 0;
	sMcard->McSdIc = IM_ALL;
}


static SWORD WaitTranState(void)
{
	register MCARD *sMcard;
	DWORD dwCurState, dwRetryTime;

	dwRetryTime = 50000;
	sMcard = (MCARD *) (MCARD_BASE);

	while ((dwRetryTime--) > 0)
	{
		SetCommand(CMD_SEND_STATUS, sInfo.dwRelativeCardAddr);
		if (WaitResponse() != SD_PASS)
		{
			MP_DEBUG("WaitTranState Wait Response fail");
			return RES_TIMEOUT;
		}
		dwCurState = (sMcard->McSdRspA & 0xe00) >> 9;
		if (dwCurState == TRANSFER_STATE)
		{
			//MP_DEBUG("Transfer state");
			return SD_PASS;
		}

		if (dwCurState == RECEIVE_STATE)
		{
//			MP_DEBUG("Receive state");
			McardIODelay(50);
			/*
			SetCommand(CMD_STOP_TRANSMISSION, 0);
			if (WaitResponse() != SD_PASS)
			{
				MP_DEBUG("Stop Transmission Wait Response fail");
				return RES_TIMEOUT;
			}
			SetCommand(CMD_SELECT_CARD, 0);
			if (WaitResponse() != SD_PASS)
			{
				MP_DEBUG("Select Card to Stand by Wait Response fail");
				return RES_TIMEOUT;
			}
			SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
			if (WaitResponse() != SD_PASS)
			{
				MP_DEBUG("Select Card to Transfer State Wait Response fail");
				return RES_TIMEOUT;
			}
			*/
		}

		if (dwCurState == STANDBY_STATE)
		{
			//MP_DEBUG("Standby state");
			SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
			if (WaitResponse() != SD_PASS)
			{
				MP_DEBUG("Select Card to Transfer State Wait Response fail");
				return RES_TIMEOUT;
			}
		}

		if (dwCurState == PROGRAM_STATE)
		{
			//MP_DEBUG("Program state");
			McardIODelay(50);
		}
		if (dwCurState == NULL_STATE)
		{
//			MP_DEBUG("Null state");
			McardIODelay(50);
		}		
		TASK_YIELD();
	}
	MP_DEBUG1("re init (dwCurState = %d)", dwCurState);
	OpenDrainDelay();
	OpenDrainDelay();
	return GoTransferMode();
}
static SWORD WaitDataRead(void)
{
	register MCARD *sMcard;
	DWORD dwTimeOut, dwCause;

	sMcard = (MCARD *) (MCARD_BASE);

	dwTimeOut = 10000000;
	while (dwTimeOut)
	{
		dwCause = sMcard->McSdIc;
		if (dwCause & IC_SDTO)
		{
			MP_DEBUG1("-E- IC_SDTO FAIL (status: %x)", dwCause);
			return READ_TIMEOUT;
		}
		if (dwCause & IC_CRC16F)
		{
			MP_DEBUG1("-E- IC_CRC16F FAIL (status: %x)", dwCause);
			return BAD_CRC16;
		}
		if (dwCause & IC_TREND)
		{
			return SD_PASS;
		}
		TASK_YIELD();
		dwTimeOut--;
	}
	MP_DEBUG1("-E- WaitDataRead FAIL (status: %x)", dwCause);
	return GENERAL_FAIL;
}

static SWORD WaitDataWrite(void)
{
	register MCARD *sMcard;
	DWORD dwTimeOut, dwCause;
	sMcard = (MCARD *) (MCARD_BASE);
	dwTimeOut = 10000000;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -