基于STM32CubeMX SDIO DMA + FATFS

在此基础增加MSC大容量存储。

 

软件架构框图

FATFS及MSC共用SDIO接口。

 

 

 

USB配置

参数均默认。

中断配置

这里特别注意,sdio的dma中断优先级需要高于usb global中断,因为usb发送接收回调均在global中断中实现,如果global中断优先级更高将导致sdio dma中断无法抢占,以致于一直处于busy状态。

如果使用了freertos,配置如下:

 

代码修改

修改USB_DEVICE\App\usbd_storage_if.c,实现SDIO调用接口。

1. 包含头文件:#include "sdio.h"

2.实现STORAGE_GetCapacity_FS函数:

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
  HAL_SD_CardInfoTypeDef info;
  if (HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER)
  {
      HAL_SD_GetCardInfo(&hsd, &info);
      *block_num = info.LogBlockNbr;
      *block_size = info.LogBlockSize;
      return USBD_OK;
  }
  return USBD_FAIL;
  /* USER CODE END 3 */
}

3.实现STORAGE_Read_FS函数:

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);
  UNUSED(buf);
  UNUSED(blk_addr);
  UNUSED(blk_len);
  int8_t ret = USBD_FAIL;
  //if (HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK)
  if(HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK)
  {
      ret = USBD_OK;
      while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY)
          ;
      while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
          ;
  }
  return ret;
  /* USER CODE END 6 */
}

4.实现STORAGE_Write_FS函数:

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);
  UNUSED(buf);
  UNUSED(blk_addr);
  UNUSED(blk_len);
  int8_t ret = USBD_FAIL;
//  if (HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK)
  if(HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK)
  {
      ret = USBD_OK;
      while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY)
          ;
      while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
          ;
  }
  return ret;
  /* USER CODE END 7 */
}