📄 sm.c
字号:
trace0(0, sm, 0, "waiting for buffer to go out...") ;
}
trace0(0, sm, 0, "buffer tx'd... should see it on the catc") ;
}
else
{
_mcu_register_wr(x_ramrdbc_b1, 0x02);
_mcu_register_wr(x_ramrdbc_b2, 0x00);
_mcu_register_wr(x_ep2_ctl, kbm_ep2_ctl_rdtog_valid |(_mcu_register_rd(x_ep2_ctl) | kbm_ep2_ctl_ramrd_tog));
_hdw_clk_domain_bug_workaround();
while ( !(x_isr0&kbm_isr0_ramrd_b))
;
}
// only turn auto xfer back on if there's more to xfer
if ( x_fmc_cnt0|x_fmc_cnt1|x_fmc_cnt2|x_fmc_cnt3)
{
trace0(0, sm, 0, "auto transfer ON") ;
_mcu_register_set_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
return (k_resume );
}
else
{
trace0(0, sm, 0, "xfer is done, DON'T resume") ;
return (k_success);
}
}
// wait for device
if ( k_success == result)
{
result = sm_wait_rdy_with_timeout(k_sm_busy_read_timeout) ;
}
if (k_success != result)
{
nand_cmd_reset_device();
result = k_error ;
}
trace0(0, sm, 0, "leaving read data portion") ;
return (result );
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_sm_read
//
// Declaration:
// void dfa_sm_read(void) reentrant
//
// Purpose:
// Read data from sm media
//
// Arguments:
// None.
// Uses _lun_data and g_bot_cbw to get its parameters.
//k
// 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_read DFA.
// It overrides dfa_lun_read.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void sm_dfa_read(void) reentrant
{
trace0(0, sm, 0, "dfa_sm_read");
_fmc_set_options(0);
_fmc_set_timeout(10000);
_fmc_set_callback(sm_read_begin_xfer, sm_read_end_xfer,
sm_read_begin_split, sm_read_end_first_split,
fmc_dflt_callback, fmc_dflt_callback, sm_read_end_burst);
#ifdef k_enable_write_caching
// catch the cache
if (_media_data(options)&kbm_media_data_opt_write_cache)
map_write_cache_flush_all() ;
#endif
dfa_lun_read();
}
//+-----------------------------------------------------------------------------
// Name:
// dfa_sm_write
//
// Declaration:
// void dfa_sm_write(void) reentrant
//
// Purpose:
// Read data from sm media
//
// 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
//------------------------------------------------------------------------------
t_result sm_write_begin_xfer(void) reentrant;
t_result sm_write_begin_xfer() reentrant
{
t_result result ;
trace4(0, sm, 10, "sm_write_begin_xfer() - start:0x%04X%04X count:0x%04X%04X" , _hw(_fmc_get_start_lb_32()), _lw(_fmc_get_start_lb_32()), _hw(_fmc_get_lb_count_32()), _lw(_fmc_get_lb_count_32()));
_lun_data(sensep) = &sense_write_error;
// copy head sectors...
result = map_write_begin( _fmc_get_start_lb_32() ) ;
if (!g_addr_page)
{
_lun_data(max_lb_per_split) = _min( _media_data(pages_per_block), _fmc_get_lb_count_32());
trace5(0, sm, 10, "-----write begin xfer - zone:%d phy:%d log:%d page:%d count:%d - first in block", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page, _lun_data(max_lb_per_split) );
}
else
{
_lun_data(max_lb_per_split) = _min( _media_data(pages_per_block) - g_addr_page, _fmc_get_lb_count_32());
trace5(0, sm, 10, "-----write begin xfer - zone:%d phy:%d log:%d page:%d count:%d", g_addr_zone, g_addr_wr_phy_blk, g_addr_log_blk, g_addr_page, _lun_data(max_lb_per_split));
}
_lun_data(max_lb_per_burst) = 1 ;
return (result );
}
//+-----------------------------------------------------------------------------
// Name:
// sm_write_end_xfer
//
// Declaration:
// t_result sm_write_end_xfer(void);
//
// Purpose:
// TBD
//
// Arguments:
// None.
//
// Return:
// TBD
//
// 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 sm_write_end_xfer(void) reentrant
{
t_result result ;
trace0(0, sm, 1, "sm_write_end_xfer()") ;
if (k_success != _fmc_get_result())
return (k_error);
_mcu_register_clr_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
trace0(0, fmc, 0, "auto-transfer bit ==> OFF");
result=map_write_flush() ;
if (_media_data(options)&(kbm_media_data_opt_write_cache|kbm_media_data_opt_erase_cache))
{
_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:
// sm_write_begin_split
//
// Declaration:
// t_result sm_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 sm_write_begin_split() reentrant
{
uint8 zone_before ;
trace0(0, sm, 1, "sm_write_begin_split()");
trace1(0, sm, 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, sm, 0, "*** trigger *** issuing a soft reset on zone-change, in case a sector map was paged in") ;
sm_set_write_mode_page_data();
}
if (map_is_addr_first_in_block())
{
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") ;
return (k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// sm_write_begin_first_split
//
// Declaration:
// t_result sm_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 sm_write_begin_first_split() reentrant
{
trace0(0, sm, 1, "sm_write_begin_first_split()");
// make sure we're in the right mode - fixes a bug where
// the first burst of the first split of the xfer begins
// on a zone that needed to be paged in...
sm_set_write_mode_page_data();
// compute phy addresses in case this is the first sector
nand_wr_va2pa() ;
nand_rd_va2pa() ;
_fmc_set_callback(sm_write_begin_xfer, sm_write_end_xfer,
sm_write_begin_split, sm_write_end_split,
sm_write_begin_burst, fmc_dflt_callback, sm_write_end_burst);
return (k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// sm_write_end_split
//
// Declaration:
// t_result sm_write_end_split(void);
//
// Purpose:
// nothing to do at the beginning of a split
//
// 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 sm_write_end_split(void) reentrant
{
trace0(0, sm, 0, "sm_write_end_split()") ;
// remove the auto-increment at end_burst.
g_addr_page-= 1 ;
// see if that finished the phyblock
if (map_is_addr_last_in_block())
{
if (k_success != map_rebind_log_blk())
{
trace0(0, sm, 0, "mapper error updating logical bindings") ;
return (k_error );
}
}
_sm_hw_set_wr_standby();
_sm_hw_set_rd_standby();
// do full-block splits to avoid split overhead on every sector.
_lun_data(max_lb_per_split) = _media_data(pages_per_block) ;
return (k_success );
}
//+-----------------------------------------------------------------------------
// 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 sm_write_begin_burst() reentrant
{
trace4(0, sm, 0, "+sm_write_begin_burst() - zone:%d WR_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);
trace1(0, sm, 0, "smc_mode_ctl: %02x", sm_mode_ctl);
trace1(0, sm, 0, " smc_stat: %02x", x_smc_stat);
trace0(0, sm, 0, "ready for burst") ;
return (k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// sm_write_end_burst
//
// Declaration:
// t_result sm_write_end_burst(void);
//
// Purpose:
// TBD
//
// Arguments:
// None.
//
// Return:
// A t_result indicating:
// k
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -