⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nf.c

📁 c51snd1c硬盘播放器全部资料.源码.线路图.protel99se的pcb图
💻 C
📖 第 1 页 / 共 5 页
字号:
                  gl_buffer[byte_6 + 1]  = block;
                }
              }
            }
          }
          temp_address += NF_PAGE_PER_BLOCK; 
          block++;
        }
          
        if (!nf_close_write_session)
        {
          /* affect to the free physical block a fictive logical block */
          /* free physical block => gl_buffer[x] = 0xFF */
          temp_address = (Uint32)(free_bloc_pos_odd) << NF_SHIFT_SECTOR_BLOCK;
          for (i = 2; i <= 0xFE; i+=4)
          {
            if (gl_buffer[i] == 0xFF)
            {
              do                                                /* Search free physical block */
              {
                temp_address += NF_PAGE_PER_BLOCK;
                if (temp_address >= ((Uint32)(nf_zone + 1) << NF_SHIFT_SECTOR_ZONE) )
                    temp_address = (Uint32)(nf_zone) << NF_SHIFT_SECTOR_ZONE;
      
                Nf_read_open_spare_area_odd(temp_address, 0x05);
                
                byte_5 = Nf_rd_byte_odd();                          /* Invalid/Valid block */
                byte_6 = Nf_rd_byte_odd();                          /* Used/Unused block */
              }
              while ( ( (byte_6 != 0xFF) && (byte_6 != 0xE8) ) || (byte_5 != 0xFF) );
    
              free_bloc_pos_odd      = (temp_address  >> NF_SHIFT_SECTOR_BLOCK);
              gl_buffer[i]           = ((Byte*)&free_bloc_pos_odd)[0] | 0x80;
              gl_buffer[i + 1]       = ((Byte*)&free_bloc_pos_odd)[1];
            }
          }
        }
    
        if (nf_close_write_session == TRUE) /* if we find two physical blocks with same */
        {                                   /* logical blocks affectation */
          /* we have already determine the value of : */
          /*  - nf_block_to_be_deleted_even : need for nf_close_write_session */
          /*  - nf_block_to_be_deleted_odd : need for nf_close_write_session */
          /*  - save_gl_cpt_page_even : need for gl_ptr_mem & gl_cpt_page determination */
          /*  - save_gl_cpt_page_odd : need for gl_ptr_mem & gl_cpt_page determination */
          /*  - nf_logical_block  : logical block value is need for gl_ptr_mem determination */
          /* we need to calculate : */
          /*  - gl_ptr_mem value */
          /*  - gl_cpt_page value */
          /*  - switch even/odd nand flash */
          gl_ptr_mem =  ( ( ((Uint32)(nf_zone) * 1000) << NF_SHIFT_SECTOR_BLOCK) + 
                          ( (Uint32)(nf_logical_block) << NF_SHIFT_SECTOR_BLOCK) + 
                          (((Byte*)&nf_current_physical_sector_addr_even)[3] & 0x3F)) << 1;
          
          gl_cpt_page = 0;
          if (bit_double_block_odd == FALSE)
          { /* if we detect only double affectation for even nf */
            /* (write session stopped before write on odd nf) */
            /* last write was on even nf */
            ((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_even;
            if (((Byte*)&gl_cpt_page)[0] == 0x08)
            {
              nf_current_physical_sector_addr_even++;
              gl_cpt_page = 0x00;
              gl_ptr_mem+=2; /* copy block tail only on nf even */
            }
            nf_parity_bit = NF_EVEN;
          }
          else
          {
            if (  (((Byte*)&nf_current_physical_sector_addr_odd)[3] & 0x3F) == 
                  (((Byte*)&nf_current_physical_sector_addr_even)[3] & 0x3F))
            {
              /* if physical address even and old is same -> last write was on odd nf */
              nf_current_physical_sector_addr_even++;
              gl_ptr_mem++;
              ((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_odd;

              if (((Byte*)&gl_cpt_page)[0] == 0x08)  /* if end of page */
              {                                     /* next write will occur in even nf */
                nf_current_physical_sector_addr_odd++;
                gl_cpt_page = 0x00;
                gl_ptr_mem++;
                nf_parity_bit = NF_EVEN;
              }
              else
              {
                nf_parity_bit = NF_ODD;
              }
            }
            else
            {
              /* last write was on even nf */
              ((Byte*)&gl_cpt_page)[0] = save_gl_cpt_page_even;
              nf_current_physical_sector_addr_odd++;
              if (((Byte*)&gl_cpt_page)[0] == 0x08)
              {
                nf_current_physical_sector_addr_even++;
                gl_cpt_page = 0x00;
                gl_ptr_mem++;
                nf_parity_bit = NF_ODD;
              }
              else
              {
                nf_parity_bit = NF_EVEN;
              }
            }
          }
          nf_calc_logical_block();
          if ( (((Byte*)&gl_ptr_mem)[3] & 0x7F) || (gl_cpt_page != 0) )
          nf_copy_block_tail(!bit_double_block_odd); 
          Nf_CS_EVEN();
          nf_block_erase((Uint32)(nf_block_to_be_deleted_even) << NF_SHIFT_SECTOR_BLOCK);    /* Erase old block */
          if (bit_double_block_odd == TRUE)
          {
            Nf_CS_ODD();
            nf_block_erase((Uint32)(nf_block_to_be_deleted_odd) << NF_SHIFT_SECTOR_BLOCK);    /* Erase old block */
          }
          /* reset all variables to restart the scan */
          gl_address = (Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK + nf_zone;
        }
        else
        {
          /* update LUT */
          Nf_CS_EVEN();
          Nf_wait_busy_even();
          Nf_send_command_even (NF_SEQUENTIAL_DATA_INPUT_CMD);
          Nf_send_address_even ( 0x00 );                               /* Column address byte 0            */
          Nf_send_address_even ( page );                               /* Column address byte 1            */
          Nf_send_address_even ( ((Byte*)&gl_address)[3] );            /* Row address byte 0               */
          Nf_send_address_even ( ((Byte*)&gl_address)[2] );            /* Row address byte 1               */
          if (NF_5_CYCLE_ADDRESS_BIT)                             /* Size of card >= 128Mbytes ?  */
            Nf_send_address_even ( ((Byte*)&gl_address)[1] );          /* Row address Byte 2           */
  
          nf_download_buffer();                                   /* Write 256 bytes from the buffer  */
          page++;
          if (page == 0x08)
          {
            /* Write redundant data */
            Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF);
            Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF);
            Nf_wr_byte_even(0xE8); Nf_wr_byte_even(0xFF);                   /* Logical block value */
            Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); /* ECC area 2 */
            Nf_wr_byte_even(0xE8); Nf_wr_byte_even(0xFF);                   /* Logical block value */
            Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); Nf_wr_byte_even(0xFF); /* ECC area 1 */
            gl_address++;
            page = 0;
          }
          Nf_send_command_even(NF_PAGE_PROGRAM_CMD);                   /* Valid the page programmation     */
          start    += 0x40;                                       /* process next 128 logical block   */
          end      += 0x40;
        }
      }
      while (start < NF_BLOCK_PER_ZONE);
    }
  }
  /* Global initialization */
  nf_block_min        = 0xFFFF;          /* Starting buffer value    */
  nf_gl_buf_idx_max   = 0;               /* Max index in the buffer  */
  nf_lut_modified     = FALSE;           /* Buffer change flag       */
  nf_gl_buf_idx       = 0;               /* Main buffer index        */
  gl_buf_free_idx     = 0;               /* Free physical buffer idx */
  nf_old_zone         = 0xFF;            /* Previous zone number     */
  nf_close_write_session = FALSE;
  nf_write_advanced = FALSE;
  return OK;
}



