STM_ATEM/USB_DEVICE/App/usbd_storage_if.c
zhoujie fee2e96eaa feat(system): 优化系统性能并简化监控模块
- 新增VSCode编辑器配置,启用保存时自动格式化
- 新增DMA2_Stream5和USART1中断处理函数,优化SPI传输性能
- 移除TIM1相关配置和性能监控模块,简化系统架构
- 优化GPIO配置,将ADC_SYNC和PA8引脚合并配置
- 简化系统监控模块,仅保留采样计数和数据溢出统计
- 优化SPI配置,使用16位数据宽度并提高DMA优先级
- 提高USART波特率(USART1:2Mbps, USART3:921600bps)
- 优化LTC2508驱动,增加初始化状态检查和缓冲区大小
- 修正数据存储模块,使用校正数据包而非校正结果结构体
- 优化RS485驱动,使用中断传输并添加传输完成回调
- 更新IOC配置文件,移除TIM1并调整中断优先级配置
- 新增系统监控简化说明文档,详细记录架构变更
2026-02-06 22:45:25 +08:00

364 lines
8.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbd_storage_if.c
* @version : v1.0_Cube
* @brief : Memory management layer.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "usbd_storage_if.h"
/* USER CODE BEGIN INCLUDE */
#include "fatfs.h"
#include "ff.h"
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
extern SD_HandleTypeDef hsd;
extern FATFS SDFatFS;
extern char SDPath[4];
static uint8_t sd_initialized = 0;
/* USER CODE END PV */
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @brief Usb device.
* @{
*/
/** @defgroup USBD_STORAGE
* @brief Usb mass storage device module
* @{
*/
/** @defgroup USBD_STORAGE_Private_TypesDefinitions
* @brief Private types.
* @{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* @}
*/
/** @defgroup USBD_STORAGE_Private_Defines
* @brief Private defines.
* @{
*/
#define STORAGE_LUN_NBR 1
#define STORAGE_BLK_NBR 0x10000
#define STORAGE_BLK_SIZ 0x200
/* USER CODE BEGIN PRIVATE_DEFINES */
/* USER CODE END PRIVATE_DEFINES */
/**
* @}
*/
/** @defgroup USBD_STORAGE_Private_Macros
* @brief Private macros.
* @{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* @}
*/
/** @defgroup USBD_STORAGE_Private_Variables
* @brief Private variables.
* @{
*/
/* USER CODE BEGIN INQUIRY_DATA_FS */
/** USB Mass storage Standard Inquiry Data. */
const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */
/* LUN 0 */
0x00,
0x80,
0x02,
0x02,
(STANDARD_INQUIRY_DATA_LEN - 5),
0x00,
0x00,
0x00,
'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
'0', '.', '0' ,'1' /* Version : 4 Bytes */
};
/* USER CODE END INQUIRY_DATA_FS */
/* USER CODE BEGIN PRIVATE_VARIABLES */
/* USER CODE END PRIVATE_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_STORAGE_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* @}
*/
/** @defgroup USBD_STORAGE_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t STORAGE_Init_FS(uint8_t lun);
static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
static int8_t STORAGE_IsReady_FS(uint8_t lun);
static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
static int8_t STORAGE_GetMaxLun_FS(void);
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
/**
* @}
*/
USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
{
STORAGE_Init_FS,
STORAGE_GetCapacity_FS,
STORAGE_IsReady_FS,
STORAGE_IsWriteProtected_FS,
STORAGE_Read_FS,
STORAGE_Write_FS,
STORAGE_GetMaxLun_FS,
(int8_t *)STORAGE_Inquirydata_FS
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the storage unit (medium) over USB FS IP
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Init_FS(uint8_t lun)
{
/* USER CODE BEGIN 2 */
UNUSED(lun);
// 1. 检查 SD 句柄状态
// 如果之前在 main.c 里已经 HAL_SD_Init 过了,这里只要确认状态即可
HAL_SD_StateTypeDef state = HAL_SD_GetState(&hsd);
if(state == HAL_SD_STATE_RESET)
{
// 只有在从未初始化的情况下才初始化
if (HAL_SD_Init(&hsd) != HAL_OK) {
return (USBD_FAIL);
}
}
// 2. 绝对不要在这里 f_mount 或 f_mkfs !!!
// USB 只是搬运工,文件系统由电脑端管理。
sd_initialized = 1;
return (USBD_OK);
/* USER CODE END 2 */
}
/**
* @brief Returns the medium capacity.
* @param lun: Logical unit number.
* @param block_num: Number of total block number.
* @param block_size: Block size.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
/* USER CODE BEGIN 3 */
UNUSED(lun);
HAL_SD_CardInfoTypeDef cardinfo;
if (HAL_SD_GetCardInfo(&hsd, &cardinfo) == HAL_OK)
{
// 修正 2: 欺骗电脑,强制报告 512 字节扇区
*block_size = 512;
if (cardinfo.LogBlockSize == 512) {
*block_num = cardinfo.LogBlockNbr - 1;
}
else {
// 如果 SD NAND 是 2048/4096 字节页,需要转换块数量
// 例如:实际 4096那 USB 看到的块数就是 实际块数 * 8
uint32_t ratio = cardinfo.LogBlockSize / 512;
*block_num = (cardinfo.LogBlockNbr * ratio) - 1;
}
return (USBD_OK);
}
return (USBD_FAIL);
/* USER CODE END 3 */
}
/**
* @brief Checks whether the medium is ready.
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_IsReady_FS(uint8_t lun)
{
/* USER CODE BEGIN 4 */
UNUSED(lun);
// 简单检查硬件状态
if (hsd.State == HAL_SD_STATE_RESET) {
return (USBD_FAIL);
}
// 对于 SD NAND即使内部 BUSY为了不让 USB 掉线,通常也返回 OK
// 实际的等待放到 Read/Write 函数里去做
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief Checks whether the medium is write protected.
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
{
/* USER CODE BEGIN 5 */
UNUSED(lun);
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Reads data from the medium.
* @param lun: Logical unit number.
* @param buf: data buffer.
* @param blk_addr: Logical block address.
* @param blk_len: Blocks number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
UNUSED(lun);
// 使用较长的超时时间 (SD NAND 读写较慢)
uint32_t timeout = 2000;
if (HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, timeout) != HAL_OK) {
return (USBD_FAIL);
}
// 等待传输完成 (重要: 确保 DMA/中断搬运完毕)
uint32_t tickstart = HAL_GetTick();
while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
{
if((HAL_GetTick() - tickstart) > timeout) return USBD_FAIL;
}
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief Writes data into the medium.
* @param lun: Logical unit number.
* @param buf: data buffer.
* @param blk_addr: Logical block address.
* @param blk_len: Blocks number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 7 */
UNUSED(lun);
// 修正 3: 增加超时时间,并等待 Busy 结束
uint32_t timeout = 5000; // 给 5秒SD NAND 写入由于要擦除/编程,很慢
if (HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, timeout) != HAL_OK) {
return (USBD_FAIL);
}
// 【最关键的一步】等待 SD NAND 内部编程结束
// 如果没有这一步,文件就会丢失!
uint32_t tickstart = HAL_GetTick();
while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
{
if((HAL_GetTick() - tickstart) > timeout) return USBD_FAIL;
}
return (USBD_OK);
/* USER CODE END 7 */
}
/**
* @brief Returns the Max Supported LUNs.
* @param None
* @retval Lun(s) number.
*/
int8_t STORAGE_GetMaxLun_FS(void)
{
/* USER CODE BEGIN 8 */
return (STORAGE_LUN_NBR - 1);
/* USER CODE END 8 */
}
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
/**
* @}
*/
/**
* @}
*/