/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file app_usbx_device.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 "app_usbx_device.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "app_filex.h" #include "usb.h" /* USER CODE END Includes */ /* 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 */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ static ULONG storage_interface_number; static ULONG storage_configuration_number; static UX_SLAVE_CLASS_STORAGE_PARAMETER storage_parameter; static TX_THREAD ux_device_app_thread; /* USER CODE BEGIN PV */ FX_MEDIA NOR_W25Q; ALIGN_32BYTES (uint32_t fx_nor_qspi_media_memory[FX_NOR_QSPI_SECTOR_SIZE / sizeof(uint32_t)]); extern PCD_HandleTypeDef hpcd_USB_DRD_FS; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ static VOID app_ux_device_thread_entry(ULONG thread_input); static UINT USBD_ChangeFunction(ULONG Device_State); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /** * @brief Application USBX Device Initialization. * @param memory_ptr: memory pointer * @retval status */ UINT MX_USBX_Device_Init(VOID *memory_ptr) { 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; TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr; /* USER CODE BEGIN MX_USBX_Device_Init0 */ /* USER CODE END MX_USBX_Device_Init0 */ /* Allocate the stack for USBX Memory */ if (tx_byte_allocate(byte_pool, (VOID **) &pointer, USBX_DEVICE_MEMORY_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS) { /* USER CODE BEGIN USBX_ALLOCATE_STACK_ERROR */ return TX_POOL_ERROR; /* USER CODE END USBX_ALLOCATE_STACK_ERROR */ } /* 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, USBD_ChangeFunction) != 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 */ } /* Allocate the stack for device application main thread */ if (tx_byte_allocate(byte_pool, (VOID **) &pointer, UX_DEVICE_APP_THREAD_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS) { /* USER CODE BEGIN MAIN_THREAD_ALLOCATE_STACK_ERROR */ return TX_POOL_ERROR; /* USER CODE END MAIN_THREAD_ALLOCATE_STACK_ERROR */ } /* Create the device application main thread */ if (tx_thread_create(&ux_device_app_thread, UX_DEVICE_APP_THREAD_NAME, app_ux_device_thread_entry, 0, pointer, UX_DEVICE_APP_THREAD_STACK_SIZE, UX_DEVICE_APP_THREAD_PRIO, UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD, UX_DEVICE_APP_THREAD_TIME_SLICE, UX_DEVICE_APP_THREAD_START_OPTION) != TX_SUCCESS) { /* USER CODE BEGIN MAIN_THREAD_CREATE_ERROR */ return TX_THREAD_ERROR; /* USER CODE END MAIN_THREAD_CREATE_ERROR */ } /* USER CODE BEGIN MX_USBX_Device_Init1 */ /* USER CODE END MX_USBX_Device_Init1 */ return ret; } /** * @brief Function implementing app_ux_device_thread_entry. * @param thread_input: User thread input parameter. * @retval none */ static VOID app_ux_device_thread_entry(ULONG thread_input) { /* USER CODE BEGIN app_ux_device_thread_entry */ TX_PARAMETER_NOT_USED(thread_input); UINT MEDIA_STATUS = FX_SUCCESS; MEDIA_STATUS = fx_media_format(&NOR_W25Q, // nor_qspi_flash_disk pointer fx_stm32_levelx_nor_driver, // Driver entry (VOID *)NOR_CUSTOM_DRIVER_ID, // Device info pointer (UCHAR *) fx_nor_qspi_media_memory, // Media buffer pointer sizeof(fx_nor_qspi_media_memory), // Media buffer size FX_NOR_W25Q_VOLUME_NAME, // Volume Name FX_NOR_W25Q_NUMBER_OF_FATS, // Number of FATs 1 32, // Directory Entries 32 FX_NOR_W25Q_HIDDEN_SECTORS, // Hidden sectors 0 (LX_STM32_W25Q_FLASH_SIZE - LX_STM32_W25Q_SECTOR_SIZE) / FX_NOR_QSPI_SECTOR_SIZE, // Total sectors 8160 FX_NOR_QSPI_SECTOR_SIZE, // Sector size 2048 8, // Sectors per cluster 1, // Heads 1); // Sectors per track if(MEDIA_STATUS != FX_SUCCESS) { Error_Handler(); } MEDIA_STATUS = fx_media_open(&NOR_W25Q, FX_NOR_W25Q_VOLUME_NAME, fx_stm32_levelx_nor_driver, (VOID *)NOR_CUSTOM_DRIVER_ID, (VOID *) fx_nor_qspi_media_memory, sizeof(fx_nor_qspi_media_memory)); if(MEDIA_STATUS != FX_SUCCESS) { Error_Handler(); } tx_thread_sleep(100); HAL_PWREx_EnableVddUSB(); /* USB_DRD_FS init function */ MX_USB_PCD_Init(); /*USB packet memory area configuration*/ HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x00, PCD_SNG_BUF, 0x14); HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, 0x80, PCD_SNG_BUF, 0x54); HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, USBD_MSC_EPOUT_ADDR, PCD_SNG_BUF, 0x94); HAL_PCDEx_PMAConfig(&hpcd_USB_DRD_FS, USBD_MSC_EPIN_ADDR, PCD_SNG_BUF, 0xD4); /* initialize the device controller driver*/ ux_dcd_stm32_initialize((ULONG) USB_DRD_FS, (ULONG) &hpcd_USB_DRD_FS); /* Start device USB */ HAL_PCD_Start(&hpcd_USB_DRD_FS); tx_thread_relinquish(); /* USER CODE END app_ux_device_thread_entry */ } /** * @brief USBD_ChangeFunction * This function is called when the device state changes. * @param Device_State: USB Device State * @retval status */ static UINT USBD_ChangeFunction(ULONG Device_State) { UINT status = UX_SUCCESS; /* USER CODE BEGIN USBD_ChangeFunction0 */ /* USER CODE END USBD_ChangeFunction0 */ switch (Device_State) { case UX_DEVICE_ATTACHED: /* USER CODE BEGIN UX_DEVICE_ATTACHED */ /* USER CODE END UX_DEVICE_ATTACHED */ break; case UX_DEVICE_REMOVED: /* USER CODE BEGIN UX_DEVICE_REMOVED */ /* USER CODE END UX_DEVICE_REMOVED */ break; case UX_DCD_STM32_DEVICE_CONNECTED: /* USER CODE BEGIN UX_DCD_STM32_DEVICE_CONNECTED */ /* USER CODE END UX_DCD_STM32_DEVICE_CONNECTED */ break; case UX_DCD_STM32_DEVICE_DISCONNECTED: /* USER CODE BEGIN UX_DCD_STM32_DEVICE_DISCONNECTED */ /* USER CODE END UX_DCD_STM32_DEVICE_DISCONNECTED */ break; case UX_DCD_STM32_DEVICE_SUSPENDED: /* USER CODE BEGIN UX_DCD_STM32_DEVICE_SUSPENDED */ /* USER CODE END UX_DCD_STM32_DEVICE_SUSPENDED */ break; case UX_DCD_STM32_DEVICE_RESUMED: /* USER CODE BEGIN UX_DCD_STM32_DEVICE_RESUMED */ /* USER CODE END UX_DCD_STM32_DEVICE_RESUMED */ break; case UX_DCD_STM32_SOF_RECEIVED: /* USER CODE BEGIN UX_DCD_STM32_SOF_RECEIVED */ /* USER CODE END UX_DCD_STM32_SOF_RECEIVED */ break; default: /* USER CODE BEGIN DEFAULT */ /* USER CODE END DEFAULT */ break; } /* USER CODE BEGIN USBD_ChangeFunction1 */ /* USER CODE END USBD_ChangeFunction1 */ return status; } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */