Ejemplo n.º 1
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
//******************************************************************
static 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 
//multiplying 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 == WRITE_SINGLE_BLOCK    ||
   cmd == ERASE_BLOCK_START_ADDR|| 
   cmd == ERASE_BLOCK_END_ADDR ) 
   {
     arg = arg << 9;
   }	   

SD_CS_ASSERT;

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

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

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

if(response == 0x00 && cmd == 58)  //checking response of CMD58
{
  status = SpiReceive() & 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;

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

SpiReceive(); //extra 8 CLK
SD_CS_DEASSERT;

return response; //return state
}
Ejemplo n.º 2
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, char buffer[BLOCK])
{
unsigned char response;
unsigned int 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)

SD_CS_ASSERT;

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

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

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

response = SpiReceive();

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(!SpiReceive()) //wait for SD card to complete writing and get idle
if(retry++ > 0xfffe){SD_CS_DEASSERT; return 1;}

SD_CS_DEASSERT;
SpiTransmit(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(!SpiReceive()) //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.º 3
0
void SPI1_ISR(void) {
 ISR_ENTRY();

 if (bit_is_set(SSPMIS, TXMIS)) {  /*  Tx half empty */
   SpiTransmit();
   SpiReceive();
   SpiEnableRti();
 }

 if ( bit_is_set(SSPMIS, RTMIS)) { /* Rx timeout      */
   SpiReceive();
   SpiClearRti();                  /* clear interrupt */
   SpiDisableRti();
   SpiDisable();
   spi_message_received = TRUE;
 }

 VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
 ISR_EXIT();
}
Ejemplo n.º 4
0
void SPI1_ISR(void) {
  ISR_ENTRY();

  if (bit_is_set(SSPMIS, TXMIS)) {  /*  Tx fifo is half empty */
    SpiTransmit();
    SpiReceive();
    SpiEnableRti();
  }

  if (bit_is_set(SSPMIS, RTMIS)) { /* Rx fifo is not empty and no receive took place in the last 32 bits period */
    SpiUnselectCurrentSlave();
    SpiReceive();
    SpiDisableRti();
    SpiClearRti();                /* clear interrupt */
    SpiDisable();
    spi_message_received = TRUE;
  }

  VICVectAddr = 0x00000000; /* clear this interrupt from the VIC */
  ISR_EXIT();
}
Ejemplo n.º 5
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
}