ms_media.c
来自「U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有」· C语言 代码 · 共 853 行 · 第 1/3 页
C
853 行
_mcu_register_clr_bits(x_imr0, kbm_isr0_blk_xfer_complete);
// $$$$$$ warning!
// $$ must do a while loop because we cannot yield
// also, cannot have a timer, because of the memory stick bug... the timer
// is in XDATA space, and touching it during ms fmdu xfers ist verboten
while (1)
{
// poll isr's to check on events that should cause us to break,
// and on those events, set the mask and get out.
if ((_mcu_register_rd(x_isr0) & kbm_isr0_blk_xfer_complete))
{
//irq_control(k_irq_blk_xfer_complete, kbm_irqctl_clear| kbm_irqctl_mask);
// dont clear it here because the irq is no longer used, and the sync is no longer
// delivered, and the fmc layer polls the bit
//_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
_mcu_register_set_bits(x_imr0, kbm_isr0_blk_xfer_complete);
//thread_set_sync(g_tid, kbm_sync_fmc_blk);
break;
}
// check for a usb reset during the xfer
else
if (_mcu_register_rd(x_wu_src1) & kbm_wk1_usb_reset)
{
_dev_soft_reset();
thread_set_sync(g_tid, kbm_sync_usbrst);
// you can't get here from there... soft reset puts everything back to por state
break;
}
// abort on status change of memory stick
else
if (_mcu_register_rd(x_wu_src1) & kbm_wk1_crd_sts_chg)
{
if (_mcu_register_rd(x_crd_stat) & kbm_crd_stat_ms_out)
{
_ejected(g_active_lun);
thread_set_sync(g_tid, kbm_sync_abort);
break;
}
}
}
_mcu_end_critical_section() ;
if (!_ms_rx_data_fifo_is_empty())
{
trace0(0, ms, 10, "alert - entered read_end_burst before rx fifo emptied - wait before stopping dma");
//if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, ms_fifo_stat_r_buf_e, 3)) //rcc test for MS bug tbh!!!
#if defined(k_mcu_97210)
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_r_buf_e, 0, 3))
return k_error;
#elif defined(k_mcu_97223)
if (k_success != ms_wait_fifo_with_timeout(kbm_ms_alt_stat_fifo_e, 0, 3))
return k_error;
#endif
}
// clear daken before issuing command other than wr-page-data and rd-page-data
#if defined(k_mcu_97210)
_ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
trace0(0, ms_media, 0, "ms_copy_sector() read complete") ;
trace0(0, ms_media, 0, "ms_copy_sector() read complete") ;
#elif defined(k_mcu_97223)
_ms_register_clr_bits(msc_mode_ctl_1, kbm_ms_mode_ctl_dam);
#endif
// bind current logical block to new physical block
ms_media_bind_log2phy() ;
// reverse data flow direction: sram->device
_mcu_register_clr_bits( x_ep2_ctl, kbm_ep2_ctl_dir) ;
// program the card to write 1 sector at g_addr_wr_phy_blk
set_wr_phyblk();
//return ms_write_issue_command();
if (k_success != ms_write_all_reg(0x80, 0x20))
return k_error;
if (k_success != ms_set_cmd(k_ms_block_write))
return k_error;
if (k_success != ms_get_int(10))
return k_error;
if (_factor & kbm_ms_reg_int_cmdnk)
{
trace0(0, ms, 10, "error: cmdnk");
return k_error;
}
if (!(_factor & kbm_ms_reg_int_breq))
{
trace0(0, ms, 10, "error: breq not set");
return k_error;
}
// daken must be set during dma transfers.
// only wr-page-data and rd-page-data can be issued with daken set.
#if defined(k_mcu_97210)
_ms_register_set_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
if (k_success != ms_set_tpc(k_ms_tpc_wr_page_data |0x02, 0))
{
_ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
return k_error;
}
#elif defined(k_mcu_97223)
_ms_register_set_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
if (k_success != ms_set_tpc(k_ms_tpc_wr_page_data |0x02, 0))
{
_ms_register_clr_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
return k_error;
}
#endif
// IMPORTANT! This begin_critical_section() is ended in the 'rw_intra_burst' function
// to prevent xdata access while blk_xfer bit is enabled
_mcu_begin_critical_section();
// set fmc ctl reg - 1 sector
_mcu_register_wr(x_fmc_cnt3, 0x00) ;
_mcu_register_wr(x_fmc_cnt2, 0x00) ;
_mcu_register_wr(x_fmc_cnt1, 0x02) ;
_mcu_register_wr(x_fmc_cnt0, 0x00) ;
// enable blk xfer, use 512 bytes per burst
_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
_mcu_register_clr_bits(x_imr0, kbm_isr0_blk_xfer_complete);
_mcu_register_wr(x_fmc_ctl, (kbm_fmc_ctl_512_byte_pkt|kbm_fmc_ctl_blk_xfer_en)) ;
// point the byte count & source buffer for fmdu to buffer a
_mcu_register_wr( x_ramrdbc_a1, 0x02) ;
_mcu_register_wr( x_ramrdbc_a2, 0x00) ;
// (rdtog_valid:1 ramrd_tog:0)
_mcu_register_set_bits( x_ep2_ctl, kbm_ep2_ctl_rdtog_valid) ;
// warning!
// must do a while loop because we cannot yield
// also, cannot have a timer, because of the memory stick bug... the timer
// is in XDATA space, and touching it during ms fmdu xfers ist verboten
while (1)
{
// poll isr's to check on events that should cause us to break,
// and on those events, set the mask and get out.
if ((_mcu_register_rd(x_isr0) & kbm_isr0_blk_xfer_complete))
{
//irq_control(k_irq_blk_xfer_complete, kbm_irqctl_clear| kbm_irqctl_mask);
// dont clear it here because the irq is no longer used, and the sync is no longer
// delivered, and the fmc layer polls the bit
//_mcu_register_wr(x_isr0, kbm_isr0_blk_xfer_complete);
_mcu_register_set_bits(x_imr0, kbm_isr0_blk_xfer_complete);
//thread_set_sync(g_tid, kbm_sync_fmc_blk);
break;
}
// check for a usb reset during the xfer
else
if (_mcu_register_rd(x_wu_src1) & kbm_wk1_usb_reset)
{
_dev_soft_reset();
thread_set_sync(g_tid, kbm_sync_usbrst);
// you can't get here from there... soft reset puts everything back to por state
break;
}
// abort on status change of memory stick
else
if (_mcu_register_rd(x_wu_src1) & kbm_wk1_crd_sts_chg)
{
if (_mcu_register_rd(x_crd_stat) & kbm_crd_stat_ms_out)
{
_ejected(g_active_lun);
thread_set_sync(g_tid, kbm_sync_abort);
break;
}
}
}
_mcu_end_critical_section() ;
if (!_ms_tx_data_fifo_is_empty())
{
trace0(0, ms, 10, "alert - entered write_end_burst before tx fifo emptied - wait before stopping dma");
#if defined(k_mcu_97210)
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
#elif defined(k_mcu_97223)
if (k_success != ms_wait_fifo_with_timeout( kbm_ms_alt_stat_fifo_e , kbm_ms_alt_stat_fifo_e , 3))
return k_error;
#endif
}
// clear daken before issuing command other than wr-page-data and rd-page-data
#if defined(k_mcu_97210)
_ms_register_clr_bits(ms_mode_ctl, kbm_ms_mode_ctl_daken);
#elif defined(k_mcu_97223)
_ms_register_clr_bits(msc_mode_ctl_1 , kbm_ms_mode_ctl_dam);
#endif
// get status
if (k_success != ms_get_int(10))
return k_error;
if (_factor & kbm_ms_reg_int_cmdnk)
{
trace0(0, ms, 10, "error: cmdnk");
return k_error;
}
if (_factor & kbm_ms_reg_int_breq)
{
trace0(0, ms, 0, "error: breq set after block-end (presumably) delivered");
return k_error;
//TRACE0(448, ms, 0, "alert: breq set");
}
if (!(_factor & kbm_ms_reg_int_ced))
{
trace0(0, ms, 0, "error: ced not set");
return k_error;
}
if (_factor & kbm_ms_reg_int_err)
{
trace0(0, ms, 10, "error: ced&err unrecoverable flash write error");
ms_media_set_phyblock_failed();
return k_error;
}
// write complete
return k_success;
}
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//t_result ms_media_write_sector() reentrant
//{
// trace0(0, ms_media, 0, "ms_media_write_sector()");
// set_wr_phyblk();
// return ms_pio_write_page(k_max_pnr);
//}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_phy2log() reentrant
{
uint16 absolute;
uint16 relative;
trace0(0, ms_media, 10, "ms_media_phy2log()");
absolute = g_ms_extra[k_log_addr_msb_flg_offset] * 256 + g_ms_extra[k_log_addr_lsb_flg_offset];
switch (g_addr_zone)
{
case 0:
relative = absolute;
break;
case 1:
relative = absolute - _media_data(logical_blocks_per_boot_zone);
break;
default:
relative = absolute - _media_data(logical_blocks_per_boot_zone);
relative %= _media_data(logical_blocks_per_zone);
break;
}
g_addr_log_blk = relative;
trace3(0, ms, 110, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
return k_success;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_bind_log2phy() reentrant
{
uint16 absolute;
trace1(0, ms_media, 10, "ms_media_bind_log2phy() log:%04X", g_addr_log_blk);
switch (g_addr_zone)
{
case 0:
absolute = g_addr_log_blk;
break;
case 1:
absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
break;
default:
absolute = g_addr_log_blk + _media_data(logical_blocks_per_boot_zone);
absolute += (g_addr_zone - 1) * _media_data(logical_blocks_per_zone);
break;
}
trace3(0, ms, 10, "...zone:%02d absolute:0x%04X relative:0x%04X", g_addr_zone, absolute, g_addr_log_blk);
g_ms_extra[k_log_addr_msb_flg_offset] = _h(absolute);
g_ms_extra[k_log_addr_lsb_flg_offset] = _l(absolute);
return k_success;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result ms_media_set_phyblock_failed() reentrant
{
trace0(0, ms_media, 0, "ms_media_set_phyblock_failed()");
g_ms_extra[k_ovwr_flg_offset] &= ~ kbm_ms_ext_ovwr_bkst;
return k_error;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#define k_reference_bad_block_table
t_bool ms_media_is_phyblock_ok() reentrant
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?