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

📄 sd.c

📁 u盘MCU端源代码,开发U盘的可以参考.
💻 C
📖 第 1 页 / 共 5 页
字号:
t_result tbh_wait_status_with_timeout(uint8 mask, uint16 ticks) reentrant;
t_result tbh_wait_status_with_timeout(uint8 mask, uint16 ticks) reentrant
{
  uint8 status;
  t_sync sync;
  trace0(0, sd, 10, "tbh_wait_status_with_timeout()");
  // do this to get kbm_sync_abort delivered of there is traffic on the control pipe
  _isr_bind_dma_owner(g_tid, kbm_sync_none);
  thread_set_timer(ticks+1);
  do
  {
    _mcu_begin_critical_section();
    sync = _thread_got_sync(kbm_sync_abort |kbm_sync_usbrst |kbm_sync_timer);
    _mcu_end_critical_section();
    thread_clr_sync(sync);
    status = _sd_register_rd(x_sdc_stat);
    if(sync & kbm_sync_abort)
    {
      trace0(0, sd, 10, "tbh_wait_status_with_timeout() - error: kbm_sync_abort");
      // must delay some after this, but unknown how long, assume a few instruction cycles...
      _sd_register_wr(sdc_ctl, kbm_sdc_ctl_sdc_rst);
      return k_aborted;
    }
    if(sync & kbm_sync_usbrst)
    {
      trace0(0, sd, 10, "tbh_wait_status_with_timeout() - error: kbm_sync_usbrst");
      // must delay some after this, but unknown how long, assume a few instruction cycles...
      _sd_register_wr(sdc_ctl, kbm_sdc_ctl_sdc_rst);
      return k_usbreset;
    }
    if(sync & kbm_sync_timer)
    {
      trace0(0, sd, 10, "tbh_wait_status_with_timeout() - error: kbm_sync_timer");
      // must delay some after this, but unknown how long, assume a few instruction cycles...
      _sd_register_wr(sdc_ctl, kbm_sdc_ctl_sdc_rst);
      return k_timeout;
    }
  } while((status & mask) != mask);
  return k_success;
}

//------------------------------------------------------------------------------
// issuing CMD0 - go idle - is the same as power on reset
// power cycling the card is easier and faster
//------------------------------------------------------------------------------
void dfa_sd_reset() reentrant
{
  trace0(0, sd, 99, "sd_reset()");
  //Jump to this location on an "Emergency Exit" due to sync_abort or sync_usbreset
  if(setjmp(_sd_context))
  {
    trace0(0, sd, 99, "EMERGENCY EXIT!!");
    thread_return_dfa(k_error);
  }
  _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_200khz);
  _sd_register_set_bits(sdc_ctl, kbm_sdc_bus_type);
  g_sdc_rca_h = 0x00;
  g_sdc_rca_l = 0x00;
  _sd_write_protected = k_false;
  _sd_card_active = k_true;
  _sd_data_loaded = k_false;
  _sd_state = 0x00;
  _sd_pwr_on();
  // can afford a 2msec blocking loop here, hopefully
  thread_set_timer(2);
  while(!thread_got_sync(kbm_sync_timer));
  //Now issue the reset command as well
  trace1(0, sd, 1, "The sdc_ctl register %02x",sdc_ctl);
  trace1(0, sd, 1, "The crd_ps register %02x",_mcu_register_rd(x_crd_ps));
  sd_pre_cmd();
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  //fill the command buffer
  sdc_cmd_rsp_buf[0] = 0x40;
  sdc_cmd_rsp_buf[1] = 0x00;
  sdc_cmd_rsp_buf[2] = 0x00;
  sdc_cmd_rsp_buf[3] = 0x00;
  sdc_cmd_rsp_buf[4] = 0x00;
  sd_display_rsp_buf();
  //reset mode control register
  sdc_mode_ctl = 0;
  sdc_mode_ctl |= (kbm_sdc_cmd_no_rsp | kbm_sdc_rsp_crc_ds);  // Disable Crc 7
  thread_set_timer(1);
  while(!(thread_got_sync(kbm_sync_timer)));
  thread_clr_sync(kbm_sync_timer);
  thread_return_dfa(k_success);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void dfa_sd_initialize() reentrant
{
  t_result rslt;
  //Jump to this location on an "Emergency Exit" due to sync_abort or sync_usbreset
  trace0(0, sd, 99, "dfa_sd_initialize()");
  // assmume no media
  _lun_data_wr(k_lun_sd, media, (_lun_data_rd(k_lun_sd, media)&~(kbm_lun_media_present |kbm_lun_media_unknown |kbm_lun_media_changed)));
  _lun_data_wr(k_lun_mmc, media, (_lun_data_rd(k_lun_mmc, media)&~(kbm_lun_media_present |kbm_lun_media_unknown |kbm_lun_media_changed)));
  // clear the rsp buf byte 1 so we don't see remnant of previous operation
  sdc_cmd_rsp_buf[1] = 0;
  // monitor the card's busy bit - $$$need a symbol instead of a hex constant...
  while(!(sdc_cmd_rsp_buf[1] & 0x80))
  {
    trace1(0, sd, 0, "top of while loop, _sd_card_active:%d", _sd_card_active);
    // probe for SD card.  if not found probe for MMC card.
    if(k_lun_sd == g_active_lun)
    {
      _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
      _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_crc_err);
      _sd_register_clr_bits(sdc_ctl, kbm_sdc_id_data);
      if(k_success != tbh_wait_status_with_timeout(kbm_sdc_stat_crd_rdy, 5))
        goto SWITCH_TO_MMC;
      if(k_success != tbh_wait_status_with_timeout(kbm_sdc_stat_cmd_rdy, 5))
        goto SWITCH_TO_MMC;
      sdc_cmd_rsp_buf[0] = 0x77;
      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;
      sdc_mode_ctl = 0;
      sdc_mode_ctl |= kbm_sdc_cmd_48b_rsp;
      rslt = tbh_wait_status_with_timeout(kbm_sdc_stat_rsp_rdy, 5);
      sdc_read_rsp(5);
      if(k_timeout == rslt)
      {
        SWITCH_TO_MMC:
        trace0(0, sd, 0, "try mmc...");
        _lun_map_log2phy(k_log_lun_sd, k_lun_mmc);
        //g_active_lun = k_lun_mmc;
        lun_set_active(k_lun_mmc);
        _sd_card_active = k_true;
      } else
        if(k_success != rslt)
        goto EXIT_NO_MEDIA;
    }
    // issue ACMD41
    trace0(0, sd, 1, "Issuing ACMD41");
    _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
    _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_crc_err);
    _sd_register_clr_bits(sdc_ctl, kbm_sdc_id_data);
    if(k_success != tbh_wait_status_with_timeout(kbm_sdc_stat_crd_rdy, 5))
      goto EXIT_NO_MEDIA;
    if(k_success != tbh_wait_status_with_timeout(kbm_sdc_stat_cmd_rdy, 5))
      goto EXIT_NO_MEDIA;
    if(k_lun_mmc == g_active_lun)
      sdc_cmd_rsp_buf[0] = 0x41;
    else
      sdc_cmd_rsp_buf[0] = 0x69;
    sdc_cmd_rsp_buf[1] = 0x80;    // Voltage range 2.0 - 2.1
    sdc_cmd_rsp_buf[2] = 0xFF;
    sdc_cmd_rsp_buf[3] = 0x80;
    sdc_cmd_rsp_buf[4] = 0x00;
    sd_display_rsp_buf();
    sdc_mode_ctl = 0;
    sdc_mode_ctl |= (kbm_sdc_cmd_48b_rsp | kbm_sdc_rsp_crc_ds);
    if(k_success != tbh_wait_status_with_timeout(kbm_sdc_stat_rsp_rdy, 5))
      goto EXIT_NO_MEDIA;
    sdc_read_rsp(5);
    _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  }
  // was there a card in the slot?  if so g_active_lun is set to the correct phy lun index.
  if(_sd_card_active)
  {
    // found a card
    // clear the media changed flag so the framework will move on and establish the geometry
    _lun_data(media)  |= (kbm_lun_media_present |kbm_lun_media_unknown);
    // need to set sense code here to get it reported (different from other luns)
    _lun_data(sensep) = &sense_media_change;
    switch(g_active_lun)
    {
    case k_lun_sd:
      trace0(0, sd, 99, "media is SD");
      _mcu_register_set_bits(x_crd_ps, kbm_crd_ps_sd);
      break;
    case k_lun_mmc:
      trace0(0, sd, 99, "media is MMC");
      _mcu_register_set_bits(x_crd_ps, kbm_crd_ps_mmc);
      break;
    }
  }
  irq_control(k_irq_sd_insert_eject, kbm_irqctl_clear |kbm_irqctl_unmask);
  trace0(0, sd, 99, "media");
#ifdef k_pfm_led
  _mcu_register_set_bits(x_gpiob_out,  kbm_gpio15);  //on
#endif
  thread_return_dfa(k_success);
  EXIT_NO_MEDIA:
  trace0(0, sd, 99, "no media");
  _sd_pwr_off();
  _lun_map_log2phy(k_log_lun_sd, k_lun_sd);
  irq_control(k_irq_sd_insert_eject, kbm_irqctl_clear |kbm_irqctl_unmask);
#ifdef k_pfm_led
  _mcu_register_clr_bits(x_gpiob_out,  kbm_gpio15);  //off
