реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Библиотека для SD карты stm32f2xx, помогите разобраться с кодом
Habr
сообщение Dec 13 2013, 14:15
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 11-10-10
Пользователь №: 60 067



Доброго времени суток .
Пытаюсь записать данные на micro sd карту, а так как не нашол библиотеки непосредственно под это семейство пытаюсь адаптировать библиотеку от stm32f4_discovery_sdio_sd.h
получилось инициализировать карту и считать с неё данные однако при выполнении функции SD_WriteBlock функция зависает
Код
SD_Error SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize)
{
  SD_Error errorstatus = SD_OK;

#if defined (SD_POLLING_MODE)
  uint32_t bytestransferred = 0, count = 0, restwords = 0;
  uint32_t *tempbuff = (uint32_t *)writebuff;
#endif

  TransferError = SD_OK;
  TransferEnd = 0;
  StopCondition = 0;

  SDIO->DCTRL = 0x0;

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

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

/*!< In case of single data block transfer no need of stop command at all */
#if defined (SD_POLLING_MODE)
  while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
  {
    if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
    {
      if ((512 - bytestransferred) < 32)
      {
        restwords = ((512 - bytestransferred) % 4 == 0) ? ((512 - bytestransferred) / 4) : (( 512 -  bytestransferred) / 4 + 1);
        for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
        {
          SDIO_WriteData(*tempbuff);
        }
      }
      else
      {
        for (count = 0; count < 8; count++)
        {
          SDIO_WriteData(*(tempbuff + count));
        }
        tempbuff += 8;
        bytestransferred += 32;
      }
    }
  }
  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);
  }
#elif defined (SD_DMA_MODE)
  SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
  SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, BlockSize);
  SDIO_DMACmd(ENABLE);
#endif

  /*!< Send CMD24 WRITE_SINGLE_BLOCK */
  SDIO_CmdInitStructure.SDIO_Argument = WriteAddr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_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_SINGLE_BLOCK);

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

  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = 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);
}

а именно на
Код
if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)

непонятно почему не выставляется флаг что буфер пустой хотя я не производил в него запись.



Возможно у кого нибудь есть готовая библиотека под данное семейство с примером ?
Go to the top of the page
 
+Quote Post
Falkon_99
сообщение Dec 13 2013, 16:03
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 169
Регистрация: 26-03-12
Из: Харьков
Пользователь №: 71 010



Вот SPL с примерами под камень stm32f2xx http://www.st.com/web/en/catalog/tools/PF257898

а по вашему проэкту тяжело сказать, либо неправильно инициализирован SDIO, либо в железе ошибка
как я понял вы используете режим SD_POLLING_MODE? попробуйте режим SD_DMA_MODE
Go to the top of the page
 
+Quote Post
Habr
сообщение Dec 13 2013, 23:13
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 11-10-10
Пользователь №: 60 067



Цитата(Falkon_99 @ Dec 13 2013, 20:03) *

это библиотека для работы с периферией SDIO, с ней более менее всё понятно
а ещё у ST есть надстройка над над ней для работы уже с SD картой
* @file stm32f4_discovery_sdio_sd.c
* @author MCD Application Team
* @version V1.0.2
* @date 05-March-2012
* @brief This file provides a set of functions needed to manage the SDIO SD
* Card memory mounted on STM32F4 Discovery board.
вот на неё бы найти описание или "порт" под stm32f2xx
Go to the top of the page
 
+Quote Post
Falkon_99
сообщение Dec 14 2013, 07:48
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 169
Регистрация: 26-03-12
Из: Харьков
Пользователь №: 71 010



там в архиве есть файл stm322xg_eval_sdio_sd.c
это то, что Вам нужно. Там есть все для работы SD карты, кроме надстройки fatfs, к сожелению
Вообще там полно примеров, сделаны они для отладочной платы STM3220G_EVAL, проц там стоит STM32F207IGH6.



Кстати, есть ли официальные примеры/библиотеки для работы с FatFS, например от ST или других фирм???
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 14 2013, 17:27
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Рекомендую посмотреть пример работы с SDIO вот здесь. В сравнении с огромным супернавороченным индусским кодом от ST - поражает простотой и лаконизмом. К тому же, свободен от некоторых глюков, присущих коду от ST.
И ещё, вот ссылка, в которой описываются некоторые тонкости интерфейса SDIO в STM32.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Habr
сообщение Dec 16 2013, 23:29
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 11-10-10
Пользователь №: 60 067



Цитата(AHTOXA @ Dec 14 2013, 21:27) *
Рекомендую посмотреть пример работы с SDIO вот здесь. В сравнении с огромным супернавороченным индусским кодом от ST - поражает простотой и лаконизмом. К тому же, свободен от некоторых глюков, присущих коду от ST.
И ещё, вот ссылка, в которой описываются некоторые тонкости интерфейса SDIO в STM32.

Спасибо теперь разобрался.
Только теперь возник другой вопрос, а ST свои функции в библиотеках вообще проверяет на работоспособность.вот например :
Код
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{
  uint32_t temp = 0x00;
  uint32_t temp_2 = 0x00;  
  temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
  GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
  temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
  GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
}

в памяти есть 2 регистра AFR[0] и AFR[1], GPIO_PinSource это число с 1 в разряде соответствующей пину то есть 0x800 соответствует 11 пину. а теперь собственно куда запишет вот эта строка для 11 пина GPIOx->AFR[GPIO_PinSource >> 0x03]. кроме того temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) всегда будет сдвигать GPIO_AF на 0 разрядов. И как теперь доверять их библиотекам !?
Go to the top of the page
 
+Quote Post
Flexz
сообщение Dec 17 2013, 06:29
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797



Цитата(Habr @ Dec 17 2013, 03:29) *
...GPIO_PinSource это число с 1 в разряде соответствующей пину то есть 0x800 соответствует 11 пину...

Ничего подобного. GPIO_PinSource это число соответствующее номеру пина напрямую, т.е. GPIO_PinSource11 это 0xB, а не 0x800.
См дефайны в stm32f2xx_gpio.h
Код
#define GPIO_PinSource0            ((uint8_t)0x00)
#define GPIO_PinSource1            ((uint8_t)0x01)
#define GPIO_PinSource2            ((uint8_t)0x02)
#define GPIO_PinSource3            ((uint8_t)0x03)
и т.д.

Ненадо додумывать, что принимают те или иные функции у ST. Смотрите в примерах, как ими пользоваться. Благо примеров в достатке.

PS между прочим, значения допустимые для параметра, о котором идет речь - описаны в коментарии прямо надо кодом, который вы привели.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 17:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016