ms_media.c

来自「U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有」· C语言 代码 · 共 853 行 · 第 1/3 页

C
853
字号
  _mcu_register_clr_bits(x_imr0, kbm_isr0_blk_xfer_complete);
  // $$$$$$ warning!
  // $$ must do a while loop because we cannot yield
  // also, cannot have a timer, because of the memory stick bug... the timer
  // is in XDATA space, and touching it during ms fmdu xfers ist verboten
 while (1)
  {
    // poll isr's to check on events that should cause us to break,
    // and on those events, set the mask and get out.
    if ((_mcu_register_rd(x_isr0) & kbm_isr0_blk_xfer_complete))
    {
      //irq_control(k_irq_blk_xfer_complete, kbm_irqctl_clear| kbm_irqctl_mask);
      // dont clear it here because the irq is no longer used, and the sync is no longer
      // delivered, and the fmc layer polls the bit
      //_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
      _mcu_register_set_bits(x_imr0, kbm_isr0_blk_xfer_complete);
      //thread_set_sync(g_tid, kbm_sync_fmc_blk);
      break;
    }
    // check for a usb reset during the xfer
    else
      if (_mcu_register_rd(x_wu_src1) & kbm_wk1_usb_reset)
    {
      _dev_soft_reset();
      thread_set_sync(g_tid, kbm_sync_usbrst);
      // you can't get here from there... soft reset puts everything back to por state
      break;
    }
    // abort on status change of memory stick
    else
      if (_mcu_register_rd(x_wu_src1) & kbm_wk1_crd_sts_chg)
    {
      if (_mcu_register_rd(x_crd_stat) & kbm_crd_stat_ms_out)
      {
        _ejected(g_active_lun);
        thread_set_sync(g_tid, kbm_sync_abort);
        break;
      }
    }
}     
  _mcu_end_critical_section() ;

  if (!_ms_rx_data_fifo_is_empty())
  {
    trace0(0, ms, 10, "alert - entered read_end_burst before rx fifo emptied - wait before stopping dma");
    //if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, ms_fifo_stat_r_buf_e, 3))  //rcc test for MS bug tbh!!!
  #if defined(k_mcu_97210)
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, 0, 3))
    return k_error;
    #elif defined(k_mcu_97223) 
    if (k_success != ms_wait_fifo_with_timeout(kbm_ms_alt_stat_fifo_e, 0, 3))
    return k_error;
    #endif
  }

 // clear daken before issuing command other than wr-page-data and rd-page-data
  
  #if defined(k_mcu_97210)
  _ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
  trace0(0, ms_media, 0, "ms_copy_sector() read complete") ;
  trace0(0, ms_media, 0, "ms_copy_sector() read complete") ;
  #elif defined(k_mcu_97223)
  _ms_register_clr_bits(msc_mode_ctl_1, kbm_ms_mode_ctl_dam);
  #endif
  // bind current logical block to new physical block
  ms_media_bind_log2phy() ;
  // reverse data flow direction: sram->device
  _mcu_register_clr_bits( x_ep2_ctl, kbm_ep2_ctl_dir) ;
  // program the card to write 1 sector at g_addr_wr_phy_blk
  set_wr_phyblk();
  //return ms_write_issue_command();
  if (k_success != ms_write_all_reg(0x80, 0x20))
    return k_error;
  if (k_success != ms_set_cmd(k_ms_block_write))
    return k_error;
  if (k_success != ms_get_int(10))
    return k_error;
  if (_factor & kbm_ms_reg_int_cmdnk)
  {
    trace0(0, ms, 10, "error: cmdnk");
    return k_error;
  }
  if (!(_factor & kbm_ms_reg_int_breq))
  {
    trace0(0, ms, 10, "error: breq not set");
    return k_error;
  }
  // daken must be set during dma transfers.
  // only wr-page-data and rd-page-data can be issued with daken set.
  #if defined(k_mcu_97210)
  _ms_register_set_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
  if (k_success != ms_set_tpc(k_ms_tpc_wr_page_data |0x02, 0))
  {
    _ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
    return k_error;
  }

#elif defined(k_mcu_97223)
  _ms_register_set_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
  if (k_success != ms_set_tpc(k_ms_tpc_wr_page_data |0x02, 0))
  {
    _ms_register_clr_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
    return k_error;
  }
#endif
  // IMPORTANT!  This begin_critical_section() is ended in the 'rw_intra_burst' function
  // to prevent xdata access while blk_xfer bit is enabled
  _mcu_begin_critical_section();
  // set fmc ctl reg - 1 sector
  _mcu_register_wr(x_fmc_cnt3, 0x00) ;
  _mcu_register_wr(x_fmc_cnt2, 0x00) ;
  _mcu_register_wr(x_fmc_cnt1, 0x02) ;
  _mcu_register_wr(x_fmc_cnt0, 0x00) ;
  // enable blk xfer, use 512 bytes per burst
  _mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
  _mcu_register_clr_bits(x_imr0, kbm_isr0_blk_xfer_complete);
  _mcu_register_wr(x_fmc_ctl, (kbm_fmc_ctl_512_byte_pkt|kbm_fmc_ctl_blk_xfer_en)) ;
  // point the byte count & source buffer for fmdu to buffer a
  _mcu_register_wr( x_ramrdbc_a1, 0x02) ;
  _mcu_register_wr( x_ramrdbc_a2, 0x00) ;
  // (rdtog_valid:1 ramrd_tog:0)
  _mcu_register_set_bits( x_ep2_ctl, kbm_ep2_ctl_rdtog_valid) ;
  // warning!
  // must do a while loop because we cannot yield
  // also, cannot have a timer, because of the memory stick bug... the timer
  // is in XDATA space, and touching it during ms fmdu xfers ist verboten
while (1)
  {
    // poll isr's to check on events that should cause us to break,
    // and on those events, set the mask and get out.
    if ((_mcu_register_rd(x_isr0) & kbm_isr0_blk_xfer_complete))
    {
      //irq_control(k_irq_blk_xfer_complete, kbm_irqctl_clear| kbm_irqctl_mask);
      // dont clear it here because the irq is no longer used, and the sync is no longer
      // delivered, and the fmc layer polls the bit
      //_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
      _mcu_register_set_bits(x_imr0, kbm_isr0_blk_xfer_complete);
      //thread_set_sync(g_tid, kbm_sync_fmc_blk);
      break;
    }
    // check for a usb reset during the xfer
    else
      if (_mcu_register_rd(x_wu_src1) & kbm_wk1_usb_reset)
    {
      _dev_soft_reset();
      thread_set_sync(g_tid, kbm_sync_usbrst);
      // you can't get here from there... soft reset puts everything back to por state
      break;
    }
    // abort on status change of memory stick
    else
      if (_mcu_register_rd(x_wu_src1) & kbm_wk1_crd_sts_chg)
    {
      if (_mcu_register_rd(x_crd_stat) & kbm_crd_stat_ms_out)
      {
        _ejected(g_active_lun);
        thread_set_sync(g_tid, kbm_sync_abort);
        break;
      }
    }
}     
  _mcu_end_critical_section() ;
  if (!_ms_tx_data_fifo_is_empty())
  {
    trace0(0, ms, 10, "alert - entered write_end_burst before tx fifo emptied - wait before stopping dma");
	 #if defined(k_mcu_97210)
    if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
    return k_error;
    #elif defined(k_mcu_97223) 
    if (k_success != ms_wait_fifo_with_timeout( kbm_ms_alt_stat_fifo_e , kbm_ms_alt_stat_fifo_e , 3))
    return k_error;
    #endif
   
  }
  // clear daken before issuing command other than wr-page-data and rd-page-data
  #if defined(k_mcu_97210)
  _ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
 #elif defined(k_mcu_97223)
 _ms_register_clr_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
  #endif
  // get status
  if (k_success != ms_get_int(10))
    return k_error;
  if (_factor & kbm_ms_reg_int_cmdnk)
  {
    trace0(0, ms, 10, "error: cmdnk");
    return k_error;
  }
  if (_factor & kbm_ms_reg_int_breq)
  {
    trace0(0, ms, 0, "error: breq set after block-end (presumably) delivered");
    return k_error;
    //TRACE0(448, ms, 0, "alert: breq set");
  }
  if (!(_factor & kbm_ms_reg_int_ced))
  {
    trace0(0, ms, 0, "error: ced not set");
    return k_error;
  }
  if (_factor & kbm_ms_reg_int_err)
  {
    trace0(0, ms, 10, "error: ced&err unrecoverable flash write error");
    ms_media_set_phyblock_failed();
    return k_error;
  }
  // write complete
  return k_success;
}
#endif

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//t_result ms_media_write_sector() reentrant
//{
//  trace0(0, ms_media, 0, "ms_media_write_sector()");
//  set_wr_phyblk();
//  return ms_pio_write_page(k_max_pnr);
//}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_phy2log() reentrant
{
  uint16 absolute;
  uint16 relative;

  trace0(0, ms_media, 10, "ms_media_phy2log()");
  absolute = g_ms_extra[k_log_addr_msb_flg_offset] * 256 + g_ms_extra[k_log_addr_lsb_flg_offset];
  switch (g_addr_zone)
  {
    case 0:
      relative = absolute;
      break;
    case 1:
      relative = absolute - _media_data(logical_blocks_per_boot_zone);
      break;
    default:
      relative = absolute - _media_data(logical_blocks_per_boot_zone);
      relative %= _media_data(logical_blocks_per_zone);
      break;
  }
  g_addr_log_blk = relative;
  trace3(0, ms, 110, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_bind_log2phy() reentrant
{
  uint16 absolute;

  trace1(0, ms_media, 10, "ms_media_bind_log2phy() log:%04X", g_addr_log_blk);
  switch (g_addr_zone)
  {
    case 0:
      absolute = g_addr_log_blk;
      break;
    case 1:
      absolute  = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
      break;
    default:
      absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
      absolute += (g_addr_zone - 1) * _media_data(logical_blocks_per_zone);
      break;
  }
  trace3(0, ms, 10, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
  g_ms_extra[k_log_addr_msb_flg_offset] = _h(absolute);
  g_ms_extra[k_log_addr_lsb_flg_offset] = _l(absolute);
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_set_phyblock_failed() reentrant
{
  trace0(0, ms_media, 0, "ms_media_set_phyblock_failed()");
  g_ms_extra[k_ovwr_flg_offset] &= ~ kbm_ms_ext_ovwr_bkst;
  return k_error;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#define k_reference_bad_block_table
t_bool ms_media_is_phyblock_ok() reentrant

⌨️ 快捷键说明

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