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

📄 sddriver.c

📁 SD卡的SPI驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
** Modified date:     2005-12-21
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	
#if SD_WriteMultiBlock_EN
int SD_WriteMultiBlock(INT32U blockaddr, INT32U blocknum, const INT8U *sendbuf)
{
	INT32U i;
	INT8U ret;
	
	if ((blockaddr + blocknum) > sds.block_num)	
		return SD_ERR_OVER_CARDRANGE;							/* operate over the card range */
		
	if (SD_ChkCardWP() == 1)
		return SD_ERR_WRITE_PROTECT;							
	
	ret = SD_WriteMultipleBlock(blockaddr);						/* write multiple blocks command */
	if (ret != SD_NO_ERR)
		return ret;

    for (i = 0; i < blocknum; i++)
    {															
 		ret = SD_WriteBlockData(1, SD_BLOCKSIZE, sendbuf);		/* write data */
 		if (ret == SD_NO_ERR)	
 			sendbuf = sendbuf + SD_BLOCKSIZE;
 		else
 		{														/* write fail */
			SD_StopTransmission();								/* stop data transmission */	
			SD_WaitBusy(SD_WAIT_WRITE);							/* waiting */
			return ret;
		}
	}
   
    SD_StopMultiToken();										/* send data stop token */
      
    ret = SD_WaitBusy(SD_WAIT_WRITE);							/* wait for finishing writing */
    if (ret != SD_NO_ERR)
    	return SD_ERR_TIMEOUT_WRITE;
    
   	ret = SD_GetNumWRBlcoks(&i);								/* read the blocks that be written correctly */
   	if (ret != SD_NO_ERR)
   	  	return ret;
   	  	
   	if(i != blocknum) 
   	 	return SD_ERR_WRITE_BLKNUMS;							/* the blocks that be written correctly is error */
   	   	     
	return SD_NO_ERR;											/* return write successfully */			
}
#endif

/*********************************************************************************************************
** Function name:    SD_EraseBlock
**
** Descriptions:     Erase the block of sd card
**
** input parameters:   INT32U startaddr: start address
**                     INT32U endaddr  : end address
**            
** Returned value:     SD_NO_ERR:  successful
**                     Others   :  fail,errors occur
**                     
**         
** Used global variables: None
** Calling modules:       
**
** Created by:        Ming Yuan Zheng
** Created Date:      2005-1-6
**-------------------------------------------------------------------------------------------------------
** Modified by:       Jing.Zhang
** Modified date:     2005-12-21
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	

#if SD_EraseBlock_EN
int SD_EraseBlock(INT32U startaddr, INT32U blocknum)
{
	INT32S tmp;
	INT8U  ret;
	
	if ((startaddr + blocknum) > sds.block_num)	
		return SD_ERR_OVER_CARDRANGE;							/* operate over the card range */
		
	if (SD_ChkCardWP() == 1)
		return SD_ERR_WRITE_PROTECT;							
		
	tmp = blocknum - sds.erase_unit;	
	while(tmp >= 0)												/* once erase is sector size */
	{	
		ret = SD_EraseStartBlock(startaddr);					/* select start address */
		if (ret != SD_NO_ERR)
			return ret;
		
		ret = SD_EraseEndBlock(startaddr + sds.erase_unit - 1);	/* select end address */
		if (ret != SD_NO_ERR)
			return ret;
			
		ret = SD_EraseSelectedBlock();							/* erase blocks selected */
		if (ret != SD_NO_ERR)
			return ret;

		startaddr += sds.erase_unit;							
		blocknum  -= sds.erase_unit;
		tmp = blocknum - sds.erase_unit;
	};		
	
	if (blocknum > 0)											
	{															/* erase blocks that numbers is not enough a sector */
		ret = SD_EraseStartBlock(startaddr);
		if (ret != SD_NO_ERR)
			return ret;
		
		ret = SD_EraseEndBlock(startaddr + blocknum - 1);
		if (ret != SD_NO_ERR)
			return ret;
			
		ret = SD_EraseSelectedBlock();
		if (ret != SD_NO_ERR)
			return ret;
	}

	return SD_NO_ERR;											/* return erase sucessfully */
}
#endif

