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

📄 sdi.c

📁 s3c2410开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
			//--Stop cmd(CMD12)
			//SDICARG CmdArg [31:0] = 0 : Command Argument
			rSDICARG=0x0;	    //CMD12(stuff bit)

			//SDICCON CmdIndex              [7:0] = 0X4C : CMD12
			//SDICCON Command Start(CMST)   [8  ] = 1    : command start
			//SDICCON WaitRsp               [9  ] = 1    : wait_resp
			//SDICCON LongRsp               [10 ] = 0    : short response
			rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;

			//-- Check end of CMD12
			if(SD_NO_ERR==Chk_CMDend(12, 1))return SD_NO_ERR; 
			    //goto RERCMD12;
			//rSDICSTA=0xa00;	// Clear cmd_end(with rsp)
		}
		return SD_ERR;
    }
    return SD_NO_ERR;
}

/*****************************************
  写存储块函数
  函数名: Wt_Block
  描述: 通过三种方式写存储块
  返回值:void
*****************************************/

U8 Wt_Block(U32 block,U32 *src,U32 *dst)
{
   U32 m,n;
  
	//SDICON  FIFO Reset (FRST)  [1] = 1 : FIFO reset
	
    rSDICON |= rSDICON|(1<<1);	// FIFO reset
    
	//SDICARG CmdArg [31:0] = 0 : Command Argument		
    rSDICARG=(int)(dst);	    // CMD24/25(addr)

//REWTCMD:
       //use dma
	    for(n=0;n<100;n++)
	    {
		    pISR_DMA0=(unsigned)DMA_end;
			//INTMSK INT_DMA0  [17] = 0 : Service availa
			rINTMSK = ~(BIT_DMA0);
			//DISRC0  S_ADDR  [30:0] = Tx_buffer : Tx_buffer
		    rDISRC0=(int)(src);
			//DISRCC0 INC [0] = 0 :  inc
		    //DISRCC0 LOC [1] = 0 :  AHB
		    rDISRCC0=(0<<1)+(0<<0);	// AHB, inc
			rDIDST0=(U32)(SDIDAT);	// SDIDAT
		    //DIDSTC0 INC [0] = 1 : fix
		    //DIDSTC0 LOC [1] = 1 : APB
			rDIDSTC0=(1<<1)+(1<<0);	// APB, fix

		    //DCON0 TC          [19: 0] = 128*block: Initial transfer count (or transfer beat).
		    //DCON0 DSZ 		[21:20] = 10	   : Word
		    //DCON0 RELOAD      [22   ] = 1        : auto-reload of
		    //DCON0 SWHW_SEL    [23   ] = 1        : H/W request
		    //DCON0 HWSRCSEL    [26:24] = 10       : SDI
		    //DCON0 SERVMODE    [27   ] = 0        : single service
		    //DCON0 TSZ         [28   ] = 0        : single tx
		    //DCON0 INT         [29   ] = 1		   : TC int
		    //DCON0 SYNC        [30   ] = 0        : sync PCLK
		    //DCON0 DMD_HS      [31   ] = 1        : handshake
			rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;

		    //DMASKTRIG0  SW_TRIG [0] = 0 : no-sw trigger 
		    //DMASKTRIG0  ON_OFF  [1] = 1 : DMA2 channel on
		    //DMASKTRIG0  STOP    [2] = 0 : no-stop
		    rDMASKTRIG0=(0<<2)+(1<<1)+0;    
		    
			//SDIDCON  BlkNum                           [11: 0] = block : Block Number (0~4095).
			//SDIDCON  Data Transfer Mode (DatMode)     [13:12] = 3     : data transmit start
			//SDIDCON  Stop by force (STOP)             [14   ] = 1     : stop by force
			//SDIDCON  DMA Enable(EnDMA)			    [15   ] = 1     : dma enable,
			//SDIDCON  Wide bus enable (WideBus)        [16   ] = 0     : standard bus mode(only SDIDAT[0] used),
			//SDIDCON  Block mode (BlkMode)  		    [17   ] = 1     : block data transfer
			//SDIDCON  Busy AfterCommand(BACMD)         [18   ] = 0     : directly after DatMode set,
			//SDIDCON  Receive After Command (RACMD)    [19   ] = 1     : Rx after cmd
			//SDIDCON  Transmit After Response(TARSP)   [20   ] = 1     : after response receive(assume DatMode sets to 2’b11)
			//SDIDCON  SDIO InterruptPeriodType(PrdType)[21   ] = 0     : exactly 2 cycle,
			rSDIDCON=(1<<20)|(1<<17)|(Wide<<16)|(1<<15)|(3<<12)|(block<<0);
			    // Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num
		    if(block<2)	    // SINGLE_WRITE
		    {
		    //SDICCON CmdIndex              [7:0] = 0X58 : CMD24
			//SDICCON Command Start(CMST)   [8  ] = 1    : command start
			//SDICCON WaitRsp               [9  ] = 1    : wait_resp
			//SDICCON LongRsp               [10 ] = 0    : short response
			rSDICCON=(0x1<<9)|(0x1<<8)|0x58;    //sht_resp, wait_resp, dat, start, CMD24
			if(SD_NO_ERR==Chk_CMDend(24, 1))	//-- Check end of CMD24
			    break;	    
		    }
		    else	    // MULTI_WRITE
		    {
		    //SDICCON CmdIndex              [7:0] = 0X59 : CMD25
			//SDICCON Command Start(CMST)   [8  ] = 1    : command start
			//SDICCON WaitRsp               [9  ] = 1    : wait_resp
			//SDICCON LongRsp               [10 ] = 0    : short response
			rSDICCON=(0x1<<9)|(0x1<<8)|0x59;    //sht_resp, wait_resp, dat, start, CMD25
			if(SD_NO_ERR==Chk_CMDend(25, 1))	//-- Check end of CMD25 
			    break;	    
		    }
	    }
	    if(n==100)return SD_ERR;

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

	    while(!TR_end);		
	    //INTMSK  BIT_DMA0 [17] = 1 : MASK
	    rINTMSK |= (BIT_DMA0);
	    TR_end=0;
		//DMASKTRIG0  STOP [2] = 1 : DMA0 stop
		rDMASKTRIG0=(1<<2);	//DMA0 stop
    
    //-- Check end of DATA
    if(!Chk_DATend()) 
    {
	    Uart_Printf("dat error\n");
	    rSDIDSTA=0x10;	
	    return SD_ERR;
	}
	//SDIDSTA  Rx Data Progress On (RxDatOn) [0 ]  R  : Data receive in progress.
	//SDIDSTA  Tx Data progress On (TxDatOn) [1 ]  R  : Data transmit in progress.
	//SDIDSTA  Start Bit Error (SbitErr)     [2 ] =0  : not detect,
	//SDIDSTA  Busy Finish (BusyFin)         [3 ] =0  : not detect,
	//SDIDSTA  Data Transfer Finish (DatFin) [4 ] =1  : data finish detect
	//SDIDSTA  Data Time Out (DatTout)       [5 ] =0  : not detect,
	//SDIDSTA  Data Receive CRC Fail (DatCrc)[6 ] =0  : not detect,
	//SDIDSTA  CRC Status Fail(CrcSta)       [7 ] =0  : not detect,
	//SDIDSTA  FIFO Fail error (FFfail)      [8 ] =0  : not detect,
	//SDIDSTA  SDIO InterruptDetect(IOIntDet)[9 ] =0  : not detect,
	//SDIDSTA  Data Time Out (DatTout)       [10] =0  : not occur,
    rSDIDSTA=0x10;	

    if(block>1)
    {
	//--Stop cmd(CMD12)
//REWCMD12:
    for(m=0;m<100;m++)
    { 

		//SDIDCON  BlkNum                           [11: 0] = block : Block Number (0~4095).
	    //SDIDCON  Data Transfer Mode (DatMode)     [13:12] = 1     : only busy check start
	    //SDIDCON  Stop by force (STOP)             [14   ] = 0     : normal
	    //SDIDCON  DMA Enable(EnDMA)			    [15   ] = 0     : disable(polling),
	    //SDIDCON  Wide bus enable (WideBus)        [16   ] = 0     : standard bus mode(only SDIDAT[0] used),
	    //SDIDCON  Block mode (BlkMode)  		    [17   ] = 1     : blk 
	    //SDIDCON  Busy AfterCommand(BACMD)         [18   ] = 1     : after command sent (assume DatMode sets to 2’b01)
	    //SDIDCON  Receive After Command (RACMD)    [19   ] = 1     : Rx after cmd
	    //SDIDCON  Transmit After Response(TARSP)   [20   ] = 0     : directly after DatMode set,
	    //SDIDCON  SDIO InterruptPeriodType(PrdType)[21   ] = 0     : exactly 2 cycle,
		rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<12)|(block<<0);

		//--Stop cmd(CMD12)
		//SDICARG CmdArg [31:0] = 0 : Command Argument
		rSDICARG=0x0;	    //CMD12(stuff bit)

		//SDICCON CmdIndex              [7:0] = 0X4c : CMD12
		//SDICCON Command Start(CMST)   [8  ] = 1    : command start
		//SDICCON WaitRsp               [9  ] = 1    : wait_resp
		//SDICCON LongRsp               [10 ] = 0    : short response
		rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;    //sht_resp, wait_resp, start, CMD12

		//-- Check end of CMD12
		if(SD_NO_ERR==Chk_CMDend(12, 1)) 
		    break;
	}
	
	if(m==100)return SD_ERR;
	//rSDICSTA=0xa00;	// Clear cmd_end(with rsp)

	//-- Check end of DATA(with busy state)
	if(!Chk_BUSYend()) 
	{
	    Uart_Printf("error\n");
	    rSDIDSTA=0x08;
	    return SD_ERR;
	}
	    
	//SDIDSTA  Rx Data Progress On (RxDatOn) [0 ]  R  : Data receive in progress.
	//SDIDSTA  Tx Data progress On (TxDatOn) [1 ]  R  : Data transmit in progress.
	//SDIDSTA  Start Bit Error (SbitErr)     [2 ] =0  : not detect,
	//SDIDSTA  Busy Finish (BusyFin)         [3 ] =1  : busy finish detect
	//SDIDSTA  Data Transfer Finish (DatFin) [4 ] =0  : not detect,
	//SDIDSTA  Data Time Out (DatTout)       [5 ] =0  : not detect,
	//SDIDSTA  Data Receive CRC Fail (DatCrc)[6 ] =0  : not detect,
	//SDIDSTA  CRC Status Fail(CrcSta)       [7 ] =0  : not detect,
	//SDIDSTA  FIFO Fail error (FFfail)      [8 ] =0  : not detect,
	//SDIDSTA  SDIO InterruptDetect(IOIntDet)[9 ] =0  : not detect,
	//SDIDSTA  Data Time Out (DatTout)       [10] =0  : not occur,
	rSDIDSTA=0x08;
	return SD_NO_ERR;
    }
    return SD_NO_ERR;
}

U8 Chk_CMDend(int cmd, int be_resp)
//0: Timeout
{
    int finish0;

    if(!be_resp)    // No response
    {	

		//SDICSTA  RspIndex                     [7:0]  R    Response index 6bit with start 2bit (8bit)
	    //SDICSTA  CMD line progress On (CmdOn) [8  ]  R    Command transfer in progress.
	    //SDICSTA  Response Receive End (RspFin)[9  ] = 1 : response end
	    //											  = 0 : not detect,
	    //SDICSTA  Command Time Out (CmdTout)   [10 ] = 1 : timeout
	    //											  = 0 : not detect
	    //SDICSTA  Command Sent (CmdSent)       [11 ] = 1 : command end
	    //											  = 0 : not detect
   		//SDICSTA  Response CRC Fail(RspCrc     [12 ] = 1 : crc fail
   		//											  = 0 : not detect
    	finish0=rSDICSTA;
	while((finish0&0x800)!=0x800)	// Check cmdend==1,
	    finish0=rSDICSTA;

	rSDICSTA=finish0;// Clear cmd end state

	return SD_NO_ERR;
    }
    else	// With response
    {
    	finish0=rSDICSTA;
	while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))    // Check cmd/rsp end
    	    finish0=rSDICSTA;

	if(cmd==1 | cmd==9 | cmd==41)	// CRC no check
	{
	    if( (finish0&0xf00) != 0xa00 )  // Check error
	    {
		rSDICSTA=finish0;   // Clear error state

		if(((finish0&0x400)==0x400))
		    return CMD_ERR;	// Timeout error
        }
	    rSDICSTA=finish0;	// Clear cmd & rsp end state
	}
	else	// CRC check
	{
	    if( (finish0&0x1f00) != 0xa00 )	// Check error
	    {
		Uart_Printf("CMD%d:rSDICSTA=0x%x, rSDIRSP0=0x%x, 0x%x\n",cmd, rSDICSTA, rSDIRSP0,(finish0&0x1f00));
		rSDICSTA=finish0;   // Clear error state

		if(((finish0&0x400)==0x400))
		    return CMD_ERR;	// Timeout error
    	}
	    rSDICSTA=finish0;
	}
	return SD_NO_ERR;
    }
}

