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

📄 nand_int_media.c

📁 <B>SMSC USB2.0 Flash硬盘驱动源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
    _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:
//   nand_int_write_begin_split
//
// Declaration:
//   t_result nand_int_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 nand_int_write_begin_quick_split() reentrant
{
  uint8 zone_before ;
  t_result result;
  t_sync sync;
  uint8 cnt;

  trace0(0, nand_int, 1, "sm_write_begin_split()");
  trace1(0, nand_int, 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, nand_int, 0, "zone-change detected.") ;
    nand_int_select_chip(_media_data(segments_per_page)-1);
    _sm_set_rd_cmd(k_sm_reset_chip);
    sm_wait_rdy_with_timeout(k_sm_busy_reset_timeout);
  }

  if(g_addr_wr_phy_blk == k_block_free)
  {
    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() ;


  // write the count registers which won't change
  _mcu_register_wr(x_fmc_cnt3, 0);
  _mcu_register_wr(x_fmc_cnt2, 0);
  _mcu_register_wr(x_fmc_cnt0, 0);
  result = k_success;

  // do max of 1 splits worth of bursts
  cnt=(uint8) _fmc_get_lb_count_32();
  while (cnt)
  {
    trace1(0, nand_int, 0, "cnt %02x",cnt);
    //choose the target chip
    nand_int_select_chip(g_addr_segment);
    //check to see if the chip is busy
    if ( nand_int_hw_bsy())
    {
      //then wait for it to be done
      result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
      if (result != k_success)
      {
        //something is seriously wrong
        trace0(0, cds, 0, "Fatal error aborted waiting for the chip to get ready!!");
        return(result);
      }
    }
    //------------------------------------------------------------------------------
    // check status... not necessary for first write, but coding is simpler to just always do it.  
    if (k_success != nand_cmd_check_status_new())
    {
      trace0(0, cds, 0, "sm_write_end_burst - write fault") ;
      return(k_error);
    }

    //------------------------------------------------------------------------------
    // start a single burst
    trace4(0, sm, 0, "+sm_write_begin_burst() - zone:%d 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);

    //------------------------------------------------------------------------------
    // start the blk xfer
    // clear blk_xfer_complete irq.
    _mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
    _mcu_register_wr(x_fmc_cnt1, 0x02);
    _mcu_register_set_bits(x_fmc_ctl, kbm_fmc_ctl_blk_xfer_en);

    //------------------------------------------------------------------------------
    // do calculations while data is moving (or waiting to move)
    cnt--;
    g_addr_segment=(g_addr_segment+1)%_media_data(segments_per_page);
    if (!g_addr_segment)
    {
      trace0(0, nand_int, 0, "last burst in the page" ) ;
      g_addr_page++;
      nand_incr_addr() ;
    }

    //------------------------------------------------------------------------------
    // wait for data to finish moving 
    thread_set_timer(g_fmc_timeout);
    do
    {
      sync = _thread_got_sync(kbm_sync_abort |kbm_sync_usbrst |kbm_sync_timer);
      _thread_clr_sync(sync);
      if (sync & kbm_sync_usbrst)
      {
        trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: kbm_sync_usbrst");
        result = k_usbreset;
        break;
      }
      if (sync & kbm_sync_abort)
      {
        trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: kbm_sync_abort");
        result = k_aborted;
        break;
      }
      if (sync & kbm_sync_timer)
      {
        trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: timeout awaiting irq");
        result = k_timeout;
        break;
      }
      // AAA: added this to poll instead of taking the interrupt
      // cds: added isr bit fmc_irq to break out of loop for fmc error (ecc or otherwise) detection
    } while (!(_mcu_register_rd(x_isr0) & (kbm_isr0_blk_xfer_complete) ));

    _sm_hw_ecc_wr_stop() ;
    sm_mode_ctl &= ~kbm_sm_mode_ecc_blk_xfer_en;

    if (k_success!=result)
    {
      trace0(0, cds, 0, "optimized interleaved write split error in xfer. aborting") ; 
      return (result);
    }
    // issue command to program the flash, then loop to next chip
    trace0(0, sm, 0, "cmd:  write") ;
    _sm_set_wr_cmd(k_sm_write);
  }

  //------------------------------------------------------------------------------
  // do one final pass through waiting for write to finally finish on all chips
  for (cnt=0;cnt<_media_data(segments_per_page);cnt++)
  {
    nand_int_select_chip(cnt);
    if ( nand_int_hw_bsy())
    {
      //then wait for it to be done
      result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
      if (result != k_success)
      {
        //something is seriously wrong
        trace0(0, cds, 0, "Fatal error aborted waiting for the chip to get ready!!");
        return(result);
      }
    }

    if (k_success != nand_cmd_check_status_new())
    {
      trace0(0, cds, 0, "sm_write_end_burst - write fault") ;
      return(k_error );
    }
  }

  g_start_lb_this_xfer.u32 += g_n_lb_this_split.u32;
  g_n_lb_this_xfer.u32 -= g_n_lb_this_split.u32;
  _mscbot_decr_residue( (g_n_lb_this_split.u32*512L) );
  g_n_lb_this_split.u32 = 0;
  return(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
//   nand_int_write_begin_split
//
// Declaration:
//   t_result nand_int_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 nand_int_write_begin_split() reentrant
{
  #ifdef Dominic
  uint8 zone_before ;
  uint8 addr_segment;
  trace0(0, nand_int, 1, "sm_write_begin_split()");
  trace1(0, nand_int, 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, nand_int, 0, "zone-change detected.") ;
    nand_int_select_chip(_media_data(segments_per_page)-1);
    sm_set_write_mode_page_data();
    nand_int_select_chip(g_addr_segment);
  }

  if (!g_addr_page)
  {
    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") ;
  #endif
  return(k_success);
}

//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result nand_int_write_end_split(void) reentrant
{
  uint8 addr_segment = g_addr_segment;
  t_result result;
  trace0(0, cds, 0, "nand_int_write_end_split()") ;
  trace2(0, nand_int, 0, "split ended on to page %d segment %d", g_addr_page, g_addr_segment) ;
  if ( g_addr_segment )
  {
    _mcu_register_clr_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
    trace0(0, nand_int, 0, "auto-transfer bit ==> OFF");
    //copy page tail
    for (; addr_segment < _media_data(segments_per_page); addr_segment++)
    {
      nand_int_select_chip(addr_segment);
      result=sm_media_copy_sector();
      if (k_success!=result)
      {
        if (k_media_copy_error_src==result)
        {
          trace0(0, nand_int, 0, "read error detected.  continue copying") ;
        }
        else
        {
          trace0(0, nand_int, 0, "fatal error occured while copying.  aborting copy_block()") ;
          return(k_error);
        }
      }
    }
    g_addr_page++;
    g_addr_segment=0;
    nand_incr_addr() ;
  }
  return(sm_write_end_split() );
}

//+-----------------------------------------------------------------------------
// 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 nand_int_write_begin_burst() reentrant
{
  #ifdef Dominic
  t_result result;
  trace5(0, nand_int, 0, "nand_int_write_begin_burst() - zone:%d log:%d-phy:%d page:%d seg:%d", g_addr_zone, g_addr_log_blk, g_addr_wr_phy_blk, g_addr_page, g_addr_segment) ;
  trace1(0, nand_int, 0, "                        - n_lbs_this_xfer:%d", g_n_lb_this_xfer.u32) ;
  //choose the next chip
  nand_int_select_chip(g_addr_segment);
  //check to see if the chip is busy
  if ( nand_int_hw_bsy())
  {
    //then wait for it to be done
    result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
    if (result != k_success)
    {
      //something is seriously wrong
      trace0(0, nand_int, 0, "Fatal error aborted waiting for the chip to get ready!!");
      return(result);
    }
    //check to see if there is a status failure
    if (k_success != nand_cmd_check_status())
    {
      trace0(0, sm, 0, "sm_write_end_burst - write fault") ;
      g_addr_page-- ;
      return(k_error );
    }
  }

  //check to see if there is a status failure
  if (k_success != nand_cmd_check_status())
  {
    trace0(0, sm, 0, "sm_write_end_burst - write fault") ;
    g_addr_page-- ;
    return(k_error );
  }
  // _mcu_register_set_bits(sm_mode_ctl,kbm_sm_mode_ecc_blk_xfer_en) ;
  // _sm_hw_ecc_wr_start() ;
  trace0(0, nand_int, 0, "bursting") ;
  #endif
  return(sm_write_begin_burst());

}


//+-----------------------------------------------------------------------------
// Name:
//   sm_write_end_burst
//
// Declaration:
//   t_result sm_write_end_burst(void);
//
// Purpose:
//   TBD
//
// 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 nand_int_write_end_burst(void) reentrant
{
  #ifdef Dominic

  trace0(0, sm, 0, "nand_int_write_end_burst()") ;
  _sm_hw_ecc_wr_stop() ;
  sm_mode_ctl &= ~kbm_sm_mode_ecc_blk_xfer_en;
  trace0(0, sm, 0, "ecc_en off") ;


  //x_smc_stat = kbm_smc_stat_rdy ;
  trace0(0, sm, 0, "cmd:  write") ;
  _sm_set_wr_cmd(k_sm_write);

  g_addr_segment++ ;

  if ( g_addr_segment==_media_data(segments_per_page) )
  {
    trace0(0, nand_int, 0, "last burst in the page" ) ;
    g_addr_page++;
    g_addr_segment=0;
    nand_incr_addr() ;
  }
  #endif
  return(k_success );
}
//+-----------------------------------------------------------------------------
// Name:
//   nand_int_read_end_burst
//
// Declaration:
//   t_result nand_int_read_end_burst(void);
//
// Purpose:
//   TBD
//
// 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 nand_int_read_end_burst(void) reentrant
{
  t_result result;

  trace0(0, nand_int, 0, "nand_int_read_end_burst()") ;
  //just check if the chip is done.., should be at this point
  if (k_success != sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
  {
    TRACE0(445, nand, 0, "error waiting for data") ;
    nand_cmd_reset_device();
    return(k_error );
  }
  result = sm_read_end_burst();
  g_addr_segment++ ;
  if ( g_addr_segment==_media_data(segments_per_page) )
  {
    g_addr_page++;
    g_addr_segment=0;
    nand_incr_addr() ;
  }
  //select the appropriate chip
  nand_int_select_chip(g_addr_segment);
  return(result);
}



⌨️ 快捷键说明

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