PERFORCE change 109576 for review

Warner Losh imp at FreeBSD.org
Thu Nov 9 00:40:47 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=109576

Change 109576 by imp at imp_lighthouse on 2006/11/09 00:39:48

	Merge mci_device.c into sd-card.c.  There wasn't much benefit from
	having them separate.  Remove a few layers of indirection, simplify
	interfaces, etc.  This saves about 650 bytes to boot!

Affected files ...

.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/mci_device.c#20 delete
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/mci_device.h#11 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/sd-card.c#13 edit

Differences ...

==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/mci_device.h#11 (text+ko) ====

@@ -83,43 +83,19 @@
 // MMC & SDCard Structures 
 ///////////////////////////////////////////////////////////////////////////////
 
-/*-----------------------------------------------*/
-/* SDCard Device Descriptor Structure Definition */
-/*-----------------------------------------------*/
-typedef struct	_AT91S_MciDeviceDesc
-{
-    volatile unsigned char	state;
-	unsigned char			SDCard_bus_width;
-
-} AT91S_MciDeviceDesc, *AT91PS_MciDeviceDesc;
-
 /*---------------------------------------------*/
-/* MMC & SDCard Structure Device Features	   */
-/*---------------------------------------------*/
-typedef struct	_AT91S_MciDeviceFeatures
-{
-	unsigned char	Card_Inserted;				// (0=AT91C_CARD_REMOVED) (1=AT91C_MMC_CARD_INSERTED) (2=AT91C_SD_CARD_INSERTED)
-	unsigned int 	Relative_Card_Address;		// RCA
-	unsigned int	READ_BL_LEN;
-	unsigned int	WRITE_BL_LEN;
-	unsigned char	Read_Partial;				// READ_BL_PARTIAL
-	unsigned char	Write_Partial;				// WRITE_BL_PARTIAL
-	unsigned char	Erase_Block_Enable;			// ERASE_BLK_EN
-	unsigned char	Read_Block_Misalignment;	// READ_BLK_MISALIGN
-	unsigned char	Write_Block_Misalignment;	// WRITE_BLK_MISALIGN
-	unsigned char	Sector_Size;				// SECTOR_SIZE
-	unsigned int	Memory_Capacity;			// Size in bits of the device
-	
-}	AT91S_MciDeviceFeatures, *AT91PS_MciDeviceFeatures ;
-
-/*---------------------------------------------*/
 /* MCI Device Structure Definition 			   */
 /*---------------------------------------------*/
 typedef struct _AT91S_MciDevice
 {
-	AT91PS_MciDeviceDesc		 	pMCI_DeviceDesc;	// MCI device descriptor
-	AT91PS_MciDeviceFeatures		pMCI_DeviceFeatures;// Pointer on a MCI device features array  
-} AT91S_MciDevice, *AT91PS_MciDevice;
+	volatile unsigned char	state;
+	unsigned char	SDCard_bus_width;
+	unsigned int 	RCA;		// RCA
+	unsigned int	READ_BL_LEN;
+#ifdef REPORT_SIZE
+	unsigned int	Memory_Capacity;
+#endif
+} AT91S_MciDevice;
 
 #include <dev/mmc/mmcreg.h>
 
@@ -450,15 +426,4 @@
 #define	CSD_0_STRUCT_M 		0x03
 
 ///////////////////////////////////////////////////////////////////////////////
-
-void 				AT91F_MCI_Device_Handler(AT91PS_MciDevice,unsigned int);
-AT91S_MCIDeviceStatus 	AT91F_MCI_SDCard_Init (AT91PS_MciDevice);
-AT91S_MCIDeviceStatus 	AT91F_MCI_SetBlocklength(unsigned int);
-AT91S_MCIDeviceStatus 	AT91F_MCI_ReadBlock(AT91PS_MciDevice,int,unsigned int *,int);
-AT91S_MCIDeviceStatus 	AT91F_MCI_WriteBlock(AT91PS_MciDevice,int,unsigned int *,int);
-#if 0
-AT91S_MCIDeviceStatus AT91F_MCI_MMC_Init (AT91PS_MciDevice pMCI_Device);
-AT91S_MCIDeviceStatus AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address);
-#endif
-
 #endif

==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/sd-card.c#13 (text+ko) ====

