Beispiel #1
0
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;
}
Beispiel #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;
}
Beispiel #3
0
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address in LBA */
	UINT count			/* Number of sectors to write */
)
{
	DRESULT res;
//	int result;

            sd_write_block (&sdc, sector, buff);
            sd_wait_notbusy (&sdc);
            res = RES_OK;
            return res;
            
            
        /*
	switch (pdrv) {
	case ATA :
		// translate the arguments here

		result = ATA_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;

	case MMC :
		// translate the arguments here

		result = MMC_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;

	case USB :
		// translate the arguments here

		result = USB_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;
	}
        
	return RES_PARERR;*/
}
Beispiel #4
0
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;
}