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

📄 ata.c

📁 u盘MCU端源代码,开发U盘的可以参考.
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Notes:
//   This is the start STATE of the dfa_ata_read DFA.
//   It overrides dfa_lun_read.
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void dfa_ata_read(void) reentrant
{
  trace0(0, ata, 0, "dfa_ata_read");
  _stack_check();
  _fmc_set_callback(fmc_dflt_callback, ata_read_end_xfer,
                    ata_read_begin_split, fmc_dflt_callback,
                    ata_read_begin_burst, fmc_dflt_callback, ata_read_end_burst);
  _fmc_set_options(0);
  dfa_lun_read();
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_write_end_xfer
//
// Declaration:
//   t_result ata_write_end_xfer(void);
//
// Purpose:
//   Turn off multiple emulation if there was an error.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - done.
//     k_usbrst  - usb reset signalling was detected while executing the command.
//     k_aborted - traffic occurred on the control pipe while wexecuting the command (probably a mass storage reset).
//     k_timeout - a timeout limit exceeded while executing the command.
//
// 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 ata_write_end_xfer(void) reentrant;
t_result ata_write_end_xfer() reentrant
{
  trace0(0, ata, 1, "ata_write_end_xfer()");
  _stack_check();
  // turn off the multiple emulation bit
  _mcu_register_clr_bits(x_cfc_ata_mode_ctl, kbm_cfc_ata_mode_ctl_mult_emu_en);
  trace0(0, ata, 0, "multiple emulation off");

  // check to see if the fmc xfer was aborted... if so, reset the drive and return k_aborted
  if (k_success != _fmc_get_result())
  {
    trace0(0, ata, 0, "fmc xfer was aborted.  reset the device to stop it");
    ata_reset();
    return _fmc_get_result();
  }
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_write_begin_split
//
// Declaration:
//   t_result ata_write_begin_split(void);
//
// Purpose:
//   Issue the write command to the ata drive.
//
// 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 ata_write_begin_split(void) reentrant;
t_result ata_write_begin_split() reentrant
{
  trace0(0, ata, 1, "ata_write_begin_split()");
  _stack_check();
  _fmc_set_options(0);
  _fmc_set_timeout(10000);
  // clear any stale ata irq
  ata_read_status();
  _ata_register_wr(&ata_device_head,
                  (kbm_ata_dev_lba|
                   (g_start_lb_this_xfer.u8.hi & kbm_msk_ata_dev_lba_hi)));
  _ata_register_wr(&ata_cylinder_hi, g_start_lb_this_xfer.u8.lh);
  _ata_register_wr(&ata_cylinder_lo, g_start_lb_this_xfer.u8.hl);
  _ata_register_wr(&ata_sector_num,  g_start_lb_this_xfer.u8.lo);
  _ata_register_wr(&ata_sector_cnt, g_n_lb_this_split.u8.lo);
  _ata_register_wr(&ata_command, k_ata_command_write_sectors);
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_write_begin_burst
//
// Declaration:
//   t_result ata_write_begin_burst(void);
//
// Purpose:
//   Wait until the drive is ready to accept the data.
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - ready to transfer data.
//     k_usbrst  - usb reset signalling was detected while executing the command.
//     k_aborted - traffic occurred on the control pipe while wexecuting the command (probably a mass storage reset).
//     k_timeout - a timeout limit exceeded while executing the command.
//
// 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 ata_write_begin_burst(void) reentrant;
t_result ata_write_begin_burst() reentrant
{
  t_result rslt;

  trace0(0, ata, 1, "ata_write_begin_burst()");
  _stack_check();
  // poll the status register until the bsy bit goes inactive
  rslt = ata_wait_status_with_timeout(kbm_ata_status_bsy, 0, 5000, NULL);
  if (k_error == rslt)
  {
    // error... put in the appropriate sense code
    trace0(0, ata, 0, "sense_write_error");
    _lun_data(sensep) = &sense_write_error;
    return k_error;
  }
  // some other error waiting for the drq
  if (k_success != rslt)
    return rslt;
  // poll the status register until the drq bit goes active
  rslt = ata_wait_status_with_timeout(kbm_ata_status_drq, kbm_ata_status_drq, 5000, NULL);
  if (k_error == rslt)
  {
    // error... put in the appropriate sense code
    trace0(0, ata, 0, "sense_write_error");
    _lun_data(sensep) = &sense_write_error;
    return k_error;
  }
  // some other error waiting for the drq
  if (k_success != rslt)
    return rslt;

  // mask the isr from the cf device
  _mcu_register_set_bits(x_cfc_stat_msk, kbm_cfc_stat_intrq);

  // turn on the multiple emulation bit
  _mcu_register_set_bits(x_cfc_ata_mode_ctl, kbm_cfc_ata_mode_ctl_mult_emu_en);

  trace0(0, ata, 0, "multiple emulation on");


  // got the drq
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   ata_write_end_burst
//
// Declaration:
//   t_result ata_write_end_burst(void);
//
// Purpose:
//   Wait until the drive is done writing the data (flushing its buffers).
//
// Arguments:
//   None.
//
// Return:
//   A t_result indicating:
//     k_success - done.
//     k_usbrst  - usb reset signalling was detected while executing the command.
//     k_aborted - traffic occurred on the control pipe while wexecuting the command (probably a mass storage reset).
//     k_timeout - a timeout limit exceeded while executing the command.
//
// 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 ata_write_end_burst(void) reentrant;
t_result ata_write_end_burst() reentrant
{
  t_result rslt;

  trace0(0, ata, 1, "ata_write_end_burst()");
  _stack_check();
  // turn off the multiple emulation bit
  _mcu_register_clr_bits(x_cfc_ata_mode_ctl, kbm_cfc_ata_mode_ctl_mult_emu_en);
  trace0(0, ata, 0, "multiple emulation off");

  // check to see if the fmc xfer was aborted... if so, reset the drive and return k_aborted
  rslt = _fmc_get_result();
  if( rslt != k_success )
  {
    trace0(0, ata, 0, "fmc xfer was aborted.  reset the device to stop it");
    ata_reset();
    return rslt;
  }

  // wait for the drive to provide the data
  rslt = ata_read_status();
  // poll the status register just to check for errors
  rslt = ata_wait_status_with_timeout(kbm_ata_status_bsy |kbm_ata_status_drq, 0, 5000, NULL);
  if (k_error == rslt)
  {
    // error... put in the appropriate sense code
    trace0(0, ata, 0, "sense_write_error");
    _lun_data(sensep) = &sense_write_error;
    return k_error;
  }
  // some other error
  if (k_success != rslt)
    return rslt;
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   dfa_ata_write
//
// Declaration:
//   void dfa_ata_write(void);
//
// Purpose:
//   Write data to an ata drive.
//
// 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
//------------------------------------------------------------------------------
void dfa_ata_write() reentrant
{
  trace0(0, ata, 0, "dfa_ata_write");
  _stack_check();
  _fmc_set_callback(fmc_dflt_callback, ata_write_end_xfer,
                    ata_write_begin_split, fmc_dflt_callback,
                    ata_write_begin_burst, fmc_dflt_callback, ata_write_end_burst);
  _fmc_set_options(0);
  dfa_lun_write();
}

//------------------------------------------------------------------------------
// verify options
#define kbm_verify_options_dpo      0x04
#define kbm_verify_options_bytchk   0x02
#define kbm_verify_options_reladr   0x01

//+-----------------------------------------------------------------------------
// Name:
//   dfa_ata_verify
//
// Declaration:
//   void dfa_ata_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 dfa_ata_verify() reentrant
{
  trace0(0, ata, 0, "dfa_ata_verify");
  _fmc_set_callback(fmc_dflt_callback, ata_write_end_xfer,
                    ata_write_begin_split, fmc_dflt_callback,
                    ata_write_begin_burst, fmc_dflt_callback, ata_write_end_burst);
  dfa_lun_verify();
}

//---eof------------------------------------------------------------------------

⌨️ 快捷键说明

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