示例#1
0
文件: sd.c 项目: ECEJunkies/pi4th
int sd_write_block (sd_context_t *sdc, u32 blockaddr, unsigned char *data){
blockaddr <<= SD_BLOCKSIZE_NBITS;			//Adjust the block address to a linear address.
sd_wait_notbusy (sdc);						// Wait until any old transfers are finished.

sd_packarg(argument, blockaddr);			//Pack the address.
if (sd_send_command(sdc, CMD24, CMD24_R, response, argument) == 0){		//Check for an error, like a misaligned write.
	return 0;
}
if (response[0] != 0){
	return 0;
}
spi_cs_assert();	//Re-assert CS to continue the transfer.
		/* The write command needs an additional 8 clock cycles before
		the block write is started. */
spi_rcv_byte();		//Clear any pending flags.
IFG1 &= ~(URXIFG0 | UTXIFG0);		//Get the block.
DMA0SA = (unsigned short)data;		//Source DMA address: the data buffer.
DMA0DA = U0TXBUF_;					//Destination DMA address: the UART send register.
DMA0SZ = SD_BLOCKSIZE;				//The size of the block to be transferred.
DMA0CTL =							//Configure the DMA transfer.
	DMADT_0 |					//Single transfer mode.
	DMASBDB |					//Byte mode.
	DMAEN |						//Enable DMA.
	DMASRCINCR1 | DMASRCINCR0;	// Increment the source address.
DMACTL0 = DMA0TSEL_3;				//DMA trigger is UART send.
//-------------------------Kick off the transfer by sending the first byte, the "start block" token---------------------------
U0TXBUF = SD_TOK_WRITE_STARTBLOCK;		//Signal that the card may be busy, so any subsequent commands should wait for the busy signalling to end (indicated by a nonzero response).
sdc->busyflag = 1;
return 1;
}
示例#2
0
/*
	This function writes a single block to the SD card at block
	blockaddr. Returns 1 if the command was successful, zero
	otherwise.

	This is an ASYNCHRONOUS call. The transfer will not be complete
	when the function returns. If you want to explicitly wait until
	any pending transfers are finished, use the command
	sd_wait_notbusy(sdc).

	sd_context_t *sdc
	 -- a pointer to an sd device context structure,
		populated by the function sd_initialize()

	u32 blockaddr
	 -- The block address to read from the card.
		This is a block address, not a linear address.

	uint8_t *data
	 -- The data, a pointer to an array of unsigned
		chars.
*/
int sd_write_block(sd_context_t *sdc, uint32_t blockaddr,
				   uint8_t *data)
{
	/* Adjust the block address to a linear address */
	blockaddr <<= SD_BLOCKSIZE_NBITS;

	/* Wait until any old transfers are finished */
	sd_wait_notbusy(sdc);

	/* Pack the address */
	sd_packarg(argument, blockaddr);

	if (sd_send_command(sdc, CMD24, CMD24_R, response, argument) == 0)
		return 0;

	/* Check for an error, like a misaligned write */
	if (response[0] != 0)
		return 0;

	/* Re-assert CS to continue the transfer */
	spi_cs_assert();

	/* The write command needs an additional 8 clock cycles before
	* the block write is started. */
	spi_rcv_byte();

	/* Clear any pending flags */
	IFG1 &= ~(URXIFG0 | UTXIFG0);

	/* Get the block */
	/* Source DMA address: the data buffer. */
	DMA0SA = (unsigned short)data;

	/* Destination DMA address: the UART send register. */
	DMA0DA = U0TXBUF_;

	/* The size of the block to be transferred */
	DMA0SZ = SD_BLOCKSIZE;

	/* Configure the DMA transfer*/
	DMA0CTL =
		DMADT_0 |    /* Single transfer mode */
		DMASBDB |    /* Byte mode */
		DMAEN |      /* Enable DMA */
		DMASRCINCR1 | DMASRCINCR0; /* Increment the source address */

	/* DMA trigger is UART send */
	DMACTL0 = DMA0TSEL_3;

	/* Kick off the transfer by sending the first byte, the "start block"
	* token */
	U0TXBUF = SD_TOK_WRITE_STARTBLOCK;

	/* Signal that the card may be busy, so any subsequent commands
	should wait for the busy signalling to end (indicated by a
	nonzero response). */
	sdc->busyflag = 1;

	return 1;
}
示例#3
0
文件: sd.c 项目: ECEJunkies/pi4th
int sd_read_block (sd_context_t *sdc, u32 blockaddr, unsigned char *data){
unsigned long int i = 0;
unsigned char tmp;
unsigned char blank = 0xFF;

blockaddr <<= SD_BLOCKSIZE_NBITS;			//Adjust the block address to a linear address. 
sd_wait_notbusy (sdc);						//Wait until any old transfers are finished.
sd_packarg(argument, blockaddr);			//Pack the address.
	
	if (sd_send_command(sdc, CMD17, CMD17_R, response, argument) == 0){			//Need to add size checking.
	return 0;
	}
	if (response[0] != 0){		// Check for an error, like a misaligned read.
	return 0;
	}
spi_cs_assert();				//Re-assert CS to continue the transfer.
i=0;							//Wait for the token.		
	do{
	tmp = spi_rcv_byte();
	i++;
	}
	while ((tmp == 0xFF) && i < sdc->timeout_read );
	if ((tmp & MSK_TOK_DATAERROR) == 0){				//Clock out a byte before returning.
	spi_send_byte(0xFF);						//The card returned an error response. Bail and return 0
	return 0;
	}
//----------------------------------Prime the interrupt flags so things happen in the correct order.------------------------------------

IFG1 &= ~URXIFG0;
IFG1 &= ~UTXIFG0;
/* Get the block */
/* Source DMA address: receive register. */
DMA0SA = U0RXBUF_;
/* Destination DMA address: the user data buffer. */
DMA0DA = (unsigned short)data;
/* The size of the block to be transferred */
DMA0SZ = SD_BLOCKSIZE;
/* Configure the DMA transfer*/
DMA0CTL =	
	DMADT_0 |		/* Single transfer mode */
	DMASBDB |		/* Byte mode */
	DMAEN |			/* Enable DMA */
	DMADSTINCR1 | DMADSTINCR0; 		/* Increment the destination address */

/* We depend on the DMA priorities here. Both triggers occur at
the same time, since the source is identical. DMA0 is handled
first, and retrieves the byte. DMA1 is triggered next, and
sends the next byte. */

/* Source DMA address: constant 0xFF (don’t increment)*/
DMA1SA = (unsigned short)&blank;			/* Destination DMA address: the transmit buffer. */
DMA1DA = U0TXBUF_;							/* Increment the destination address */
DMA1SZ = SD_BLOCKSIZE-1;					/* The size of the block to be transferred */
DMA1CTL =									/* Configure the DMA transfer*/
	DMADT_0 |								/* Single transfer mode */
	DMASBDB |								/* Byte mode */
	DMAEN;									/* Enable DMA */
DMACTL0 = DMA0TSEL_3 | DMA1TSEL_3;				/* DMA trigger is UART receive for both DMA0 and DMA1 */
U0TXBUF = 0xFF;									/* Kick off the transfer by sending the first byte */
return 1;
}
示例#4
0
文件: sd.c 项目: px2ec/elo312_project
/*
 * This function initializes the SD card. It returns 1 if
 * initialization was successful, 0 otherwise.
 *
 * sd_context_t *sdc -- Pointer to a data structure containing
 *                      information about the card. For now, the
 *                      timeouts must be specified in advance. It
 *                      is not yet calculated from the card data.
 */
