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

📄 sd.c

📁 u盘MCU端源代码,开发U盘的可以参考.
💻 C
📖 第 1 页 / 共 5 页
字号:
  {
    _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
  if(sie_is_high_speed())
  {
    // 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();
  } 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);
    }
  }
  //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.
  sdc_wait_status_with_timeout(kbm_sdc_stat_crd_rdy,1000);
  //Only on 2.0 speeds and in writes
  if(sie_is_high_speed() || ( _sd_data_xfer_cmd == k_sdc_cmd_write_mult_blocks))
    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);
  _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;
t_result sd_read_intra_burst() reentrant
{
  //get the buffer ready to receive data
  trace0(0, sd, 3, "sd_read_intra_burst");
  if (!sie_is_high_speed())
  {
  #ifdef k_dbg_on
    dbg_bufferstat();
  #endif
    _mcu_register_clr_bits(x_ep2_ctl, kbm_ep2_ctl_ramwr_tog | kbm_ep2_ctl_rdtog_valid);
    _mcu_register_set_bits(x_ep2_ctl, kbm_ep2_ctl_wrtog_valid);
    _mcu_register_wr(x_isr0, kbm_isr0_ramwr_a);
  #ifdef k_dbg_on
    dbg_bufferstat();
  #endif
  }
  else
  {
    //make a copy of this register for read retries
    _current_byte_count.u8.hi = _mcu_register_rd(x_fmc_cnt3);
    _current_byte_count.u8.lh = _mcu_register_rd(x_fmc_cnt2);
    _current_byte_count.u8.hl = _mcu_register_rd(x_fmc_cnt1);
    _current_byte_count.u8.lo = _mcu_register_rd(x_fmc_cnt0);
  }
  return sd_read_write_begin_split();
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
uint8 k;
uint8 xdata * data data_ptr;
uint8 xdata temp_buf[64];
t_result sd_read_end_burst() reentrant
{
  //allocate 64 bytes of xdata space for the temporary holder
  uint8  n, Result = 0;
  uint16 offset = 0;
  t_udw32 n_bytes;
  trace0(0, sd, 3, "sd_read_end_burst");
  g_cdm0 = 0;
  //Did a CRC Error occur?
  if (_mcu_register_rd(x_sdc_stat) & kbm_sdc_stat_crc_err)
  {
    trace0(0, sd, 0, "A CRC Error occurred");
    return k_error;
  }
  //Just for High speed
  if (sie_is_high_speed())

⌨️ 快捷键说明

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