FreeBSD/sys/boot/arm/at91/libat91/sd-card.c
//*----------------------------------------------------------------------------
//* \fn    sdcard_init
//* \brief get the mci device ready to read from an SD or SDHC card.
//*
//* Unlike most functions in this file, the return value from this one is
//* bool-ish; returns 0 on failure, 1 on success.
//*----------------------------------------------------------------------------
\fn    sdcard_init
\brief get the mci device ready to read from an SD or SDHC card.

Unlike most functions in this file, the return value from this one is
bool-ish; returns 0 on failure, 1 on success.
\ fn sdcard_init \ brief get the mci device ready to read from an SD or SDHC card . Unlike most functions in this file the return value from this one is bool - ish ; returns 0 on failure 1 on success .
int
sdcard_init(void)
{
	unsigned int	tab_response[4];
	int i;
	AT91F_MCI_CfgPIO();	
	AT91F_MCI_CfgPMC();
	AT91F_PDC_Open(AT91C_BASE_PDC_MCI);
	MCI_Device.state		= AT91C_MCI_IDLE;
	MCI_Device.SDCard_bus_width	= 0;
	MCI_Device.IsSDv2		= 0;
	MCI_Device.IsSDHC		= 0;
	AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIDIS | 0x80;
	AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF;
	AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES;
	AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 114; 
	AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_MMC_SLOTA;
	AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN|AT91C_MCI_PWSEN;
	for (i = 0; i < 100; i++) {
		if (MCI_SDCard_GetOCR() == 0)
			break;
		if ((i & 0x01) == 0) {
			printf(".");
		}
	}
	if (i >= 100)
		return 0;
	if (MCI_SDCard_GetCID(tab_response))
		return 0;
	if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
		return 0;
	MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
	AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE | 1; 
	if (MCI_GetCSD(MCI_Device.RCA,tab_response))
		return 0;
	MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) &
	    CSD_1_RD_B_LEN_M;
#ifdef REPORT_SIZE
	{
		unsigned int	mult,blocknr;
		mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
		    CSD_2_C_SIZE_M_M) + 2 );
		blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
		    CSD_1_CSIZE_H_M) << 2;
		 * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR
		blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) &
		    CSD_2_CSIZE_L_M)) + 1);
		MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr;
		printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);
	}
#endif
	if (MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16))
		return 0;
	if (MCI_SendCommand(SET_BLOCKLEN_CMD, SD_BLOCK_SIZE))
		return 0;
	return 1;
}
int sdcard_init ( void ) { unsigned int tab_response [ 4 ] ; int i ; AT91F_MCI_CfgPIO ( ) ; AT91F_MCI_CfgPMC ( ) ; AT91F_PDC_Open ( AT91C_BASE_PDC_MCI ) ; MCI_Device . state = AT91C_MCI_IDLE ; MCI_Device . SDCard_bus_width = 0 ; MCI_Device . IsSDv2 = 0 ; MCI_Device . IsSDHC = 0 ; AT91C_BASE_MCI -> MCI_CR = AT91C_MCI_MCIDIS | 0x80 ; AT91C_BASE_MCI -> MCI_IDR = 0xFFFFFFFF ; AT91C_BASE_MCI -> MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES ; AT91C_BASE_MCI -> MCI_MR = AT91C_MCI_PDCMODE | 114 ; AT91C_BASE_MCI -> MCI_SDCR = AT91C_MCI_MMC_SLOTA ; AT91C_BASE_MCI -> MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN ; for ( i = 0 ; i < 100 ; i ++ ) { if ( MCI_SDCard_GetOCR ( ) == 0 ) break ; if ( ( i & 0x01 ) == 0 ) { printf ( " " ) ; } } if ( i >= 100 ) return 0 ; if ( MCI_SDCard_GetCID ( tab_response ) ) return 0 ; if ( MCI_SendCommand ( SET_RELATIVE_ADDR_CMD , 0 ) ) return 0 ; MCI_Device . RCA = ( AT91C_BASE_MCI -> MCI_RSPR [ 0 ] >> 16 ) ; AT91C_BASE_MCI -> MCI_MR = AT91C_MCI_PDCMODE | 1 ; if ( MCI_GetCSD ( MCI_Device . RCA , tab_response ) ) return 0 ; MCI_Device . READ_BL_LEN = ( tab_response [ 1 ] >> CSD_1_RD_B_LEN_S ) & CSD_1_RD_B_LEN_M ; #ifdef REPORT_SIZE { unsigned int mult , blocknr ; mult = 1 << ( ( ( tab_response [ 2 ] >> CSD_2_C_SIZE_M_S ) & CSD_2_C_SIZE_M_M ) + 2 ) ; blocknr = ( ( tab_response [ 1 ] >> CSD_1_CSIZE_H_S ) & CSD_1_CSIZE_H_M ) << 2 ; blocknr = mult * ( ( blocknr + ( ( tab_response [ 2 ] >> CSD_2_CSIZE_L_S ) & CSD_2_CSIZE_L_M ) ) + 1 ) ; MCI_Device . Memory_Capacity = ( 1 << MCI_Device . READ_BL_LEN ) * blocknr ; printf ( " \n " , MCI_Device . Memory_Capacity ) ; } #endif if ( MCI_SendCommand ( SEL_DESEL_CARD_CMD , ( MCI_Device . RCA ) << 16 ) ) return 0 ; if ( MCI_SendCommand ( SET_BLOCKLEN_CMD , SD_BLOCK_SIZE ) ) return 0 ; return 1 ; }
\fn    sdcard_init
\brief get the mci device ready to read from an SD or SDHC card.
\ fn sdcard_init \ brief get the mci device ready to read from an SD or SDHC card .
// Init MCI for MMC and SDCard interface // Init Device Structure // Reset the MCI and set the bus speed. // Using MCK/230 gives a legal (under 400khz) bus speed for the card id // sequence for all reasonable master clock speeds. /* clkdiv 114 = MCK/230 */ // Wait for the card to come out of power-up-busy state by repeatedly // sending ACMD41.  This also probes for SDHC versus standard cards. // Tell the card to set its address, and remember the result. // After sending CMD3 (set addr) we can increase the clock to full speed. // Using MCK/4 gives a legal (under 25mhz) bus speed for all reasonable // master clock speeds. /* clkdiv 1 = MCK/4 */ // compute MULT // compute MSB of C_SIZE // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR // Select card and set block length for following transfers.