mscbot.c
来自「U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有」· C语言 代码 · 共 1,068 行 · 第 1/4 页
C
1,068 行
}
//------------------------------------------------------------------------------
// this is only called form the isrs
//------------------------------------------------------------------------------
static t_result hpbot_wait_create() reentrant using 1
{
trace0(0, bot, 0, "hpbot_wait_create()");
_tx_missed_ack = k_no;
_thread_clr_sync(kbm_sync_outnak);
_endpoint_unmask_outnak(k_rx_pipe);
dev_turn_off_activity_indicator();
#ifdef k_pfm_demo
// turn off the debug lights of science
_mcu_register_set_bits(x_gpiob_out, kbm_gpio12 |kbm_gpio13 |kbm_gpio14 |kbm_gpio15);
#endif
#ifdef k_pfm_led
// turn off the activity LEDs
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio12 |kbm_gpio13 |kbm_gpio14 |kbm_gpio15);
#endif
_hpbot_thread_entry = hpbot_wait_pipe_ready_for_rx;
return(k_success);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static t_result hpbot_wait_pipe_ready_for_rx(uint8 intr) reentrant using 1
{
trace1(0, bot, 0, "hpbot_wait_pipe_ready_for_rx(%d)", intr);
switch (intr)
{
// outnak
case k_irq_nak2rx:
if (!dev_rd_most_recent_config())
{
// do nothing but rearm for outnaks until the set-config has been processed.
// this avoids a race condition where the hardware processes the set-config(1)
// then the first cbw arrives and is delivered to the drive -before- the drive
// is powered on because the fgnd has not yet processed the set-config()
// and powered up the drive. (the fw does not process the control pipe for set-config...
// the hardware does, and then gives an interrupt letting the fw see the config value...
// so, leave the pipe in the "por nakking" state, or, after suspend, the "tx"
// state so the cbw will be nakked, not received, until the drive gets powered
// on and initialized. (note this requires that the suspend handler put the
// pipe into the "tx" state so any cbw will be nakked in the case where the
// resume interrupt occurs, then a usbreset, then a set-config, and a quickly
// following inquiry on the bulk pipe.
//DS Modified to unmask the pipe only when we are done configuring
if (!g_new_config)
{
_endpoint_unmask_outnak(k_rx_pipe);
}
return(k_success);
}
// the outnak signals that the host is trying to send us a cbw
trace0(0, bot, 0, "got the nak, enabling rx endpoint");
_endpoint_rx_enable(k_rx_pipe);
_buffer_rx_enable(4);
_hpbot_thread_entry = hpbot_wait_cbw;
return(k_success);
// usbrst
case k_irq_usb_stat_reset:
case k_irq_usb_reset:
_thread_clr_sync(kbm_sync_all);
hpbot_wait_create();
// let the default interrupt handler see this also
return(k_ignored);
// let the default inrt handler handle everything else
default:
trace0(0, bot, 0, "intr ignored");
return(k_ignored);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static t_result hpbot_wait_cbw(uint8 intr) reentrant using 1
{
// t_data_ref bufp;
t_xdata_ref bufp;
trace1(0, bot, 0, "hpbot_wait_cbw(%d)", intr);
switch (intr)
{
// usbrx: profiling shows this case takes about 58usec
case k_irq_ramwr_a:
//_profile_on(5);
//mmu_rd_pkt(pnr, sizeof(t_cbw), (t_memory_ref)&g_bot_cbw);
// bufp = (t_data_ref)&g_bot_cbw;
bufp=(t_xdata_ref)&g_bot_cbw;
_mcu_register_wr(x_sram_addr_lo, k_pkt_addrlo[4]);
_mcu_register_wr(x_sram_addr_hi, k_pkt_addrhi[4]);
_hdw_clk_domain_bug_workaround();
// unrolled loop, 31 bytes of cbw
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
*bufp++=_mcu_register_rd(x_sram_data);
//mmu_deallocate(4);
_mcu_register_wr(x_isr0, kbm_isr0_ramwr_a);
_mcu_register_clr_bits(x_imr0, kbm_isr0_ramwr_a);
// dump its contents
trace1(0, bot, 0, "dwCBWSignature: %02X (lsw lsb)", g_bot_cbw.dwCBWSignatureLo);
trace1(0, bot, 0, "dwCBWSignature: %02X (lsw msb)", g_bot_cbw.dwCBWSignatureHl);
trace1(0, bot, 0, "dwCBWSignature: %02X (msw lsb)", g_bot_cbw.dwCBWSignatureLh);
trace1(0, bot, 0, "dwCBWSignature: %02X (msw msb)", g_bot_cbw.dwCBWSignatureHi);
trace1(0, bot, 0, " dwCBWTag: %02X (lsw lsb)", g_bot_cbw.dwCBWtagLo);
trace1(0, bot, 0, " dwCBWTag: %02X (lsw msb)", g_bot_cbw.dwCBWtagHl);
trace1(0, bot, 0, " dwCBWTag: %02X (msw lsb)", g_bot_cbw.dwCBWtagLh);
trace1(0, bot, 0, " dwCBWTag: %02X (msw msb)", g_bot_cbw.dwCBWtagHi);
trace1(0, bot, 0, " dwXferLength: %02X (lsw lsb)", g_bot_cbw.dwCBWXferLengthLo);
trace1(0, bot, 0, " dwXferLength: %02X (lsw msb)", g_bot_cbw.dwCBWXferLengthHl);
trace1(0, bot, 0, " dwXferLength: %02X (msw lsb)", g_bot_cbw.dwCBWXferLengthLh);
trace1(0, bot, 0, " dwXferLength: %02X (msw msb)", g_bot_cbw.dwCBWXferLengthHi);
trace1(0, bot, 0, " bCBWlun: %02X", g_bot_cbw.bCBWlun);
trace1(0, bot, 0, " bmCBWFlags: %02X", g_bot_cbw.bCBWFlags);
trace1(0, bot, 0, " bCBWCBLength: %02X", g_bot_cbw.bCBWCBLength);
// verify the signature
if ((0x55 != g_bot_cbw.dwCBWSignatureLo) ||
(0x53 != g_bot_cbw.dwCBWSignatureHl) ||
(0x42 != g_bot_cbw.dwCBWSignatureLh) ||
(0x43 != g_bot_cbw.dwCBWSignatureHi))
{
trace0(0, bot, 0, "error - bad signature");
return(hpbot_send_status(k_command_failed));
}
// verify the cdb length
if (0x10 < g_bot_cbw.bCBWCBLength)
{
trace0(0, bot, 0, "error - bad cdb length");
return(hpbot_send_status(k_command_failed));
}
// initialize everything we might need to use
// extract the parameters from the command
g_bot_data_len.u8.lo = g_bot_cbw.dwCBWXferLengthLo;
g_bot_data_len.u8.hl = g_bot_cbw.dwCBWXferLengthHl;
g_bot_data_len.u8.lh = g_bot_cbw.dwCBWXferLengthLh;
g_bot_data_len.u8.hi = g_bot_cbw.dwCBWXferLengthHi;
// what direction is the data supposed to flow?
g_bot_xfer_dir = g_bot_cbw.bCBWFlags & kbm_cbw_dir_d2h ? k_dir_read : k_dir_write;
// reverse pipe for reads
if (g_bot_xfer_dir == k_dir_read)
{
if (_tx_missed_ack)
ndp2_tx_enable_ex();
else
{
_endpoint_tx_enable(k_tx_pipe);
}
}
// convert the logical lun (from the cbw) into a physical lun (index into lun tables)
_active_lun = _lun_log2phy(g_bot_cbw.bCBWlun);
#ifdef k_pfm_demo
// there are 5 phy luns, but only 4 leds. assumes sd and mmc "share" an led.
_mcu_register_clr_bits(x_gpiob_out, 0x10 << _min(3, _active_lun));
#endif
// the mux is no longer enabled here because this is an isr.
// the mux is enabled in the dev thread when it wakes on sync-cbw.
// _lun_enable_mux(_active_lun)();
// data access led on during read/write
switch (g_bot_cbw.cdb[0])
{
case k_protocol_read_10:
case k_protocol_read_12:
case k_protocol_write_10:
case k_protocol_write_12:
case k_protocol_verify_10:
if (g_post_access_blink_secs) //Are we blinking still?
{
irq_control(k_irq_cpu_t1, kbm_irqctl_mask); //then stop the timer
g_post_access_blink_secs = 0x00;
dev_turn_off_activity_indicator();
trace0(0, dev, 0, "next data access blinker off");
}
//if (g_blink_interval) //Are we supposed to blink?
//{
irq_control(k_irq_cpu_t1, kbm_irqctl_unmask); //then start the timer
_data_access = k_true;
//}
dev_toggle_activity_indicator();
//rcc code to turn OFF leds during access to respective luns LEDs are ON when card inserted
// they go off when card is out or blink off when accessed.
#ifdef k_pfm_led
// there are 5 phy luns, but only 4 leds. assumes sd and mmc "share" an led.
//_mcu_register_clr_bits(x_gpiob_out, 0x10 << _min(3, _active_lun));
if (_lun_is_media_present(_active_lun))
{
switch (_active_lun)
{
case k_lun_cf:
trace0(0, dev, 66, "CF LED OFF!");
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio13);
dev_common_media_led_off();
break;
case k_lun_ms:
trace0(0, dev, 66, "MS LED OFF!");
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio12);
dev_common_media_led_off();
break;
case k_lun_sm:
trace0(0, dev, 66, "SM LED OFF!");
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio14);
dev_common_media_led_off();
break;
case k_lun_sd:
trace0(0, dev, 66, "SD LED OFF!");
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio15);
dev_common_media_led_off();
break;
case k_lun_mmc:
trace0(0, dev, 66, "MMC LED OFF!");
_mcu_register_clr_bits(x_gpiob_out, kbm_gpio15);
dev_common_media_led_off();
break;
}
}
#endif
break;
}
// break the interrupt chain until the foreground is done and restarts the chain
_hpbot_thread_entry = NULL;
// tell the fgnd to run the command
//thread_set_sync(g_ix_dev_thread, kbm_sync_cbw);
g_thread[g_ix_dev_thread].bits_got |= kbm_sync_cbw;
//_profile_off(5);
return(k_success);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?