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

📄 amdflash.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 2 页
字号:
		data_size = COPY_BUFFER_SIZE;
		dst_offset = 0;
	}

	dst_data_ptr--;

	RESET_TO_READ(dst_data_ptr);

	/* resume if flash was suspended */
	if (suspended)
	{
		ERASE_RESUME(dst_data_ptr);
	}

	/* release flash write mutex */
	FsmReleaseMtxSem(pDev->DevWriteLock);

	return status;
}


/******************************************************************************
 * FsmAmdFlashErase()
 *
 * descriptions:
 *   erase a flash block.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *    uint32 Addr - The starting address of the flash block to be erased.
 *
 * return:
 *   HW_ERR_NONE,  HW_ERR_SYSTEM, HW_ERR_PARAM, HW_ERR_ERASE.
 *
 *****************************************************************************/

uint32 FsmAmdFlashErase(FsmDevObjHdrT * DevObjP, uint32 Addr)
{
	volatile FLASH_DATA_PTR	flash_ptr;

	uint32			status;
	uint8			bRet;
	BANK_STATUS		bank_status;

	FsmFlashDevT *	pDev;


	pDev = (FsmFlashDevT *)DevObjP;

	/* validate address */
#ifdef VALIDATE_ADDRESS

	if(Addr > (pDev->BlockSize * pDev->Blocks))
	{
		return HW_ERR_PARAM;
	}

#endif /* VALIDATE_ADDRESS */

	Addr += pDev->DevStartAddr;

	/* Align address */
	flash_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(Addr);

	/* get flash erase mutex */
	if(FsmGetMtxSem(pDev->DevEraseLock) != ERR_NONE)
	{
		if(FsmStarting == FALSE)
			return HW_ERR_SYSTEM;
	}


	/* wait if flash is busy programming */
	while(TRUE)
	{
		bank_status = BankStatus(flash_ptr);
		if (bank_status == BANK_STATUS_BUSY)
		{
			TASK_SLEEP(10);
		}
		else if (bank_status == BANK_STATUS_TIMEOUT)
		{
			/*
				we SHOULD delay some time to let the 
				program initiator know what has happened.
			*/
			TASK_SLEEP(100);
			RESET_TO_READ(flash_ptr);
			break;
		}
		else
		{
			/* The bank is ready */
			break;
		}
	}

	DISABLE_INTERRUPTS();

	ERASE_BLOCK(flash_ptr, pDev->DevStartAddr);

	ENABLE_INTERRUPTS();

	/* wait until flash is done */
	bRet = PollWait(flash_ptr, FLASH_ERASE_DATA);

	if (!bRet)
	{
		status = HW_ERR_ERASE;
	}
	else
	{
		status = HW_ERR_NONE;
	}

	RESET_TO_READ(flash_ptr);

	/* release flash erase mutex */
	FsmReleaseMtxSem(pDev->DevEraseLock);

	return status;
}


/******************************************************************************
 * FsmAmdFlashCopy()
 *
 * descriptions:
 *   copy data from one flash location to another.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *    uint32 DstAddr - The starting address within flash to copy data to.
 *    uint32 SrcAddr - The starting address within flash to read the data from.
 *    uint32 length - The amount of data, in bytes, to be copied.
 * 
 *
 * return:
 *   HW_ERR_NONE.
 *
 *****************************************************************************/

