Портал для радиолюбителей и разработчиков электроники · с 2003 годаРеклама на сайте
Найти компонент, схему или даташит

Даташиты, справочник отечественных приборов, схемы с разбором и живой форум


 
Опции темы

STM32+SDIO SDSC не работает

Непрочитано 22.02.2023, 13:29  
djoni
Частый гость
 
Регистрация: 15.09.2022
Сообщений: 44
Сказал спасибо: 16
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
djoni на пути к лучшему
По умолчанию STM32+SDIO SDSC не работает

Перекопал весь инет, но так и не нашел в какую сторону смотреть. Суть проблемы в том, что карта SDSC 2 гига не работает, а карты от 8 гигов до 64 работают без проблем. Частота обмена с картой 4Мб (пока на проводах, больше скорость не поднять).
Сам интерфейс работает в POLLING режиме (ДМА пока без надобности).
Инициализация всех карт проходит на ура. А вот чтение 0 блока SDSC проваливает. Самое грустное, что в отладке не совсем ясна причина, в зависимости как быстро шагаешь или вылетаешь по флагу RXOVERR или в цикле чтения зависаешь, потому как флаги не взлетают
Код:
SD_Error SD_ReadBlockS(uint8_t *readbuff, uint32_t ReadAddr, uint32_t NumberOfBlocks, uint16_t BlockSize){
  TransferError = SD_OK;
  TransferEnd = 0;
  StopCondition = 0;	
	SD_Error errorstatus = SD_OK;
 // uint32_t errorstate; 
  uint32_t count, data, dataremaining;
  uint32_t add = ReadAddr;
  uint8_t *tempbuff = readbuff;

  if(NULL == readbuff)
  {
        return SD_INVALID_PARAMETER;
  }
    TransferError = SD_OK;
    if((add + NumberOfBlocks) › (SDCardInfo.LogBlockNbr))
    {
      errorstatus = SD_ADDR_MISALIGNED;
      return SD_REQUEST_NOT_APPLICABLE;
    }
    /* Initialize data control register */
    SDMMC1-›DCTRL = 0U;

    if(SDCardInfo.CardType != CARD_SDHC_SDXC)
    {
      add *= 512U;
    }

    /* Configure the SD DPSM (Data Path State Machine) */
  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BLOCKSIZE;
  SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_512b;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);
		
    /* Read block(s) in polling mode */
    if(NumberOfBlocks › 1U)
    {
      SDCardInfo.Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;
				
      /* Read Multi Block command */
      errorstatus = SDMMC_CmdReadMultiBlock(add);
    }
    else
    {
      SDCardInfo.Context = SD_CONTEXT_READ_SINGLE_BLOCK;

      /* Read Single Block command */
      errorstatus = SDMMC_CmdReadSingleBlock(add);
    }
    if(errorstatus != SD_OK)
    {
      /* Clear all the static flags */
      __SDMMC_CLEAR_FLAG(SDMMC_STATIC_FLAGS);
      SDCardInfo.Context = SD_CONTEXT_NONE;
      return SD_ERROR;
    }	

    /* Poll on SDMMC flags */
    dataremaining = SDIO_DataInitStructure.SDIO_DataLength; //config.DataLength;
    while(!(SDMMC1-›STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)))
    {
      if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) && (dataremaining › 0U)) 
      {
        /* Read data from SDMMC Rx FIFO */
        for(count = 0U; count ‹ 8U; count++)
        {
          data = SDMMC1-›FIFO;
          *tempbuff = (uint8_t)(data & 0xFFU);
          tempbuff++;
          dataremaining--;
          *tempbuff = (uint8_t)((data ›› 8U) & 0xFFU);
          tempbuff++;
          dataremaining--;
          *tempbuff = (uint8_t)((data ›› 16U) & 0xFFU);
          tempbuff++;
          dataremaining--;
          *tempbuff = (uint8_t)((data ›› 24U) & 0xFFU);
          tempbuff++;
          dataremaining--;
        }
      }		
    }

    /* Send stop transmission command in case of multiblock read */
    if((SDMMC1-›STA & SDIO_FLAG_DATAEND) && (NumberOfBlocks › 1U))
    {
      if(SDCardInfo.CardType ‹ SDIO_SECURE_DIGITAL_IO_CARD)
      {
        /* Send stop transmission command */
        errorstatus = SDMMC_CmdStopTransfer();
        if(errorstatus != SD_OK)
        {
           /* Clear all the static flags */
        __SDMMC_CLEAR_FLAG(SDMMC_STATIC_FLAGS);
					
          SDCardInfo.Context = SD_CONTEXT_NONE;
          return errorstatus;
        }
      }
    }

    /* Get error state */
    if(SDMMC1-›STA & SDIO_FLAG_DTIMEOUT)
    {
      /* Clear all the static flags */
      __SDMMC_CLEAR_FLAG(SDMMC_STATIC_FLAGS);
			SDCardInfo.Context = SD_CONTEXT_NONE;
      return SD_DATA_TIMEOUT;
    }
    else if(SDMMC1-›STA & SDIO_FLAG_DCRCFAIL)
    {
      /* Clear all the static flags */
			__SDMMC_CLEAR_FLAG(SDMMC_STATIC_FLAGS);
			SDCardInfo.Context = SD_CONTEXT_NONE;
      return SD_DATA_CRC_FAIL;
    }
    else if(SDMMC1-›STA & SDIO_FLAG_RXOVERR)
    {
      /* Clear all the static flags */
			__SDMMC_CLEAR_FLAG(SDMMC_STATIC_FLAGS);
			SDCardInfo.Context = SD_CONTEXT_NONE;
      return SD_RX_OVERRUN;
    }
    else
    {
      /* Nothing to do */
    }

    /* Clear all the static flags */
    __SDMMC_CLEAR_FLAG(SDMMC_STATIC_DATA_FLAGS);
    return SD_OK;
}
В принципе 2 гиговые карточки уже тяжело найти, но все таки не нравится когда что-то идет не совсем так, может у кого встречалась чудная проблема.
Реклама:

