⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc.c

📁 TI公司TMS320VC5509的外设驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
{    
      
   
    pMMC->argh = 0;
    pMMC->argl = block_len;	   
	pMMC->cmd  = SET_BLOCKLEN;
	if( wait_for( RSPDNE ) == 0 ) 
	{
		CurrentBlen = block_len;
		return(0);
	}	
	return( -1 );
}                                 

// Tested, tnyc, just one block
int MMC_ReadBlock(unsigned long lba, unsigned short *pBuf, int swapbytes)
{
	unsigned short   count = CurrentBlen/2;
	register volatile unsigned short stat;
	int error;
	int ddr;
		
	// The nblk and blen parameters can be a little confusing.
	// blen can be less then the CSD blen which is usually 512.
	// Thus I can simply read 10 bytes. 	  
    pMMC->nblk = 1;   
    pMMC->blen = CurrentBlen;  
 	pMMC->argl = (unsigned short)((lba << 9) & 0xffff);
	pMMC->argh = (unsigned short)((lba >> 7) & 0xffff); 
	pMMC->cmd  = READ_SINGLE_BLOCK | DATA | DCLR;
 
    // May want to check for a response.  But for now
    // we just check for data. 
    if( count < 1 )
    	return( -1 );
    	
	do 
	{
		do
		{
			stat  = pMMC->st0;
			ddr   = ((stat & DRRDY)             != 0);
			error = ((stat & ( CRCRD | TOUTRD)) != 0 );
			// Checking for early DATDNE
			Done  |= (stat & 1);
		}while(  !error && !ddr  ); 
			
		if(ddr)				  
			*pBuf++ = (swapbytes) ? ((pMMC->ddr & 0xff00) >> 8) + ((pMMC->ddr & 0x00ff) << 8) : pMMC->ddr; 
			
 	}while( !error && --count );  
      
    // Test to make sure that we see a DATDNE signal  
    if( (error == 0) && (Done == 0) )
    {
   	  if( (error = wait_for( DATDNE )) == 0 )
   	  	Done = 1;
   	}  
 			      
	// Check for errors.
	return( error == 0 ? 0 : -1 );
		 
}                            

// Tested, tnyc, just one block
static int read_single_block( unsigned long address )
{
	unsigned short   count = CurrentBlen/2;   
	unsigned short * pBuf  = ReadBlock;
	register volatile unsigned short stat;
	int error;
	int ddr;
		
	// The nblk and blen parameters can be a little confusing.
	// blen can be less then the CSD blen which is usually 512.
	// Thus I can simply read 10 bytes. 	  
    pMMC->nblk = 1;   
    pMMC->blen = CurrentBlen;  
 	pMMC->argl = (unsigned short)address;
	pMMC->argh = (unsigned short)(address>>16); 
	pMMC->cmd  = READ_SINGLE_BLOCK | DATA | DCLR;
 
    // May want to check for a response.  But for now
    // we just check for data. 
    if( count < 1 )
    	return( -1 );
    	
	do 
	{
		do
		{
			stat  = pMMC->st0;
			ddr   = ((stat & DRRDY)             != 0);
			error = ((stat & ( CRCRD | TOUTRD)) != 0 );
			// Checking for early DATDNE
			Done  |= (stat & 1);
		}while(  !error && !ddr  ); 
			
		if(ddr)				  
			*pBuf++ = pMMC->ddr; 
			
 	}while( !error && --count );  
      
    // Test to make sure that we see a DATDNE signal  
    if( (error == 0) && (Done == 0) )
    {
   	  if( (error = wait_for( DATDNE )) == 0 )
   	  	Done = 1;
   	}  
 			      
	// Check for errors.
	return( error == 0 ? 0 : -1 );
		 
}                            

