📄 nand_int_media.c
字号:
_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:
// nand_int_write_begin_split
//
// Declaration:
// t_result nand_int_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 nand_int_write_begin_quick_split() reentrant
{
uint8 zone_before ;
t_result result;
t_sync sync;
uint8 cnt;
trace0(0, nand_int, 1, "sm_write_begin_split()");
trace1(0, nand_int, 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, nand_int, 0, "zone-change detected.") ;
nand_int_select_chip(_media_data(segments_per_page)-1);
_sm_set_rd_cmd(k_sm_reset_chip);
sm_wait_rdy_with_timeout(k_sm_busy_reset_timeout);
}
if(g_addr_wr_phy_blk == k_block_free)
{
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() ;
// write the count registers which won't change
_mcu_register_wr(x_fmc_cnt3, 0);
_mcu_register_wr(x_fmc_cnt2, 0);
_mcu_register_wr(x_fmc_cnt0, 0);
result = k_success;
// do max of 1 splits worth of bursts
cnt=(uint8) _fmc_get_lb_count_32();
while (cnt)
{
trace1(0, nand_int, 0, "cnt %02x",cnt);
//choose the target chip
nand_int_select_chip(g_addr_segment);
//check to see if the chip is busy
if ( nand_int_hw_bsy())
{
//then wait for it to be done
result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
if (result != k_success)
{
//something is seriously wrong
trace0(0, cds, 0, "Fatal error aborted waiting for the chip to get ready!!");
return(result);
}
}
//------------------------------------------------------------------------------
// check status... not necessary for first write, but coding is simpler to just always do it.
if (k_success != nand_cmd_check_status_new())
{
trace0(0, cds, 0, "sm_write_end_burst - write fault") ;
return(k_error);
}
//------------------------------------------------------------------------------
// start a single burst
trace4(0, sm, 0, "+sm_write_begin_burst() - zone:%d 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);
//------------------------------------------------------------------------------
// start the blk xfer
// clear blk_xfer_complete irq.
_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
_mcu_register_wr(x_fmc_cnt1, 0x02);
_mcu_register_set_bits(x_fmc_ctl, kbm_fmc_ctl_blk_xfer_en);
//------------------------------------------------------------------------------
// do calculations while data is moving (or waiting to move)
cnt--;
g_addr_segment=(g_addr_segment+1)%_media_data(segments_per_page);
if (!g_addr_segment)
{
trace0(0, nand_int, 0, "last burst in the page" ) ;
g_addr_page++;
nand_incr_addr() ;
}
//------------------------------------------------------------------------------
// wait for data to finish moving
thread_set_timer(g_fmc_timeout);
do
{
sync = _thread_got_sync(kbm_sync_abort |kbm_sync_usbrst |kbm_sync_timer);
_thread_clr_sync(sync);
if (sync & kbm_sync_usbrst)
{
trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: kbm_sync_usbrst");
result = k_usbreset;
break;
}
if (sync & kbm_sync_abort)
{
trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: kbm_sync_abort");
result = k_aborted;
break;
}
if (sync & kbm_sync_timer)
{
trace0(0, cds, 1, "optimized fmc_wait_blk_irq_with_timeout() - error: timeout awaiting irq");
result = k_timeout;
break;
}
// AAA: added this to poll instead of taking the interrupt
// cds: added isr bit fmc_irq to break out of loop for fmc error (ecc or otherwise) detection
} while (!(_mcu_register_rd(x_isr0) & (kbm_isr0_blk_xfer_complete) ));
_sm_hw_ecc_wr_stop() ;
sm_mode_ctl &= ~kbm_sm_mode_ecc_blk_xfer_en;
if (k_success!=result)
{
trace0(0, cds, 0, "optimized interleaved write split error in xfer. aborting") ;
return (result);
}
// issue command to program the flash, then loop to next chip
trace0(0, sm, 0, "cmd: write") ;
_sm_set_wr_cmd(k_sm_write);
}
//------------------------------------------------------------------------------
// do one final pass through waiting for write to finally finish on all chips
for (cnt=0;cnt<_media_data(segments_per_page);cnt++)
{
nand_int_select_chip(cnt);
if ( nand_int_hw_bsy())
{
//then wait for it to be done
result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
if (result != k_success)
{
//something is seriously wrong
trace0(0, cds, 0, "Fatal error aborted waiting for the chip to get ready!!");
return(result);
}
}
if (k_success != nand_cmd_check_status_new())
{
trace0(0, cds, 0, "sm_write_end_burst - write fault") ;
return(k_error );
}
}
g_start_lb_this_xfer.u32 += g_n_lb_this_split.u32;
g_n_lb_this_xfer.u32 -= g_n_lb_this_split.u32;
_mscbot_decr_residue( (g_n_lb_this_split.u32*512L) );
g_n_lb_this_split.u32 = 0;
return(k_success);
}
//+-----------------------------------------------------------------------------
// Name:
// nand_int_write_begin_split
//
// Declaration:
// t_result nand_int_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 nand_int_write_begin_split() reentrant
{
#ifdef Dominic
uint8 zone_before ;
uint8 addr_segment;
trace0(0, nand_int, 1, "sm_write_begin_split()");
trace1(0, nand_int, 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, nand_int, 0, "zone-change detected.") ;
nand_int_select_chip(_media_data(segments_per_page)-1);
sm_set_write_mode_page_data();
nand_int_select_chip(g_addr_segment);
}
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") ;
#endif
return(k_success);
}
//+-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result nand_int_write_end_split(void) reentrant
{
uint8 addr_segment = g_addr_segment;
t_result result;
trace0(0, cds, 0, "nand_int_write_end_split()") ;
trace2(0, nand_int, 0, "split ended on to page %d segment %d", g_addr_page, g_addr_segment) ;
if ( g_addr_segment )
{
_mcu_register_clr_bits(x_fmc_ctl, kbm_fmc_ctl_auto_trans);
trace0(0, nand_int, 0, "auto-transfer bit ==> OFF");
//copy page tail
for (; addr_segment < _media_data(segments_per_page); addr_segment++)
{
nand_int_select_chip(addr_segment);
result=sm_media_copy_sector();
if (k_success!=result)
{
if (k_media_copy_error_src==result)
{
trace0(0, nand_int, 0, "read error detected. continue copying") ;
}
else
{
trace0(0, nand_int, 0, "fatal error occured while copying. aborting copy_block()") ;
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 nand_int_write_begin_burst() reentrant
{
#ifdef Dominic
t_result result;
trace5(0, nand_int, 0, "nand_int_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, nand_int, 0, " - n_lbs_this_xfer:%d", g_n_lb_this_xfer.u32) ;
//choose the next chip
nand_int_select_chip(g_addr_segment);
//check to see if the chip is busy
if ( nand_int_hw_bsy())
{
//then wait for it to be done
result = sm_wait_rdy_with_timeout(k_sm_busy_programming_timeout);
if (result != k_success)
{
//something is seriously wrong
trace0(0, nand_int, 0, "Fatal error aborted waiting for the chip to get ready!!");
return(result);
}
//check to see if there is a status failure
if (k_success != nand_cmd_check_status())
{
trace0(0, sm, 0, "sm_write_end_burst - write fault") ;
g_addr_page-- ;
return(k_error );
}
}
//check to see if there is a status failure
if (k_success != nand_cmd_check_status())
{
trace0(0, sm, 0, "sm_write_end_burst - write fault") ;
g_addr_page-- ;
return(k_error );
}
// _mcu_register_set_bits(sm_mode_ctl,kbm_sm_mode_ecc_blk_xfer_en) ;
// _sm_hw_ecc_wr_start() ;
trace0(0, nand_int, 0, "bursting") ;
#endif
return(sm_write_begin_burst());
}
//+-----------------------------------------------------------------------------
// 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 nand_int_write_end_burst(void) reentrant
{
#ifdef Dominic
trace0(0, sm, 0, "nand_int_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") ;
//x_smc_stat = kbm_smc_stat_rdy ;
trace0(0, sm, 0, "cmd: write") ;
_sm_set_wr_cmd(k_sm_write);
g_addr_segment++ ;
if ( g_addr_segment==_media_data(segments_per_page) )
{
trace0(0, nand_int, 0, "last burst in the page" ) ;
g_addr_page++;
g_addr_segment=0;
nand_incr_addr() ;
}
#endif
return(k_success );
}
//+-----------------------------------------------------------------------------
// Name:
// nand_int_read_end_burst
//
// Declaration:
// t_result nand_int_read_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 nand_int_read_end_burst(void) reentrant
{
t_result result;
trace0(0, nand_int, 0, "nand_int_read_end_burst()") ;
//just check if the chip is done.., should be at this point
if (k_success != sm_wait_rdy_with_timeout(k_sm_busy_read_timeout))
{
TRACE0(445, nand, 0, "error waiting for data") ;
nand_cmd_reset_device();
return(k_error );
}
result = sm_read_end_burst();
g_addr_segment++ ;
if ( g_addr_segment==_media_data(segments_per_page) )
{
g_addr_page++;
g_addr_segment=0;
nand_incr_addr() ;
}
//select the appropriate chip
nand_int_select_chip(g_addr_segment);
return(result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -