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

📄 nf.c

📁 D12 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

/*_____ E X T E R N  V A R I A B L E ___________________________________*/
extern data    Uint32	gl_ptr_mem;         /* memory data pointer */
extern data    Byte		EnglishPage;
extern bdata 	Byte		PlayStatusSign;
extern xdata 	Byte		sound_mode;
extern xdata 	Byte		light_mode;
extern xdata   Byte		PlayVolume;
extern pdata   Byte		gl_buffer[];
extern bdata 	bit		light_bit;
extern bdata 	bit		record_open_bit;
extern bdata	bit		NormalPlay;
extern xdata 	Uint16	nb_reserved_sector;
extern xdata	Byte		ReplayTime;
extern  Union_IDATA xdata UnionIDATA;
extern  Union_XDATA xdata UnionXDATA;
/*_____ EXTERN ADDRESS _________________________________________________*/

xdata Byte nf_send_cmd At(NF_CMD_LATCH_ENABLE_ADD); /* Command */
xdata Byte nf_send_add At(NF_ADD_LATCH_ENABLE_ADD); /* Address */
xdata Byte volatile nf_data At(NF_ADDRESS_CMD_DATA);/* Data    */

extern void 	nf_read_init(Uint32 offset);
void store_read(void);
void store_write(void);
/*_____ V A R I A B L E ________________________________________________*/
bdata bit block_used;    /* When a block was used */
bdata bit nf_busy;
bdata	bit nf_64=1;

data  Uint32 current_physical_sector_addr;
data  Uint32 address;
data  Uint16 look_up_table_block;                   /* Look up table block address  */
data  Byte 	 index_block_erased = 0;              /* give the number of block to be erased      */
xdata Byte   store_ptr;

idata Uint32 address_look_up_table;
idata Uint16 gl_cpt_page;
idata Byte   index_reassign;                  /* give the number of block to be reassigned  */
idata Byte   nf_zone_max;                     /* max zone number (from 1 to 8)              */
idata Byte 	 nf_device_type;                  /* Give the size of device in Mbytes          */ 
idata Byte 	 index_look_up_table;             /* Index of free block for LUT                */
idata Uint16 redundant_logical_block_value; /* Logical block value in the redundant area  */

idata Uint16 block_to_be_erased[NF_FREE_BLOCK_SIZE];/* Block address to be erased   */
idata Byte index_block_used[NF_FREE_BLOCK_SIZE];    /* Index of new assigned block */
xdata Byte nf_spare_block_number[NF_ZONE_MAX];      /* Number of free spare block in each zone */
xdata Uint32 nf_disk_size;            /* Size of the disk in sector - 1  */ 
xdata Byte index_free_block[NF_ZONE_MAX];   /* index in the LUT for free block for data   */

/* reassign_block : conversion logical block/physical block   */
/* it's used to update the look up table                      */
xdata t_reassign_block  reassign_block[NF_FREE_BLOCK_SIZE];
/*_____ D E F I N I T I O N ____________________________________________*/

/*_____ C O D E ________________________________________________________*/
/* Card Identification System definition */
code Byte nf_cis_table[]=
  {
  0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21,
  0x02, 0x04, 0x01, 0x22, 0x02, 0x01, 0x01, 0x22, 0x03, 0x02, 0x04, 0x07, 0x1A, 0x05, 0x01, 0x03, 
  0x00, 0x02, 0x0F, 0x1B, 0x08, 0xC0, 0xC0, 0xA1, 0x01, 0x55, 0x08, 0x00, 0x20, 0x1B, 0x0A, 0xC1, 
  0x41, 0x99, 0x01, 0x55, 0x64, 0xF0, 0xFF, 0xFF, 0x20, 0x1B, 0x0C, 0x82, 0x41, 0x18, 0xEA, 0x61, 
  0xF0, 0x01, 0x07, 0xF6, 0x03, 0x01, 0xEE, 0x1B, 0x0C, 0x83, 0x41, 0x18, 0xEA, 0x61, 0x70, 0x01, 
  0x07, 0x76, 0x03, 0x01, 0xEE, 0x15, 0x14, 0x05, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x30, 0x2E, 0x30, 0x00, 0xFF, 0x14, 0x00, 0xFF, 0x00, 0x00

  };


extern bdata bit Nf_WP;
/*_____ D E C L A R A T I O N ______________________________________________*/
 

/*F**************************************************************************
* NAME:     read_spare_byte
----------------------------------------------------------------------------
* PURPOSE:  read spare data byte and construct the look up table.

*****************************************************************************/
Uint16 read_spare_byte_sub(Byte mode,Byte nf_zone,Uint16 start,Uint16 free_bloc_pos);

void read_spare_byte(void)
{
  Uint16 free_bloc_pos,start,block;
  Uint16 i,j;
  Byte   dummy,nf_zone;
//  idata Uint32 address2; /* LUT table address */
//  idata Uint32 address3; /* Used to determine free physical block */
  bit    bad_block;
  xdata Uint16 last_physical_used_block[NF_ZONE_MAX]; /* Last physical block used     */


  Nf_CS_ON();
  /***************************************************/
  /* Search bad block                                */
  /***************************************************/
	address = 0x8000;            /* Start from sector 0 */
	Nf_wait_busy();
	for (j = NF_BLOCK_PER_ZONE; j != 0; j--) /* Only zone 0 */
	{
		nf_send_rc_cmd();
		if ( Nf_rd_byte() == 0xFF )				/* Not a bad block */
		{
			if ( Nf_rd_byte() == 0xE8)				/* Look up table? */
			{
				nf_block_erase(address);
			}
		}
		address += 32;
	}

  address = 0;            /* Start from sector 0 */
  Nf_wait_busy();
  for (i = 0; i < nf_zone_max; i++)
  {
    nf_spare_block_number[i] = 0;
    for (j = NF_BLOCK_PER_ZONE; j != 0; j--)
    {
		nf_send_rc_cmd();
      if ( Nf_rd_byte() != 0xFF )                 /* 0xFF = valid block */
        nf_spare_block_number[i]++;
      else
      {
        dummy = Nf_rd_byte();
			if (  (dummy == 0x00) || ( (dummy != 0xFF) && ( (dummy & 0xF8) != 0x10 )) )	// Value in redundant spare area not correct 
			{
				nf_spare_block_number[i]++;
				if(i == 1)
				{
					gl_buffer[nf_spare_block_number[1]-1] = dummy;
				}
			}
      }
      address += 32;
    }
  }

	for (i = 0; i < nf_zone_max; i++)
	{
		nf_spare_block_number[i] = (32 - nf_spare_block_number[i]) << 1;
	}

  /***************************************************/
  /* Search a look-up table and erase it             */
  /***************************************************/
  address = 0;
  Nf_wait_busy();
  for (j = NF_BLOCK_PER_ZONE; j != 0; j--) /* Only zone 0 */
  {
	nf_send_rc_cmd();
    if ( Nf_rd_byte() == 0xFF )				/* Not a bad block */
    {
      if ( Nf_rd_byte() == 0xE8)				/* Look up table? */
      {
        nf_block_erase(address);
      }
    }
    address += 32;
  }
  /***************************************************/
  /* Find the last physical block used for each zone */
  /***************************************************/
  for (nf_zone = 0; nf_zone < nf_zone_max; nf_zone++)
  {
    last_physical_used_block[nf_zone] = (Uint16)(nf_zone) << 10;
    address = (Uint32)(nf_zone) << 15;
    Nf_wait_busy();   
    for (j = NF_BLOCK_PER_ZONE; j != 0; j--)
    {
		nf_send_rc_cmd();
      if ( Nf_rd_byte() == 0xFF)                  /* Not a bad block            */
      {
        dummy = Nf_rd_byte();
        if ( ((dummy & 0xF8) == 0x10) && (dummy != 0x00) )       /* Used block                 */
        {
          last_physical_used_block[nf_zone] = address >> 5;
        }
      }
      address += 32;
    }
  }

  
  /***************************************************/
  /*          Find free physical block for LUT       */
  /***************************************************/
  address = 0;
  do
  {
    bad_block = FALSE;
    /* Send READ C Area command */

	nf_send_rc_cmd();

    if (Nf_rd_byte() == 0xFF)                   /* Not a bad block            */
      dummy = Nf_rd_byte();
    else
      bad_block = TRUE;
    address += 32;
  }
  while ( (dummy != 0xFF) || (dummy == 0x00) || (bad_block) );

  address -= 32;
  /* Updata look up table address */
  look_up_table_block = address >> 5;
  address_look_up_table = address;

  /*********************************************************/
  /* Create the look-up table                              */
  /* ***************************************************** */
  for (nf_zone = 0; nf_zone < nf_zone_max; nf_zone++)           /* for each zone */
  {
    start = 0;                                /* initialize the logical block value */
    free_bloc_pos = last_physical_used_block[nf_zone];
    do
    {
	  free_bloc_pos = read_spare_byte_sub(MODE_CMDA,nf_zone,start,free_bloc_pos);
      start += 128;                           /* process next 128 logical block */
	  free_bloc_pos = read_spare_byte_sub(MODE_CMDB,nf_zone,start,free_bloc_pos);
      start += 128;  
      address++;
    }
    while (start < NF_BLOCK_PER_ZONE);
  }
  /***************************************************/
  /*                Recopy the LUT                   */
  /***************************************************/
  index_look_up_table = 20;
  index_free_block[0] = 0;

  address = address_look_up_table + 3;

  Nf_wait_busy();

  Nf_send_command(NF_READ_B_AREA_CMD);       
  Nf_send_address(0x00);
  Nf_send_address ( ((Byte*)&address)[3] );   
  Nf_send_address ( ((Byte*)&address)[2] );   
  if (nf_64)                                  
    Nf_send_address ( ((Byte*)&address)[1] ); 
  Nf_wait_busy();

  nf_upload_buffer();
  
  block = (gl_buffer[192] << 8) + gl_buffer[193];

  block = block & 0x7FFF;

  if (block != look_up_table_block)
  {
    address = (Uint32)(block) << 5;
    for (j = 32; j != 0; j--)
    {
      Nf_wait_busy();

      Nf_send_command(NF_READ_A_AREA_CMD);
      Nf_send_address(0x00);
      Nf_send_address ( ((Byte*)&address_look_up_table)[3] );   
      Nf_send_address ( ((Byte*)&address_look_up_table)[2] );   
      if (nf_64)                                                
        Nf_send_address ( ((Byte*)&address_look_up_table)[1] ); 
      Nf_wait_busy();
      nf_upload_buffer();

	  nf_send_w_cmd(MODE_CMDA,0);

      nf_download_buffer();
  
      Nf_send_command(NF_PAGE_PROGRAM_CMD);
      Nf_wait_busy();

      Nf_send_command(NF_READ_B_AREA_CMD);
      Nf_send_address(0x00);
      Nf_send_address ( ((Byte*)&address_look_up_table)[3] );  
      Nf_send_address ( ((Byte*)&address_look_up_table)[2] );  
      if (nf_64)        
        Nf_send_address ( ((Byte*)&address_look_up_table)[1] );
      Nf_wait_busy();

      nf_upload_buffer();

	  nf_send_w_cmd(MODE_CMDB,0);
      nf_download_buffer();
  
      /* Write redundant data */
      Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); Nf_wr_byte(0xFF);
      Nf_wr_byte(0xFF); Nf_wr_byte(0xFF);
      Nf_wr_byte(0xFF);
      Nf_wr_byte(0xE8); Nf_wr_byte(0xFF);                   /* Logical block value */
      Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); /* ECC area 2 */
      Nf_wr_byte(0xE8); Nf_wr_byte(0xFF);                   /* Logical block value */
      Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); Nf_wr_byte(0xFF); /* ECC area 1 */
  
      Nf_send_command(NF_PAGE_PROGRAM_CMD);
      address++;
      address_look_up_table++;
    }
  
    /* Erase old LUT */
    nf_block_erase(address_look_up_table - 1);
    /* New address of LUT */
    look_up_table_block = block;
    address_look_up_table = (Uint32)(block) << 5;
  }
  Nf_CS_OFF();

}
//------------------------
Uint16 read_spare_byte_sub(Byte mode,Byte nf_zone,Uint16 start,  Uint16 free_bloc_pos)
{
data	Uint16 block;
idata Uint32 address2; 
idata Uint32 address3; 
data	Uint16 i,j;
data	Byte   dummy;
bdata	bit    bad_block;

	nf_init_buffer();                       /* Reinitialize the buffer  */
	address2 = (Uint32)(nf_zone) << 15;     /* Block address            */
	Nf_wait_busy();
  
	for (j = NF_BLOCK_PER_ZONE; j != 0 ; j--)            /* for each block */
	{ // Read Spare data value 
		Nf_send_command (NF_READ_C_AREA_CMD);
		Nf_send_address ( 0x05 );
		Nf_send_address ( ((Byte*)&address2)[3] );  
		Nf_send_address ( ((Byte*)&address2)[2] );  
		if (nf_64)                                  
		{
			Nf_send_address ( ((Byte*)&address2)[1] );
		}
		Nf_wait_busy();

		// Calculate the logical/physical conversion 
		if (Nf_rd_byte() == 0xFF)                   // Not a bad block 
		{
			// Read the value of logical block 
			((Byte*)&block)[0] = Nf_rd_byte();
			((Byte*)&block)[1] = Nf_rd_byte();
          // Don't take bad block or unused block 
			if ((block != 0xFFFF) && (block != 0x0000))
			{
				// Calculate the logical block value 
            block = (block & 0x0FFF) >> 1;
            // If the value is in the range, then save it 
            if ( (block < start + 128) && (block >= start))
            {
					gl_buffer[2 * block] = (address2 >> 5) >> 8;
					gl_buffer[2 * block + 1] = address2 >> 5;
				}
			}
		}
		address2 += 32; // increase address 
	}
      
	address3 = (Uint32)(free_bloc_pos) << 5;
	for (i = 0; i < 256; i+=2)
	{
		if (gl_buffer[i] == 0xFF)
		{
			do   // Search free physical block 
			{
				bad_block = FALSE;
				address3 += 32;
				if (address3 >= ((Uint32)(nf_zone + 1) << 15) )
				{
					address3 = (Uint32)(nf_zone) << 15;
				}

				Nf_send_command(NF_READ_C_AREA_CMD);
				Nf_send_address(0x05);
				Nf_send_address ( ((Byte*)&address3)[3] );  
				Nf_send_address ( ((Byte*)&address3)[2] );  
				if (nf_64)
				{
					Nf_send_address ( ((Byte*)&address3)[1] );
				}
				Nf_wait_busy();

				if (Nf_rd_byte() == 0xFF)                   // Not a bad block ? 
				{
					dummy = Nf_rd_byte();
				}
				else
				{
					bad_block = TRUE;
				}
			}
			while ( (dummy != 0xFF) || (dummy == 0x00) || (bad_block) );
			free_bloc_pos = address3 >> 5;
			gl_buffer[i] = (free_bloc_pos >> 8) + 0x80;
			gl_buffer[i + 1] = free_bloc_pos;
		}
	}

	nf_send_w_cmd(mode,0);
	// Write 256 bytes from the buffer 
	nf_download_buffer();  
	// Valid the page programmation 
	Nf_send_command(NF_PAGE_PROGRAM_CMD);
	return free_bloc_pos;
}
//------------------------
void nf_send_rc_cmd()
{
	Nf_send_command (NF_READ_C_AREA_CMD);
    Nf_send_address ( 0x05 );
    Nf_send_address ( ((Byte*)&address)[3] );  /* 2nd address cycle         */
    Nf_send_address ( ((Byte*)&address)[2] );  /* 3rd address cycle         */
    if (nf_64)                                  /* Size of card >= 64Mbytes ?*/
      Nf_send_address ( ((Byte*)&address)[1] );/* 4th address cycle         */

    Nf_wait_busy();
}
//------------------------
void nf_send_ra_cmd()
{
	Nf_send_command (NF_READ_A_AREA_CMD);
	Nf_send_address ( 0x00 );              
	Nf_send_address ( ((Byte*)&current_physical_sector_addr)[3] ); 
	Nf_send_address ( ((Byte*)&current_physical_sector_addr)[2] ); 
	if (nf_64)
	{        
		Nf_send_address ( ((Byte*)&current_physical_sector_addr)[1] );
	}
}
//------------------------
void nf_send_w_cmd(Byte Mode,bit Par)
{
	Nf_wait_busy();
	if (Mode == MODE_CMDA)
	{
		Nf_send_command (NF_READ_A_AREA_CMD);
	}
	else
	{
		Nf_send_command (NF_READ_B_AREA_CMD);
	}
	Nf_send_command(NF_SEQUENTIAL_DATA_INPUT_CMD);
	Nf_send_address (0x00);

	if(!Par)
    {
	   	Nf_send_address ( ((Byte*)&address)[3] );   
   		Nf_send_address ( ((Byte*)&address)[2] );   
   		if (nf_64)                                  
      	Nf_send_address ( ((Byte*)&address)[1] );  
  	}
	else
    {
   		Nf_send_address ( ((Byte*)&current_physical_sector_addr)[3] );   
	   	Nf_send_address ( ((Byte*)&current_physical_sector_addr)[2] );   
   		if (nf_64)                                  
  		   Nf_send_address ( ((Byte*)&current_physical_sector_addr)[1] ); 
	}
}
/*F**************************************************************************
* NAME:     nf_init

*----------------------------------------------------------------------------
* PURPOSE:  NF initialisation

*****************************************************************************/
//bdata bit		nf_connect=1;
extern void	load_hex(Byte i ,Byte j, Byte buf);
extern void	lcd_deal(void);

void nf_init (void)
{
	Nf_CS_ON();
	/* Read ID code */
	Nf_send_command(NF_READ_ID_CMD);
	Nf_send_address(0x00);
	Nf_wait_busy();

	ACC = Nf_rd_byte();

//	if (0XEC == Nf_rd_byte())nf_connect=KO;

	switch (Nf_rd_byte())   /* Device code */
	{
		case 0x73 :                         /* 16 Mbyte  */
			nf_device_type = NF_SIZE_16MB;
			nf_zone_max = 1;
			nb_reserved_sector=1;
			nf_disk_size =  NF_SECTOR_SIZE_16MB;

⌨️ 快捷键说明

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