// Tested, tnyc.  Just one block
int write_single_block( unsigned long address )
{
	unsigned short   count = CurrentBlen/2;   
	unsigned short * pBuf  = ReadBlock;
	register volatile unsigned short stat;
	int error;
	int dxr;
		
	// The nblk and blen parameters can be a little confusing.
	// blen can be less then the CSD blen which is usually 512.
	// Thus I can simply read 10 bytes. 	  
    pMMC->nblk = 1;   
    pMMC->blen = CurrentBlen;  
 	pMMC->argl = (unsigned short)address;	
 	pMMC->argh = (unsigned short)(address>>16); 
	pMMC->cmd  = WRITE_BLOCK | DATA | WRITE| DCLR;
 
    SWDelayUsec(1);
    
     // May want to check for a response.  But for now
    // we just check for data. 
    if( count < 1 )
    	return( -1 );
    	
	do 
	{
		do
		{
			stat  = pMMC->st0;
			dxr   = ((stat & DXRDY)      != 0 );
			error = ((stat & ( CRCWR   ))!= 0 );
			// Checking for early DATDNE
			Done  |= ( stat & 1 );
						
		}while( !error && !dxr ); 
			
		if(dxr)				  
			pMMC->dxr = *pBuf++;
					
 	}while( !error && --count );  
     
   // Test to make sure that we see a DATDNE signal       
    if( (error == 0) && (Done == 0) )
    {
   	  if( (error = wait_for( DATDNE )) == 0 )
   	  	Done = 1;
   	}  

	// Check for errors.  
	return( error == 0 ? 0 : -1 );	
}                            

int MMC_InitClock()
{
    // Reset the command/data       
	pMMC->ctl= CMDRST | DATRST; 	
	                                               
	// controls the MMC clock-- should be 20 Mhz for MMC mode and 5 Mhz for SPI mode
	// MMC clock = function clock / (MMCCLK_RATE + 1) 
	// 
	pMMC->clk &= ~CLKEN; // Turn off the clock before switching to new rate
    // This has no effect on the FPGA implementation.  The functional clock
    // equal to the C55xx clockout.
	pMMC->fckctl = dspclk.pllmult - 1;  
	pMMC->clk =	0x000e;       // Clock divide by 8 ~400KHz = 9	
	pMMC->im  = 0;   /*all interrupts are masked */
	pMMC->tor = 16;  /*response time out */
	pMMC->tod = 0;   /*no data read time out */

	/*need to set the length of a block in bytes-- must be same as in CSD register*/	
	pMMC->blen = BLEN; 
	
	pMMC->ctl = 0; /*enable dat and cmd lines*/
	
	/* enable the clock  ???? where to put it ????? */	
	/*maybe put it before go idle state????*/
	pMMC->clk |= CLKEN;                    
	
	// Wait long enough MMC module to reset. 
	SWDelayUsec(10);
}
                     
int MMC_Init(void)
{     
    PC55XX_EXTBUS pExtBus = (PC55XX_EXTBUS)C55XX_EXTBUS_ADDR;
    volatile long delay = 1000;  

    int error = 0;

    // Configure serial port 2 for MMC mode
    WriteField(pExtBus -> exbussel, EXBUSSEL_SPMODE_MMC, EXBUSSEL_SP2MODE);

    // Set all the arguments to the default state  
	memset( &csd,		0, sizeof(CSD_STRUCT));
	memset( &cid,		0, sizeof(CID_STRUCT));
	memset( &status,	0, sizeof(STATUS_STRUCT));   
	memset( &Mmc,		0, sizeof(C55XX_MMC));             
	memset( &CardStatus,0, sizeof(CARD_STATUS));
	memset( &CardCid,	0, sizeof(CARD_CID)); 
	memset( &CardCsd,   0, sizeof(CARD_CSD));   

	SaveStat0 	= 0;   
	SaveStat1	= 0;
	OpLoop 		= 0;  
	TestFail 	= 0;
	Debug 		= 1; 	// Enable debug stuff  
	CurrentBlen = 512;

	MmcAddr    	= 2;	// Non-default address

//    Emif_Init();
//	InterruptInit();

    MMC_InitClock();
               

	if( go_idle_state() != 0 ) 
	{
		error = ERROR_IDLE;
		goto MMC_INIT_FAIL; 
	}

	if( send_op_cond() != 0 ) 
	{
		error = ERROR_OP;	
		goto MMC_INIT_FAIL; 
	}
	
	// For simulation test there is only one card so skip
	// multiple card stuff
	if( all_send_cid() != 0 )
	{
		error = ERROR_ALL_CID;	
		goto MMC_INIT_FAIL;
	}	
	   
	// Set the RCA to something other then the
	// default of 0x0001       
	if( set_relative_addr( MmcAddr ) != 0 )
	{	   
		error = ERROR_ADDR;	
		goto MMC_INIT_FAIL;
	}
	  
	// Make sure the card is in Standby at this point	  
	if( send_status( MmcAddr ) != 0 )
	{	   
		error = ERROR_STATUS;	
		goto MMC_INIT_FAIL;
	}
	if( CardStatus.state != stby )
	{
		error = ERROR_STATUS;	
		goto MMC_INIT_FAIL;
	}
	
	// Read the CID via the CID command.  Check for the Sandisk ID.
	// Need to know the Siemens ID.	
	if( send_cid( MmcAddr ) != 0 )
	{	   
		error = ERROR_CID;	
		goto MMC_INIT_FAIL;
	}
	
	if( CardCid.mfg_id != MFG_ID_SANDISK )
	{	   
		error = ERROR_MFG_ID;	
		goto MMC_INIT_FAIL;
	}  
	  
	// Read the CSD and verify that structure is for MMC protocol version 1.4  
	if( send_csd( MmcAddr ) != 0 )
	{	   
		error = ERROR_CSD;	
		goto MMC_INIT_FAIL;
	} 

	if(  CardCsd.csd_struct != 1 )
	{	   
		error = ERROR_CSD_VER;	
		goto MMC_INIT_FAIL;
	}  		

    if( select_card( MmcAddr ))
    {
        error = -1;
        goto MMC_INIT_FAIL;
    }
	
    return( 0 );
     
MMC_INIT_FAIL:
	return( error  );
}

int
MMC_Test( int TestLoop )
{
    int TestFail;
    int i,j; 
	int ErrorCount;
	unsigned long BlockAddr = 0;    
    ErrorCount = 0;

    if( TestFail =  MMC_Init())
        return( -1 );   
    
	for( i=0; i<TestLoop; i++ )
	{
		BlockAddr = 0;	 
		for( j=0; j<4; j++ )
		{
						 
		    for( OpLoop=0; OpLoop<256; OpLoop++)
		    	ReadBlock[OpLoop] = (OpLoop+j+i) + OpLoop;
		    
		    OpLoop = 0;
		     
		    // Set done to 0.  If we get a DATADNE then this will be
		    // set to 1 if DATDNE is working. 
		    Done = 0;
		    		      
			if( TestFail = write_single_block( BlockAddr ))
			    return(-1);	
			
			do
			{	
				if( TestFail = send_status( MmcAddr ))
					return(-1 );
			}while( CardStatus.state == prg );	
			
			BlockAddr += 512;	
			
		}										
                 
		BlockAddr = 0;	 
		for( j=0; j<4; j++ )
		{
		     
			// Set done to 0.  If we get a DATADNE then this will be
		    // set to 1 if DATDNE is working.            
	        Done = 0;
	                  
	                  
	        MMC_ReadBlock(BlockAddr, ReadBlock, 0);
//			if( TestFail = read_single_block( BlockAddr ))
//				return(-1);     
				
		    for( OpLoop=0; OpLoop<256; OpLoop++)
		    	if( ReadBlock[OpLoop] != OpLoop+j+i)
		    		ErrorCount++;		
		
//			if( ErrorCount )
//				return( -1 );   
				
			BlockAddr += 512;
		}   
	
//		if( TestFail = deselect_card( MmcAddr ))
//			return(-1); 
				
	}
	return( 0 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -