コード例 #1
0
ファイル: nfc_wl.cpp プロジェクト: zhouglu/K60F120M
uint_32 nfc_write_phy_page_raw
   (  
      /* [IN] the NAND flash information */
      IO_NANDFLASH_WL_STRUCT_PTR nandflash_ptr,

      /* [IN] where to copy data from */
      uchar_ptr               from_ptr,

      /* [IN] the first page to write */
      uint_32                 phy_page_number,

      /* [IN] the amount of pages to write */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2;
   uint_32 row, col, num_ecc_bytes;
   boolean swap = FALSE;
   uint_32 cfg_bck;

   NFC_MemMapPtr  nfc_ptr;

   if (nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT) {
      (*nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT)(&nandflash_ptr->CORE_NANDFLASH, FALSE);
   }/* Endif */
   
   /* Get the pointer to nfc registers structure */
   nfc_ptr = (NFC_MemMapPtr)_bsp_get_nfc_address();
   
      /* Set the ECCMODE to 0 - ECC bypass */
   cfg_bck = nfc_ptr->CFG;
   nfc_ptr->CFG &= ~(NFC_CFG_ECCMODE(7));
   
   /* Reset the swap register */
   nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) | 
                    NFC_SWAP_ADDR2(0x7FF);


   for (count1 = phy_page_number; count1 < (phy_page_number + page_count); count1++)
   {
      num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->CORE_NANDFLASH.ECC_SIZE);
      row = count1;
      col =0;
     

      if(nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16)
         col = col/2;
     
      /* Copy one virtual page into the SRAM buffer #0 */
      for ( count2 = 0; count2 < (nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE + nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE); count2++ )
      {
         // nfc_ptr->SRAM_B0[count2] = *(from_ptr + count2);
         NFC_SRAM_B0_REG(nfc_ptr, count2) = *(from_ptr + count2);
      }
      
      nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE2) | 
                     NFC_CMD1_BYTE3(NANDFLASH_CMD_READ_STATUS);
      nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE1) |  
                     NFC_CMD2_CODE(0x7FD8) |
                     NFC_CMD2_BUFNO(0);
      nfc_ptr->CAR  = col & 0xFFFF;
      nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                     NFC_RAR_RB0_MASK |
                     (row & 0xFFFFFF);
      nfc_ptr->SECSZ  = nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE + nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE ;
      

      nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK | 
                     NFC_ISR_DONEEN_MASK | 
                     NFC_ISR_IDLECLR_MASK |
                     NFC_ISR_IDLEEN_MASK);
      
      /* Start command execution */
      nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

      for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
      {
         if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
         {
            if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
            {
               result = NANDFLASHERR_WRITE_FAILED;
               goto exit;
            }
            else
            {
               result = NANDFLASHERR_NO_ERROR;
            }
            break;
         }
      }
      from_ptr += nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE;
   }

exit:
   if (nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT) {
      (*nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT)(&nandflash_ptr->CORE_NANDFLASH, TRUE);
   }/* Endif */
   
   nfc_ptr->CFG = cfg_bck;
   
   return(result);

} /* Endbody */
コード例 #2
0
ファイル: nfc_wl.cpp プロジェクト: zhouglu/K60F120M
uint_32 nfc_read_phy_page_raw
   (  
      /* [IN] the NAND flash information */
      IO_NANDFLASH_WL_STRUCT_PTR nandflash_ptr,

      /* [OUT} where to copy data to */
      uchar_ptr               to_ptr,

      /* [IN] the page to read */
      uint_32                 phy_page_number,

      /* [IN] the amount of pages to read */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2, count3;
   uint_32 output_offset = 0;   
   uint_32 row, col;
   uint_32 num_ecc_bytes;
   
   uint_32 count, cfg_bck;

   NFC_MemMapPtr  nfc_ptr;

   /* Get the pointer to nfc registers structure */
   nfc_ptr = (NFC_MemMapPtr)_bsp_get_nfc_address();
   
   
   /* Set the ECCMODE to 0 - ECC bypass */
   cfg_bck = nfc_ptr->CFG;
   nfc_ptr->CFG &= ~(NFC_CFG_ECCMODE(7));
   /* Do not write ECC Status to SRAM */
   nfc_ptr->CFG &= ~(NFC_CFG_ECCSRAM_MASK);
 
   /* Reset the swap register */
   nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) | 
                    NFC_SWAP_ADDR2(0x7FF);

   for (count1 = phy_page_number; count1 < (phy_page_number + page_count); count1++)
   {
      num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->CORE_NANDFLASH.ECC_SIZE);
      row = count1;
      /* Read from begin of physical page */
      col = 0;
      /* Is the bad block byte(s) about to be re-written? */

      nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
      nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) | 
                     NFC_CMD2_CODE(0x7EE0) |
                     NFC_CMD2_BUFNO(1);
      nfc_ptr->CAR  = col & 0xFFFF;
      nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                     NFC_RAR_RB0_MASK |
                     (row & 0xFFFFFF);
      nfc_ptr->SECSZ  = nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE + nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE ;


      nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK | 
                       NFC_ISR_DONEEN_MASK | 
                       NFC_ISR_IDLECLR_MASK |
                       NFC_ISR_IDLEEN_MASK);
    
      /* Start command execution */
      nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

      for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
      {
         if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
         {
            for(count3 = 0; count3 < (nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE + nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE); count3++)
            {
               *(to_ptr + output_offset) = NFC_SRAM_B1_REG(nfc_ptr, count3);
               output_offset++;            
            }
            result = NANDFLASHERR_NO_ERROR;

            break; /* break for (count2 = 0;... */

         } /* if nfc_ptr->ISR & NFC_ISR_IDLE */ 
      }
   } /* for (count1 = phy_page_number */

   nfc_ptr->CFG = cfg_bck;

   return(result);

} /* Endbody */
コード例 #3
0
ファイル: nfc_wl.cpp プロジェクト: zhouglu/K60F120M
uint_32 nfc_write_page_with_metadata
   (  
      /* [IN] the NAND flash information */
      IO_NANDFLASH_WL_STRUCT_PTR nandflash_ptr,

      /* [IN] where to copy data from */
      uchar_ptr               data_from_ptr,
      
      /* [IN] where to copy metadata from */
      uchar_ptr               metadata_from_ptr,

      /* [IN] the first page to write */
      uint_32                 page_number,

      /* [IN] the amount of pages to write */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2;
   uint_32 row, col, num_ecc_bytes, num_metadata_bytes;
   boolean swap = FALSE;
   uint_32 output_offset = 0;
   uint_32 output_metadata_offset = 0;
   uint_32 real_virt_page_offset;
   NFC_MemMapPtr  nfc_ptr;

   if (nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT) {
      (*nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT)(&nandflash_ptr->CORE_NANDFLASH, FALSE);
   } /* Endif */
   
   num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->CORE_NANDFLASH.ECC_SIZE);
   num_metadata_bytes = nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO 
                        - num_ecc_bytes;
   
   /* Get the pointer to nfc registers structure */
   nfc_ptr = (NFC_MemMapPtr)_bsp_get_nfc_address();
   
   for (count1 = page_number; count1 < (page_number + page_count); count1++)
   {        
      /* Calculate physical page address */
      row = count1/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
      real_virt_page_offset = nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO   
                              - 1 - (count1 - (row * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO));
      
      /* Calculate byte offset in this physical page */
      /* For preserve bad marking block address, we writes all pages in reserved order.
      * Virtual page 0 <-> write physically in Virtual page 3
      * Virtual page 1 <-> write physically in Virtual page 2 */

      col = real_virt_page_offset  *(nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + num_ecc_bytes);
      
      /* If the last virtual page of the first or the second physical page
      is about to be written the swapping needs to be switched on due 
      to the bad block marking */
      count2 = count1 % 
               ((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->BLOCK_SIZE / nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE) 
               * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO);
      swap = ((count2 == (0)) ||
               (count2 == (nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO)));
      
      if(swap)
      {
         nfc_ptr->SWAP  = NFC_SWAP_ADDR1(nfc_swap_addr1_with_metadata) | 
         NFC_SWAP_ADDR2(nfc_swap_addr2);
      }
      else
      {
         nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) | 
         NFC_SWAP_ADDR2(0x7FF);
      }

      if(nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16)
         col = col/2;
      
      /* Copy one virtual page data into the SRAM buffer #0 */
      for ( count2 = 0; count2 < (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE); count2++ )
      {
         NFC_SRAM_B0_REG(nfc_ptr, count2) = *(data_from_ptr + output_offset);
         output_offset++;
      }
      
      NFC_LOG("nfc_write_page_with_metadata: copy %d from page DATA to SRAM \n", count2);      
      
      /* Copy one virtual page metadata into the SRAM buffer #0 */
      for ( count2 = nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE;
      count2 < (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes); count2++)
      {
         NFC_SRAM_B0_REG(nfc_ptr, count2) = *(metadata_from_ptr + output_metadata_offset);
         output_metadata_offset++;
      }
      
      NFC_LOG("nfc_write_page_with_metadata: copy %d from page METADATA to SRAM \n", count2 - nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE);
      
      nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE2) | 
                        NFC_CMD1_BYTE3(NANDFLASH_CMD_READ_STATUS);
      nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_PROGRAM_CYCLE1) |  
                        NFC_CMD2_CODE(0x7FD8) |
                        NFC_CMD2_BUFNO(0);
      nfc_ptr->CAR  = col & 0xFFFF;
      nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                        NFC_RAR_RB0_MASK |
                        (row & 0xFFFFFF);
      nfc_ptr->SECSZ  = (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE)+ num_metadata_bytes + num_ecc_bytes;
      
      /* For 16-bit data width flash devices, only odd SIZE is supported */
      if((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16) && !(nfc_ptr->SECSZ % 2))
         nfc_ptr->SECSZ  += 1;

      NFC_LOG("nfc_write_page_with_metadata: issue a WRITE cmd w/ SECTZ=%d at COL*2=%d page %d\n", 
      nfc_ptr->SECSZ, col*2, count1);
      nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK | 
                        NFC_ISR_DONEEN_MASK | 
                        NFC_ISR_IDLECLR_MASK |
                        NFC_ISR_IDLEEN_MASK);
      
      /* Start command execution */
      nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;

      for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
      {
         if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
         {
            if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
            {
               result = NANDFLASHERR_WRITE_FAILED;
               goto exit;
            }
            else
            {
               result = NANDFLASHERR_NO_ERROR;
            }
            break;
         }
      }
   }

exit:
   if (nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT) {
      (*nandflash_ptr->CORE_NANDFLASH.WRITE_PROTECT)(&nandflash_ptr->CORE_NANDFLASH, TRUE);
   }/* Endif */
   
   nfc_dump_buff(data_from_ptr, output_offset, "Write Page Buffer");
   nfc_dump_buff(metadata_from_ptr, output_metadata_offset,
   "Write Page Metadata Buffer");
   
   return(result);

} /* Endbody */
コード例 #4
0
ファイル: nfc_wl.cpp プロジェクト: zhouglu/K60F120M
uint_32 nfc_read_page_metadata
   (  
      /* [IN] the NAND flash information */
      IO_NANDFLASH_WL_STRUCT_PTR nandflash_ptr,

      /* [OUT} where to copy data to */
      uchar_ptr               to_ptr,

      /* [IN] the page to read */
      uint_32                 page_number,

      /* [IN] the amount of pages to read */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2, count3;
   uint_32 output_offset = 0;
   boolean  swap = FALSE;
   uint_32 row, col, num_ecc_bytes, real_virt_page_offset ;
   uint_32 num_metadata_bytes;
   
   uint_32 cfg_bck;

   NFC_MemMapPtr  nfc_ptr;   
   
   num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->CORE_NANDFLASH.ECC_SIZE);
   num_metadata_bytes = nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO 
                        - num_ecc_bytes;
   
   /* Get the pointer to nfc registers structure */
   nfc_ptr = (NFC_MemMapPtr)_bsp_get_nfc_address();
   
   /* Set the ECCMODE to 0 - ECC bypass */
   cfg_bck = nfc_ptr->CFG;
   nfc_ptr->CFG &= ~(NFC_CFG_ECCMODE(7));
   /* Do not write ECC Status to SRAM */
   nfc_ptr->CFG &= ~(NFC_CFG_ECCSRAM_MASK);
   
   /* Reset the swap register */
   nfc_ptr->SWAP = NFC_SWAP_ADDR1(0x7FF) | NFC_SWAP_ADDR2(0x7FF);

   for (count1 = page_number; count1 < (page_number + page_count); count1++) {
      row = count1/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
      real_virt_page_offset = nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO
                              - 1 - (count1 - (row * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO));

      /* Calculate byte offset in this physical page */
      /* For preserve bad marking block address, we writes all pages in reserved order.
      * Virtual page 0 <-> write physically in Virtual page 3
      * Virtual page 1 <-> write physically in Virtual page 2 */

      col = real_virt_page_offset *(nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + num_ecc_bytes);row = count1/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
      real_virt_page_offset = nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO
                              - 1 - (count1 - (row * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO));

      /* Calculate byte offset in this physical page */
      /* For preserve bad marking block address, we writes all pages in reserved order.
      * Virtual page 0 <-> write physically in Virtual page 3
      * Virtual page 1 <-> write physically in Virtual page 2 */

      col = real_virt_page_offset *(nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + num_ecc_bytes);
      col += nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE;

      /* Is the bad block byte(s) about to be re-written? */
      count2 = count1 %
               ((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->BLOCK_SIZE / nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE)
               * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO);
      swap = ((count2 == (0)) ||
               (count2 == (nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO)));
      /* If the last virtual page of the first or the second physical page
      is about to be read the virtual page needs to be enlarged
      by 8 bytes and swapping switched on due to the bad block marking */
      if(swap)
      {
         /* Here we are read MD from page MD swapped   *
         * -> we need to calculate to real MD of this * 
         * swapped page 
         */ 
         col -= ( nfc_swap_addr2 - nfc_swap_addr1_with_metadata  ) * 8;
      }

      if(nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16)
      col = col/2;
      
      nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
      nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) | 
                        NFC_CMD2_CODE(0x7EE0) |
                        NFC_CMD2_BUFNO(1);
      nfc_ptr->CAR  = col & 0xFFFF;
      nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                        NFC_RAR_RB0_MASK |
                        (row & 0xFFFFFF);
      /* Calculate metadata size for each page (exclude ECC size), 
      * since SPARE_ARE_SIZE is total spare size for each Physical page */
      
      nfc_ptr->SECSZ = num_metadata_bytes +num_ecc_bytes;
      
      /* For 16-bit data width flash devices, only odd SIZE is supported */
      if((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16) && !(nfc_ptr->SECSZ % 2))
         nfc_ptr->SECSZ  += 1;

      nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK | 
                        NFC_ISR_DONEEN_MASK | 
                        NFC_ISR_IDLECLR_MASK |
                        NFC_ISR_IDLEEN_MASK);
      NFC_LOG("nfc_read_page_metadata: issue a READ cmd w/ col =%d page %d\n", col, count1);
      /* Start command execution */
      nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;
      
      for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
      {
         if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
         {
            for(count3 = 0; count3 < (num_metadata_bytes); count3++)
            {
               *(to_ptr + output_offset) = NFC_SRAM_B1_REG(nfc_ptr, count3);
               output_offset++;            
            }
            result = NANDFLASHERR_NO_ERROR;
            break;
         }
      }
   }
   
   nfc_ptr->CFG = cfg_bck;
   return(result);

} /* Endbody */
コード例 #5
0
ファイル: nfc_wl.cpp プロジェクト: zhouglu/K60F120M
uint_32 nfc_read_page_with_metadata
   (  
      /* [IN] the NAND flash information */
      IO_NANDFLASH_WL_STRUCT_PTR nandflash_ptr,

      /* [OUT] where to copy data to */
      uchar_ptr               to_data_ptr,
      
      /* [OUT] where to copy metadata to */
      uchar_ptr               to_metadata_ptr,

      /* [IN] the page to read */
      uint_32                 page_number,

      /* [IN] the amount of pages to read */
      uint_32                 page_count
   )
{ /* Body */
   uint_32 result = NANDFLASHERR_TIMEOUT;
   uint_32 count1, count2, count3, real_virt_page_offset;
   uint_32 data_output_offset = 0, metadata_output_offset = 0;
   boolean ecc_corrected = FALSE, swap = FALSE;
   uint_32 row, col, num_ecc_bytes, num_metadata_bytes;
   uint_32 cfg_bck;
   
   NFC_MemMapPtr  nfc_ptr;
   uint_8 ecc_num_bit_correct;   

   num_ecc_bytes = NANDFLASH_ECC_SIZE_TO_NUM_BYTES_CONV(nandflash_ptr->CORE_NANDFLASH.ECC_SIZE);
   num_metadata_bytes = nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->SPARE_AREA_SIZE/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO 
                        - num_ecc_bytes;
   /* Get the pointer to nfc registers structure */
   nfc_ptr = (NFC_MemMapPtr)_bsp_get_nfc_address();
   
   /* back up current nfc_ptr then change the ECC status position in output read buffer */
   cfg_bck = nfc_ptr->CFG;   
   nfc_ptr->CFG =  (nfc_ptr->CFG & (~NFC_CFG_ECCAD(0xFFFF))) 
                  | NFC_CFG_ECCAD(( (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE  +num_metadata_bytes) / 8) + 1); 
   
   for (count1 = page_number; count1 < (page_number + page_count); count1++)
   {     
      /* Calculate physical page address */
      row = count1/nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO;
      real_virt_page_offset = nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO
      - 1 - (count1 - (row * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO));

      /* Calculate byte offset in this physical page */
      /* For preserve bad marking block address, we writes all pages in reserved order.
      * Virtual page 0 <-> write physically in Virtual page 3
      * Virtual page 1 <-> write physically in Virtual page 2 */

      col = real_virt_page_offset *(nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + num_ecc_bytes);

      /* If the last virtual page of the first or the second physical page
      is about to be written the swapping needs to be switched on due 
      to the bad block marking */
      count2 = count1 %
               ((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->BLOCK_SIZE / nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->PHY_PAGE_SIZE)
               * nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO);
      swap = ((count2 == (0)) ||
               (count2 == (nandflash_ptr->CORE_NANDFLASH.PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO)));
      
      if(nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16)
         col = col/2;
      
      nfc_ptr->CMD1 = NFC_CMD1_BYTE2(NANDFLASH_CMD_PAGE_READ_CYCLE2);
      nfc_ptr->CMD2 = NFC_CMD2_BYTE1(NANDFLASH_CMD_PAGE_READ_CYCLE1) | 
                        NFC_CMD2_CODE(0x7EE0) |
                        NFC_CMD2_BUFNO(1);
      nfc_ptr->CAR  = col & 0xFFFF;
      nfc_ptr->RAR  = NFC_RAR_CS0_MASK |
                        NFC_RAR_RB0_MASK |
                        (row & 0xFFFFFF);
      nfc_ptr->SECSZ  = (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE)+ num_metadata_bytes +num_ecc_bytes ;
      
      /* For 16-bit data width flash devices, only odd SIZE is supported */
      if((nandflash_ptr->CORE_NANDFLASH.NANDFLASH_INFO_PTR->WIDTH == 16) && !(nfc_ptr->SECSZ % 2))
         nfc_ptr->SECSZ  += 1;
      
      /* If the last virtual page of the first or the second physical page
      is about to be read the virtual page needs to be enlarged
      by 8 bytes and swapping switched on due to the bad block marking */
      if(swap)
      {
         nfc_ptr->SWAP  = NFC_SWAP_ADDR1(nfc_swap_addr1_with_metadata) | 
         NFC_SWAP_ADDR2(nfc_swap_addr2);
      }
      else
      {
         nfc_ptr->SWAP  = NFC_SWAP_ADDR1(0x7FF) | 
         NFC_SWAP_ADDR2(0x7FF);
      }
      NFC_LOG("nfc_read_page_with_metadata: issue a READ cmd w/ SECTZ=%d at COL*2=%d, page=%d\n", 
      nfc_ptr->SECSZ, col*2, count1);
      
      nfc_ptr->ISR  |= (NFC_ISR_DONECLR_MASK | 
      NFC_ISR_DONEEN_MASK | 
      NFC_ISR_IDLECLR_MASK |
      NFC_ISR_IDLEEN_MASK);
      
      /* Start command execution */
      nfc_ptr->CMD2 |= NFC_CMD2_BUSY_START_MASK;
      
      for (count2 = 0; count2 <= MAX_WAIT_COMMAND; count2++)
      {
         if (nfc_ptr->ISR & NFC_ISR_IDLE_MASK)
         {
            
            if ( nandflash_ptr->CORE_NANDFLASH.ECC_SIZE == 0)
            {
               if (nfc_ptr->SR2 & NANDFLASH_STATUS_ERR)
               {
                  result = NANDFLASHERR_ECC_FAILED;
                  break; /* break to out of for MAX_WAIT_COMMAND*/
               }
            }
            else  /* if nandflash_ptr->ECC_SIZE == 0)*/
            {      
               if((*(uint_32*)&NFC_SRAM_B1_REG(nfc_ptr, nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + (num_ecc_bytes + 4))) & NFC_ECC_STATUS_CORFAIL)
               {
                  /* ECC Fix FAILED */
                  result = NANDFLASHERR_ECC_FAILED;
                  break;
               }
               else
               {
                  if((*(uint_32*)&NFC_SRAM_B1_REG(nfc_ptr, nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + (num_ecc_bytes + 4))) & NFC_ECC_STATUS_CORFAIL)
                  {               
                     ecc_corrected = TRUE;
                     ecc_num_bit_correct = (*(uint_32*)&NFC_SRAM_B1_REG(nfc_ptr, nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes + (num_ecc_bytes + 4))) & NFC_ECC_STATUS_ERROR_COUNT;
                     result = NANDFLASHERR_ECC_CORRECTED;
                  }
                  else /* ECC is success, we donot need to correct any bits */
                  {
                     result = NANDFLASHERR_NO_ERROR;
                  }
               }      
            } /* if nfc_ptr->ISR & NFC_ISR_IDLE*/

            /* In case we catch ECC_CORRECTED or NO_ERROR, we still copy data from SRAM -> requested buffer */
            
            /* Copy Page DATA from SRAM buffer to to_data_ptr */
            for(count3 = 0; count3 < (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE); count3++)
            {
               *(to_data_ptr + data_output_offset) = NFC_SRAM_B1_REG(nfc_ptr, count3);
               data_output_offset++;            
            }
            
            NFC_LOG("nfc_read_page_with_metadata: copy %d from page DATA to SRAM \n", count3);
            
            /* Copy Page METADATA from SRAM buffer to to_data_ptr */
            for(count3 = nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE; 
            count3 < (nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE + num_metadata_bytes); count3++)
            {
               *(to_metadata_ptr + metadata_output_offset) = NFC_SRAM_B1_REG(nfc_ptr, count3);
               metadata_output_offset++;            
            }
            
            NFC_LOG("nfc_read_page_with_metadata: copy %d from page METADATA to SRAM \n", count3-nandflash_ptr->CORE_NANDFLASH.VIRTUAL_PAGE_SIZE);                 
            
            
            break;
         } /* if nfc_ptr->ISR & IDLE */
      } /* for MAX_WAIT_COMMAND */

      /* Everytime we catch error even ECC_CORRECTED, just quit */
      if (NANDFLASHERR_NO_ERROR != result ) 
      {
         break; /* break out of for count1=page_number */
      }
   } 
   
   if (ecc_corrected)
   {
      if (ecc_num_bit_correct >= _ecc_mode_threshold[curr_ecc_mode])
         result = NANDFLASHERR_ECC_CORRECTED_EXCEED_THRESHOLD;
      else
         result = NANDFLASHERR_ECC_CORRECTED;
   }
   
   nfc_dump_buff(to_data_ptr, data_output_offset, "Read Page Buffer");
   nfc_dump_buff(to_metadata_ptr, metadata_output_offset, "Read Page Metadata Buffer");
   
   /* Restore nfc config */
   nfc_ptr->CFG = cfg_bck ;
   return(result);

} /* Endbody */
コード例 #6
0
ファイル: nfc.c プロジェクト: Vinhuit/Freescale
uint32_t nfc_init
   (
      /* [IN] the NAND flash information */
      IO_NANDFLASH_STRUCT_PTR nandflash_ptr
   )
{ /* Body */

   uint32_t result = NANDFLASHERR_NO_ERROR;
   NFC_MemMapPtr nfc_ptr;
   uint32_t nand_id, block_size_kB, density, num_ecc_bytes;
   NANDFLASH_INFO_STRUCT_PTR nand_info_ptr;

   /* Initialize NFC I/O Pins */
   nfc_io_init();

   /* Get the pointer to nfc registers structure */
   nfc_ptr = _bsp_get_nfc_address();

   /* Create NANDFLASH_INFO_STRUCT based on NAND ID read from the NAND Flash,
      if not defined before manually */
   if((nandflash_ptr->NANDFLASH_INFO_PTR) == NULL)
   {
       nand_info_ptr = (NANDFLASH_INFO_STRUCT_PTR)_mem_alloc_system_zero(
                       (_mem_size)sizeof(NANDFLASH_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
       if(nand_info_ptr == NULL)
       {
          return((uint32_t)MQX_OUT_OF_MEMORY);
       } /* Endif */
#endif

       if (((*nandflash_ptr->IOCTL)(nandflash_ptr,NANDFLASH_IOCTL_GET_ID,&nand_id)) == NANDFLASHERR_NO_ERROR)
       {
           nand_info_ptr->PHY_PAGE_SIZE =
             (_mem_size)(((nand_id & NANDFLASH_ID_PAGE_SIZE_MASK) + 1)*1024);

           if((nand_id & NANDFLASH_ID_SPARE_BYTES_NUM_MASK)>>2 == 1)
           {
               nand_info_ptr->SPARE_AREA_SIZE = (_mem_size)64;
           }

           if(nand_id & NANDFLASH_ID_BLOCK_SIZE_MASK)
           {
               nand_info_ptr->BLOCK_SIZE =
                 (_mem_size)((nand_id & NANDFLASH_ID_BLOCK_SIZE_MASK)*8192);
           }
           else
           {
               nand_info_ptr->BLOCK_SIZE = 65536;
           }

           block_size_kB = (nand_info_ptr->BLOCK_SIZE)/1024;
           density = (nand_id & NANDFLASH_ID_DENSITY_MASK)>>16;
           switch(density)
           {
               case NANDFLASH_DENSITY_1Gb:
                   /* nand_info_ptr->NUM_BLOCKS = 1024/8*1024/block_size_kB; */
                   nand_info_ptr->NUM_BLOCKS = 131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_2Gb:
                   nand_info_ptr->NUM_BLOCKS = 2*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_4Gb:
                   nand_info_ptr->NUM_BLOCKS = 4*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_8Gb:
                   nand_info_ptr->NUM_BLOCKS = 8*131072/block_size_kB;
                   break;

               case NANDFLASH_DENSITY_16Gb:
                   nand_info_ptr->NUM_BLOCKS = 16*131072/block_size_kB;
                   break;

               default:
                   break;
           }

           nand_info_ptr->WIDTH =
             (_mqx_uint)(8 + ((nand_id & NANDFLASH_ID_WIDTH_MASK)>>3));

           nandflash_ptr->NANDFLASH_INFO_PTR = nand_info_ptr;
           nandflash_ptr->NUM_VIRTUAL_PAGES  =
             ((nand_info_ptr->BLOCK_SIZE)/(nandflash_ptr->VIRTUAL_PAGE_SIZE))*(nand_info_ptr->NUM_BLOCKS);
           nandflash_ptr->PHY_PAGE_SIZE_TO_VIRTUAL_PAGE_SIZE_RATIO =
             (nand_info_ptr->PHY_PAGE_SIZE)/(nandflash_ptr->VIRTUAL_PAGE_SIZE);
       }