Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm32f10x, FatFs + SDIO + SD card + USB
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
spectral1989
Здравствуйте! Имеется в наличии отладочная плата от терра электроники на stm32f103, пробую запустить SDIO + SD card + USB. Cкачал с сайта СТ либу usb mass storage device на stm32f10x, поправил под свою плату, запустил, но все работает не совсем так, как хотелось бы. Инициализация карты проходит. В системе появляется съемный диск, размер 0 байт, файловая система RAW, хотя я ее форматировал через FatFs в fat32, размер сектора = 512. При попытке открыть предлагает отформатировать, нажимаю да - появляется окошко, там указан размер карты 3,75гб, стало быть до карты проц достучаться может. Пробую форматировать - вылезает ошибка, не удается завершить форматирование. В чем может быть проблема?

Пробовал уменьшать частоту тактирования карты: увеличил делитель с 1 до 0хА - не помогает.

И еще вопрос, я скачал библиотеку FatFs и прикрутил к ней низкоуровневые функции stm32f10x - заработало, читает и пишет, создает файлы и форматирует. Теперь, чтобы при соединении через USB с компьютером я мог работать на нем с SD картой мне нужно сделать примерно так:

SD карта -> интерфейс обмена данными(SDIO в моем случае) -> драйвер файловой системы(FatFs в моем случае) -> драйвер USB mass storage device -> ПК
я правильно понимаю ситуацию?
Alexashka
проверьте питание на карте памяти -должно быть 3.3В.
драйвер USB MSD работает с картой напрямую, безо всяких файловых систем.
Еще у них там в проекте 2 штуки LUN, второй если не ошибаюсь -внешняя флешь память, которой нет на вашей плате. Вроде все заработало, когда вычистил все ссылки на эту память, сделал один LUN и подал питание на карточку (там транзистор по питанию не открывался)
spectral1989
С транзистором я разобрался еще когда FatFs ковырял. Ок, попробую почистить LUN. Спасибо!
spectral1989
Проверил на всякий случай питание, все ок! 3,3В Сделал один LUN, почистил ссылки, теперь появляется только один съемный диск. Но он по прежнему не доступен для работыsad.gif

вот кстати еще такая деталь: карта почему-то не инициализируется на значении SDIO_INIT_CLK_DIV = 0xB2, виснет на функции CmdResp3Error, а конкретно тут:
Код
  while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)))
  {
    status = SDIO->STA;
  }

если увеличить делитель SDIO_INIT_CLK_DIV до 0xF2 - инициализация проходит. хотя в соседнем проекте с FatFs на значении по умолчанию не возникает никаких проблем. Файл с низкоуровневыми функциями(инициализация, чтение) один и тот же.

проект Keil
http://disk.tom.ru/h7r3l2k

карта 4гб

нашел спорный момент. почему-то в функции MAL_GetStatus в файле mass_mal.c каждый раз вызывалась инициализация карты. зачем? поправил ее так:
Код
uint16_t MAL_GetStatus (uint8_t lun)
{
  uint32_t DeviceSizeMul = 0,NumberOfBlocks = 0;;

  if (lun == 0)
  {
    SD_GetCardInfo(&mSDCardInfo);
    DeviceSizeMul = (mSDCardInfo.SD_csd.DeviceSizeMul + 2);

    if(mSDCardInfo.CardType == SDIO_HIGH_CAPACITY_SD_CARD)
    {
      Mass_Block_Count[0] = (mSDCardInfo.SD_csd.DeviceSize + 1) * 1024;
    }
    else
    {
      NumberOfBlocks  = ((1 << (mSDCardInfo.SD_csd.RdBlockLen)) / 512);
      Mass_Block_Count[0] = ((mSDCardInfo.SD_csd.DeviceSize + 1) * (1 << DeviceSizeMul) << (NumberOfBlocks/2));
    }
    Mass_Block_Size[0]  = 512;
    
    Mass_Memory_Size[0] = Mass_Block_Count[0] * Mass_Block_Size[0];
//  STM_EVAL_LEDOn(LED2);
    return MAL_OK;
  }
//  STM_EVAL_LEDOn(LED2);
  return MAL_FAIL;
}

но легче не стало


скачал WinHex. Он определяет, что файловая система Fat32, но стартовый сектор почему-то уехал на 1 сектор. Из-за чего это может быть? Скрин прилагается:
http://disk.tom.ru/fkzggq1
Alexashka
Цитата(spectral1989 @ Sep 6 2012, 07:57) *
вот кстати еще такая деталь: карта почему-то не инициализируется на значении SDIO_INIT_CLK_DIV = 0xB2, виснет на функции CmdResp3Error, а конкретно тут:
Код
  while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)))
  {
    status = SDIO->STA;
  }

если увеличить делитель SDIO_INIT_CLK_DIV до 0xF2 - инициализация проходит. хотя в соседнем проекте с FatFs на значении по умолчанию не возникает никаких проблем. Файл с низкоуровневыми функциями(инициализация, чтение) один и тот же.

А изза какого флага виснет?

Кстати вспомнил, я еще увеличивал SD_DATATIMEOUT до 0x007FFFFF (в файле stm32_eval_sdio_sd.c) правда это вроде проявилось только при мультиблоковой записи, но все равно. А какая ревизия платы? Зеленая, красная? снизу платы напаяны резисторы подтяжки SDIO?


spectral1989
флаг CMDREND - command responce recieved(CRC check passed) не появляется, FLAG_CTIMEOUT почему-то тоже. на момент, когда останавливаешь выполнение программы status = 0x800 - CMDACT command transfer in progress. причем такой нюанс, запускаешь в отладчике на автовыполнение - он виснет на этом условии, но если остановить и вручную прошагать условие - программа выполняется дальше, пока опять до этого места не дойдет.

Покупал недавно, плата красная, на обратной стороне три резистора под разъемом microSD, не знаю подтяжки это или нет.

мультиблоковую запись не трогал пока, POLLING mode стоит. без дма даже. а не могли бы вы выложить свой проект?

понаставил брэйкпоинтов в низкоуровневой функции чтения внутри условий проверки на ошибки и нашел еще косяк: флаг SD_RX_OVERRUN появляется, когда комп к карте обращается.
spectral1989
включил hardware flow control и заработалоsm.gif ПК думал около минуты перед тем, как определить флешку, видимо контроллер захлебывался от количества запросов. буду пробовать мультиблочную запись/чтение!

спасибо за помощь!
Alexashka
Цитата(spectral1989 @ Sep 6 2012, 14:26) *
включил hardware flow control и заработало sm.gif ПК думал около минуты перед тем, как определить флешку, видимо контроллер захлебывался от количества запросов. буду пробовать мультиблочную запись/чтение!

спасибо за помощь!

если флешка чистая то открывается через 3-4сек. Вообще я проект правил по минимуму, стараясь не трогать то что не знаю. Проект у меня иаровский, для STM3210-EVAL, могу скинуть если еще актуально)

Мультиблок в массстораже? Расскажите потом какая скорость получилась. Я так и не придумал как сделать мультиблок в нем, слишком там сложно все закручено.

ЗЫ. Да незачто, Вы все сами сделали)
spectral1989
3-4с время открытия? а какого объема карту подключаете?
spectral1989
Заметил такой глюк: беру архив около 100мб, копирую на SD карту, проверяю контрольные суммы - сходится. Копирую архив с карты на ПК, проверяю контрольные суммы - опять сходится. Делаю безопасное извлечение, вытаскиваю шнур USB, вставляю - карта определяется корректно(правильный размер, есть файл, который я создал с помощью FatFs), но этого архива нет. В чем проблема может быть?

Alexashka, пожалуйста скиньте все таки свой проектsm.gif

