Ejemplo n.º 1
0
//***************************************************************************
//Function: to read multiple blocks from SD card & send every block to UART
//Arguments: none
//return: unsigned char; will be 0 if no error,
// otherwise the response byte will be sent
//****************************************************************************
unsigned char SD_readMultipleBlock (unsigned long startBlock, unsigned long totalBlocks) {
    unsigned char response;
    unsigned int i, retry=0;

    retry = 0;
    response = SD_sendCommand(READ_MULTIPLE_BLOCKS, startBlock <<9);
    //read a Block command
    //block address converted to starting address of 512 byte Block
    if(response != 0x00) {
        //check for SD status: 0x00 - OK (No flags set)
        return response;
    }

    SD_CS_ASSERT;

    while( totalBlocks ) {
        retry = 0;
        while(SPI_receive() != 0xfe) {
            //wait for start block token 0xfe (0x11111110)
            if(retry++ > 0xfffe) {
                SD_CS_DEASSERT;
                return 1;
            } //return if time-out
        }

        for(i=0; i<512; i++) {
            //read 512 bytes
            buffer[i] = SPI_receive();
        }

        SPI_receive();
        //receive incoming CRC (16-bit), CRC is ignored here
        SPI_receive();

        SPI_receive();
        //extra 8 cycles
        TX_NEWLINE;
        transmitString_F(PSTR(" --------- "));
        TX_NEWLINE;

        for(i=0; i<512; i++) {
            //send the block to UART
            if(buffer[i] == '~') {
                break;
            }
            transmitByte ( buffer[i] );
        }

        TX_NEWLINE;
        transmitString_F(PSTR(" --------- "));
        TX_NEWLINE;
        totalBlocks--;
    }

    SD_sendCommand(STOP_TRANSMISSION, 0); //command to stop transmission
    SD_CS_DEASSERT;
    SPI_receive(); //extra 8 clock pulses

    return 0;
}
Ejemplo n.º 2
0
//******************************************************************
//Function: to initialize the SD card in SPI mode
//Arguments: none
//return: unsigned char; will be 0 if no error,
// otherwise the response byte will be sent
//******************************************************************
unsigned char SD_init(void)
{
unsigned char i, response, retry=0 ;

SD_CS_ASSERT;
do
{
   for(i=0;i<10;i++)
      SPI_transmit(0xff);
   response = SD_sendCommand(GO_IDLE_STATE, 0);//send 'reset & go idle' command
   retry++;
   if(retry>0xfe) {transmitString_F(PSTR("SD init fail..")); return 1; }//time out
} while(response != 0x01);

SD_CS_DEASSERT;

SPI_transmit (0xff);
SPI_transmit (0xff);

retry = 0;

do
{
    response = SD_sendCommand(SEND_OP_COND, 0); //activate card's initialization process

    response = SD_sendCommand(SEND_OP_COND, 0); //resend command (for compatibility with some cards)
    retry++;
    if(retry>0xfe) return 1; //time out
}while(response);

SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode
SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512

return 0; //normal return
}
Ejemplo n.º 3
0
//***************************************************************************
//Function	: to read multiple blocks from SD card & send every block to UART
//Arguments	: none
//return	: uint8_t; will be 0 if no error,
// 			  otherwise the response byte will be sent
//****************************************************************************
uint8_t SD_readMultipleBlock (uint32_t startBlock, uint32_t totalBlocks)
{
	uint8_t response;
	uint16_t i, retry=0;



	response = SD_sendCommand(READ_MULTIPLE_BLOCKS, startBlock); //write a Block command
  
	if(response != 0x00) 
		return(response); 				//check for SD status: 0x00 - OK (No flags set)

	SD_CS_ASSERT;

	while( totalBlocks )
	{
		retry = 0;
		while(SPI_Receive8(SD_SPI_PORT) != 0xfe) 	//wait for start block token 0xfe (0x11111110)
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		} 								//return if time-out

		for(i=0; i<512; i++) 			//read 512 bytes
			buffer[i] = SPI_Receive8(SD_SPI_PORT);

		SPI_Receive8(SD_SPI_PORT); 				//receive incoming CRC (16-bit), CRC is ignored here
		SPI_Receive8(SD_SPI_PORT);

		SPI_Receive8(SD_SPI_PORT); 				//extra 8 cycles
//		printf_P(PSTR("\n --------- \n"));

		for(i=0; i<512; i++) 			//send the block to UART
		{
			if(buffer[i] == '~') 
				break;
//			printf("%c", buffer[i] );
		}

//		printf_P(PSTR("\n --------- \n"));
		totalBlocks--;
	}

	SD_sendCommand(STOP_TRANSMISSION, 0); //command to stop transmission
	SD_CS_DEASSERT;
	SPI_Receive8(SD_SPI_PORT); 					//extra 8 clock pulses

	return(0);
}
Ejemplo n.º 4
0
//******************************************************************
//Function	: to write to a single block of SD card
//Arguments	: none
//return	: uint8_t; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
uint8_t SD_writeSingleBlock(uint32_t startBlock)			//, uint8_t atomic)
{
	uint8_t response;
	uint16_t i, retry=0;

	if(Atomic)
	{
		LIS_SD_ATOMIZE;					// disable INT0	to make it quasi atomic
	}

	response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock); //write a Block command
  
	if(response != 0x00) 
		return(response); 				//check for SD status: 0x00 - OK (No flags set)

	SD_CS_ASSERT;

	SPI_Send8(0xfe,SD_SPI_PORT);   		//Send start block token 0xfe (0x11111110)
		
	for(i=0; i<512; i++)    			//send 512 bytes data
		SPI_Send8(buffer[i],SD_SPI_PORT);

	SPI_Send8(0xff,SD_SPI_PORT);   		//transmit dummy CRC (16-bit), CRC is ignored here
	SPI_Send8(0xff,SD_SPI_PORT);

	response = SPI_Receive8(SD_SPI_PORT);

	if( (response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted
	{                              	//AAA='101'-data rejected due to CRC error
		SD_CS_DEASSERT;              //AAA='110'-data rejected due to write error
		return(response);
	}

	while(!SPI_Receive8(SD_SPI_PORT)) //wait for SD card to complete writing and get idle
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		}

	SD_CS_DEASSERT;
	SPI_Send8(0xff,SD_SPI_PORT);   //just spend 8 clock cycle delay before reasserting the CS line
	SD_CS_ASSERT;         //re-asserting the CS line to verify if card is still busy

	while(!SPI_Receive8(SD_SPI_PORT)) //wait for SD card to complete writing and get idle
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		}

	SD_CS_DEASSERT;

	if(Atomic)
	{
		LIS_SD_DEATOMIZE;					// disable INT0	to make it quasi atomic
	}

	return(0);
}
Ejemplo n.º 5
0
//******************************************************************
//Function: to read a single block from SD card
//Arguments: none
//return: unsigned char; will be 0 if no error,
// otherwise the response byte will be sent
//******************************************************************
unsigned char SD_readSingleBlock(unsigned long startBlock) {
    unsigned char response;
    unsigned int i, retry=0;

    response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock<<9);
    //read a Block command
    //block address converted to starting address of 512 byte Block
    if(response != 0x00) {
        //check for SD status: 0x00 - OK (No flags set)
        return response;
    }

    SD_CS_ASSERT;

    while(SPI_receive() != 0xfe) {
        //wait for start block token 0xfe (0x11111110)
        if(retry++ > 0xfffe) {
            SD_CS_DEASSERT;
            return 1;
        } //return if time-out
    }

    for(i=0; i<512; i++) {
        //read 512 bytes
        buffer[i] = SPI_receive();
    }

    SPI_receive(); //receive incoming CRC (16-bit), CRC is ignored here
    SPI_receive();

    SPI_receive(); //extra 8 clock pulses
    SD_CS_DEASSERT;

    return 0;
}
Ejemplo n.º 6
0
//******************************************************************
//Function	: to read a single block from SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_readSingleBlock(unsigned long startBlock, char buffer[BLOCK])
{
unsigned char response;
unsigned int i, retry=0;

 response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); //read a Block command
 
 if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set)

