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

📄 sdhal.c

📁 SD卡驱动程序。周立功单片机公司开发板提供的标准例程。
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	if (SD_INSERT_STATUS() != 0)
		return 0;								/* 未完全插入 */
	else
		return 1;								/* 完全插入 */
}


/*******************************************************************************************************************
** 函数名称: SdHal_CheckCardWP()				
**
** 功能描述: 检测卡写保护
**
** 输   入: sd_struct *sds:  卡信息结构体
**	         
** 输   出: 1: 卡已写保护	  0: 卡未写保护
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_CheckCardWP(sd_struct *sds)
{
	if (SD_WP_STATUS() != 0)
		return 1;								/* 写保护 */
	else
		return 0;								/* 未写保护 */
}



/*******************************************************************************************************************
** 函数名称: SdHal_BeforeReadBlock()				
**
** 功能描述: 在发送读单块命令之前, 给硬件控制器做一些事情的机会
**
** 输   入: sd_struct *sds  :  卡信息结构体 
**	         
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_BeforeReadBlock(sd_struct *sds)
{	
    MCIMask0 |= (DATA_RX_INT_MASK) | (FIFO_INT_MASK);	    /* 仅使能接收中断 */
	MCIMask1 = MCIMask0;

	MCIClear = 0x7FF;							            /* 清空清零寄存器的所有标志 */
	MCIDataCtrl = 0;							            /* 数据控制寄存器清0  */
			 
	MCIDataTimer = sds->timeout_read;                       /* 超时值 */
	MCIDataLength = SD_BLOCKSIZE;				            /* 块长度 */
    MCIFifoCnt = 0;    
    
    lpc_mci.RecCnt = 0;
    lpc_mci.RxTxFlag = MCI_RESET_FLAG;
    lpc_mci.psds = sds;    
    lpc_mci.CurTran = MCI_CUR_REC; 
         
	return SD_NO_ERR;
}


/*******************************************************************************************************************
** 函数名称: SdHal_ReadBlock()				
**
** 功能描述: 在发送读单块命令之后, 由硬件控制器实现读取数据
**
** 输   入: sd_struct *sds  :  卡信息结构体 
**	         
** 输   出: INT8U *recbuf: 接收缓冲区, 大小为512字节
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_ReadBlock(sd_struct *sds, INT8U *recbuf)
{
	INT32U DataCtrl = 0;
	INT8U ret;
			
	lpc_mci.pRecBuf = recbuf;	

#if MCI_DMA_ENABLED
    // DMA 控制器初始化
	DMA_Init(1, P2M);                                                           
	DMACC1Configuration |= 0x10001 | (0x04 << 1) | (0x00 << 6) | (0x06 << 11);
	
	// 设置数据控制寄存器: 读,块传输,DMA传输,块长度
	DataCtrl |= ((1 << 0) | (1 << 1) | (1 << 3) | (SD_BLOCKSIZE_NBITS << 4));	    
#else
    // 设置数据控制寄存器: 读,块传输,块长度
	DataCtrl |= ((1 << 0) | (1 << 1) | (SD_BLOCKSIZE_NBITS << 4));
#endif
	
#if SD_UCOSII_EN
    OS_ENTER_CRITICAL();
    MCIDataCtrl = DataCtrl;						                /* 启动数据传输 */
    OSSemPend(sds->pSemSdmmcRW, sds->timeout_read_os, &ret);    /* 进入等待状态 */
    if (ret == OS_NO_ERR)   
        ret = lpc_mci.RxTxFlag;                                 /* 返回数据接收结果 */                            
    else if (ret == OS_TIMEOUT)
        ret = SD_ERR_TIMEOUT_READ;                              /* 接收数据超时 */            
    else
        ret = SD_ERR_WAIT_WRSEM;                                /* 等待信号量失败 */
    
    OS_EXIT_CRITICAL();
#else	
    MCIDataCtrl = DataCtrl;                                     /* 启动数据传输 */
	do
	{                                                           /* 等待数据接收 */
	    if (lpc_mci.RxTxFlag == SD_NO_ERR)
	        break;                                              /* 数据接收成功 */
	}while (lpc_mci.RxTxFlag == MCI_RESET_FLAG);
	
	ret = lpc_mci.RxTxFlag;                                     /* 返回接收结果 */
#endif	

	MCIMask0 &= ~((DATA_RX_INT_MASK) | (FIFO_INT_MASK));        /* 仅禁止接收中断 */
	MCIMask1 = MCIMask0;  	

#if MCI_DMA_ENABLED
    src_addr = (INT32U *)DMA_SRC;                               /* 取得 DMA 源地址 */         
	dest_addr = (INT32U *)DMA_DST;                              /* 取得 DMA 目标地址 */    
    if (ret == SD_NO_ERR)
        memcpy(recbuf, dest_addr, 512);                         /* 返回接收到的数据 */
#endif

    return ret;
}



/*******************************************************************************************************************
** 函数名称: SdHal_BeforeWriteBlock()				
**
** 功能描述: 在发送写单块命令之前, 给硬件控制器做一些事情的机会
**
** 输   入: 无 
**	         
** 输   出: INT8U *recbuf: 接收缓冲区, 大小为512字节
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_BeforeWriteBlock(sd_struct *sds)
{
	MCIMask0 = DATA_TX_INT_MASK | (FIFO_INT_MASK);	      /* 仅使能TX中断 */
	MCIMask1 = MCIMask0; 

	MCIClear = 0x7FF;							          /* 清空清零寄存器的所有标志 */
	MCIDataCtrl = 0;							          /* 数据控制寄存器清0  */
		 
	MCIDataTimer = sds->timeout_write;                    /* 超时值 		 */
	MCIDataLength = SD_BLOCKSIZE;				          /* 块长度 		 */
    MCIFifoCnt = 0;  
    
    lpc_mci.psds = sds;                                   /* 初始化lpc_mci结构体变量 */  
    lpc_mci.RxTxFlag = MCI_RESET_FLAG; 
    lpc_mci.SendCnt = 0;
    lpc_mci.CurTran = MCI_CUR_SEND;   
	return SD_NO_ERR;
}


/*******************************************************************************************************************
** 函数名称: SdHal_WriteBlock()				
**
** 功能描述: 在发送写单块命令之后, 由硬件控制器向卡发送数据
**
** 输   入: 无 
**	         
** 输   出: INT8U *recbuf: 接收缓冲区, 大小为512字节
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_WriteBlock(sd_struct *sds, INT8U *sendbuf)
{
	INT32U DataCtrl = 0;
	INT8U ret;
	
#if MCI_DMA_ENABLED
    src_addr = (INT32U *)DMA_SRC;                           
	dest_addr = (INT32U *)DMA_DST;
	//memcpy(sendbuf, src_addr, 512);
	memcpy(src_addr, sendbuf, 512);                              /* 复制要写入的数据到DMA源地址 */

	DMA_Init(0, M2P);                                            /* DMA控制器初始化 */
	DMACC0Configuration |= 0x00001 | (0x00 << 1) | (0x04 << 6) | (0x05 << 11);
	
	/* 设置数据控制寄存器: 写, 块传输, DMA, 数据长度 */
	DataCtrl |= ((1 << 0) | (1 << 3) | (SD_BLOCKSIZE_NBITS << 4));               
#else
 	lpc_mci.pSendBuf = sendbuf;
 	
 	/* 设置数据控制寄存器: 读, 块传输, 数据长度 */
 	DataCtrl |= ((1 << 0) | (SD_BLOCKSIZE_NBITS << 4));
#endif 	


#if SD_UCOSII_EN
    OS_ENTER_CRITICAL();
    MCIDataCtrl = DataCtrl;                                      /* 启动数据传输 */
    OSSemPend(sds->pSemSdmmcRW, sds->timeout_write_os, &ret);    /* 进入等待状态 */
    if (ret == OS_NO_ERR)
	    ret = lpc_mci.RxTxFlag;                                  /* 返回写块数据结果 */
    else if (ret == OS_TIMEOUT)
        ret = SD_ERR_TIMEOUT_WRITE;                              /* 返回等待超时 */
    else
        ret = SD_ERR_WAIT_WRSEM;                                 /* OSSemPend()执行失败 */
    
    OS_EXIT_CRITICAL();
#else
    MCIDataCtrl = DataCtrl;                                      /* 启动数据传输 */
	do
	{
	    if (lpc_mci.RxTxFlag == SD_NO_ERR)
	        break;                                               /* 发送数据成功 */   
	}while (lpc_mci.RxTxFlag == MCI_RESET_FLAG);
	
	ret = lpc_mci.RxTxFlag;                                      /* 返回发送数据执行结果 */
#endif

	MCIMask0 &= ~(DATA_TX_INT_MASK | FIFO_INT_MASK);	         /* 仅禁止TX中断 */
	MCIMask1 = MCIMask0;  	
  
	return ret;
}


/*******************************************************************************************************************
** 函数名称: SDMMC_WaitReadyforData()				
**
** 功能描述: 等待卡可接收数据, 即等待卡状态寄存器的 bit8 为1, 大约为2次循环	
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体 
**	         
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_WaitReadyforData(sd_struct *sds)
{
    INT8U ret;
    INT32U status;
    
	do	
	{	
		ret = SdCmd_Send_Status(sds, &status);					/* 读取卡的状态 */
		if (ret != SD_NO_ERR)
	        return ret;
	        
	    if (!SdHal_CheckCard(sds))							    /* 检测卡是否拔出 */
 		    return SD_ERR_NO_CARD; 
	        
	}while((status & CARD_STATUS_RDY_DATA) == 0); 
	
	return SD_NO_ERR;
}


/*******************************************************************************************************************
** 函数名称: SdHal_WaitBusy()				
**
** 功能描述: 等待卡编程结束, 即等待卡状态由编程状态变为传输状态: prg --> tran
**
** 输   入: sd_struct *sds  : SD/MMC卡信息结构体 
**	         
** 输   出: 无
**
** 返 回 值: 0:   正确    >0:   错误码, 见 sddriver.h 文件
********************************************************************************************************************/
INT8U SdHal_WaitBusy(sd_struct *sds)
{
    INT8U ret;
    INT32U status;
    
    do	
	{	
		ret = SdCmd_Send_Status(sds, &status);           /* 读取卡的状态 */
		if (ret != SD_NO_ERR)
			return ret;
			
	    if (!SdHal_CheckCard(sds))                       /* 检测卡是否拔出 */
 		    return SD_ERR_NO_CARD; 	
			
	}while((status & 0x1F00) != 0x900);
	
	return SD_NO_ERR;
}


/*******************************************************************************************************************
** 函数名称: MCI_Delay()				
**
** 功能描述: 延时函数	
**
** 输   入: INT16U val:  延时值, 1大约相当于5ms
**							  	
** 输   出: 无
**
** 返 回 值: 无 
********************************************************************************************************************/
void MCI_Delay(INT16U val)
{
#if !SD_UCOSII_EN
    INT16U i,j;
    for (i = 0; i < val; i++)
        for (j = 0; j < 0xC000; j++);
#else
    OSTimeDly(val); 
#endif   
}


/*******************************************************************************************************************
** 函数名称: MCI_SendCmd()				
**
** 功能描述: 发送命令给卡, 但不获取响应
**
** 输   入: INT32U CmdIndex    : 命令索引
**           INT32U Argument    : 命令参数
**           INT32U ExpectResp  : 期望得到的回复 
**           INT32U AllowTimeout: 是否允许超时
**	         
** 输   出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
void MCI_SendCmd(INT32U CmdIndex, INT32U Argument, INT32U ExpectResp, INT32U AllowTimeout)
{
    INT32U CmdData = 0, i;
	INT32U CmdStatus;
		
	while ((CmdStatus = MCIStatus) & MCI_CMD_ACTIVE)    /* 命令正在处理中 */
	{
		MCICommand = 0;                                 
		MCIClear = CmdStatus | MCI_CMD_ACTIVE;          /* 清除相关状态 */
		for(i = 0; i < 0x20; i++);
	}	
		

⌨️ 快捷键说明

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