Exemple #1
0
UINT8 SD_SendCommand(UINT8 u8SDCommand,UINT8 u8SDResponse) 
{
    UINT8 u8Counter;
    volatile UINT8 u8Temp=0;

    /* Send Start byte */
    WriteSPIByte(u8SDCommand);

    /* Send Argument */
    for(u8Counter=0;u8Counter<4;u8Counter++) 
        WriteSPIByte(gu8SD_Argument.bytes[u8Counter]);
  
    /* Send CRC */
    WriteSPIByte(0x95);
  
    /* Response RHandler */
    u8Counter=SD_WAIT_CYCLES;
    do
    {
        u8Temp=ReadSPIByte();
        u8Counter--;
    }while((u8Temp != u8SDResponse) && u8Counter > 0);
    
    if(u8Counter)   return(OK);
    else            return(COMMAND_FAILS);
}
Exemple #2
0
/*****************************************************************************
 *
 *   SD_SendCommand
 *
 *  Description:  Sends a command to the SD card and receives the response.
 *                All data is sent MSB first, and MSb first.
 *                NB: Does not handle SS signal.
 *
 *  Input:        u8SDCommand - The command to send with start bit (b7) clear
 *                              and transmission bit (b6) set.
 *                u8SDResponse - The correct R1 response byte.
 *                               If 0x80 don't care what the response is so
 long as its a byte with b7 = 0.
 *                
 *  Response:     Return OK (0x00) if a response is received, 
 *                       COMMAND_FAILS (0x01) if not.
 *                Response is stored in response[] with the number of response
 *                     bytes controlled by response_type.
 *
 *****************************************************************************/
UINT8 SD_SendCommand(UINT8 u8SDCommand, UINT8 u8SDResponse) {
	UINT8 u8Counter, CRC7;
	volatile UINT8 u8Temp = 0;

	loopUntilReady();

	/* Send command byte */WriteSPIByte(u8SDCommand);

	/* Send Argument, MSB first. */
	for (u8Counter = 0; u8Counter < 4; u8Counter++)
		WriteSPIByte(gu8SD_Argument.bytes[u8Counter]);

	/* Send CRC */
	switch (u8SDCommand) {
	case (SD_CMD55 | 0x40): // CMD55 with zero argument
		CRC7 = 0x65;
		break;
	case (SD_CMD41 | 0x40): // ACMD41 with argument 0x40000000
		CRC7 = 0x77;
		break;
	default:
		CRC7 = 0x95;
	}
	WriteSPIByte(CRC7);

	/* Response Handler */
	u8Counter = SD_WAIT_CYCLES; // 10 byte reads

	if (u8SDResponse == 0x80) {

		/* Get any valid response - a byte with b7 clear */
		do {
			u8Temp = ReadSPIByte(); // Transmit 0xFF
			u8Counter--;
		} while ((u8Temp & 0x80) && u8Counter > 0);

	} else {

		/* Get a response that matches u8SDResponse */
		do {
			u8Temp = ReadSPIByte(); // Transmit 0xFF
			u8Counter--;
		} while ((u8Temp != u8SDResponse) && u8Counter > 0);

	}

	/* Save the response */
	gu8SD_Response[0] = u8Temp;
	gu8SD_Response[1] = u8Counter;

	/* Set up return conditions */
	if (u8Counter)
		return (OK); // 0x00
	else
		return (COMMAND_FAILS); // 0x01

}
Exemple #3
0
UINT8 SD_Init(void) 
{
    _SD_PRESENT=_IN;
    
    /* Check for SD */
    if(SD_PRESENT)
        return(NO_SD_CARD);
    
    /* Initialize SPI Module */
    InitSPI();

    /* Start SD card Init */
    SPI_SS=ENABLE;
    SD_CLKDelay(10);            // Send 80 clocks 
    SPI_SS=DISABLE;
  
    gu8SD_Argument.lword=0;
    SD_CLKDelay(8);  
    
    /* IDLE Command */
    
    SPI_SS=ENABLE;
    if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE))
    {
        SPI_SS=DISABLE;
        return(INIT_FAILS);      
    }
    SPI_SS=DISABLE;
    
    (void)ReadSPIByte();  // Dummy SPI cycle
    
    /*  Initialize SD Command */
    SPI_SS=ENABLE;
    while(SD_SendCommand(SD_CMD1|0x40,SD_OK)) ;
    SPI_SS=DISABLE;
    
    (void)ReadSPIByte();  // Dummy SPI cycle

    /*  Block Length */
    SPI_SS=ENABLE;
      
    gu8SD_Argument.lword=SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,SD_OK))
    {
        SPI_SS=DISABLE;
        return(INIT_FAILS);      
    }
    
    SPI_SS=DISABLE;
    
    //HighSpeedSPI();

    WriteSPIByte(0x00);
    WriteSPIByte(0x00);
    return(OK);
}
Exemple #4
0
UINT8 SD_Write_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT16 u16Counter;
    UINT8 SD_response;

    SPI_SS=ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD24|0x40,SD_OK))
    {
        SPI_SS=DISABLE;
        return(WRITE_COMMAND_FAILS);      
    }
    
    WriteSPIByte(0xFE);
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        WriteSPIByte(*pu8DataPointer++);

    WriteSPIByte(0xFF);    // checksum Bytes not needed
    WriteSPIByte(0xFF);

    
    /* Buggy, replaced with //--
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++) ;
    
    if((ReadSPIByte() & 0x0F) != 0x05)
    {
        SPI_SS=DISABLE;
        return(WRITE_DATA_FAILS);      
    }
    */

    //-- 
    SD_response=0xFF; // #001 created this variable
    while (SD_response==0xFF) SD_response=ReadSPIByte(); // #001 wait for SD response <> 0xFF
    if((SD_response & 0x0F) != 0x05)  // #001 checks if response = 0101 = data accepted
    {
        SPI_SS=DISABLE;
        return(WRITE_DATA_FAILS);    
    }
    //-- Thx to Celso Monteiro

    while(SPI_Receive_byte()==0x00) ;  // Dummy SPI cycle

    SPI_SS=DISABLE;
    return(OK);
}
Exemple #5
0
/***************************************************************************************
 *
 *     *** SD_CBufferDataSectorWrite ***
 *
 *     Description: Write a 512 bytes from the circular buffer as a data sector.
 *                  Assume:
 *                         - SD Card has been previously erased.
 *                         - Write a full sector at a time.
 *
 *     Entry: void. 
 *
 ****************************************************************************************/
void SD_CBufferDataSectorWrite(void) {
	UINT16 u16Counter;

	SPI_SS = ENABLE;

	gu8SD_Argument.lword = u32DataSector++; // Set WRITE_BLOCK command argument
											//     to the current data segment
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD24 | 0x40, SD_OK)) // WRITE_BLOCK command
			{
		SPI_SS = DISABLE;
		return;
	}

	WriteSPIByte(0xFE); // Start Block Token

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++) // Write the block
		WriteSPIByte(FromCBuffer());

	WriteSPIByte(0xFF); // checksum Bytes not needed
	WriteSPIByte(0xFF);

//    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++);

//    if((ReadSPIByte() & 0x0F) != 0x05)                // Read the status token.
	// Correct response is 0x05
	// Foust p5.
	while ((SPI_Receive_byte() & 0x0F) != 0x05)
		;
//    {
//        SPI_SS=DISABLE;
//        return;      
//    }

	while (SPI_Receive_byte() == 0x00)
		; // Wait while the card is busy

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return;

}
Exemple #6
0
UINT8 
SD_Write_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer) 
{
    UINT16 u16Counter;
    T32_8 gu8SD_Argument;
    
    /* Check for Write Protection */
    if(SD_PROTECTED)
        return(WRITE_PROTECTED);
    
    
    SD_ENABLE;

    gu8SD_Argument.lword=u16SD_Block;
    gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;

    if(SD_SendCommand(SD_CMD24|0x40,gu8SD_Argument,SD_OK))
    {
        SD_DISABLE;
        return(WRITE_COMMAND_FAILS);      
    }
    
    WriteSPIByte(SDhandle,0xFE);
    
    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
        WriteSPIByte(SDhandle,*pu8DataPointer++);

    WriteSPIByte(SDhandle,0xFF);    // checksum Bytes not needed
    WriteSPIByte(SDhandle,0xFF);

    for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
    ;
    
    if((ReadSPIByte(SDhandle) & 0x0F) != 0x05)
    {
        SD_DISABLE;
        return(WRITE_DATA_FAILS);      
    }

    while(ReadSPIByte(SDhandle)==0x00)
    ;  // Dummy SPI cycle

    SD_DISABLE;
    return(OK);
}
Exemple #7
0
/*****************************************************************************
 *
 **************SD_Write_Block************
 *
 *      Description: Write a 512 byte sector (block) to the SD card.
 *
 *      Inputs:      u16SD_Block - the sector (block) number where the block is
 *                                 to be written.
 *                   pu8DataPointer - the 512 byte buffer that is to be written
 *                                    to the SD card.
 *
 *****************************************************************************/
UINT8 SD_Write_Block(UINT32 u16SD_Block, UINT8 *pu8DataPointer) {
	UINT16 u16Counter;

	SPI_SS = ENABLE;

	gu8SD_Argument.lword = u16SD_Block; // Set WRITE_BLOCK command argument
	gu8SD_Argument.lword = gu8SD_Argument.lword << SD_BLOCK_SHIFT; // Convert sector number to
																   // byte address

	if (SD_SendCommand(SD_CMD24 | 0x40, SD_OK)) // WRITE_BLOCK command
			{
		SPI_SS = DISABLE;
		return (WRITE_COMMAND_FAILS);
	}

	WriteSPIByte(0xFE); // Start Block Token

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++) // Write the block
		WriteSPIByte(*pu8DataPointer++);

	WriteSPIByte(0xFF); // checksum Bytes not needed
	WriteSPIByte(0xFF);

	for (u16Counter = 0; u16Counter < BLOCK_SIZE; u16Counter++)
		;

	if ((ReadSPIByte() & 0x0F) != 0x05) // Read the status token.
										// Correct response is 0x05
										// Foust p5.
			{
		SPI_SS = DISABLE;
		return (WRITE_DATA_FAILS);
	}

	while (SPI_Receive_byte() == 0x00)
		; // Wait while the card is busy

	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	return (OK);
}
Exemple #8
0
void SD_CLKDelay(UINT8 u8Frames) 
{
    while(u8Frames--)
        WriteSPIByte(0xFF);
}
Exemple #9
0
/*****************************************************************************
 *
 *   SD_SendCommandR3
 *
 *  Description:  Sends a command to the SD card that requires an R3 (5 byte) response. 
 *                Used by SEND_IF_COND (CMD58) to read the OCR.
 *
 *  Input:        u8SDCommand - the command.
 *                u8SDResponse - The correct R1 response for this command.
 *                u8CRC7 - the CRC7 + end bit for the command (with Tx bit set)
 *                             and argument.
 *                The 4 byte argument "gu8SD_Argument" must be set before 
 *                     calling this function.
 *
 *  Response:     OK (0x00) if valid R3 response received else COMMAND_FAILS (0x01).
 *                The R1 response is available in  gu8SD_Response[0].
 *                The 32 bit Operation Conditions Register (OCR) is available in
 *                    gu8SD_Response[1-4] with MSB in gu8SD_Response[1].
 *
 *****************************************************************************/
