Skip to main content
Visitor II
July 8, 2024
Question

How to work with SD Card FileX and USBX MSC on stm32h573i-dk

  • July 8, 2024
  • 3 replies
  • 2092 views
I'd like to use both FileX and USBX MSC as SD cards on stm32h573i-dk. FileX and USBX MSC worked respectively with reference to the example. USBX MSC cannot be used when using filex_media_open().
 
 

 

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file ux_device_msc.c
 * @author MCD Application Team
 * @brief USBX Device applicative file
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

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

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h> 
#include "main.h"
#include "fx_stm32_sd_driver.h"
/* USER CODE END Includes */
#include "fx_api.h"
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
enum {
 SD_WRITE_FLAG = 0x01,
 SD_READ_FLAG = 0x02,
};
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
extern SD_HandleTypeDef hsd1;
extern HAL_SD_CardInfoTypeDef sd_info;
extern TX_EVENT_FLAGS_GROUP sdmmc_event;
extern FX_MEDIA sdio_disk;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
static INT check_sd_status(uint32_t instance)
{
 uint32_t start = tx_time_get();

 while (tx_time_get() - start < 100) {
 if (fx_stm32_sd_get_status(instance) == 0) {
 return 0;
 }
 }

 return 1;
}
/* USER CODE END 0 */

/**
 * @brief USBD_STORAGE_Activate
 * This function is called when insertion of a storage device.
 * @PAram storage_instance: Pointer to the storage class instance.
 * @retval none
 */
VOID USBD_STORAGE_Activate(VOID *storage_instance)
{
 /* USER CODE BEGIN USBD_STORAGE_Activate */
 UX_PARAMETER_NOT_USED(storage_instance);
 printf("USBD_STORAGE_Activate\n");
 /* USER CODE END USBD_STORAGE_Activate */

 return;
}

/**
 * @brief USBD_STORAGE_Deactivate
 * This function is called when extraction of a storage device.
 * @PAram storage_instance: Pointer to the storage class instance.
 * @retval none
 */
VOID USBD_STORAGE_Deactivate(VOID *storage_instance)
{
 /* USER CODE BEGIN USBD_STORAGE_Activate */
 UX_PARAMETER_NOT_USED(storage_instance);
 printf("USBD_STORAGE_Activate\n");
 /* USER CODE END USBD_STORAGE_Activate */

 return;
}

/**
 * @brief USBD_STORAGE_Read
 * This function is invoked to read from media.
 * @PAram storage_instance : Pointer to the storage class instance.
 * @PAram lun: Logical unit number is the command is directed to.
 * @PAram data_pointer: Address of the buffer to be used for reading or writing.
 * @PAram number_blocks: number of sectors to read/write.
 * @PAram lba: Logical block address is the sector address to read.
 * @PAram media_status: should be filled out exactly like the media status
 * callback return value.
 * @retval status
 */
UINT USBD_STORAGE_Read(VOID *storage_instance, ULONG lun, UCHAR *data_pointer,
 ULONG number_blocks, ULONG lba, ULONG *media_status)
{
 UINT status = UX_SUCCESS;

 /* USER CODE BEGIN USBD_STORAGE_Read */
 UX_PARAMETER_NOT_USED(storage_instance);
 UX_PARAMETER_NOT_USED(lun);
 // UX_PARAMETER_NOT_USED(data_pointer);
 // UX_PARAMETER_NOT_USED(number_blocks);
 // UX_PARAMETER_NOT_USED(lba);
 UX_PARAMETER_NOT_USED(media_status);
 ULONG WriteFlags = 0;
 status = UX_ERROR;

 status = check_sd_status(0);
 if (status) {
 printf("SD card not ready\n");
 return status;
 }

 /* Start the Dma write */
 status = fx_stm32_sd_read_blocks(0, (UINT *)data_pointer, lba, number_blocks);
 if(status != HAL_OK) {
 printf("HAL_SD_ReadBlocks_DMA failed\n");
 }

 /* Wait on readflag until SD card is ready to use for new operation */
 tx_event_flags_get(&sdmmc_event, 
 SD_READ_FLAG, 
 TX_OR_CLEAR, 
 &WriteFlags, 
 TX_WAIT_FOREVER);

 /* USER CODE END USBD_STORAGE_Read */

 return status;
}

/**
 * @brief USBD_STORAGE_Write
 * This function is invoked to write in media.
 * @PAram storage_instance : Pointer to the storage class instance.
 * @PAram lun: Logical unit number is the command is directed to.
 * @PAram data_pointer: Address of the buffer to be used for reading or writing.
 * @PAram number_blocks: number of sectors to read/write.
 * @PAram lba: Logical block address is the sector address to read.
 * @PAram media_status: should be filled out exactly like the media status
 * callback return value.
 * @retval status
 */
