mirror of
https://github.com/eclipse-threadx/levelx.git
synced 2026-09-14 20:48:51 +08:00
Update on 18 Jan 2023. Expand to see details.
22299de Remove internal deprecated files. 2b9332f Fix ECC issues by new NAND logic 6a5eda1 Add a notice for not released file. b756fb0 Upgrade to the latest Container Images.
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** LevelX Component */
|
||||
/** */
|
||||
/** NAND 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_nand_flash_data_page_copy PORTABLE C */
|
||||
/* 6.x */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Xiuwen Cai, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function copies logical sectors into new block. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* nand_flash NAND flash instance */
|
||||
/* logical_sector Logical sector number */
|
||||
/* source_block Source block number */
|
||||
/* src_block_status Source block status */
|
||||
/* destination_block Destination block number */
|
||||
/* dest_block_status_ptr Pointer to destination block */
|
||||
/* status */
|
||||
/* sectors Number of sectors to copy */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* return status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* lx_nand_flash_driver_pages_copy Driver pages copy */
|
||||
/* lx_nand_flash_driver_pages_read Driver pages read */
|
||||
/* _lx_nand_flash_system_error Internal system error handler */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Internal LevelX */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* xx-xx-xxxx Xiuwen Cai Initial Version 6.x */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _lx_nand_flash_data_page_copy(LX_NAND_FLASH* nand_flash, ULONG logical_sector, ULONG source_block, USHORT src_block_status,
|
||||
ULONG destination_block, USHORT* dest_block_status_ptr, ULONG sectors)
|
||||
{
|
||||
|
||||
LONG source_page;
|
||||
ULONG destination_page;
|
||||
UINT status = LX_SUCCESS;
|
||||
UINT i;
|
||||
ULONG available_pages;
|
||||
ULONG spare_data1;
|
||||
UCHAR *spare_buffer_ptr;
|
||||
ULONG dest_block_status;
|
||||
ULONG number_of_pages;
|
||||
|
||||
|
||||
/* Get the destination block status. */
|
||||
dest_block_status = *dest_block_status_ptr;
|
||||
|
||||
/* Get the current page number of the destination block. */
|
||||
destination_page = dest_block_status & LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK;
|
||||
|
||||
/* Get the available pages in the source block. */
|
||||
available_pages = (src_block_status & LX_NAND_BLOCK_STATUS_FULL) ? (nand_flash -> lx_nand_flash_pages_per_block) : (src_block_status & LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK);
|
||||
|
||||
/* Check if pages in the source block are sequential. */
|
||||
if (src_block_status & LX_NAND_BLOCK_STATUS_NON_SEQUENTIAL)
|
||||
{
|
||||
|
||||
/* Get buffer for spare data. */
|
||||
spare_buffer_ptr = nand_flash -> lx_nand_flash_page_buffer + nand_flash -> lx_nand_flash_bytes_per_page;
|
||||
|
||||
/* Loop to copy the data. */
|
||||
for (i = 0; i < sectors; i++)
|
||||
{
|
||||
|
||||
/* Loop to search the page. */
|
||||
for (source_page = (LONG)(available_pages - 1); source_page >= 0; source_page--)
|
||||
{
|
||||
|
||||
/* Read one page. */
|
||||
status = (nand_flash -> lx_nand_flash_driver_pages_read)(source_block, (ULONG)source_page, LX_NULL, spare_buffer_ptr, 1);
|
||||
|
||||
/* Check for an error from flash driver. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Call system error handler. */
|
||||
_lx_nand_flash_system_error(nand_flash, status, source_block, 0);
|
||||
|
||||
/* Return an error. */
|
||||
return(LX_ERROR);
|
||||
}
|
||||
|
||||
/* Get the spare data. */
|
||||
spare_data1 = LX_UTILITY_LONG_GET(&spare_buffer_ptr[nand_flash -> lx_nand_flash_spare_data1_offset]);
|
||||
|
||||
/* Check the address match. */
|
||||
if ((spare_data1 & LX_NAND_PAGE_TYPE_USER_DATA_MASK) == (logical_sector + i))
|
||||
{
|
||||
|
||||
/* Check if the page contains valid data. */
|
||||
if ((spare_data1 & (~LX_NAND_PAGE_TYPE_USER_DATA_MASK)) == (LX_NAND_PAGE_TYPE_USER_DATA))
|
||||
{
|
||||
|
||||
/* Call the driver to copy the page. */
|
||||
status = (nand_flash -> lx_nand_flash_driver_pages_copy)(source_block, (ULONG)source_page, destination_block, destination_page, 1, nand_flash -> lx_nand_flash_page_buffer);
|
||||
|
||||
/* Check for an error from flash driver. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Call system error handler. */
|
||||
_lx_nand_flash_system_error(nand_flash, status, source_block, 0);
|
||||
|
||||
/* Return an error. */
|
||||
return(LX_ERROR);
|
||||
}
|
||||
|
||||
/* Check if the pages in destination block is still sequential. */
|
||||
if ((destination_page) != (logical_sector + i % nand_flash -> lx_nand_flash_pages_per_block))
|
||||
{
|
||||
/* Mark the block status as non sequential. */
|
||||
dest_block_status |= LX_NAND_BLOCK_STATUS_NON_SEQUENTIAL;
|
||||
}
|
||||
|
||||
/* Update the available pages. */
|
||||
destination_page++;
|
||||
|
||||
/* Check if available page count reaches pages per block. */
|
||||
if (destination_page == nand_flash -> lx_nand_flash_pages_per_block)
|
||||
{
|
||||
|
||||
/* Set block full flag. */
|
||||
dest_block_status |= LX_NAND_BLOCK_STATUS_FULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Get the source page number. */
|
||||
source_page = (LONG)(logical_sector % nand_flash -> lx_nand_flash_pages_per_block);
|
||||
|
||||
/* Check if the page to copy is greater than the available pages. */
|
||||
number_of_pages = ((ULONG)source_page + sectors) > available_pages ?
|
||||
(available_pages > (ULONG)source_page ? available_pages - (ULONG)source_page : 0) : sectors;
|
||||
|
||||
/* Check if there is any pages to be copied. */
|
||||
if (number_of_pages)
|
||||
{
|
||||
|
||||
/* Call the driver to copy pages. */
|
||||
status = (nand_flash -> lx_nand_flash_driver_pages_copy)(source_block, (ULONG)source_page, destination_block, destination_page, number_of_pages, nand_flash -> lx_nand_flash_page_buffer);
|
||||
|
||||
/* Check for an error from flash driver. */
|
||||
if (status)
|
||||
{
|
||||
|
||||
/* Call system error handler. */
|
||||
_lx_nand_flash_system_error(nand_flash, status, source_block, 0);
|
||||
|
||||
/* Return an error. */
|
||||
return(LX_ERROR);
|
||||
}
|
||||
|
||||
/* Check if the pages in destination block is still sequential. */
|
||||
if ((ULONG)source_page != destination_page)
|
||||
{
|
||||
|
||||
/* Mark the block status as non sequential. */
|
||||
dest_block_status |= LX_NAND_BLOCK_STATUS_NON_SEQUENTIAL;
|
||||
}
|
||||
|
||||
/* Update the available pages. */
|
||||
destination_page += number_of_pages;
|
||||
|
||||
/* Check if available page count reaches pages per block. */
|
||||
if (destination_page == nand_flash -> lx_nand_flash_pages_per_block)
|
||||
{
|
||||
|
||||
/* Set block full flag. */
|
||||
dest_block_status |= LX_NAND_BLOCK_STATUS_FULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the block status. */
|
||||
*dest_block_status_ptr = (USHORT)(destination_page | (dest_block_status & ~LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK));
|
||||
|
||||
/* Return status. */
|
||||
return(status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user