Перейти к содержанию
    

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Status = SD_SetDeviceMode(SD_POLLING_MODE);

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтения блока не происходит. Происходит зацикливание в функции SD_ReadBlock на строке:

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

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

323   DMA2_Channel4_5_IRQHandler
>324                   B       .

Изменено пользователем ALXLight

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

323   DMA2_Channel4_5_IRQHandler
>324                   B       .

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте вызвать SD_SetDeviceMode() с другим параметром (не SD_DMA_MODE, там ещё два варианта).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...