/*********************************************************************************************************
** Function name:    SD_GetCardInfo
**
** Descriptions:     Get the information of SD card
**
** input parameters:   INT32U startaddr: start address
**                     INT32U endaddr  : end address
**            
** Returned value:     SD_NO_ERR:  successful
**                     Others   :  fail,errors occur
**                     
**         
** Used global variables: None
** Calling modules:       
**
** Created by:        Ming Yuan Zheng
** Created Date:      2005-1-6
**-------------------------------------------------------------------------------------------------------
** Modified by:       Jing.Zhang
** Modified date:     2005-12-21
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	
int SD_GetCardInfo(void)
{
	INT32U tmp;
	INT8U csdbuf[16],ret;
		
	ret = SD_ReadCSD(16,csdbuf);	 								    		/* read CSD register */
	if (ret != SD_NO_ERR)	
		return ret;	
		
	SD_CalTimeout(csdbuf);														/* calculate timeout value */
		
    /* calculate the size of a sector */
	sds.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK);  			/* (2 ^ READ_BL_LEN) */
	
	/* calculate the sector numbers of the SD Card */
	sds.block_num = ((csdbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
	      			 (csdbuf[C_SIZE_POS2] << 2) +
	 	 			((csdbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1;				/* (C_SIZE + 1)*/
		 	  															
	tmp = ((csdbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +   
	      ((csdbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2;				/* (C_SIZE_MULT + 2) */
    	
    /* get the block numbers in card */
	sds.block_num = sds.block_num * (1 << tmp);									/* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
																			
	/* calculate the size of sector */
	sds.erase_unit = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +  			
	                 ((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* SD (SECTOR_SIZE + 1) */
	    			
	return SD_NO_ERR;															/* return perform successfully */
}

/*********************************************************************************************************
** Function name:    SD_CalTimeout
**
** Descriptions:     Get the timeout information
**
** input parameters:   INT8U *csdbuf: a pointer to the content of CSD register
**            
** Returned value:     None
**                     
**         
** Used global variables: None
** Calling modules:       
**
** Created by:        Ming Yuan Zheng
** Created Date:      2005-1-6
**-------------------------------------------------------------------------------------------------------
** Modified by:       Jing.Zhang
** Modified date:     2005-12-21
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	
void SD_CalTimeout(INT8U *csdbuf)
{
	INT32U tmp;
	INT8U time_u,time_v,fator;
	
	sds.timeout_read = READ_TIMEOUT_100MS;								
	sds.timeout_write = WRITE_TIMEOUT_250MS;							
	sds.timeout_erase = WRITE_TIMEOUT_250MS;
		
	time_u = (csdbuf[TAAC_POS] & TAAC_MSK);								/* read timeout unit */
	time_v = (csdbuf[TAAC_POS] & NSAC_MSK) >> 3;						/* read timeout value */
	fator = (csdbuf[R2WFACTOR_POS] & R2WFACTOR_MSK) >> 2;				/* write timeout factor */
	
	if(time_v == 0)	return;
	if(fator >= 6) return;
	
	tmp = SPI_CLOCK * time_value[time_v] / 10 / time_unit[time_u];		/* TACC * f ( unit: clock) */
	tmp = tmp + csdbuf[NSAC_POS] * 100;									/* TACC * f + NSAC * 100 ( unit: clock) */
	
	/* the timeout value of being calculated */
	sds.timeout_read = tmp;
	sds.timeout_write = tmp * r2w_fator[fator];							/* (TACC * f + NSAC * 100) * R2WFACTOR (unit:clock)*/
	
	sds.timeout_read  = sds.timeout_read * 100 / 8;					
	sds.timeout_write = sds.timeout_write * 100 / 8;
	
	if (sds.timeout_read > READ_TIMEOUT_100MS)						
		sds.timeout_read = READ_TIMEOUT_100MS;
	
	if (sds.timeout_write > WRITE_TIMEOUT_250MS)
		sds.timeout_write = WRITE_TIMEOUT_250MS;

	sds.timeout_erase = sds.timeout_write;
}

/*********************************************************************************************************
** Function name:    SD_ActiveInit
**
** Descriptions:     Activate the SD card
**
** input parameters:   None
**            
** Returned value:     SD_NO_ERR:  successful
**                     Others   :  fail,errors occur
**         
** Used global variables: None
** Calling modules:       
**
** Created by:        Ming Yuan Zheng
** Created Date:      2005-1-6
**-------------------------------------------------------------------------------------------------------
** Modified by:       Jing.Zhang
** Modified date:     2005-12-21
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	
int SD_ActiveInit(void)
{
	INT8U param[4] = {0,0,0,0},resp[5],ret;
	INT32U i = 0;

 	do 
    {													/* send CMD1 to poll card status */
        ret = SD_SendCmd(CMD1, param, CMD1_R, resp);
        if (ret != SD_NO_ERR)
       		return ret;
  
        i++;
    }while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i < SD_IDLE_WAIT_MAX));
													
														
    if (i >= SD_IDLE_WAIT_MAX)
        return SD_ERR_TIMEOUT_WAITIDLE;					/* time out,return error */

	return SD_NO_ERR;
}

⌨️ 快捷键说明

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