Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 SDIO 4bit SD-card
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
zksystem
Всем привет, подскажите пожалуйста кто реализовывал работу с SD картой через 4bit SDIO на STM32, у меня почему-то зависает напрочь при инициализации SD_EnableWideBusOperation(SDIO_BusWide_4b);


printf("Init SD card:");
Status = SD_Init();
printf("%u\n",Status);

printf("get info status:");
Status = SD_GetCardInfo(&SDCardInfo);
printf("%u\n",Status);

printf("Select card:");
Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));
printf("%u\n",Status);

printf("Set 4bit operation:");
Status = SD_EnableWideBusOperation(SDIO_BusWide_4b); <- дальше этого не идет
printf("%u\n",Status);

printf("Set DMA mode:");
Status = SD_SetDeviceMode(SD_DMA_MODE);
printf("%u\n",Status);
zksystem
Вопрос снят, оказывается забыл запаять подтягивающие резисторы 47К на SDIO0..3, SDIOCLK, SDIOCMD.
klen
Цитата(zksystem @ Jul 16 2010, 15:16) *
Вопрос снят, оказывается забыл запаять подтягивающие резисторы 47К на SDIO0..3, SDIOCLK, SDIOCMD.

sdio и резисторы на stm32 это уже не просто грабли - это место культового посещения граблей. я тоже бывал в этой ситуации.
011119xx
Столкнулся с проблемой чтения блока из карты. Код выглядит так:
Код
    ...То что выше опущено...

    Status = SD_Init();                                            

    if (Status == SD_OK)
      {
        /*----------------- Read CSD/CID MSD registers ------------------*/
        Status = SD_GetCardInfo(&SDCardInfo);
      }

      if (Status == SD_OK)
      {
        /*----------------- Select Card --------------------------------*/
        Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));
      }

      if (Status == SD_OK)
      {
        Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
      }

      /* Set Device Transfer Mode */
      if (Status == SD_OK)
      {
        Status = SD_SetDeviceMode(SD_DMA_MODE);
      }

      Status = SD_ReadBlock(0, tempbuf1, 512);


Чтения блока не происходит. Происходит зацикливание в функции SD_ReadBlock на строке:
Код
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}


Обработчик прерывания SDIO определен как:
Код
void SDIO_IRQHandler(void)
{
  /* Process All SDIO Interrupt Sources */
  SD_ProcessIRQSrc();
}


Прерывания инициализированы так:
Код
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
    
  /* Configure the NVIC Preemption Priority Bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


Может забыл чего-то еще сделать?
011119xx
В качестве эксперимента попробовал другой режим:
Код
Status = SD_SetDeviceMode(SD_POLLING_MODE);

В результате при попытке чтения блока устанавливается флаг SDIO_FLAG_STBITERR. Такое ощущение что с шиной данных что-то не то.
011119xx
Проблема неработоспособности была в том, что вывод SDIO_D1 был закорочен на землю. После устранения коротыша сектора читаются правильно. Но работает только комбинация режимов: SD_POLLING_MODE и SDIO_BusWide_1b. Некоторые комбинации вообще приводят к HardFault exception. Возможно ли, что вывод SDIO_D1 микроконтроллера погорел от коротыша на землю?
zksystem
Цитата(011119xx @ May 6 2011, 05:42) *
Проблема неработоспособности была в том, что вывод SDIO_D1 был закорочен на землю. После устранения коротыша сектора читаются правильно. Но работает только комбинация режимов: SD_POLLING_MODE и SDIO_BusWide_1b. Некоторые комбинации вообще приводят к HardFault exception. Возможно ли, что вывод SDIO_D1 микроконтроллера погорел от коротыша на землю?

SDIO [D0..D3] резисторами подтянуты?

P.S. Вы библиотечный пример SDIO смотрели? ИМХО там не сразу на 4bit передача включается, вначале определяется тип карты.
011119xx
Проблема решена полностью. Работают все режимы. Дело было в том, что в стартовом ассемблерном файле, который кейл создает при создании проекта, содержит неполную информацию о прерываниях (при этом прерывания от периферии в принципе не могут быть обработаны). Замена кейловского файл на аналогичный из библиотеки stm привела к полному порядку.
ALXLight
Цитата(011119xx @ May 3 2011, 09:05) *
Чтения блока не происходит. Происходит зацикливание в функции SD_ReadBlock на строке:
Код
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}

Аналогичная проблема на плате Open103Z (STM32F103ZE). Пытаюсь прикрутить FatFs на карточку, но, видимо, не приходит прерывание. Можно поподробнее расписать от чего может быть такое? Или, если это возможно, кинуть заработавший проект, попробую расковырять сам.
Прошу прощения, если написал фигню, просто в микроконтроллерах я не очень разбираюсь.
011119xx
Если использовал стартовый ассемблерный файл, созданный по умолчанию, то попробуй заменить его на стартовый файл из библиотеки периферии, в моем случае это startup_stm32f10x_xl.s
ALXLight
Я брал файл с диска от платы. Насчёт startup_stm32f10x_xl.s не уверен, у меня памяти 512к, поэтому взял как в примере, hd.

Что самое странное, пример с диска по записи звука на флэшку вообще не работал, валился с ошибкой длины блока при попытке чтения. Взял отсюда часть по работе с карточкой - блоки нормально, но виснет этот while.
Если стопнуть выполнение, он показывает на эту строчку
Код
323   DMA2_Channel4_5_IRQHandler
>324                   B       .
AHTOXA
Цитата(ALXLight @ Mar 23 2012, 18:03) *
Взял отсюда часть по работе с карточкой - блоки нормально, но виснет этот while.
Если стопнуть выполнение, он показывает на эту строчку
Код
323   DMA2_Channel4_5_IRQHandler
>324                   B       .

Дык, вроде правильно виснет. Потому что в примере в файле fatfs_sdcard/fatfs_stm32_sdio.c в процедуре disk_initialize () вызывается SD_SetDeviceMode(SD_DMA_MODE), а в этом случае включаются прерывания от DMA.
ALXLight
Цитата(AHTOXA @ Mar 23 2012, 20:53) *
Дык, вроде правильно виснет. Потому что в примере в файле fatfs_sdcard/fatfs_stm32_sdio.c в процедуре disk_initialize () вызывается SD_SetDeviceMode(SD_DMA_MODE), а в этом случае включаются прерывания от DMA.

Ну это я понял. А можно для нубов пояснить как это работает? Чего реально ждёт этот пример и зачем это сделано? И что нужно сделать, чтобы он читал/писал сразу?
ALXLight
Не нашёл кнопки редактирования, поэтому прошу прощения за даблпост.
Проверил чтение/зпись напрямую, без ФС. запись - нормально, чтение всё равно виснет там же.
AHTOXA
Попробуйте вызвать SD_SetDeviceMode() с другим параметром (не SD_DMA_MODE, там ещё два варианта).
ALXLight
Polling выдаёт ошибку, а interrupt мне не подходит. Да и непонятно почему запись проходит в ДМА, а чтение - нет.
MBR
1. УМВР без подтяжки. Достаточно включить внутреннюю подтяжку.
2. Какая нафиг подтяжка на CLK?
3. При работе с ДМА нужно сразу взять за правило делать align 4 всех данных.
4. По возможности отказаться от использования индусских либ и вдумчиво читать реф. мануалы.
dezna
пытаюсь "поженить" scmRTOS на stm32f103 с SD картой fatfs через стмовский драйвер по SDIO интерфейсу.
процесс с обработчиком SD-карты имеет самый низкий приоритет.
проблема заключается в том, что при чтении с карты виснет время от времени после посылки команды на чтение.
что в режиме дма, что в режиме прерываний. выяснил, что если ОС прерывает процесс между посылкой команды и обработкой ответа на команду в процедуре CmdResp1Error, в которой сбрасываются флаги прерываний модуля sd, буфер фифо успевает заполниться и соответственно после сброса флагов прерывание не возникает.
вопрос состоит в том, как безболезненно заблокировать ОС на эти пару команд?
худо-бедно начинает работать при делителе тактового сигнала на 30 примерно 2 МГц.
без ОС все работает.
DmitryM
Цитата(dezna @ Feb 16 2013, 14:32) *
пытаюсь "поженить" scmRTOS на stm32f103 с SD картой fatfs через стмовский драйвер по SDIO интерфейсу.
вопрос состоит в том, как безболезненно заблокировать ОС на эти пару команд?

TCritSect cs;
dezna
Цитата(DmitryM @ Feb 17 2013, 10:34) *
TCritSect cs;

если не трудно объясните пожалуйста что это даст, и как этим воспользоваться?
dezna
что это такое разобрался, но в документации нет примера использования.
конструктор вызываю.
как вызвать деструктор? я в с++ пока не горазд. начал изучать только из-за ОС.
DmitryM
деструктор вызовется компилятором при выходе из секции.
dezna
Цитата(DmitryM @ Feb 18 2013, 10:18) *
деструктор вызовется компилятором при выходе из секции.

а нельзя ли принудительно его вызвать?
код просто написан так, что в теле одного блока нужно запретить/разрешить.
драйвер SD карты взят от STM. а там упаришься переделывать.
DmitryM
Цитата(dezna @ Feb 18 2013, 09:27) *
а нельзя ли принудительно его вызвать?
код просто написан так, что в теле одного блока нужно запретить/разрешить.
драйвер SD карты взят от STM. а там упаришься переделывать.

При выходе из блока автоматически будет вызван деструктор, который восстановит состояние,
предшествовавшее входу в критическую секцию. Т.е. при таком способе отсутствует возможность
«забыть» разрешить прерывания при выходе из критической секции.

P.S. для обсуждения scmRTOS есть отдельный форум scmRTOS
dezna
Цитата(DmitryM @ Feb 18 2013, 10:56) *
P.S. для обсуждения scmRTOS есть отдельный форум scmRTOS

спасибо.
Allregia
Блин, столкнулся с тем, что SD-коннекторы бывают с нормльно замкунытым пином SD-Detect!
Теперь придется два варианта программы делать, смотря что на плату напаяют (там 2 футпринта совмещены).
dezna
Цитата(Allregia @ Feb 21 2013, 12:26) *
Блин, столкнулся с тем, что SD-коннекторы бывают с нормльно замкунытым пином SD-Detect!
Теперь придется два варианта программы делать, смотря что на плату напаяют (там 2 футпринта совмещены).

зачем 2 варианта? если есть свободная нога контроллера, то в зависимости от держателя замыкать или нет на землю.
нога как вход с подтяжкой. замыкать - дорожка под обрезание, или перемычка на ПП под каплю припоя.
а программа при старте анализирует и соответственно реагирует. или например делать исключающее или ножек.
Allregia
У меня и так стоят 4 джампера конфигурирования, но они для оперативного конфигурирования, кторое может меняться. в процессе эксплуатации. А смысл пина в коннекторе может меняться только при производстве, поэтому еще на это ножку тратить неохота.
A.Lex
Столкнулся с проблемой:

Делаю

Status = SD_Init();

ответ Status = SD_OK;

Status = SD_GetCardInfo(&SDCardInfo);

ответ Status = SD_OK;

Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));

ответ Status = SD_CMD_RSP_TIMEOUT;


В чем причина? На низком уровне пишет/читает блок. Карточка microSD 1Gb.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.