Beispiel #1
0
DRESULT disk_readp (
	BYTE *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	DWORD lba,		/* Sector number (LBA) */
	WORD ofs,		/* Byte offset to read from (0..511) */
	WORD cnt		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
	DRESULT res;
	BYTE d;
	WORD bc, tmr;


	if (!(CardType & CT_BLOCK)) lba *= 512;		/* Convert to byte address if needed */

	res = RES_ERROR;
	if (send_cmd(CMD17, lba) == 0) {		/* READ_SINGLE_BLOCK */

		tmr = 1000;
		do {							/* Wait for data packet in timeout of 100ms */
//			DLY_US(100);
			mmc_spi_Wait100us();
			d = rcvr_mmc();
		} while (d == 0xFF && --tmr);

		if (d == 0xFE) {				/* A data packet arrived */
			bc = 514 - ofs - cnt;

			/* Skip leading bytes */
			if (ofs) skip_mmc(ofs);

			/* Receive a part of the sector */
//			if (buff) {	/* Store data to the memory */
				do
					*buff++ = rcvr_mmc();
				while (--cnt);
//			} else {	/* Forward data to the outgoing stream */
//				do {
//					d = rcvr_mmc();
//					FORWARD(d);
//				} while (--cnt);
//			}

			/* Skip trailing bytes and CRC */
			skip_mmc(bc);

			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Beispiel #2
0
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, buf[4];
	UINT tmr;


//	INIT_PORT();
	mmc_spi_InitSocket();

//	CS_H();
	mmc_spi_SetCardDeselect();
	skip_mmc(10);			/* Dummy clocks */

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			/* Enter Idle state */
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2 */
			for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();	/* Get trailing return value of R7 resp */
			if (buf[2] == 0x01 && buf[3] == 0xAA) {			/* The card can work at vdd range of 2.7-3.6V */
				for (tmr = 1000; tmr; tmr--) {				/* Wait for leaving idle state (ACMD41 with HCS bit) */
					if (send_cmd(ACMD41, 1UL << 30) == 0) break;
//					DLY_US(1000);
					mmc_spi_SetTimer(1);
					while( mmc_spi_CheckTimer() ) {}
				}
				if (tmr && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
					for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();
					ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 (HC or SC) */
				}
			}
		} else {							/* SDv1 or MMCv3 */
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
			} else {
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
			}
			for (tmr = 1000; tmr; tmr--) {			/* Wait for leaving idle state */
				if (send_cmd(ACMD41, 0) == 0) break;
//				DLY_US(1000);
				mmc_spi_SetTimer(1);
				while( mmc_spi_CheckTimer() ) {}
			}
			if (!tmr || send_cmd(CMD16, 512) != 0)			/* Set R/W block length to 512 */
				ty = 0;
		}
	}
	CardType = ty;
	release_spi();

//	return ty ? 0 : STA_NOINIT;

	if ( !ty ) return STA_NOINIT;

	mmc_spi_SetTransClock();
	return 0;
}
Beispiel #3
0
DRESULT disk_readp (
	BYTE *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	DWORD sector,	/* Sector number (LBA) */
	UINT offset,	/* Byte offset to read from (0..511) */
	UINT count		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
        BYTE *buff_sec = buffer;
	DRESULT res;
	BYTE d;
	UINT bc, tmr;

	if (!(CardType & CT_BLOCK)) sector *= 512;	/* Convert to byte address if needed */

	// check if sector is already in sector buffer
	if(buffer_sector == sector) {
	  buff_sec += offset;  // skip to requested bytes
	  while(count--)
	    *buff++ = *buff_sec++;

	  return RES_OK;
	}

	res = RES_ERROR;
	if (send_cmd(CMD17, sector) == 0) {		/* READ_SINGLE_BLOCK */

		tmr = 1000;
		do {							/* Wait for data packet in timeout of 100ms */
			DLY_US(100);
			d = rcvr_mmc();
		} while (d == 0xFF && --tmr);

		if (d == 0xFE) {				/* A data packet arrived */
			bc = 512 - offset - count;

			/* Skip leading bytes (store in buffer only) */
			while(offset--)
			  *buff_sec++ = rcvr_mmc();

			/* Receive a part of the sector */
			if (buff) {	/* Store data to the memory */
			    do
			        *buff_sec++ = *buff++ = rcvr_mmc();
			    while (--count);
			} else {	/* Forward data to the outgoing stream */
				do {
					*buff_sec++ = d = rcvr_mmc();
					FORWARD(d);
				} while (--count);
			}

			/* Skip trailing bytes (store in buffer only) */
			while(bc--)
			  *buff_sec++ = rcvr_mmc();
			
			/* and skip crc */
			skip_mmc(2);

			buffer_sector = sector;
			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Beispiel #4
0
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, buf[4];
	UINT tmr;


#if AXI_SPI
	/*
	 * Initialize the SPI driver so that it's ready to use,
	 * specify the device ID that is generated in xparameters.h.
	 */
	XStatus Status = XSpi_Initialize(&Spi, XPAR_SDCARD_SPI_DEVICE_ID);
	if(Status != XST_SUCCESS) {\
   		xil_printf("Failure INIT\r\n");
		return XST_FAILURE;
	}
	/*
	 * Set the SPI device as a master and in manual slave select mode such
	 * that the slave select signal does not toggle for every byte of a
	 * transfer, this must be done before the slave select is set.
	 */
	Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION |
						XSP_MANUAL_SSELECT_OPTION);
	if(Status != XST_SUCCESS) {
   		xil_printf("Failure Options\r\n");
		return XST_FAILURE;
	}

	Status = XSpi_SetSlaveSelect(&Spi, 1);
	if(Status != XST_SUCCESS) {
   		xil_printf("Failure Slave Select\r\n");
		return XST_FAILURE;
	}

	XSpi_Start(&Spi);
	XSpi_IntrGlobalDisable(&Spi);

	DLY_US(1);
#else
	INIT_PORT();

	CS_H();
#endif
	skip_mmc(10);			/* Dummy clocks */

	ty = 0;
	if (send_cmd(CMD0, 0) == 1) {			/* Enter Idle state */
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2 */
			for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();	/* Get trailing return value of R7 resp */
			if (buf[2] == 0x01 && buf[3] == 0xAA) {			/* The card can work at vdd range of 2.7-3.6V */
				for (tmr = 1000; tmr; tmr--) {				/* Wait for leaving idle state (ACMD41 with HCS bit) */
					if (send_cmd(ACMD41, 1UL << 30) == 0) break;
					DLY_US(1000);
				}
				if (tmr && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
					for (n = 0; n < 4; n++) buf[n] = rcvr_mmc();
					ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 (HC or SC) */
				}
			}
		} else {							/* SDv1 or MMCv3 */
			if (send_cmd(ACMD41, 0) <= 1) 	{
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
			} else {
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
			}
			for (tmr = 1000; tmr; tmr--) {			/* Wait for leaving idle state */
				if (send_cmd(cmd, 0) == 0) break;
				DLY_US(1000);
			}
			if (!tmr || send_cmd(CMD16, 512) != 0)			/* Set R/W block length to 512 */
				ty = 0;
		}
	}
	CardType = ty;
	release_spi();

	return ty ? 0 : STA_NOINIT;
}