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

📄 cfc_data.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
*   File:    cfc_data.c  -   Read / Write Functions
* 
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subject to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
****************************************************************************/
#include "cfcard.h"

//-----------------------------------------------------------------------------
// Global Variables and Macros in CFC_DATA.C
//-----------------------------------------------------------------------------
extern HANDLE cfIntrEvent;
extern HANDLE cfIntrThread;
extern HANDLE cfDataEvent;

extern unsigned char	ChannelNumber;
extern unsigned long	InterruptID;
extern HANDLE			DMAIntrEvent;

unsigned long TempBuf[SECTORS_PER_BATCH*BYTES_PER_SECTOR/4];

#define MIN(__x,__y) ((__x)<(__y)?(__x):(__y)) 
#define RETRYNUM 5

//------------------------------------------------------------------------------
//
// Safe read - read sectors from the card
//
// 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
//
// Functions:
//		Call function CFC_ReadSectors_FIFO or CFC_ReadSectors_DMA 
//		to read data from sectors. Retry if error occured. 
//
//------------------------------------------------------------------------------
BOOL 
CFC_SafeRead(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt
	)
{
	unsigned long error = 0;
	int i;
	int retry;
	int batchnum = (int)((sectorcnt-1)/SECTORS_PER_BATCH);	// transfer at most 128 sectors every time. 
	int sectorcntthis;	// transfer sector number this time.
	unsigned char * bufthis;
	for (i=0;i<=batchnum;i++)
	{
		retry = RETRYNUM+1;
		sectorcntthis = MIN((int)sectorcnt, (int)SECTORS_PER_BATCH);
		if ((int)buf&0x3)
			bufthis = (unsigned char*)TempBuf;
		else
			bufthis = (unsigned char*)buf;
		// safe read
		while (--retry)
		{
			error = 0;
			if (sectorcnt > SECTORS_NEED_DMA_READ && InterruptID != 0 && SECTORS_NEED_DMA_READ != 0xFF)
			{
				if (CFC_ReadSectors_DMA(regs, (unsigned short*)bufthis, sectornum, sectorcntthis, &error))
					break;
			}
			error = 0;
			if (CFC_ReadSectors_FIFO(regs, (unsigned short*)bufthis, sectornum, sectorcntthis, &error))
				break;
		}
		if ((int)buf&0x3)
			memcpy(buf, TempBuf, BYTES_PER_SECTOR * sectorcntthis);
		if (retry == 0)
		{
			break;
		}
		// to next batch
		buf += BYTES_PER_SECTOR * sectorcntthis/(sizeof(unsigned short));
		sectornum += sectorcntthis;
		sectorcnt -= sectorcntthis;
	}
	if (retry && !sectorcnt)
		return TRUE;
	return FALSE;
}

//------------------------------------------------------------------------------
//
// Safe write - write sectors to the card
//
// 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
//
// Functions:
//		Call function CFC_WriteSectors_FIFO or CFC_WriteSectors_DMA 
//		to write data to sectors. Retry if error occured. 
//
//------------------------------------------------------------------------------
BOOL 
CFC_SafeWrite(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt
	)
{
	unsigned long error = 0;
	int i;
	int retry;
	int batchnum = (int)((sectorcnt-1)/SECTORS_PER_BATCH);	// transfer at most 255 sectors every time. 
	int sectorcntthis;	// transfer sector number this time.
	unsigned char * bufthis;
	for (i=0;i<=batchnum;i++)
	{
		retry = RETRYNUM+1;
		sectorcntthis = MIN((int)sectorcnt, (int)SECTORS_PER_BATCH);
		if ((int)buf&0x3)
		{
			bufthis = (unsigned char*)TempBuf;
			memcpy(TempBuf, buf, BYTES_PER_SECTOR * sectorcntthis);
		}
		else
			bufthis = (unsigned char*)buf;
		// safe write
		while (--retry)
		{
			error = 0;
			if (sectorcnt > SECTORS_NEED_DMA_WRITE && InterruptID != 0 && SECTORS_NEED_DMA_WRITE != 0xFF)
			{
				if (CFC_WriteSectors_DMA(regs, (unsigned short*)bufthis, sectornum, sectorcntthis, &error))
					break;
			}
			error = 0;
			if (CFC_WriteSectors_FIFO(regs, (unsigned short*)bufthis, sectornum, sectorcntthis, &error))
				break;
		}
		if (retry == 0)
		{
			break;
		}
		// to next batch
		buf += BYTES_PER_SECTOR * sectorcntthis/(sizeof(unsigned short));
		sectornum += sectorcntthis;
		sectorcnt -= sectorcntthis;
	}
	if (retry && !sectorcnt)
		return TRUE;
	return FALSE;
}

//------------------------------------------------------------------------------
//
// Read sectors from FIFO directly
//
// 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 read data from FIFO whenever FIFO is 
//		half full.  
//
//------------------------------------------------------------------------------
BOOL 
CFC_ReadSectors_FIFO(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt, 
	unsigned long *errorcode)
{
	unsigned long i = 0;
	unsigned long k = SleepCircle;
	unsigned char atastatus, ataerror;
	unsigned long * Dbuf = (unsigned long *) buf;
	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_FIFOreq = (1<<FIFOreq_ClearFifo) 
			| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
		regs->CF_ADDR_SectorCfg = 0x7f00 + sectorcnt;	
		regs->CF_ADDR_FIFOreq = (1<<FIFOreq_StopFifo) 
			| (1<<FIFOreq_RXPush) | (1<<FIFOreq_RXPop) ;

		while (i < (int)(BYTES_PER_SECTOR*sectorcnt/4))
		{
			unsigned long j;
			regs->CF_ADDR_CFINTena = (1<<CfRawIntr_RxfifoHfReq);		
			if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
			{
				RETAILMSG(1, (_T("CFCARD: ReadSectorsFIFO - read rxfifohfreq 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 = 3;
				break;
			}
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
			for (j=0; j<16; j ++)
				Dbuf[i++] = regs->CF_ADDR_FIFO;
			regs->CF_ADDR_CFINTR = (1<<CfRawIntr_RxfifoHfReq);
			InterruptDone(SYSINTR_CF);				
			if (regs->CF_ADDR_CFINTR & (1<<CfRawIntr_FifoUnderrun))
			{
				error = 4;
				break;
			}
		}//while i<BYTES.../4
	}

	if (!error)
	{
		if (i == (int)(BYTES_PER_SECTOR*sectorcnt/4))
		{
			regs->CF_ADDR_CFINTena = (1<<CfRawIntr_RxPopOver);		
			if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
			{
				RETAILMSG(1, (_T("CFCARD: ReadSectorsFIFO - 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
			{
				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);
				InterruptDone(SYSINTR_CF);	
				while (k--)
				{
					AtaReadStatus(regs, atastatus);
					if (atastatus == 0x50)
						break;
					if (atastatus & 0x01)
					{
						AtaReadError(regs, ataerror);
						error = 6;
						break;
					}
				}
			}
		}//if i==BYTES.../4
		else
			error = 7;
	}

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

//------------------------------------------------------------------------------
//
// Write sectors to FIFO directly
//
// 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 write data to FIFO whenever FIFO is 
//		half empty.  
//
//------------------------------------------------------------------------------
BOOL
CFC_WriteSectors_FIFO(
	CFRegs *regs, 
	unsigned short *buf, 
	unsigned long sectornum, 
	unsigned long sectorcnt, 
	unsigned long *errorcode
	)
{
	unsigned long i = 0;
	unsigned long k = SleepCircle;
	unsigned char atastatus, ataerror;
	unsigned long * Dbuf = (unsigned long *) buf;
	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)
				break;
			if (atastatus & (0x01))
			{
				AtaReadError(regs, ataerror);
				error = 2;
				break;
			}
		}
	}

	if (!error)
	{
		CFC_SetFifoAccessMode(regs);
		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_StopFifo) 
			| (1<<FIFOreq_TXPush) | (1<<FIFOreq_TXPop) ;

		while (i < (int)(BYTES_PER_SECTOR*sectorcnt/4))
		{
			unsigned long j;
			regs->CF_ADDR_CFINTena = (1<<CfRawIntr_TxfifoHfReq);		
			if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
			{
				RETAILMSG(1, (_T("CFCARD: WriteSectorsFIFO - write txfifohfreq 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 = 3;
				break;
			}
			regs->CF_ADDR_CFINTena = 0;	//(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);		
			for (j=0; j<16; j ++)
				regs->CF_ADDR_FIFO = Dbuf[i++];
			regs->CF_ADDR_CFINTR = (1<<CfRawIntr_TxfifoHfReq);
			InterruptDone(SYSINTR_CF);				
			if (regs->CF_ADDR_CFINTR & (1<<CfRawIntr_FifoUnderrun))
			{
				error = 4;
				break;
			}
		}//while i<BYTES.../4
	}
	if (!error)
	{
		if (i == (int)(BYTES_PER_SECTOR*sectorcnt/4))
		{
			regs->CF_ADDR_CFINTena = (1<<CfRawIntr_TxPopOver);		
			if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
			{
				RETAILMSG(1, (_T("CFCARD: WriteSectorsFIFO - 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
			{
				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);
				InterruptDone(SYSINTR_CF);						
				while (k--)
				{
					AtaReadStatus(regs, atastatus);
					if (atastatus == 0x50)
						break;
					if (atastatus & 0x01)
					{
						AtaReadError(regs, ataerror);
						error = 6;
						break;
					}
				}
			}
		}//if i==BYTES.../4
		else
			error = 7;

⌨️ 快捷键说明

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