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

📄 sd_write.c

📁 s3c2410开发板
💻 C
字号:
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2410addr.h"
#include "2410lib.h"
#include "sdi.h"
#include "fs_int.h"

U8   SD_WriteBlock(U32 blocknum,U8 *recbuf)
{
     
	 U8 ret,status[4];
	 U32 i;
	 U32 src[128],dst;
	 TR_end=0;
	 for(i=0;i<128;i++)
	 {
	 	src[i]=(recbuf[4*i+0]<<24)+(recbuf[4*i+1]<<16)+(recbuf[4*i+2]<<8)+(recbuf[4*i+3]);
	 }
	 dst=blocknum*SD_BLOCKSIZE;
	 ret=SD_ReadCard_Status((FS__pDevInfo[0].harddisk_info->RCA),4,status);
	  if(ret!=SD_NO_ERR) return ret;
	 ret=SD_SelectCard((FS__pDevInfo[0].harddisk_info->RCA));
	 if(ret!=SD_NO_ERR)
	 {
	    // Uart_Printf("Select err\n");
	     return ret;
	 }
	 //Uart_Printf("Select sucess\n");
     if((FS__pDevInfo[0].harddisk_info->card_type)==SD_CARD)
     {
     	 ret=Set_4bit_bus((FS__pDevInfo[0].harddisk_info->RCA));
     	 if(ret!=SD_NO_ERR)return ret;
     }
     //Uart_Printf("block_LEN=0x%x\n",rSDIBSIZE);
     ret=Wt_Block(1,src,dst);
     if(ret!=SD_NO_ERR)return ret;
     ret=SD_DeSelectCard();
     return ret;
}

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

U8 Wt_Block(U32 block,U32 *src,U32 dst)
{
   U32 m,n;
   U8 resp[6];
  
	//SDICON  FIFO Reset (FRST)  [1] = 1 : FIFO reset
	
    rSDICON |= rSDICON|SDICON_FRESET;	// FIFO reset
	    for(n=0;n<15;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=(U32)(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 : DMA0 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=SDIDCON_TARSP_1|SDIDCON_BLK|SDIDCON_WIDE|SDIDCON_DMA |SDIDCON_TX|(block<<0);
			    // Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num
		    if(block<2)	    // SINGLE_WRITE
		    {
				if(SD_NO_ERR == SD_SendCommand(CMD24,dst,CMD24_R,resp))	
				    break;	    
		    }
		    else	    // MULTI_WRITE
		    {
		         if(SD_NO_ERR == SD_SendCommand(CMD25,dst,CMD25_R,resp))
		            break;	
		    }
	    }
	    if(n==15)
	    {
	        //Uart_Printf("cmd24 err\n");
	        return SD_ERR;
	    }
       // Uart_Printf("cmd24 success\n");
	    //rSDICSTA=0xa00;	// Clear cmd_end(with rsp)
     
	    while(!TR_end);
	    //INTMSK  BIT_DMA0 [17] = 1 : MASK
	    rINTMSK |= (BIT_DMA0);
	    rSDIDCON&=(~(SDIDCON_DMA));
	    
	    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");
	    return SD_ERR;
	}
    if(block>1)
    {
	    for(m=0;m<15;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);

			if(SD_NO_ERR==SD_SendCommand(CMD12,0x0,CMD12_R,resp)) 
			    break;
		}
	
	if(m==15)return SD_ERR;
	if(!Chk_BUSYend()) 
	{
	    Uart_Printf("error\n");
	    return SD_ERR;
	}
	return SD_NO_ERR;
    }
    return SD_NO_ERR;
}

⌨️ 快捷键说明

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