⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c

📁 U盘控制器USB97C223的固件代码,对2kPAGE NAND FLASH 有很好的支持.
💻 C
📖 第 1 页 / 共 5 页
字号:
  {
       trace0(0, sd, 1, "sd protected by bit 7");
      _sd_write_protected = k_true;    // bit 7 set, always write protect
  }
  else
  {
  //Is the media write protected?
  //Check for hardware write protection...
  //...added to check the attribute bit. this is Melco's request. - hm 02/27/03
  
        if (_mcu_register_rd(x_media_sts) & 0x01)       // SD_nWP is low
        {
            if (!(g_dev_attr_lo & kbm_attr_lo_sd_wp))   // bit 6 is 0
            {
                trace0(0, sd, 1, "sd protected - active low SD_nWP");
                _sd_write_protected = k_true;           // normal WP
            }
        }
        else                                            // SD_nWP is high
        {
            if (g_dev_attr_lo & kbm_attr_lo_sd_wp)     // bit 6 is 1
            {
                trace0(0, sd, 1, "sd protected - active high SD_nWP");
                _sd_write_protected = k_true;          // reverse polarity WP
            }
        }
  }
  
  //Check for software write protection
  if ((sdc_cmd_rsp_buf[15] & 0x04) || (sdc_cmd_rsp_buf[15] & 0x08))
    _sd_write_protected = k_true;
  if (_sd_write_protected == k_true)
  {
    _lun_data(media) |= kbm_lun_media_wrprot;
  }
  else
  {
    _lun_data(media) &= ~kbm_lun_media_wrprot;
  }
  sdc_read_rsp(17);
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  //Put the device into transfer mode and get ready to roll
  sd_get_status();
  //select the crd
  sd_pre_cmd();
  sdc_cmd_rsp_buf[0] = 0x47;
  sdc_cmd_rsp_buf[1] = g_sdc_rca_h;
  sdc_cmd_rsp_buf[2] = g_sdc_rca_l;
  sdc_cmd_rsp_buf[3] = 0x00;
  sdc_cmd_rsp_buf[4] = 0x00;
  sd_display_rsp_buf();
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  _sd_wait_48b_resp();
  sd_display_rsp_buf();
  sd_get_status();
  sdc_read_rsp(5);
  //**********************************
  //Set the block length
  trace0(0, sd, 1, "Set the block length to 512")
  sd_pre_cmd();
  sdc_cmd_rsp_buf[0] = 0x50;
  sdc_cmd_rsp_buf[1] = 0x00;
  sdc_cmd_rsp_buf[2] = 0x00;
  sdc_cmd_rsp_buf[3] = 0x02;
  sdc_cmd_rsp_buf[4] = 0x00;
  //sd_display_rsp_buf();
  trace1(0, sd, 0, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  _sd_wait_48b_resp();
  sd_display_rsp_buf();
  sd_get_status();
  sdc_read_rsp(5);
  //********************************************
  //set the data bus to 4 bit wide
  if (g_active_lun == k_lun_sd)
  {
    sd_set_bus_width(k_four_data_lines);
  }
  sd_get_status();
  _lun_data(media) &= ~kbm_lun_media_unknown;
  _mcu_register_clr_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_disable);
  _mcu_register_set_bits(x_fmc_clk_ctl, k_fmc_clk_ctl_sd_20mhz);
  //Enough time to let the clk freq change... should be changed to more accurate time.
  thread_set_timer(1);
  while (!(thread_got_sync(kbm_sync_timer)));
  thread_clr_sync(kbm_sync_timer);
  thread_return_dfa(k_success);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void sd_pre_erase() reentrant
{
  trace0(0, sd, 0, "+sd_pre_erase();");
  sd_app_cmd();
  sd_pre_cmd();
  sdc_cmd_rsp_buf[0] = 0x57;      //pre_ERASE
  sdc_cmd_rsp_buf[1] = 0X00;
  sdc_cmd_rsp_buf[2] = 0X00;
  sdc_cmd_rsp_buf[3] = g_n_lb_this_split.u8.hl;
  sdc_cmd_rsp_buf[4] = g_n_lb_this_split.u8.lo;
  _sd_wait_48b_resp();
  sd_display_rsp_buf();
  sdc_read_rsp(5);
  return;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result sd_read_write_begin_xfer() reentrant
{
  uint32 n_bytes_this_xfer = 0;
  //The max lbs we can transfer is however much the host asks for
  #ifndef k_mcu_97223
  if (sie_is_high_speed())
  #endif
  {
    // timer1 disabled during sd transfers to avoid data corruption issue.  bug report #343
    #if 0




    //Turn off the timer interrupt for 2.0 reads
    irq_control(k_irq_cpu_t1,  kbm_irqctl_mask);
    //Put the led in the opposite state of idle
    if (g_led_stays_on)           //opposite of idle state
      gpio_clrbit(0);
    else
      gpio_setbit(0);
    #endif

    _lun_data(max_lb_per_split) =_fmc_get_lb_count_32();
    _lun_data(max_lb_per_burst) = _fmc_get_lb_count_32();
  }
  #ifndef k_mcu_97223 
  else
  {
    if (_sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks)  // we can issue mult write cmd
    {
      _lun_data(max_lb_per_split) = _fmc_get_lb_count_32();
      _lun_data(max_lb_per_burst) = 1;
      //Turn off Auto xfer  and exit on count zero
      _fmc_set_options(kbm_fmc_disable_auto_xfer |kbm_fmc_end_burst_on_count_down |kbm_fmc_xfer_512_byte_pkt);
    }
    else
    {                             //1.1 reads
      _lun_data(max_lb_per_split) = 1;
      _lun_data(max_lb_per_burst) = 1;
      //Turn off Auto xfer
      _fmc_set_options(kbm_fmc_disable_auto_xfer |kbm_fmc_xfer_512_byte_pkt);
      trace1(0, sd, 3, "Setting the 512 byte pkt bit.. %02x", g_fmc_options);
    }
  }

  #endif
  //Even though the timeout should be calculated based on the CSD register, we shall calculate based on 1.1
  //transfer speed. Currently we are at 200kBPS and this is the slowest part of the equation.
  //On future releases, when we have overcome the hardware limitations, we shall calculate the timeout using
  //the media-dependant values from the CSD register.
  //Since any 16 or 32 bit computation slows down the reads/writes.. this value is computed offline
  //It takes 2.5 ms to xfer a block of data at 200 KBPS. Let us round it to 3 ms. The  multiply by 2 to add a margin.
  //g_fmc_timeout = ( 6 * _fmc_get_lb_count_32());
  // if(g_fmc_timeout < 250)
  //  g_fmc_timeout = 250;           // Set the minimum timeout to 50 ms, to care of the device overhead

  //The speeds of cards vary. So the timeout value is being set to a big number 10 sec, following the 
  //other luns
  _fmc_set_timeout(10000);
  trace1(0, sd, 0, "Setting the timeout value to.. %04x", g_fmc_timeout);
  //Clear and unmask the CRC error interrupt
  irq_control(k_irq_fmc_sdc_crc_err, kbm_irqctl_clear |kbm_irqctl_unmask);
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result sd_read_write_end_xfer() reentrant
{
  t_result Result = 0;
  trace0(0, sd, 3, "sd_read_write_end_xfer");
  //Did we get here on a failure?
  if (k_success !=_fmc_get_result())
  {
    //did the media get removed
    if (!(_mcu_register_rd(x_crd_ps) & (kbm_crd_ps_sd |kbm_crd_ps_mmc)))
      return  _fmc_get_result();
    //Issue a get status to see if the device is alive and kicking ?
    sd_get_status();
    //Did a CRC Error occur? or  Did we exit on a sd_blk_ovrrun error Or the card is dead?
    if ((_mcu_register_rd(x_sdc_stat) & kbm_sdc_stat_crc_err) || (_mcu_register_rd(x_fmc_err) & kbm_fmc_err_sd_blk_ovrun)
        || (_sd_card_active == k_false))
    {
      if (_sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks)
      {
        _lun_data(sensep) = &sense_write_error;
      }
      else
      {
        //if the sd_blk_ovrrun error occurred there are atleast 2 blocks that were not received by the host
        //This has not been observed in 1.1 speeds as we hand fill the buffers
        if ((_mcu_register_rd(x_fmc_err) & kbm_fmc_err_sd_blk_ovrun) && sie_is_high_speed())
        {
          _mscbot_incr_residue(0x400);
        }
        _lun_data(sensep) = &sense_read_error;

      }
    }

  }
  //We are done with the data transfer... so issue the stop command
  //NB:- The SD spec says in  section 4.3.3 'Some cards may require long an unpredictable times to write a block of data"
  // So, how long should we wait? On trial and error basis I have set the timeout to 1 sec. We have good
  // reasons now why lesser values will not work.
  if (_sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks)
    sdc_wait_status_with_timeout(kbm_sdc_stat_crd_rdy,1000);

  //Only on 2.0 speeds and in writes in 210 , always issue stop on 223
  #ifndef k_mcu_97223
  if (sie_is_high_speed() || ( _sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks))
  #endif 
    sd_stop_transfer();

  // timer1 disabled during sd transfers to avoid data corruption issue.  bug report #343
  #if 0
  if (sie_is_high_speed())
  {
    //Turn on the timer interrupt
    irq_control(k_irq_cpu_t1,  kbm_irqctl_unmask);
    if (g_led_stays_on)           //restore to idle state
      gpio_setbit(0);
    else
      gpio_clrbit(0);
  }
  #endif

  return _fmc_get_result();
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
t_result sd_read_write_begin_split() reentrant
{
  trace0(0, sd, 3, "sd_read_write_begin_split");
#ifdef Debug_On
  gpio_bit_is_output(5);
  gpio_setbit(5);
#endif




  //did the media get removed
  if ((_sd_card_active == k_false)||(!(_mcu_register_rd(x_crd_ps) & (kbm_crd_ps_sd |kbm_crd_ps_mmc))))
    return k_error;
  //issue the cmd
  //check to see if the device is done with previous transfer
  if (!(x_sdc_stat & kbm_sdc_stat_crd_rdy))
    sdc_wait_status_with_timeout(kbm_sdc_stat_crd_rdy,1000);
  //we have some data to start with ... so do the prep
  trace1(0, tm, 0, "@%d Start wait state tran", g_cdm0);
  sd_get_status();
  while ((_sd_state != k_sdc_state_tran) && (_sd_card_active == k_true))
  {
    sd_get_status();
  }
  trace1(0, tm, 3, "@%d End wait state tran", g_cdm0);
  //did the media get removed
  if (_sd_card_active == k_false)
    return k_error;
  //Issue the Read/write  command  CMD18
  trace1(0, sd, 3, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  //if it is a write issue pre erase
  if ((_sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks) && (g_active_lun == k_lun_sd))
    sd_pre_erase();
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  if (g_active_lun == k_lun_sd)
    sdc_ctl |= (kbm_sdc_id_data | kbm_sdc_bus_type);
  else
    sdc_ctl |= (kbm_sdc_id_data);
  trace1(0, sd, 3, "The fmc_clk_ctl register %02x",x_fmc_clk_ctl);
  trace1(0, sd, 3, "The sdc_ctl register %02x",sdc_ctl);
  //sdc_wait_status_with_timeout(kbm_sdc_stat_crd_rdy,1000);
  if (!(x_sdc_stat & kbm_sdc_stat_cmd_rdy))
    sdc_wait_status_with_timeout(kbm_sdc_stat_cmd_rdy,1000);
  _sd_start_addr_this_xfer.u32 = _fmc_get_start_lb_32();
  trace2(0, sd, 3, "read/write addr:%04X%04X ", _hw(_sd_start_addr_this_xfer.u32), _lw(_sd_start_addr_this_xfer.u32));
  _sd_start_addr_this_xfer.u32 =  _sd_start_addr_this_xfer.u32 * (uint32) 512;
  trace2(0, sd, 3, "read/write addr:%04X%04X ", _hw(_sd_start_addr_this_xfer.u32), _lw(_sd_start_addr_this_xfer.u32));
  sdc_cmd_rsp_buf[0] = _sd_data_xfer_cmd;
  sdc_cmd_rsp_buf[1] = _sd_start_addr_this_xfer.u8.hi;
  sdc_cmd_rsp_buf[2] = _sd_start_addr_this_xfer.u8.lh;
  sdc_cmd_rsp_buf[3] = _sd_start_addr_this_xfer.u8.hl;
  sdc_cmd_rsp_buf[4] = _sd_start_addr_this_xfer.u8.lo;
  sd_display_rsp_buf();
  trace1(0, sd, 3, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  trace0(0, sd, 0, "I am HERE!!!");
  //Not calling the macro coz we have to wait a little longer for the response
  // _sd_wait_48b_resp();
  sdc_mode_ctl = 0;
  trace1(0, sd, 0, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_mode_ctl |= kbm_sdc_cmd_48b_rsp;
  trace1(0, sd, 0, "The sdc_mode_ctl register %02x",sdc_mode_ctl);
  sdc_wait_status_with_timeout(kbm_sdc_stat_rsp_rdy,2000);
  trace1(0, sd, 0, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  //did the media get removed
  if (_sd_card_active == k_false)
    return k_error;
  trace1(0, sd, 3, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  //clear this bit only for writes. Why does this happen? This is weird because according to spec this bit
  //should be at its default state "1", except for when the device is programming.
  //but we saw that during a read if we clear this bit it is stuck at zero??? so this workaround
  if (_sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks)
  {
    _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_crd_rdy);
  }
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_crc_err);
  _mcu_register_clr_bits(x_sdc_stat_msk,kbm_sdc_stat_crc_err);
  trace1(0, sd, 3, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  trace1(0, sd, 3, "The stat msk register %02x",x_sdc_stat_msk);
#ifdef Debug_On
  gpio_clrbit(5);
#endif
  return k_success;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
xdata t_udw32 _current_byte_count;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -