Can't open my flash memory on Windows
Hello,
I am trying to set up an external flash memory (MX25V1635F) on a Nucleo-U575ZI-Q.
I have successfully used the low-level drivers (LLD) from the manufacturer Macronix and integrated them into the Levelx functions. (more info : https://community.st.com/t5/stm32-mcus-embedded-software/difficulties-using-fx-media-format/td-p/845435 )
Also, i use FileX to formand open my media, and it seems to work :
UINT ret = FX_SUCCESS;
/* USER CODE BEGIN MX_FileX_Init */
lx_stm32_nor_custom_driver_initialize(&nor_flash);
/* USER CODE END MX_FileX_Init */
/* Initialize FileX. */
fx_system_initialize();
/* USER CODE BEGIN MX_FileX_Init 1*/
/* Format the NOR flash as FAT */
status = fx_media_format(&nor_flash_disk,
fx_stm32_levelx_nor_driver, // Driver entry
(VOID*)NOR_CUSTOM_DRIVER_ID, // Device info pointer
(UCHAR*)media_memory, // Media buffer pointer
sizeof(media_memory), // Media buffer size
"NOR_FLASH_DISK", // Volume Name
1, // Number of FATs
32, // Directory Entries
0, // Hidden sectors
TOTAL_SECTOR_LOGICAL, // Total sectors
SECTOR_SIZE_LOGICAL, // Sector size
8, // Sectors per cluster
1, // Heads
1); // Sectors per track
/* Check if the format status */
if (status != FX_SUCCESS)
{
Error_Handler();
}
/* Open the SPI NOR Flash disk driver. */
status = fx_media_open(&nor_flash_disk, "FX_LX_NOR_DISK", fx_stm32_levelx_nor_driver,(VOID*)NOR_CUSTOM_DRIVER_ID , media_memory, sizeof(media_memory));
/* Check the media open status. */
if (status != FX_SUCCESS)
{
Error_Handler();
}
I'm using USBX as Device and MSC :
UINT MX_USBX_Device_Init(VOID)
{
UINT ret = UX_SUCCESS;
UCHAR *device_framework_high_speed;
UCHAR *device_framework_full_speed;
ULONG device_framework_hs_length;
ULONG device_framework_fs_length;
ULONG string_framework_length;
ULONG language_id_framework_length;
UCHAR *string_framework;
UCHAR *language_id_framework;
UCHAR *pointer;
/* USER CODE BEGIN MX_USBX_Device_Init0 */
/* USER CODE END MX_USBX_Device_Init0 */
pointer = ux_device_byte_pool_buffer;
/* Initialize USBX Memory */
if (ux_system_initialize(pointer, USBX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0) != UX_SUCCESS)
{
/* USER CODE BEGIN USBX_SYSTEM_INITIALIZE_ERROR */
return UX_ERROR;
/* USER CODE END USBX_SYSTEM_INITIALIZE_ERROR */
}
/* Get Device Framework High Speed and get the length */
device_framework_high_speed = USBD_Get_Device_Framework_Speed(USBD_HIGH_SPEED,
&device_framework_hs_length);
/* Get Device Framework Full Speed and get the length */
device_framework_full_speed = USBD_Get_Device_Framework_Speed(USBD_FULL_SPEED,
&device_framework_fs_length);
/* Get String Framework and get the length */
string_framework = USBD_Get_String_Framework(&string_framework_length);
/* Get Language Id Framework and get the length */
language_id_framework = USBD_Get_Language_Id_Framework(&language_id_framework_length);
/* Install the device portion of USBX */
if (ux_device_stack_initialize(device_framework_high_speed,
device_framework_hs_length,
device_framework_full_speed,
device_framework_fs_length,
string_framework,
string_framework_length,
language_id_framework,
language_id_framework_length,
UX_NULL) != UX_SUCCESS)
{
/* USER CODE BEGIN USBX_DEVICE_INITIALIZE_ERROR */
return UX_ERROR;
/* USER CODE END USBX_DEVICE_INITIALIZE_ERROR */
}
/* Initialize the storage class parameters for the device */
storage_parameter.ux_slave_class_storage_instance_activate = USBD_STORAGE_Activate;
storage_parameter.ux_slave_class_storage_instance_deactivate = USBD_STORAGE_Deactivate;
/* Store the number of LUN in this device storage instance */
storage_parameter.ux_slave_class_storage_parameter_number_lun = STORAGE_NUMBER_LUN;
/* Initialize the storage class parameters for reading/writing to the Flash Disk */
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_last_lba = USBD_STORAGE_GetMediaLastLba();
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_block_length = USBD_STORAGE_GetMediaBlocklength();
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_removable_flag = STORAGE_REMOVABLE_FLAG;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_read_only_flag = STORAGE_READ_ONLY;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_read = USBD_STORAGE_Read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_write = USBD_STORAGE_Write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_flush = USBD_STORAGE_Flush;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_status = USBD_STORAGE_Status;
storage_parameter.ux_slave_class_storage_parameter_lun[0].
ux_slave_class_storage_media_notification = USBD_STORAGE_Notification;
/* USER CODE BEGIN STORAGE_PARAMETER */
/* USER CODE END STORAGE_PARAMETER */
/* Get storage configuration number */
storage_configuration_number = USBD_Get_Configuration_Number(CLASS_TYPE_MSC, 0);
/* Find storage interface number */
storage_interface_number = USBD_Get_Interface_Number(CLASS_TYPE_MSC, 0);
/* Initialize the device storage class */
if (ux_device_stack_class_register(_ux_system_slave_class_storage_name,
ux_device_class_storage_entry,
storage_configuration_number,
storage_interface_number,
&storage_parameter) != UX_SUCCESS)
{
/* USER CODE BEGIN USBX_DEVICE_STORAGE_REGISTER_ERROR */
return UX_ERROR;
/* USER CODE END USBX_DEVICE_STORAGE_REGISTER_ERROR */
}
/* USER CODE BEGIN MX_USBX_Device_Init1 */
MX_USB_OTG_FS_PCD_Init();
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, USBD_MAX_EP0_SIZE / 4);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, USBD_MSC_EPIN_FS_MPS / 2);
if(ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS) != UX_SUCCESS)
{
Error_Handler();
}
HAL_PCD_Start(&hpcd_USB_OTG_FS);
/* USER CODE END MX_USBX_Device_Init1 */
return ret;
}
And i'm using this function for MSC :
VOID USBD_STORAGE_Activate(VOID *storage_instance)
{
/* USER CODE BEGIN USBD_STORAGE_Activate */
UX_PARAMETER_NOT_USED(storage_instance);
/* 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_Deactivate */
UX_PARAMETER_NOT_USED(storage_instance);
/* USER CODE END USBD_STORAGE_Deactivate */
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 */
UINT fx_status;
UX_PARAMETER_NOT_USED(storage_instance);
UX_PARAMETER_NOT_USED(lun);
UX_PARAMETER_NOT_USED(media_status);
for (ULONG i = 0; i < number_blocks; i++)
{
fx_status = fx_media_read(&nor_flash_disk, lba + i, data_pointer + (i * SECTOR_SIZE_LOGICAL));
if (fx_status != FX_SUCCESS)
{
status = UX_ERROR;
break;
}
}
/* 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 */
UINT fx_status;
UX_PARAMETER_NOT_USED(storage_instance);
UX_PARAMETER_NOT_USED(lun);
UX_PARAMETER_NOT_USED(media_status);
for (ULONG i = 0; i < number_blocks; i++)
{
fx_status = fx_media_write(&nor_flash_disk,
lba + i,
data_pointer + (i * SECTOR_SIZE_LOGICAL));
if (fx_status != FX_SUCCESS)
{
status = UX_ERROR;
break;
}
}
/* 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);
fx_media_flush(&nor_flash_disk);
/* 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);
*media_status = UX_SUCCESS;
/* 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);
/* 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 = TOTAL_SECTOR_LOGICAL - 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 = SECTOR_SIZE_LOGICAL;
/* USER CODE END USBD_STORAGE_GetMediaBlocklength */
return MediaBlockLen;
}
Windows see my disk but can't mount the volume :



When windows see my USB Device, it wants to format it (but i use FileX to format it in my code, so windows don't see it i think) :


And it says that windows cannot format the disk :

Do you have any suggestions ?