uint32 FsmAmdFlashCopy(FsmDevObjHdrT * DevObjP, uint32 DstAddr, uint32 SrcAddr, uint32 length)
{
	volatile FLASH_DATA_PTR		dst_data_ptr;
	volatile FLASH_DATA_PTR		src_data_ptr;

	FLASH_DATA		temp_buffer[COPY_BUFFER_SIZE / sizeof(FLASH_DATA)];

	uint8 *		dst_byte_ptr;
	uint8 *		src_byte_ptr;
	uint32		dst_offset;
	uint32		byte_size;
	uint32		data_size;
	uint32		status = HW_ERR_NONE;
	uint32		rem_byte_size;
	uint8		suspended = (uint8) FALSE;

	BANK_STATUS		bank_status;

	FsmFlashDevT *	pDev;


	pDev = (FsmFlashDevT *)DevObjP;

	/* validate address */
#ifdef VALIDATE_ADDRESS

	if((SrcAddr + length) > (pDev->BlockSize * pDev->Blocks))
	{
		return HW_ERR_PARAM;
	}

	if((DstAddr + length) > (pDev->BlockSize * pDev->Blocks))
	{
		return HW_ERR_PARAM;
	}


#endif /* VALIDATE_ADDRESS */

	SrcAddr += pDev->DevStartAddr;
	DstAddr += pDev->DevStartAddr;

	/* return if nothing to write */
	if (length == 0)
	{
		return HW_ERR_NONE;
	}


	dst_data_ptr = (volatile FLASH_DATA_PTR) ALIGN_ADDRESS(DstAddr);
	dst_offset   = UNALIGNED_BYTES(DstAddr);
	dst_byte_ptr = (uint8 *) temp_buffer + dst_offset;
	data_size    = COPY_BUFFER_SIZE - dst_offset;
	src_byte_ptr = (uint8 *) SrcAddr;


	/* get flash write mutex. */
	if(FsmGetMtxSem(pDev->DevWriteLock) != ERR_NONE)
	{
		if(FsmStarting == FALSE)
			return HW_ERR_SYSTEM;
	}


   /* suspend if flash is busy erasing */
	bank_status = BankEraseStatus(dst_data_ptr);
	if (bank_status == BANK_STATUS_BUSY)
	{
		ERASE_SUSPEND(dst_data_ptr);

		PollWait(dst_data_ptr, FLASH_ERASE_DATA);

		if (IsEraseSuspended(dst_data_ptr))
		{
			suspended = (uint8) TRUE;
		}
	}
	else if (bank_status == BANK_STATUS_TIMEOUT)
	{
		/*
			we SHOULD delay some time to let the 
			erase initiator know what has happened.
		*/
		TASK_SLEEP(100);
		RESET_TO_READ(dst_data_ptr);
	}
	else
	{
		/* The bank is ready */
	}


	while ((length > 0) && (status == HW_ERR_NONE))
	{
		/* */
		byte_size = GET_MIN(data_size, length);

		/* calculate the number of FLASH_DATA to write */
		data_size = (byte_size + dst_offset + sizeof(FLASH_DATA) - 1) /
						sizeof(FLASH_DATA);

		src_data_ptr = (volatile FLASH_DATA_PTR) ALIGN_ADDRESS((uint32) src_byte_ptr);

		RESET_TO_READ(src_data_ptr);

		/* For AMD flash device, if you attempt to program a bit
		* from 0 to 1, device will timeout, so we can't initialize
		* the leader spare area to 0xFF, we must read data from 
		* flash to initialize these bytes, the same to the remainder
		* area for the buffer.
		*/
		if(dst_offset != 0)
		{
			FsmMemoryMove((uint8 *)temp_buffer, (uint8 *)dst_data_ptr, dst_offset);
		}
		rem_byte_size = (byte_size + dst_offset) % (sizeof(FLASH_DATA));
		if(rem_byte_size != 0)
		{
			FsmMemoryMove(((uint8 *)temp_buffer) + byte_size + dst_offset, \
						  ((uint8 *)dst_data_ptr) + byte_size + dst_offset, \
						  sizeof(FLASH_DATA) - rem_byte_size
						  );
		}

		FsmMemoryMove(dst_byte_ptr, src_byte_ptr, (uint16)byte_size);

		/* write buffer */
		status = WriteToFlash(dst_data_ptr, temp_buffer, data_size, pDev->DevStartAddr);

		/* update pointers/variables */
		dst_data_ptr += data_size;
		dst_byte_ptr = (uint8 *) temp_buffer;
		src_byte_ptr += byte_size;
		length -= byte_size;
		data_size = COPY_BUFFER_SIZE;
		dst_offset = 0;
	}

	dst_data_ptr--;

	RESET_TO_READ(dst_data_ptr);

	/* resume if flash was suspended */
	if (suspended)
	{
		ERASE_RESUME(dst_data_ptr);
	}

	/* release flash write mutex, and return */
	FsmReleaseMtxSem(pDev->DevWriteLock);

	return status;
}

/******************************************************************************
 * FsmAmdFlashRead()
 *
 * descriptions:
 *   reset flash device to read-mode.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *    uint8 * buf - buffer to receive the returned data
 *    uint32 Addr - where to read from within flash.
 *    uint32 length - number of bytes to read.
 *
 * return:
 *   HW_ERR_NONE.
 *
 *****************************************************************************/

uint32 FsmAmdFlashRead(FsmDevObjHdrT * DevObjP, uint8 * buf, uint32 Addr, uint32 length)
{
	volatile FLASH_DATA_PTR		flash_data_ptr;

	volatile uint8 *	flash_byte_ptr;

	FLASH_DATA_PTR	ram_data_ptr;
	uint8 *			ram_byte_ptr;

	uint32			flash_offset;
	uint32			ram_offset;

	uint8			suspended = (uint8) FALSE;
	BANK_STATUS		bank_status;

	FsmFlashDevT *	pDev;


	pDev = (FsmFlashDevT *)DevObjP;

	/* validate address */
#ifdef VALIDATE_ADDRESS

	if((Addr + length) > (pDev->BlockSize * pDev->Blocks))
	{
		return HW_ERR_PARAM;
	}

#endif /* VALIDATE_ADDRESS */

	Addr += pDev->DevStartAddr;

	/* return if nothing to read */
	if (length == 0)
	{
		return HW_ERR_NONE;
	}


	flash_data_ptr = (FLASH_DATA_PTR) ALIGN_ADDRESS(Addr);
	flash_byte_ptr = (uint8 *) Addr;
	ram_byte_ptr = buf;

	flash_offset = (uint32) UNALIGNED_BYTES(Addr);
	ram_offset = (uint32) UNALIGNED_BYTES((uint32) buf);


	/*
		For the best performance,we should suspend erase 
		if bank is busy erasing.
		NOW we haven't done that,it should be done in the future.
	*/
	/* wait if bank is busy */
	while(TRUE)
	{
		bank_status = BankStatus(flash_data_ptr);
		if (bank_status == BANK_STATUS_BUSY)
		{
			TASK_SLEEP(10);
		}
		else if (bank_status == BANK_STATUS_TIMEOUT)
		{
			/*
				we SHOULD delay some time to let the 
				operation initiator know what has happened.
			*/
			TASK_SLEEP(100);
			RESET_TO_READ(flash_data_ptr);
			break;
		}
		else
		{
			/* The bank is ready */
			break;
		}
	}

	/*
	* determine if source and destination addresses allow the reading on
	* aligned addresses
	*/

	RESET_TO_READ(flash_data_ptr);

	if ((flash_offset == ram_offset) && (length > sizeof(FLASH_DATA)))
	{
		/* read initial unaligned bytes */
		if (flash_offset != 0)
		{
			while (flash_offset < sizeof(FLASH_DATA))
			{
				*ram_byte_ptr = *flash_byte_ptr;
				ram_byte_ptr++;
				flash_byte_ptr++;
				length--;
				flash_offset++;
			}
		}

		/* read aligned data */
		ram_data_ptr = (FLASH_DATA_PTR) ram_byte_ptr;
		flash_data_ptr = (FLASH_DATA_PTR) flash_byte_ptr;
		while (length >= sizeof(FLASH_DATA))
		{
			*ram_data_ptr = *flash_data_ptr;
			ram_data_ptr++;
			flash_data_ptr++;
			length -= sizeof(FLASH_DATA);
		}

		/* read remaining unaligned bytes */
		if (length > 0)
		{
			ram_byte_ptr = (uint8 *) ram_data_ptr;
			flash_byte_ptr = (uint8 *) flash_data_ptr;

			while (length > 0)
			{
				*ram_byte_ptr = *flash_byte_ptr;
				ram_byte_ptr++;
				flash_byte_ptr++;
				length--;
			}
		}
	}

	/*
	* source and destination addresses do not allow the reading on aligned
	* addresses; therefore, a byte-by-byte copy needs to be done
	*/
	else
	{
		while (length > 0)
		{
			*ram_byte_ptr = *flash_byte_ptr;
			ram_byte_ptr++;
			flash_byte_ptr++;
			length--;
		}
	}

	/* if suspended, resume */
	if (suspended)
	{
		/* 
			we didn't suspend any operation now,
			it should be done in the future.
		*/
	}

	return HW_ERR_NONE;
}

/******************************************************************************
 * FsmAmdFlashCtrl()
 *
 * descriptions:
 *   flash driver io control.
 *
 * parameters:
 *    FsmDevObjHdrT * DevObjP - device object
 *    uint32 CtrlCode - command to be executed.
 *    void *arg - argument that is command specified
 *
 * return:
 *   HW_ERR_NONE.
 *
 *****************************************************************************/

uint32 FsmAmdFlashCtrl(FsmDevObjHdrT * DevObjP, uint32 CtrlCode, void *arg)
{
	return HW_ERR_NONE;
}

/*****************************************************************************
* $Log: amdflash.c $
* Revision 1.3  2004/03/17 12:57:57  zgy
* Revision 1.4  2004/03/16 15:56:19  jjs
* Revision 1.3  2003/11/05 10:50:20  zgy
* Revision 1.2  2003/11/04 10:46:46  jjs
* Check original data before write to flash.
* Revision 1.1  2003/10/27 09:48:35  jjs
* Initial revision
* Initial revision -- jjs
*****************************************************************************/



⌨️ 快捷键说明

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