@@ -51,13 +51,7 @@
 #define BUFFER_SIZE_MCI_DEVICE	512
 #define MASTER_CLOCK		60000000
 
-//Private functions
-//static void initInts(void);
-static void AT91F_MCI_Handler(void);
-
 //* Global Variables
-AT91S_MciDeviceFeatures		MCI_Device_Features;
-AT91S_MciDeviceDesc		MCI_Device_Desc;
 AT91S_MciDevice			MCI_Device;
 char				Buffer[BUFFER_SIZE_MCI_DEVICE];
 
@@ -83,56 +77,126 @@
 	}
 	while( !(status & AT91C_MCI_NOTBUSY)  && (timeout>0) );	
 
-	AT91F_MCI_Handler();
+	status = AT91C_BASE_MCI->MCI_SR;
+
+	// If End of Tx Buffer Empty interrupt occurred
+	if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) {
+		AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE;
+ 		AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS;
+		MCI_Device.state = AT91C_MCI_IDLE;
+	}	// End of if AT91C_MCI_TXBUFF
+
+	// If End of Rx Buffer Full interrupt occurred
+	if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) {
+		AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF;
+ 		AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS;
+		MCI_Device.state = AT91C_MCI_IDLE;
+	}	// End of if AT91C_MCI_RXBUFF
+}
+
+inline static unsigned int
+swap(unsigned int a)
+{
+    return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8)
+      | ((a & 0xff000000) >> 24));
 }
 
-#if 0
-int
-MCI_write (unsigned dest, char* source, unsigned length)
+inline static void
+wait_ready()
 {
-	unsigned sectorLength = 1 << MCI_Device.pMCI_DeviceFeatures->WRITE_BL_LEN;
-	unsigned offset = dest % sectorLength;
-	AT91S_MCIDeviceStatus status;
-	int sizeToWrite;
+	int status;
 
-	//As long as there is data to write
-	while (length)
+	// wait for CMDRDY Status flag to read the response
+	do
 	{
-		//See if we've got at least a sector to write
-		if (length > sectorLength) 
-			sizeToWrite = sectorLength;
-		//Else just write the remainder
-		else
-			sizeToWrite = length;
+		status = AT91C_BASE_MCI->MCI_SR;
+	} while( !(status & AT91C_MCI_CMDRDY) );
+}
+
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_SendCommand
+//* \brief Generic function to send a command to the MMC or SDCard
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_SendCommand(
+	unsigned int Cmd,
+	unsigned int Arg)
+{
+	unsigned int	error;
 
-		AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
-		//Do the writing
-		status = AT91F_MCI_WriteBlock(&MCI_Device, dest, (unsigned int*)source, sizeToWrite);
-		//TODO:Status checking
+	AT91C_BASE_MCI->MCI_ARGR = Arg;
+	AT91C_BASE_MCI->MCI_CMDR = Cmd;
 
-		//Update counters & pointers
-		length -= sizeToWrite;
-		dest += sizeToWrite;
-		source += sizeToWrite;
+//	printf("CMDR %x ARG %x\n", Cmd, Arg);
+	wait_ready();
+	// Test error  ==> if crc error and response R3 ==> don't check error
+	error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR;
+	if (error != 0) {
+		if (error != AT91C_MCI_RCRCE)
+			return (1);
 	}
+	return 0;
+}
 
-	return 0;
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_GetStatus
+//* \brief Addressed card sends its status register
+//*----------------------------------------------------------------------------
+static unsigned int
+AT91F_MCI_GetStatus()
+{
+	if (AT91F_MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16))
+		return AT91C_CMD_SEND_ERROR;
+	return (AT91C_BASE_MCI->MCI_RSPR[0]);
 }
-#endif
 
