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

📄 fmc.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
void fmc_select_sdc() reentrant
{
#if (k_log_lun_sd < k_max_log_lun)
  _mcu_begin_critical_section();
  x_fmc_mode_ctl=k_fmc_mode_sdc;
  TRACE1(18, fmc, 0, "select sd/mmc device.  fmc_out_ctl:0x%02X fmc_mode_ctl:0x%02X", x_fmc_mode_ctl);
  // throttle up the CKCON for fastest access to xdata registers
  CKCON = 0x00;
  _mcu_end_critical_section();
#endif
}

//+-----------------------------------------------------------------------------
// Name:
//   fmc_select_nand
//
// Declaration:
//   void fmc_select_nand(void);
//
// Purpose:
//   Aim the fmdu at the nand controller (same as the sm controller)
//
// Arguments:
//   None.
//
// Return:
//   None.
//
// Notes:
//   - This is a FUNCTION, not a DFA.
//   - Overrides lun_enable_mux.
//   - This does NOT affect the chip select GPIO
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void fmc_select_nand() reentrant
{
#if (k_log_lun_nand < k_max_log_lun)
  mcu_begin_critical_section();
  x_fmc_mode_ctl= k_fmc_mode_smc;
  trace1(0, nand, 0, "select nand device. fmc_mode_ctl:0x%02X", x_fmc_mode_ctl);
  // slow down access to xdata registers to give hardware time to access the media
  CKCON = 0x01;
  media_set_active(g_ix_media_nand) ;
  mcu_end_critical_section();
#endif
}


//+-----------------------------------------------------------------------------
// Name:
//   fmc_abort_transfer
//
// Declaration:
//   void fmc_abort_transfer(void);
//
// Purpose:
//   Abort the current fmdu transfer.
//
// Arguments:
//   None.
//
// Return:
//   None.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------

static void fmc_abort_transfer(void) reentrant;
static void fmc_abort_transfer() reentrant
{
  t_udw32 remaining;
  TRACE0(19, fmc, 0, "fmc_abort_transfer()");
  if (!_dev_sense_vbus())
  {
    TRACE0(20, fmc, 0, " -- cutting power to the compact flash");
    _cf_pwr_off();
    //trace0(0, fmc, 0, " -- issuing device reset");
    //_dev_soft_reset();
  }
  _mcu_begin_critical_section();
  _mcu_register_clr_bits(x_fmc_ctl, (kbm_fmc_ctl_blk_xfer_en | kbm_fmc_ctl_auto_trans));
  _mcu_register_wr(x_isr0, kbm_isr0_ramrd_a |kbm_isr0_ramrd_b |kbm_isr0_ramwr_a |kbm_isr0_ramwr_b);
  remaining.u8.hi = _mcu_register_rd(x_fmc_cnt3);
  remaining.u8.lh = _mcu_register_rd(x_fmc_cnt2);
  remaining.u8.hl = _mcu_register_rd(x_fmc_cnt1);
  remaining.u8.lo = _mcu_register_rd(x_fmc_cnt0);
  _mscbot_set_residue(remaining.u32);

//  if (g_usbrst)
//    fgnd_hpbot_wait_create();

  _mcu_end_critical_section();
}

