Files
levelx/common/src/lx_nor_flash_format.c
T

168 lines
7.1 KiB
C

/***************************************************************************
* Copyright (c) 2025 Microsoft Corporation
* Copyright (c) 2025 STmicroelectronics
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** LevelX Component */
/** */
/** NOR Flash */
/** */
/**************************************************************************/
/**************************************************************************/
#define LX_SOURCE_CODE
/* Disable ThreadX error checking. */
#ifndef LX_DISABLE_ERROR_CHECKING
#define LX_DISABLE_ERROR_CHECKING
#endif
/* Include necessary system files. */
#include "lx_api.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _lx_nor_flash_format PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function opens a NOR flash instance then erases all the non */
/* erased blocks, then writes the erase count */
/* */
/* INPUT */
/* */
/* nor_flash NOR flash instance */
/* name Name of NOR flash instance */
/* nor_driver_initialize Driver initialize */
/* nor_driver_info_ptr Drivier user data pointer */
/* */
/* OUTPUT */
/* */
/* return status */
/* */
/* CALLS */
/* */
/* (nor_driver_initialize) Driver initialize */
/* _lx_nor_flash_driver_read Driver read */
/* _lx_nor_flash_driver_write Driver write */
/* (lx_nor_flash_driver_block_erased_verify) */
/* NOR flash verify block erased */
/* _lx_nor_flash_driver_block_erase Driver block erase */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/**************************************************************************/
UINT _lx_nor_flash_format(LX_NOR_FLASH *nor_flash, CHAR *name, UINT (*nor_driver_initialize)(LX_NOR_FLASH *), VOID *nor_driver_info_ptr)
{
ULONG l;
UINT status;
ULONG block_word;
ULONG *block_word_ptr;
LX_PARAMETER_NOT_USED(name);
/* Clear the NOR flash control block. User extension is not cleared. */
LX_MEMSET(nor_flash, 0, (ULONG)((UCHAR*)&(nor_flash -> lx_nor_flash_open_previous) - (UCHAR*)nor_flash) + sizeof(nor_flash -> lx_nor_flash_open_previous));
nor_flash -> lx_nor_flash_driver_info_ptr = nor_driver_info_ptr;
/* Call the flash driver's initialization function. */
(nor_driver_initialize)(nor_flash);
#ifndef LX_DIRECT_READ
/* Determine if the driver supplied a RAM buffer for reading the NOR sector if direct read is not
supported. */
if (nor_flash -> lx_nor_flash_sector_buffer == LX_NULL)
{
/* Return an error. */
return(LX_NO_MEMORY);
}
#endif
for (l = 0; l < nor_flash -> lx_nor_flash_total_blocks; l++)
{
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
/* Check that the block is already erased */
status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(nor_flash, l);
#else
status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(l);
#endif
/* the block is not erased, thus make sure to erase it */
if (status)
{
/* the max erase count is not needed just pass the value 0 */
status = _lx_nor_flash_driver_block_erase(nor_flash, l, 0);
/* Check for an error from flash driver */
if (status)
{
/* Call system error handler. */
_lx_nor_flash_system_error(nor_flash, status);
/* Return an error. */
return(LX_ERROR);
}
/* check that the sector was correctly erased */
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(nor_flash, l);
#else
status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(l);
#endif
if (status)
{
/* Call system error handler. */
_lx_nor_flash_system_error(nor_flash, status);
/* Return an error. */
return(LX_ERROR);
}
}
/* Setup the block word pointer to the first word of the first block */
block_word_ptr = nor_flash -> lx_nor_flash_base_address + l * nor_flash -> lx_nor_flash_words_per_block;
/* Setup the initial erase_count to 1 and mark the block as erased.
* When the lx_nor_flash_open() gets called only the erase count will be kept.
*/
block_word = ((ULONG)1 | LX_BLOCK_ERASED);
status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr, &block_word, 1);
if (status)
{
/* Call system error handler. */
_lx_nor_flash_system_error(nor_flash, status);
/* Return an error. */
return(LX_ERROR);
}
}
return(LX_SUCCESS);
}