UINT USBD_STORAGE_Write(VOID *storage_instance, ULONG lun, UCHAR *data_pointer,
 ULONG number_blocks, ULONG lba, ULONG *media_status)
{
 UINT status = UX_SUCCESS;

 /* USER CODE BEGIN USBD_STORAGE_Write */
 UX_PARAMETER_NOT_USED(storage_instance);
 // UX_PARAMETER_NOT_USED(lun);
 // UX_PARAMETER_NOT_USED(data_pointer);
 // UX_PARAMETER_NOT_USED(number_blocks);
 // UX_PARAMETER_NOT_USED(lba);
 UX_PARAMETER_NOT_USED(media_status);
 ULONG ReadFlags = 0U;
 status = UX_ERROR;

 status = check_sd_status(0);
 if (status) {
 printf("SD card not ready\n");
 return status;
 }

 /* Start the Dma write */
 status = fx_stm32_sd_write_blocks(0, (UINT *)data_pointer, lba, number_blocks);
 if(status != HAL_OK) {
 printf("HAL_SD_WriteBlocks_DMA failed\n");
 }

 /* Wait on writeflag until SD card is ready to use for new operation */
 tx_event_flags_get(&sdmmc_event, 
 SD_WRITE_FLAG, 
 TX_OR_CLEAR, 
 &ReadFlags, 
 TX_WAIT_FOREVER);

 /* USER CODE END USBD_STORAGE_Write */

 return status;
}

/**
 * @brief USBD_STORAGE_Flush
 * This function is invoked to flush media.
 * @PAram storage_instance : Pointer to the storage class instance.
 * @PAram lun: Logical unit number is the command is directed to.
 * @PAram number_blocks: number of sectors to read/write.
 * @PAram lba: Logical block address is the sector address to read.
 * @PAram media_status: should be filled out exactly like the media status
 * callback return value.
 * @retval status
 */
UINT USBD_STORAGE_Flush(VOID *storage_instance, ULONG lun, ULONG number_blocks,
 ULONG lba, ULONG *media_status)
{
 UINT status = UX_SUCCESS;

 /* USER CODE BEGIN USBD_STORAGE_Flush */
 UX_PARAMETER_NOT_USED(storage_instance);
 UX_PARAMETER_NOT_USED(lun);
 UX_PARAMETER_NOT_USED(number_blocks);
 UX_PARAMETER_NOT_USED(lba);
 UX_PARAMETER_NOT_USED(media_status);
 // status = UX_ERROR;

 /* USER CODE END USBD_STORAGE_Flush */

 return status;
}

/**
 * @brief USBD_STORAGE_Status
 * This function is invoked to obtain the status of the device.
 * @PAram storage_instance : Pointer to the storage class instance.
 * @PAram lun: Logical unit number is the command is directed to.
 * @PAram media_id: is not currently used.
 * @PAram media_status: should be filled out exactly like the media status
 * callback return value.
 * @retval status
 */
UINT USBD_STORAGE_Status(VOID *storage_instance, ULONG lun, ULONG media_id,
 ULONG *media_status)
{
 UINT status = UX_SUCCESS;

 /* USER CODE BEGIN USBD_STORAGE_Status */
 UX_PARAMETER_NOT_USED(storage_instance);
 UX_PARAMETER_NOT_USED(lun);
 UX_PARAMETER_NOT_USED(media_id);
 UX_PARAMETER_NOT_USED(media_status);
 // status = UX_ERROR;

 /* USER CODE END USBD_STORAGE_Status */

 return status;
}

/**
 * @brief USBD_STORAGE_Notification
 * This function is invoked to obtain the notification of the device.
 * @PAram storage_instance : Pointer to the storage class instance.
 * @PAram lun: Logical unit number is the command is directed to.
 * @PAram media_id: is not currently used.
 * @PAram notification_class: specifies the class of notification.
 * @PAram media_notification: response for the notification.
 * @PAram media_notification_length: length of the response buffer.
 * @retval status
 */
UINT USBD_STORAGE_Notification(VOID *storage_instance, ULONG lun, ULONG media_id,
 ULONG notification_class, UCHAR **media_notification,
 ULONG *media_notification_length)
{
 UINT status = UX_SUCCESS;

 /* USER CODE BEGIN USBD_STORAGE_Notification */
 UX_PARAMETER_NOT_USED(storage_instance);
 UX_PARAMETER_NOT_USED(lun);
 UX_PARAMETER_NOT_USED(media_id);
 UX_PARAMETER_NOT_USED(notification_class);
 UX_PARAMETER_NOT_USED(media_notification);
 UX_PARAMETER_NOT_USED(media_notification_length);
 // status = UX_ERROR;

 /* USER CODE END USBD_STORAGE_Notification */

 return status;
}

/**
 * @brief USBD_STORAGE_GetMediaLastLba
 * Get Media last LBA.
 * @PAram none
 * @retval last lba
 */