//+-----------------------------------------------------------------------------
// Name:
//   fmc_wait_count_down_with_timeout
//
// Declaration:
//   t_result fmc_wait_count_down_with_timeout(uint16 ticks);
//
// Purpose:
//   Wait for the block transfer to edecrement to zero, without yielding.
//
// Arguments:
//   ticks   - a uint16 representing the timeout limit
//
// Return:
//   A t_result indicating:
//     k_success - the ata status register logically anded with the mask equals the value.
//     k_usbrst  - usb reset signalling was detected while waiting.
//     k_aborted - traffic occurred on the control pipe while waiting (probably a mass storage reset).
//     k_timeout - timeout limit exceeded.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result fmc_wait_count_down_with_timeout(uint16 ticks) reentrant
{
  t_sync sync;

  TRACE0(21, fmc, 1, "fmc_wait_blk_count_down_with_timeout()");
  thread_set_timer(ticks);
  do
  {
    sync = thread_got_sync(kbm_sync_abort |kbm_sync_usbrst |kbm_sync_timer);
    _thread_clr_sync(sync);
    if (sync & kbm_sync_usbrst)
    {
      TRACE0(22, fmc, 1, "fmc_wait_blk_count_down_with_timeout() - error: kbm_sync_usbrst");
      return k_usbreset;
    }
    if (sync & kbm_sync_abort)
    {
      TRACE0(23, fmc, 1, "fmc_wait_blk_count_down_with_timeout() - error: kbm_sync_abort");
      return k_aborted;
    }
    if (sync & kbm_sync_timer)
    {
      TRACE0(24, fmc, 1, "fmc_wait_blk_count_down_with_timeout() - error: timeout awaiting irq");
      return k_timeout;
    }
    //_mcu_begin_critical_section();
    //TRACE4(161, fmc, 0, "fmc_cnt#: %02x%02x%02x%02x", x_fmc_cnt3, x_fmc_cnt2, x_fmc_cnt1, x_fmc_cnt0);
    //_mcu_end_critical_section();
  } while (_mcu_register_rd(x_fmc_cnt3) | _mcu_register_rd(x_fmc_cnt2) |
           _mcu_register_rd(x_fmc_cnt1) | _mcu_register_rd(x_fmc_cnt0));
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   fmc_wait_blk_irq_with_timeout
//
// Declaration:
//   t_result fmc_wait_blk_irq_with_timeout(uint16 ticks);
//
// Purpose:
//   Wait for the block transfer interrupt, without yielding.
//
// Arguments:
//   ticks   - a uint16 representing the timeout limit
//
// Return:
//   A t_result indicating:
//     k_success - the ata status register logically anded with the mask equals the value.
//     k_usbrst  - usb reset signalling was detected while waiting.
//     k_aborted - traffic occurred on the control pipe while waiting (probably a mass storage reset).
//     k_timeout - timeout limit exceeded.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------

t_result fmc_wait_blk_irq_with_timeout(uint16 ticks) reentrant
{
  t_sync sync;
  TRACE0(25, fmc, 1, "fmc_wait_blk_irq_with_timeout()");
  thread_set_timer(ticks);
  do
  {
    sync = thread_got_sync(kbm_sync_abort |kbm_sync_usbrst |kbm_sync_timer |kbm_sync_fmc_blk);
    _thread_clr_sync(sync);
    if (sync & kbm_sync_usbrst)
    {
      TRACE0(26, fmc, 1, "fmc_wait_blk_irq_with_timeout() - error: kbm_sync_usbrst");
      return k_usbreset;
    }
    if (sync & kbm_sync_abort)
    {
      TRACE0(27, fmc, 1, "fmc_wait_blk_irq_with_timeout() - error: kbm_sync_abort");
      return k_aborted;
    }
    if (sync & kbm_sync_timer)
    {
      TRACE0(28, fmc, 1, "fmc_wait_blk_irq_with_timeout() - error: timeout awaiting irq");
      return k_timeout;
    }
    #if 1
    // AAA: fmc_transfer doesnt call this any more - it unrolls the function
    // so i turned this optimization off to avoid breaking sd.
    // added this to poll instead of taking the interrupt
    if (_mcu_register_rd(x_isr0) & kbm_isr0_blk_xfer_complete)
      break;
    #endif
  } while (!(sync & kbm_sync_fmc_blk));
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result fmc_dflt_callback() reentrant
{
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   fmc_transfer
//
// Declaration:
//   t_result fmc_transfer(void);
//
// Purpose:
//   Transfer data via the fmdu.
//
// Arguments:
//   No parameters, but the caller must have previously called:
//     _fmc_set_start_lb_8() OR _fmc_set_start_lb_32()
//     AND
//     _fmc_set_lb_count_8() Or _fmc_set_lb_count_32()
//     AND
//     _fmc_set_callback()
//     AND
//     _fmc_set_timeout()
//     AND
//     must have set both _lun_data(lun, max_lb_per_split) and _lun_data(lun, max_lb_per_burst)
//
// Return:
//   A t_result indicating:
//     k_success - transfer complete.
//     k_usbrst  - usb reset signalling was detected during the transfer.
//     k_aborted - traffic occurred on the control pipe during the transfer (probably a mass storage reset).
//     k_timeout - timeout limit exceeded.
//
// Notes:
//   The class/subclass/protocol specifies starting logical block and the number
//   of logical blocks for a read/write/verify operation.  A logical block is
//   analogous to a disk sector, which is 512 bytes for all of the supported flash
//   cards.
//
//   A "transfer" is a data move that satisfies the full amount requested via the
//   protocol; e.g., read 2500 logical blocks starting from logical block 99.
//   However, some drive types cannot move arbitrarily large numbers of logical blocks
//   in a single command.  For example, ata drives have a single byte sector count
//   register and thus can only move 256 sectors (logical blocks) per command.
//   Therefore, to read 300 logical blocks from an ata drive requires two read commands;
//   one for 256 logical blocks, another for the remainder.  Thus the transfer must
//   be "split" into multiple peices, and the command issued for each split.
//
//   Additionally, different drive types have differnt policies for generating
//   interrupts.  Some can move multiple logical blocks without generating an interrupt,
//   others generate an interrupt after moving each logical block, and others after
//   various numbers of logical blocks have moved.  Moving some number of logical
//   blocks and then getting an interrupt is called a "burst".
//
//   These globals affect the operation.  Don't access then directly in callbacks.
//   Instead, use the _fmc_set_xxxx() and _fmc_get_xxxx() wrappers.  That will
//   keep the implementation opaque (knock on wood).  Use _fmc_get_result to check the result.
//
//   g_start_lb_this_xfer - specifies the starting logical block for the transfer
//                          per the protocol

⌨️ 快捷键说明

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