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

📄 sd.c

📁 mp3播放器
💻 C
📖 第 1 页 / 共 4 页
字号:
#include "dp8051.h"
#include "config.h"
#include "absacc.h"
#include "constant.h"
#include "variable.h"
#include "function.h"
#include "sdhost.h"
#include "sssmp3_regs.h"
#include "fat.h"
#include "mp3_appl.h"
//***********************************************
#if 0
idata Uint32   sd_mem_size;   /* memory disk size in pages */

#define Sd_disk_size()        (( Uint32 )( sd_mem_size ))
#endif

extern Bool gfSysUSBMP3Mode;
/************************************************
函 数 名: SYSDelay()
功    能:系统延时
说    明:
调    用:
全局变量:i
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SYSDelay(void)
{
	for( varAl.i = 0; varAl.i < 0x1FFF; varAl.i++ );
}
/************************************************
函 数 名: SDCIF_Init()
功    能:SD Host初始化
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SDCIF_Init( void )
{
   // for SD_Host initial, 100KHz~400KHz
   // Either VBUS in or not
   if( gfSysUSBMP3Mode )
   {
      // in USB mode
      SDH_CLOCK = 0x4C; 
   }
   else
   {
      // in MP3 mode
      //SDH_CLOCK = 0x0F;  // CLK down to 380(375)KHz for MMC card, 
      SDH_CLOCK = 0x1F;    // CLK down to 380(375)KHz for MMC card, 
   }  // but In USB V_Bus mode will be 375*2.5=937KHz
   
  	//SDH_CLOCK = 0x0F;//32分频
  	//SDH_DMA_CS = 0x05;//SRAM5

  	// select SD DMA Buffer
   //SDH_DMA_CS = 0x00; // select buffer 0 at 0x9000  
   SDH_DMA_CS = 0x01;   // select buffer 0 at 0x9000  
 
   varAl.USB_DMA_CS = 0;
  	
  	SDIFCON0 = CLK_EN;   //clock enable
  	BLKCNT11_08 = 0;
  	BLKCNT07_00 = 0;
  	BLKLEN11_08 = 0x02;
  	BLKLEN07_00 = 0x00;
  	DATACON = 0x00;

  	// pls note that new FPGA has added one byte timer count
  	DTIMER15_08 = 0xFF;
  	DTIMER07_00 = 0xFF;
}
/************************************************
函 数 名: GetSDMemoryOCR()
功    能:获得SD卡Operating Conditions Register
说    明:SDCIF_IF:  0 -> SD Memory,1 -> SDIO,2 --> MMC
调    用:
全局变量:RCA, OCR, SDCIF_IF
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool GetSDMemoryOCR( void )
{
  	Bool flag = 0;
  	Bool SDv20CCS = 0;
  	SDCIF_CMD0();
  	SDCIF_CMD08();

  	SDVar.RCA[ 1 ] = 0;
  	SDVar.RCA[ 0 ] = 0;

  	SDVar.OCR[ 3 ] = 0;
  	if( SDVar.Info.CardVer2 )
  	   SDVar.OCR[ 3 ] |= 0x40; // SD 2.0 --> CMD8 resp
  	SDVar.OCR[ 2 ] = 0;
  	SDVar.OCR[ 1 ] = 0;
  	SDVar.OCR[ 0 ] = 0;
  	do
  	{
  	   // --------- CMD55---------- RCA = 0x0000 
      if( !SDCIF_CMD55())
      {
         flag = 1;
	  		break;
      }
      // --------- ACMD41---------- OCR = 0x0000 -> High
      if( !SDCIF_ACMD41())
      {
         flag = 1;
         break;
      }
      if( SDVar.Info.CardVer2 )
      {
         // SD 2.0 --> CMD8 resp
         SDVar.OCR[ 3 ] = 0x40;
         if( RESP119_112 & BIT6 )
            SDv20CCS = 1;
      }
      else
      {
         SDVar.OCR[ 3 ] = RESP119_112 & 0x7F;
      }
      
      SDVar.OCR[ 2 ] = RREP111_104;
      SDVar.OCR[ 1 ] = RREP103_096;
      SDVar.OCR[ 0 ] = RREP095_088;
  	}
  	while( !( RESP119_112 & 0x80 )); // wait Bit31 is ready
  	SDVar.Info.SDCIF_IF = 0;   //0 -> SD Memory
  	if( SDv20CCS == 0 )
  	   SDVar.Info.CardVer2 = 0 ;  // SDv20 card but in low-capacity card

  	//MMC
  	if( !flag )
      return OK;

   SDIFCON0 = 0x00;  // CLK Dis-able ,Mason@20060309
   for( varAl.i = 0; varAl.i < 0x7000; varAl.i++ );   // delay
   // gfSysUSBMP3Mode
   if( gfSysUSBMP3Mode )
   {
      // in USB mode
      SDH_CLOCK = 0x59;       
   }
   else
   {                     	            	
      SDH_CLOCK = 0x27;	
   }   
   //SDH_CLOCK = 0x3B;
   SDIFCON0 = CLK_EN;   // CLK enable & 1-bit Bus mode 
     
   SDCIF_CMD0();
   SDVar.OCR[ 3 ] = 0;
   SDVar.OCR[ 2 ] = 0;
   SDVar.OCR[ 1 ] = 0;
   SDVar.OCR[ 0 ] = 0;
   
   // Finding MMC card by CMD1
   do
   {
      if( !SDCIF_CMD1())
         return KO;
      SDVar.OCR[ 3 ] = RESP119_112 & 0x7F;
      SDVar.OCR[ 2 ] = RREP111_104;
      SDVar.OCR[ 1 ] = RREP103_096;
      SDVar.OCR[ 0 ] = RREP095_088;
   }
   while( !( RESP119_112 & 0x80 )); // wait Bit31 is ready
   SDVar.Info.SDCIF_IF = 2;   //2 --> MMC
   return OK;
}
/************************************************
函 数 名: SDMemoryCardInit()
功    能:SD卡初始化
说    明:
调    用:
全局变量:BusBits
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SDMemoryCardInit( void )
{
   idata unsigned char CMD6_SW;
   
   if( !SDCIF_CMD2()
      && ( SDVar.SDCIF_IF == 2 ))   // for MMC card, init twice if its failed in 1st time
   {
      SDH_CLOCK = 0x40;
      //SDH_CLOCK = 0x19;  // 230K  seems all OK
      SYSDelay();
      GetSDMemoryOCR();
      if( !SDCIF_CMD2())
      {
         SDH_CLOCK = 0x50; // 46K  for MMC one last time
         SYSDelay();
         GetSDMemoryOCR();
         SDCIF_CMD2();
      }
   }

   SDCIF_CMD3();

   SDCIF_CMD09();

   if( gfSysUSBMP3Mode )
   {
      // Read Card capacity only in USB mode
      Read_CardCapacity(); // Mason@0116
   }

   // CMD7 to enter Transfer Mode
   SDCIF_SDIOCMD7(); // SD & SDIO use a same CMD7

   //* change to 4 bits mode for SD Card only
   if( !SDVar.Info.SDCIF_IF )
   {
      SDCIF_CMD55();
      SDVar.BusBits = 0x02;   //2 -> 4-bit bus
      SDCIF_ACMD06();   //set bus wide
      /*if(SDVar.ErrVal)
      {
         //while(P1_6);
         SDIFCON0 = 0x00;
         SYSDelay();
         (*(void(*)())0)();
      }*/
   }

   // need to add MMC in High-speed mode
   if( gfSysUSBMP3Mode )
   {
      // Detect Speed mode in USB mode
      for( varAl.i = 0; varAl.i < 64; varAl.i++ )
         XBYTE[ 0x9000 + varAl.i ] = 0;
      ChkCurrentState();

      if( SDVar.Info.SDCIF_IF == 0 )
      {
         CMD6_SW = 0;
         if( SDCIF_CMD6( SWITCH_FUNCTION_CHECK ))
         {
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            for( varAl.i = 0; varAl.i < 0x1ff; varAl.i++ ); // a delay --> must
            if(( XBYTE[ 0x9000 + 13 ]& 0x03 ) == 0x03 )
            {
               if( SDCIF_CMD6( SWITCH_FUNCTION_SET ))
                  CMD6_SW = 1;
               else
                  CMD6_SW = 0;
               
            }
         }
      }
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      if(( SDVar.Info.CardVer2 )||( CMD6_SW == 1 ))
         SDH_CLOCK = 0x00; // CLK up to 30MHz for High-Speed mode
      else
         SDH_CLOCK = 0x01; // CLK down to 15MHz for SD Memory card
   }
   else
   {
      // in MP3 mode , SD Host in 12MHz
      SDH_CLOCK = 0x00;
   }
   
   //SDH_CLOCK = CLK_SEL; //system clock

   //DTIMER15_08 = 0x00;
   //DTIMER07_00 = 0x2E;
}
/************************************************
函 数 名: SDCIF_CMD0()
功    能:Resets all cards to Idle State
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
//复位SD卡,进入空闲状态
void SDCIF_CMD0( void )
{
   ARG31_24 = 0;//argument dont't care
   ARG23_16 = 0;
   ARG15_08 = 0;
   ARG07_00 = 0;
   CMDCON = 0;
   CMDINDEX = GO_IDLE_STATE;
   while( !( STATUS07_00 & CMDSEND ));
   STATUS07_00 = 0xFF;
}
/************************************************
函 数 名: SDCIF_CMD1()
功    能:ask MMC to send their Operation Conditions
说    明:
调    用:
全局变量:OCR
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_CMD1(void)// MMC card used
{
   Bool status = OK;
   ARG31_24 = SDVar.OCR[ 3 ]; // argument = OCR
   ARG23_16 = SDVar.OCR[ 2 ];
   ARG15_08 = SDVar.OCR[ 1 ];
   ARG07_00 = SDVar.OCR[ 0 ];
   CMDCON = WAITRSP;          // short respnse
   CMDINDEX = SEND_OP_COND;   // CMD1
   while( !( STATUS07_00 & CMDSEND ));
   while( !( STATUS07_00 & RSPRXVP ))
   {
      if(( STATUS07_00 & RSPTIMEOUT )/*||( STATUS07_00 & CRC7ERROR )*/)
      {
	      //STATUS07_00 = 0xFF;
	      //return KO;
	      status = KO;
	      break;
      }
   }
   STATUS07_00 = 0xFF;
   return status;
}
/************************************************
函 数 名: SDCIF_CMD2()
功    能:Asks any card to send their CID numbers on the CMD line
说    明:
调    用:
全局变量:
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
//获得CID(card identification)	进入识别状态
Bool SDCIF_CMD2( void )
{
   Bool status = OK;
   idata U8 deleycnt;
   //argument dont't care
   /*if( SDVar.Info.SDCIF_IF )
   {
      // for MMC
      ARG31_24 = 0; 
      ARG23_16 = 0;
      ARG15_08 = 0;
      ARG07_00 = 0;
   }*/

   CMDCON = LONGRSP | WAITRSP;   // Long respnse
   CMDINDEX = ALL_SEND_CID;      // CMD2
   while( !( STATUS07_00 & CMDSEND ));
   while( !( STATUS07_00 & RSPRXVP ))
   {
      /*if(( STATUS07_00 & RSPTIMEOUT )
         ||( STATUS07_00 & CRC7ERROR ))*/
      if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
      {
         //STATUS07_00 = 0xFF;
         //return KO;
         for( deleycnt = 0; deleycnt < 0xF0; deleycnt++ );
         status = KO;
         break;
      }
   }
   STATUS07_00 = 0xFF;
   //return OK;
   return status;
}
/************************************************
函 数 名: SDCIF_CMD3()
功    能:Asks the card to publish a new relative address
说    明:get RCA
调    用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
//获得RCA(relative card address)
Bool SDCIF_CMD3( void )
{
   Bool status = OK;

   //argument dont't care if SD
   if( SDVar.Info.SDCIF_IF ) //MMC or SDIO
   {
      SDVar.RCA[ 1 ] = 0;
	   SDVar.RCA[ 0 ] = 1;
      ARG31_24 = SDVar.RCA[ 1 ];
      ARG23_16 = SDVar.RCA[ 0 ];
      ARG15_08 = 0;
      ARG07_00 = 0;
   }
   CMDCON = WAITRSP;    // short respnse
   CMDINDEX = SEND_RCA; // CMD3
   while( !( STATUS07_00 & CMDSEND ));
   while( !( STATUS07_00 & RSPRXVP ))
   {
      /*if(( STATUS07_00 & RSPTIMEOUT )
         ||( STATUS07_00 & CRC7ERROR ))*/
      if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
      {
         //STATUS07_00 = 0xFF;
         //return KO;
         status = KO;
         break;
      }
   }
   STATUS07_00 = 0xFF;

   if( !SDVar.Info.SDCIF_IF ) //SD
   {
      SDVar.RCA[ 1 ] = RESP119_112; //get RCA
      SDVar.RCA[ 0 ] = RREP111_104;
   }
   SDVar.CardStatus[ 1 ] = RREP103_096;
   SDVar.CardStatus[ 0 ] = RREP095_088;

   ChkCurrentState();
   //return OK;
   return status;
}
/************************************************
函 数 名: SDCIF_CMD6()
功    能:Checking High-speed mode supported or not
说    明:
调    用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_CMD6( U8 modeset )
{
   Bool status = OK;
 
   //if( SDVar.Info.CardVer2 == 0 )
   {
      BLKLEN11_08 = 0x00;
      BLKLEN07_00 = 0x40;
   }

   DATACON = 0x00;

   ARG31_24 = modeset;
   ARG23_16 = 0xFF;
   ARG15_08 = 0xFF;
   ARG07_00 = 0x01;
   
   //CMDCON = WAITRSP;  // short respnse
   CMDCON = WAITRSP | DATA_WITH; // short respnse with data Xfer
  
   CMDINDEX = SWITCH_FUNCTION; //CMD6
   while( !( STATUS07_00 & CMDSEND ));
   while( !( STATUS07_00 & RSPRXVP ))
   {
      // maybe re-moved
      //if( STATUS07_00 & RSPTIMEOUT )
      if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR | DTIMEOUT | CRC16ERROR ))
      {
         status = KO;
         break;
      }
      /*if( STATUS07_00 & CRC7ERROR )
      {
         status = KO;
         break;
      }*/

   //}
   //while( !( STATUS07_00 & XFEREND ))
   //{
      // Marked for USB Testing...Mason@20060302
      /*if( STATUS07_00 & DTIMEOUT )
      {
         status = KO;
         break;
      }
      if( STATUS07_00 & CRC16ERROR )
      {
         status = KO;
         break;
      }*/
      if( STATUS07_00 & XFEREND )
      {
         //status = OK;
         break;
      }
   }

   STATUS07_00 = 0xFF;

   BLKLEN11_08 = 0x02;
   BLKLEN07_00 = 0x00;
   return status;
}
/************************************************
函 数 名: SDCIF_SDIOCMD7()
功    能:选择/释放SD卡(RCA)
说    明:
调    用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_SDIOCMD7( void )
{
   Bool status = OK;
   ARG31_24 = SDVar.RCA[ 1 ];//argument = RCA, form CMD3
   ARG23_16 = SDVar.RCA[ 0 ];
   //ARG15_08 = 0;//argument dont't care
   //ARG07_00 = 0;
   CMDCON = WAITRSP;
   CMDINDEX = SELECT_DESELECT;
   while( !( STATUS07_00 & CMDSEND ));
   while( !( STATUS07_00 & RSPRXVP ))
   {
      /*if(( STATUS07_00 & RSPTIMEOUT )
         ||( STATUS07_00 & CRC7ERROR ))*/
      if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
      {
         //STATUS07_00 = 0xFF;

⌨️ 快捷键说明

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