logo
首页 产品中心 支付方式 联系我们
AVR32应用笔记 AVR32单片机笑傲江湖 AVR32 USB MASS STORAGE U盘应用

AVR32 USB MASS STORAGE U盘应用

以下资料由微雪电子整理并发布,未经许可不得转载,否则追究相应责任!

系统功能

  USB MASS STORAGE应用示例,将AVR32内部ROM,DATAFLASH,SD/MMC模拟成3个U盘。
  目标MCU为32UC3B0256,目标系统采用EVK3B开发板。


硬件设计

     关于AVR32的USB功能及相关介绍详见Datasheet,这里仅给出原理图。


电路原理图(点击图片放大,不需要放大镜!

软件设计

//建立好工程,导入相应的Software Framework
/* This source file is part of the ATMEL AVR32-SoftwareFramework-1.2.1ES-AT32UC3B Release */

/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Main file of the USB mass-storage example.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a USB module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/

/*! \mainpage AVR32 USB Software Framework for Mass Storage
*
* \section intro License
* Use of this program is subject to Atmel's End User License Agreement.
*
* Please read the \ref license at the bottom of this page.
*
* \section install Description
* This embedded application source code illustrates how to implement a USB mass-storage application
* on the AVR32 microcontroller.
*
* As the AVR32 implements a device/host USB controller, the embedded application can operate
* in one of the following USB operating modes:
* - USB device;
* - USB reduced-host controller;
* - USB dual-role device (depending on the ID pin). This is the default configuration used in this example.
*
*
* To optimize embedded code/RAM size and reduce the number of source modules, the application can be
* configured to use one and only one of these operating modes.
*
* \section sample About the Sample Application
* By default the sample code is delivered with a simple preconfigured dual-role USB application.
* It means that the code generated allows to operate as a device or a host depending on the USB ID pin:
*
* - Attached to a mini-B plug (ID pin unconnected) the application will be used in the device operating mode.
* Thus, the application can be connected to a system host (e.g. a PC) to operate as a USB mass-storage device (removable drive):
*
* \image html appli_evk1100_device.jpg "EVK1100 USB Device Mode"
* \image html appli_evk1101_device.jpg "EVK1101 USB Device Mode"
*
* - Attached to a mini-A plug (ID pin tied to ground) the application will operate in reduced-host mode.
* This mode allows to connect a USB mass-storage device:
*
* \image html appli_evk1100_host.jpg "EVK1100 USB Host Mode"
* \image html appli_evk1101_host.jpg "EVK1101 USB Host Mode"
*
* - In both modes, the application can be connected to a serial terminal (e.g. HyperTerminal under
* Windows systems or minicom under Linux systems; UART settings: 57600 bauds, 8-bit data, no parity bit,
* 1 stop bit, no flow control), from where the user can access a simple command line interpreter (uShell)
* to perform file-system accesses.
*
* \section device_use Using the USB Device Mode
* Connect the application to a USB mass-storage host (e.g. a PC) with a mini-B (embedded side) to A (PC host side) cable.
* The application will behave as a USB key. It will allow to access files on the on-board virtual, data flash and SD/MMC memories.
*
* \section host_use Using the USB Host Mode
* Connect the application to a USB mass-storage device (e.g. a USB key). The application will behave as a USB mass-storage
* reduced host. It will allow to exchange files between the on-board virtual, data flash and SD/MMC memories and the mass-storage device.
*
* \section uShell Using the USB Shell Terminal
* Connected to a serial terminal the uShell command line interpreter allows to:
* - access the file system (both on-board virtual, data flash and SD/MMC memories and connected USB mass-storage device):
* - disk: get the number of drives,
* - a:, b:, etc.: go to selected drive,
* - mount drivename (a, b, etc.): go to selected drive,
* - format drivename (a, b, etc.): format selected drive,
* - fat: get FAT type used by current drive,
* - df: get free space information for all connected drives,
* - cd dirname: go to selected directory,
* - cd..: go to upper directory,
* - mark: bookmark current directory,
* - goto: go to bookmarked directory,
* - ls: list files and directories in current directory,
* - rm filename: remove selected file or empty directory,
* - rm*: remove all files or empty directories in current directory,
* - cp filename: copy filename to bookmarked directory,
* - mv src_filename dst_filename: rename selected file,
* - mkdir dirname: make directory,
* - deltree dirname: remove directory and its content,
* - touch filename: create file,
* - append filename: append to selected file from terminal input,
* - cat filename: list file contents;
* - get information about the connected device and to perform miscellaneous commands:
* - lsusb: when in USB host mode, get USB information,
* - usbsync {device|host}: when in USB host mode, synchronize device or host USB drive,
* - suspend: when in USB host mode, suspend USB bus activity,
* - resume: when in USB host mode, resume USB bus activity,
* - reboot: reset the application,
* - help: get help about uShell commands.
*
* \section arch Architecture
* As illustrated in the figure below, the application entry point is located in the mass_storage_example.c file.
* The main function first performs the initialization of services and tasks and then runs them in an infinite loop.
*
* The sample mass-storage application is based on four different tasks:
* - The USB task (usb_task.c associated source file) is the task performing the USB low-level
* enumeration process in device or host mode. Once this task has detected that the USB connection is fully
* operational, it updates various status flags that can be checked within the high-level applicative tasks.
* - The device mass-storage task (device_mass_storage_task.c associated source file) performs
* SCSI bulk-only protocol decoding and flash memory accesses.
* - The host mass-storage task (host_mass_storage_task.c associated file) manages the connected
* device mass-storage interface by performing SCSI bulk-only protocol encoding and flash memory accesses.
* - The USB shell task (ushell_task.c associated file) manages the processing of terminal commands.
*
* \image html arch_full.jpg "Architecture Overview"
*
* \section config Configuration
* The sample application is configured to implement both host and device functionalities.
* Of course it can also be configured to be used only in device or reduced-host mode (see the conf_usb.h file).
* Depending on the USB operating mode selected, the USB task will call either the USB host task (usb_host_task.c),
* or the USB device task (usb_device_task.c) to manage USB specification chapter 9 requests.
*
* \section limitations Limitations
* Some mass-storage devices do not present directly a mass-storage-class
* interface, which may e.g. be hidden behind a hub-class device. These devices
* are not supported by this example and the current mass-storage software
* framework.
*
* \section contactinfo Contact Information
* For further information, visit
* <A href="http://www.atmel.com/products/AVR32/">Atmel AVR32</A>.\n
* Support and FAQ: http://support.atmel.no/
*
* \section license Copyright Notice
* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/

//_____ I N C L U D E S ___________________________________________________

#ifndef FREERTOS_USED
#if __GNUC__
#include <sys/cpu.h>
#endif
#else
#include <stdio.h>
#endif
#include "compiler.h"
#include "preprocessor.h"
#include "board.h"
#include "print_funcs.h"
#include "intc.h"
#include "pm.h"
#include "gpio.h"
#include "spi.h"
#include "ctrl_access.h"
#if AT45DBX_MEM == ENABLE
#include "conf_at45dbx.h"
#endif
#if SD_MMC_MEM == ENABLE
#include "conf_sd_mmc.h"
#endif
#ifdef FREERTOS_USED
#include "FreeRTOS.h"
#include "task.h"
#endif
#include "conf_usb.h"
#include "usb_task.h"
#if USB_DEVICE_FEATURE == ENABLED
#include "device_mass_storage_task.h"
#endif
#if USB_HOST_FEATURE == ENABLED
#include "host_mass_storage_task.h"
#endif
#include "ushell_task.h"

//_____ D E F I N I T I O N S ______________________________________________

#ifndef FREERTOS_USED

#if __GNUC__

/*! \brief Low-level initialization routine called during startup, before the
* main function.
*
* This version comes in replacement to the default one provided by Newlib.
* Newlib's _init_startup only calls init_exceptions, but Newlib's exception and
* interrupt vectors are defined in the same section and Newlib's interrupt
* vectors are not compatible with the interrupt management of the INTC module.
* More low-level initializations are besides added here.
*/
void _init_startup(void)
{
// Import the Exception Vector Base Address.
extern void _evba;

// Load the Exception Vector Base Address in the corresponding system register.
Set_system_register(AVR32_EVBA, (int)&_evba);

// Enable exceptions.
Enable_global_exception();

// Initialize interrupt handling.
INTC_init_interrupts();

// Give the used CPU clock frequency to Newlib, so it can work properly.
set_cpu_hz(FOSC0);
}

#elif __ICCAVR32__

/*! \brief Low-level initialization routine called during startup, before the
* main function.
*/
int __low_level_init(void)
{
// Enable exceptions.
Enable_global_exception();

// Initialize interrupt handling.
INTC_init_interrupts();

// Request initialization of data segments.
return 1;
}

#endif // Compiler

#endif // FREERTOS_USED

#if AT45DBX_MEM == ENABLE

/*! \brief Initializes AT45DBX resources: GPIO, SPI and AT45DBX.
*/
static void at45dbx_resources_init(void)
{
static const gpio_map_t AT45DBX_SPI_GPIO_MAP =
{
{AT45DBX_SPI_SCK_PIN, AT45DBX_SPI_SCK_FUNCTION }, // SPI Clock.
{AT45DBX_SPI_MISO_PIN, AT45DBX_SPI_MISO_FUNCTION }, // MISO.
{AT45DBX_SPI_MOSI_PIN, AT45DBX_SPI_MOSI_FUNCTION }, // MOSI.
#define AT45DBX_ENABLE_NPCS_PIN(NPCS, unused) \
{AT45DBX_SPI_NPCS##NPCS##_PIN, AT45DBX_SPI_NPCS##NPCS##_FUNCTION}, // Chip Select NPCS.
MREPEAT(AT45DBX_MEM_CNT, AT45DBX_ENABLE_NPCS_PIN, ~)
#undef AT45DBX_ENABLE_NPCS_PIN
};

// SPI options.
spi_options_t spiOptions =
{
.reg = AT45DBX_SPI_FIRST_NPCS, // Defined in conf_at45dbx.h.
.baudrate = AT45DBX_SPI_MASTER_SPEED, // Defined in conf_at45dbx.h.
.bits = AT45DBX_SPI_BITS, // Defined in conf_at45dbx.h.
.spck_delay = 0,
.trans_delay = 0,
.stay_act = 1,
.spi_mode = 0,
.fdiv = 0,
.modfdis = 1
};

// Assign I/Os to SPI.
gpio_enable_module(AT45DBX_SPI_GPIO_MAP,
sizeof(AT45DBX_SPI_GPIO_MAP) / sizeof(AT45DBX_SPI_GPIO_MAP[0]));

// If the SPI used by the AT45DBX is not enabled.
if (!spi_is_enabled(AT45DBX_SPI))
{
// Initialize as master.
spi_initMaster(AT45DBX_SPI, &spiOptions);

// Set selection mode: variable_ps, pcs_decode, delay.
spi_selectionMode(AT45DBX_SPI, 0, 0, 0);

// Enable SPI.
spi_enable(AT45DBX_SPI);
}

// Initialize data flash with SPI clock Osc0.
at45dbx_init(spiOptions, FOSC0);
}

#endif // AT45DBX_MEM == ENABLE

#if SD_MMC_MEM == ENABLE

/*! \brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
*/
static void sd_mmc_resources_init(void)
{
static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
{
{SD_MMC_SPI_SCK_PIN, SD_MMC_SPI_SCK_FUNCTION }, // SPI Clock.
{SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION}, // MISO.
{SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION}, // MOSI.
{SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION} // Chip Select NPCS.
};

// SPI options.
spi_options_t spiOptions =
{
.reg = SD_MMC_SPI_NPCS,
.baudrate = SD_MMC_SPI_MASTER_SPEED, // Defined in conf_sd_mmc.h.
.bits = SD_MMC_SPI_BITS, // Defined in conf_sd_mmc.h.
.spck_delay = 0,
.trans_delay = 0,
.stay_act = 1,
.spi_mode = 0,
.fdiv = 0,
.modfdis = 1
};

// Assign I/Os to SPI.
gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));

// If the SPI used by the SD/MMC is not enabled.
if (!spi_is_enabled(SD_MMC_SPI))
{
// Initialize as master.
spi_initMaster(SD_MMC_SPI, &spiOptions);

// Set selection mode: variable_ps, pcs_decode, delay.
spi_selectionMode(SD_MMC_SPI, 0, 0, 0);

// Enable SPI.
spi_enable(SD_MMC_SPI);
}

// Initialize SD/MMC with SPI clock Osc0.
sd_mmc_init(spiOptions, FOSC0);
}

#endif // SD_MMC_MEM == ENABLE

/*! \brief Main function. Execution starts here.
*
* \retval 42 Fatal error.
*/
int main(void)
{
pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);

// Initialize USART link.
init_dbg_rs232(FOSC0);

#if AT45DBX_MEM == ENABLE
at45dbx_resources_init();
#endif
#if SD_MMC_MEM == ENABLE
sd_mmc_resources_init();
#endif
#ifdef FREERTOS_USED
if (!ctrl_access_init())
{
portDBG_TRACE("The module CTRL_ACCESS could not be initialized.");
return 42;
}
#endif // FREERTOS_USED

// Initialize USB clock.
pm_configure_usb_clock();

// Initialize USB tasks.
usb_task_init();
#if USB_DEVICE_FEATURE == ENABLED
device_mass_storage_task_init();
#endif
#if USB_HOST_FEATURE == ENABLED
host_mass_storage_task_init();
#endif
ushell_task_init();

#ifdef FREERTOS_USED
vTaskStartScheduler();
portDBG_TRACE("FreeRTOS returned.");
return 42;
#else
while (TRUE)
{
usb_task();
#if USB_DEVICE_FEATURE == ENABLED
device_mass_storage_task();
#endif
#if USB_HOST_FEATURE == ENABLED
host_mass_storage_task();
#endif
ushell_task();
}
#endif // FREERTOS_USED
}


系统调试

   程序运行后,PC机会找到3个U盘,分别是
"On-Chip Virtual Memory" OK 10240 bytes
"AT45DBX Data Flash" OK 2097152 bytes
"SD/MMC Card" OK 1017643520 bytes


(点击图片放大,不需要放大镜!
可以打开U盘,建立文件夹,建立、修改、删除文件。
本示例程序还可通过串口可对U盘上的文件进行操作,串口支持常用的LINUX命令。


(点击图片放大,不需要放大镜!



AVR32 USB MASS STORAGE U盘应用

——