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

📄 sd.c

📁 S3C2440开发板SD驱动程序。ADS1.2源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		    }
	    }

	    rSDICSTA = 0xa00;							// Clear cmd_end(with rsp)
	    Delay(50);
	    
	    rDMASKTRIG0 = (0<<2)+(1<<1)+0;    			//no-stop, DMA0 channel on, no-sw trigger

	    while(!TR_end);
		Uart_Printf("rSDIFSTA=0x%x\n",rSDIFSTA);
	    rINTMSK |= (BIT_DMA0);
	    TR_end = 0;
	    rDMASKTRIG0 = (1<<2);						//DMA0 stop

	    break;

	default:
	    break;
    }
    
    //-- Check end of DATA
    for (i = 0; i < 50; i++)
    {
	    if(Chk_DATend())
		{
			break;
		}
	    else
	    {
			Uart_Printf("Read Dat Error!!\n");
			return 0;
		}
	}
	
	rSDIDCON = rSDIDCON&~(7<<12);		//YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
	rSDIFSTA = rSDIFSTA&0x200;		//Clear Rx FIFO Last data Ready, YH 040221
    rSDIDSTA = 0x10;					// Clear data Tx/Rx end detect

    if(blocknum > 1)
    {
    	i = 0;
		do
		{    
			//--Stop cmd(CMD12)
			rSDICARG = 0x0;	    			//CMD12(stuff bit)
			rSDICCON = (0x1<<9)|(0x1<<8)|0x4c;//sht_resp, wait_resp, start, CMD12
			i++;
		}		
		//-- Check end of CMD12
		while(!Chk_CMDend(12, 1) && (i < 100)); 

		rSDICSTA = 0xa00;	// Clear cmd_end(with rsp)
    }
    //CMD13();
    
    return 1;
}

int SD_Wt_Block(card_desc *CardInfo, U32 mode, U32 addr, U32 blocknum)
{
    int status;
    int i = 0;
    int wt_cnt = 0; 
	const U32 cc = 1;
	
	rSDIFSTA = rSDIFSTA | (1<<16);		//YH 040223 FIFO reset

    if (mode != 2)
    {
		//rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(3<<12)|(block<<0);
		rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(blocknum<<0);	//YH 040220

		    //Word Tx, Tx after rsp, blk, 4bit bus, Tx start,Data transmit mode, blk num
	}

    rSDICARG = addr;	    			// CMD24/25(addr)写入地址

    switch(mode)
    {
	case POL:
	    if(blocknum < 2)	// SINGLE_WRITE
	    {
			do
			{
				rSDICCON = (0x1<<9)|(0x1<<8)|0x58;	//sht_resp, wait_resp, dat, start, CMD24
				i++;
			}
			while(!Chk_CMDend(24, 1) && (i < 50));				//-- Check end of CMD24

	    }
	    else				// MULTI_WRITE
	    {
	    	do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x59;	//sht_resp, wait_resp, dat, start, CMD25
				i++;
			}
			while(!Chk_CMDend(25, 1) && (i < 50));				//-- Check end of CMD25
	
	    }

	    rSDICSTA = 0xa00;							// Clear cmd_end(with rsp)	    
	   
	    i = 0;
	    while(wt_cnt < 128*blocknum)
	    {
			status = rSDIFSTA;
			if((status&0x2000) == 0x2000) 
			{
			    rSDIDAT = *(Tx_buffer + i);
			    i++;		    
			    wt_cnt++;
				//Uart_Printf("Dat=%d, wt_cnt=%d\n",*(Tx_buffer+i),wt_cnt);
			}
	    }		

	    break;
	
	case INT:
		return 0;
	/*
	    pISR_SDI = (unsigned)Wt_Int;	    

	    rSDIIMSK = 0x10;  // Tx FIFO half int.
	    rINTMSK &= ~(BIT_SDI);

	    if(blocknum<2)	    // SINGLE_WRITE
	    {
			rSDICCON=(0x1<<9)|(0x1<<8)|0x58;    //sht_resp, wait_resp, dat, start, CMD24
			if(!Chk_CMDend(24, 1))				//-- Check end of CMD24
			    goto REWTCMD;
	    }
	    else	    // MULTI_WRITE
	    {
			rSDICCON=(0x1<<9)|(0x1<<8)|0x59;    //sht_resp, wait_resp, dat, start, CMD25
			if(!Chk_CMDend(25, 1))				//-- Check end of CMD25 
			    goto REWTCMD;
	    }

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

	    while(!TR_end);
	    //while(wt_cnt<128);

	    rINTMSK |= (BIT_SDI);
	    TR_end=0;
	    rSDIIMSK=0;	// All mask
	    break;
	    */

	case DMA:
				
	    pISR_DMA0 = (unsigned)DMA_end;
	    
	    rINTMSK = ~(BIT_DMA0);
	    
		rSDIDCON = rSDIDCON|(1<<24); 			//YH 040227, Burst4 Enable

	    rDISRC0 = (int)(Tx_buffer);				// source=Tx_buffer
	    rDISRCC0 = (0<<1) + (0<<0);				// AHB, inc	    
	    rDIDST0 = (U32)(SDIDAT);				// Destination=SDIDAT
	    rDIDSTC0 = (1<<1) + (1<<0);				// APB, fix
	    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, single tx, single service, SDI, H/W request, 
		    //auto-reload off, word, 128blk*num
	    	    
		rSDIDCON = (2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<15)|(1<<14)|(3<<12)|(blocknum<<0);	//YH 040220
		    // Word Tx, Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num
		
		i = 0;    
	    if(blocknum < 2)	// SINGLE_WRITE
	    {
			do
			{
				rSDICCON = (0x1<<9)|(0x1<<8)|0x58;	//sht_resp, wait_resp, dat, start, CMD24
				i++;
			}
			while(!Chk_CMDend(24, 1) && (i < 50));				//-- Check end of CMD24

	    }
	    else				// MULTI_WRITE
	    {
	    	do
			{
				rSDICCON=(0x1<<9)|(0x1<<8)|0x59;	//sht_resp, wait_resp, dat, start, CMD25
				i++;
			}
			while(!Chk_CMDend(25, 1) && (i < 50));				//-- Check end of CMD25
	
	    }

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

		rDMASKTRIG0 = (0<<2) + (1<<1)+0;    	//no-stop, DMA0 channel on, no-sw trigger

	    while(!TR_end);		

	    rINTMSK |= (BIT_DMA0);
	    TR_end = 0;
	    rDMASKTRIG0 = (1<<2) + (0<<1);			//DMA0 stop,DMA0 channel off

	    break;

	default:
	    break;
    }
    
    //-- Check end of DATA
    for (i = 0; i < 50; i++)
    {
	    if(Chk_DATend())
		{
			break;
		}
	    
	}
	if (i == 50)
	{
		Uart_Printf("Write Dat Error!!\n");
		return 0;
	}

	rSDIDCON = rSDIDCON & ~(7<<12);			//YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
    rSDIDSTA = 0x10;						// Clear data Tx/Rx end

    if((blocknum > 1) )	
    {
		//--Stop cmd(CMD12)
		i = 0;
		do
		{    
			rSDIDCON=(1<<18)|(1<<17)|(Wide<<16)|(1<<14)|(1<<12)|(blocknum<<0); 	//YH  040220

			
			rSDICARG = 0x0;	    				//CMD12(stuff bit)
			rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;    //sht_resp, wait_resp, start, CMD12
		}
		//-- Check end of CMD12
		while(!Chk_CMDend(12, 1) && (i < 50));
		   
		rSDICSTA = 0xa00;						// Clear cmd_end(with rsp)
		
		//-- Check end of DATA(with busy state)
		if(!Chk_BUSYend()) 
		{
		    Uart_Printf("Chk_BUSYend Error!!\n");
		    return 0;
		}

		rSDIDSTA = 0x08;						//! Should be cleared by writing '1'.
    }
    return 1;
    
    //CMD13();
}

int SD_Get_CardStat(int iRCA)//CMD13
{
    int response0;
	unsigned int cc = 1;
    rSDICARG = iRCA<<16;					// CMD13(RCA,stuff bit)
    rSDICCON = (0x1<<9) | (0x1<<8) | 0x4d;	// sht_resp, wait_resp, start, CMD13

    //-- Check end of CMD13
    if(!Chk_CMDend(13, 1)) 
    {
		return -1;
	}
    //Uart_Printf("rSDIRSP0=0x%x\n", rSDIRSP0);
    
    if (rSDIRSP0 & (cc << 31))
    {
		Uart_Printf("Error: OUT_OF_RANGE!\n");
	}
	else if (rSDIRSP0 & (cc << 30))
    {
		Uart_Printf("Error: ADDRESS_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 29))
    {
		Uart_Printf("Error: BLOCK_LEN_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 28))
    {
		Uart_Printf("Error: ERASE_SEQUENCE_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 27))
    {
		Uart_Printf("Error: ERASE_INVALID_BLOCKS_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 26))
    {
		Uart_Printf("Error: WP_VIOLATION_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 25))
    {
		Uart_Printf("CARD_IS_LOCKED!\n");
	}
	else if (rSDIRSP0 & (cc << 24))
    {
		Uart_Printf("Error: LOCK_UNLOCK_FAILED!\n");
	}
	else if (rSDIRSP0 & (cc << 23))
    {
		Uart_Printf("Error: COM_CRC_ERROR!\n");
	}
	else if (rSDIRSP0 & (cc << 22))
    {
		Uart_Printf("Error: ILLEGAL_COMMAND!\n");
	}
	
    if(rSDIRSP0 & 0x100)
    {
		Uart_Printf("Ready for Data,");
	}

    response0 = rSDIRSP0;
    response0 &= 0x1e00;	//wangq
    response0 = (response0 >> 9);
    switch (response0)
    {
    	case 0:	
    		Uart_Printf("Current Status = 'Idle'\n");
    		break;
    	case 1:	
    		Uart_Printf("Current Status = 'Ready'\n");
    		break;
    	case 2:	
    		Uart_Printf("Current Status = 'Ident'\n");
    		break;
    	case 3:	
    		Uart_Printf("Current Status = 'stby:Stand-by'\n");
    		break;
    	case 4:	
    		Uart_Printf("Current Status = 'tran:Transfer'\n");
    		break;
    	case 5:	
    		Uart_Printf("Current Status = 'data:Sending data'\n");
    		break;
    	case 6:	
    		Uart_Printf("Current Status = 'rcv:Receive data'\n");
    		break;
    	case 7:	
    		Uart_Printf("Current Status = 'prg:Programming'\n");
    		break;
    	case 8:	
    		Uart_Printf("Current Status = 'dis:Disconnect'\n");
    		break;
    	default:	
    		Uart_Printf("Current Status = 'Reserved'\n");
    		break;

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

void SD_Test(void)
{
	//U32 bnum;
	U32 save_rGPEUP, save_rGPECON;
	card_desc CardInf;
    
    save_rGPEUP = rGPEUP;
	save_rGPECON = rGPECON;

    Uart_Printf("SDI Card Read and Write Test\n");
    
    if( !SD_Card_Init(&CardInf) )	// 初始化
    {
    	Uart_Printf("Initialize SD Card fail,No Card assertion!!\n");
		return;
	}
		
	if(!CMD9(CardInf.RCA))			// Get CSD
	{
		Uart_Printf("Get CSD Failed!!!\n");
	}
		
    TR_Buf_new();    				// 初始化缓冲区
/*
INOM:    
    Uart_Printf("How many blocks to test? (1~16): ");
    bnum = (U32)Uart_GetIntNum();
    if ((bnum == 0) | (bnum > 16))
    {
		goto INOM;
	}
    Uart_Printf("\n");
*/
    //CMD13();			// Get card status		
	
	Uart_Printf("---- Block Write Test ----\n");
    if( !SD_Wt_Block(&CardInf, DMA, 0, 20) )
    {
    	Uart_Printf("Write Test Failed!\n");
    }
    	
    Uart_Printf("---- Block Read Test ----\n");
    if( !SD_Rd_Block(&CardInf, POL, 0, 20) )
    {
    	Uart_Printf("Read Test Failed!\n");
    }
    
    Check_RxTx_buf(16);
    
    if(CardInf.Card_Type == ENUM_CARD_TYPE_MMC)
    {
		rSDICON |= (1<<5);	// YH 0519, MMC Type SDCLK

		//Wt_Stream(0,1);
		//Rd_Stream(0,1);
		//Check_RxTx_buf(1);
    }

    Card_Deselect();		// Card deselect
	
    rSDIDCON = 0;	//tark???
    rSDICSTA = 0xffff;
	rGPEUP = save_rGPEUP;
	rGPECON = save_rGPECON;		
	
}

⌨️ 快捷键说明

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