SD_CS_ASSERT;

retry = 0;
while(SpiReceive() != 0xfe) //wait for start block token 0xfe (0x11111110)
  if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;} //return if time-out

for(i=0; i<BLOCK; i++) //read 512 bytes
  buffer[i] = SpiReceive();

SpiReceive(); //receive incoming CRC (16-bit), CRC is ignored here
SpiReceive();

SpiReceive(); //extra 8 clock pulses
SD_CS_DEASSERT;

return 0;
}
Ejemplo n.º 7
0
uint8_t SD_Idle(uint8_t power)
{
	uint8_t response, retry = 0;
	
	SPI_LOW_SPEED;

	SD_CS_ASSERT;
	do
	{
		response = SD_sendCommand(GO_IDLE_STATE, 0); //send 'reset & go idle' command
		retry++;
		if(retry>0x20) 
			return(0xff);   	//time out, card not detected
	} while(response != 0x01);

	SD_CS_DEASSERT;
	SPI_Send8(0xff,SD_SPI_PORT);
	SPI_Send8(0xff,SD_SPI_PORT);
	
	if(power)
	{
		SD_Status |= SDSTAT_IDLE;
		return(1);
	}

	SD_POWER_OFF;					// switch off power for SD card
	SPI_Init(SPI_SD_OFF);			// disable SPI and tristate the port
//	SD_Status |= SDSTAT_NOTINIT;	// only if first time powered on - checking the type of card after init!!!
	SD_Status &= ~(SDSTAT_INIT | SDSTAT_POWER);
	
	return(0);
}
Ejemplo n.º 8
0
Archivo: SD.c Proyecto: jevgeniS/Xjalad
//******************************************************************
//Function	: to read a single block from SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_readSingleBlock(unsigned long startBlock)
{
unsigned char response;
unsigned int i, retry=0;
//transmitString_F(PSTR("\nSD_readsingleBlock send command READ_SINGLE_BLOCK"));
 response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); //read a Block command
 
 if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set)

SD_CS_ASSERT;
//transmitString_F(PSTR("\nSD_readsingleBlock SD status "));
retry = 0;
while(receiveByte_SPI() != 0xfe) //wait for start block token 0xfe (0x11111110)
  if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;} //return if time-out

for(i=0; i<512; i++) //read 512 bytes
  buffer[i] = receiveByte_SPI();

//transmitString_F(PSTR("\nSD_readsingleBlock After filling buffer"));
receiveByte_SPI(); //receive incoming CRC (16-bit), CRC is ignored here
receiveByte_SPI();

receiveByte_SPI(); //extra 8 clock pulses
SD_CS_DEASSERT;

//transmitString_F(PSTR("\nSD_readsingleBlock ending"));
return 0;
}
Ejemplo n.º 9
0
unsigned char SD_readSingleBlock(unsigned long startBlock)
{
	unsigned char response;
	unsigned int i, retry=0;

		 response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); 							/**read a Block command*/

		 if(response != 0x00) return response; 												/**check if SD status: 0x00 - OK (no flag activated)*/

		SD_CS_ASSERT;

		retry = 0;
		while(SPI_receive() != 0xfe) 														/**wait for start block to get the 0xfe value*/
		  if(retry++ > 0xfffe){
			  	 	 SD_CS_DEASSERT;
			  	 	 return 1;  } 															/**function output  time-out*/

		for(i=0; i<512; i++) 																/**read every 512 bytes*/
			buffer[i] = SPI_receive();


		SPI_receive(); 																		/**let 8 clock pulses*/
		SD_CS_DEASSERT;

	return 0;
}
//******************************************************************
//Function	: to read a single block from SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_readSingleBlock(char *inputbuffer,uint32_t startBlock)
{
    unsigned char response;
    uint16_t i, retry=0;

    response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); //read a Block command

    if(response != 0x00)
    {
        return response; //check for SD status: 0x00 - OK (No flags set)
    }

    SPI_EnableChipSelect();

    retry = 0;
    while(SPI_Read() != 0xfe) //wait for start block token 0xfe (0x11111110)
    {
        if(retry++ > 0xfffe)
        {
            SPI_DisableChipSelect();
            return 1; //return if time-out
        }
    }

    for(i=0; i<512; i++) //read 512 bytes
        inputbuffer[i] = SPI_Read();

    SPI_Read(); //receive incoming CRC (16-bit), CRC is ignored here
    SPI_Read();

    SPI_Read(); //extra 8 clock pulses
    SPI_DisableChipSelect();

    return 0;
}
Ejemplo n.º 11
0
void init_SD(void) 
{
		unsigned char i, response, retry=0 ;

		ENABLE_SD;
		do
		{
				for(i=0;i<10;i++)
					SPI_sendchar(0xff);
				response = SD_sendCommand(GO_IDLE_STATE, 0);      //send 'reset & go idle' command
				retry++;
				if(retry>0xfe) 
				{
					printString("SD init fail..Code: ");
					printByte(response);
					printString("Retry: ");
					printByte(retry);
					printString("\r\n");
					return ;
				} //time out
			 
		} while(response != 0x01);

		DISABLE_SD;
		SPI_sendchar (0xff);
		SPI_sendchar (0xff);

		retry = 0;

		do
		{
				response = SD_sendCommand(SEND_OP_COND, 0); //activate card's initialization process
				response = SD_sendCommand(SEND_OP_COND, 0); //same command sent again for compatibility with some cards
				retry++;
				if(retry>0xfe)
				{
					printString("SD Failed: SEND_OP_COND\r\n");
					return ; //time out
				}
		}while(response);

		SD_sendCommand(CRC_ON_OFF, 0); //disable CRC; deafault - CRC disabled in SPI mode
		SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512

		printString("SD initialized\r\n");
		return;
}
Ejemplo n.º 12
0
//******************************************************************
//Function: to write to a single block of SD card
//Arguments: none
//return: unsigned char; will be 0 if no error,
// otherwise the response byte will be sent
//******************************************************************
unsigned char SD_writeSingleBlock(unsigned long startBlock) {
    unsigned char response;
    unsigned int i, retry=0;

    response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock<<9);
    //write a Block command
    if(response != 0x00) {
        //check for SD status: 0x00 - OK (No flags set)
        return response;
    }

    SD_CS_ASSERT;

    SPI_transmit(0xfe);     //Send start block token 0xfe (0x11111110)

    for(i=0; i<512; i++) {
        //send 512 bytes data
        SPI_transmit(buffer[i]);
    }

    SPI_transmit(0xff);     //transmit dummy CRC (16-bit), CRC is ignored here
    SPI_transmit(0xff);

    response = SPI_receive();

    if( (response & 0x1f) != 0x05) {
        //response= 0xXXX0AAA1 ; AAA='010' - data accepted
        //AAA='101'-data rejected due to CRC error
        SD_CS_DEASSERT;
        //AAA='110'-data rejected due to write error
        return response;
    }

    while(!SPI_receive()) {
        //wait for SD card to complete writing and get idle
        if(retry++ > 0xfffe) {
            SD_CS_DEASSERT;
            return 1;
        }
    }

    SD_CS_DEASSERT;
    SPI_transmit(0xff);
    //just spend 8 clock cycle delay before reasserting the CS line
    SD_CS_ASSERT;
    //re-asserting the CS line to verify if card is still busy

    while(!SPI_receive()) {
        //wait for SD card to complete writing and get idle
        if(retry++ > 0xfffe) {
            SD_CS_DEASSERT;
            return 1;
        }
    }
    SD_CS_DEASSERT;
    return 0;
}
Ejemplo n.º 13
0
unsigned char SD_erase (unsigned long startBlock, unsigned long totalBlocks)
{
	unsigned char response;

		response = SD_sendCommand(ERASE_BLOCK_START_ADDR, startBlock); 						/**send address of starting block*/
		if(response != 0x00) 																/**check the SD status: 0x00 - OK (No flags set)*/
		  return response;

		response = SD_sendCommand(ERASE_BLOCK_END_ADDR,(startBlock + totalBlocks - 1));		/**send adress of end block*/
		if(response != 0x00)																/**check the SD status: 0x00 - OK (No flags set)*/
		  return response;

		response = SD_sendCommand(ERASE_SELECTED_BLOCKS, 0); 								/**erase all selected blocks*/
		if(response != 0x00)																/**check SD status: 0x00 - OK (No flags set)*/
		  return response;

	return 0; //normal return
}
Ejemplo n.º 14
0
//*****************************************************************
//Function	: to erase specified no. of blocks of SD card
//Arguments	: none
//return	: uint8_t; will be 0 if no error,
// 			  otherwise the response byte will be sent
//*****************************************************************
uint8_t SD_erase (uint32_t startBlock, uint32_t totalBlocks)
{
	uint8_t response;

	response = SD_sendCommand(ERASE_BLOCK_START_ADDR, startBlock); 					//send starting block address
	if(response != 0x00) 																//check for SD status: 0x00 - OK (No flags set)
		return(response);

	response = SD_sendCommand(ERASE_BLOCK_END_ADDR,(startBlock + totalBlocks - 1)); 	//send end block address
	if(response != 0x00)
		return(response);

	response = SD_sendCommand(ERASE_SELECTED_BLOCKS, 0); 								//erase all selected blocks
	if(response != 0x00)
		return(response);

	return(0); 																		//normal return
}
Ejemplo n.º 15
0
//*****************************************************************
//Function	: to erase specified no. of blocks of SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//*****************************************************************
unsigned char SD_erase (unsigned long startBlock, unsigned long totalBlocks)
{
unsigned char response;

response = SD_sendCommand(ERASE_BLOCK_START_ADDR, startBlock); //send starting block address
if(response != 0x00) //check for SD status: 0x00 - OK (No flags set)
  return response;

response = SD_sendCommand(ERASE_BLOCK_END_ADDR,(startBlock + totalBlocks - 1)); //send end block address
if(response != 0x00)
  return response;

response = SD_sendCommand(ERASE_SELECTED_BLOCKS, 0); //erase all selected blocks
if(response != 0x00)
  return response;

return 0; //normal return
}
Ejemplo n.º 16
0
unsigned char SD_readSingleBlock(unsigned long startBlock)
{
    /*int i;
    uint16_t ix;
    char r1 =  Command(0x51,0,512,0xFF);
    for (ix = 0; ix < 50000; ix++) {
        if (r1 == (char)0x00) break;
        r1 = SPI_sendchar(0xFF);
    }
    if (r1 != (char)0x00) {
    return 1;
    }
    //read from the card will start after the framework
    while(SPI_sendchar(0xFF) != (char)0xFE);
    for(i=0; i < 512; i++) {
        while(!(SPSR & (1<<SPIF)));
        buffer[i] = SPDR;
        SPDR = SPI_sendchar(0xFF);
    }
    SPI_sendchar(0xFF);
    SPI_sendchar(0xFF);
    return 0;*/
    unsigned char response;
		unsigned int i, retry=0;

		response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock<<9); //read a Block command
		//block address converted to starting address of 512 byte Block
		if(response != 0x00) //check for SD status: 0x00 - OK (No flags set)
			return response;

		ENABLE_SD;

		retry = 0;
		while(SPI_sendchar(0xFF) != 0xfe) //wait for start block token 0xfe (0x11111110)
		{
			if(retry++ > 0xfffe)
			{
				printString("Error reading\r\n");
				DISABLE_SD;
				return 1;
			} //return if time-out
		}

		for(i=0; i<512; i++) //read 512 bytes
			buffer[i] = SPI_sendchar(0xFF);

		SPI_sendchar(0xFF); //receive incoming CRC (16-bit), CRC is ignored here
		SPI_sendchar(0xFF);

		SPI_sendchar(0xFF); //extra 8 clock pulses
		DISABLE_SD;
		//printString("Reading succesful\r\n");

		return 0;
}
//******************************************************************
//Function	: to write to a single block of SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_writeSingleBlock(char *inputbuffer,uint32_t startBlock)
{
    unsigned char response;
    uint16_t i, retry=0;

    response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock); //write a Block command

    if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set)

    SPI_EnableChipSelect();

    SPI_Write(0xfe);     //Send start block token 0xfe (0x11111110)

    for(i=0; i<512; i++)    //send 512 bytes data
        SPI_Write(inputbuffer[i]);

    SPI_Write(0xff);     //transmit dummy CRC (16-bit), CRC is ignored here
    SPI_Write(0xff);

    response = SPI_Read();

    if( (response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted
    {                              //AAA='101'-data rejected due to CRC error
        SPI_DisableChipSelect();              //AAA='110'-data rejected due to write error
        return response;
    }

    while(!SPI_Read()) //wait for SD card to complete writing and get idle
    {
        if(retry++ > 0xfffe)
        {
            SPI_DisableChipSelect();
            return 1;
        }
    }

    SPI_DisableChipSelect();
    SPI_Write(0xff);   //just spend 8 clock cycle delay before reasserting the CS line
    SPI_EnableChipSelect();         //re-asserting the CS line to verify if card is still busy

    while(!SPI_Read()) //wait for SD card to complete writing and get idle
    {
        if(retry++ > 0xfffe)
        {
            SPI_DisableChipSelect();
            return 1;
        }
    }
    SPI_DisableChipSelect();


    return 0;
}
Ejemplo n.º 18
0
unsigned char SD_writeSingleBlock(unsigned long startBlock)
{
	unsigned char response;
	unsigned int i, retry=0;

		 response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock); 						/** block's writing command*/

		 if(response != 0x00) return response; 												/**check if SD status: 0x00 - OK (no flag activated)*/

		SD_CS_ASSERT;

		SPI_transmit(0xfe);     															/**send the 0xfe block (page 197 datasheet SD)*/

		for(i=0; i<512; i++)    															/**send the 512 bytes data*/
			SPI_transmit(buffer[i]);

		SPI_transmit(0xff);     //transmit dummy CRC (16-bit), CRC is ignored here
		SPI_transmit(0xff);

		response = SPI_receive();

		if( (response & 0x1f) != 0x05)														 /**response= 0xXXX0AAA1 ; if: {	AAA='010' - data accepted
		                              						 	 																AAA='101'-data rejected due to CRC error
																																AAA='110'-data rejected due to write error
																															}*/
		{
			SD_CS_DEASSERT;
			return response;
		}

		while(!SPI_receive()) 																/**wait for SD card to complete the writing and go to get idle state*/
			if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}									/**function output time-out*/

		SD_CS_DEASSERT;
		SPI_transmit(0xff);   																/**allow a 8 clock cycles delay before CS line reaffirming*/
		SD_CS_ASSERT;         																/**CS line reaffirming to check if the card is still busy*/

		while(!SPI_receive()) 																/**wait for SD card to complete the writing and go to get idle state*/
			if(retry++ > 0xfffe){
				SD_CS_DEASSERT; return 1;
			}

		SD_CS_DEASSERT;

	return 0;
}
Ejemplo n.º 19
0
//******************************************************************
//Function	: to read a single block from SD card
//Arguments	: none
//return	: uint8_t; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
uint8_t SD_readSingleBlock(uint32_t startBlock)			//, uint8_t atomic)
{
	uint8_t response;
	uint16_t i, retry=0;

	if(Atomic)
	{
		LIS_SD_ATOMIZE;					// disable INT0	to make it quasi atomic
	}

	response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); //read a Block command
 
	if(response != 0x00) 
		return(response); 			//check for SD status: 0x00 - OK (No flags set)

	SD_CS_ASSERT;

	retry = 0;
	while(SPI_Receive8(SD_SPI_PORT) != 0xfe) 	//wait for start block token 0xfe (0x11111110)
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		} 							//return if time-out

	for(i=0; i<512; i++) 			//read 512 bytes
		buffer[i] = SPI_Receive8(SD_SPI_PORT);

	SPI_Receive8(SD_SPI_PORT);		//receive incoming CRC (16-bit), CRC is ignored here
	SPI_Receive8(SD_SPI_PORT);

	SPI_Receive8(SD_SPI_PORT);		//extra 8 clock pulses
	SD_CS_DEASSERT;

	if(Atomic)
	{
		LIS_SD_DEATOMIZE;					// disable INT0	to make it quasi atomic
	}

	return(0);
}
Ejemplo n.º 20
0
unsigned char SD_writeSingleBlock(unsigned long startBlock)
{ 
    uint8_t wbr;
    
    unsigned char response;
		unsigned int i;
		DISABLE_SD;
		response = SD_sendCommand(24, startBlock<<9); //write a Block command
		if(response != 0x00) //check for SD status: 0x00 - OK (No flags set)
			return response;

		ENABLE_SD;

		SPI_sendchar(0xfe);     //Send start block token 0xfe (0x11111110)

		for(i=0; i<512; i++)    //send 512 bytes data
		{
			SPI_sendchar(buffer[i]);
			//SPI_sendchar(0x12);
		}
    
    SPI_sendchar(0xff); //transmit dummy CRC (16-bit), CRC is ignored here
		SPI_sendchar(0xff);

		wbr = SPI_sendchar(0xff);
    //write block response and testing error
    wbr &= 0x1F;
    //zeroing top three indeterminate bits 0b.0001.1111
    if (wbr != 0x05) 
    {
			printString("ERooR\r\n");
			printByte(wbr);
		  return 1;
    }
    while(SPI_sendchar(0xFF) != (char)0xFF);
		//printString("File writed\r\n");
    //wait for the completion of a write operation to the card
    DISABLE_SD;
    return 0;
}
Ejemplo n.º 21
0
/*
  * fct_SDCard.c
 *
 *  Created on: 21 juin 2016
 *      Author: formateur
 */

#include <avr/io.h>
#include <util/delay.h>

#include "../lib/usart.h"
#include "../lib/fct_spi.h"
#include "../lib/fct_SDCard.h"



//******************************************************************
//Function	: to initialize the SD/SDHC card in SPI mode
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_init(void)
{
	unsigned char response, SD_version;
	unsigned int retry=0 ;
	int i=0;

	//Spi init
	spi_init();																/**send init on spi peripheral**/

	for(i=0;i<10;i++){
		SD_CS_ASSERT;														/**set chip select*/
		do
		{
		   response = SD_sendCommand(GO_IDLE_STATE, 0); 					/**send software reset */
		   retry++;
		   if(retry>0x20){
			   //
			  USART0_print("\rpas de carte\n");
			   //
			   return 1;  													/**time out, card not detected*/
		   }


		} while(response != 0x01);											/**response= 0x01 : card in idle state and no error*/

		SD_CS_DEASSERT;
		SPI_transmit (0xff);												/**1st byte transmission  */
		SPI_transmit (0xff);												/**2nd byte transmission */

		retry = 0;															/**reset retries counter*/

		SD_version = 2; //default set to SD compliance with ver2.x;
						//this may change after checking the next command
		do
		{
		response = SD_sendCommand(SEND_IF_COND,0x000001AA); 				/**check power supply status,for SDHC card*/
		retry++;
		if(retry>0xfe)
		   {
			  SD_version = 1;
			  cardType = 1;
			  break;
		   } //time out

		}while(response != 0x01);

		retry = 0;

		do
		{
		response = SD_sendCommand(APP_CMD,0); //CMD55, must be sent before sending any ACMD command
		response = SD_sendCommand(SD_SEND_OP_COND,0x40000000); //ACMD41

		retry++;
		if(retry>0xfe)
		   {
			  USART0_print("\rinitialisation a échoué\n");
			  return 2;  //time out, card initialization failed
		   }

		}while(response != 0x00);


		retry = 0;
		SDHC_flag = 0;

		if (SD_version == 2)
		{
		   do
		   {
			 response = SD_sendCommand(READ_OCR,0);
			 retry++;
			 if(retry>0xfe)
			 {
			   cardType = 0;
			   break;
			 } //time out

		   }while(response != 0x00);

		   if(SDHC_flag == 1) cardType = 2;
		   else cardType = 3;
		}

		//SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode
		//SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512; default size is 512

		//
		switch (cardType)													/** switch for card type (to check communication with the card)*/
		{
		case 1 :  USART0_print("\rver1.x\n");break;
		case 2 :  USART0_print("\rSDHC\n");break;
		case 3 :  USART0_print("\rver2.x\n");break;
		default : USART0_print("runknown Sd card\n");
		}
		//

	return 0;break;															/**successful return*/
	}
	_delay_ms(1);															/**give some time to end the init*/
	return 0;
}


//******************************************************************
//Function	: to send a command to SD card
//Arguments	: unsigned char (8-bit command value)
// 			  & unsigned long (32-bit command argument)
//return	: unsigned char; response byte
//******************************************************************

unsigned char SD_sendCommand(unsigned char cmd, unsigned long arg)
{
	unsigned char response, retry=0, status;

	//SD card accepts byte address while SDHC accepts block address in multiples of 512
	//so, if it's SD card we need to convert block address into corresponding byte address by
	//multipying it with 512. which is equivalent to shifting it left 9 times
	//following 'if' loop does that

		if(SDHC_flag == 0)
			if(cmd == READ_SINGLE_BLOCK     ||
			   cmd == READ_MULTIPLE_BLOCKS  ||
			   cmd == WRITE_SINGLE_BLOCK    ||
			   cmd == WRITE_MULTIPLE_BLOCKS ||
			   cmd == ERASE_BLOCK_START_ADDR||
			   cmd == ERASE_BLOCK_END_ADDR )
			   {
				 	 arg = arg << 9;
			   }

		SD_CS_ASSERT;

		SPI_transmit(cmd | 0x40); //send command, first two bits always '01'
		SPI_transmit(arg>>24);
		SPI_transmit(arg>>16);
		SPI_transmit(arg>>8);
		SPI_transmit(arg);

		if(cmd == SEND_IF_COND)	 //it is compulsory to send correct CRC for CMD8 (CRC=0x87) & CMD0 (CRC=0x95)
			SPI_transmit(0x87);    //for remaining commands, CRC is ignored in SPI mode
		else
			SPI_transmit(0x95);

		while((response = SPI_receive()) == 0xff) //wait response
			if(retry++ > 0xfe) break; //time out error

		if(response == 0x00 && cmd == 58)  //checking response of CMD58
		{
			  status = SPI_receive() & 0x40;     //first byte of the OCR register (bit 31:24)
			  if(status == 0x40) SDHC_flag = 1;  //we need it to verify SDHC card
			  else SDHC_flag = 0;

			  SPI_receive(); //remaining 3 bytes of the OCR register are ignored here
			  SPI_receive(); //one can use these bytes to check power supply limits of SD
			  SPI_receive();
		}

		SPI_receive(); //extra 8 CLK
		SD_CS_DEASSERT;


	return response; //return state
}

//*****************************************************************
//Function	: to erase specified no. of blocks of SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//*****************************************************************

unsigned char SD_erase (unsigned long startBlock, unsigned long totalBlocks)
{
	unsigned char response;

		response = SD_sendCommand(ERASE_BLOCK_START_ADDR, startBlock); 						/**send address of starting block*/
		if(response != 0x00) 																/**check the SD status: 0x00 - OK (No flags set)*/
		  return response;

		response = SD_sendCommand(ERASE_BLOCK_END_ADDR,(startBlock + totalBlocks - 1));		/**send adress of end block*/
		if(response != 0x00)																/**check the SD status: 0x00 - OK (No flags set)*/
		  return response;

		response = SD_sendCommand(ERASE_SELECTED_BLOCKS, 0); 								/**erase all selected blocks*/
		if(response != 0x00)																/**check SD status: 0x00 - OK (No flags set)*/
		  return response;

	return 0; //normal return
}

//******************************************************************
//Function	: to read a single block from SD card
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************

unsigned char SD_readSingleBlock(unsigned long startBlock)
{
	unsigned char response;
	unsigned int i, retry=0;

		 response = SD_sendCommand(READ_SINGLE_BLOCK, startBlock); 							/**read a Block command*/

		 if(response != 0x00) return response; 												/**check if SD status: 0x00 - OK (no flag activated)*/

		SD_CS_ASSERT;

		retry = 0;
		while(SPI_receive() != 0xfe) 														/**wait for start block to get the 0xfe value*/
		  if(retry++ > 0xfffe){
			  	 	 SD_CS_DEASSERT;
			  	 	 return 1;  } 															/**function output  time-out*/

		for(i=0; i<512; i++) 																/**read every 512 bytes*/
			buffer[i] = SPI_receive();


		SPI_receive(); 																		/**let 8 clock pulses*/
		SD_CS_DEASSERT;

	return 0;
}

//******************************************************************
//Function	: to write to a single block of SD card
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************

unsigned char SD_writeSingleBlock(unsigned long startBlock)
{
	unsigned char response;
	unsigned int i, retry=0;

		 response = SD_sendCommand(WRITE_SINGLE_BLOCK, startBlock); 						/** block's writing command*/

		 if(response != 0x00) return response; 												/**check if SD status: 0x00 - OK (no flag activated)*/

		SD_CS_ASSERT;

		SPI_transmit(0xfe);     															/**send the 0xfe block (page 197 datasheet SD)*/

		for(i=0; i<512; i++)    															/**send the 512 bytes data*/
			SPI_transmit(buffer[i]);

		SPI_transmit(0xff);     //transmit dummy CRC (16-bit), CRC is ignored here
		SPI_transmit(0xff);

		response = SPI_receive();

		if( (response & 0x1f) != 0x05)														 /**response= 0xXXX0AAA1 ; if: {	AAA='010' - data accepted
		                              						 	 																AAA='101'-data rejected due to CRC error
																																AAA='110'-data rejected due to write error
																															}*/
		{
			SD_CS_DEASSERT;
			return response;
		}

		while(!SPI_receive()) 																/**wait for SD card to complete the writing and go to get idle state*/
			if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}									/**function output time-out*/

		SD_CS_DEASSERT;
		SPI_transmit(0xff);   																/**allow a 8 clock cycles delay before CS line reaffirming*/
		SD_CS_ASSERT;         																/**CS line reaffirming to check if the card is still busy*/

		while(!SPI_receive()) 																/**wait for SD card to complete the writing and go to get idle state*/
			if(retry++ > 0xfffe){
				SD_CS_DEASSERT; return 1;
			}

		SD_CS_DEASSERT;

	return 0;
}



#ifndef FAT_TESTING_ONLY

//***************************************************************************/
//Function	: to read multiple blocks from SD card & send every block to UART
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//****************************************************************************/
unsigned char SD_readMultipleBlock (unsigned long startBlock, unsigned long totalBlocks)
{
unsigned char response;
unsigned int i, retry=0;

retry = 0;

response = SD_sendCommand(READ_MULTIPLE_BLOCKS, startBlock); //write a Block command

if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set)

SD_CS_ASSERT;

while( totalBlocks )
{
  retry = 0;
  while(SPI_receive() != 0xfe) //wait for start block token 0xfe (0x11111110)
  if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;} //return if time-out

  for(i=0; i<512; i++) //read 512 bytes
    buffer[i] = SPI_receive();

  SPI_receive(); //receive incoming CRC (16-bit), CRC is ignored here
  SPI_receive();

  SPI_receive(); //extra 8 cycles
  TX_NEWLINE;
  transmitString_F(PSTR(" --------- "));
  TX_NEWLINE;

  for(i=0; i<512; i++) //send the block to UART
  {
    if(buffer[i] == '~') break;
    transmitByte ( buffer[i] );
  }

  TX_NEWLINE;
  transmitString_F(PSTR(" --------- "));
  TX_NEWLINE;
  totalBlocks--;
}

SD_sendCommand(STOP_TRANSMISSION, 0); //command to stop transmission
SD_CS_DEASSERT;
SPI_receive(); //extra 8 clock pulses

return 0;
}

//***************************************************************************/
//Function: to receive data from UART and write to multiple blocks of SD card
//Arguments: none
//return: unsigned char; will be 0 if no error,
// otherwise the response byte will be sent
//****************************************************************************/
unsigned char SD_writeMultipleBlock(unsigned long startBlock, unsigned long totalBlocks)
{
unsigned char response, data;
unsigned int i, retry=0;
unsigned long blockCounter=0, size;

response = SD_sendCommand(WRITE_MULTIPLE_BLOCKS, startBlock); //write a Block command

if(response != 0x00) return response; //check for SD status: 0x00 - OK (No flags set)

SD_CS_ASSERT;

TX_NEWLINE;
transmitString_F(PSTR(" Enter text (End with ~): "));
TX_NEWLINE;

while( blockCounter < totalBlocks )
{//e. Cette librairie est dépendante de la librairie SPI. Voici le code à m
   i=0;
   do
   {
     data = receiveByte();
     if(data == 0x08)	//'Back Space' key pressed
	 {
	   if(i != 0)
	   {
	     transmitByte(data);
	     transmitByte(' ');
	     transmitByte(data);
	     i--;
		 size--;
	   }
	   continue;
	 }
     transmitByte(data);
     buffer[i++] = data;
     if(data == 0x0d)
     {
        transmitByte(0x0a);
        buffer[i++] = 0x0a;
     }
	 if(i == 512) break;
   }while (data != '~');

   TX_NEWLINE;
   transmitString_F(PSTR(" ---- "));
   TX_NEWLINE;

   SPI_transmit(0xfc); //Send start block token 0xfc (0x11111100)

   for(i=0; i<512; i++) //send 512 bytes data
     SPI_transmit( buffer[i] );

   SPI_transmit(0xff); //transmit dummy CRC (16-bit), CRC is ignored here
   SPI_transmit(0xff);

   response = SPI_receive();
   if( (response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted
   {                              //AAA='101'-data rejected due to CRC error
      SD_CS_DEASSERT;             //AAA='110'-data rejected due to write error
      return response;
   }

   while(!SPI_receive()) //wait for SD card to complete writing and get idle
     if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}

   SPI_receive(); //extra 8 bits
   blockCounter++;
}

SPI_transmit(0xfd); //send 'stop transmission token'

retry = 0;
	   if(data == '~')
	   {
		  fileSize--;	//to remove the last entered '~' character
		  i--;

		  for(;i<512;i++)  //fill the rest of the buffer with 0x00
			buffer[i]= 0x00;

		  error = SD_writeSingleBlock (startBlock);

		  txString(_COM1, "data = ~\n");
		  break;
	   }
while(!SPI_receive()) //wait for SD card to complete writing and get idle
   if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}

SD_CS_DEASSERT;
SPI_transmit(0xff); //just spend 8 clock cycle delay before reasserting the CS signal
SD_CS_ASSERT; //re assertion of the CS signal is required to verify if card is still busy

while(!SPI_receive()) //wait for SD card to complete writing and get idle
   if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}
SD_CS_DEASSERT;

