560 lines
21 KiB
C
560 lines
21 KiB
C
/* ----------------------------------------------------------------------------
|
|
* ATMEL Microcontroller Software Support
|
|
* ----------------------------------------------------------------------------
|
|
* Copyright (c) 2008, 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:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the disclaimer below.
|
|
*
|
|
* Atmel's name may not be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
|
* 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.
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/// \dir "USB Enumeration project"
|
|
///
|
|
/// !!!Purpose
|
|
///
|
|
/// The USB Enumeration Project will help you to get familiar with the
|
|
/// USB Device Port(UDP)interface on AT91SAM microcontrollers. Also
|
|
/// it can help you to be familiar with the USB Framework that is used for
|
|
/// rapid development of USB-compliant class drivers such as USB Communication
|
|
/// Device class (CDC).
|
|
///
|
|
/// You can find following information depends on your needs:
|
|
/// - Sample usage of USB Device Framework.
|
|
/// - USB enumerate sequence, the standard and class-specific descriptors and
|
|
/// requests handling.
|
|
/// - The initialize sequence and usage of UDP interface.
|
|
///
|
|
/// !See
|
|
/// - pio: Pin configurations and peripheral configure.
|
|
/// - usb: USB Device Framework and UDP interface driver
|
|
/// - "AT91 USB device framework"
|
|
/// - "USBD API"
|
|
/// - "USB Device Enumeration"
|
|
///
|
|
/// !!!Requirements
|
|
///
|
|
/// This package can be used with all Atmel evaluation kits that have UDP
|
|
/// interface.
|
|
///
|
|
/// The current supported board list:
|
|
/// - at91sam7s-ek (exclude at91sam7s32)
|
|
/// - at91sam7x-ek
|
|
/// - at91sam7xc-ek
|
|
/// - at91sam7a3-ek
|
|
/// - at91sam7se-ek
|
|
/// - at91sam9260-ek
|
|
/// - at91sam9263-ek
|
|
///
|
|
/// !!!Description
|
|
///
|
|
/// When an EK running this program connected to a host (PC for example), with
|
|
/// USB cable, host will notice the attachment of a USB %device. No %device
|
|
/// driver offered for the %device now.
|
|
///
|
|
/// !!!Usage
|
|
///
|
|
/// -# Build the program and download it inside the evaluation board. Please
|
|
/// refer to the
|
|
/// <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6224.pdf">
|
|
/// SAM-BA User Guide</a>, the
|
|
/// <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
|
|
/// GNU-Based Software Development</a> application note or to the
|
|
/// <a href="ftp://ftp.iar.se/WWWfiles/arm/Guides/EWARM_UserGuide.ENU.pdf">
|
|
/// IAR EWARM User Guide</a>, depending on your chosen solution.
|
|
/// -# On the computer, open and configure a terminal application
|
|
/// (e.g. HyperTerminal on Microsoft Windows) with these settings:
|
|
/// - 115200 bauds
|
|
/// - 8 bits of data
|
|
/// - No parity
|
|
/// - 1 stop bit
|
|
/// - No flow control
|
|
/// -# Start the application.
|
|
/// -# In the terminal window, the following text should appear:
|
|
/// \code
|
|
/// -- USB Device Core Project xxx --
|
|
/// -- AT91xxxxxx-xx
|
|
/// -- Compiled: xxx xx xxxx xx:xx:xx --
|
|
/// \endcode
|
|
/// -# When connecting USB cable to windows, the LED blinks, and the host
|
|
/// reports a new USB %device attachment.
|
|
///
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/// \unit
|
|
///
|
|
/// !Purpose
|
|
///
|
|
/// This file contains all the specific code for the
|
|
/// usb-device-core-project
|
|
///
|
|
/// !Contents
|
|
///
|
|
/// The code can be roughly broken down as follows:
|
|
/// - Configuration functions
|
|
/// - VBus_Configure
|
|
/// - PIO configurations in start of main
|
|
/// - Interrupt handlers
|
|
/// - ISR_Vbus
|
|
/// - Callback functions
|
|
/// - USBDCallbacks_RequestReceived
|
|
/// - The main function, which implements the program behavior
|
|
///
|
|
/// Please refer to the list of functions in the #Overview# tab of this unit
|
|
/// for more detailed information.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Headers
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include <board.h>
|
|
#include <utility/trace.h>
|
|
#include <utility/led.h>
|
|
#include <pio/pio.h>
|
|
#include <pio/pio_it.h>
|
|
#include <usb/common/core/USBGenericDescriptor.h>
|
|
#include <usb/common/core/USBDeviceDescriptor.h>
|
|
#include <usb/common/core/USBConfigurationDescriptor.h>
|
|
#include <usb/common/core/USBInterfaceDescriptor.h>
|
|
#include <usb/common/core/USBGenericRequest.h>
|
|
#include <usb/device/core/USBD.h>
|
|
#include <usb/device/core/USBDDriver.h>
|
|
#include <usb/device/core/USBDDriverDescriptors.h>
|
|
#include <usb/device/core/USBDCallbacks.h>
|
|
#include <pmc/pmc.h>
|
|
|
|
#include "benchm_drv.h"
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Definitions
|
|
//------------------------------------------------------------------------------
|
|
/// Use for power management
|
|
#define STATE_IDLE 0
|
|
/// The USB device is in suspend state
|
|
#define STATE_SUSPEND 4
|
|
/// The USB device is in resume state
|
|
#define STATE_RESUME 5
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Internal variables
|
|
//------------------------------------------------------------------------------
|
|
/// State of USB, for suspend and resume
|
|
unsigned char USBState = STATE_IDLE;
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Local types
|
|
//------------------------------------------------------------------------------
|
|
/// Configuration descriptors with one interface.
|
|
struct SimpleConfigurationDescriptors {
|
|
|
|
USBConfigurationDescriptor configuration;
|
|
USBInterfaceDescriptor interface;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Local variables
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// VBus monitoring (optional)
|
|
//------------------------------------------------------------------------------
|
|
#if defined(PIN_USB_VBUS)
|
|
|
|
#define VBUS_CONFIGURE() VBus_Configure()
|
|
|
|
/// VBus pin instance.
|
|
static const Pin pinVbus = PIN_USB_VBUS;
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Handles interrupts coming from PIO controllers.
|
|
//------------------------------------------------------------------------------
|
|
static void ISR_Vbus(const Pin *pPin)
|
|
{
|
|
// Check current level on VBus
|
|
if (PIO_Get(&pinVbus)) {
|
|
|
|
TRACE_INFO("VBUS conn\n\r");
|
|
USBD_Connect();
|
|
}
|
|
else {
|
|
|
|
TRACE_INFO("VBUS discon\n\r");
|
|
USBD_Disconnect();
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Configures the VBus pin to trigger an interrupt when the level on that pin
|
|
/// changes.
|
|
//------------------------------------------------------------------------------
|
|
static void VBus_Configure( void )
|
|
{
|
|
TRACE_INFO("VBus configuration\n\r");
|
|
|
|
// Configure PIO
|
|
PIO_Configure(&pinVbus, 1);
|
|
PIO_ConfigureIt(&pinVbus, ISR_Vbus);
|
|
PIO_EnableIt(&pinVbus);
|
|
|
|
// Check current level on VBus
|
|
if (PIO_Get(&pinVbus)) {
|
|
|
|
// if VBUS present, force the connect
|
|
TRACE_INFO("VBUS conn\n\r");
|
|
USBD_Connect();
|
|
}
|
|
else {
|
|
TRACE_INFO("VBUS discon\n\r");
|
|
USBD_Disconnect();
|
|
}
|
|
}
|
|
|
|
#else
|
|
#define VBUS_CONFIGURE() USBD_Connect()
|
|
#endif //#if defined(PIN_USB_VBUS)
|
|
|
|
#if defined (CP15_PRESENT)
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in 32kHz, disable PLL, main oscillator
|
|
/// Put voltage regulator in standby mode
|
|
//------------------------------------------------------------------------------
|
|
void LowPowerMode(void)
|
|
{
|
|
PMC_CPUInIdleMode();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
/// Put voltage regulator in normal mode
|
|
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void NormalPowerMode(void)
|
|
{
|
|
}
|
|
|
|
#elif defined(at91sam7a3)
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in 32kHz, disable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void LowPowerMode(void)
|
|
{
|
|
// MCK=48MHz to MCK=32kHz
|
|
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=SLCK : then change prescaler
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// disable PLL
|
|
AT91C_BASE_PMC->PMC_PLLR = 0;
|
|
// Disable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = 0;
|
|
|
|
PMC_DisableProcessorClock();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void NormalPowerMode(void)
|
|
{
|
|
// MCK=32kHz to MCK=48MHz
|
|
// enable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
|
|
|
|
// enable PLL@96MHz
|
|
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
|
|
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
|
|
(AT91C_CKGR_MUL & (0x48<<16)));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
|
|
// MCK=SLCK/2 : change prescaler first
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=PLLCK/2 : then change source
|
|
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
}
|
|
|
|
#elif defined (at91sam7se)
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in 32kHz, disable PLL, main oscillator
|
|
/// Put voltage regulator in standby mode
|
|
//------------------------------------------------------------------------------
|
|
void LowPowerMode(void)
|
|
{
|
|
// MCK=48MHz to MCK=32kHz
|
|
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=SLCK : then change prescaler
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// disable PLL
|
|
AT91C_BASE_PMC->PMC_PLLR = 0;
|
|
// Disable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = 0;
|
|
|
|
// Voltage regulator in standby mode : Enable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
|
|
|
|
PMC_DisableProcessorClock();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
/// Put voltage regulator in normal mode
|
|
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void NormalPowerMode(void)
|
|
{
|
|
// Voltage regulator in normal mode : Disable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
|
|
|
|
// MCK=32kHz to MCK=48MHz
|
|
// enable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
|
|
|
|
// enable PLL@96MHz
|
|
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
|
|
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
|
|
(AT91C_CKGR_MUL & (0x48<<16)));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
|
|
// MCK=SLCK/2 : change prescaler first
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=PLLCK/2 : then change source
|
|
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
}
|
|
|
|
#elif defined (at91sam7s)
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in 32kHz, disable PLL, main oscillator
|
|
/// Put voltage regulator in standby mode
|
|
//------------------------------------------------------------------------------
|
|
void LowPowerMode(void)
|
|
{
|
|
// MCK=48MHz to MCK=32kHz
|
|
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=SLCK : then change prescaler
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// disable PLL
|
|
AT91C_BASE_PMC->PMC_PLLR = 0;
|
|
// Disable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = 0;
|
|
|
|
// Voltage regulator in standby mode : Enable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
|
|
|
|
PMC_DisableProcessorClock();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Put voltage regulator in normal mode
|
|
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void NormalPowerMode(void)
|
|
{
|
|
// Voltage regulator in normal mode : Disable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
|
|
|
|
// MCK=32kHz to MCK=48MHz
|
|
// enable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
|
|
|
|
// enable PLL@96MHz
|
|
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
|
|
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
|
|
(AT91C_CKGR_MUL & (0x48<<16)));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
|
|
// MCK=SLCK/2 : change prescaler first
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=PLLCK/2 : then change source
|
|
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
|
|
}
|
|
|
|
#elif defined (at91sam7x) || defined (at91sam7xc)
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in 32kHz, disable PLL, main oscillator
|
|
/// Put voltage regulator in standby mode
|
|
//------------------------------------------------------------------------------
|
|
void LowPowerMode(void)
|
|
{
|
|
// MCK=48MHz to MCK=32kHz
|
|
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=SLCK : then change prescaler
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// disable PLL
|
|
AT91C_BASE_PMC->PMC_PLLR = 0;
|
|
// Disable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = 0;
|
|
|
|
// Voltage regulator in standby mode : Enable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
|
|
|
|
PMC_DisableProcessorClock();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Put voltage regulator in normal mode
|
|
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
|
|
//------------------------------------------------------------------------------
|
|
void NormalPowerMode(void)
|
|
{
|
|
// Voltage regulator in normal mode : Disable VREG Low Power Mode
|
|
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
|
|
|
|
// MCK=32kHz to MCK=48MHz
|
|
// enable Main Oscillator
|
|
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
|
|
|
|
// enable PLL@96MHz
|
|
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
|
|
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
|
|
(AT91C_CKGR_MUL & (0x48<<16)));
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
|
|
// MCK=SLCK/2 : change prescaler first
|
|
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
// MCK=PLLCK/2 : then change source
|
|
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
|
|
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
|
|
}
|
|
#else
|
|
//------------------------------------------------------------------------------
|
|
/// Put the CPU in low power mode (for customer)
|
|
//------------------------------------------------------------------------------
|
|
static void LowPowerMode(void)
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Return the CPU to normal speed (for customer)
|
|
//------------------------------------------------------------------------------
|
|
static void NormalPowerMode(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Callbacks re-implementation
|
|
//------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------
|
|
/// Invoked when the USB device leaves the Suspended state. By default,
|
|
/// configures the LEDs.
|
|
//------------------------------------------------------------------------------
|
|
void USBDCallbacks_Resumed(void)
|
|
{
|
|
// Initialize LEDs
|
|
LED_Configure(USBD_LEDPOWER);
|
|
LED_Set(USBD_LEDPOWER);
|
|
LED_Configure(USBD_LEDUSB);
|
|
LED_Clear(USBD_LEDUSB);
|
|
USBState = STATE_RESUME;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Invoked when the USB device gets suspended. By default, turns off all LEDs.
|
|
//------------------------------------------------------------------------------
|
|
void USBDCallbacks_Suspended(void)
|
|
{
|
|
// Turn off LEDs
|
|
LED_Clear(USBD_LEDPOWER);
|
|
LED_Clear(USBD_LEDUSB);
|
|
USBState = STATE_SUSPEND;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Global functions
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// Initializes the system, connects the USB and waits indefinitely.
|
|
//------------------------------------------------------------------------------
|
|
int main()
|
|
{
|
|
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
|
|
printf("-- USB Benchmark Project %s --\n\r", SOFTPACK_VERSION);
|
|
printf("-- %s\n\r", BOARD_NAME);
|
|
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
|
|
|
|
// If they are present, configure Vbus & Wake-up pins
|
|
PIO_InitializeInterrupts(0);
|
|
|
|
// If there is on board power, switch it off
|
|
#ifdef PIN_USB_POWER_ENB
|
|
{ const Pin pinUsbPwr = PIN_USB_POWER_ENB;
|
|
PIO_Configure(&pinUsbPwr, 1);
|
|
}
|
|
#endif
|
|
|
|
// USB initialization, Disable Pull-up
|
|
TRACE_INFO("USB initialization\n\r");
|
|
benchmark_drv_init();
|
|
|
|
// Wait about 10ms so that host detach the device to re-enumerate
|
|
// Device connection
|
|
TRACE_INFO("Connecting device\n\r");
|
|
|
|
// Enable Vbus detect, connect if needed (vbus detected)
|
|
VBUS_CONFIGURE();
|
|
while (USBD_GetState() < USBD_STATE_CONFIGURED);
|
|
|
|
benchmark_start(2);
|
|
//benchmark_start(5);
|
|
|
|
// Infinite loop
|
|
while (1) {
|
|
if( USBState == STATE_SUSPEND ) {
|
|
TRACE_DEBUG("suspend !\n\r");
|
|
LowPowerMode();
|
|
USBState = STATE_IDLE;
|
|
}
|
|
if( USBState == STATE_RESUME ) {
|
|
// Return in normal MODE
|
|
TRACE_DEBUG("resume !\n\r");
|
|
NormalPowerMode();
|
|
USBState = STATE_IDLE;
|
|
}
|
|
}
|
|
}
|
|
|