int Chk_DATend(void)
{
    int finish;

    finish=rSDIDSTA;
    while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))	
	// Chek timeout or data end
	finish=rSDIDSTA;

    if( (finish&0xfc) != 0x10 )
    {
        Uart_Printf("DATA:finish=0x%x\n", finish);
        rSDIDSTA=0xec;  // Clear error state
        return 0;
    }
    return 1;
}

int Chk_BUSYend(void)
{
    int finish;

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

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

U8 CMD0(void)
{
    //-- Make card idle state 
	//SDICARG CmdArg [31:0] = 0 : Command Argument
	rSDICARG=0x0;	    // CMD0(stuff bit)

	//SDICCON CmdIndex              [7:0] = 0X40 : CMD0
	//SDICCON Command Start(CMST)   [8  ] = 1    : command start
	rSDICCON=(1<<8)|0x40;   
    //-- Check end of CMD0
    return (Chk_CMDend(0, 0));
    //rSDICSTA=0x800;	    // Clear cmd_end(no rsp)
}

U8 CMD55(U16 RCA)
{
    //--Make ACMD

	//SDICARG CmdArg [31:0] = 0 : Command Argument
	rSDICARG=RCA<<16;			//CMD7(RCA,stuff bit)

	//SDICCON CmdIndex              [7:0] = 0X77 : CMD55
	//SDICCON Command Start(CMST)   [8  ] = 1    : command start
	//SDICCON WaitRsp               [9  ] = 1    : wait_resp
	//SDICCON LongRsp               [10 ] = 0    : short response
	rSDICCON=(0x1<<9)|(0x1<<8)|0x77;	//sht_resp, wait_resp, start, CMD55

    //-- Check end of CMD55
    if(SD_NO_ERR!=Chk_CMDend(55, 1)) 
	return CMD_ERR;

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



U8 Set_4bit_bus(U16 RCA)
{
    U8 ret;
    Wide=1;
    ret=SetBus(RCA);
    if(ret!=SD_NO_ERR)return ret;
    Uart_Printf("\n****4bit bus****\n");
    return ret;
}

U8 SetBus(U16 RCA)
{
    U32 n;
//SET_BUS:
    for(n=0;n<100;n++)
    {
	    if(SD_NO_ERR!=CMD55(RCA))return SD_ERR;	// Make ACMD
	    //-- CMD6 implement
		//SDICARG CmdArg [31:0] = 0 : Command Argument
	    rSDICARG=Wide<<1;	    //Wide 0: 1bit, 1: 4bit

	    //SDICCON CmdIndex              [7:0] = 0X46 : CMD55
		//SDICCON Command Start(CMST)   [8  ] = 1    : command start
		//SDICCON WaitRsp               [9  ] = 1    : wait_resp
		//SDICCON LongRsp               [10 ] = 0    : short response
		rSDICCON=(0x1<<9)|(0x1<<8)|0x46;	//sht_resp, wait_resp, start, CMD55

	    if(SD_NO_ERR==Chk_CMDend(6, 1))break;   // ACMD6
	}
	if(n==100)return SD_ERR;
	return SD_NO_ERR;
    //rSDICSTA=0xa00;	    // Clear cmd_end(with rsp)
}

void Set_Prt(void)
{
    //-- Set protection addr.0 ~ 262144(32*16*512) 
    Uart_Printf("[Set protection(addr.0 ~ 262144) test]\n");

RECMD28:
    //--Make ACMD
	//SDICARG CmdArg [31:0] = 0 : Command Argument
    rSDICARG=0;	    // CMD28(addr) 

	//SDICCON CmdIndex              [7:0] = 0X5c : CMD28
	//SDICCON Command Start(CMST)   [8  ] = 1    : command start
	//SDICCON WaitRsp               [9  ] = 1    : wait_resp
	//SDICCON LongRsp               [10 ] = 0    : short response
	rSDICCON=(0x1<<9)|(0x1<<8)|0x5c;	//sht_resp, wait_resp, start, CMD28

⌨️ 快捷键说明

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