STM32H750VB_Bootloader/USB_DEVICE/App/usbd_dfu_if.c

291 lines
7.3 KiB
C

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_dfu_if.c
* @brief : Usb device for Download Firmware Update.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* 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****/