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

📄 cfc_data.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	if (error)
	{
		RETAILMSG(1, (_T("CFCARD: WriteSectorsFIFO - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Read sectors from FIFO by DMA
//
// Arguments:
//		regs - Cf registers' base address
//		buf - buffer to receive data
//		sectornum - the number of first sector to be read
//		sectorcnt - how many sectors to be read
//		errorcode - record error
//
// Functions:
//		Send command to card, then config DMA. Wait the end of transfer.  
//
//------------------------------------------------------------------------------
BOOL
CFC_ReadSectors_DMA(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt, 
	unsigned long *errorcode
	)
{
	unsigned long k = SleepCircle;
	unsigned char atastatus, ataerror;
	unsigned long Opcode = DISK_IOCTL_READ;
	unsigned long error = 0;

	if (regs == NULL || buf == NULL)
		error = 1;

	if (!error)
	{
		AtaSetSectorNum(regs, (unsigned char)sectornum);
		AtaSetCylinderLow(regs, (unsigned char)(sectornum>>8));
		AtaSetCylinderHigh(regs, (unsigned char)(sectornum>>16));
		AtaSetHead(regs, 0xe0 | (unsigned char)(sectornum>>24));
		AtaSetSectorCount(regs, (unsigned char)sectorcnt);
		AtaSetCommand(regs, ATA_CMD_READ);	

		while (k--) 
		{
			AtaReadStatus(regs, atastatus);

			if (atastatus == 0x58)
				break;
			if (atastatus & (0x01))
			{
				AtaReadError(regs, ataerror);
				error = 2;
				break;
			}
		}
	}

	if (!error)
	{
		CFC_SetFifoAccessMode(regs);
		regs->CF_ADDR_CFINTena = 0;
		regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo) 
			| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
		regs->CF_ADDR_SectorCfg = 0x7f00 + sectorcnt;
		regs->CF_ADDR_FIFOreq = (1<<FIFOreq_DmaRxReq) | (1<<FIFOreq_StopFifo)
			| (1<<FIFOreq_RXPush) | (1<<FIFOreq_RXPop) ;

		if (!CFC_InitDMA(DISK_IOCTL_READ))
		{
			error = 3;
		}
		else
		{
			if (!CFC_StartDMA(
				regs,
				DISK_IOCTL_READ, 
				(unsigned long)(CF_HOST_BASE_ADDRESS+0x80), 
				buf, 
				sectorcnt))
			{
				error = 4;
			}
		}
	}
	
	if (!error)
	{
		regs->CF_ADDR_CFINTena = (1<<CfRawIntr_RxPopOver);		
		if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
		{
			RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - read rxpopover TIMEOUT\r\n")));
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
			regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
			InterruptDone(SYSINTR_CF);				
			error = 5;		
		}
		else
		{
//			RETAILMSG(MSG_DATA, (_T("CFCARD: ReadSectorsDMA - CF_ADDR_TXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_TXFIFOCnt));
//			RETAILMSG(MSG_DATA, (_T("CFCARD: ReadSectorsDMA - CF_ADDR_RXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_RXFIFOCnt));
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);		
			regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo) 
				| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);		
			regs->CF_ADDR_FIFOreq = 0x00;
//			regs->CF_ADDR_CFINTR = (1<<CfRawIntr_RxPopOver);
			regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
			InterruptDone(SYSINTR_CF);	
		}
	}

	if (!error)
	{
		while (k--)
		{
			AtaReadStatus(regs, atastatus);
			if (atastatus == 0x50)
				break;
			if (atastatus & 0x01)
			{
				AtaReadError(regs, ataerror);
				RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - ataerror(0x%x)\r\n"), ataerror));		
				error = 6;
				break;
			}
		}
	}
	
	if (error)
	{
		RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Write sectors to FIFO by DMA
//
// Arguments:
//		regs - Cf registers' base address
//		buf - buffer to send data
//		sectornum - the number of first sector to be write
//		sectorcnt - how many sectors to be write
//		errorcode - record error
//
// Functions:
//		Send command to card, then config DMA. Wait the end of transfer.  
//
//------------------------------------------------------------------------------
BOOL
CFC_WriteSectors_DMA(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt, 
	unsigned long *errorcode
	)
{
	unsigned long k = SleepCircle;
	unsigned char atastatus, ataerror;
	unsigned long Opcode = DISK_IOCTL_WRITE;
	unsigned long error = 0;

	if (regs == NULL || buf == NULL)
		error = 1;

	if (!error)
	{
		AtaSetSectorNum(regs, (unsigned char)sectornum);
		AtaSetCylinderLow(regs, (unsigned char)(sectornum>>8));
		AtaSetCylinderHigh(regs, (unsigned char)(sectornum>>16));
		AtaSetHead(regs, 0xe0 | (unsigned char)(sectornum>>24));
		AtaSetSectorCount(regs, (unsigned char)sectorcnt);
		AtaSetCommand(regs, ATA_CMD_WRITE);	

		while (k--) 
		{
			AtaReadStatus(regs, atastatus);

			if (atastatus == 0x58)	//addr7, atastatus
				break;
			if (atastatus & (0x01))
			{
				AtaReadError(regs, ataerror);
				error = 2;
				break;
			}
		}
	}

	if (!error)
	{
		CFC_SetFifoAccessMode(regs);
		regs->CF_ADDR_CFINTena = 0;
		regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo) | 
			(1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
		regs->CF_ADDR_SectorCfg = 0x7f00 + sectorcnt;
		regs->CF_ADDR_FIFOreq = (1<<FIFOreq_DmaTxReq) | (1<<FIFOreq_StopFifo) 
			| (1<<FIFOreq_TXPush) | (1<<FIFOreq_TXPop) ;

		if (!CFC_InitDMA(DISK_IOCTL_WRITE))
		{
			error = 3;
		}
		else
		{
			if (!CFC_StartDMA(
				regs,
				DISK_IOCTL_WRITE, 
				(unsigned long)(CF_HOST_BASE_ADDRESS+0x80), 
				buf, 
				sectorcnt))
			{
				error = 4;
			}
		}
	}

	if (!error)
	{
		regs->CF_ADDR_CFINTena = (1<<CfRawIntr_TxPopOver);		
		if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
		{
			RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - write txpopover TIMEOUT\r\n")));		
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
			regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
			InterruptDone(SYSINTR_CF);				
			error = 5;					
		}
		else
		{
//			RETAILMSG(MSG_DATA, (_T("CFCARD: WriteSectorsDMA - CF_ADDR_TXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_TXFIFOCnt));
//			RETAILMSG(MSG_DATA, (_T("CFCARD: WriteSectorsDMA - CF_ADDR_RXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_RXFIFOCnt));
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);		
			regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo) 
				| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);		
			regs->CF_ADDR_FIFOreq = 0x00;
//			regs->CF_ADDR_CFINTR = (1<<CfRawIntr_TxPopOver);
			regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
			InterruptDone(SYSINTR_CF);						
		}
	}

	if (!error)
	{
		while (k--)
		{
			AtaReadStatus(regs, atastatus);
			if (atastatus == 0x50)
				break;
			if (atastatus & 0x01)
			{
				AtaReadError(regs, ataerror);
				RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - ataerror(0x%x)\r\n"), ataerror));		
				error = 6;
				break;
			}
		}
	}

	if (error)
	{
		RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Read a byte from card
//
// Arguments:
//		regs - Cf registers' base address
//		offset - the byte's offset
//		result - data to be read
//
// Functions:
//		Read a byte from card. Always used to read common registers.  
//
//------------------------------------------------------------------------------
int 
CFC_ReadByte(
	CFRegs *regs, 
	unsigned long offset, 
	unsigned char* result
	)
{
	static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
	unsigned long wordoffset = offset / 4;
	if (regs == 0 || result ==0)
		return 0;
	offset = offset % 4;
	regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) + 
		(CFMODE_MEMORY<<CfU_Signal_cs_b) +
		(bytecode[offset]<<CfU_Signal_be_b);
	*result = (unsigned char)(regs->CF_BaseADDR_CARD[wordoffset]>> (offset*8));
	return 1;
}