int sd_initialize(sd_context_t *sdc)
{
	u16 i;

	/*
	 * SPI SDv2 initialization sequence:
	 *   CMD0
	 *   CMD8
	 *   CMD55+ACMD41
	 *   CMD58
	 *     (There is no CMD2 or CMD3 in SPI mode. These
	 *      instructions are devoted to addressing on the SD bus)
	 */

	sdc->busyflag = 0;

	/*
	 * Delay for at least 74 clock cycles. This means to actually
	 * *clock* out at least 74 clock cycles with no data present on
	 * the clock. In SPI mode, send at least 10 idle bytes (0xFF)
	 */
	spi_cs_deassert();
	sd_delay(100);
	spi_cs_assert();
	sd_delay(2);

	/* Put the card in thee idle state */
	if (sd_send_command(sdc, CMD0, CMD0_R, response, NULL) == 0)
		return 0;

	sd_packarg(argument, 0x000001AA);
	if (sd_send_command(sdc, CMD8, CMD8_R, response, argument) == 0) {
		return 0;
	}

	if (response[0] & MSK_ILL_CMD) {
		/* Illegal command, try SDv1 init */
		sd_packarg(argument, 0x00000000);
	} else {
		/* Check if the voltage range is appropiate */
		if (response[3] == 0x01 && response[4] == 0xAA) {
			sd_packarg(argument, 0x40000000);
		} else {
			return 0;
		}
	}

	/* Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX */
	i = 0;
	do {
		i++;
		/* Flag the next command as an application-specific command */
		if (sd_send_command(sdc, CMD55, CMD55_R, response, NULL) == 1) {
			/* Tell the card to send its OCR */
			sd_send_command(sdc, ACMD41, ACMD41_R, response, argument);
		} else {
			/* No response, bail early */
			i = SD_IDLE_WAIT_MAX;
		}
	} while ((response[0] & MSK_IDLE) == MSK_IDLE && i < SD_IDLE_WAIT_MAX);

	/* As long as we didn't hit the timeout, assume we're OK */
	if (i >= SD_IDLE_WAIT_MAX)
		return 0;

	if (sd_send_command(sdc, CMD58, CMD58_R, response, NULL) == 0)
		return 0;

	/* At the very minimum, we must allow 3.3V */
	if ((response[2] & MSK_OCR_33) != MSK_OCR_33)
		return 0;

	/* Set the block length */
	if (sd_set_blocklen(sdc, SD_BLOCKSIZE) != 1)
		return 0;

	/* If we got this far, initialization was OK */
	return 1;
}