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

📄 sd_data.c

📁 linux 2.6下的sd卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
{	ch_r = ver_request_dma(0, "dma_sd", 0, 0);	ch_w = ver_request_dma(0, "dma_sd", 0, 0);	if(ch_r < 0 || ch_w < 0){		printk("<1> alloc sd dma error\n");		return -1;	}else{		printk("<1> sd dma chan: r(%d), w(%d)\n", ch_r, ch_w);	}	memset(&pa, 0, sizeof (pa));	pa.SWidth = DMAC_TSIZE_WORD;    pa.DWidth = DMAC_TSIZE_WORD;	//init read dma params	pa.FlowCntrl = FLOW_PER_MEM_DMAC;			pa.SBsize = BURST_SIZE_8;	pa.DBsize = BURST_SIZE_1;	    pa.SIncr = 0;    pa.DIncr = 1;	if (ver_set_dma(ch_r, &pa) != 0) {		printk("<1>sd read:set dma fail:\n");		return -1;	}	//init write dma params	pa.FlowCntrl = FLOW_MEM_PER_DMAC;	pa.SBsize = BURST_SIZE_1;	pa.DBsize = BURST_SIZE_8;    pa.SIncr = 1;    pa.DIncr = 0;	if (ver_set_dma(ch_w, &pa) != 0) {		printk("<1>sd write:set dma fail:\n");		return -1;	}	return 0;}static int sd_free_dma(void){	if ((ver_free_dma(ch_r) != 0) && (ver_free_dma(ch_w) != 0)) {		printk("<1>free sd dma error\n");		return -1;	}	return 0;}static int sd_start_dma(int read, void *buffer, u32 size, void *p_comp){	pa.sg_len = 0;	pa.tsize = size;	if(read){		pa.sbuf = (void *) (PHYS_SD0_BASE+0x80);		pa.dbuf = buffer;	}else{		pa.sbuf = buffer;		pa.dbuf = (void *) (PHYS_SD0_BASE+0x80);	}	pa.trans_done = sd_dma_done;	pa.done_data = p_comp;	if (read) {		if (ver_start_dma(ch_r, &pa) != 0) {			printk("<1>sd:start dma fail:%d\n", size);			return -1;		}	} else {		if (ver_start_dma(ch_w, &pa) != 0) {			printk("<1>sd:start dma fail:%d\n", size);			return -1;		}	}	return 0;}#endifstatic void SDI_Print_Sector(unsigned long SectorNum, unsigned long SectorCnt, unsigned char* buffer){	int i, j;		for (i=0; i<SectorCnt; i++) {		printk("%lX:\n", (SectorNum + i) * BYTES_PER_SECTOR);		for (j=0; j<8; j++) {			printk("%x ", buffer[i * BYTES_PER_SECTOR + j]);						}		printk("\n");	}}#define SD_READ_DMA_TIMEOUT 100#define SD_WRITE_DMA_TIMEOUT 250//------------------------------------------------------------------------------//// Read data from SD FIFO register by DMA//// Arguments://		controller - instance created in SDI_InitInterface//		SectorNum - the number of first sector to be read//		SectorCnt - how many sectors to be write//		buffer - buffer to receive data//		errorcode - record error. //// Functions://		Send command to card, then call functions SDI_InitDMA//		and SDI_StartDMA finished the transfer. ////------------------------------------------------------------------------------//2007-07-31: modified some sd read steps to stronger read actionBOOL SDI_BatchRead_DMA(	SD_controller* controller, 	unsigned long SectorNum, 	unsigned long SectorCnt,	unsigned char* buffer, 	unsigned long* errorcode		){	unsigned long error = 0;	unsigned long timeout;	unsigned long DataCtrl = 0;		SD_REG *regs;#if (SD_DATA_DEBUG_LEVEL == 1)	printk("SDI_BatchRead_DMA: sector at %ld, offset = %lX, len = %ld\n", 			SectorNum, SectorNum * BYTES_PER_SECTOR, SectorCnt);#endif		DECLARE_COMPLETION(comp);		regs = controller->Registers;		if (!controller || !buffer) {		error = 1;		goto read_error_handle;	}	if (SectorNum >= controller->CardCSD.CardSize / BYTES_PER_SECTOR) {		error = 2;		goto read_error_handle;	}	if(sd_start_dma(1, buffer, SectorCnt * BYTES_PER_SECTOR, &comp) < 0){		printk("<1>sd start dma error\n");		error = 3;		goto read_error_handle;	}			if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &error))	{				error = 0;		if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &error)) {			printk("<1>r: cmd--SET_BLOCKLEN, error--%ld\n", error);			error = 4;			goto read_error_handle;		}	}		DataCtrl = 0;	apBIT_SET(DataCtrl, MCI_DATA_ENABLE,1);	apBIT_SET(DataCtrl, MCI_DATA_DIRECTION, apMCI_DATA_RECEIVE);	apBIT_SET(DataCtrl, MCI_DATA_MODE, apMCI_DATA_BLOCKING);	apBIT_SET(DataCtrl, MCI_DATA_DMA_ENABLE, 1);	apBIT_SET(DataCtrl, MCI_DATA_BLOCKSIZE, BYTES_PER_SECTOR_SH);	regs->sd_MASK0	= 0;	regs->sd_CLEAR	= MCI_STATUS_STATIC_MASK;	regs->sd_DATATMR  = 0xFFFFFFFF;	regs->sd_DATALEN  = 0xFFFF;	regs->sd_DATACTRL = DataCtrl;	if (!SDI_SendCmd(controller, &CommandParameters[READ_MULTIPLE_BLOCK], SectorNum * BYTES_PER_SECTOR, 0, &error))	{		printk("<1>cmd--READ_MULTIPLE_BLOCK, error--%ld\n", error);		error = 5;		goto read_error_handle;	}	{#if 0				if (regs->sd_STATUS & regs->sd_MASK0 & 			(MCI_STATUS_DATACRCFAIL|MCI_STATUS_DATATIMEOUT|MCI_STATUS_TXUNDERRUN|MCI_STATUS_RXOVERRUN)) {			printk("<1>read: status reg error\n");			error = 6;			goto stop_r_trans_handle;		}#endif				//wait_for_completion(&comp);		timeout = wait_for_completion_timeout(&comp, SD_READ_DMA_TIMEOUT);		if(!timeout){			printk("<1>sd read dma timeout,%ld, reset, status:%x\n", SectorNum, regs->sd_STATUS);			error = 6;					}		#if 0			int i= 0;				while (regs->sd_STATUS & MCI_STATUS_RXDATAAVLBL) {			{volatile int a; for(a=0; a<50000; a++); }			if (i++ > 100) {				printk("<1>Can not wait rx data empty, quit while");				break;			}						}			current->state = TASK_INTERRUPTIBLE;		while (!(regs->sd_STATUS & MCI_STATUS_RXFIFOEMPTY)) {			//{volatile int a; for(a=0; a<50000; a++); }			schedule_timeout(msecs_to_jiffies(100));		}#endifstop_r_trans_handle:		if (!SDI_SendCmd(controller, &CommandParameters[STOP_TRANSMISSION], 0, 0, &error))		{			printk("<1>cmd--STOP_TRANSMISSION, error--%ld\n", error);			error = 7;			goto read_error_handle;		}	}	#if 0		if (!error)	{		apMCI_sResponse response;		int i;		response.ShortResponse = 0;		for (i=0; i<100; i++)		{			unsigned char resp;						SDI_SendCmd(controller, &CommandParameters[SEND_STATUS], RCA, &response, 0) ;			resp = (response.ShortResponse >> 9) & 0x0F; 			if (resp == ST_TRAN)				break;						{volatile int a; for(a=0; a<50000; a++); }		}		//printk("<1>delay:%d\n", i);	}#endifread_error_handle:	regs->sd_DATACTRL = 0;	regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;	if (error)	{		printk("<1>read start (%ld) length (%ld) error (%ld)\n", SectorNum, SectorCnt, error);		if (errorcode)			*errorcode = error;		return FALSE;	}	return TRUE;}//------------------------------------------------------------------------------//// Write data to SD FIFO register by DMA//// Arguments://		controller - instance created in SDI_InitInterface//		SectorNum - the number of first sector to be write//		SectorCnt - how many sectors to be write//		buffer - buffer to send data//		errorcode - record error. //// Functions://		Send command to card, then call functions SDI_InitDMA//		and SDI_StartDMA finished the transfer. ////------------------------------------------------------------------------------//2007-07-31: modified some sd write steps to stronger write actionBOOL SDI_BatchWrite_DMA(	SD_controller* controller, 	unsigned long SectorNum, 	unsigned long SectorCnt, 	unsigned char* buffer, 	unsigned long* errorcode	){	unsigned long error = 0;	unsigned long timeout;	unsigned long DataCtrl = 0;	SD_REG *regs;#if (SD_DATA_DEBUG_LEVEL == 1)	printk("SDI_BatchWrite_DMA: sector at %ld, len = %ld\n", SectorNum, SectorCnt);	printk("%lX------%lX\n", SectorNum * BYTES_PER_SECTOR, (SectorNum + SectorCnt) * BYTES_PER_SECTOR);	{}#endif	DECLARE_COMPLETION(comp);	#if (SD_DATA_DEBUG_LEVEL == 1)	SDI_Print_Sector(SectorNum, SectorCnt, buffer);#endif	regs = controller->Registers;		if (!controller || !buffer) {		error = 1;		goto write_error_handle;	}		if (SectorNum >= controller->CardCSD.CardSize / BYTES_PER_SECTOR) {		error = 2;		goto write_error_handle;	}				if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &error))	{				error = 0;		if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &error)) {						printk("<1>w: cmd--SET_BLOCKLEN, error--%ld\n", error);			error = 3;			goto write_error_handle;		}	}		DataCtrl = 0;	apBIT_SET(DataCtrl, MCI_DATA_ENABLE,1);	apBIT_SET(DataCtrl, MCI_DATA_DIRECTION, apMCI_DATA_TRANSMIT);	apBIT_SET(DataCtrl, MCI_DATA_MODE, apMCI_DATA_BLOCKING);	apBIT_SET(DataCtrl, MCI_DATA_DMA_ENABLE, 1);	apBIT_SET(DataCtrl, MCI_DATA_BLOCKSIZE, BYTES_PER_SECTOR_SH);			regs->sd_MASK0	= 0;	regs->sd_CLEAR	= MCI_STATUS_STATIC_MASK;	regs->sd_DATATMR  = 0xFFFFFFFF;	regs->sd_DATALEN  = 0xFFFF;	regs->sd_DATACTRL = DataCtrl;			if (!SDI_SendCmd(controller, &CommandParameters[WRITE_MULTIPLE_BLOCK], SectorNum * BYTES_PER_SECTOR, 0, &error))	{		printk("<1>w1: cmd--WRITE_MULTIPLE_BLOCK, error--%ld\n", error);		error = 4;		goto write_error_handle;	}	regs->sd_MASK0 = 0;				if (sd_start_dma(0, buffer, SectorCnt * BYTES_PER_SECTOR, &comp) < 0) {		printk("<1>sd start dma error\n");		error = 5;		goto stop_w_trans_handle;	}			timeout = wait_for_completion_timeout(&comp, SD_WRITE_DMA_TIMEOUT);	if(!timeout){		u32 status;				printk("<1>sd write dma timeout,%ld, reset\n", SectorNum);				error = 6;				set_current_state(TASK_INTERRUPTIBLE);		do {			status = regs->sd_STATUS;			printk("<1>status:%x\n", status);			regs->sd_CLEAR = status;						if (status & MCI_STATUS_DATAEND) {				error = 0;				set_current_state(TASK_RUNNING);				break;			}			if (status & (MCI_STATUS_DATACRCFAIL|MCI_STATUS_DATATIMEOUT|MCI_STATUS_TXUNDERRUN|MCI_STATUS_RXOVERRUN)) {				set_current_state(TASK_RUNNING);				goto stop_w_trans_handle;			}			schedule_timeout(msecs_to_jiffies(10));		} while (status);			}					do{		apMCI_sResponse response;				response.ShortResponse = 0;		if (!SDI_SendCmd(controller, &CommandParameters[SEND_STATUS], RCA, &response, &error)) {			printk("<1>w1: cmd--SEND_STATUS, error--%ld\n", error);			error = 7;			break;		}		//printk("write resp = %x\n", response.ShortResponse);		if (response.ShortResponse & READY_FOR_DATA)			break;			} while (1);	if ((SectorCnt * BYTES_PER_SECTOR) != (0xffff - regs->sd_DATACNT)) {		//note: may not be wrong here!		//printk("sector at %ld, len = %ld\n", SectorNum, SectorCnt);			}stop_w_trans_handle:	if (!SDI_SendCmd(controller, &CommandParameters[STOP_TRANSMISSION], SectorNum * BYTES_PER_SECTOR, 0, &error))	{		printk("<1>w1: cmd--STOP_TRANSMISSION, error--%ld\n", error);		error = 8;	}write_error_handle:	regs->sd_MASK0 = 0;	regs->sd_DATACTRL = 0;	regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;			if (error)	{		printk("<1>write error:%ld\n", error);		if (errorcode)			*errorcode = error;		return FALSE;	}	return TRUE;}

⌨️ 快捷键说明

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