UINT8 SD_SendCommandR3(UINT8 u8SDCommand, UINT8 u8SDResponse, UINT8 u8CRC7) {
	UINT8 u8Counter, mlCounter, i;
	volatile UINT8 u8Temp = 0;

	loopUntilReady();

	/* Debug checks */
	for (i = 0; i <= 4; i++) { // Initialise gu8SD_Response[] so you can be sure its changed
		gu8SD_Response[i] = 0xAA;
	}

	/* Main loop - Send the command and wait for a valid response */
	mlCounter = 5; // loop max of 5 times
	do {
		mlCounter--;
		/* Send command byte with set transmission bit (b6) set */WriteSPIByte(
				u8SDCommand | 0x40);

		/* Send Argument */
		for (u8Counter = 0; u8Counter < 4; u8Counter++) {
			i = gu8SD_Argument.bytes[u8Counter];
			WriteSPIByte(gu8SD_Argument.bytes[u8Counter]);
		}

		/* Send CRC */WriteSPIByte(u8CRC7);

		/* Response Handler. 
		 Do up to SD_WAIT_CYCLES card reads looking for a valid response.
		 Valid response is 5 bytes which are stored in gu8SD_Response[].
		 Valid response is received MSB first.
		 The five bytes are: 
		 - gu8SD_Response[0]; MSB is a normal R1 response which is SD_IDLE (0x01).
		 - gu8SD_Response[1-4]; is the argument that was transmitted.
		 The card responds with 0xFF until it transmits the valid response. */
		u8Counter = SD_WAIT_CYCLES; // Do up to SD_WAIT_CYCLES card reads

		/* Response loop - Do up to SD_WAIT_CYCLES card reads looking for a valid response */
		do // Look for a R1 response byte
		{
			u8Temp = ReadSPIByte(); // Transmit 0xFF. MOSI line must be kept high
			u8Counter--;
		} while ((u8Temp != u8SDResponse) && u8Counter > 0); // Response loop test
//    } while((u8Temp & 0xC0) && u8Counter > 0);   // Response loop test
		// - exit on valid response or timeout

	} while ((u8Temp != u8SDResponse) && mlCounter > 0); // Main loop test
//  } while((u8Temp & 0xC0) && mlCounter > 0);     // Main loop test
	// - exit on valid response or timeout

	/* Place the 5 byte response in gu8SD_Response[] */
	gu8SD_Response[0] = u8Temp; // R1
	for (i = 1; i <= 4; i++) { // OCR
		gu8SD_Response[i] = ReadSPIByte();
	}

	/* Set up return condition */
	if (gu8SD_Response[0] == u8SDResponse)
		return (OK); // 0x00

	else
		return (COMMAND_FAILS); // 0x01
}
Exemple #10
0
UINT8 
SD_Init(void) 
{
    T32_8 gu8SD_Argument;
    
    SD_PRESENT_INIT;
    SD_PROTECTED_INIT;
    
    /* Check for SD */
    if(SD_PRESENT)
    {
       return(NO_SD_CARD);
    }        
    
    /* Initialize SPI Module */
    SD_DISABLE;/*First init*/
    
    /**********************FSL: SPI start-up*******************************/
    //if SPIhandle NULL, serial cannot be used!!!
    SDhandle = xSPIinit((eSPIPort)SD_CARD_SPI_PORT/*BSP being used*/, 
                             spi300,/*300KHz baudrate*/ 
                             serIDLEslow, 
                             serMiddleSample, 
                             serMaster,
                             serInterrupt,
                             SPI_SDCARD_BUFFER_LIMIT/*defined at header file*/);

    /* Start SD card Init */
    SD_ENABLE;
    SD_CLKDelay(10);            // Send 80 clocks 
    SD_DISABLE;
  
    gu8SD_Argument.lword=0;
    SD_CLKDelay(8);  
    
    /* IDLE Command */
    
    SD_ENABLE;
    if(SD_SendCommand(SD_CMD0|0x40,gu8SD_Argument,SD_IDLE))
    {
        SD_DISABLE;
        return(INIT_FAILS);      
    }
    SD_DISABLE;
    
    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle
    
    /*  Initialize SD Command */
    SD_ENABLE;
    while(SD_SendCommand(SD_CMD1|0x40,gu8SD_Argument,SD_OK))
    ;
    SD_DISABLE;
    
    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle

    /*  Block Length */
    SD_ENABLE;
      
    gu8SD_Argument.lword=SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,gu8SD_Argument,SD_OK))
    {
        SD_DISABLE;
        return(INIT_FAILS);      
    }
    
    SD_DISABLE;
    
    xSPIChangeToPolling(SDhandle);
    
    HighSpeedSPI(SD_CARD_SPI_PORT);

    WriteSPIByte(SDhandle,0x00);
    WriteSPIByte(SDhandle,0x00);
    return(OK);
}