з.ы. мультиблок с ходу не заработал, я его пока отложил
Alexashka
Цитата(spectral1989 @ Sep 7 2012, 11:30) *
Заметил такой глюк: беру архив около 100мб, копирую на SD карту, проверяю контрольные суммы - сходится. Копирую архив с карты на ПК, проверяю контрольные суммы - опять сходится. Делаю безопасное извлечение, вытаскиваю шнур USB, вставляю - карта определяется корректно(правильный размер, есть файл, который я создал с помощью FatFs), но этого архива нет. В чем проблема может быть?

Alexashka, пожалуйста скиньте все таки свой проектsm.gif

з.ы. мультиблок с ходу не заработал, я его пока отложил

Хм...интересный эффект, как будто данные о созданном файле были занесены в кэш но не прописались в ФАТ таблицу на диске. Попробуйте проделать тоже самое с картой вставив ее в какойнить картридер -может карта глючная. У меня есть карточка (недавно купленная) с которой я не могу удалить файлы, и не могу отформатировать ее. Т.е файлы удаляются, потом вытащишь-вставишь -а они тут как тут, все на месте biggrin.gif
Я писал много раз уже, но мелкие файлы, пропадания не замечено. Надо будет попробовать записать большой. Карты у меня на 1,2,4,8 ГБ. Проблем не было никаких. Которая за 4 сек открывается это 4ГБ, класс 10, Трансценд вроде бы.
Сейчас ничего не могу скинуть, проект на работе, так что -до понедельника sm.gif
Есть еще на 2Гб, помню она дольше открывается и пишется, раза в 2 точно если не в 3. Заметил еще такую вещь -если на карте есть мультимедийные файлы то открывание диска затягивается на очень длительное время...

ЗЫ. Кстати, а сколько у Вас пишется по времени 100МБ?
Allregia
Цитата(Alexashka @ Sep 7 2012, 19:05) *
Есть еще на 2Гб, помню она дольше открывается и пишется, раза в 2 точно если не в 3.


Попробуте форматнуть ее прямо в устройстве, командой f_mkfs - у меня это увеличило скорость записи почти на порядок!
Правда немного другой процессор.
Обсуждалось тут: http://electronix.ru/forum/index.php?showtopic=105763
spectral1989
купил несколько новых карт: 2, 4, 8гб разного класса. теперь все определяются быстро, но глюк, когда записываешь что-нибудь на флешку с ПК, вытаскиваешь-вставляешь - файлы пропадают остался. в чем может быть проблема?
spectral1989
собрал заново проект, все заработало. видимо накосячил где-то, когда второй ЛУН убирал. спасибо всем помогавшим и сочувствующимsm.gif
Alexashka
Цитата(Allregia @ Sep 9 2012, 01:17) *
Попробуте форматнуть ее прямо в устройстве, командой f_mkfs - у меня это увеличило скорость записи почти на порядок!
Правда немного другой процессор.
Обсуждалось тут: http://electronix.ru/forum/index.php?showtopic=105763

Похоже у Вас не работает как положено мультиблоковая запись. Если используете драйвер SDIO от ST, то гляньте там между записью блоков в команде CMD25 имеется задержка, у меня тоже скорость была очень низкая, пока я эту задержку не покоцал. Там зачемто сделано ожидание перед опросом состояния записи -возможно чтобы не прерывать процессы в контроллере карты. Вообщем я ее уменьшил в несколько раз и скорость записи теперь достаточно стабильна и пропорциональна только классу карты
Allregia
Цитата(Alexashka @ Sep 10 2012, 18:43) *
Похоже у Вас не работает как положено мультиблоковая запись. Если используете драйвер SDIO от ST,


Да, его.

Цитата
то гляньте там между записью блоков в команде CMD25 имеется задержка, у меня тоже скорость была очень низкая, пока я эту задержку не покоцал. Там зачемто сделано ожидание перед опросом состояния записи -возможно чтобы не прерывать процессы в контроллере карты. Вообщем я ее уменьшил в несколько раз и скорость записи теперь достаточно стабильна и пропорциональна только классу карты


Не пойму где именно надо покоцать.
Вот процедура блочной записи:
Код
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{
  SD_Error errorstatus = SD_OK;

  TransferError = SD_OK;
  TransferEnd = 0;
  StopCondition = 1;
  
  SDIO->DCTRL = 0x0;

  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    WriteAddr /= 512;
  }

  SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
  SDIO_DMACmd(ENABLE);
  SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, (NumberOfBlocks * BlockSize));
  
  /* Set Block Size for Card */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);

  if (SD_OK != errorstatus)
  {
    return(errorstatus);
  }
  
  /*!< To improve performance */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) (RCA << 16);
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);


  errorstatus = CmdResp1Error(SD_CMD_APP_CMD);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }
  /*!< To improve performance */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)NumberOfBlocks;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCK_COUNT;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }


  /*!< Send CMD25 WRITE_MULT_BLOCK with argument data address */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)WriteAddr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK);

  if (SD_OK != errorstatus)
  {
    return(errorstatus);
  }

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);

  return(errorstatus);
}
Alexashka
Цитата(Allregia @ Sep 11 2012, 12:08) *
Да, его.
Не пойму где именно надо покоцать.
Вот процедура блочной записи:


Хм..странно, в Вашей версии практически никакие проверки не делаются. У меня наверно постарей чутка версия:


Код
  * @file    stm32_eval_sdio_sd.c
  * @author  MCD Application Team
  * @version V4.4.0
  * @date    31-December-2010


Код
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{
  SD_Error errorstatus = SD_OK;
  uint8_t  power = 0, cardstate = 0;
  uint32_t bytestransferred = 0;
  uint32_t restwords = 0;
  uint32_t *tempbuff = (uint32_t *)writebuff;
  __IO uint32_t count = 0;
  
  if (writebuff == NULL)
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  TransferError = SD_OK;
  TransferEnd = 0;
  TotalNumberOfBytes = 0;

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = 0;
  SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable;
  SDIO_DataConfig(&SDIO_DataInitStructure);
  SDIO_DMACmd(DISABLE);

  if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
  {
    errorstatus = SD_LOCK_UNLOCK_FAILED;
    return(errorstatus);
  }

  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    WriteAddr /= 512;
  }
  
  /*!< Set the block size, both on controller and card */
  if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
  {
    power = convert_from_bytes_to_power_of_two(BlockSize);

    SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);

    if (errorstatus != SD_OK)
    {
      return(errorstatus);
    }
  }
  else
  {
    errorstatus = SD_INVALID_PARAMETER;
    return(errorstatus);
  }

  /*!< Wait till card is ready for data Added */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) (RCA << 16);
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_SEND_STATUS);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }

  if (NumberOfBlocks > 1)
  {
    /*!< Common to all modes */
    if (NumberOfBlocks * BlockSize > SD_MAX_DATA_LENGTH)
    {
      errorstatus = SD_INVALID_PARAMETER;
      return(errorstatus);
    }

    if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
    {
      /*!< To improve performance */
      SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) (RCA << 16);
      SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
      SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
      SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
      SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
      SDIO_SendCommand(&SDIO_CmdInitStructure);


      errorstatus = CmdResp1Error(SD_CMD_APP_CMD);

      if (errorstatus != SD_OK)
      {
        return(errorstatus);
      }
      /*!< To improve performance */
      SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)NumberOfBlocks;
      SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCK_COUNT;
      SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
      SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
      SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
      SDIO_SendCommand(&SDIO_CmdInitStructure);

      errorstatus = CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);

      if (errorstatus != SD_OK)
      {
        return(errorstatus);
      }
    }

    /*!< Send CMD25 WRITE_MULT_BLOCK with argument data address */
    SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)WriteAddr;
    SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_MULT_BLOCK;
    SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
    SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
    SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
    SDIO_SendCommand(&SDIO_CmdInitStructure);

    errorstatus = CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK);

    if (SD_OK != errorstatus)
    {
      return(errorstatus);
    }

    TotalNumberOfBytes = NumberOfBlocks * BlockSize;
    StopCondition = 1;
    SrcBuffer = (uint32_t *)writebuff;

    SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
    SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
    SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) power << 4;
    SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
    SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
    SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
    SDIO_DataConfig(&SDIO_DataInitStructure);

    if (DeviceMode == SD_POLLING_MODE)
    {
      while (!(SDIO->STA & (SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DATAEND | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
      {
        if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
        {
          if (!((TotalNumberOfBytes - bytestransferred) < SD_HALFFIFOBYTES))
          {
            for (count = 0; count < SD_HALFFIFO; count++)
            {
              SDIO_WriteData(*(tempbuff + count));
            }
            tempbuff += SD_HALFFIFO;
            bytestransferred += SD_HALFFIFOBYTES;
          }
          else
          {
            restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) :
                        ((TotalNumberOfBytes - bytestransferred) / 4 + 1);

            for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
            {
              SDIO_WriteData(*tempbuff);
            }
          }
        }
      }

      if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
      {
        SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
        errorstatus = SD_DATA_TIMEOUT;
        return(errorstatus);
      }
      else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
      {
        SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
        errorstatus = SD_DATA_CRC_FAIL;
        return(errorstatus);
      }
      else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)
      {
        SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
        errorstatus = SD_TX_UNDERRUN;
        return(errorstatus);
      }
      else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
      {
        SDIO_ClearFlag(SDIO_FLAG_STBITERR);
        errorstatus = SD_START_BIT_ERR;
        return(errorstatus);
      }

      if (SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)
      {
       if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
        {
          /*!< Send CMD12 STOP_TRANSMISSION */
          SDIO_CmdInitStructure.SDIO_Argument = 0x0;
          SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_STOP_TRANSMISSION;
          SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
          SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
          SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
          SDIO_SendCommand(&SDIO_CmdInitStructure);


          errorstatus = CmdResp1Error(SD_CMD_STOP_TRANSMISSION);

          if (errorstatus != SD_OK)
          {
            return(errorstatus);
          }
        }
      }
    }
    else if (DeviceMode == SD_INTERRUPT_MODE)
    {
      SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXFIFOHE | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
      while ((TransferEnd == 0) && (TransferError == SD_OK))
      {}
      if (TransferError != SD_OK)
      {
        return(TransferError);
      }
    }
    else if (DeviceMode == SD_DMA_MODE)
    {
      SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
      SDIO_DMACmd(ENABLE);
      SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, (NumberOfBlocks * BlockSize));

      while ((SD_DMAEndOfTransferStatus() == RESET) && (TransferEnd == 0) && (TransferError == SD_OK))
      {}
      if (TransferError != SD_OK)
      {
        return(TransferError);
      }
    }
  }
  /*!< Clear all the static flags */
  SDIO_ClearFlag(SDIO_STATIC_FLAGS);
  
  /*!< Add some delay before checking the Card Status */
  for(count = 0; count < 0x1FF; count++)
  {
  }
  /*!< Wait till the card is in programming state */
  errorstatus = IsCardProgramming(&cardstate);

  while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
  {
    errorstatus = IsCardProgramming(&cardstate);
  }

  return(errorstatus);
}


Вот тут почти в самом конце имеется задержка...

Allregia
Цитата(Alexashka @ Sep 12 2012, 06:42) *
Хм..странно, в Вашей версии практически никакие проверки не делаются. У меня наверно постарей чутка версия:


Код
  * @file    stm32_eval_sdio_sd.c
   * @author  MCD Application Team
   * @version V4.4.0
   * @date    31-December-2010


Вы видимо не заметили - у меня и процессор чуть другой (F4 а не F1)

Код
  * @file    stm324xg_eval_sdio_sd.c
  * @author  MCD Application Team
  * @version V1.0.2
  * @date    09-March-2012
Alexashka
Цитата(Allregia @ Sep 12 2012, 11:46) *
Вы видимо не заметили - у меня и процессор чуть другой (F4 а не F1)

Задержка насколько я понимаю касается алгоритма работы с SD картой, а не конкретного процессора.
Allregia
Цитата(Alexashka @ Sep 12 2012, 09:59) *
Задержка насколько я понимаю касается алгоритма работы с SD картой, а не конкретного процессора.


Так у него же и библиотеки другие.
Alexashka
Кстати, а ктонибудь пробовал функцию удаления файла из Чановской FatFs? У меня она почемуто зависает напрочь
spectral1989
Итак, собрал проект на stm32f103 в котором есть USB mass storage, SD карта на 2гб и файловая система Chan'a FatFs. Все это работает через SDIO в поблочном режиме через DMA. Идея такая: ПК определяет флешку как mass storage device и если нужно скачивает с нее файлы логов работы устройств, подключенных к контроллеру по сети CAN(CAN не подключал пока к этому проекту, на stm32f103 can+usb вместе не работают). На контроллере стоит FatFs и заполняет эти самые файлы логов.

По отдельности FatFs и USB mass storage работают нормально. Файлы пишутся/читаются/создаются, ПК определяет SD карту как флешку. Пробую объединить в один проект USB и FatFs и при попытке дописать что-нибудь в файл на SD карте контроллер вылетает в Hard Fault. Может тут есть какие-нибудь нюансы? Такую модель вообще можно реализовать?

Цитата(Alexashka @ Sep 13 2012, 12:59) *
Кстати, а ктонибудь пробовал функцию удаления файла из Чановской FatFs? У меня она почемуто зависает напрочь

у меня отлично работает. FatFs 9a, поблочная запись/чтение через DMA
Allregia
Цитата(Alexashka @ Sep 13 2012, 10:59) *
Кстати, а ктонибудь пробовал функцию удаления файла из Чановской FatFs? У меня она почемуто зависает напрочь


Удаление отлично работает, проблем не видел.
Вот где наткнулся - на форматировании, если форматировать подряд несколько разных флешек, на какой-то подвисает DMA.
Столкнулся только на днях, и пока не придумал в чем дело.
Alexashka
Цитата(spectral1989 @ Sep 14 2012, 07:42) *
По отдельности FatFs и USB mass storage работают нормально. Файлы пишутся/читаются/создаются, ПК определяет SD карту как флешку. Пробую объединить в один проект USB и FatFs и при попытке дописать что-нибудь в файл на SD карте контроллер вылетает в Hard Fault. Может тут есть какие-нибудь нюансы? Такую модель вообще можно реализовать?

у меня usb и fatfs в одном проекте работают, только mass storage инициализируется после закрытия диска на fatfs. У Вас не так? Там запросы от USB разбираются в прерывании, так что в тот момент когда Вы пишете в файл вполне может произойти обращение к карте через эти же функции в прерывании. Надо запрещать прерывания на время пока пишете в файл. Видимо так.
spectral1989
Цитата(Alexashka @ Sep 16 2012, 21:33) *
у меня usb и fatfs в одном проекте работают, только mass storage инициализируется после закрытия диска на fatfs. У Вас не так? Там запросы от USB разбираются в прерывании, так что в тот момент когда Вы пишете в файл вполне может произойти обращение к карте через эти же функции в прерывании. Надо запрещать прерывания на время пока пишете в файл. Видимо так.

У меня наоборот, сначала инициализируется mass storage, потом только монтируется fatfs. как мне выгрузить mass storage? перепробовал разные варианты, сейчас делаю так:
Код
    Bot_Abort(BOTH_DIR);
    Suspend();
    PowerOff();    
        GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);
    NVIC->ICER[0] |= (1 << (USB_HP_CAN1_TX_IRQn  & 0x1F));
    NVIC->ICER[0] |= (1 << (USB_LP_CAN1_RX0_IRQn  & 0x1F));

при попытке записать что-нибудь в файл с помощью fatfs все равно вылетаю в hard fault
Alexashka
Цитата(spectral1989 @ Sep 17 2012, 08:51) *
У меня наоборот, сначала инициализируется mass storage, потом только монтируется fatfs. как мне выгрузить mass storage?
при попытке записать что-нибудь в файл с помощью fatfs все равно вылетаю в hard fault

Че гадать -посмотрите в стеке какая последняя функция вызвала аборт.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.