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

📄 sd.c

📁 S3C2440开发板SD驱动程序。ADS1.2源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    while((i<50) && (!Chk_CMDend(6, 1)));   	// ACMD6
    
    rSDICSTA = 0xa00;	    // Clear cmd_end(with rsp)   
    
    if (i < 50)
    {	     
	    Uart_Printf("****1bit bus****\n");
	    return	1;
    }
    else
    {
    	return 0;
    }
}

static void TR_Buf_new(void)
{
    //-- Tx & Rx Buffer initialize
    int i;

    for(i = 0; i < MAX_RWBUFFER_BLOCKNUM * WORDS_PER_BLOCK; i++)		//128[word]*16[blk]=8192[byte]
    {
		*(Tx_buffer + i) = i;
	}
		
	for(i = 0; i < MAX_RWBUFFER_BLOCKNUM * WORDS_PER_BLOCK; i++)		//128[word]*16[blk]=8192[byte]
	{
		*(Rx_buffer + i) = 0;
	}

}

static void View_Rx_buf(U32 blocknum)
{
    //-- Display Rx buffer 
    int i;

    for(i = 0; i < WORDS_PER_BLOCK * blocknum; i++)
    {
		Uart_Printf("Rx[%02x] = %08x\n", i, *(Rx_buffer+i));
	}
}

static void View_Tx_buf(U32 blocknum)
{
    //-- Display Tx buffer 
    int i;

    for(i = 0; i < WORDS_PER_BLOCK * blocknum; i++)
    {
		Uart_Printf("Tx[%02x] = %08x\n", i, *(Tx_buffer+i));
	}
}

static void Check_RxTx_buf(U32 blocknum)
{
	//-- Check Rx/Tx buffer 
	int i, error = 0;

    Uart_Printf("----Check Rx/Tx data----\n");

    for(i=0; i < WORDS_PER_BLOCK * blocknum; i++)
    {
    	if(*(Rx_buffer+i) != *(Tx_buffer+i))
		{
		    Uart_Printf("\nTx/Rx error:"); 
		    Uart_Printf("%d:Tx-0x%08x, Rx-0x%08x\n",i,*(Tx_buffer+i), *(Rx_buffer+i));
		    
		    error = 1;
		    //break;
        }
    }
    
    if(!error)
    {
		Uart_Printf("The Tx_buffer is the same to Rx_buffer!\n");
		Uart_Printf("SD CARD Write and Read test is Successful!\n");
	}
}

static int Chk_DATend(void)
{
    int i=0,finish;
    	
    finish = rSDIDSTA;
    
    while( !( ((finish&0x10) == 0x10) | ((finish&0x20) ==0x20) | (i>500) ))		// Chek timeout or data end
	{
		finish = rSDIDSTA;
		i++;
	}
	if( ((finish&0x2) == 0x2) || ((finish&0x1) == 0x1) ) 
		{	
			Delay(200);
		}
    if( (finish&0xf0) != 0x10 )				//wangq,reserved 位也可能为1!!
    {
        Uart_Printf("DATA Error:SDIDatSta=0x%x\n", finish);
        //rSDIDSTA=0xec;  // Clear error state
        rSDIDSTA = 0xf8;  // Clear error state,wangq
        return 0;
    }
    return 1;
}

static int Chk_BUSYend(void)
{
    int finish;

    finish = rSDIDSTA;
    while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))
    {
		finish = rSDIDSTA;
	}

    if( (finish&0xf8) != 0x08 )
    {
        Uart_Printf("DATA Error:SDIDSTA=0x%x\n", finish);
        //rSDIDSTA=0xf4;  //clear error state
        rSDIDSTA = 0xf8;  //clear error state,wangq
        return 0;
    }
    return 1;
}