#endif
  thread_return_dfa(k_success);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void dfa_sd_identify_device() reentrant
{
  uint8 i =0;
  //local variables for calculating the size
  uint8 read_bl_len, c_size_mult;
  uint16 c_size, block_len, mult;
  uint32 blocknr;
  uint8 Result = 0;
  //Jump to this location on an "Emergency Exit" due to sync_abort or sync_usbreset
  if(setjmp(_sd_context))
  {
    trace0(0, sd, 0, "EMERGENCY EXIT!!");
    thread_return_dfa(k_error);
  }
  trace0(0, sd, 1, "+sd_identify_device()");
  //This will det the identification data from the sd device
  trace1(0, sd, 1, "The sdc_ctl register %02x",sdc_ctl);
  sd_pre_cmd();
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_cmd_rsp_buf[0] = 0x42;
  sdc_cmd_rsp_buf[1] = 0x00;
  sdc_cmd_rsp_buf[2] = 0x00;
  sdc_cmd_rsp_buf[3] = 0x00;
  sdc_cmd_rsp_buf[4] = 0x00;
  sdc_cmd_rsp_buf[5] = 0x00;
  //sd_display_rsp_buf();
  //reset mode control register
  sdc_mode_ctl = 0;
  //ready to receive the response
  sdc_mode_ctl |= (kbm_sdc_cmd_136b_rsp );
  trace1(0, sd, 1, "The sdc_mode_ctl register %02x",sdc_mode_ctl);
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_wait_status_with_timeout(kbm_sdc_stat_rsp_rdy,300);
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_read_rsp(17);
  //sd_display_rsp_buf();
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  //Issue CMD3 Or GetRCA
  trace1(0, sd, 1, "The sdc_ctl register %02x",sdc_ctl);
  sd_pre_cmd();
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  //If the device is mmc then we need to preset the rca
  if(g_active_lun == k_lun_mmc)
  {
    g_sdc_rca_h = 0x01;
    g_sdc_rca_l = 0x02;
  }
  sdc_cmd_rsp_buf[0] = 0x43;
  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;
  sdc_cmd_rsp_buf[5] = 0x00;
  //sd_display_rsp_buf();
  _sd_wait_48b_resp();
  if(g_active_lun == k_lun_sd)
  {
    g_sdc_rca_h = sdc_cmd_rsp_buf[1];
    g_sdc_rca_l = sdc_cmd_rsp_buf[2];
  }
  //sd_display_rsp_buf();
  sdc_read_rsp(5);
  _mcu_register_wr(x_sdc_stat, kbm_sdc_stat_rsp_rdy);
  //sd_get_status();
  //sdc_read_rsp(17);
  //SEND_CSD or CMD9
  trace0(0, sd, 1, "Issue SEND_CSD");
  sd_pre_cmd();
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_cmd_rsp_buf[0] = 0x49;
  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;
  sdc_cmd_rsp_buf[5] = 0x00;
  //reset mode control register
  sdc_mode_ctl = 0;
  //ready to receive the response
  sdc_mode_ctl |= (kbm_sdc_cmd_136b_rsp);
  trace1(0, sd, 1, "The sdc_mode_ctl register %02x",sdc_mode_ctl);
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sdc_wait_status_with_timeout(kbm_sdc_stat_rsp_rdy,300);
  trace1(0, sd, 1, "The stat register %02x",_mcu_register_rd(x_sdc_stat));
  sd_display_rsp_buf();
  //Calculate LBA max
  read_bl_len = (sdc_cmd_rsp_buf[6] & 0x0f);
  c_size = (sdc_cmd_rsp_buf[7] & 0x03);
  c_size = (c_size << 10);
  c_size += ((uint16)sdc_cmd_rsp_buf[8] << 2);
  c_size += ((sdc_cmd_rsp_buf[9] & 0xc0) >> 6);
  c_size &= 0x0fff;
  c_size_mult = (sdc_cmd_rsp_buf[10] & 0x03);
  c_size_mult = (c_size_mult << 1);
  c_size_mult += ((sdc_cmd_rsp_buf[11] & 0x80) >> 7);
  trace3(0, sd, 1, " The read_bl_len is %d , c_size is %04x, c_size_mult : %d ", read_bl_len,c_size,c_size_mult);
  block_len = (1 << read_bl_len);
  mult = (1 << (c_size_mult + 2));
  trace2(0, sd, 1, " Block_len is %d, mult = %d",block_len, mult);
  blocknr = (((uint32)c_size + (uint32)1) * (uint32)mult);
  trace2(0, sd, 1, "the blocknr is %04x%04x", _hw(blocknr),_lw(blocknr));
  blocknr = blocknr - (uint32) 1;
  trace2(0, sd, 1, "the blocknr is %04x%04x", _hw(blocknr),_lw(blocknr));
  _lun_data(capacity).lba_max.u32 = blocknr;
  _lun_data(capacity).lba_sz.u32 = block_len;
  trace2(0, sd, 1, "Total User-addressable Sectors: %04X%04X", _hw(_lun_data(capacity).lba_max.u32), _lw(_lun_data(capacity).lba_max.u32));
  //Is the media write protected?
  //Check for hardware write protection...
  if(_mcu_register_rd(x_media_sts) & 0x01)
    _sd_write_protected = k_true;
  //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

⌨️ 快捷键说明

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