return 0;
}
Ejemplo n.º 22
0
//******************************************************************
//Function	: to initialize the SD/SDHC card in SPI mode
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_init(void)
{
	unsigned char response, SD_version;
	unsigned int retry=0 ;
	int i=0;

	//Spi init
	spi_init();																/**send init on spi peripheral**/

	for(i=0;i<10;i++){
		SD_CS_ASSERT;														/**set chip select*/
		do
		{
		   response = SD_sendCommand(GO_IDLE_STATE, 0); 					/**send software reset */
		   retry++;
		   if(retry>0x20){
			   //
			  USART0_print("\rpas de carte\n");
			   //
			   return 1;  													/**time out, card not detected*/
		   }


		} while(response != 0x01);											/**response= 0x01 : card in idle state and no error*/

		SD_CS_DEASSERT;
		SPI_transmit (0xff);												/**1st byte transmission  */
		SPI_transmit (0xff);												/**2nd byte transmission */

		retry = 0;															/**reset retries counter*/

		SD_version = 2; //default set to SD compliance with ver2.x;
						//this may change after checking the next command
		do
		{
		response = SD_sendCommand(SEND_IF_COND,0x000001AA); 				/**check power supply status,for SDHC card*/
		retry++;
		if(retry>0xfe)
		   {
			  SD_version = 1;
			  cardType = 1;
			  break;
		   } //time out

		}while(response != 0x01);

		retry = 0;

		do
		{
		response = SD_sendCommand(APP_CMD,0); //CMD55, must be sent before sending any ACMD command
		response = SD_sendCommand(SD_SEND_OP_COND,0x40000000); //ACMD41

		retry++;
		if(retry>0xfe)
		   {
			  USART0_print("\rinitialisation a échoué\n");
			  return 2;  //time out, card initialization failed
		   }

		}while(response != 0x00);


		retry = 0;
		SDHC_flag = 0;

		if (SD_version == 2)
		{
		   do
		   {
			 response = SD_sendCommand(READ_OCR,0);
			 retry++;
			 if(retry>0xfe)
			 {
			   cardType = 0;
			   break;
			 } //time out

		   }while(response != 0x00);

		   if(SDHC_flag == 1) cardType = 2;
		   else cardType = 3;
		}

		//SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode
		//SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512; default size is 512

		//
		switch (cardType)													/** switch for card type (to check communication with the card)*/
		{
		case 1 :  USART0_print("\rver1.x\n");break;
		case 2 :  USART0_print("\rSDHC\n");break;
		case 3 :  USART0_print("\rver2.x\n");break;
		default : USART0_print("runknown Sd card\n");
		}
		//

	return 0;break;															/**successful return*/
	}
	_delay_ms(1);															/**give some time to end the init*/
	return 0;
}
Ejemplo n.º 23
0
//******************************************************************
//Function	: to initialize the SD/SDHC card in SPI mode
//Arguments	: none
//return	: unsigned char; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
unsigned char SD_init(unsigned char *cardType){
	unsigned char i, response, SD_version;
	unsigned int retry=0 ;

	for(i=0;i<10;i++)
		SpiTransmit(0xff);   //80 clock pulses spent before sending the first command

	SD_CS_ASSERT;
do
{
  
   response = SD_sendCommand(GO_IDLE_STATE, 0); //send 'reset & go idle' command
   retry++;
   if(retry>0x20) 
   	  return 1;   //time out, card not detected
   
} while(response != 0x01);

SD_CS_DEASSERT;
SpiTransmit (0xff);
SpiTransmit (0xff);

retry = 0;

SD_version = 2; //default set to SD compliance with ver2.x; 
				//this may change after checking the next command
do
{
response = SD_sendCommand(SEND_IF_COND,0x000001AA); //Check power supply status, mandatory for SDHC card
retry++;
if(retry>0xfe) 
   {
	  SD_version = 1;
	  *cardType = 1;
	  break;
   } //time out

}while(response != 0x01);

retry = 0;

do
{
response = SD_sendCommand(APP_CMD,0); //CMD55, must be sent before sending any ACMD command
response = SD_sendCommand(SD_SEND_OP_COND,0x40000000); //ACMD41

retry++;
if(retry>0xfe) 
   {
	  return 2;  //time out, card initialization failed
   } 

}while(response != 0x00);


retry = 0;
SDHC_flag = 0;

if (SD_version == 2)
{ 
   do
   {
	 response = SD_sendCommand(READ_OCR,0);
	 retry++;
	 if(retry>0xfe) 
     {
	   *cardType = 0;
	   break;
     } //time out

   }while(response != 0x00);

   if(SDHC_flag == 1) *cardType = 2;
   else *cardType = 3;
}

//SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode
//SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512; default size is 512


return 0; //successful return
}
uint8_t init_SdCard(uint8_t *cardType)
{
    uint8_t  i, response, sd_version;
    uint16_t retry=0 ;


    for(i=0;i<10;i++)
        SPI_Write(0xff);   //80 clock pulses spent before sending the first command


    SPI_EnableChipSelect();
    do
    {

        response = SD_sendCommand(GO_IDLE_STATE, 0); //send 'reset & go idle' command
        retry++;
        if(retry>0x20)
            return SDCARD_NOT_DETECTED;   //time out, card not detected

    } while(response != 0x01);

    SPI_DisableChipSelect();
    SPI_Write (0xff);
    SPI_Write (0xff);

    retry = 0;

    sd_version = 2; //default set to SD compliance with ver2.x;
    //this may change after checking the next command
    do
    {
        response = SD_sendCommand(SEND_IF_COND,0x000001AA); //Check power supply status, mendatory for SDHC card
        retry++;
        if(retry>0xfe)
        {

            sd_version = 1;
            *cardType = SDCARD_TYPE_STANDARD;
            break;
        } //time out

    }while(response != 0x01);

    retry = 0;

    do
    {
        response = SD_sendCommand(APP_CMD,0); //CMD55, must be sent before sending any ACMD command
        response = SD_sendCommand(SD_SEND_OP_COND,0x40000000); //ACMD41

        retry++;
        if(retry>0xfe)
        {

            return SDCARD_INIT_FAILED;  //time out, card initialization failed
        }

    }while(response != 0x00);


    retry = 0;
    V_SdHighcapacityFlag_u8 = 0;

    if (sd_version == 2)
    {
        do
        {
            response = SD_sendCommand(READ_OCR,0);
            retry++;
            if(retry>0xfe)
            {

                *cardType = SDCARD_TYPE_UNKNOWN;
                break;
            } //time out

        }while(response != 0x00);

        if(V_SdHighcapacityFlag_u8 == 1)
        {
            *cardType = SDCARD_TYPE_HIGH_CAPACITY;
        }
        else
        {
            *cardType = SDCARD_TYPE_STANDARD;
        }
    }

    return response;
}
Ejemplo n.º 25
0
//***************************************************************************
//Function: to receive data from UART and write to multiple blocks of SD card
//Arguments: none
//return: uint8_t; will be 0 if no error,
// otherwise the response byte will be sent
//****************************************************************************
uint8_t SD_writeMultipleBlock(uint32_t startBlock, uint32_t totalBlocks)
{
	uint8_t response, data = 0;
	uint16_t i, retry=0;
	uint32_t blockCounter=0;

	response = SD_sendCommand(WRITE_MULTIPLE_BLOCKS, startBlock); 	//write a Block command

	if(response != 0x00) 
		return(response); 											//check for SD status: 0x00 - OK (No flags set)

	SD_CS_ASSERT;
//	printf_P(PSTR("\n Enter text (End with ~): \n"));

	while( blockCounter < totalBlocks )
	{
		i=0;
//		do
//		{
//			data = receiveByte();
//			if(data == 0x08)											//'Back Space' key pressed
//			{ 
//				if(i != 0)
//				{ 
//					transmitByte(data);
//					transmitByte(' '); 
//					transmitByte(data); 
//					i--; 
//					size--;
//				} 
//				continue;     
//			}
//			transmitByte(data);
			buffer[i++] = data;
//			if(data == 0x0d)
//			{
//				transmitByte(0x0a);
//				buffer[i++] = 0x0a;
//			}
//			if(i == 512) break;
//		}while (data != '~');

//		printf_P(PSTR("\n ---- \n"));
		
		SPI_Send8(0xfc,SD_SPI_PORT); 				//Send start block token 0xfc (0x11111100)

		for(i=0; i<512; i++) 			//send 512 bytes data
			SPI_Send8( buffer[i],SD_SPI_PORT);

		SPI_Send8(0xff,SD_SPI_PORT); 				//transmit dummy CRC (16-bit), CRC is ignored here
		SPI_Send8(0xff,SD_SPI_PORT);

		response = SPI_Receive8(SD_SPI_PORT);
		if( (response & 0x1f) != 0x05) //response= 0xXXX0AAA1 ; AAA='010' - data accepted
		{                              	//AAA='101'-data rejected due to CRC error
			SD_CS_DEASSERT;             //AAA='110'-data rejected due to write error
			return(response);
		}

		while(!SPI_Receive8(SD_SPI_PORT)) 			//wait for SD card to complete writing and get idle
			if(retry++ > 0xfffe)
			{
				SD_CS_DEASSERT; 
				return(1);
			}

		SPI_Receive8(SD_SPI_PORT); 				//extra 8 bits
		blockCounter++;
	}

	SPI_Send8(0xfd,SD_SPI_PORT); 					//send 'stop transmission token'

	retry = 0;

	while(!SPI_Receive8(SD_SPI_PORT)) 				//wait for SD card to complete writing and get idle
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		}

	SD_CS_DEASSERT;
	SPI_Send8(0xff,SD_SPI_PORT); 					//just spend 8 clock cycle delay before reasserting the CS signal
	SD_CS_ASSERT; 						//re assertion of the CS signal is required to verify if card is still busy

	while(!SPI_Receive8(SD_SPI_PORT)) 				//wait for SD card to complete writing and get idle
		if(retry++ > 0xfffe)
		{
			SD_CS_DEASSERT; 
			return(1);
		}
	SD_CS_DEASSERT;

	return(0);
}
Ejemplo n.º 26
0
//******************************************************************
//Function	: to initialize the SD/SDHC card in SPI mode
//Arguments	: uint8_t power 1 - already on, 2 - init
//return	: uint8_t; will be 0 if no error,
// 			  otherwise the response byte will be sent
//******************************************************************
uint8_t SD_Init(void)
{
	uint8_t i, response, SD_version;
	uint16_t retry=0 ;

	SPI_Init(SPI_SD);				// enable SPI and reinitialize SPI
	SPI_LOW_SPEED;

// after each power up
	if(!(SD_Status & SDSTAT_POWER))					
	{
		SD_CS_DEASSERT;					// pull high CS before starting the interface
		SD_POWER_ON;
		_delay_ms(10);
		
		SD_Status |= SDSTAT_POWER;
		
		for(i=0;i<10;i++)
			SPI_Send8(0xff,SD_SPI_PORT);   	//80 clock pulses spent before sending the first command

		SD_CS_ASSERT;
		do
		{
			response = SD_sendCommand(GO_IDLE_STATE, 0); //send 'reset & go idle' command
			retry++;
			if(retry>0x20) 
				return(1);   	//time out, card not detected
		} while(response != 0x01);

		SD_CS_DEASSERT;
		SPI_Send8(0xff,SD_SPI_PORT);
		SPI_Send8(0xff,SD_SPI_PORT);

		retry = 0;

		SD_version = 2; 		//default set to SD compliance with ver2.x; 
							//this may change after checking the next command
		do
		{
			response = SD_sendCommand(SEND_IF_COND,0x000001AA); //Check power supply status, mandatory for SDHC card
			retry++;
			if(retry>0xfe) 
			{
				SD_version = 1;
				cardType = 1;
				break;
			} //time out

		}while(response != 0x01);
		
		SD_Status |= SDSTAT_IDLE;
	}
	
// only if activation from idle
	if(SD_Status & SDSTAT_IDLE)
	{
		retry = 0;
		do
		{
			response = SD_sendCommand(APP_CMD,0); //CMD55, must be sent before sending any ACMD command
			response = SD_sendCommand(SD_SEND_OP_COND,0x40000000); //ACMD41
			retry++;
			if(retry>0xfe) 
			{
				return 2;  		//time out, card initialization failed
			} 
		}while(response != 0x00);
		SD_Status &= ~SDSTAT_IDLE;
	}

//only in init
	if(SD_Status & SDSTAT_NOTINIT)		
	{
		retry = 0;
		SDHC_flag = 0;

		if (SD_version == 2)
		{ 
			do
			{
				response = SD_sendCommand(READ_OCR,0);
				retry++;
				if(retry>0xfe) 
				{
					cardType = 0;
					break;
				} //time out
			}while(response != 0x00);

			if(SDHC_flag == 1) 
				cardType = 2;
			else 
				cardType = 3;
		}
		SD_Status &= ~SDSTAT_NOTINIT;
	}	

//SD_sendCommand(CRC_ON_OFF, OFF); //disable CRC; deafault - CRC disabled in SPI mode
//SD_sendCommand(SET_BLOCK_LEN, 512); //set block size to 512; default size is 512

// test to save power
	SPI_HIGH_SPEED;
	
	SD_Status |= SDSTAT_INIT;
	
	return(0); //successful return
}