Последний раз редактировалось mike-y-k; 02.03.2023 в 17:04. Причина: spoiler
djoni вне форума  
Непрочитано 02.03.2023, 09:07  
-Alan-
Прописка
 
Аватар для -Alan-
 
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
-Alan- на пути к лучшему
По умолчанию Re: STM32+SDIO SDSC не работает

Выводите отладочные сообщения в консоль вместо попытки отладить код. На SDIO отладчкик ломает всю логику интерфейса.
А выводить сообщения в консоль можно через буфер - это более-менее неблокирующий вариант (писать лог в буфер, выводить по возможности).

У меня в одном из старых проектов используется библиотека ChaN'а аж от 2014 года с сильно переписаным sdio.c под STM32F745. Разве что до ума окончательно не довёл - читается по секторно. Дописывать линейное чтение было лень. Вроди бы спокойно работало с любыми картами, что подсовывал (хотя и с разными были интересные приколы).

Приложил свои исходники.
Вывод отладки максимально заглушен. Можно полностью закомментировать оставшиеся сообщения console_put*, либо раскомментировать и заменить их на какой-нибудь printf(). У меня это всё вывод в консоль БЕЗ использования тяжеловесных функций.

Обратите внимание на переменную `SDType`. Она используется для расчёта номера сектора. Возможно у вас та же проблема.
Вложения:
Тип файла: zip sdio.zip (8.5 Кб, 0 просмотров)
-Alan- вне форума  
Эти 2 пользователя(ей) сказали Спасибо -Alan- за это сообщение:
djoni (13.03.2023), mike-y-k (02.03.2023)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как работает удвоитель напряжения на конденсаторах. monopolie Электроника - это просто 65 18.10.2019 01:24
Не работает релейный реверс массажной кровати 123ksn Автоматика и аппаратура связи 64 16.03.2019 15:59
Не работает Attiny13 spamkerdyk AVR 16 03.03.2019 03:39
Проблема с USB STM32 worldmasters ПЛИС и другие МК 9 28.12.2018 18:06
PROTEUS не работает crystall Proteus 1 21.11.2006 00:27


Часовой пояс GMT +4, время: 06:59.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.