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

📄 sddriver.c

📁 基于S3C2440处理器的sd卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    }		SDIBSIZE = SD_BLOCKSIZE;           				/* 块数据的长度 		block data length */	//SDICON |= SDICON_FRESET;            			/* 复位 FIFO			reset FIFO */			SDIFSTA= SDIFSTA|(1<<16);		SDIDCON=(00<<22)|(1<<20)|(1<<17)|(1<<16)|(1<<14)|(3<<12)|(1<<0);	//YH 040220	ret = SD_WriteSingleBlock(blockaddr);			/* 写单块命令 write single block */	if (ret != SD_NO_ERR)			return ret;	SDICSTA=0xa00;	// Clear cmd_end(with rsp)	  		ret = SD_WriteBlockData(0, SD_BLOCKSIZE, sendbuf, sds->timeout_write);	/*   */ 	if (ret == SD_NO_ERR)							/* 读Card Status寄存器, 检查写入是否成功 */ 	{												/* read Card Status register to check write wheather sucessfully */ 		ret = SD_ReadCard_Status(sds->RCA, 4, tmp); 		if (ret != SD_NO_ERR)		 			return ret;								/* 读寄存器失败 read register fail */ 		 		ret = SD_JudgeResult(tmp);					/* 响应指示写失败 response indicate write fail */ 		if (ret != SD_NO_ERR) 			return ret;			     						 	}	else	{		ret = SD_ReadCard_Status(sds->RCA, 4, tmp);			if (ret != SD_NO_ERR)			return ret;	} 	ret = SD_DeSelectCard();						/* CMD7, 退出传输状态 */  	return ret;										/* 返回写入结果 return the result of writing */										}INT8U SD_WriteBlock_1(sd_struct *sds, int blockaddr, int blocknum, const INT8U *buf){	//int rd_cnt = 0;	INT8U ret,status[4];	INT32U stat = 0,i=0;	// Uart_Printf("[MultiBlock write test]\n\r");	ret = SD_ReadCard_Status(sds->RCA, 4, status);	/* 读取卡的状态  	  	read the status of the card */	if (ret != SD_NO_ERR)		return ret;				ret = SD_SelectCard(sds->RCA);					/* CMD7,进入传输状态  	CMD7, enter tranfer status */    if (ret != SD_NO_ERR)    	return ret;    	  	if (sds->card_type == CARDTYPE_SD)	    {												/* 卡为SD卡           	card is SD card */   		ret = SD_SetBusWidth(sds->RCA, 1);    		/* 设置卡为数据总线方式 set card to wide data bus  */    	if (ret != SD_NO_ERR)    		return ret;     }		SDIBSIZE = SD_BLOCKSIZE;  	/* 复位 FIFO			reset FIFO */	SDIFSTA= SDIFSTA|(1<<16);	SDIDCON=(00<<22)|(1<<20)|(1<<17)|(1<<16)|(1<<14)|(3<<12)|(blocknum<<0);	//YH 040220	ret = SD_WriteMultipleBlock(blockaddr);			/* 读多块命令 			read single blocks command */							if (ret != SD_NO_ERR) 		return ret;		SDICSTA=0xa00;	// Clear cmd_end(with rsp)	  	//Uart_Printf("\r\n");	//Uart_Printf("%d Block\r\n", blockaddr++);    while(i<512*blocknum)	// 512*block bytes    {		if((SDIDSTA&0x20)==0x20) // Check timeout 		{		    SDIDSTA=(0x1<<0x5);  // Clear timeout flag		    break;		}		stat=SDIFSTA; 		if (stat & SDIFSTA_TX)  		{ 							           		/* 如果TX FIFO有效   if TX FIFO is valid  */    			int cnt = SDI_MAX_TX_FIFO - (stat & SDIFSTA_CNT);			                                		/* 64 - FIFO中的字节数 */			if (cnt) 			{				//SDIDAT = (sendbuf[i + 3] << 24) + (sendbuf[i + 2] << 16) +  (sendbuf[i + 1] << 8) + sendbuf[i];  				SDIDAT8 = buf[i];				i++;			}		}    }	//delay for writing ok	for(i=0; i<10000; i++);		SD_StopTransmission();  	ret = SD_DeSelectCard();						/* CMD7, 退出传输状态 */	return ret;	}/********************************************************************************************************************* 函数名称: INT8U SD_GetCardInfo()				Name:	  INT8U SD_GetCardInfo()** 功能描述: 获得SD卡的信息						Function: get the information of SD card** 输   入: sd_struct *sds: SD卡信息结构体 	Input:    sd_struct *sds: the information structure of SD Card** 输   出: 0:   成功   > 0:   错误码			Output:	  0:  sucessfully	> 0:  error code*******************************************************************************************************************/INT8U SD_GetCardInfo(sd_struct *sds){	INT32U tmp;	//,INT8U fator;time_v;time_u,	INT8U recbuf[16],ret;		ret = SD_ReadCSD(sds->RCA, 16, recbuf);	 				    	    /* 读CSD寄存器    read CSD register */	if (ret != SD_NO_ERR)			return ret;	sds->file_format 	= (recbuf[1] & 0xc) >> 2;	sds->tmp_write_pro 	= 	recbuf[1] & 0x10 >> 4;	sds->perm_write_pro = 	recbuf[1] & 0x20 >> 5;	sds->copy			=	recbuf[1] & 0x40 >> 6;	sds->file_format_grp	=	recbuf[1] & 0x80>>7;		sds->write_bl_partial   = 	(recbuf[2] & 0x20) >> 5;	sds->write_bl_len		=	((recbuf[2] & 0xc0)>> 6 ) + ( (recbuf[3] & 0x03) << 6);	sds->r2w_factor			=	(recbuf[3] & 0x1c) >> 2;	sds->wp_grp_enable		=	recbuf[3] & 0x80 >> 7;	sds->wp_grp_size		=	recbuf[4] & 0x7f;	sds->erase_sector_size		=	(recbuf[4] & 0x80)>>7 + ((recbuf[5] & 0x3f ) << 1);	sds->erase_blk_en			=	(recbuf[5] & 0x40 ) >> 6;	sds->C_Size_mult			=	((recbuf[5] & 0x80 ) >> 7 )+ (( recbuf[6] & 0x3) << 1);	sds->vdd_w_curr_max			=	(recbuf[6] & 0x1c )	>> 2;	sds->vdd_w_curr_min			=	(recbuf[6] & 0xe0) >> 5;	sds->vdd_r_curr_max			=	recbuf[7] & 0x3;	sds->vdd_r_curr_min			=	(recbuf[7]& 0x38) >> 3;	sds->C_size					=	((recbuf[7] & 0xc0) >> 6) + (recbuf[8] << 2) + ((recbuf[9] & 0x3) << 10);	sds->dsr_imp				= 	(recbuf[9] & 0x10 ) >> 4;	sds->read_blk_mis			=	(recbuf[9] & 0x20 ) >> 5;	sds->write_blk_mis			=   (recbuf[9] & 0x40 ) >> 6;	sds->read_bl_partial		=	(recbuf[9] & 0x80) >> 7;	sds->read_bl_len			=	recbuf[10] & 0xf;	sds->CCC					=	((recbuf[10] & 0xf0) >> 4) + (recbuf[11] << 4) ;	sds->TRAN_SPEED				= 	recbuf[12];	sds->NSAC					=	recbuf[13];	sds->TAAC					=	recbuf[14];	sds->CSD_stuc				=	(recbuf[15] & 0xc0) >> 6;	/* 计算块的最大长度 calculate the size of a sector */	sds->block_len = 1 << (recbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK);  /* (2 ^ READ_BL_LEN) */		/* 计算卡中块的个数 calculate the sector numbers of the SD Card */	sds->block_num = ((recbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +	      			  (recbuf[C_SIZE_POS2] << 2) +	 	 			 ((recbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1;	/* 计算(C_SIZE + 1)*/		 	  																tmp = ((recbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +   	      ((recbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2;		/* 计算(C_SIZE_MULT + 2) */     																sds->block_num = sds->block_num * (1 << tmp);						/* 获得卡中块的数量: (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */																		/* get the block numbers in card: (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */	/* 计算扇区大小 calculate the size of sector */	tmp = ((recbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +  				      ((recbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1;		/* 计算(SECTOR_SIZE + 1)*/		 			sds->sector_size = tmp;												/* 保存在sds中 save into sds */		    				return SD_NO_ERR;													/* 返回执行成功 return perform sucessfully */}/*********************************************************************************************************** Function name: Card_Indentify** Descriptions:  identify card type: SD or MMC card**                判别卡的型号:SD或MMC卡			** Input: 		  sd_struct *sds  : SD/MMC卡信息结构体 	     sd_struct *sds  : the information structure of SD/MMC ** Output: 		  CARDTYPE_SD -- SD card     CARDTYPE_MMC -- MMC card   ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U Card_Indentify(void){	INT32U param = 0;	INT8U response[6],ret;	ret = SD_SendCommand(CMD55, param, CMD55_R, response);    if (ret == SD_NO_ERR)		return CARDTYPE_SD;	else		return CARDTYPE_MMC;}	/*********************************************************************************************************** Function name: SD_ActiveCard** Descriptions:  active card**                激活卡			** Input: 		  NULL** Output: 		  0:   成功    > 0:  错误码					0:  sucessfully	 > 0:  error code ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_ActiveCard(sd_struct *sds){	INT8U ret,resp[4];	INT32U count = 0; 	do     {	    	if (sds->card_type == CARDTYPE_SD)			/* 读OCR寄存器      read OCR register */        	ret = SD_ReadOCR(4, resp);        else        	ret = MMC_ReadOCR(4, resp);                if (ret != SD_NO_ERR)       		return ret;        if (count >= SD_IDLE_WAIT_MAX)            return SD_ERR_TIMEOUT_WAITIDLE;			/* 超时,返回错误码  timeout,return error code */     	      	count ++;            }while ((resp[3] & MSK_READY) == 0x00);	    if ((resp[2] & MSK_OCR_33) != MSK_OCR_33)        return SD_ERR_VOL_NOTSUSP;					/* 卡不支3.3V电压   card don't support 3.3V voltage */				sds->vtg_win = (resp[3] << 24) + (resp[2] << 16) + (resp[1] << 8) + resp[0];	return SD_NO_ERR;}/*********************************************************************************************************** Function name: sdmmc_interrupt** Descriptions:  SD/MMC card interrupt handler **                SD/MMC 卡中断处理程序			** Input: 		  input parameter of linux interrupt handler** Output: 		  NULL ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/#if SD_INTERRUPT_ENvoid sdmmc_interrupt(int irq, void *dev_id, struct pt_regs *regs){	INT32U stat;	INT32U cnt;	INT32U tmp;	if (reading == 1)	{		stat = SDIFSTA;                            		  	  /* 读FIFO状态寄存器 */				/* FIFO 中的数据不足64个字节 */		if (stat & SDIFSTA_RX_LAST)		{ 									                  /* 最后数据就绪 */                    			cnt = (stat & SDIFSTA_CNT) / sizeof(INT32U);      /* 取得FIFO中的“字”数 */			while (cnt) 			{				tmp = SDIDAT;								  /* 从FIFO中读出数据 */				buffer[bufcnt] = (INT8U)(tmp); 				buffer[bufcnt + 1] = (INT8U)(tmp >> 8); 				buffer[bufcnt + 2] = (INT8U)(tmp >> 16); 				buffer[bufcnt + 3] = (INT8U)(tmp >> 24); 				bufcnt += sizeof(INT32U);				cnt--;			}					/* Rx FIFO为满,那么读64个字节 */			}		else if (stat & SDIFSTA_RX_FULL)		{			cnt = SDI_MAX_RX_FIFO / sizeof(INT32U);			while (cnt && bufcnt < datalen) 			{				tmp = SDIDAT;								  /* 从FIFO中读出数据 */				buffer[bufcnt] = (INT8U)(tmp); 				buffer[bufcnt + 1] = (INT8U)(tmp >> 8); 				buffer[bufcnt + 2] = (INT8U)(tmp >> 16); 				buffer[bufcnt + 3] = (INT8U)(tmp >> 24); 				bufcnt += sizeof(INT32U);				cnt--;			}		}				stat = SDIDSTA;		if (stat & SDIDSTA_DFIN)		{             									 	   /* 数据传输完成 */			SDIDSTA = stat;			error = SD_NO_ERR;			wake_up_interruptible(&wq);		} 		else if (stat & SDIDSTA_TOUT) 		{       											   /* 数据/忙接收超时 */    			SDIDSTA = stat;			error = SD_ERR_TIMEOUT_READ;			wake_up_interruptible(&wq);		}			}		/* 下面为写状态 */	else	{		stat = SDIFSTA;		if (stat & SDIFSTA_TX_EMP)		{               							    		/* TX FIFO 为空  */			cnt = SDI_MAX_TX_FIFO / sizeof(INT32U);			while (cnt && bufcnt < datalen) 			{ 	 												/* 往FIFO里写入数据 */				SDIDAT = (buffer[bufcnt + 3] << 24) + (buffer[bufcnt + 2] << 16) +  						 (buffer[bufcnt + 1] << 8) + buffer[bufcnt];  				bufcnt += sizeof(INT32U);				cnt--;			}		}		stat = SDIDSTA;		if (stat & SDIDSTA_DFIN) 		{											     		/* 数据传输完成,使能等待任务 */			SDIDSTA = stat;			error = SD_NO_ERR;			wake_up_interruptible(&wq);		} 		else if (stat & SDIDSTA_TOUT) 		{ 											     		/* 数据传输超时 */			SDIDSTA = stat;			error = SD_ERR_TIMEOUT_WRITE;			wake_up_interruptible(&wq);		}		}		/* clear the interrupt of mcu */ 	SRCPND = 1 << 21;											/* 清除相关中断标志 */			INTPND = 1 << 21; 	}#endif/*********************************************************************************************************** Function name: card_detect_interrupt** Descriptions:  the interrupt handler of card insert detect**                卡插入检测中断处理函数			** Input: 		  input parameter of linux interrupt handler** Output: 		  NULL ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/#if 0void card_detect_interrupt(int irq, void *dev_id, struct pt_regs *regs){	int bempty;#ifdef SD_CD_LEVEL_LOW                          	/* 如果是低电平表示插入 */	//bempty = read_gpio_bit(SD_GPIO_CD);#else	//bempty = !read_gpio_bit(SD_GPIO_CD);#endif	if ((!card_insert) && (!bempty)) 	{		/* card inserted 卡插入 */		card_insert = 1;		card_change = 1;		//printk("SD/MMC card insert!\n");	} 	else if (card_insert && bempty)	{	/* card ejected 卡拔出 */		card_insert = 0;		card_change = 1;#if SD_INTERRUPT_EN		error = SD_ERR_NO_CARD;						/* no card error code */		wake_up_interruptible(&wq);#endif		//printk("SD/MMC card ejected!\n");	}	}#endif/***********************************************************************************************************                            End Of File**********************************************************************************************************/

⌨️ 快捷键说明

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