//------------------------------------------------------------------------------
//
// Write a byte to card
//
// Arguments:
//		regs - Cf registers' base address
//		offset - the byte's offset
//		data - data to be written
//
// Functions:
//		Write a byte to card. Always used to write common registers.  
//
//------------------------------------------------------------------------------
int 
CFC_WriteByte(
	CFRegs *regs, 
	unsigned long offset, 
	unsigned char data
	)
{
	static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
	unsigned long wordoffset = offset / 4;
	if (regs == 0)
		return 0;
	offset = offset % 4;
	regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) + 
		(CFMODE_MEMORY<<CfU_Signal_cs_b) +
		(bytecode[offset]<<CfU_Signal_be_b);
	regs->CF_BaseADDR_CARD[wordoffset] = data << (offset*8);
	return 1;
}

//------------------------------------------------------------------------------
//
// Read a half-word from card
//
// Arguments:
//		regs - Cf registers' base address
//		offset - the half-word's offset
//		result - data to be read
//
// Functions:
//		Read a half-word from card. Always used to read data registers.  
//
//------------------------------------------------------------------------------
int 
CFC_ReadHWd(
	CFRegs *regs, 
	unsigned long offset, 
	unsigned short* result
	)
{
	static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
	unsigned long wordoffset = offset / 4;
	if (regs == 0 || result ==0)
		return 0;
	offset = offset % 4;
	regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
		(CFMODE_MEMORY<<CfU_Signal_cs_b) +
		((bytecode[offset]&bytecode[offset+1])<<CfU_Signal_be_b);
	*result = (unsigned short)(regs->CF_BaseADDR_CARD[wordoffset] >> (offset*8));
	return 1;
}

//------------------------------------------------------------------------------
//
// Write a half-word to card
//
// Arguments:
//		regs - Cf registers' base address
//		offset - the half-word's offset
//		result - data to be write
//
// Functions:
//		Write a half-word to card. Always used to write data registers.  
//
//------------------------------------------------------------------------------
int 
CFC_WriteHWd(
	CFRegs *regs, 
	unsigned long offset, 
	unsigned short data
	)
{
	static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
	unsigned long wordoffset = offset / 4;
	if (regs == 0)
		return 0;
	offset = offset % 4;
	regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) + 
		(CFMODE_MEMORY<<CfU_Signal_cs_b) +
		((bytecode[offset]&bytecode[offset+1])<<CfU_Signal_be_b);
	regs->CF_BaseADDR_CARD[wordoffset] = data << (offset*8);
	return 1;
}

//------------------------------------------------------------------------------
//
// Set FIFO access mode
//
// Arguments:
//		regs - Cf registers' base address
//
// Functions:
//		Used to set FIFO to memory mode.  
//
//------------------------------------------------------------------------------
int 
CFC_SetFifoAccessMode(
	CFRegs *regs
	)
{
	static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
	regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) + 
		(CFMODE_MEMORY<<CfU_Signal_cs_b) +
		((bytecode[0]&bytecode[1])<<CfU_Signal_be_b);
	return 0;								
}

⌨️ 快捷键说明

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