예제 #1
0
byte MMC_ReadOCR(byte cmd, uint32_t param, byte* ocr)
{
	byte r = MMC_Command(cmd,param);
	byte i = 4;
	while (i--)
		*ocr++ = SPI_ReceiveByte(0xFF);
	return r;
}
예제 #2
0
파일: mmc.cpp 프로젝트: Drew471/Libraries
byte MMC_ReadSector(byte *buffer, uint32_t sector)
{
	if (!(_mmcState & MMC_INITED))
		return MMC_NOT_INITED;
	if (!(_mmcState & MMC_HIGH_DENSITY))
		sector <<= 9;
	MMC_SS_LOW();
	if (MMC_Command(17,sector) != 0 || MMC_Token() != 0xFE)
		return MMC_Release(READ_FAILED);
	SPI_Receive(buffer,512);	// WARNING! Will strip 2 CRC bytes as well
	return MMC_Release(0);
}
예제 #3
0
byte MMC_Init2()
{
	byte ocr[4];
	MMC_SS_HIGH();	//
	SPI_Init();		// Init slow at first TODO
	_mmcState = 0;

	// initialize the MMC card into SPI mode by sending 80 clks
	int i;
	for (i = 0; i < 10; i++)
		SPI_ReceiveByte(0xFF);

	// Send GO_IDLE_STATE
	MMC_SS_LOW();
	if (MMC_Command(0,0) != 1)
		return GO_IDLE_TIMEOUT;
	_mmcState = MMC_PRESENT;
	MMC_SS_HIGH();

	//	Full speed
	SPI_Enable();
	MMC_SS_LOW();

	if (MMC_ReadOCR(58,0,ocr) != 1)		// Read OCR check voltages
		return READ_OCR_TIMEOUT;		// Can't read OCR
	if ((ocr[1] & 0x10) == 0)
		return BAD_VOLTAGE;				// Card does not like out voltage

	// Try CMD8
	if (MMC_ReadOCR(8,0x1AA,ocr) == 1)
	{
		//	SDHC
		_mmcState |= MMC_SDHC;
		if ((ocr[2] & 0x0F) != 1)
			return BAD_VOLTAGE;				// Card does not like out voltage
		if (ocr[3] != 0xAA)
			return BAD_PATTERN;

		//	Send ACMD41 and wait for it to come out of idle
		i = 0x7FFF;	// Wait a long time. A long, long time - some cards take 700 miliseconds or more.
		while (i--)
		{
			MMC_Command(55,0);						// SEND_APP_CMD
			if (MMC_Command(41,1L << 30) == 0)		// ACMD41 with HCS bit 30 set
				break;
		}
		if (i < 0)
			return OP_COND_TIMEOUT;

		//	Check density again
		if (MMC_ReadOCR(58,0,ocr) != 0)				// Bits[30:29]=1,0
			return READ_OCR_TIMEOUT;				// Can't read OCR
		if ((ocr[0] & 0x60) == 0x40)
			_mmcState |= MMC_HIGH_DENSITY;

	} else {

		//	SDCARD 1vXX
		//	Send SEND_OP_COND and wait for it to come out of idle
		i = 0x7FFF;
		while (i--)
		{
			if ((MMC_Command(1,0) & 1) == 0)
				break;
		}
		if (i < 0)
			return OP_COND_TIMEOUT;
	}

	//	Send SET_BLOCKLEN for 512 byte block
	if (MMC_Command(16,512) != 0)
		return SET_BLOCKLEN_TIMEOUT;

	_mmcState |= MMC_INITED;
	return 0;
}