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 + -
显示快捷键?