/*F**************************************************************************
* NAME: nf_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   OK : init complete
*   KO : - NF not supported or not recognise
*----------------------------------------------------------------------------
* PURPOSE:
*   NF initialisation
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit nf_init (void)
{
  P2 = NF_IDLE_STATE_ADD;
  Nf_active_EVEN();
  Nf_send_command_even(NF_RESET_CMD);
  Nf_active_ODD();
  Nf_send_command_odd(NF_RESET_CMD);

  #if (NF_CAPACITY_AUTO_DETECT == TRUE)               /* Auto Detect the type of nand-flash  */
    Nf_wait_busy_even();
    Nf_send_command_even(NF_READ_ID_CMD);
    Nf_send_address_even(0x00);
    Nf_rd_byte_even();                                     /* Maker  code */
    switch (Nf_rd_byte_even())                             /* Device code */
    {
      /***************************************************************************/
      case NF_K9F1G08U0M :                            /*------- 128 Mbyte -------*/
      case NF_K9F1K08Q0M :                            /*------- 128 Mbyte -------*/
        nf_device_type = NF_SIZE_256MB;
        nf_zone_max = 1;                              /* 1 zone : 1024 blocks    */
        nf_mem_size =  (NF_SECTOR_SIZE_256MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
        nf_5_cycle_address = 0;                       /* 4 address cycles        */
      break;
      /***************************************************************************/
      case NF_K9K2G08Q0M :                            /*------- 256 Mbyte -------*/
      case NF_K9K2G08U0M :                            /*------- 256 Mbyte -------*/
        nf_device_type = NF_SIZE_512MB;
        nf_zone_max = 2;                              /* 2 zones : 2048 blocks   */
        nf_mem_size =  (NF_SECTOR_SIZE_512MB + 1) * 4 - 1 - MEM_RESERVED_SIZE;
        nf_5_cycle_address = 1;                       /* 5 address cycles        */
      break;
      default:
        return KO;
    }
  #else
    nf_mem_size = (NF_SECTOR_SIZE + 1) * 4 - 1 - MEM_RESERVED_SIZE;
  #endif

  nf_reserved_space_start = nf_mem_size + 1;

  return OK;
}




/*F**************************************************************************
* NAME: nf_read_open
*----------------------------------------------------------------------------
* PARAMS:
*   pos: address of the logic sector to read (size 512 bytes)
*
* return:
*   Update memory for reading
*----------------------------------------------------------------------------
* PURPOSE:
*   Low level memory read update
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE: 
*----------------------------------------------------------------------------
* REQUIREMENTS: 
*****************************************************************************/
bit nf_read_open (Uint32 pos)
{
Uint16 physical_block;

  if (nf_lut_modified)
  {
    if (nf_close_write_session)
    {
      nf_close_write_session = FALSE;
      nf_force_write_close();
    }
    nf_reassign_block();
    nf_lut_modified = FALSE;
  }

  gl_ptr_mem = pos >> 2;
  gl_cpt_page = (pos & 0x03) << 9 ;


  nf_logical_block  = (gl_ptr_mem >> NF_SHIFT_SECTOR_BLOCK) >> 1;     
  nf_zone           = nf_logical_block / 1000;                            /* Determinate logical zone */
  nf_logical_block  = nf_logical_block - (1000 * (Uint16)(nf_zone));      /* Logical block value      */

  /* lut address calculation  */
  gl_address        = ((Uint32)(nf_lut_block[nf_zone]) << NF_SHIFT_SECTOR_BLOCK) + 
                      ((Uint32)(nf_lut_index[nf_zone]) << 1) +
                      (((Byte*)&nf_logical_block)[0]   >> 1);

  Nf_CS_EVEN();
  Nf_wait_busy_even();
  Nf_send_command_even (NF_READ_CMD);                     /* Open the look-up table       */
  Nf_send_address_even ( nf_logical_block << 2 );         /* Column address Byte 0        */
  Nf_send_address_even ( (nf_logical_block >> 6) & 0x07 );/* Column address Byte 1        */
  Nf_send_address_even ( ((Byte*)&gl_address)[3] );       /* Row address Byte 0           */
  Nf_send_address_even ( ((Byte*)&gl_address)[2] );       /* Row address Byte 1           */
  if (NF_5_CYCLE_ADDRESS_BIT)                             /* Size of nf >= 256Mbytes?     */
    Nf_send_address_even ( ((Byte*)&gl_address)[1] );     /* Row address Byte 2           */
  Nf_send_command_even(NF_READ_CMD2);

  nf_busy = TRUE;                                         /* Set busy flag */
  nf_write_advanced = FALSE;                              /* Desactive write optimization */

  Nf_wait_busy_even();

  ((Byte*)&physical_block)[0] = Nf_rd_byte_even() & 0x7F;     
  ((Byte*)&physical_block)[1] = Nf_rd_byte_even();
  nf_current_physical_sector_addr_even = ((Uint32)(physical_block) << NF_SHIFT_SECTOR_BLOCK) + 
                                    ((((Byte*)&gl_ptr_mem)[3] & 0x7F) >> 1) + 
                                    ((((Byte*)&gl_ptr_mem)[3] & 0x01));   

  ((Byte*)&physical_block)[0] = Nf_rd_byte_even() & 0x7F;     
  ((Byte*)&physical_block)[1] = Nf_rd_byte_even();
  nf_current_physical_sector_addr_odd = ((Uint32)(physical_block) << NF_SHIFT_SECTOR_BLOCK) + 
                                    ((((Byte*)&gl_ptr_mem)[3] & 0x7F) >> 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -