Micron MT29F NAND driver

The READ PARAMETER PAGE (ECh) command is used to read the ONFI parameter page programmed into the target. This command is accepted by the target only when all die (LUNs) on the target are idle.

Parameters:
[out]flash_width*ppage: a filled structure with ONFI paramter page
Returns:
Return code
Return values:
NAND_SUCCESS
NAND_TIMEOUT
Pseudo Code Steps
  1. Send parameter page command (ECh)
  2. Send address for parameter page (00h)
  3. Wait tWB nanoseconds before read
  4. Wait for ready
  5. Read the content of the parameter page
  6. Parse the parameter page buffer and fill the data structure

Definition at line 249 of file nand_MT29F_lld.c.

References __as_string(), __as_uint16(), __as_uint32(), __wait_for_ready(), ADDR_PARAM_PAGE, parameter_page_t::bit_per_cell, parameter_page_t::block_endurance, parameter_page_t::blocks_per_lun, CMD_READ_PARAM_PAGE, parameter_page_t::command, parameter_page_t::data_bytes_per_page, parameter_page_t::data_bytes_per_partial_page, parameter_page_t::date_code, parameter_page_t::feature, parameter_page_t::guarenteed_valid_blocks, parameter_page_t::interleaved_op_attr, parameter_page_t::jedec_id, parameter_page_t::luns_per_ce, parameter_page_t::manufacturer, parameter_page_t::max_bad_blocks_per_lun, parameter_page_t::model, NAND_BAD_PARAMETER_PAGE, NAND_SUCCESS, parameter_page_t::num_addr_cycles, parameter_page_t::num_ECC_bits_correctable, parameter_page_t::num_interleaved_addr_bits, NUM_OF_PPAGE_BYTES, parameter_page_t::num_programs_per_page, parameter_page_t::pages_per_block, parameter_page_t::partial_prog_attr, PLATFORM_Close(), PLATFORM_Open(), PLATFORM_ReadData(), PLATFORM_SendAddr(), PLATFORM_SendCmd(), PLATFORM_Wait(), parameter_page_t::rev_num, parameter_page_t::signature, parameter_page_t::spare_bytes_per_page, parameter_page_t::spare_bytes_per_partial_page, and TIME_WB.

                                                   {
   MT_uint8 rbuf[NUM_OF_PPAGE_BYTES];
   MT_uint8 ret;
   MT_uint32 i;

   /* init board transfer */
    PLATFORM_Open();

    /* send command and/or address */
    PLATFORM_SendCmd(CMD_READ_PARAM_PAGE);
    PLATFORM_SendAddr(ADDR_PARAM_PAGE);

    /* wait (see datasheet for details) */
    PLATFORM_Wait(TIME_WB);
    ret = __wait_for_ready();

    /* return if timeout */
    if (NAND_SUCCESS != ret)
      return ret;

    /* read output */
    for(i=0; i<NUM_OF_PPAGE_BYTES; i++)
      rbuf[i] = PLATFORM_ReadData();

    /* close board transfer */
    PLATFORM_Close();

    /*
     * Fill the parameter page data structure in the right way
     */

    /* Parameter page signature (ONFI) */
   __as_string(rbuf, ppage->signature, 0, 3);

   /* check if the buffer contains a valid ONFI parameter page */
   if (strcmp(ppage->signature, "ONFI"))
      return NAND_BAD_PARAMETER_PAGE;

   /* Revision number */
   ppage->rev_num = __as_uint16(rbuf[4], rbuf[5]);

   /* Features supported */
   ppage->feature = __as_uint16(rbuf[6], rbuf[7]);

   /* Optional commands supported */
   ppage->command = __as_uint16(rbuf[8], rbuf[9]);

   /* Device manufacturer */
   __as_string(rbuf, ppage->manufacturer, 32, 43);

   /* Device part number */
   __as_string(rbuf, ppage->model, 44, 63);

   /* Manufacturer ID (Micron = 2Ch) */
   ppage->jedec_id = rbuf[64];

   /* Date code */
   ppage->date_code = __as_uint16(rbuf[65], rbuf[66]);

   /* Number of data bytes per page */
   ppage->data_bytes_per_page = __as_uint32(rbuf[80], rbuf[81], rbuf[82], rbuf[83]);

   /* Number of spare bytes per page */
   ppage->spare_bytes_per_page = __as_uint16(rbuf[84], rbuf[85]);

   /* Number of data bytes per partial page */
   ppage->data_bytes_per_partial_page = __as_uint32(rbuf[86], rbuf[87], rbuf[88], rbuf[89]);

   /* Number of spare bytes per partial page */
   ppage->spare_bytes_per_partial_page = __as_uint16(rbuf[90], rbuf[91]);

   /* Number of pages per block */
   ppage->pages_per_block = __as_uint32(rbuf[92], rbuf[93], rbuf[94], rbuf[95]);

   /* Number of blocks per unit */
   ppage->blocks_per_lun = __as_uint32(rbuf[96], rbuf[97], rbuf[98], rbuf[99]);

   /* Number of logical units (LUN) per chip enable */
   ppage->luns_per_ce = rbuf[100];

   /* Number of address cycles */
   ppage->num_addr_cycles = rbuf[101];

   /* Number of bits per cell (1 = SLC; >1= MLC) */
   ppage->bit_per_cell = rbuf[102];

   /* Bad blocks maximum per unit */
   ppage->max_bad_blocks_per_lun = __as_uint16(rbuf[103], rbuf[104]);

   /* Block endurance */
   ppage->block_endurance = __as_uint16(rbuf[105], rbuf[106]);

   /* Guaranteed valid blocks at beginning of target */
   ppage->guarenteed_valid_blocks = rbuf[107];

   /* Block endurance for guaranteed valid blocks */
   ppage->guarenteed_valid_blocks = __as_uint16(rbuf[108], rbuf[109]);

   /* Number of programs per page */
   ppage->num_programs_per_page = rbuf[110];

   /* Partial programming attributes */
   ppage->partial_prog_attr = rbuf[111];

   /* Number of bits ECC bits */
   ppage->num_ECC_bits_correctable = rbuf[112];

   /* Number of interleaved address bits */
   ppage->num_interleaved_addr_bits = rbuf[113];

   /* Interleaved operation attributes */
   ppage->interleaved_op_attr = rbuf[114];

    return ret;
}