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

📄 ms.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
// Return:
//   A t_result indicating:
//     k_success - status & mask == 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 ms_wait_fifo_with_timeout(uint8 msk, uint8 val, uint8 ticks) reentrant;
t_result ms_wait_fifo_with_timeout(uint8 msk, uint8 val, uint8 ticks) reentrant
{
  //uint8 status;
  //t_sync sync;

  trace3(0, ms, 1, "ms_wait_fifo_with_timeout(mask:%02X val:%02X ticks:%d)", msk, val, ticks);
  //_stack_check();
  thread_set_timer(ticks+1);
  do
  {
    status = _ms_register_rd(ms_fifo_stat);
    sync = thread_got_sync(kbm_sync_usbrst |kbm_sync_abort |kbm_sync_timer);
    _thread_clr_sync(sync);
    if (sync & kbm_sync_abort)
    {
      trace0(0, err, 110, "ms_wait_fifo_with_timeout() - error: kbm_sync_abort");
      return k_aborted;
    }
    if (sync & kbm_sync_usbrst)
    {
      trace0(0, err, 110, "ms_wait_fifo_with_timeout() - error: kbm_sync_usbrst");
      return k_usbreset;
    }
    if (sync & kbm_sync_timer)
    {
      trace0(0, err, 110, "ms_wait_fifo_with_timeout() - error: kbm_sync_timer");
      return k_timeout;
    }
  } while ((status & msk) != val);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_set_tpc
//
// Declaration:
//   t_result ms_set_tpc(uint8 tpc, uint8 count);
//
// Purpose:
//   Send a transfer protocol command (TPC) to the MS card.
//
// Arguments:
//   tpc - a uint8 indicating the tpc.
//   count - a uint8 indicating the number of bytes to move during this command.
//
// Return:
//   A t_result indicating:
//     k_success - tpc issued.
//     k_error   - failed to issue tpc.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_set_tpc(uint8 tpc, uint8 count) reentrant;
t_result ms_set_tpc(uint8 tpc, uint8 count) reentrant
{
  // profile:
  //  during read:
  //  ms_set_tpc     48usec to 76usec
  //    wait rdy bit 46usec to 74usec

  //_profile_on(5);
  trace2(0, ms, 0, "ms_set_tpc() tpc:%02X count:%02X", tpc, count);
  //_stack_check();
  // wait for the rdy bit in msc_stat to go hi
  //_profile_on(4);
  if (k_success != ms_wait_msc_stat_rdy_with_timeout(10))
    return k_error;
  //_profile_off(4);
  // write the byte count
  _ms_register_wr(ms_bc, count);
  // write the tpc
  _ms_register_wr(ms_tpc_cmd, tpc);
  //_profile_off(5);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_get_int
//
// Declaration:
//   t_result ms_get_int(uint8 ticks);
//
// Purpose:
//   Issue a getint command to solicit the result of the previous command.
//
// Arguments:
//   ticks - a uint8 representing the timeout period in milliseconds.
//
// Return:
//   A t_result indicating:
//     k_success - the module global variable _factor contains the results.
//     k_error   - either cannot issue the command or read back the results.
//                 contents of _factor undefined.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   The module global variable _factor is written with the results as a side effect.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_get_int(uint8 ticks) reentrant;
t_result ms_get_int(uint8 ticks) reentrant
{
  // profile:
  //  during read:
  //  ms_get_int                108 to 133usec
  //  wait sif                  52usec
  //  ms_set_tpc                52usec to 76usec
  //  wait fifo empty           2usec

  //_profile_on(6);
  trace0(0, ms, 0, "ms_get_int()");
  //_stack_check();
  // if you dont have this in here sisoft sandra fails. tbh...
  // the problem may well be a stack overflow...
  #if 1
  //_profile_on(6);
  // new - dont wait if its already there
  if ((_ms_register_rd(ms_alt_stat) & kbm_msc_stat_sif) == kbm_msc_stat_sif)
    {_mcu_register_wr(x_msc_stat, kbm_msc_stat_sif);}
  else
  // end of new
  #endif
    if (k_success != ms_wait_msc_stat_sif_with_timeout(ticks))
      return k_error;
  //_profile_off(6);
  // write the tpc
  //_profile_on(5);
  ms_set_tpc(k_ms_tpc_get_int, 1);
  //_profile_off(5);
  //_profile_on(4);
  // wait rx fifo not empty
  if (_ms_rx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, 0, 3))
      return k_error;
  //_profile_off(4);
  // read the interrupt data
  _factor = _ms_register_rd(ms_rx_db_lsb);
  g_tmp = _ms_register_rd(ms_rx_db_msb);  // throw away
  trace1(0, ms, 0, "_factor:%02X", _factor);
  //_profile_off(6);
  return k_success;
}

// so far i haven't got the acd code to work correctly...
// but since it doesn't improve performance anyhow, there's not much point...
//#define k_use_acd
#ifdef k_use_acd
//+-----------------------------------------------------------------------------
// Name:
//   ms_get_int_acd
//
// Declaration:
//   t_result ms_get_int_acd(uint8 ticks);
//
// Purpose:
//   Issue a getint command to solicit the result of the previous command.
//   Only to be used with ACD mode.
//   Allows skipping the wait for SIF, and the set-tpc for getint.
//   The goal is to use it to slightly improve the read performance.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - the module global variable _factor contains the results.
//     k_error   - either cannot issue the command or read back the results.
//                 contents of _factor undefined.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//   The module global variable _factor is written with the results as a side effect.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_get_int_acd(void) reentrant;
t_result ms_get_int_acd(void) reentrant
{
  trace0(0, ms, 0, "ms_get_int_acd()");
  //_stack_check();
  // wait rx fifo not empty
  if (_ms_rx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, 0, 3))
      return k_error;
    // read the interrupt data
  _factor = _ms_register_rd(ms_rx_db_lsb);
  g_tmp = _ms_register_rd(ms_rx_db_msb);  // throw away
  trace1(0, ms, 0, "_factor:%02X", _factor);
  return k_success;
}
#endif

//+-----------------------------------------------------------------------------
// Name:
//   ms_set_cmd
//
// Declaration:
//   t_result ms_set_cmd(uint8 cmd);
//
// Purpose:
//   Send a flash command to the MS card.
//
// Arguments:
//   cmd - a uint8 representing the command id.
//
// Return:
//   A t_result indicating:
//     k_success - command issued.
//     k_error   - failed to issue command.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_set_cmd(uint8 cmd) reentrant;
t_result ms_set_cmd(uint8 cmd) reentrant
{
  trace1(0, ms, 0, "ms_set_cmd() cmd:%02X", cmd);
  //_stack_check();
  // write the tpc
  if (k_success != ms_set_tpc(k_ms_tpc_set_cmd, 1))
    return k_error;
  // write the command
  _ms_register_wr(ms_tx_db_msb, 0);
  _ms_register_wr(ms_tx_db_lsb, cmd);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_set_read_reg_addrs
//
// Declaration:
//   t_result ms_set_read_reg_addrs(uint8 start, uint8 count);
//
// Purpose:
//   Tell the MS card that its registers are to be read by specifying the starting
//   register offset and the number of registers to be read.
//
// Arguments:
//   start - the offset of the first register to read.
//   count - the number of consecutive registers to read.
//
// Return:
//   A t_result indicating:
//     k_success - read register start/count are delivered to the card.
//     k_error   - failed to configure the card for a register read.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_set_read_reg_addrs(uint8 start, uint8 count) reentrant;
t_result ms_set_read_reg_addrs(uint8 start, uint8 count) reentrant
{
  trace2(0, ms, 0, "ms_set_read_reg_addrs() start:0x%02X count:0x%02X", start, count);
  //_stack_check();
  // write the tpc
  if (k_success != ms_set_tpc(k_ms_tpc_set_rw_reg, 4))
    return k_error;
  // write the command
  _ms_register_wr(ms_tx_db_msb, count);
  _ms_register_wr(ms_tx_db_lsb, start);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  _ms_register_wr(ms_tx_db_msb, 0);
  _ms_register_wr(ms_tx_db_lsb, k_ms_parm_system);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_set_write_reg_addrs
//
// Declaration:
//   t_result ms_set_write_reg_addrs(uint8 start, uint8 count);
//
// Purpose:
//   Tell the MS card that its registers are to be written by specifying the starting
//   register offset and the number of registers to be written.
//
// Arguments:
//   start - the offset of the first register to write.
//   count - the number of consecutive registers to write.
//
// Return:
//   A t_result indicating:
//     k_success - write register start/count are delivered to the card.
//     k_error   - failed to configure the card for a register write.
//
// Notes:
//   This is a FUNCTION, not a DFA.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result ms_set_write_reg_addrs(uint8 start, uint8 count) reentrant;
t_result ms_set_write_reg_addrs(uint8 start, uint8 count) reentrant
{
  //_profile_on(6);
  trace2(0, ms, 0, "ms_set_write_reg_addrs() start:%02X count:0x%02X", start, count);
  //_stack_check();
  // write the tpc
  if (k_success != ms_set_tpc(k_ms_tpc_set_rw_reg, 4))
    return k_error;
  // write the command
  _ms_register_wr(ms_tx_db_msb, k_ms_ext_ovwr_flg);
  _ms_register_wr(ms_tx_db_lsb, 0);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  _ms_register_wr(ms_tx_db_msb, count);
  _ms_register_wr(ms_tx_db_lsb, start);
  if (!_ms_tx_data_fifo_is_empty())
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
      return k_error;
  //_profile_off(6);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ms_read_status
//
// Declaration:
//   t_result ms_read_status(void);
//
// Purpose:
//   After an error read the status registers to determine the cause.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - the module global variables _status0 and _status1 contain the status.
//     k_error   - failed to obtain the status.
//                 contents of _status0 and _status1 undefined.
//

⌨️ 快捷键说明

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