int SD_Card_Init(card_desc *CardInfo)
{
	//-- SD controller & card initialize 

    int i;    
    card_desc *pCardInfo = CardInfo;
    pCardInfo->RCA = 0;

    /* Important notice for MMC test condition */
    /* Cmd & Data lines must be enabled by pull up resister */
    
    SD_Set_IOPort();

    rSDIPRE = PCLK/(INICLK) - 1;	// 400KHz
	Uart_Printf("Initial Frequency is %dKHz\n",(PCLK/(rSDIPRE+1))/1000 );
    
	rSDICON = (1<<4)|1;				// Type B, clk enable
	rSDIFSTA = rSDIFSTA|(1<<16);	// YH 040223 FIFO reset
    rSDIBSIZE = 0x200;				// 512byte(128word)
    rSDIDTIMER = MAX_DATABUSY_TIMEOUT;			// Set timeout count

    for(i = 0; i < 0x1000; i++);  	// Wait 74 SDCLK for MMC card

    CMD0();
    Uart_Printf("Card is in idle\n");
/*
    //-- Check MMC card OCR
    if (Chk_MMC_OCR() == ENUM_CARD_TYPE_MMC) 	//ACMD1
    {
		Uart_Printf("MMC check end!!\nIn MMC ready\n");
		pCardInfo->Card_Type = ENUM_CARD_TYPE_MMC;
		goto RECMD2;
    }
    else
    {
    	pCardInfo->Card_Type = ENUM_CARD_TYPE_SD;
    }
    
    //-- Check SD card OCR
    
	if (!CMD8())
	{
		return 0;
	}
*/	


	pCardInfo->Card_Type = ENUM_CARD_TYPE_SD;

	i = Chk_SD_OCR();	//ACMD41
    if (i == 1) 	
    {
        //Uart_Printf("----SD Card is Ready----\n"); 
        pCardInfo->Card_Capacity_Stat = ENUM_High_Capacity;       
    }
    else if (i == 2) 
    {
    	pCardInfo->Card_Capacity_Stat = ENUM_Standard_Capacity;  
    }
    else
    {
		return 0;
    }
	

RECMD2:    
	//-- Check attached cards, it makes card identification state
    if(CMD2())			//Get_CID
    {
    	pCardInfo->Maker_ID = ((rSDIRSP0 & 0xff000000) >> 24); 
    	pCardInfo->Product_Name[0] = (rSDIRSP0&0xff0000)>>16;
    	pCardInfo->Product_Name[1] = (rSDIRSP0&0xff00)>>8;
    	pCardInfo->Product_Name[2] = rSDIRSP0&0xff;
    	pCardInfo->Product_Name[3] = (rSDIRSP1 & 0xff000000) >> 24;
    	pCardInfo->Product_Name[4] = (rSDIRSP1&0xff0000)>>16;
    	pCardInfo->Product_Name[5] = (rSDIRSP1&0xff00)>>8;
    	pCardInfo->Product_Name[6] = rSDIRSP1&0xff;
    	pCardInfo->Product_Name[7] = 0;
    	pCardInfo->Serial_Num = ((rSDIRSP2 & 0xffffff) << 8) | ((rSDIRSP3 & 0xff000000) >> 24);
    	pCardInfo->Manufacturing_Date[0] = 2000+((rSDIRSP3&0xff000)>>12);
    	pCardInfo->Manufacturing_Date[1] = (rSDIRSP3&0xf00)>>8;
    }
    else
	{
		return 0;
	}
		
    if(CMD3() != 0)		// Get_RCA	
    {
	    if(pCardInfo->Card_Type == ENUM_CARD_TYPE_MMC)
		{
			pCardInfo->RCA = 1;
			
			rSDIPRE=(PCLK/MMCCLK)-1;	// YH 0812, Normal clock=20MHz
        	Uart_Printf("MMC Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
		}
		else
		{
			pCardInfo->RCA = ( rSDIRSP0 & 0xffff0000 )>>16;
			Uart_Printf("RCA = 0x%x\n",pCardInfo->RCA);
			
			rSDIPRE = (PCLK/SDCLK) - 1;		// Normal clock=25MHz
			Uart_Printf("Now SD Frequency is %dMHz\n",(PCLK/(rSDIPRE+1))/1000000);
		}
		
    }
    else
	{
		return 0;
	}
	
    //CMD13();			// Get card status
    
    Card_Select(pCardInfo->RCA);	// 选中当前卡   
	
	//--设置总线位数
    if(pCardInfo->Card_Type == ENUM_CARD_TYPE_SD)
    {
		SetBus(pCardInfo->RCA, Wide);
	}
    else
    {
		Set_1bit_bus(pCardInfo->RCA);
	}

    return 1;
}


static void __irq DMA_end(void)
{
    ClearPending(BIT_DMA0);
    
    TR_end = 1;
}

void __irq  IsrEINT8_23(void)
{
	rINTMSK = rINTMSK | BIT_EINT8_23; 				// 关中断
	
	if ( rEINTPEND & (1<<16) )
	{	
		Uart_Printf("\nSD Card (EINT16) Detect!!!\n");
	}

	ClearPending(BIT_EINT8_23);						// 清中断状态标志位
	rEINTPEND = (1<<16);							// 清外部中断状态标志位--------重要

 	SD_CardIn = 1;
 	
	rINTMSK = ~(BIT_EINT8_23); 						// 开EINT8_23中断	
	
}

int SD_Rd_Block(card_desc *CardInfo, U32 mode, U32 addr, U32 blocknum)
{
    int status;
    int i = 0;
    int rd_cnt = 0;
	const U32	cc = 1;
	//-----  Reset the FIFO -----
	rSDIFSTA = rSDIFSTA|(1<<16);	// FIFO reset

    if(mode!=2)
		rSDIDCON=(2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<14)|(2<<12)|(blocknum<<0);	//YH 040220
		//Word Rx, Rx after cmd, blk, 4bit bus, Rx start, blk num, data start, data transmit mode

    rSDICARG = addr;				// CMD17/18(addr)读地址

    switch(mode)
    {
	case POL:
	    if(blocknum<2)	// SINGLE_READ
	    {	   
			do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x51;	// sht_resp, wait_resp, dat, start, CMD17
				i++;
			}
			while(!Chk_CMDend(17, 1) && (i<50));	//-- Check end of CMD17
			if(i == 50)
			{
				Uart_Printf("CMD18 Failed\n");
				return 0;
		    }
	    }
	    else		// MULTI_READ
	    {
			do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    // sht_resp, wait_resp, dat, start, CMD18
				i++;
			}
			while(!Chk_CMDend(18, 1) && (i<50));	//-- Check end of CMD18 
			if(i == 50)
			{
				Uart_Printf("CMD18 Failed\n");
				return 0;
		    }
	    }

	    rSDICSTA = 0xa00;	// Clear cmd_end(with rsp)	    

	    while(rd_cnt < (128*blocknum))	// 512*block bytes
	    {
	    	//Uart_Printf("***rd_cnt:%d dat:%d\n",rd_cnt,rSDIDAT);
			if ((rSDIDSTA & 0x20) == 0x20) 			// Check timeout 
			{
			    //rSDIDSTA=(0x1<<0x5);  			// Clear timeout flag
			    rSDIDSTA = (0x1<<5);  			// Clear timeout flag,wangq
			   
			    Uart_Printf("Read Error,timeout!!!\n");
			    break;
			}
			status = rSDIFSTA;
			if((status&0x1000) == 0x1000)			// Is Rx data?
			{				
				//Uart_Printf("Number of data(byte) in FIFO:%d \n",status&0x7f);	
				//for(i=0; i < (status&0x7f); i++)
				{
				    *(Rx_buffer+rd_cnt) = rSDIDAT;
				    //Uart_Printf("rd_cnt:%d dat:%d\n", rd_cnt, *(Rx_buffer+rd_cnt));		    
				    rd_cnt++;
			    }
			}
			
	    }
	    break;
	
	case INT:
		return 0;
	/*
	    pISR_SDI=(unsigned)Rd_Int;
	    rINTMSK = ~(BIT_SDI);
	    
	    rSDIIMSK=5;	// Last & Rx FIFO half int.

	    if(blocknum<2)	// SINGLE_READ
	    {
		rSDICCON=(0x1<<9)|(0x1<<8)|0x51;    // sht_resp, wait_resp, dat, start, CMD17
		if(!Chk_CMDend(17, 1))	//-- Check end of CMD17
		    goto RERDCMD;	    
	    }
	    else	// MULTI_READ
	    {
		rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    // sht_resp, wait_resp, dat, start, CMD18
		if(!Chk_CMDend(18, 1))	//-- Check end of CMD18 
		    goto RERDCMD;
	    }
    
	    rSDICSTA=0xa00;	// Clear cmd_end(with rsp)

	    while(rd_cnt<128*blocknum);

	    rINTMSK |= (BIT_SDI);
	    rSDIIMSK=0;	// All mask
	    break;
	*/
	case DMA:
	    pISR_DMA0 = (unsigned)DMA_end;
 
	    rINTMSK = ~(BIT_DMA0);					// 开DMA0中断
	    	    
		rSDIDCON = rSDIDCON | (1<<24); 			//YH 040227, Burst4 Enable
		
		//----- Initialize the DMA channel for input mode -----
		rDISRC0 = (int)(SDIDAT);				// source=SDIDAT
	    rDISRCC0 = (1<<1) | (1<<0);				// APB, fix
	    rDIDST0 = (U32)(Rx_buffer);				// Destination=Rx_buffer
	    rDIDSTC0 = (0<<1) | (0<<0);				// TC reaches 0 Interrupt,AHB, inc
	    rDCON0 = (cc<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+(128*blocknum);
			    //handshake, sync PCLK, TC int, A unit tx, single service, SDI, H/W request, 
			    //auto-reload off, word, 128blk*num 
	    
	    
	    rSDIDCON = (2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(1<<14)|(2<<12)|(blocknum<<0);
		    // Word Rx, Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num, Data start, data receive mode, YH 040220
   		
   		i = 0;
		if(blocknum<2)	// SINGLE_READ
	    {	   
			do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x51;	// sht_resp, wait_resp, dat, start, CMD17
				i++;
			}
			while(!Chk_CMDend(17, 1) && (i<50));	//-- Check end of CMD17
			if(i == 50)
			{
				Uart_Printf("CMD18 Failed\n");
				return 0;
		    }
	    }
	    else		// MULTI_READ
	    {
			do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x52;    // sht_resp, wait_resp, dat, start, CMD18
				i++;
			}
			while(!Chk_CMDend(18, 1) && (i<50));	//-- Check end of CMD18 
			if(i == 50)
			{
				Uart_Printf("CMD18 Failed\n");
				return 0;

⌨️ 快捷键说明

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