Старт ARM. SDIO. FatFS.

Доброе время суток, продолжаем изучать микроконтроллеры ARM архитектуры. На повестке дня у нас SDIO и FatFS.

SDIO
SDIO – (Secure Digital Input/Output) – стандарт для работы со слотами расширения формата SD/MMS. Сегодня на самом деле используется не так много стандартов флэш-памяти. Это Secure Digital/Multimedia Card, которая включая некоторые их модификации, такие как RS-MMC, CompactFlash Type II, реже — MemoryStick. Карты памяти семейства SD/MMC сегодня довольно многообразны как по емкости, так и по форм-фактору. Кроме «традиционных» карт Secure Digital существуют,так называемые карты половинной высоты (Reduced Size MMC), MMCmobile (RS-MMC со сниженными требованиями к напряжению). Secure Digital Memory Card (SD) — формат карт памяти (флеш-память), разработанный для использования в основном в портативных устройствах. На сегодняшний день широко используется в цифровых фотоаппаратах и видеокамерах, мобильных телефонах, электронных книгах, GPS-навигаторах и в некоторых игровых приставках.

Система передачи данных
Карты могут поддерживать различные сочетания следующих типов шин и режимов передачи. Режим шины SPI и однобитовый режим шин SD является обязательным для всех типов карт. Нумерация выводов для всех размеров карт SD и хост-устройств является одинаковой.

Режим шины SPI: Serial Peripheral Interface в основном используется в микроконтроллерах. Этот тип шины поддерживает только 3,3-вольтовой интерфейс. Это единственный тип шины, которые не требуют лицензии на хост.
Однобитовый режим шины SD: Отдельная шина для команды и каналов передачи данных.
Четырёхбитовый режим шины SD: Использует дополнительные контакты, переназначены некоторые контакты. Для карт UHS-I и UHS-II требуется именно этот режим.

Физический интерфейс включает в себя 9 контактов, за исключением того, что для карт miniSD добавлено два несвязанных контакта в центре и microSD карты не использует один из двух общих контактов.

FatFs
FatFs является модулем простой файловой системы FAT (generic FAT file system), предназначенным для маленьких встраиваемых систем на микроконтроллерах (embedded systems). FatFS-module-layers FatFs написан на ANSI C(C89) и полностью разделен по уровням дискового ввода/вывода (disk I/O). Таким образом, модуль полностью не зависит от аппаратной архитектуры подключения носителя данных (карта памяти, жесткий диск, FLASH, SDRAM и т. п.) к микроконтроллеру, и может быть легко портирован на любой микроконтроллер и систему. Модуль хорошо подходит для микроконтроллеров нижней ценовой категории типа AVR, 8051, PIC, ARM, Z80, 68k и т. д., и портируется без всяких изменений. Для того, чтобы модуль заработал, нужно только предоставить низкоуровневый интерфейс ввода вывода (см. далее, Disk I/O Interface). Модуль Petit FatFs также доступен как пример реализации такого ввода/вывода для 8-битных микроконтроллеров.

Подробное описание о работе с FatFs на русском языке.
http://microsin.net/programming/file-systems/fatfs-file-system.html
http://microsin.net/programming/file-systems/fatfs-appnotes.html

Мы с вами просто возьмем готовый пример, немного его исправим, чтобы он у нас запускался и затем поиграемся с основными функциями, для работы с SD и FatFS.

Изменять будем STM32Cube_FW_F4_V1.5.0\Projects\STM324x9I_EVAL\Applications\FatFs\FatFs_uSD для STM324x9I_EVAL на STM32F429i-Disco.

Но первым делам нужно развести плату для microSD карты (я делаю писибишки в Altium Designer).

Писибишка

main.c

/**
  ******************************************************************************
  * @file    FatFs/FatFs_uSD/Src/main.c
  * @author  MCD Application Team
  * @version V1.2.1
  * @date    13-March-2015
  * @brief   Main program body
  *          This sample code shows how to use FatFs with uSD card drive.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
FATFS SDFatFs;  /* File system object for SD card logical drive */
FIL MyFile;     /* File object */
char SDPath[4]; /* SD card logical drive path */

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  FRESULT res;                                          /* FatFs function common result code */
  uint32_t byteswritten, bytesread;                     /* File write/read counts */
  uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
  uint8_t rtext[100];                                   /* File read buffer */
  
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */
  HAL_Init();
  
  /* Configure the system clock to 175 MHz */
  SystemClock_Config();
  
  /* Configure LED1 and LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);
  
  /*##-1- Link the micro SD disk I/O driver ##################################*/
  if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
  {
    /*##-2- Register the file system object to the FatFs module ##############*/
    if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      Error_Handler();
    }
    else
    {
      /*##-3- Create a FAT file system (format) on the logical drive #########*/
      /* WARNING: Formatting the uSD card will delete all content on the device */
      if(f_mkfs((TCHAR const*)SDPath, 0, 0) != FR_OK)
      {
        /* FatFs Format Error */
        Error_Handler();
      }
      else
      {
        /*##-4- Create and Open a new text file object with write access #####*/
        if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
        {
          /* 'STM32.TXT' file Open for write Error */
          Error_Handler();
        }
        else
        {
          /*##-5- Write data to the text file ################################*/
          res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
          
          if((byteswritten == 0) || (res != FR_OK))
          {
            /* 'STM32.TXT' file Write or EOF Error */
            Error_Handler();
          }
          else
          {
            /*##-6- Close the open text file #################################*/
            f_close(&MyFile);
            
            /*##-7- Open the text file object with read access ###############*/
            if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK)
            {
              /* 'STM32.TXT' file Open for read Error */
              Error_Handler();
            }
            else
            {
              /*##-8- Read data from the text file ###########################*/
              res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);
              
              if((bytesread == 0) || (res != FR_OK))
              {
                /* 'STM32.TXT' file Read or EOF Error */
                Error_Handler();
              }
              else
              {
                /*##-9- Close the open text file #############################*/
                f_close(&MyFile);
                
                /*##-10- Compare read data with the expected data ############*/
                if((bytesread != byteswritten))
                {                
                  /* Read data is different from the expected data */
                  Error_Handler();
                }
                else
                {
                  /* Success of the demo: no error occurrence */
                  BSP_LED_On(LED1);
                }
              }
            }
          }
        }
      }
    }
  }
  
  /*##-11- Unlink the micro SD disk I/O driver ###############################*/
  FATFS_UnLinkDriver(SDPath);
  
  /* Infinite loop */
  while (1)
  {
  }
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 175000000
  *            HCLK(Hz)                       = 175000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 350
  *            PLL_P                          = 2
  *            PLL_Q                          = 7
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 5
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 350;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
  
  /* Activate the Over-Drive mode */
  HAL_PWREx_EnableOverDrive();
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
static void Error_Handler(void)
{
  /* Turn LED3 on */
  BSP_LED_On(LED3);
  while(1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Сейчас нам необходимо подправить 2 участка кода, чтобы проект у нас с Вами начал полноценно функционировать. Первый участок кода, находим uint8_t BSP_SD_Init(void) внутри функции находим uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; Переходим по определению (F12) и изменяем define на define следующего вида #define SDIO_TRANSFER_CLK_DIV ((uint8_t)0xFF). Второе изменения касается использования пина для фиксации SD карточки. Находим функцию uint8_t BSP_SD_IsDetected(void) и просто, основной код этой функции комментируем(а не удаляем, конечно лучше поставить define и в следующей раз когда будет необходимость собрать проект, для SD, просто нужно будет сказать компилятору, что у нас проект с фиксацией или без фиксации карточки).

uint8_t BSP_SD_IsDetected(void)
{
  __IO uint8_t status = SD_PRESENT;
  
  /* Check SD card detect pin */
  /*
  if(BSP_IO_ReadPin(SD_DETECT_PIN))
  {
    status = SD_NOT_PRESENT;
  }
  */
  return status;
}

Проект в Keil для SD карты.
После зашивки проекта в микроконтроллер, достаем карту памяти и вставляем ее в кард ридер. И ВОЛЯ! 🙂

Начало положено, 2 статью уже начал писать. Вопросы оставляйте в комментариях.

4 thoughts on “Старт ARM. SDIO. FatFS.

  1. Здравствуйте.
    А для чего такие сигзаги на трассировке?
    Спасибо.

    1. Просто в моем старом проекте для SDIO стояла правило согласование по длине, для высокоскоростной передачи данных. Поэтому я быстро скопировал и залудил платку.

  2. А почему на плате дорожки не прямые а в некоторых местах есть зигзаги? Предполагаю что это связано с передачей данных, защита линий данных от взаимных помех. Хотя с другой стороны такие зигзаги это лишняя индуктивность дорожки которая тоже может быть вредна.

    1. В альтиуме стаяло правило согласование длины проводника для высокоскоростной передачи данных

Comments are closed.