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

📄 sdmmc.c

📁 SD卡驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			// Now the boot sector
			if((error = LoadBootSector(dsk)) == CE_GOOD)
				dsk->mount = TRUE; // Mark that the DISK mounted successfully
		}

	} // -- Initialize the SDMMC card

	return(error);
} // -- mount

/******************************************************************************
 * Function:        CETYPE LoadMBR ( DISK *dsk)
 *
 * PreCondition:    Called from DISKmount
 *
 * Input:           dsk		- The disk containing the master boot record to be loaded
 *
 * Output:          CE_GOOD 			- MBR loaded successfully
 *                  CE_BAD_SECTOR_READ	- A bad read occured of a sector 
 *					CE_BAD_PARTITION	- The boot record is bad
 *
 * Side Effects:    None
 *
 * Overview:        Loads the MBR and extracts the necessary information
 *
 * Note:            None
 *****************************************************************************/

BYTE LoadMBR(DISK *dsk)
{
    PT_FAT  Partition;
    BYTE error = CE_GOOD;
    BYTE type;

    // Get the partition table from the MBR
    if ( SECTORread( FO_MBR, dsk->buffer) != TRUE) 
        error = CE_BAD_SECTOR_READ;
    else
    {
		// assign it the partition table strucutre
    	Partition = (PT_FAT)dsk->buffer;
    
        // Ensure its good
        if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
        {
            error = CE_BAD_PARTITION;
        }
        else
        {    
            /*    Valid Master Boot Record Loaded   */

            // Get the 32 bit offset to the first partition 
            dsk->firsts = Partition->Partition0.PTE_FrstSect; 

            // check if the partition type is acceptable
           	type = Partition->Partition0.PTE_FSDesc;
			
            switch (type)
            {
                case 0x01:
				//============================================================================
				//Stephen Jiang 2006,10,31
				//substitue following 2 lines for supporting 16MB SD card

                //   dsk->type = FAT12;
                //   error = CE_CARDFAT12;
                dsk->type = FAT16;
				type=0x0e;
                //=============================================================================


                    break;
               
				case 0x04:
                case 0x06:
                case 0x0E:
                    dsk->type = FAT16;
                    break;
                
                case 0x0B:
                case 0x0C:
                    dsk->type = FAT32; // and error out				
                    error = CE_CARDFAT32;
                    break;
                    
                default:
                    error = CE_BAD_PARTITION;
            } // switch 
        }
    }

    return(error);
}// -- LoadMBR


/******************************************************************************
 * Function:        BYTE LoadBootSector (DISK *dsk)
 *
 * PreCondition:    Called from DISKmount
 *
 * Input:           dsk		- The disk containing the boot sector
 *                  
 * Output:          CE_GOOD 			- Boot sector loaded
 *                  CE_BAD_SECTOR_READ	- A bad read occured of a sector 
 *					CE_NOT_FORMATTED	- The disk is of an unsupported format
 *					CE_CARDFAT12		- FAT12 during intial testing we are not supporting FAT12
 *					CE_CARDFAT32		- FAT 32 - card not supported
 *
 * Side Effects:    None
 *
 * Overview:        Load the boot sector information and extract the necessary information
 *
 * Note:            None
 *****************************************************************************/

