📄 lld.c
字号:
int lld_EraseSuspendCmd
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
uint32 cpsr;
#ifdef PAUSE_BETWEEN_ERASE_SUSPENDS
DWORD volatile i;
#endif
/*
* Reserved for Future Use.
* Trivial assignment to prevent compiler warnings
*/
data_cfg = data_cfg;
#ifdef PAUSE_BETWEEN_ERASE_SUSPENDS
for(i = 0; i < DELAY_10ms; i++) i = i;
#endif
#ifdef AMD_DRIVER_FLASH_FOR_SW
/* Write Suspend Command */
cpsr = int_disable();
dev.state = DEV_ERASE_SUSPEND;
#endif
status = HalWrite(base_addr + offset, NOR_SUSPEND_CMD, err_code_ptr,
err_buf);
#ifdef AMD_DRIVER_FLASH_FOR_SW
int_enable(cpsr);
#endif
return(status);
}
/******************************************************************************
*
* lld_EraseResumeCmd - Writes Resume Command to Flash
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:
* errors generated by HAL functions
*/
int lld_EraseResumeCmd
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
int buffer_size_in_bytes;
DEVSTATUS dev_status = dev_status_unknown;
FLASHDATA actual_data = 0;
uint32 cpsr;
/*
* Reserved for Future Use.
* Trivial assignment to prevent compiler warnings
*/
data_cfg = data_cfg;
#ifdef MIRRORBIT_DEVICE
#ifdef USING_ERASE_SUSPEND
/* For MirrorBit, before the resume can begin, we must */
/* flush the write buffer by programming a maximum */
/* buffer full of ones (0xFF, 0xFFFF or 0xFFFFFFFF) */
/* to a non-erase suspended sector. We leave the */
/* decision for the address of the non-erase suspended */
/* sector to you. We have used a macro to define the */
/* address, but you may need to do it using a variable */
/* if you cannot guarantee a single sector as never */
/* being erase suspended. */
/* When complete, issue the reset command to go back */
/* to the suspended read array mode. */
/* determine buffer size */
switch (data_cfg)
{
case X8_AS_X8:
case X8X16_AS_X8:
case X16_AS_X16:
case X8X16_AS_X16:
buffer_size_in_bytes = 32;
break;
case X8_AS_X16:
case X16_AS_X32:
case X8X16_AS_X32:
case X16X32_AS_X16:
case X16X32_AS_X32:
buffer_size_in_bytes = 64;
break;
case X8_AS_X32:
buffer_size_in_bytes = 128;
break;
default:
*err_code_ptr = LLD_E_INVALID_PARAMETER;
MY_SPRINTF(err_buf, "Invalid data config.\n");
status = LLD_ERROR;
return(status);
}
#define E3_BASE_ADDRESS 0
#define E3_OFFSET 0
status = lld_WrtBufPgmOpWithoutPoll(E3_BASE_ADDRESS, E3_OFFSET, data_cfg, buffer_size_in_bytes, ff, err_code_ptr, err_buf);
do
{
status = lld_StatusGet(base_addr, offset, data_cfg, &dev_status, &actual_data, LLD_P_POLL_RESUME, err_code_ptr, err_buf);
} while (dev_status == dev_busy);
if(status != LLD_OK) return(status);
status = lld_ResetCmd(base_addr, offset, data_cfg, err_code_ptr, err_buf);
if(status != LLD_OK) return(status);
#endif
#endif
/* Write Resume Command */
// NOTEME: See note in erase_suspend()... We assume that the erase
// resume is safe even though the erase IS actually already finished.
#ifdef AMD_DRIVER_FLASH_FOR_SW
cpsr = int_disable();
dev.state = DEV_ERASE;
#endif
status = HalWrite(base_addr + offset, NOR_RESUME_CMD, err_code_ptr,
err_buf);
#ifdef AMD_DRIVER_FLASH_FOR_SW
int_enable(cpsr);
#endif
return(status);
}
/******************************************************************************
*
* lld_ProgramResumeCmd - Writes Resume Command to Flash
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:
* errors generated by HAL functions
*/
int lld_ProgramResumeCmd
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
/*
* Reserved for Future Use.
* Trivial assignment to prevent compiler warnings
*/
data_cfg = data_cfg;
/* Write Resume Command */
status = HalWrite(base_addr + offset, NOR_RESUME_CMD, err_code_ptr,
err_buf);
return(status);
}
/******************************************************************************
*
* lld_CfiEnterCmd - Writes CFI Entry Command Sequence to Flash
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:
* errors from UnlockAddrsInit
* errors generated by HAL functions
*/
int lld_CfiEnterCmd
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
DWORD ulock_addr1;
DWORD ulock_addr2;
/*
* Reserved for Future Use.
* Trivial assignment to prevent compiler warnings
*/
offset = offset;
status = UnlockAddrsInit(&ulock_addr1, &ulock_addr2, data_cfg,
err_code_ptr, err_buf);
if(status != LLD_OK)
return(status);
status = HalWrite(base_addr + ulock_addr1, NOR_CFI_QUERY_CMD,
err_code_ptr, err_buf);
return(status);
}
/******************************************************************************
*
* lld_CfiExitCmd - Writes Cfi Exit Command Sequence to Flash
*
* This function resets the device out of CFI Query mode.
* This is a "wrapper function" to provide "Enter/Exit" symmetry in
* higher software layers.
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:
* errors from UnlockAddrsInit
* errors generated by HAL functions
*/
int lld_CfiExitCmd
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
status = lld_ResetCmd(base_addr, offset, data_cfg, err_code_ptr, err_buf);
return(status);
}
/******************************************************************************
*
* lld_Poll - Polls flash device for embedded operation completion
*
* Function polls the Flash device to determine when an embedded
* operation has finished.
* Function performs a verify on the polling address if the device
* returns from status routine in a non-busy/non-error state.
* Function relies on status function to update the <err_code_ptr>
* <err_buf> contents in "error" states.
*
* <polling_type> variable is used to determine type of polling to perform.
* This variable tells the status routine what mode the device is in.
* Future versions of this function will also use the <polling_type>
* variable to properly initialize and implement watchdog timers.
* Acceptable values for <polling_type> are:
* LLD_P_POLL_PGM
* LLD_P_POLL_WRT_BUF_PGM
* LLD_P_POLL_SEC_ERS
* LLD_P_POLL_CHIP_ERS
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:
*
* errors from UnlockAddrsInit
* errors generated by HAL functions
*/
int lld_Poll
(
ADDRESS base_addr, /* device base address in system */
DWORD offset, /* address offset from base address */
PARAM data_cfg, /* flash data width and # of devices */
FLASHDATA *exp_data_ptr, /* expect data */
FLASHDATA *act_data_ptr, /* actual data */
PARAM polling_type, /* type of polling to perform */
PARAM *err_code_ptr, /* variable to store error code */
char *err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
DEVSTATUS dev_status = dev_status_unknown;
#ifdef WAIT_4us_FOR_DATA_POLLING_BITS_TO_BECOME_ACTIVE
DWORD volatile i;
if((polling_type == LLD_P_POLL_PGM) || (polling_type == LLD_P_POLL_WRT_BUF_PGM))
{
for(i = 0; i < DELAY_4us; i++)
{
i = i;
}
}
#endif
/* Perform Polling Operation */
do
{
status = lld_StatusGet(base_addr, offset, data_cfg, &dev_status,
act_data_ptr, polling_type, err_code_ptr, err_buf);
if(status != LLD_OK)
return status;
}
while(dev_status == dev_busy);
/*
* if device returns status other than "not busy" then we
* have a polling error state.
* Note: assumes the "while dev_busy" test above does not change!
*
* if device was "not busy" then verify polling location.
*/
if(dev_status != dev_not_busy)
{
if(*err_code_ptr == LLD_E_WRITE_BUFFER_LOAD_ERROR)
{
lld_WrtToBufAbortResetCmd(base_addr, offset, data_cfg,
err_code_ptr, err_buf);
}
else
{
/* Issue software reset. */
lld_ResetCmd(base_addr, offset, data_cfg,
err_code_ptr, err_buf);
}
/* indicate to caller that there was an error */
status = LLD_ERROR;
}
else
{
/* device steady state, see if location passed */
FLASHDATA read_mask = 0;
/* Initialize Mask */
status = ReadMaskInit(&read_mask, data_cfg, err_code_ptr, err_buf);
if(status != LLD_OK)
return(status);
/* Check that polling location verifies correctly */
if((*exp_data_ptr & read_mask) == (*act_data_ptr & read_mask))
{
status = LLD_OK;
}
else
{
*err_code_ptr = LLD_E_VERIFY_ERROR;
MY_SPRINTF(err_buf, "Verify Error.\n");
status = LLD_ERROR;
}
}
return(status);
}
/*****************************************************************************/
int DeviceMultiplierInit
(
FLASHDATA* device_multiplier_ptr, /* variable to store multiplier */
PARAM data_cfg, /* data width, # of devices */
PARAM* err_code_ptr, /* variable to store error code */
char* err_buf /* buffer to store error text */
)
{
int status = LLD_OK;
/* force single return control path */
for (;;)
{
/* if not in a multi-device configuration, assign default */
if (!(data_cfg & MULTI_DEVICE_CFG))
{
*device_multiplier_ptr = 0x01;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -