📄 amdflash.c
字号:
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 + -