-inline static unsigned int
-swap(unsigned int a)
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_ReadBlock
+//* \brief Read an ENTIRE block or PARTIAL block
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_ReadBlock(int src, unsigned int *dataBuffer, int sizeToRead)
 {
-    return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8)
-      | ((a & 0xff000000) >> 24));
+	unsigned log2sl = MCI_Device.READ_BL_LEN;
+	unsigned sectorLength = 1 << log2sl;
+
+	///////////////////////////////////////////////////////////////////////
+	if (MCI_Device.state != AT91C_MCI_IDLE)
+		return 1;
+    
+	if ((AT91F_MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0)
+		return 1;
+
+	///////////////////////////////////////////////////////////////////////
+      
+        // Init Mode Register
+	AT91C_BASE_MCI->MCI_MR |= ((sectorLength << 16) | AT91C_MCI_PDCMODE);
+	 
+	sizeToRead = sizeToRead / 4;
+
+	AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
+	AT91C_BASE_PDC_MCI->PDC_RPR  = (unsigned int)dataBuffer;
+	AT91C_BASE_PDC_MCI->PDC_RCR  = sizeToRead;
+
+	// Send the Read single block command
+	if (AT91F_MCI_SendCommand(READ_SINGLE_BLOCK_CMD, src))
+		return AT91C_READ_ERROR;
+	MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK;
+
+	// Enable AT91C_MCI_RXBUFF Interrupt
+	AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF;
+
+	// (PDC) Receiver Transfer Enable
+	AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN;
+	
+	return 0;
 }
 
 int
 MCI_read(char* dest, unsigned source, unsigned length)
 {
-	unsigned log2sl = MCI_Device.pMCI_DeviceFeatures->READ_BL_LEN;
+	unsigned log2sl = MCI_Device.READ_BL_LEN;
 	unsigned sectorLength = 1 << log2sl;
-	AT91S_MCIDeviceStatus status;
 	int sizeToRead;
 	unsigned int *walker;
 
@@ -146,11 +210,8 @@
 
 		AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
 		//Do the reading
-		status = AT91F_MCI_ReadBlock(&MCI_Device, source,
-		  (unsigned int*)dest, sizeToRead);
-
-		//TODO:Status checking
-		if (status != AT91C_READ_OK)
+		if (AT91F_MCI_ReadBlock(source,
+			(unsigned int*)dest, sizeToRead))
 			return -1;
 
 		//* Wait MCI Device Ready
@@ -179,29 +240,122 @@
 {
 	// Init Device Structure
 
-	MCI_Device_Features.Relative_Card_Address = 0;
-	MCI_Device_Features.Card_Inserted 	= AT91C_SD_CARD_INSERTED;
-	MCI_Device_Features.READ_BL_LEN		= 0;
-	MCI_Device_Features.WRITE_BL_LEN	= 0;
-	MCI_Device_Features.Read_Partial 	= 0;
-	MCI_Device_Features.Write_Partial 	= 0;
-	MCI_Device_Features.Erase_Block_Enable 	= 0;
-	MCI_Device_Features.Sector_Size 	= 0;
-	MCI_Device_Features.Memory_Capacity 	= 0;
-	MCI_Device_Desc.state			= AT91C_MCI_IDLE;
-	MCI_Device_Desc.SDCard_bus_width	= AT91C_MCI_SCDBUS;
-	MCI_Device.pMCI_DeviceDesc 		= &MCI_Device_Desc;
-	MCI_Device.pMCI_DeviceFeatures 		= &MCI_Device_Features;
+	MCI_Device.RCA = 0;
+	MCI_Device.READ_BL_LEN		= 0;
+#ifdef REPORT_SIZE
+	MCI_Device.Memory_Capacity 	= 0;
+#endif
+	MCI_Device.state			= AT91C_MCI_IDLE;
+	MCI_Device.SDCard_bus_width	= AT91C_MCI_SCDBUS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_SDCard_SendAppCommand
+//* \brief Specific function to send a specific command to the SDCard
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_SDCard_SendAppCommand(
+	unsigned int Cmd_App,
+	unsigned int Arg)
+{
+	// Send the CMD55 for application specific command
+	AT91C_BASE_MCI->MCI_ARGR = (MCI_Device.RCA << 16 );
+	AT91C_BASE_MCI->MCI_CMDR = APP_CMD;
+
+	wait_ready();
+	// if an error occurs
+	if (AT91C_BASE_MCI->MCI_SR & AT91C_MCI_SR_ERROR)
+		return (1);
+	return (AT91F_MCI_SendCommand(Cmd_App,Arg));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_GetCSD
+//* \brief Asks to the specified card to send its CSD
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_GetCSD(unsigned int rca, unsigned int *response)
+{
+ 	
+ 	if (AT91F_MCI_SendCommand(SEND_CSD_CMD, (rca << 16)))
+		return 1;
+	
+	response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
+   	response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
+	response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
+	response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
+    
+	return 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_SDCard_GetOCR
+//* \brief Asks to all cards to send their operations conditions
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_SDCard_GetOCR()
+{
+	unsigned int	response=0x0;
+
+	// The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000.
+	MCI_Device.RCA = 0x0;
+ 	
+ 	while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) {
+		if (AT91F_MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD,
+			AT91C_MMC_HOST_VOLTAGE_RANGE))
+			return 1;
+		response = AT91C_BASE_MCI->MCI_RSPR[0];
+	}
+	return (0);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_SDCard_GetCID
+//* \brief Asks to the SDCard on the chosen slot to send its CID
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_SDCard_GetCID(unsigned int *response)
+{
+	if (AT91F_MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT))
+		return 1;
+	
+	response[0] = AT91C_BASE_MCI->MCI_RSPR[0];
+   	response[1] = AT91C_BASE_MCI->MCI_RSPR[1];
+	response[2] = AT91C_BASE_MCI->MCI_RSPR[2];
+	response[3] = AT91C_BASE_MCI->MCI_RSPR[3];
+    
+	return 0;
 }
 
-static void AT91F_MCI_Handler(void)
+//*----------------------------------------------------------------------------
+//* \fn    AT91F_MCI_SDCard_SetBusWidth
+//* \brief  Set bus width for SDCard
+//*----------------------------------------------------------------------------
+static int
+AT91F_MCI_SDCard_SetBusWidth()
 {
-	int status;
+	volatile int	ret_value;
+	char			bus_width;
+
+	do {
+		ret_value=AT91F_MCI_GetStatus();
+	}
+	while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0));
+
+	// Select Card
+	AT91F_MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16);
+
+	// Set bus width for Sdcard
+	if (MCI_Device.SDCard_bus_width == AT91C_MCI_SCDBUS)
+		bus_width = AT91C_BUS_WIDTH_4BITS;
+	else
+		bus_width = AT91C_BUS_WIDTH_1BIT;
 
