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

📄 nand.c

📁 U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有很好的支持.
💻 C
📖 第 1 页 / 共 4 页
字号:
//+-----------------------------------------------------------------------------
// Name:
//   sm_power_up()
//
// Declaration:
//  t_result sm_power_up(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result nand_power_up(void) reentrant
{
  trace0(0, nand, 0, "nand_power_up()");
  return k_success ;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_reset_controller()
//
// Declaration:
//   void sm_reset_controller(void) reentrant
//
// Purpose:
//   erase all physical blocks on media card, then
//   rebuild sector mapping table
//
// Arguments:
//   none
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_reset_controller(void) reentrant
{
  trace0(0, nand, 0, "nand_reset_controller()");
}

//+-----------------------------------------------------------------------------
// Name:
//   dfa_sm_identify_media
//
// Declaration:
//   void dfa_sm_identify_media(void);
//
// Purpose:
//   determine if smart media is present the device and if so,
//   determine max lba and lb size
//
// Arguments:
//   none
//
// Return:
//   none
//
// Notes:
//   This is a DFA
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_identify_media(void) reentrant
{
  trace0(0, nand, 0, "nand_dfa_identify_media()");
  _lun_data(media) |= kbm_lun_media_unknown ;

  if (k_success != nand_check_format())
  {
    trace0(0, nand, 0, "nand_check_format() returned an error!") ;
      _thread_return_dfa(k_error) ;
  }

  _lun_data(capacity.lba_max.u32) = _media_data(num_zones) * (uint32) _media_data(logical_blocks_per_zone) * (uint32) _media_data(pages_per_block) ;
  _lun_data(capacity.lba_sz.u32)  = 512 ;

  if( x_media_sts & kbm_media_sts_sm_256_page )
    _lun_data(capacity.lba_max.u32) /= 2 ;
  if( k_ix_media_nand_2k == g_active_media)
    _lun_data(capacity.lba_max.u32) *= 4 ;

  _lun_data(capacity.lba_max.u32) -= (uint32) 1 ;

  // media is now known
  _lun_data(media) &= ~kbm_lun_media_unknown;
  _lun_data(sensep) = &sense_media_change;

  if(x_media_sts & kbm_media_sts_sm_wp )
    _lun_data(media) |= kbm_lun_media_wrprot ;
  else
    _lun_data(media) &= ~kbm_lun_media_wrprot ;

#if 1
  // check attributes
  if(g_dev_attr_lo&kbm_attr_lo_sm_timing)
  {
    trace0(0, nand, 0, "Forcing Smart Media-Compatible Cycle Timing on NAND flash") ;
    g_nand_rw_speed=0;
  }
  else
  {
    trace0(0, nand, 0, "Enabling fast cycle time on NAND flash") ;
    g_nand_rw_speed=kbm_sm_mode_fast_cycle_time;
  }
#else
  g_nand_rw_speed=0;
#endif
  trace2(0, nand, 0, "nand capacity:  lba_max:%04x%04x lba_sz:00000200", _hw(_lun_data(capacity.lba_max.u32)), _lw(_lun_data(capacity.lba_max.u32))) ;


  thread_return_dfa(k_success) ;
}

//+-----------------------------------------------------------------------------
// Name:
//   TBD
//
// Declaration:
//   TBD
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   This is a DFA, not a FUNCTION.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_initialize_media() reentrant
{
  trace0(0, nand, 0, "nand_dfa_initialize_media()");
  _lun_data(media) &= ~kbm_lun_media_changed;
  trace2(0, lun, 0, "_lun_data(%d, media)=%02x", g_active_media, _lun_data(media));
  _thread_return_dfa(k_success);
}

//+-----------------------------------------------------------------------------
// Name:
//   TBD
//
// Declaration:
//   TBD
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   This is a DFA, not a FUNCTION.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_reset_media() reentrant
{
  trace0(0, nand, 0, "nand_dfa_reset_media()");
  _thread_return_dfa(k_success);
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_initialize_controller()
//
// Declaration:
//   void sm_initialize_controller(void) reentrant
//
// Purpose:
//   TBD
//
// Arguments:
//   TBD
//
// Return:
//   TBD
//
// Notes:
//   TBD
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_initialize_controller(void) reentrant
{
  uint16 i;
  trace0(0, nand, 0, "nand_initialize_controller()") ;

  // initialize _lun_data
  memcpy(_lun_data(device_id), "HD", k_lun_max_devid_sz) ;
  _lun_data(media) &=~ kbm_lun_media_unknown ;
  g_nand_rw_speed=0 ;

#ifdef k_opt_password
  _lun_data(media) |= kbm_lun_media_lockable;
#endif
  // by default, it is thus.  However, we must check at run-time
  // whether or not to keep it such.  The removable bit is first used
  // checked on Inquiry processing
  _lun_data(media) &=~ kbm_lun_media_removable;
  _lun_data(device_type) = k_device_type_nand ;

  // we have to make sure we wait at least 1 ms before accessing the device,
  // but we don't have a timer running yet
  i=1000 ;
  while(i--) ;

  // try to identify the media configuration
  fmc_select_nand() ;
  if ( k_success != nand_identify_media_format() )
  {
    trace0(0, nand, 0, "failed to identify media format") ;
    return;
  }

// $$$ intercepting
  // util_trace_media() ;
  // util_trace_map_media() ;

  // read the boot block to see if out custom boot structure exists.
  nand_boot_seek() ;

#ifdef k_enable_write_caching
  // initialize the write head/tail cache
  map_write_cache_init() ;
#endif

  // safe erase the media here...  for utilitarian purposes
  // util_safe_erase_media() ;
  // util_trace_map_media();
  
/*
  for(g_addr_rd_phy_blk=0;g_addr_rd_phy_blk<8;g_addr_rd_phy_blk++)
  {
    util_trace_phy_block();
  }
*/  

  // util_trace_log_media();
/*
  g_addr_rd_phy_blk=0;
  g_addr_page=0;
  _media_data(boot_block)=0;
  _media_data(boot_page)=0;
  _media_data(assign_zone)=0;
  g_addr_zone=0;
  map_build_sector_map();
  util_test_copy_double_bit_ecc(33) ;
*/

  // store initial state of the wp bit.
  _nand_media_status = _mcu_register_rd(x_media_sts) ;
}

//------------------------------------------------------------------------------
void nand_dfa_inquiry(void) reentrant
{
  trace0(0, nand, 0, "nand_dfa_inquiry()") ;

  // check attribute bit... will be valid by this point
  if(g_dev_attr_lo&kbm_attr_lo_hd_as_rm)
  {
    trace0(0, nand, 0, "kbm_attr_lo_hd_as_rm bit set.  Reporting lun as Removable") ;
    _lun_data(media)|=kbm_lun_media_removable ;
  }
  else if(x_media_sts&kbm_media_sts_sm_wp )
  {
    trace0(0, nand, 0, "nand write protected.  Reporting lun as Removable") ;
    _lun_data(media)|=kbm_lun_media_removable ;
  }
  else if(!g_password_validated)
  {
    trace0(0, nand, 0, "Password exists, and is not validated.  Make removable") ;
    _lun_data(media)|=kbm_lun_media_removable;
  }
  else
  {
    trace0(0, nand, 0, "reporting lun as Fixed Media") ;
    _lun_data(media)&=~kbm_lun_media_removable ;
  }

  // call base class
  dfa_lun_inquiry() ;
}

//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result nand_check_wp() reentrant
{
  uint8 cs ;
  trace0(0, nand, 0, "nand_check_wp()") ;

  if( _lun_data(media)&kbm_lun_media_removable)
  {
    // check to see if there's been a change
    cs=_mcu_register_rd(x_media_sts)&kbm_media_sts_sm_wp;
    _nand_media_status&= kbm_media_sts_sm_wp;
    if(_nand_media_status^cs)
    {
      trace2(0, nand, 0, "media_sts sm_wp bit change detected.  _nand_media_status:%02X x_media_sts:%02X", _nand_media_status, x_media_sts) ;
      _lun_data(sensep) = &sense_media_change ;
      _lun_data(media) |= kbm_lun_media_unknown;
      _nand_media_status=cs;
      // change
      return k_true ;
    }
  }
  // no change in wp status
  return k_false ;

}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void nand_process_idle() reentrant
{
  trace0(0, nand, 0, "nand_dfa_process_idle()") ;
#if 0
  if( _media_data(options)&kbm_media_data_opt_write_cache)
  {
    trace0(0, nand, 0, "flushing write cache()") ;
    map_write_cache_flush_all();
  }
#endif
  if( _media_data(options)&kbm_media_data_opt_erase_cache)
  {
    trace0(0, nand, 0, "flushing erase cache()") ;
    map_erase_cache_flush_all();
  }
  _lun_data(media)&=~kbm_lun_media_process_idle;
}

//+-----------------------------------------------------------------------------
// Name:
//   nand_dfa_test_unit_ready
//
// Declaration:
//   void dfa_lun_test_unit_ready(void);
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//   This allows us to check if the wp status has 'changed' since previous cmd.
//   if so, then report a media change.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_test_unit_ready(void)reentrant
{
  trace0(0, nand, 0, "nand_dfa_test_unit_ready()");
  
  // if happy, check wp status.  this function will update sensep
  if( _lun_data(sensep) == &sense_none)
    nand_check_wp() ;

  // call base-class
  dfa_lun_test_unit_ready() ;
  // report sense as normal.
  _thread_return_dfa((_lun_data(sensep) == &sense_none) ? k_command_passed : k_command_failed);
}



//+-----------------------------------------------------------------------------
// Name:
//   sm_dfa_verify()
//
// Declaration:
//   void sm_dfa_verify(void);
//
// Purpose:
//   Verify that the data on the drive matches the data sent down.
//
// Arguments:
//   None.
//   Uses _lun_data and g_bot_cbw to get its parameters.
//
// Return:
//   No return value.
//   However, on exit the DFA's argument pointer is written with a t_csw_status indicating:
//     k_command_passed - command completed.
//     k_command_failed - an error occurred.
//
// Notes:
//   This is the start STATE of the dfa_ata_verify DFA.
//   It overrides dfa_lun_verify.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_verify() reentrant
{
  trace0(0, nand, 0, "dfa_ata_verify");
  // _fmc_set_callback(sm_read_begin_xfer, sm_read_end_xfer, sm_read_begin_split, sm_read_end_split, sm_read_begin_burst, fmc_dflt_callback, sm_read_end_burst);
  dfa_lun_verify();
}




⌨️ 快捷键说明

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