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 + -
显示快捷键?