Micron MT29F NAND driver
MT_uint8 NAND_Copy_Back ( nand_addr_t  src_addr,
nand_addr_t  dest_addr 
)

The copy back function allow to copy a content of a page in another page without any byte is transferred to the host. The destination page must be erased.

Parameters:
[in]nand_addr_tsrc_addr: address of source page
[in]nand_addr_tdest_addr: source of destination page
Returns:
Return code
Return values:
DRIVER_STATUS_NOT_INITIALIZED
NAND_INVALID_NAND_ADDRESS
NAND_PROGRAM_FAILED_WRITE_PROTECT
NAND_PROGRAM_FAILED
NAND_SUCCESS
NAND_TIMEOUT
Pseudo Code Steps
  1. Send read command (00h)
  2. Send source address (5 cycles)
  3. Send read for internal data move command (35h)
  4. Wait for ready
  5. Send program for internal data move command (85h)
  6. Send destination address (5 cycles)
  7. Send confirm command (10h)
  8. Wait for ready
  9. Check status register value

Definition at line 1090 of file nand_MT29F_lld.c.

References __build_cycle_addr(), __compare_addr(), __is_valid_addr(), __wait_for_ready(), nand_address_t::block, CMD_PAGE_PROGRAM_CONFIRM, CMD_PROGRAM_INTERNAL_DATA_MOVE, CMD_READ_INTERNAL_DATA_MOVE, CMD_READ_MODE, nand_address_t::column, parameter_page_t::command, device_info, driver_status, DRIVER_STATUS_INITIALIZED, NAND_INVALID_NAND_ADDRESS, NAND_PROGRAM_FAILED, NAND_PROGRAM_FAILED_WRITE_PROTECT, NAND_Read_Status(), NAND_SUCCESS, NAND_UNSUPPORTED, NUM_OF_ADDR_CYCLE, OPTIONAL_CMD_COPYBACK, nand_address_t::page, PLATFORM_Close(), PLATFORM_Open(), PLATFORM_SendAddr(), PLATFORM_SendCmd(), PLATFORM_Wait(), STATUS_FAIL, STATUS_WRITE_PROTECTED, SUPPORTED_ODD_TO_EVEN_PAGE_COPYBACK, and TIME_WB.

                                                                     {
   MT_uint8 src_address_stream[NUM_OF_ADDR_CYCLE];
   MT_uint8 dest_address_stream[NUM_OF_ADDR_CYCLE];
   MT_uint8 status_reg;
   MT_uint8 ret;
   MT_uint32 k;
   int i;

   /* verify if driver is initialized */
   if(DRIVER_STATUS_INITIALIZED != driver_status)
      return driver_status;

   /* check if this feature/command is supported */
   if ((device_info.command & OPTIONAL_CMD_COPYBACK) == 0)
      return NAND_UNSUPPORTED;

   /* check input parameters */
   if((NAND_SUCCESS != __is_valid_addr(src_addr)) || (NAND_SUCCESS != __is_valid_addr(dest_addr)))
      return NAND_INVALID_NAND_ADDRESS;

   /* check if the source and destination address are the same */
   if(!__compare_addr(src_addr, dest_addr))
      return NAND_INVALID_NAND_ADDRESS;

   /* check if odd to even copy back is supported */
   if ((device_info.command & SUPPORTED_ODD_TO_EVEN_PAGE_COPYBACK) == 0) {
      if(((src_addr.page & 1) != 0) && ((dest_addr.page & 1) == 0))
         return NAND_INVALID_NAND_ADDRESS;
      if(((src_addr.page & 1) == 0) && ((dest_addr.page & 1) != 0))
         return NAND_INVALID_NAND_ADDRESS;
   }

   /* copy back allows to move data from one page to another on the same plane */
   if(((src_addr.block & 1) != 0) && ((dest_addr.block & 1) == 0))
      return NAND_INVALID_NAND_ADDRESS;
   if(((src_addr.block & 1) == 0) && ((dest_addr.block & 1) != 0))
      return NAND_INVALID_NAND_ADDRESS;

   /* copy back is allowed only at the start of a page (ignoring column) */
   src_addr.column = 0;
   dest_addr.column = 0;

   /* build address cycles for source and destination address */
   __build_cycle_addr(src_addr, src_address_stream);
   __build_cycle_addr(dest_addr, dest_address_stream);

   /* init board transfer */
   PLATFORM_Open();

   /* send command */
   PLATFORM_SendCmd(CMD_READ_MODE);

   /* send source address */
   for(i=0; i<NUM_OF_ADDR_CYCLE; i++)
      PLATFORM_SendAddr(src_address_stream[i]);

   /* read for internal data move */

   /* send command */
   PLATFORM_SendCmd(CMD_READ_INTERNAL_DATA_MOVE);

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

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

    /* program for internal data move */

   /* send command */
   PLATFORM_SendCmd(CMD_PROGRAM_INTERNAL_DATA_MOVE);

   /* send destination address */
   for(i=0; i<NUM_OF_ADDR_CYCLE; i++)
      PLATFORM_SendAddr(dest_address_stream[i]);

   PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM);

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

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

   status_reg = NAND_Read_Status();

   /* close board transfer */
   PLATFORM_Close();

   /* check if program is good */
   if(!(status_reg & STATUS_WRITE_PROTECTED))
      return NAND_PROGRAM_FAILED_WRITE_PROTECT;

   if(status_reg & STATUS_FAIL)
      return NAND_PROGRAM_FAILED;

   return ret;
}