ULONG USBD_STORAGE_GetMediaLastLba(VOID)
{
 ULONG LastLba = 0U;

 /* USER CODE BEGIN USBD_STORAGE_GetMediaLastLba */
 LastLba = (ULONG)(sd_info.BlockNbr - 1);
 /* USER CODE END USBD_STORAGE_GetMediaLastLba */

 return LastLba;
}

/**
 * @brief USBD_STORAGE_GetMediaBlocklength
 * Get Media block length.
 * @PAram none.
 * @retval block length.
 */
ULONG USBD_STORAGE_GetMediaBlocklength(VOID)
{
 ULONG MediaBlockLen = 0U;

 /* USER CODE BEGIN USBD_STORAGE_GetMediaBlocklength */
 MediaBlockLen = (ULONG) sd_info.BlockSize;
 /* USER CODE END USBD_STORAGE_GetMediaBlocklength */

 return MediaBlockLen;
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

 

    This topic has been closed for replies.

    3 replies

    Technical Moderator
    July 8, 2024

    Hi @bangjinyoung 

    filex_media_open() is not a standard function in the FileX stack or ST's stack. Instead, it seems to be a custom function. Could you provide more details about the function definition?

    Visitor II
    July 8, 2024

    oh, i'm sorry. fx_media_open () is correct. I added the code below~

    Super User
    July 9, 2024

    One sorry is enough.. :)

     

    > USBX MSC cannot be used when using filex_media_open().

    In your code i see open for sd-card and nor-flash - so what about the usb problem ?

     

    Super User
    July 8, 2024

    >USBX MSC cannot be used when using filex_media_open()

    -- you mean:   fx_media_open(..) ?

    Visitor II
    July 8, 2024

    oh, i'm sorry. fx_media_open () is correct. I added the code below.

    Visitor II
    July 8, 2024

    oh, i'm sorry fx_media_open() is right

    void fx_app_thread_entry(ULONG thread_input)
     {
    
     UINT sd_status = FX_SUCCESS;
    
     UINT nor_ospi_status = FX_SUCCESS;
    
    /* USER CODE BEGIN fx_app_thread_entry 0*/
    
    /* USER CODE END fx_app_thread_entry 0*/
    
    /* Open the SD disk driver */
     sd_status = fx_media_open(&sdio_disk, FX_SD_VOLUME_NAME, fx_stm32_sd_driver, (VOID *)FX_NULL, (VOID *) fx_sd_media_memory, sizeof(fx_sd_media_memory));
    
    // /* Check the media open sd_status */
     if (sd_status != FX_SUCCESS)
     {
     /* USER CODE BEGIN SD DRIVER get info error */
     while(1);
     /* USER CODE END SD DRIVER get info error */
     }
    
     /* Open the OCTO-SPI NOR driver */
     nor_ospi_status = fx_media_open(&nor_ospi_flash_disk, FX_NOR_OSPI_VOLUME_NAME, fx_stm32_levelx_nor_driver, (VOID *)LX_NOR_OSPI_DRIVER_ID, (VOID *) fx_nor_ospi_media_memory, sizeof(fx_nor_ospi_media_memory));
    
    /* Check the media open nor_ospi_status */
     if (nor_ospi_status != FX_SUCCESS)
     {
     /* USER CODE BEGIN OCTO-SPI NOR open error */
     while(1);
     /* USER CODE END OCTO-SPI NOR open error */
     }
    
    /* USER CODE BEGIN fx_app_thread_entry 1*/
     UINT status;
     CHAR entry_name[256];
     UINT attributes;
     ULONG size;
     UINT year;
     UINT month;
     UINT day;
     UINT hour;
     UINT minute;
     UINT second;
    
     /* Get the next directory entry in the default directory with full information. */
     printf("nor flash disk directory:\n");
     do {
     status = fx_directory_next_full_entry_find(&nor_ospi_flash_disk, entry_name, &attributes, &size,
     &year, &month, &day,
     &hour, &minute, &second);
     if (status == FX_SUCCESS) {
     /* Process the directory entry. */
     printf("File: %s, Size: %lu, Date: %02u/%02u/%04u, Time: %02u:%02u:%02u\n",
     entry_name, size, day, month, year, hour, minute, second);
     }
     } while (status == FX_SUCCESS);
    
     /* Get the next directory entry in the default directory with full information. */
     printf("sd disk directory:\n");
     do {
     status = fx_directory_next_full_entry_find(&sdio_disk, entry_name, &attributes, &size,
     &year, &month, &day,
     &hour, &minute, &second);
     if (status == FX_SUCCESS) {
     /* Process the directory entry. */
     printf("File: %s, Size: %lu, Date: %02u/%02u/%04u, Time: %02u:%02u:%02u\n",
     entry_name, size, day, month, year, hour, minute, second);
     }
     } while (status == FX_SUCCESS);
    
     status = fx_media_close(&sdio_disk);
     if (status) {
     printf("Failed to close sd disk: %x\n", status);
     }
    
    /* USER CODE END fx_app_thread_entry 1*/
     }