📄 nand.c
字号:
//
// 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_read DFA.
// It overrides dfa_lun_read.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
void nand_dfa_read(void) reentrant
{
TRACE0(396, nand, 0, "nand_dfa_read()");
_fmc_set_options(0);
_fmc_set_timeout(10000);
if ( g_ix_media_nand == k_ix_media_nand_int)
{
_fmc_set_callback(nand_read_begin_xfer, sm_read_end_xfer,
nand_read_begin_split, nand_read_end_first_split,
fmc_dflt_callback, fmc_dflt_callback, nand_int_read_end_burst);
}
else
{
_fmc_set_callback(nand_read_begin_xfer, sm_read_end_xfer,
nand_read_begin_split, nand_read_end_first_split,
fmc_dflt_callback, fmc_dflt_callback, sm_read_end_burst);
}
#ifdef k_enable_write_caching
// flush write cache
if (_media_data(options)&kbm_media_data_opt_write_cache)
map_write_cache_flush_all() ;
#endif
dfa_lun_read();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//+-----------------------------------------------------------------------------
// Name:
// nand_write_begin_first_split
//
// Declaration:
// t_result nand_write_begin_first_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_write_begin_first_split() reentrant
{
TRACE0(397, nand, 1, "nand_write_begin_first_split()");
// compute phy addresses in case this is the first sector
if (k_ix_media_nand_int != g_active_media)
nand_select_card() ;
nand_wr_va2pa() ;
nand_rd_va2pa() ;
if (k_ix_media_nand==g_active_media)
{
g_fmc_begin_split_callback = (t_fmc_callback) sm_write_begin_split;
_sm_rd_cmd_begin(k_sm_reset_chip);
sm_wait_rdy_with_timeout(k_sm_busy_reset_timeout);
}
else if (k_ix_media_nand_int == g_active_media)
{
g_fmc_begin_split_callback = (t_fmc_callback) nand_int_write_begin_quick_split;
nand_int_select_chip(_media_data(segments_per_page)-1);
_sm_rd_cmd_begin(k_sm_reset_chip);
sm_wait_rdy_with_timeout(k_sm_busy_reset_timeout);
return(nand_int_write_begin_quick_split());
trace2(0, nand_int, 0, "beginning split at page:%d segment:%d", g_addr_page, g_addr_segment) ;
}
else
{
g_fmc_begin_split_callback = (t_fmc_callback) n2k_write_begin_split;
trace2(0, n2k, 0, "beginning split at page:%d segment:%d", g_addr_page, g_addr_segment) ;
// check to see if we are starting in middle of a page
if (g_addr_segment)
{
// pre-read the old page into chip cache
n2k_page_read_for_copy() ;
// write the full destination address
nand_cmd_page_write_cache_data() ;
n2k_page_set_wr_offset( _n2k_data_offset( g_addr_segment ) ) ;
}
return(k_success);
}
return(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// n2k_write_begin_xfer
//
// Declaration:
// void n2k_write_begin_xfer(void) reentrant
//
// Purpose:
//
// Arguments:
//
// Return:
//
// Notes:
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result n2k_write_begin_xfer() reentrant
{
t_result result ;
uint16 max_split_size ;
trace4(0, sm, 10, "n2k_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;
// get virtual addr
map_lba2addr_rd(_fmc_get_start_lb_32()) ;
// enable the correct card
nand_select_card() ;
// copy head
result = map_write_begin( _fmc_get_start_lb_32() ) ;
// 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();
// precompute max split size
max_split_size = (_media_data(pages_per_block)-g_addr_page)*_media_data(segments_per_page)-g_addr_segment ;
if (!g_addr_page)
{
_lun_data(max_lb_per_split) = _min( max_split_size, _fmc_get_lb_count_32());
trace5(0, n2k, 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( max_split_size, _fmc_get_lb_count_32());
trace5(0, n2k, 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));
}
// burst size needs to be 1, because the sm controller can't
// handle more than 512 bytes out at a time.
_lun_data(max_lb_per_burst) = 1;
return(result );
}
//+-----------------------------------------------------------------------------
// Name:
// n2k_write_begin_split
//
// Declaration:
// t_result n2k_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 n2k_write_begin_split() reentrant
{
uint8 zone_before ;
trace0(0, n2k, 1, "sm_write_begin_split()");
trace1(0, n2k, 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, n2k, 0, "zone-change detected.") ;
nand_select_card() ;
sm_set_write_mode_page_data() ;
}
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") ;
return(k_success);
}
//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result n2k_write_end_split(void) reentrant
{
trace0(0, n2k, 0, "n2k_write_end_split()") ;
trace2(0, n2k, 0, "split ended on to page %d segment %d", g_addr_page, g_addr_segment) ;
if ( g_addr_segment )
{
trace0(0, n2k, 0, "last split. need to flush current page cache") ;
if ( k_success != nand_cmd_page_program() )
{
trace0(0, n2k, 0, "nand_cmd_cache_program failed") ;
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 n2k_write_begin_burst() reentrant
{
trace5(0, n2k, 0, "n2k_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, n2k, 0, " - n_lbs_this_xfer:%d", g_n_lb_this_xfer.u32) ;
// check to see if we are starting in middle of a page
if (!g_addr_segment)
{
// pre-read the old page into chip cache
n2k_page_read_for_copy() ;
// write data into the on-chip cache, starting at the beginning of the page
nand_cmd_page_write_cache_data() ;
}
_mcu_register_set_bits(sm_mode_ctl,kbm_sm_mode_ecc_blk_xfer_en) ;
_sm_hw_ecc_wr_start() ;
trace0(0, n2k, 0, "bursting") ;
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_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 n2k_write_end_burst(void) reentrant
{
trace0(0, sm, 0, "n2k_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") ;
g_addr_segment++ ;
if ( g_addr_segment==_media_data(segments_per_page) )
{
trace0(0, n2k, 0, "last burst in the page. program the page cache") ;
if ( k_success != nand_cmd_page_program() )
{
trace0(0, sm, 0, "nand_cmd_cache_program failed") ;
return(k_error );
}
g_addr_page++;
g_addr_segment=0;
nand_incr_addr() ;
}
return(k_success );
}
//+-----------------------------------------------------------------------------
// 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.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -