📄 fdi_sprc.c
字号:
/* Copyright(R) 2001-2002 Intel Corporation */
/* ############################################################################
### Object: Low Level Driver
###
### Module: FDI_Sprc.c - Single Partition Relocatable Code
### $Archive: /FDI/SRC/LOWLVL/fdi_sprc.c $
### $Revision: 33 $
### $Date: 6/03/04 9:45a $
### $Author: Wtiso $
###
###$NoKeywords: $
########################################################################### */
/*
*****************************************************************
* NOTICE OF LICENSE AGREEMENT
*
* This code is provided by Intel Corp., and the use is governed
* under the terms of a license agreement. See license agreement
* for complete terms of license.
*
* YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS. YOUR
* USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY
* PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN
* INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE
* FROM INTEL LICENSING ANY SUCH USE.
*****************************************************************
*/
#ifdef CURRENT_FILE_BEING_COMPILED
#undef CURRENT_FILE_BEING_COMPILED
#endif
#define CURRENT_FILE_BEING_COMPILED FDI_SPRC
/*
*### Include Files
*#########################
*/
#include "fdi_lowl.h"
/* This code is compiled only in single partition mode */
#if (PARTITIONS == SINGLE)
/*
*### Local Declarations
*#########################
*/
/*
* If FDI block-locking support is enabled, these macros will lock/unlock the
* block pointed to by its argument
*/
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
#define LOCK_BLOCK(addr_ptr) \
*(addr_ptr) = FLASH_COMMAND_LOCK; \
*(addr_ptr) = FLASH_COMMAND_LOCK_CONFIRM
#define UNLOCK_BLOCK(addr_ptr) \
*(addr_ptr) = FLASH_COMMAND_LOCK; \
*(addr_ptr) = FLASH_COMMAND_UNLOCK_CONFIRM
#else /* (!BLOCK_LOCKING_SUPPORT) || (!ENABLE_FDI_BLOCKLOCKING) */
#define LOCK_BLOCK(addr_ptr)
#define UNLOCK_BLOCK(addr_ptr)
#endif /* (BLOCK_LOCKING_SUPPORT) && (ENABLE_FDI_BLOCKLOCKING) */
/* For non-FDI block locking support */
#if (BLOCK_LOCK_SUPPORT == TRUE)
#define BLOCK_LOCK_STATUS_OFFSET 2
#endif
/*
* When using the hardware buffer on flash components, the user must
* specify the number of bytes/words being written to the buffer after
* issuing the write-to-buffer command
*/
#if (BUFFER_SIZE > 0)
#define BUFFER_SIZE_TO_WRITE(s) CREATE_COMMAND((s) - 1)
#endif /* BUFFER_SIZE */
/* E5.0.480 START */
#if (FLASH_PAIRED == TRUE)
#define ALL_F ((FLASH_DATA) (-1))
#define SHIFT_FACTOR (sizeof(FLASH_DATA) << 2)
#define DEVICE0_MASK ((FLASH_DATA) (ALL_F >> SHIFT_FACTOR))
#define DEVICE1_MASK ((FLASH_DATA) ((ALL_F >> SHIFT_FACTOR) << SHIFT_FACTOR))
#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
*(fp) = FLASH_COMMAND_STATUS; \
if ((*(fp) & DEVICE0_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
{ \
*(fp) = ((FLASH_COMMAND_STATUS & DEVICE1_MASK) | \
(FLASH_COMMAND_RESUME & DEVICE0_MASK)); \
} \
if ((*(fp) & DEVICE1_MASK) & FLASH_STATUS_WRITE_SUSPENDED) \
{ \
*(fp) = ((FLASH_COMMAND_STATUS & DEVICE0_MASK) | \
(FLASH_COMMAND_RESUME & DEVICE1_MASK)); \
}
#else /* FLASH_PAIRED != TRUE */
#define RESUME_WRITE_SUSPENDED_FLASH(fp) \
*(fp) = FLASH_COMMAND_STATUS; \
if (*(fp) & FLASH_STATUS_WRITE_SUSPENDED) \
{ \
*(fp) = FLASH_COMMAND_RESUME; \
}
#endif /* FLASH_PAIRED */
/* E5.0.480 END */
/*
*### Global Declarations
*#########################
*/
#if (TIME_MONITOR_ENABLED == TRUE)
extern const DWORD LowLvlTimeNeeded;
#endif /* TIME_MONITOR_ENABLED */
/*
*### Global Functions
*#########################
*/
#if (BUFFER_SIZE > 0)
/*#############################################################################
### LowLvlWrite (Buffered Version)
###
### DESCRIPTION:
### Writes the data buffer to the flash hardware.
###
### PARAMETERS:
### IN: flash_ptr (FLASH_DATA_PTR) - A pointer to the physical address
### in flash to write the buffer passed.
### ram_ptr (FLASH_DATA_PTR) - A pointer to the buffer in RAM to
### read from.
### size (DWORD) - The size (in FLASH_DATA units) to write.
### OUT:
###
### PRECONDITIONS:
### 'size' must not exceed the size of the hardware buffer
###
### RETURNS:
### If one data value was not written properly, the function returns
### HW_ERR_WRITE. If the function needs to suspend the write operation
### due to a pending interrupt, the function returns HW_ERR_SUSPEND. If
### the command sequence to write a buffer was interrupted, the function
### returns HW_ERR_ABORT. If all the data in the data buffer is programmed
### without suspending flash hardware, the function returns HW_ERR_NONE.
###
*/
/* E.5.0.652 Begin */
HW_ERROR LowLvlWrite(volatile FLASH_DATA *flash_ptr,
FLASH_DATA *ram_ptr, DWORD size)
/* E.5.0.652 End */
{
static HW_ERROR status = HW_ERR_NONE;
/* if suspended, resume */
if (status == HW_ERR_SUSPEND)
{
/* E5.0.480 START */
RESUME_WRITE_SUSPENDED_FLASH(flash_ptr);
/* E5.0.480 END */
*flash_ptr = FLASH_COMMAND_STATUS;
}
/* otherwise, write data */
else
{
UNLOCK_BLOCK(flash_ptr);
status = HW_ERR_NONE;
/* not enough data, use single write */
if (size == 1)
{
*flash_ptr = FLASH_COMMAND_WRITE;
*flash_ptr = *ram_ptr;
}
/* enough data to use hardware buffer */
else
{
/* check for buffer to be ready */
do
{
*flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
} while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);
/* fill buffer */
*flash_ptr = BUFFER_SIZE_TO_WRITE(size);
while (size > 0)
{
*flash_ptr = *ram_ptr;
flash_ptr++;
ram_ptr++;
size--;
}
/*
* decrement pointer to make sure that the same block is
* being addressed, then check for interrupts before committing
* buffer
*/
flash_ptr--;
if (INTERRUPT_PENDING)
{
*flash_ptr = FLASH_COMMAND_ABORT;
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_ABORT;
}
else
{
*flash_ptr = FLASH_COMMAND_CONFIRM;
}
}
}
/* if the write was not aborted, finish write */
if (status != HW_ERR_ABORT)
{
/* wait until flash is ready */
while (((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY) &&
(!(INTERRUPT_PENDING)))
{
#if (TIME_MONITOR_ENABLED == TRUE)
if (TICKS_TILL_NEXT_INTERRUPT() < LowLvlTimeNeeded)
{
break;
}
#endif
}
/* if an interrupt occurred, suspend */
if ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
*flash_ptr = FLASH_COMMAND_SUSPEND;
*flash_ptr = FLASH_COMMAND_STATUS;
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
status = HW_ERR_SUSPEND;
}
/* check for errors */
else if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_WRITE;
}
/* write successful */
else
{
status = HW_ERR_NONE;
}
}
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
/* lock block if not suspended */
if (status != HW_ERR_SUSPEND)
{
LOCK_BLOCK(flash_ptr);
}
#endif /* BLOCK_LOCK_SUPPORT && ENABLE_FDI_BLOCKLOCKING */
/* place flash into read array mode */
*flash_ptr = FLASH_COMMAND_READ;
return status;
}
#else /* BUFFER_SIZE == 0 */
/*#############################################################################
### LowLvlWrite (Buffered Version)
###
### DESCRIPTION:
### Writes the data buffer to the flash hardware.
###
### PARAMETERS:
### IN: flash_ptr (FLASH_DATA_PTR) - A pointer to the physical address
### in flash to write the buffer passed.
### ram_ptr (FLASH_DATA_PTR) - A pointer to the buffer in RAM to
### read from.
### size (DWORD) - The size (in FLASH_DATA units) to write.
### OUT:
###
### RETURNS:
### If one data value was not written properly, the function returns
### HW_ERR_WRITE. If the function needs to suspend the write operation
### due to a pending interrupt, the function returns HW_ERR_SUSPEND. If
### the command sequence to write a buffer was interrupted, the function
### returns HW_ERR_ABORT. If all the data in the data buffer is programmed
### without suspending flash hardware, the function returns HW_ERR_NONE.
###
*/
/* E.5.0.652 Begin */
HW_ERROR LowLvlWrite(volatile FLASH_DATA *flash_ptr,
FLASH_DATA *ram_ptr)
/* E.5.0.652 End */
{
static HW_ERROR status = HW_ERR_NONE;
/* if previously suspended, resume write */
if (status == HW_ERR_SUSPEND)
{
/* E5.0.480 START */
RESUME_WRITE_SUSPENDED_FLASH(flash_ptr);
/* E5.0.480 END */
*flash_ptr = FLASH_COMMAND_STATUS;
}
/* otherwise, write data */
else
{
UNLOCK_BLOCK(flash_ptr);
*flash_ptr = FLASH_COMMAND_WRITE;
*flash_ptr = *ram_ptr;
}
/* wait until flash ready or interrupt occurs */
while (((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY) &&
(!(INTERRUPT_PENDING)))
{
#if (TIME_MONITOR_ENABLED == TRUE)
if (TICKS_TILL_NEXT_INTERRUPT() < LowLvlTimeNeeded)
{
break;
}
#endif
}
/* if an interrupt occurred, suspend */
if ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
*flash_ptr = FLASH_COMMAND_SUSPEND;
*flash_ptr = FLASH_COMMAND_STATUS;
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
status = HW_ERR_SUSPEND;
}
/* write complete, check for errors */
else if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_WRITE;
}
/* write was successful */
else
{
status = HW_ERR_NONE;
}
#if ((BLOCK_LOCK_SUPPORT == TRUE) && (ENABLE_FDI_BLOCKLOCKING == TRUE))
/* lock block if not suspended */
if (status != HW_ERR_SUSPEND)
{
LOCK_BLOCK(flash_ptr);
}
#endif /* BLOCK_LOCK_SUPPORT && ENABLE_FDI_BLOCKLOCKING */
/* place back into read array mode */
*flash_ptr = FLASH_COMMAND_READ;
return status;
}
#endif /* BUFFER_SIZE */
/*#############################################################################
### LowLvlEraseBlock
###
### DESCRIPTION:
### Erases the block containing the address specified in the flash
### hardware.
###
### If an interrupt occurs while erasing the flash block, the erase is
### suspended before the function returns. If an erase was suspended
### and this function called, the function resumes the erase and does
### not start a new one.
###
### PARAMETERS:
### IN: address (DWORD) - An absolute physical starting address of the
### block to be erased.
### OUT:
###
### RETURNS:
### If the flash block could not be erased, the function returns
### HW_ERR_ERASE. If the funciton needs to suspend the erase due to
### a pending interrupt, the function returns HW_ERR_SUSPEND. If the
### block is erased successfully, the function returns HW_ERR_NONE.
###
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -