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

📄 sm.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
        trace0(0, sm, 0, "waiting for buffer to go out...") ;
      }
      trace0(0, sm, 0, "buffer tx'd... should see it on the catc") ;
    }
    else
    {
      _mcu_register_wr(x_ramrdbc_b1, 0x02);
      _mcu_register_wr(x_ramrdbc_b2, 0x00);
      _mcu_register_wr(x_ep2_ctl, kbm_ep2_ctl_rdtog_valid |(_mcu_register_rd(x_ep2_ctl) | kbm_ep2_ctl_ramrd_tog));
      _hdw_clk_domain_bug_workaround();
      while ( !(x_isr0&kbm_isr0_ramrd_b))
        ;
    }
    // only turn auto xfer back on if there's more to xfer
    if ( x_fmc_cnt0|x_fmc_cnt1|x_fmc_cnt2|x_fmc_cnt3)
    {
      trace0(0, sm, 0, "auto transfer ON") ;
      _mcu_register_set_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
      return (k_resume );
    }
    else
    {
      trace0(0, sm, 0, "xfer is done, DON'T resume") ;
      return (k_success);
    }
  }
  // wait for device
  if ( k_success == result)
  {
    result = sm_wait_rdy_with_timeout(k_sm_busy_read_timeout) ;
  }
  if (k_success != result)
  {
    nand_cmd_reset_device();
    result =  k_error ;
  }
  trace0(0, sm, 0, "leaving read data portion") ;
  return (result );
}



//+-----------------------------------------------------------------------------
// Name:
//   dfa_sm_read
//
// Declaration:
//   void dfa_sm_read(void) reentrant
//
// Purpose:
//   Read data from sm media
//
// Arguments:
//   None.
//   Uses _lun_data and g_bot_cbw to get its parameters.
//k
// 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_read DFA.
//   It overrides dfa_lun_read.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void sm_dfa_read(void) reentrant
{
  trace0(0, sm, 0, "dfa_sm_read");
  _fmc_set_options(0);
  _fmc_set_timeout(10000);
  _fmc_set_callback(sm_read_begin_xfer, sm_read_end_xfer,
                    sm_read_begin_split, sm_read_end_first_split,
                    fmc_dflt_callback, fmc_dflt_callback, sm_read_end_burst);

#ifdef k_enable_write_caching

  // catch the cache
  if (_media_data(options)&kbm_media_data_opt_write_cache)
    map_write_cache_flush_all() ;
#endif

  dfa_lun_read();
}


//+-----------------------------------------------------------------------------
// Name:
//   dfa_sm_write
//
// Declaration:
//   void dfa_sm_write(void) reentrant
//
// Purpose:
//   Read data from sm media
//
// 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_write DFA.
//   It overrides dfa_lun_write.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_begin_xfer(void) reentrant;
t_result sm_write_begin_xfer() reentrant
{
  t_result result ;

  trace4(0, sm, 10, "sm_write_begin_xfer() - start:0x%04X%04X count:0x%04X%04X" , _hw(_fmc_get_start_lb_32()), _lw(_fmc_get_start_lb_32()), _hw(_fmc_get_lb_count_32()), _lw(_fmc_get_lb_count_32()));

  _lun_data(sensep) = &sense_write_error;

  // copy head sectors...
  result = map_write_begin( _fmc_get_start_lb_32() ) ;

  if (!g_addr_page)
  {
    _lun_data(max_lb_per_split) = _min( _media_data(pages_per_block), _fmc_get_lb_count_32());
    trace5(0, sm, 10, "-----write begin xfer - zone:%d phy:%d log:%d page:%d count:%d - first in block", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page, _lun_data(max_lb_per_split) );
  }
  else
  {
    _lun_data(max_lb_per_split) = _min( _media_data(pages_per_block) - g_addr_page, _fmc_get_lb_count_32());
    trace5(0, sm, 10, "-----write begin xfer - zone:%d phy:%d log:%d page:%d count:%d", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page, _lun_data(max_lb_per_split));
  }
  _lun_data(max_lb_per_burst) = 1 ;

  return (result );
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_write_end_xfer
//
// Declaration:
//   t_result sm_write_end_xfer(void);
//
// Purpose:
//   TBD
//
// Arguments:
//   None.
//
// Return:
//   TBD
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   Do not yeild, or run a DFA, from within this callback.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_end_xfer(void) reentrant
{
  t_result result ;
  trace0(0, sm, 1, "sm_write_end_xfer()") ;

  if (k_success != _fmc_get_result())
    return (k_error);

  _mcu_register_clr_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
  trace0(0, fmc, 0, "auto-transfer bit ==> OFF");

  result=map_write_flush() ;
  if (_media_data(options)&(kbm_media_data_opt_write_cache|kbm_media_data_opt_erase_cache))
  {
    _lun_data(media)|=kbm_lun_media_process_idle;
  }
  _sm_hw_set_wr_standby() ;
  _sm_hw_set_rd_standby() ;
  if (k_success == result)
    _lun_data(sensep) = &sense_none;
  return (result );
}




//+-----------------------------------------------------------------------------
// Name:
//   sm_write_begin_split
//
// Declaration:
//   t_result sm_write_begin_split(void);
//
// Purpose:
//   Issue the write command to the smart media device.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - command completed.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   Do not yeild, or run a DFA, from within this callback.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_begin_split() reentrant
{
  uint8 zone_before ;
  trace0(0, sm, 1, "sm_write_begin_split()");
  trace1(0, sm, 0, "g_addr_rd_phy_blk: %d", g_addr_rd_phy_blk) ;

  zone_before = g_addr_zone ;

  // if a new physical block, tell the mapper to go git us one.
  if (k_success != map_lba2addr_rd(_fmc_get_start_lb_32()))
    return(k_error);

  if (g_addr_zone != zone_before)
  {
    // we've crossed a boundry on a split, do a reset
    trace0(0, sm, 0, "*** trigger ***  issuing a soft reset on zone-change, in case a sector map was paged in") ;
    sm_set_write_mode_page_data();
  }

  if (map_is_addr_first_in_block())
  {
    if (k_success != map_alloc_wr_blk())
      return(k_error);
  }


  // convert virtual address zone/block/sector into page/offsets
  nand_rd_va2pa() ;
  nand_wr_va2pa() ;

  trace0(0, sm, 0, "ready to begin writing sectors") ;
  return (k_success);
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_write_begin_first_split
//
// Declaration:
//   t_result sm_write_begin_split(void);
//
// Purpose:
//   Issue the write command to the smart media device.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - command completed.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   Do not yeild, or run a DFA, from within this callback.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_begin_first_split() reentrant
{
  trace0(0, sm, 1, "sm_write_begin_first_split()");

  // make sure we're in the right mode - fixes a bug where
  // the first burst of the first split of the xfer begins
  // on a zone that needed to be paged in...
  sm_set_write_mode_page_data();

  // compute phy addresses in case this is the first sector
  nand_wr_va2pa() ;
  nand_rd_va2pa() ;

  _fmc_set_callback(sm_write_begin_xfer, sm_write_end_xfer,
                    sm_write_begin_split, sm_write_end_split,
                    sm_write_begin_burst, fmc_dflt_callback, sm_write_end_burst);
  return (k_success);
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_write_end_split
//
// Declaration:
//   t_result sm_write_end_split(void);
//
// Purpose:
//   nothing to do at the beginning of a split
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - command completed.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   Do not yeild, or run a DFA, from within this callback.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_end_split(void) reentrant
{
  trace0(0, sm, 0, "sm_write_end_split()") ;

  // remove the auto-increment at end_burst.
  g_addr_page-= 1 ;
  // see if that finished the phyblock
  if (map_is_addr_last_in_block())
  {
    if (k_success != map_rebind_log_blk())
    {
      trace0(0, sm, 0, "mapper error updating logical bindings") ;
      return (k_error );
    }
  }
  _sm_hw_set_wr_standby();
  _sm_hw_set_rd_standby();

  // do full-block splits to avoid split overhead on every sector.
  _lun_data(max_lb_per_split) = _media_data(pages_per_block) ;
  return (k_success );
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_write_begin_burst
//
// Declaration:
//   t_result sm_write_begin_burst(void);
//
// Purpose:
//   Issue the write command to the smart media device.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - command completed.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   Do not yeild, or run a DFA, from within this callback.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_write_begin_burst() reentrant
{
  trace4(0, sm, 0, "+sm_write_begin_burst() - zone:%d WR_PHY:%d log:%d page:%d", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page) ;
  _sm_set_wr_cmd(k_sm_write_data);
  _media_set_write_addr() ;
  _mcu_register_set_bits(sm_mode_ctl, kbm_sm_mode_ecc_blk_xfer_en);
  _sm_hw_ecc_wr_start() ;
  _mcu_register_wr(x_smc_stat, kbm_smc_stat_rdy);
  trace1(0, sm, 0, "smc_mode_ctl: %02x", sm_mode_ctl);
  trace1(0, sm, 0, "    smc_stat: %02x", x_smc_stat);

  trace0(0, sm, 0, "ready for burst") ;
  return (k_success);
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_write_end_burst
//
// Declaration:
//   t_result sm_write_end_burst(void);
//
// Purpose:
//   TBD
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k

⌨️ 快捷键说明

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