/*
BYTE LoadBootSector(DISK *dsk)
{
    WORD     RootDirSectors;
    DWORD     TotSec,DataSec;
    BYTE      error = CE_GOOD;
    BS		BootSec;        // boot sector, assume its FAT16 til we know better

	WORD   BytesPerSec;
                    
    // Get the Boot sector
	Delayms(10);
    if ( SECTORread(dsk->firsts, dsk->buffer) != TRUE) 

        error = CE_BAD_SECTOR_READ;  
    else
    {
        // Assign the type
        BootSec = (BS)dsk->buffer;

        //Verify the Boot Sector is valid
        if((BootSec->Signature0 != FAT_GOOD_SIGN_0) || (BootSec->Signature1 != FAT_GOOD_SIGN_1))
        {
            error = CE_NOT_FORMATTED;
        }
        else
        {     
            // determine the number of sectors in one FAT (FATSz)
			dsk->fatsize = ReadWord( dsk->buffer, BSI_FATSz16 ); 

			// Figure out the total number of sectors
	        TotSec = ReadWord( dsk->buffer, BSI_TotSec16 );
			if( TotSec == 0 )
				TotSec = ReadDWord( dsk->buffer, BSI_TotSec32 );
            	                       
	        // 6.  get the full partition/drive layout
	        // 6.1 determine the size of a cluster
	        dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SecPerClus );
	        	        
	        // 6.2 determine fat, root and data lbas
	        // FAT = first sector in partition (boot record) + reserved records
	      // dsk->fat        = dsk->firsts + ReadWord( dsk->buffer, BSI_RsvdSecCount );
	        dsk->fat        =  ReadWord( dsk->buffer, BSI_RsvdSecCount );
	        // 6.3 fatcopy is the number of FAT tables 
	        dsk->fatcopy    = ReadByte( dsk->buffer, BSI_NumFATs );

	        // 6.4 MAX ROOT is the maximum number of entries in the root directory
	        dsk->maxroot    = ReadWord( dsk->buffer, BSI_RootEntCnt );   
	        
            // "root" Is the sector location of the root directory
            dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);

			BytesPerSec = ReadWord( dsk->buffer, BSI_BytesPerSec );

			if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 ) //cannot be 0 or odd
				return( CE_NOT_FORMATTED );
	                        
	        RootDirSectors = ((dsk->maxroot * 32) + (BytesPerSec - 1)) / BytesPerSec;               

			// figure out how many data sectors there is 
            DataSec = TotSec - (dsk->root + RootDirSectors);
	        
	        dsk->maxcls = DataSec / dsk->SecPerClus;
	        
	        // Straight out of MS FAT Hardware White Paper
	        if(dsk->maxcls < 4085)
	        {
	            // Volume is FAT12 
	            dsk->type = FAT12;
                error = CE_CARDFAT12;
    	    }
    	    else 
			{
				if(dsk->maxcls < 65525)
	    	    {
	    	        //Volume is FAT16 
	    	        dsk->type = FAT16;
	    	    }
	    	    else
	    	        // Volume is FAT32 
	    	        // We don't support FAT32
	    	        error = CE_CARDFAT32;     
			}
	                	        
	        // 6.5 DATA = ROOT + (MAXIMUM ROOT *32 / 512) 
	        dsk->data = dsk->root + ( dsk->maxroot >> 4); // assuming maxroot % 16 == 0!!!
	        
	        // make sure that we can read in a complete sector!
	        if(BytesPerSec != MEDIA_SECTOR_SIZE)
	            error = CE_NOT_FORMATTED;
		}
    }

	return(error);
}
*/
BYTE LoadBootSector(DISK *dsk)
{
    WORD     RootDirSectors;
    DWORD     TotSec,DataSec;
    BYTE      error = CE_GOOD;
    BS		BootSec;        // boot sector, assume its FAT16 til we know better

	WORD   BytesPerSec;
                    
    // Get the Boot sector
    if ( SECTORread( dsk->firsts, dsk->buffer) != TRUE) 

        error = CE_BAD_SECTOR_READ;  
    else
    {
        // Assign the type
        BootSec = (BS)dsk->buffer;

        //Verify the Boot Sector is valid

        if((BootSec->Signature0 != FAT_GOOD_SIGN_0) || (BootSec->Signature1 != FAT_GOOD_SIGN_1))
        {
            error = CE_NOT_FORMATTED;
        }
        else
        {     
            // determine the number of sectors in one FAT (FATSz)
			dsk->fatsize = ReadWord( dsk->buffer, BSI_FATSz16 ); 

			// Figure out the total number of sectors
	        TotSec = ReadWord( dsk->buffer, BSI_TotSec16 );
			if( TotSec == 0 )
				TotSec = ReadDWord( dsk->buffer, BSI_TotSec32 );
            	                       
	        // 6.  get the full partition/drive layout
	        // 6.1 determine the size of a cluster
	        dsk->SecPerClus = ReadByte( dsk->buffer, BSI_SecPerClus );
	        	        
	        // 6.2 determine fat, root and data lbas
	        // FAT = first sector in partition (boot record) + reserved records
	        dsk->fat        = dsk->firsts + ReadWord( dsk->buffer, BSI_RsvdSecCount );
	        
	        // 6.3 fatcopy is the number of FAT tables 
	        dsk->fatcopy    = ReadByte( dsk->buffer, BSI_NumFATs );

	        // 6.4 MAX ROOT is the maximum number of entries in the root directory
	        dsk->maxroot    = ReadWord( dsk->buffer, BSI_RootEntCnt );   
	        
            // "root" Is the sector location of the root directory
            dsk->root = dsk->fat + (dsk->fatcopy * dsk->fatsize);

			BytesPerSec = ReadWord( dsk->buffer, BSI_BytesPerSec );

			if( BytesPerSec == 0 || (BytesPerSec & 1) == 1 ) //cannot be 0 or odd
				return( CE_NOT_FORMATTED );
	                        
	        RootDirSectors = ((dsk->maxroot * 32) + (BytesPerSec - 1)) / BytesPerSec;               

			// figure out how many data sectors there is 
            DataSec = TotSec - (dsk->root + RootDirSectors);
	        
	        dsk->maxcls = DataSec / dsk->SecPerClus;
	        
	        // Straight out of MS FAT Hardware White Paper
	        if(dsk->maxcls < 4085)
	        {
	            /* Volume is FAT12 */
	            dsk->type = FAT12;
                error = CE_CARDFAT12;
    	    }
    	    else 
			{
				if(dsk->maxcls < 65525)
	    	    {
	    	        /* Volume is FAT16 */
	    	        dsk->type = FAT16;
	    	    }
	    	    else
	    	        /* Volume is FAT32 */
	    	        // We don't support FAT32
	    	        error = CE_CARDFAT32;     
			}
	                	        
	        // 6.5 DATA = ROOT + (MAXIMUM ROOT *32 / 512) 
	        dsk->data = dsk->root + ( dsk->maxroot >> 4); // assuming maxroot % 16 == 0!!!
	        
	        // make sure that we can read in a complete sector!
	        if(BytesPerSec != MEDIA_SECTOR_SIZE)
	            error = CE_NOT_FORMATTED;
		}
    }

	return(error);
}


/******************************************************************************
 * Function:        void StopCard(DISK *dsk, CARDSTATUS *cs)
 *
 * PreCondition:    Disk mounted
 *
 * Input:           cs		- Status of the card
 *					dsk		- Disk to be unmounted
 *                  
 * Output:			void
 *
 * Side Effects:    None
 *
 * Overview:        Cleanly unmount the card and fix the status
 *
 * Note:            None
 *****************************************************************************/

void StopCard(DISK *dsk, CARDSTATUS *cs)
{
    // turn off the card
    ShutdownMedia();
    
    cs->_word = 0x00;
    
    dsk->mount = FALSE;     
}



BYTE ReadByte( BYTE* pBuffer, WORD index )
{
	return( pBuffer[index] );
}

WORD ReadWord( BYTE* pBuffer, WORD index )
{
	BYTE loByte, hiByte;
	WORD res;

	loByte = pBuffer[index];
	hiByte = pBuffer[index+1];
	res = hiByte;
	res *= 0x100;
	res |= loByte;
	return( res );
}
DWORD ReadDWord( BYTE* pBuffer, WORD index )
{
	WORD loWord, hiWord;
	DWORD result;

	loWord = ReadWord( pBuffer, index );
	hiWord = ReadWord( pBuffer, index+2 );

	result = hiWord;
	result *= 0x10000;
	result |= loWord;
	return result;
}
//这个函数主要用来读取SD卡中的寄存器
BYTE SD_ReadRegister(WORD len, BYTE *recbuf)
{	
	WORD i = 0;
	BYTE resp;

    CS_LOW;
    do{    											/* 等待数据起始令牌 wait for data start token */
        resp = SPI_RecByte();
    	i++;
    }while((resp == 0xFF) && (i < 0xFFF));    
    
    if (i >= 0xFFF)
    {
    	CS_HIGH;
    	return 1;					/* 超时, 返回错误 timeout, return error */
  	}
  	
   	if (resp != 0xFE)				
   	{												/* 不是收到数据起始令牌 not receive data start token */
		recbuf[0] = resp;							
		i = 1;										/* 还有len - 1个字节要接收 still len - 1 bytes will be received */
   	}
   	else
   		i = 0;										/* 收到数据起始令牌,还有len个字节要接收 received data start token,still len bytes will be received */
   	  	
    for (; i < len; i++)
   		recbuf[i] = SPI_RecByte();					/* 接收数据 receive data */
   		
    i = SPI_RecByte();								
    i = (i << 8) + SPI_RecByte();    				/* 读取16位CRC get 16-bit CRC */	


  
    SPI_SendByte(0xFF);								/* 返回之前发送8个clock  clock out 8 clk before return */
    CS_HIGH;	
    	
	return 0;
}	
BYTE SD_ReadCSD(BYTE csdlen, BYTE *recbuf)
{
    MMC_RESPONSE ret;
  
    ret = SendMMCCmd(SEND_CSD,0);		/* 读CSD寄存器命令 command that read CSD register */								
    
	return (SD_ReadRegister(csdlen, recbuf));
}
BYTE SD_GetCardInfo()
{
	WORD tmp;
	BYTE csdbuf[16],ret;
	sd_struct sds;
		
	ret = SD_ReadCSD(16,csdbuf);	 								    		/* 读CSD寄存器    read CSD register */
	if (ret != 0)	
		return ret;	
		
	//SD_CalTimeout(csdbuf);														/* 计算超时时间值 calculate timeout value */
		
	/* 计算块的最大长度  */														/* calculate the size of a sector */
	sds.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK);  			/* (2 ^ READ_BL_LEN) */
	
	/* 计算卡中块的个数 */														/* calculate the sector numbers of the SD Card */
	sds.block_num = ((csdbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
	      			 (csdbuf[C_SIZE_POS2] << 2) +
	 	 			((csdbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1;				/* (C_SIZE + 1)*/
		 	  															
	tmp = ((csdbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +   
	      ((csdbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2;				/* (C_SIZE_MULT + 2) */
    	
    /* 获得卡中块的数量 */														/* get the block numbers in card */
	sds.block_num = sds.block_num * (1 << tmp);									/* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
																			
	/* 计算扇区大小 */															/*calculate the size of sector */
	sds.erase_unit = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +  			
	                 ((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* SD (SECTOR_SIZE + 1) */
	    			
	return 0;															/* 返回执行成功 return perform sucessfully */
}

⌨️ 快捷键说明

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