RTEMS
5.0.0
|
NAND MLC Controller. More...
Files | |
file | nand-mlc.h |
NAND MLC controller API. | |
file | nand-mlc-erase-block-safe.c |
lpc32xx_mlc_erase_block_safe(), lpc32xx_mlc_erase_block_safe_3(), and lpc32xx_mlc_zero_block() implementation. | |
file | nand-mlc-read-blocks.c |
lpc32xx_mlc_read_blocks() implementation. | |
file | nand-mlc-write-blocks.c |
lpc32xx_mlc_write_blocks() implementation. | |
file | nand-mlc.c |
NAND MLC controller implementation. | |
Data Structures | |
struct | lpc32xx_mlc_config |
MLC NAND controller configuration. More... | |
Macros | |
#define | MLC_SMALL_PAGES 0x1U |
Selects small pages (512 Bytes user data and 16 Bytes spare data) or large pages (2048 Bytes user data and 64 Bytes spare data) if not set. | |
#define | MLC_MANY_ADDRESS_CYCLES 0x2U |
#define | MLC_NORMAL_BLOCKS 0x4U |
Selects 64 pages per block or 128 pages per block if not set. More... | |
#define | MLC_IO_WIDTH_16_BIT 0x8U |
Selects 16-bit IO width or 8-bit IO width if not set. | |
Typedefs | |
typedef bool(* | lpc32xx_mlc_read_process) (void *process_arg, uint32_t page_index, uint32_t page_size, uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT], uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]) |
Read blocks process function type. More... | |
Functions | |
void | lpc32xx_mlc_init (const lpc32xx_mlc_config *cfg) |
Initializes the MLC NAND controller according to cfg. | |
uint32_t | lpc32xx_mlc_page_size (void) |
uint32_t | lpc32xx_mlc_pages_per_block (void) |
uint32_t | lpc32xx_mlc_block_count (void) |
uint32_t | lpc32xx_mlc_io_width (void) |
void | lpc32xx_mlc_write_protection (uint32_t page_index_low, uint32_t page_index_high) |
void | lpc32xx_mlc_read_id (uint8_t *id, size_t n) |
rtems_status_code | lpc32xx_mlc_read_page (uint32_t page_index, void *data, void *spare, uint32_t *symbol_error_count) |
Reads the page with index page_index. More... | |
rtems_status_code | lpc32xx_mlc_is_valid_block (uint32_t block_index) |
Checks if the block with index block_index is valid. More... | |
rtems_status_code | lpc32xx_mlc_erase_block (uint32_t block_index) |
Erases the block with index block_index. More... | |
rtems_status_code | lpc32xx_mlc_erase_block_safe (uint32_t block_index) |
Erases the block with index block_index. More... | |
rtems_status_code | lpc32xx_mlc_erase_block_safe_3 (uint32_t block_index, uint32_t page_begin, uint32_t page_end) |
Erases the block with index block_index. More... | |
void | lpc32xx_mlc_zero_pages (uint32_t page_begin, uint32_t page_end) |
Writes zero values to the pages specified by page_begin and page_end. More... | |
rtems_status_code | lpc32xx_mlc_write_page_with_ecc (uint32_t page_index, const void *data, const void *spare) |
Writes the page with index page_index. More... | |
rtems_status_code | lpc32xx_mlc_write_blocks (uint32_t block_begin, uint32_t block_end, const void *src, size_t src_size, uint32_t page_buffer [MLC_LARGE_DATA_WORD_COUNT]) |
Writes src_size Bytes from src to the flash area specified by block_begin and block_end. More... | |
rtems_status_code | lpc32xx_mlc_read_blocks (uint32_t block_begin, uint32_t block_end, lpc32xx_mlc_read_process process, void *process_arg, uint32_t page_buffer_0 [MLC_LARGE_DATA_WORD_COUNT], uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT]) |
Reads the pages of block block_begin up to and excluding block_end. More... | |
MLC NAND Lock Protection Register (MLC_LOCK_PR) | |
#define | MLC_UNLOCK_PROT 0xa25e |
MLC NAND Auto Encode Register (MLC_ECC_AUTO_ENC) | |
#define | MLC_ECC_AUTO_ENC_PROGRAM BSP_BIT32(8) |
NAND Status Register | |
#define | NAND_STATUS_ERROR (1U << 0) |
#define | NAND_STATUS_READY (1U << 6) |
#define | NAND_STATUS_NOT_PROTECTED (1U << 7) |
NAND MLC Controller.
Timing constraints:
Known flash layouts (Format: SP = small pages, LP = large pages / address cycles / pages per block):
#define MLC_MANY_ADDRESS_CYCLES 0x2U |
Selects 4/5 address cycles for small/large pages or 3/4 address cycles if not set.
#define MLC_NORMAL_BLOCKS 0x4U |
Selects 64 pages per block or 128 pages per block if not set.
This flag is only valid for large pages.
typedef bool(* lpc32xx_mlc_read_process) (void *process_arg, uint32_t page_index, uint32_t page_size, uint32_t page_data [MLC_LARGE_DATA_WORD_COUNT], uint32_t page_spare [MLC_LARGE_SPARE_WORD_COUNT]) |
Read blocks process function type.
false | Continue processing. |
true | Stop processing. |
rtems_status_code lpc32xx_mlc_erase_block | ( | uint32_t | block_index | ) |
Erases the block with index block_index.
RTEMS_SUCCESSFUL | Successful operation. |
RTEMS_INVALID_ID | Invalid block_index value. |
RTEMS_UNSATISFIED | Erase error. |
rtems_status_code lpc32xx_mlc_erase_block_safe | ( | uint32_t | block_index | ) |
Erases the block with index block_index.
In case of an erase error all pages and the spare areas of this block are programmed with zero values. This will hopefully mark the block as bad.
RTEMS_SUCCESSFUL | Successful operation. |
RTEMS_INCORRECT_STATE | The block is bad. |
RTEMS_INVALID_ID | Invalid block_index value. |
RTEMS_UNSATISFIED | Erase error. |
RTEMS_NOT_IMPLEMENTED | No implementation available for this flash type. |
rtems_status_code lpc32xx_mlc_erase_block_safe_3 | ( | uint32_t | block_index, |
uint32_t | page_begin, | ||
uint32_t | page_end | ||
) |
Erases the block with index block_index.
Variant of lpc32xx_mlc_erase_block_safe() with more parameters for efficiency reasons. The page_begin must be the index of the first page of the block. The page_end must be the page index of the last page of the block plus one.
rtems_status_code lpc32xx_mlc_is_valid_block | ( | uint32_t | block_index | ) |
Checks if the block with index block_index is valid.
The initial valid block information of the manufacturer will be used. Unfortunately there seems to be no standard for this. A block will be considered as bad if the first or second page of this block does not contain 0xff at the 6th byte of the spare area. This should work for flashes with small pages and a 8-bit IO width.
RTEMS_SUCCESSFUL | The block is valid. |
RTEMS_INVALID_ID | Invalid block_index value. |
RTEMS_IO_ERROR | Uncorrectable bit error. |
RTEMS_INCORRECT_STATE | The block is bad. |
RTEMS_NOT_IMPLEMENTED | No implementation available for this flash type. |
rtems_status_code lpc32xx_mlc_read_blocks | ( | uint32_t | block_begin, |
uint32_t | block_end, | ||
lpc32xx_mlc_read_process | process, | ||
void * | process_arg, | ||
uint32_t | page_buffer_0[MLC_LARGE_DATA_WORD_COUNT], | ||
uint32_t | page_buffer_1[MLC_LARGE_DATA_WORD_COUNT] | ||
) |
Reads the pages of block block_begin up to and excluding block_end.
For each page process will be called with the process_arg parameter, the page_index, the page data and the page spare.
The page_buffer_0 and page_buffer_1 will be used as intermediate buffers.
rtems_status_code lpc32xx_mlc_read_page | ( | uint32_t | page_index, |
void * | data, | ||
void * | spare, | ||
uint32_t * | symbol_error_count | ||
) |
Reads the page with index page_index.
Bytes 6 to 15 of the spare area will contain the ECC.
If the read is successful, then the symbol_error_count will contain the number of detected symbol errors (0, 1, 2, 3, or 4), else the value will be 0xffffffff. The symbol_error_count pointer may be NULL
.
RTEMS_SUCCESSFUL | Successful operation. |
RTEMS_INVALID_ID | Invalid page_index value. |
RTEMS_IO_ERROR | Uncorrectable bit error. |
rtems_status_code lpc32xx_mlc_write_blocks | ( | uint32_t | block_begin, |
uint32_t | block_end, | ||
const void * | src, | ||
size_t | src_size, | ||
uint32_t | page_buffer[MLC_LARGE_DATA_WORD_COUNT] | ||
) |
Writes src_size Bytes from src to the flash area specified by block_begin and block_end.
The page_buffer will be used as an intermediate buffer.
RTEMS_SUCCESSFUL | Successful operation. |
RTEMS_INVALID_ID | Invalid block_begin or block_end value. |
RTEMS_IO_ERROR | Too many bad blocks or source area too big. |
rtems_status_code lpc32xx_mlc_write_page_with_ecc | ( | uint32_t | page_index, |
const void * | data, | ||
const void * | spare | ||
) |
Writes the page with index page_index.
Only the bytes 0 to 5 of the spare area can be used for user data, the bytes 6 to 15 will be used for the automatically generated ECC.
RTEMS_SUCCESSFUL | Successful operation. |
RTEMS_INVALID_ID | Invalid page_index value. |
RTEMS_IO_ERROR | Write error. |
void lpc32xx_mlc_zero_pages | ( | uint32_t | page_begin, |
uint32_t | page_end | ||
) |
Writes zero values to the pages specified by page_begin and page_end.
The data and spare area are cleared to zero. This marks the pages as bad.