/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : usbd_dfu_if.c * @brief : Usb device for Download Firmware Update. ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "usbd_dfu_if.h" /* USER CODE BEGIN INCLUDE */ #include "w25_qspi.h" #include "printf.h" #include "pin_config.h" /* USER CODE END INCLUDE */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY * @brief Usb device. * @{ */ /** @defgroup USBD_DFU * @brief Usb DFU device module. * @{ */ /** @defgroup USBD_DFU_Private_TypesDefinitions * @brief Private types. * @{ */ /* USER CODE BEGIN PRIVATE_TYPES */ /* USER CODE END PRIVATE_TYPES */ /** * @} */ /** @defgroup USBD_DFU_Private_Defines * @brief Private defines. * @{ */ #define FLASH_DESC_STR "@QSPI Flash/0x90000000/4096*4Kg" /* USER CODE BEGIN PRIVATE_DEFINES */ /* USER CODE END PRIVATE_DEFINES */ /** * @} */ /** @defgroup USBD_DFU_Private_Macros * @brief Private macros. * @{ */ /* USER CODE BEGIN PRIVATE_MACRO */ /* USER CODE END PRIVATE_MACRO */ /** * @} */ /** @defgroup USBD_DFU_Private_Variables * @brief Private variables. * @{ */ /* USER CODE BEGIN PRIVATE_VARIABLES */ extern QSPI_HandleTypeDef hqspi; w25_qspi_t w25_flash; /* USER CODE END PRIVATE_VARIABLES */ /** * @} */ /** @defgroup USBD_DFU_Exported_Variables * @brief Public variables. * @{ */ extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE BEGIN EXPORTED_VARIABLES */ /* USER CODE END EXPORTED_VARIABLES */ /** * @} */ /** @defgroup USBD_DFU_Private_FunctionPrototypes * @brief Private functions declaration. * @{ */ static uint16_t MEM_If_Init_FS(void); static uint16_t MEM_If_Erase_FS(uint32_t Add); static uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len); static uint8_t *MEM_If_Read_FS(uint8_t *src, uint8_t *dest, uint32_t Len); static uint16_t MEM_If_DeInit_FS(void); static uint16_t MEM_If_GetStatus_FS(uint32_t Add, uint8_t Cmd, uint8_t *buffer); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ /** * @} */ #if defined ( __ICCARM__ ) /* IAR Compiler */ #pragma data_alignment=4 #endif __ALIGN_BEGIN USBD_DFU_MediaTypeDef USBD_DFU_fops_FS __ALIGN_END = { (uint8_t*)FLASH_DESC_STR, MEM_If_Init_FS, MEM_If_DeInit_FS, MEM_If_Erase_FS, MEM_If_Write_FS, MEM_If_Read_FS, MEM_If_GetStatus_FS }; /* Private functions ---------------------------------------------------------*/ /** * @brief Memory initialization routine. * @retval USBD_OK if operation is successful, MAL_FAIL else. */ uint16_t MEM_If_Init_FS(void) { /* USER CODE BEGIN 0 */ w25_flash.interface = &hqspi; w25_flash.mode = W25_MODE_QUAD; w25_flash.address_size = W25_ADDRESS_24BITS; #if(USE_QPI_MODE == 1) W25_QPI_Mode(&w25_flash, 0); #endif // USE_QPI_MODE W25_QSPI_Init(&w25_flash); printf("MEM_If_Init_FS: Mfg: 0x%x\r\n", w25_flash.manufacturer); return (USBD_OK); /* USER CODE END 0 */ } /** * @brief De-Initializes Memory * @retval USBD_OK if operation is successful, MAL_FAIL else */ uint16_t MEM_If_DeInit_FS(void) { /* USER CODE BEGIN 1 */ return (USBD_OK); /* USER CODE END 1 */ } /** * @brief Erase sector. * @param Add: Address of sector to be erased. * @retval 0 if operation is successful, MAL_FAIL else. */ uint16_t MEM_If_Erase_FS(uint32_t Add) { /* USER CODE BEGIN 2 */ printf("Mem_If_Erase_FS: Add: 0x%08x\r\n", Add); W25_QSPI_Erase_Sector(&w25_flash, Add - 0x90000000); //HAL_Delay(100); return (USBD_OK); /* USER CODE END 2 */ } /** * @brief Memory write routine. * @param src: Pointer to the source buffer. Address to be written to. * @param dest: Pointer to the destination buffer. * @param Len: Number of data to be written (in bytes). * @retval USBD_OK if operation is successful, MAL_FAIL else. */ uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len) { /* USER CODE BEGIN 3 */ HAL_GPIO_TogglePin(LED_PORT, LED_PIN); printf("Mem_If_Write_FS: Add: 0x%08x Src: 0x%08x Len: 0x%08x 1St: 0x%02x\r\n", (uint32_t)dest, (uint32_t)src, Len, src[0]); uint8_t page_count = Len / 256; if(Len & 0xFFU) page_count++; for(uint8_t i = 0; i < page_count; i++) { uint32_t page_addr = (uint32_t)dest - 0x90000000 + 256 * i; printf("Mem_If_Write_FS: Pge: 0x%08x\r\n", page_addr); W25_QSPI_Program_Page(&w25_flash, page_addr, &src[256 * i]); } //HAL_Delay(10); return (USBD_OK); /* USER CODE END 3 */ } /** * @brief Memory read routine. * @param src: Pointer to the source buffer. Address to be written to. * @param dest: Pointer to the destination buffer. * @param Len: Number of data to be read (in bytes). * @retval Pointer to the physical address where data should be read. */ uint8_t *MEM_If_Read_FS(uint8_t *src, uint8_t *dest, uint32_t Len) { /* Return a valid address to avoid HardFault */ /* USER CODE BEGIN 4 */ HAL_GPIO_TogglePin(LED_PORT, LED_PIN); printf("Mem_If_Read_FS: Add: 0x%08x\r\n", (uint32_t)src); W25_QSPI_Read(&w25_flash, (uint32_t)src - 0x90000000, dest, Len); //HAL_Delay(100); return (uint8_t*)(USBD_OK); /* USER CODE END 4 */ } /** * @brief Get status routine * @param Add: Address to be read from * @param Cmd: Number of data to be read (in bytes) * @param buffer: used for returning the time necessary for a program or an erase operation * @retval USBD_OK if operation is successful */ uint16_t MEM_If_GetStatus_FS(uint32_t Add, uint8_t Cmd, uint8_t *buffer) { /* USER CODE BEGIN 5 */ switch (Cmd) { case DFU_MEDIA_PROGRAM: buffer[2] = 0; buffer[1] = 0x0A; buffer[0] = 0; break; case DFU_MEDIA_ERASE: buffer[2] = 0; buffer[1] = 0x64; buffer[0] = 0; default: break; } return (USBD_OK); /* USER CODE END 5 */ } /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/