打印
[AT32 WorkBench]

AT32 WorkBench常用功能13—USB Device MSC

[复制链接]
1001|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 muyichuan2012 于 2024-8-15 17:25 编辑

AT32WorkBench常用功能 13
—USB Device MSC

AT32 WorkBench最新版下载地址:https://www.arterytek.com/file/download/1710

USB MSC工程建立
本文主要介绍如何基于AT32 WorkBench配置USB MSC
硬件环境
l  AT-START-F405
l  USB线缆

软件环境
l  AT32 Workbench
l  MDK5

配置步骤:
1.    打开AT32 WorkBench新建AT32F405RCT7工程

2.    在外设中打开USB_OTGHS1并选择设备,视情况选择是否勾选相关信号,本案例不勾选

3.    可以看到时钟配置菜单栏打了红叉  ,这是因为缺少12M外部晶振为OTGHS PHY提供时钟,所以需要在外设CRM中打开高速外部晶振。

4.    在中间件USB_DEVICE中选择OTGHS1设备类为MSC,HS设备描述符和端点FIFO可根据需要修改,本案例使用默认数值。

5.    点击生成代码,然后生成MDK_V5工程即可完成MSC基础工程的建立

6.    使用MDK_V5打开项目,修改msc_diskio.c和msc_diskio.h文件相关内容
6.1  在msc_diskio.c文件开头添加如下变量
  
/*  private variables ---------------------------------------------------------*/
  
/* add  user code begin private variables */
  
uint32_t sector_size = 2048;
  
uint32_t msc_flash_size;
  
/* add  user code end private variables */
  
6.2  修改msc_diskio.c文件的msc_disk_read(…)函数
  
usb_sts_type  msc_disk_read(uint8_t lun, uint64_t addr, uint8_t *read_buf, uint32_t len)
  
{
  
  /* add user code begin msc_disk_read 0 */
  
  
  /* add user code end msc_disk_read 0 */
  
  
//   switch(lun)
  
//  {
  
//    case  INTERNAL_FLASH_LUN:
  
//      break;
  
//    case  SPI_FLASH_LUN:
  
//      break;
  
//    case  SD_LUN:
  
//      break;
  
//    default:
  
//      break;
  
//  }
  
  
  /* add user code begin msc_disk_read 1 */
  
uint32_t i = 0;
  
  uint32_t  flash_addr = (uint32_t)addr + USB_FLASH_ADDR_OFFSET;
  
  switch(lun)
  
  {
  
    case  INTERNAL_FLASH_LUN:
  
      for(i =  0; i < len; i ++)
  
      {
  
         read_buf = *((uint8_t *)flash_addr);
  
         flash_addr += 1;
  
      }
  
      break;
  
    case SPI_FLASH_LUN:
  
      break;
  
    case  SD_LUN:
  
      break;
  
    default:
  
      break;
  
  }
  
  /* add user code end msc_disk_read 1 */
  
  
  return USB_OK;
  
}
  
6.3  修改msc_diskio.c文件的msc_disk_write(…)函数
  
usb_sts_type  msc_disk_write(uint8_t lun, uint64_t addr, uint8_t *buf, uint32_t len)
  
{
  
  /* add user code begin msc_disk_write 0 */
  
  
  /* add user code end msc_disk_write 0 */
  
  
//   switch(lun)
  
//  {
  
//    case  INTERNAL_FLASH_LUN:
  
//      break;
  
//    case  SPI_FLASH_LUN:
  
//      break;
  
//    case  SD_LUN:
  
//      break;
  
//    default:
  
//       break;;
  
//  }
  
  
  /* add user code begin msc_disk_write 1 */
  
uint32_t flash_addr = (uint32_t)addr + USB_FLASH_ADDR_OFFSET;
  
  uint32_t i =  0, tolen = len;
  
  uint32_t  erase_addr = flash_addr;
  
  switch(lun)
  
  {
  
    case  INTERNAL_FLASH_LUN:
  
       flash_unlock();
  
       while(tolen >= sector_size)
  
      {
  
         flash_sector_erase(erase_addr);
  
        tolen  -= sector_size;
  
         erase_addr += sector_size;
  
      }
  
      for(i =  0; i < len; i ++)
  
      {
  
         flash_byte_program(flash_addr+i, buf);
  
      }
  
       flash_lock();
  
      break;
  
    case  SPI_FLASH_LUN:
  
      break;
  
    case  SD_LUN:
  
      break;
  
    default:
  
      break;;
  
  }
  
  /* add user code end msc_disk_write 1 */
  
  
  return USB_OK;
  
}
  
6.4  修改msc_diskio.c文件的msc_disk_capacity (…)函数
  
usb_sts_type  msc_disk_capacity(uint8_t lun, uint32_t *blk_nbr, uint32_t *blk_size)
  
{
  
  /* add user code begin msc_disk_capacity 0  */
  
  
  /* add user code end msc_disk_capacity 0 */
  
  
//   switch(lun)
  
//  {
  
//    case  INTERNAL_FLASH_LUN:
  
//      break;
  
//    case  SPI_FLASH_LUN:
  
//      break;
  
//    case  SD_LUN:
  
//      break;
  
//    default:
  
//      break;
  
//  }
  
  
  /* add user code begin msc_disk_capacity 1  */
  
  uint32_t  devid = (*((uint32_t *)DEBUG_BASE) & 0x00007000) >> 12;
  
   msc_flash_size = (*((uint32_t *)0x1FFFF7E0) << 10) -  (USB_FLASH_ADDR_OFFSET - FLASH_BASE);
  
   switch(devid)
  
  {
  
    case 2:
  
       sector_size = SECTOR_SIZE_1K;
  
      break;
  
    case 3:
  
       sector_size = SECTOR_SIZE_2K;
  
      break;
  
    case 4:
  
      sector_size  = SECTOR_SIZE_4K;
  
      break;
  
    default:
  
       sector_size = SECTOR_SIZE_2K;
  
      break;
  
  }
  
  switch(lun)
  
  {
  
    case  INTERNAL_FLASH_LUN:
  
      *blk_nbr  = msc_flash_size / sector_size;
  
       *blk_size = sector_size;
  
      break;
  
    case  SPI_FLASH_LUN:
  
      break;
  
    case  SD_LUN:
  
      break;
  
    default:
  
      break;
  
  }
  
  /* add user code end msc_disk_capacity 1 */
  
  
  return USB_OK;
  
}
  
6.5  在msc_diskio.h文件增加如下宏定义,然后编译并下载到开发板
  
/*  private define ------------------------------------------------------------*/
  
/* add  user code begin private define */
  
#define USB_FLASH_ADDR_OFFSET            0x08005000
  
#define SECTOR_SIZE_1K                   1024
  
#define SECTOR_SIZE_2K                   2048
  
#define SECTOR_SIZE_4K                   4096
  
/* add  user code end private define */
  


7.    将开发板HS_Device口连接到PC并复位,可以观察到PC识别到U盘,查看设备管理器可以看到新增的MSC设备

注意:对于USB_OTGFS来说,步骤相似,但可以不开启12M高速外部时钟,且输入到OTGFS控制器的时钟必须是48MHz。若选择hick to usbfs则可以解锁外设AAC功能,可以在AT32 WorkBench时钟配置界面进行确认。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

197

主题

1909

帖子

29

粉丝