cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX, FatFS and SDIO?

antonius
Senior
Posted on February 20, 2017 at 22:57

Everyone,

How can I use cubeMX for SDcard ? I have generated for MDK but :

this function doesn't work , from UM1721

User manual

Developing Applications on STM32Cube with FatFs page 21.

:

uint32_t wbytes; /* File write counts */

uint8_t wtext[] = 'text to write logical disk'; /* File write buffer */

if(FATFS_LinkDriver(&mynewdisk_Driver, mynewdiskPath) == 0)

{

if(f_mount(&mynewdiskFatFs, (TCHAR const*)mynewdiskPath, 0) == FR_OK)

{

if(f_open(&MyFile, 'STM32.TXT', FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)

{

if(f_write(&MyFile, wtext, sizeof(wtext), (void *)&wbytes) == FR_OK);

{

f_close(&MyFile);

}

}

}

}

FATFS_UnLinkDriver(mynewdiskPath);

This variable :

&mynewdisk_Driver doesn't exist, which file is related ?

Thank you

54 REPLIES 54
antonius
Senior
Posted on February 25, 2017 at 13:15

 I got until this if, but the code is stopped here ,

Is SDCard initialized properly already ?

if(f_open(&MyFile, 'Hello.txt', FA_CREATE_ALWAYS | FA_WRITE) !=    FR_OK)

antonius
Senior
Posted on February 26, 2017 at 12:09

I'm confused, so sdio and SD card isn't yet initalized ??

Posted on February 26, 2017 at 16:14

Hi

No, FATFS can run on different backends not only SD-cards. SD-card can be controlled by different interface types.

Namely SPI, SDIO. SDIO can work in 1 bit, 4 bit and 8 bit. In some MCUs there is a peripheral for SDIO

and you can take advantage of that fact using CubeMX.

For SPI, not using a predefined bord in CubeMX, you have to provide your own implementation.  

You can find an SD-card based example for user_diskio.c in most Cube_FW... repositories.

For example STM32Cube_FW_F1_V1.4.0/Middlewares/Third_Party/FatFs/src/drivers/sd_diskio.c

There are functions in this file which are using IO functions like BSP_SD_ReadBlocks()

These functions in turn are using functions like

SD_IO_WriteReadData()

These functions in turn are using functions like

SPIx_WriteReadData()

These functions in turn are using functions like

HAL_SPI_TransmitReceive()

happy learning

Dieter

antonius
Senior
Posted on February 26, 2017 at 22:14

From :

STM32Cube\Repository\STM32Cube_FW_F1_V1.4.0\Middlewares\Third_Party\FatFs\src\drivers\sd_diskio.c

How can I link it with my generated code ? I don't understand ??

/**

  ******************************************************************************

  * @file    sd_diskio.c

  * @author  MCD Application Team

  * @version V1.3.0

  * @date    08-May-2015

  * @brief   SD Disk I/O driver

  ******************************************************************************

  * @attention

  *

  * <h2><center>&copy; COPYRIGHT 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:

  *

  *       

https://community.st.com/external-link.jspa?url=http%3A%2F%2Fwww.st.com%2Fsoftware_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 <string.h>

#include 'ff_gen_drv.h'

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Block Size in Bytes */

#define BLOCK_SIZE                512

/* Private variables ---------------------------------------------------------*/

/* Disk status */

static volatile DSTATUS Stat = STA_NOINIT;

/* Private function prototypes -----------------------------------------------*/

DSTATUS SD_initialize (BYTE);

DSTATUS SD_status (BYTE);

DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);

#if _USE_WRITE == 1

  DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);

#endif /* _USE_WRITE == 1 */

#if _USE_IOCTL == 1

  DRESULT SD_ioctl (BYTE, BYTE, void*);

#endif  /* _USE_IOCTL == 1 */

 

const Diskio_drvTypeDef  SD_Driver =

{

  SD_initialize,

  SD_status,

  SD_read,

#if  _USE_WRITE == 1

  SD_write,

#endif /* _USE_WRITE == 1 */

 

#if  _USE_IOCTL == 1

  SD_ioctl,

#endif /* _USE_IOCTL == 1 */

};

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

/**

  * @brief  Initializes a Drive

  * @param  lun : not used

  * @retval DSTATUS: Operation status

  */

DSTATUS SD_initialize(BYTE lun)

{

  Stat = STA_NOINIT;

 

  /* Configure the uSD device */

  if(BSP_SD_Init() == MSD_OK)

  {

    Stat &= ~STA_NOINIT;

  }

  return Stat;

}

/**

  * @brief  Gets Disk Status

  * @param  lun : not used

  * @retval DSTATUS: Operation status

  */

DSTATUS SD_status(BYTE lun)

{

  Stat = STA_NOINIT;

  if(BSP_SD_GetStatus() == MSD_OK)

  {

    Stat &= ~STA_NOINIT;

  }

 

  return Stat;

}

/**

  * @brief  Reads Sector(s)

  * @param  lun : not used

  * @param  *buff: Data buffer to store read data

  * @param  sector: Sector address (LBA)

  * @param  count: Number of sectors to read (1..128)

  * @retval DRESULT: Operation result

  */

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)

{

  DRESULT res = RES_OK;

 

  if(BSP_SD_ReadBlocks((uint32_t*)buff,

                       (uint64_t) (sector * BLOCK_SIZE),

                       BLOCK_SIZE,

                       count) != MSD_OK)

  {

    res = RES_ERROR;

  }

 

  return res;

}

/**

  * @brief  Writes Sector(s)

  * @param  lun : not used

  * @param  *buff: Data to be written

  * @param  sector: Sector address (LBA)

  * @param  count: Number of sectors to write (1..128)

  * @retval DRESULT: Operation result

  */

#if _USE_WRITE == 1

DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)

{

  DRESULT res = RES_OK;

 

  if(BSP_SD_WriteBlocks((uint32_t*)buff,

                        (uint64_t)(sector * BLOCK_SIZE),

                        BLOCK_SIZE, count) != MSD_OK)

  {

    res = RES_ERROR;

  }

 

  return res;

}

#endif /* _USE_WRITE == 1 */

/**

  * @brief  I/O control operation

  * @param  lun : not used

  * @param  cmd: Control code

  * @param  *buff: Buffer to send/receive control data

  * @retval DRESULT: Operation result

  */

#if _USE_IOCTL == 1

DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)

{

  DRESULT res = RES_ERROR;

  SD_CardInfo CardInfo;

 

  if (Stat & STA_NOINIT) return RES_NOTRDY;

 

  switch (cmd)

  {

  /* Make sure that no pending write process */

  case CTRL_SYNC :

    res = RES_OK;

    break;

 

  /* Get number of sectors on the disk (DWORD) */

  case GET_SECTOR_COUNT :

    BSP_SD_GetCardInfo(&CardInfo);

    *(DWORD*)buff = CardInfo.CardCapacity / BLOCK_SIZE;

    res = RES_OK;

    break;

 

  /* Get R/W sector size (WORD) */

  case GET_SECTOR_SIZE :

    *(WORD*)buff = BLOCK_SIZE;

    res = RES_OK;

    break;

 

  /* Get erase block size in unit of sector (DWORD) */

  case GET_BLOCK_SIZE :

    *(DWORD*)buff = BLOCK_SIZE;

    break;

 

  default:

    res = RES_PARERR;

  }

 

  return res;

}

#endif /* _USE_IOCTL == 1 */

 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
antonius
Senior
Posted on February 26, 2017 at 22:20

Here's the complete generated code from STM32CubeMX, please have a look, thanks

https://drive.google.com/open?id=0B7YziG3F_7SqWklSdlZUSHN1dDQ

Posted on February 26, 2017 at 22:41

You have to know what pointers to functions are.

ff_gen_drv.h:

/** 
 * @brief Disk IO Driver structure definition 
 */ 
typedef struct
{
 DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
 DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
 DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
#if _USE_WRITE == 1 
 DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1 
 DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeDef;
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Dieter

Posted on February 27, 2017 at 08:08

Hello Rick,

I have similar problem. The program stuck in fopen(). I posted a thread there:

https://community.st.com/0D50X00009XkfcxSAB

When I generate code using cubemx for F405, it works, but doesn't works for F4 The hardware problem was excluded because I have code generated by clive using spl. With that code, reading/writing has been passed.

I just couldn't figure out what is the problem.

antonius
Senior
Posted on February 27, 2017 at 12:18

In UM1721 page 19 :

3 FatFs applications

In the STM32CubeF4 solution, many applications are provided based on FatFs

middleware. The table below gives you insight on how the FatFs middleware

component is used in different examples which are classified by complexity and

depending on used physical drive interfaced (uSD, RAMDisk, USBDisk): ....

 

Where can I see those examples ? thanks

antonius
Senior
Posted on February 27, 2017 at 12:27

This is what I got :

STM32Cube\Repository\STM32Cube_FW_F1_V1.4.0\Projects\STM3210E_EVAL\Applications\FatFs

How can I adapt it to my custom code ?

Posted on February 27, 2017 at 12:13

Is there any working SDcard driver example ? I read from UM1718, there's an example ? where is it ?

It's not easy to write SDcard driver from scratch..