Jump to content

    
Sign in to follow this  
zksystem

STM32 SDIO 4bit SD-card

Recommended Posts

Всем привет, подскажите пожалуйста кто реализовывал работу с 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);

Share this post


Link to post
Share on other sites
Вопрос снят, оказывается забыл запаять подтягивающие резисторы 47К на SDIO0..3, SDIOCLK, SDIOCMD.

sdio и резисторы на stm32 это уже не просто грабли - это место культового посещения граблей. я тоже бывал в этой ситуации.

Share this post


Link to post
Share on other sites

Столкнулся с проблемой чтения блока из карты. Код выглядит так:

    ...То что выше опущено...

    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);
}

 

Может забыл чего-то еще сделать?

Share this post


Link to post
Share on other sites

В качестве эксперимента попробовал другой режим:

Status = SD_SetDeviceMode(SD_POLLING_MODE);

В результате при попытке чтения блока устанавливается флаг SDIO_FLAG_STBITERR. Такое ощущение что с шиной данных что-то не то.

Share this post


Link to post
Share on other sites

Проблема неработоспособности была в том, что вывод SDIO_D1 был закорочен на землю. После устранения коротыша сектора читаются правильно. Но работает только комбинация режимов: SD_POLLING_MODE и SDIO_BusWide_1b. Некоторые комбинации вообще приводят к HardFault exception. Возможно ли, что вывод SDIO_D1 микроконтроллера погорел от коротыша на землю?

Share this post


Link to post
Share on other sites
Проблема неработоспособности была в том, что вывод SDIO_D1 был закорочен на землю. После устранения коротыша сектора читаются правильно. Но работает только комбинация режимов: SD_POLLING_MODE и SDIO_BusWide_1b. Некоторые комбинации вообще приводят к HardFault exception. Возможно ли, что вывод SDIO_D1 микроконтроллера погорел от коротыша на землю?

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

 

P.S. Вы библиотечный пример SDIO смотрели? ИМХО там не сразу на 4bit передача включается, вначале определяется тип карты.

Share this post


Link to post
Share on other sites

Проблема решена полностью. Работают все режимы. Дело было в том, что в стартовом ассемблерном файле, который кейл создает при создании проекта, содержит неполную информацию о прерываниях (при этом прерывания от периферии в принципе не могут быть обработаны). Замена кейловского файл на аналогичный из библиотеки stm привела к полному порядку.

Share this post


Link to post
Share on other sites
Чтения блока не происходит. Происходит зацикливание в функции SD_ReadBlock на строке:

    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}

Аналогичная проблема на плате Open103Z (STM32F103ZE). Пытаюсь прикрутить FatFs на карточку, но, видимо, не приходит прерывание. Можно поподробнее расписать от чего может быть такое? Или, если это возможно, кинуть заработавший проект, попробую расковырять сам.

Прошу прощения, если написал фигню, просто в микроконтроллерах я не очень разбираюсь.

Share this post


Link to post
Share on other sites

Если использовал стартовый ассемблерный файл, созданный по умолчанию, то попробуй заменить его на стартовый файл из библиотеки периферии, в моем случае это startup_stm32f10x_xl.s

Share this post


Link to post
Share on other sites

Я брал файл с диска от платы. Насчёт startup_stm32f10x_xl.s не уверен, у меня памяти 512к, поэтому взял как в примере, hd.

 

Что самое странное, пример с диска по записи звука на флэшку вообще не работал, валился с ошибкой длины блока при попытке чтения. Взял отсюда часть по работе с карточкой - блоки нормально, но виснет этот while.

Если стопнуть выполнение, он показывает на эту строчку

323   DMA2_Channel4_5_IRQHandler
>324                   B       .

Edited by ALXLight

Share this post


Link to post
Share on other sites
Взял отсюда часть по работе с карточкой - блоки нормально, но виснет этот while.

Если стопнуть выполнение, он показывает на эту строчку

323   DMA2_Channel4_5_IRQHandler
>324                   B       .

Дык, вроде правильно виснет. Потому что в примере в файле fatfs_sdcard/fatfs_stm32_sdio.c в процедуре disk_initialize () вызывается SD_SetDeviceMode(SD_DMA_MODE), а в этом случае включаются прерывания от DMA.

Share this post


Link to post
Share on other sites
Дык, вроде правильно виснет. Потому что в примере в файле fatfs_sdcard/fatfs_stm32_sdio.c в процедуре disk_initialize () вызывается SD_SetDeviceMode(SD_DMA_MODE), а в этом случае включаются прерывания от DMA.

Ну это я понял. А можно для нубов пояснить как это работает? Чего реально ждёт этот пример и зачем это сделано? И что нужно сделать, чтобы он читал/писал сразу?

Share this post


Link to post
Share on other sites

Не нашёл кнопки редактирования, поэтому прошу прощения за даблпост.

Проверил чтение/зпись напрямую, без ФС. запись - нормально, чтение всё равно виснет там же.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this