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

📄 nf.c

📁 一个可作为mp3播放器固件的代码集,包括解码,播放,控制,任务管理等.
💻 C
📖 第 1 页 / 共 5 页
字号:
      if ((byte_6 == 0xE8) && ((gl_address & 0x1F) == 0))
      {
        lut_index[i]--;
        gl_address = gl_address - NB_PAGE_BY_LUT;
      }
      else
      {
        lut_index[i]-=2;
        gl_address = gl_address - (NB_PAGE_BY_LUT << 1);
      }

      Nf_read_open_C_area_even(gl_address, 0x00);
      if (Nf_rd_byte_even() != 0xFF)                              /* LUT have been modified */
      {
        nf_block_erase(gl_address);
        lut_is_present[i] = FALSE;   
        lut_index[i] = 0;
        Nf_wait_busy_even();
      }
    }
  }
  
  
  /*****************************************************************/
  /*          Find free physical block for LUT for each zone       */
  /*****************************************************************/
  for (i = 0; i < NF_ZONE_MAX_CPT; i++)
  {
    if (lut_is_present[i] == FALSE)
    {
      block = last_physical_used_block_even[i];
      start = (Uint16)(i);                                    /* starting value for each zone */
      j = 0;                                                  /* reset turn around counter    */
      if (block == start)                                     /* starting block for scan      */
      {
        block = start + ((NF_ZONE_MAX_CPT << 10) - NF_ZONE_MAX_CPT);
      }
      block_valid = FALSE;                                    /* init flag block valid */
      do
      {
        gl_address = (Uint32)(block) << 5;
        Nf_read_open_C_area_even(gl_address, 0x05);
        byte_5 = Nf_rd_byte_even();
        byte_6 = Nf_rd_byte_even();
    
        if ( (byte_5 == 0xFF) && (byte_6 == 0xFF) )           /* not assigned and valid block */
        {
          block_valid = TRUE;                                 /* find a correct block         */
        }
        else                                                  /* else decrease block number   */
        {
          if (block == start)                       
          {
            block = start + ((NF_ZONE_MAX_CPT << 10) - NF_ZONE_MAX_CPT);
          }
          else
          {
            block-=NF_ZONE_MAX_CPT;
          }
        }
        j++;
      }
      while (( !block_valid  ) && (j < 1024));
      if (j == 1024)
        return KO;
      lut_block[i] = block;                                   /* Update look up table address */
    }
  }
      
    
    /**********************************************************/
    /* Create the look-up table                               */
    /* Process is done zone per zone and by step of 256 blocks*/
    /* ********************************************************/
    for (nf_zone = 0; nf_zone < NF_ZONE_MAX_CPT; nf_zone++)           /* for each zone */
    {
      if (lut_is_present[nf_zone] == FALSE)
      {
        start = 0x00;
        end   = 0x40;                                             /* 256 bytes for gl_buffer <-> 64 blocks */

        free_bloc_pos_even  = (Uint16)(last_physical_used_block_even[nf_zone]);
        free_bloc_pos_odd   = (Uint16)(last_physical_used_block_odd[nf_zone]);
        gl_address          = (Uint32)(lut_block[nf_zone]) << 5; 
        lut_part            = 0;
        do
        {
          Nf_CS_EVEN();                                         /* even Part                  */
          nf_init_buffer();                                     /* reinitialize the buffer    */
          temp_address = (Uint32)(nf_zone) << 5;                /* at the beginning           */
          block        = (Uint16)(nf_zone);
          Nf_wait_busy_even();

          for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--)             /* for each block             */
          { 
            Nf_read_open_C_area_even(temp_address, 0x05);
            if (Nf_rd_byte_even() == 0xFF)                      /* If not a bad block         */
            {
              block2.b[0] = Nf_rd_byte_even();                  /* Read logical block address */
              block2.b[1] = Nf_rd_byte_even();
              if ( (block2.b[0] & 0xF8) == 0x10)
              {
                block2.w = (block2.w & 0x0FFF) >> 1;          
                if ( (block2.w < end) && (block2.w >= start)) 
                { 
                  gl_buffer[(Byte)(4 * block2.b[1])] = block >> 8;        /* Save logical block value */
                  gl_buffer[(Byte)(4 * block2.b[1] + 1)] = block & 0xFF;  /* in the buffer            */
                }
              }
            }
            temp_address += (NF_ZONE_MAX_CPT << 5); 
            block+=NF_ZONE_MAX_CPT;
          }
            
          /* affect to the free physical block a fictive logical block */
          /* free physical block => gl_buffer[x] = 0xFF */
          temp_address = (Uint32)(free_bloc_pos_even) << 5;
          for (j = 0; j <= 0xFC; j += 4)
          {
            if (gl_buffer[j] == 0xFF)
            {
              do                                                    /* Search free physical block */
              {
                temp_address += (NF_ZONE_MAX_CPT << 5);
                if (temp_address >= ((Uint32)(NF_ZONE_MAX_CPT) << 15) )
                    temp_address = (Uint32)(nf_zone) << 5;
                Nf_read_open_C_area_even(temp_address, 0x05);
                byte_5 = Nf_rd_byte_even();                          /* Invalid/Valid block */
                byte_6 = Nf_rd_byte_even();                          /* Used/Unused block   */
              }
              while ( ( (byte_6 != 0xFF) && (byte_6 != 0xE8) ) || (byte_5 != 0xFF) );
              free_bloc_pos_even = temp_address >> 5;
              gl_buffer[j] = (free_bloc_pos_even >> 8) | 0x80;
              gl_buffer[j + 1] = free_bloc_pos_even;
            }
          }

          Nf_CS_ODD();                                            /* Odd Part */  
          temp_address  = (Uint32)(nf_zone) << 5;                 /* We start at the beginning  */
          block         = (Uint16)(nf_zone);
          Nf_wait_busy_odd();
          for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--)               /* for each block             */
          { 
            Nf_read_open_C_area_odd(temp_address, 0x05);
            if (Nf_rd_byte_odd() == 0xFF)                         /* If not a bad block         */
            {
              block2.b[0] = Nf_rd_byte_odd();                     /* Read logical block address */
              block2.b[1] = Nf_rd_byte_odd();
              if ( (block2.b[0] & 0xF8) == 0x10)
              {
                
                block2.w = (block2.w & 0x0FFF) >> 1;          
                if ( (block2.w < end) && (block2.w >= start)) 
                { /* Save logical block value in the buffer */
                  gl_buffer[(Byte)(4 * block2.b[1] + 2)] = block >> 8;
                  gl_buffer[(Byte)(4 * block2.b[1] + 1 + 2)] = block;
          
                }
              }
            }
            temp_address += (NF_ZONE_MAX_CPT << 5); 
            block+= NF_ZONE_MAX_CPT;
          }
          
          /* affect to the free physical block a fictive logical block */
          /* free physical block => gl_buffer[x] = 0xFF */
          temp_address = (Uint32)(free_bloc_pos_odd) << 5;
          for (j = 2; j <= 0xFE; j+=4)
          {
            if (gl_buffer[j] == 0xFF)
            {
              do                                                /* Search free physical block */
              {
                temp_address += (NF_ZONE_MAX_CPT << 5);
                if (temp_address >= ((Uint32)(NF_ZONE_MAX_CPT) << 15) )
                    temp_address = (Uint32)(nf_zone) << 15;
                Nf_read_open_C_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 >> 5;
              gl_buffer[j] = (free_bloc_pos_odd >> 8) | 0x80;
              gl_buffer[j + 1] = free_bloc_pos_odd;
            }
          }
            
          Nf_CS_EVEN();
          Nf_wait_busy_even();  
          if (lut_part == 0)
          {
            Nf_write_open_A_area_even(gl_address, 0x00);    /* First part of LUT */
            nf_download_buffer();
          }
          else
          {
            Nf_write_open_B_area_even(gl_address, 0x00);
            nf_download_buffer();
            /* 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 */
            /* Increase the address of the conversion table */
            gl_address++;
          }
          lut_part = ~lut_part;

          Nf_send_command_even(NF_PAGE_PROGRAM_CMD);
          start    += 0x40;                                 /* process next 64 logical block   */
          end      += 0x40;
          nf_init_buffer();                                 /* reinitialize the global buffer   */
        }
        while (start < NF_BLOCK_PER_ZONE);
      }
  }
  Nf_wait_busy_even();
  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)
{   
Byte manufacturer;

  P2 = NF_IDLE_STATE_ADD;
  Nf_CS_EVEN();
  Nf_wait_busy_even();
  Nf_send_command_even(NF_RESET_CMD);
  Nf_CS_ODD();
  Nf_wait_busy_odd();
  Nf_send_command_odd(NF_RESET_CMD);
  Nf_wait_busy_odd();

  #if (NF_CAPACITY_AUTO_DETECT == TRUE)

    Nf_send_command_even(NF_READ_ID_CMD);
    Nf_send_address_even(0x00);
    manufacturer = Nf_rd_byte_even();
    nf_copy_back = FALSE;
    switch (Nf_rd_byte_even())
    {
      /******************************************************************************/
      case 0x73 :                                 /*--------- 2 * 16 Mbyte ---------*/
        nf_device_type = NF_SIZE_32MB;
        nf_zone_max = 1;                          /* 1 zone / slot : 1024 blocks    */
        nf_mem_size =  NF_SECTOR_SIZE_32MB - MEM_RESERVED_SIZE;
        nf_4_cycle_address = 0;                       /* 3 address cycles           */
      break;
      /******************************************************************************/
      case 0x75 :                                 /*--------- 2 * 32 Mbyte ---------*/
        nf_device_type = NF_SIZE_64MB;
        nf_zone_max = 2;                          /* 2 zones / slot : 2048 blocks   */
        nf_mem_size =  NF_SECTOR_SIZE_64MB - MEM_RESERVED_SIZE;
        nf_4_cycle_address = 0;                   /* 3 address cycles               */
        if (manufacturer == M_SAMSUNG)
        {
          nf_copy_back = TRUE;
        }
      break;
      /******************************************************************************/
      case 0x76 :                                  /*--------- 2 * 64 Mbyte --------*/
        nf_device_type = NF_SIZE_128MB;
        nf_zone_max = 4;                           /* 4 zones / slot : 4096 blocks  */
        nf_mem_size =  NF_SECTOR_SIZE_128MB - MEM_RESERVED_SIZE;
        nf_4_cycle_address = 1;                    /* 4 address cycles              */
        if (manufacturer == M_SAMSUNG)
        {
          nf_copy_back = TRUE;
        }
        break;
      /******************************************************************************/
      case 0x79 :                                  /*-------- 2 * 128 Mbyte --------*/
        nf_device_type = NF_SIZE_256MB;
        nf_zone_max = 8;                           /* 8 zones / slot : 8192 blocks  */
        nf_mem_size =  NF_SECTOR_SIZE_256MB - MEM_RESERVED_SIZE;
        nf_4_cycle_address = 1;                    /* 4 address cycles              */
        if (manufacturer == M_SAMSUNG)
        {
          nf_copy_back = TRUE;
        }        
        break;
      /******************************************************************************/
      default:                                     /* Nand Flash not recognise or   */
        return KO;                                 /* bad response                  */
      /******************************************************************************/
    }
  #else
    nf_mem_size = NF_DISK_SIZE - MEM_RESERVED_SIZE;
  #endif

  nf_reserved_space_start = nf_mem_size + 1;

  return OK;


}

/*F**************************************************************************
* NAME: nf_read_open

⌨️ 快捷键说明

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