sm.c

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

C
1,935
字号

void _sm_hw_set_wr_addr() reentrant
{
  sm_mode_ctl=(uint8)(kbm_wr_addr|kbm_disable_wp) ;
  trace1(0, sm, 50, "_sm_hw_set_wr_addr() - sm_mode_ctl:%02x", (kbm_wr_addr|kbm_disable_wp)) ;
}

void _sm_hw_set_wr_standby() reentrant
{
  sm_mode_ctl=(uint8)(kbm_standby|kbm_disable_wp);
  trace1(0, sm, 50, "_sm_hw_set_wr_standby() - sm_mode_ctl:%02x", (kbm_standby|kbm_disable_wp)) ;
}

t_bool _sm_hw_bsy() reentrant
{
  uint8 val ;
  val = (!(x_smc_stat & kbm_smc_stat_rdy))?k_true:k_false ;
  trace1(0, sm, 50, "_sm_hw_bsy? %c", (val?'Y':'N')) ;
  return val;
}
#endif

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void nand_calc_split_size() reentrant
{
  uint16 max_split_size;
  trace0(0, sm, 0, "nand_calc_split_size()") ;

  // precompute max split size
  max_split_size = (_media_data(pages_per_block)-g_addr_page)*_media_data(segments_per_page)-g_addr_segment ;
  _lun_data(max_lb_per_split) = _min( max_split_size, _fmc_get_lb_count_32());
  trace2(0, sm, 0, "max split size = %04X%04X", _hw(_lun_data(max_lb_per_split)), _lw(_lun_data(max_lb_per_split))); 
}

#if 0 
//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
void sm_dbg_dump_redt_data() reentrant
{
  uint8 i ;

  for (i=0; i<16;i++)
  {
    trace2(0, sm, 0, "x_sm_redt_data[%d]:%02x", i, (uint16) x_sm_redt_data[i]) ;
  }
}
#endif


//+-----------------------------------------------------------------------------
// Name:
//   sm_set_rd_cmd()
//
// Declaration:
//   void sm_set_rd_cmd(uint8 cmd) reentrant
//
// Purpose:
//   set up the media for issuing read command
//   (using write protection signal to prevent accidental writes)
//
// Arguments:
//   cmd  - command to be issued.  should be one of the following
//          constants: k_sm_read, k_sm_read_redt, k_sm_read2, k_sm_reset_chip
//          k_sm_read_status or k_sm_read_id
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void sm_set_rd_cmd(uint8 cmd) reentrant
{
  trace1(0, sm, 50, "sm_set_rd_cmd(%02x)", cmd) ;
  _sm_set_rd_cmd(cmd) ;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void sm_rd_cmd_begin(uint8 cmd) reentrant
{
  trace1(0, sm, 50, "sm_rd_cmd_begin(%02x).", cmd) ;
  trace1(0, sm, 0, "x_smc_stat = %02x", kbm_smc_stat_rdy) ;
  _sm_rd_cmd_begin(cmd);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void sm_set_wr_cmd(uint8 cmd) reentrant
{
  trace1(0, sm, 50, "sm_set_wr_cmd(%02x)", cmd) ;
  _sm_set_wr_cmd(cmd);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void sm_wr_cmd_begin(uint8 cmd) reentrant
{
  trace1(0, sm, 50, "sm_wr_cmd_begin(%02x)", cmd) ;
  trace1(0, sm, 50, "smc_stat_rdy=%02x", kbm_smc_stat_rdy);
  _sm_wr_cmd_begin(cmd);
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_check_status()
//
// Declaration:
//   t_result sm_check_status(void)
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_check_status(void) reentrant
{
  uint8 status ;

  sm_set_rd_cmd(k_sm_read_status);
  status = _sm_data_rd() ;
  trace1(0, sm, 0, "sm_check_status:  status:%02x", status ) ;
  if (status&kbm_sm_status_write_failed)
    return k_error;
  return k_success;
}

//+-----------------------------------------------------------------------------
// Name:
//   bit_count8()
//
// Declaration:
//   t_result bit_count8(void) reentrant ;
//
// Purpose:
//   Count # of bits in a 8-bit value
//
// Arguments:
//   val  - 8-bit value in which to count bits
//
// Return:
//   0-8, depending on the number of bits set in 'val'
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
uint8 bit_count8(uint8 val) reentrant
{
  uint8 cnt=0;
  while (val)
  {
    cnt+=(uint8)(val &0x01);
    val >>=1 ;
  }
  return cnt;
}

//+-----------------------------------------------------------------------------
// Name:
//   TBD
//
// Declaration:
//   TBD
//
// Purpose:
//   Count # of bits in a 16-bit value
//
// Arguments:
//   val  - 16-bit value in which to count bits
//
// Return:
//   0-16, depending on the number of bits set in 'val'
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
uint8 bit_count16(uint16 val) reentrant
{
  uint8 cnt=0;
  while (val)
  {
    cnt+= (uint8) (val&0x01);
    val>>=1;
  }
  return cnt;
}

//+-----------------------------------------------------------------------------
// Name:
//   sm_wait_rdy_with_timeout()
//
// Declaration:
//   t_result sm_wait_rdy_with_timeout(uint16 ticks) reentrant
//
// Purpose:
//
// Arguments:
//   none
//
// Return:
//
// Notes:
//   currently, not a dfa
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
t_result sm_wait_rdy_with_timeout(uint16 ticks) reentrant
{
  t_sync sync ;

  thread_set_timer( ticks ) ;
  sync = kbm_sync_none ;
  while (!(sync & kbm_sync_timer))
  {
    // $$$ cds -> should patch in the usbrst and abort syncs after sm debug
    sync = thread_got_sync(kbm_sync_timer) ;
    _thread_clr_sync(sync) ;
    if (sync & kbm_sync_usbrst)
    {
      trace0(0, sm, 1, "sm_wait_rdy_with_timeout() - error: kbm_sync_usbrst");
      return k_usbreset;
    }
    if (sync & kbm_sync_abort)
    {
      trace0(0, sm, 1, "sm_wait_rdy_with_timeout() - error: kbm_sync_abort");
      return k_aborted;
    }
    if (sync & kbm_sync_timer)
    {
      trace0(0, sm, 1, "sm_wait_rdy_with_timeout() - timed out");
      return k_timeout;
    }

    // the actual unique condition
    if (!_sm_hw_bsy())
    {
      return k_success;
    }
  }

  trace0(0, sm, 0, "sm_wait_rdy_with_timeout() - should not get here!!!") ;
  return k_success;
}
//+-----------------------------------------------------------------------------
// Name:
//   sm_setup_mult_write_emu()
//
// Declaration:
//  void sm_setup_mult_write_emu() reentrant
//
// Purpose:
//
// Arguments:
//   none
//
// Return:
//
// Notes:
//   currently, not a dfa
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
#ifdef k_smc_write_multi_support
void sm_setup_mult_write_emu() reentrant
{
  trace0(0, sm, 0, "sm_setup_mult_write_emu()");
  _mcu_register_wr(sm_mode_ctl2,g_sm_mode_ctl_2_opts);
  x_smc_stat = kbm_smc_stat_rdy ;
  sm_mode_ctl |= kbm_sm_mode_ecc_blk_xfer_en;
  _sm_hw_ecc_wr_start() ;
  sm_emu_pg_addr_2 = g_nand_wr_addr_msb;
  sm_emu_pg_addr_1 = g_nand_wr_addr_mid;  // send pa8-pa15
  sm_emu_pg_addr_0 = g_nand_wr_addr_lsb;  // send pa0-pa7
  _mcu_register_set_bits(sm_mode_ctl2,kbm_sm_mode_mult_emu_en);  
  trace4(0, sm, 0, "multiple emulation => ON  (sm_mode_ctl2:%02x, sm_emu_pg_addr_[2,1,0]: %02x%02x%02x)", sm_mode_ctl2, sm_emu_pg_addr_2, sm_emu_pg_addr_1, sm_emu_pg_addr_0);
}
#endif

//+-----------------------------------------------------------------------------
// Name:
//   sm_media_erase_all()
//
// Declaration:
//   t_result sm_media_erase_all(void) reentrant
//
// Purpose:
//   erase all physical blocks on media card, then
//   rebuild sector mapping table
//
// Arguments:
//   none
//
// Return:
//   k_success  - on successful completion
//
// Notes:
//   currently, not a dfa
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
void sm_reset_device(void) reentrant
{
  // reset the chip
  trace0(0, sm, 0, "sm_reset_device()") ;
  sm_rd_cmd_begin(k_sm_reset_chip) ;
  sm_wait_rdy_with_timeout(k_sm_busy_reset_timeout) ;
  _sm_hw_set_rd_standby();
}


//+-----------------------------------------------------------------------------
// Name:
//   sm_read_id()
//
// Declaration:
//   uint8 sm_read_id(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
//   fmc-1.0
//------------------------------------------------------------------------------
xdata uint8 nand_id_maker ;
xdata uint8 nand_id_device ;
xdata uint8 nand_id_3;
xdata uint8 nand_id_4;
xdata uint8 nand_id_5;
xdata uint8 nand_id_ex_1 ;
xdata uint8 g_nand_has_unique_id;

uint8 sm_read_id(void) reentrant
{
  // issue read id
  _sm_hw_set_rd_cmd();
  _sm_data_wr(k_sm_read_id);

  // set addr to 0
  _sm_hw_set_rd_addr();
  _sm_data_wr(0x00);

  // get 4 bytes of data.
  _sm_hw_set_rd_data(0);
  nand_id_maker  = _sm_data_rd() ;
  nand_id_device = _sm_data_rd() ;
  nand_id_3 = _sm_data_rd() ;
  nand_id_4 = _sm_data_rd() ;
  nand_id_5 = _sm_data_rd() ;

  trace1(0, sm, 0, "nand maker :%02X", nand_id_maker);
  trace1(0, sm, 0, "nand device:%02X", nand_id_device) ;
  trace1(0, sm, 0, "nand id 3  :%02X", nand_id_3);
  trace1(0, sm, 0, "nand id 4  :%02X", nand_id_4);
  trace1(0, sm, 0, "nand id 5  :%02X", nand_id_5);

  // turn off chip enable
  _sm_hw_set_rd_standby();

#if 0
  if (0xa5==nand_id_3)
  {
    trace0(0, sm, 0, "card has unique Smart Media ID assignment") ;
    g_nand_has_unique_id=k_true;
  }
  else
  {
    trace0(0, sm, 0, "card does not have unique Smart Media ID assignment") ;
    g_nand_has_unique_id=k_false;

⌨️ 快捷键说明

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