RTEMS  5.1
Files | Data Structures | Macros | Typedefs | Functions
NAND MLC Controller

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 Flash Dimensions

#define MLC_SMALL_PAGE_SIZE   528
 
#define MLC_SMALL_DATA_SIZE   512
 
#define MLC_SMALL_SPARE_SIZE   16
 
#define MLC_SMALL_USER_SPARE_SIZE   6
 
#define MLC_SMALL_ECC_SPARE_SIZE   10
 
#define MLC_SMALL_DATA_WORD_COUNT   (MLC_SMALL_DATA_SIZE / 4)
 
#define MLC_SMALL_SPARE_WORD_COUNT   (MLC_SMALL_SPARE_SIZE / 4)
 
#define MLC_SMALL_PAGES_PER_LARGE_PAGE   4
 
#define MLC_LARGE_PAGE_SIZE   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_PAGE_SIZE)
 
#define MLC_LARGE_DATA_SIZE   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_DATA_SIZE)
 
#define MLC_LARGE_SPARE_SIZE   (MLC_SMALL_PAGES_PER_LARGE_PAGE * MLC_SMALL_SPARE_SIZE)
 
#define MLC_LARGE_DATA_WORD_COUNT   (MLC_LARGE_DATA_SIZE / 4)
 
#define MLC_LARGE_SPARE_WORD_COUNT   (MLC_LARGE_SPARE_SIZE / 4)
 

NAND Flash Clock Control Register (FLASHCLK_CTRL)

#define FLASHCLK_IRQ_MLC   BSP_BIT32(5)
 
#define FLASHCLK_MLC_DMA_RNB   BSP_BIT32(4)
 
#define FLASHCLK_MLC_DMA_INT   BSP_BIT32(3)
 
#define FLASHCLK_SELECT_SLC   BSP_BIT32(2)
 
#define FLASHCLK_MLC_CLK_ENABLE   BSP_BIT32(1)
 
#define FLASHCLK_SLC_CLK_ENABLE   BSP_BIT32(0)
 

MLC NAND Timing Register (MLC_TIME_REG)

#define MLC_TIME_WR_LOW(val)   BSP_FLD32(val, 0, 3)
 
#define MLC_TIME_WR_HIGH(val)   BSP_FLD32(val, 4, 7)
 
#define MLC_TIME_RD_LOW(val)   BSP_FLD32(val, 8, 11)
 
#define MLC_TIME_RD_HIGH(val)   BSP_FLD32(val, 12, 15)
 
#define MLC_TIME_NAND_TA(val)   BSP_FLD32(val, 16, 18)
 
#define MLC_TIME_BUSY_DELAY(val)   BSP_FLD32(val, 19, 23)
 
#define MLC_TIME_TCEA_DELAY(val)   BSP_FLD32(val, 24, 25)
 

MLC NAND Lock Protection Register (MLC_LOCK_PR)

#define MLC_UNLOCK_PROT   0xa25e
 

MLC NAND Status Register (MLC_ISR)

#define MLC_ISR_DECODER_FAILURE   BSP_BIT32(6)
 
#define MLC_ISR_SYMBOL_ERRORS(reg)   BSP_FLD32GET(reg, 4, 5)
 
#define MLC_ISR_ERRORS_DETECTED   BSP_BIT32(3)
 
#define MLC_ISR_ECC_READY   BSP_BIT32(2)
 
#define MLC_ISR_CONTROLLER_READY   BSP_BIT32(1)
 
#define MLC_ISR_NAND_READY   BSP_BIT32(0)
 

MLC NAND Controller Configuration Register (MLC_ICR)

#define MLC_ICR_SOFT_WRITE_PROT   BSP_BIT32(3)
 
#define MLC_ICR_LARGE_PAGES   BSP_BIT32(2)
 
#define MLC_ICR_ADDR_WORD_COUNT_4_5   BSP_BIT32(1)
 
#define MLC_ICR_IO_BUS_16   BSP_BIT32(0)
 

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)
 

Detailed Description

NAND MLC Controller.

Timing constraints:

  1. (WR_LOW + 1) / HCLK >= tWP
  2. (WR_HIGH - WR_LOW) / HCLK >= tWH
  3. (WR_LOW + 1) / HCLK + (WR_HIGH - WR_LOW) / HCLK >= tWC
  4. (RD_LOW + 1) / HCLK >= tRP
  5. (RD_LOW + 1) / HCLK >= tREA + tSU
  6. (RD_HIGH - RD_LOW) / HCLK >= tREH
  7. (RD_LOW + 1) / HCLK + (RD_HIGH - RD_LOW) / HCLK >= tRC
  8. (RD_HIGH - RD_LOW) / HCLK + NAND_TA / HCLK >= tRHZ
  9. BUSY_DELAY / HCLK >= max(tWB, tRB)
  10. TCEA_DELAY / HCLK >= tCEA - tREA

Known flash layouts (Format: SP = small pages, LP = large pages / address cycles / pages per block):

  1. SP/3/32
  2. SP/4/32
  3. LP/4/64
  4. LP/5/64
  5. LP/5/128

Macro Definition Documentation

◆ MLC_MANY_ADDRESS_CYCLES

#define MLC_MANY_ADDRESS_CYCLES   0x2U

@Brief Selects 4/5 address cycles for small/large pages or 3/4 address cycles if not set.

◆ MLC_NORMAL_BLOCKS

#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 Documentation

◆ lpc32xx_mlc_read_process

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.

See also
lpc32xx_mlc_read_blocks().
Return values
falseContinue processing.
trueStop processing.

Function Documentation

◆ lpc32xx_mlc_erase_block()

rtems_status_code lpc32xx_mlc_erase_block ( uint32_t  block_index)

Erases the block with index block_index.

Return values
RTEMS_SUCCESSFULSuccessful operation.
RTEMS_INVALID_IDInvalid block_index value.
RTEMS_UNSATISFIEDErase error.

◆ lpc32xx_mlc_erase_block_safe()

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.

Return values
RTEMS_SUCCESSFULSuccessful operation.
RTEMS_INCORRECT_STATEThe block is bad.
RTEMS_INVALID_IDInvalid block_index value.
RTEMS_UNSATISFIEDErase error.
RTEMS_NOT_IMPLEMENTEDNo implementation available for this flash type.

◆ lpc32xx_mlc_erase_block_safe_3()

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.

◆ lpc32xx_mlc_is_valid_block()

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.

Return values
RTEMS_SUCCESSFULThe block is valid.
RTEMS_INVALID_IDInvalid block_index value.
RTEMS_IO_ERRORUncorrectable bit error.
RTEMS_INCORRECT_STATEThe block is bad.
RTEMS_NOT_IMPLEMENTEDNo implementation available for this flash type.

◆ lpc32xx_mlc_read_blocks()

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.

◆ lpc32xx_mlc_read_page()

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.

Return values
RTEMS_SUCCESSFULSuccessful operation.
RTEMS_INVALID_IDInvalid page_index value.
RTEMS_IO_ERRORUncorrectable bit error.

◆ lpc32xx_mlc_write_blocks()

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.

Return values
RTEMS_SUCCESSFULSuccessful operation.
RTEMS_INVALID_IDInvalid block_begin or block_end value.
RTEMS_IO_ERRORToo many bad blocks or source area too big.

◆ lpc32xx_mlc_write_page_with_ecc()

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.

Return values
RTEMS_SUCCESSFULSuccessful operation.
RTEMS_INVALID_IDInvalid page_index value.
RTEMS_IO_ERRORWrite error.

◆ lpc32xx_mlc_zero_pages()

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.