-//	status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR );
-	status = AT91C_BASE_MCI->MCI_SR;
+	if (AT91F_MCI_SDCard_SendAppCommand(
+	      SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK)
+		return 1;
 
-	AT91F_MCI_Device_Handler(&MCI_Device, status);
+	return 0;
 }
 
 //*----------------------------------------------------------------------------
@@ -211,12 +365,12 @@
 int
 sdcard_init(void)
 {
-///////////////////////////////////////////////////////////////////////////////
-//  MCI Init : common to MMC and SDCard
-///////////////////////////////////////////////////////////////////////////////
+	unsigned int	tab_response[4];
+#ifdef REPORT_SIZE
+	unsigned int	mult,blocknr;
+#endif
+	int i;
 
-	//initInts();
-
 	// Init MCI for MMC and SDCard interface
 	AT91F_MCI_CfgPIO();	
 	AT91F_MCI_CfgPMC();
@@ -229,8 +383,43 @@
 	    AT91C_MCI_DTOR_1MEGA_CYCLES,
 	    AT91C_MCI_PDCMODE,
 	    AT91C_MCI_SDCARD_4BITS_SLOTA);
-	
-	if (AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK)
+	AT91F_MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
+
+	for (i = 0; i < 100; i++) {
+		if (!AT91F_MCI_SDCard_GetOCR(&MCI_Device))
+			break;
+		printf(".");
+	}
+	if (i >= 100)
+		return 0;
+	if (AT91F_MCI_SDCard_GetCID(tab_response))
+		return 0;
+	if (AT91F_MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0))
+		return 0;
+
+	MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16);
+	if (AT91F_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
+	// compute MULT
+	mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) &
+	    CSD_2_C_SIZE_M_M) + 2 );
+	// compute MSB of C_SIZE
+	blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) &
+	    CSD_1_CSIZE_H_M) << 2;
+	// compute MULT * (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;
+#endif
+	if (AT91F_MCI_SDCard_SetBusWidth())
+		return 0;
+	if (AT91F_MCI_SendCommand(SET_BLOCKLEN_CMD, 1 << MCI_Device.READ_BL_LEN))
 		return 0;
+#ifdef REPORT_SIZE
+	printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity);
+#endif
 	return 1;
 }


More information about the p4-projects mailing list