diff options
| author | Harald Welte <laforge@gnumonks.org> | 2011-07-31 12:17:31 +0200 | 
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2011-07-31 12:19:34 +0200 | 
| commit | 0279a2bcf0e9a06f7be8fde44f1afe15eb5b18d1 (patch) | |
| tree | ec82c06f85012461a6f9ffd40fb1a4a8db25aad1 | |
| parent | d0afa79e7f84851c35116af28f821c6c4f65ed1c (diff) | |
import usb-device-cdc-serial
| -rw-r--r-- | at91lib/peripherals/tc/tc.h | 74 | ||||
| -rw-r--r-- | usb-device-cdc-serial-project/Makefile | 163 | ||||
| -rw-r--r-- | usb-device-cdc-serial-project/bin/.empty | 0 | ||||
| -rw-r--r-- | usb-device-cdc-serial-project/main.c | 728 | ||||
| -rw-r--r-- | usb-device-cdc-serial-project/obj/.empty | 0 | 
5 files changed, 965 insertions, 0 deletions
| diff --git a/at91lib/peripherals/tc/tc.h b/at91lib/peripherals/tc/tc.h new file mode 100644 index 0000000..8bf96e5 --- /dev/null +++ b/at91lib/peripherals/tc/tc.h @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------
 + *         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.
 + * ----------------------------------------------------------------------------
 + */
 +
 +//------------------------------------------------------------------------------
 +/// \unit
 +///
 +/// !Purpose
 +///
 +/// API for configuring and using Timer Counter (TC) peripherals.
 +///
 +/// !Usage
 +/// -# Optionally, use TC_FindMckDivisor() to let the program find the best
 +///    TCCLKS field value automatically.
 +/// -# Configure a Timer Counter in the desired mode using TC_Configure().
 +/// -# Start or stop the timer clock using TC_Start() and TC_Stop().
 +//------------------------------------------------------------------------------
 +
 +#ifndef TC_H
 +#define TC_H
 +
 +//------------------------------------------------------------------------------
 +//         Headers
 +//------------------------------------------------------------------------------
 +
 +#include <board.h>
 +
 +#if !defined(AT91C_ID_TC0) && defined(AT91C_ID_TC012)
 +    #define AT91C_ID_TC0 AT91C_ID_TC012
 +#endif
 +
 +//------------------------------------------------------------------------------
 +//         Global functions
 +//------------------------------------------------------------------------------
 +
 +extern void TC_Configure(AT91S_TC *pTc, unsigned int mode);
 +
 +extern void TC_Start(AT91S_TC *pTc);
 +
 +extern void TC_Stop(AT91S_TC *pTc);
 +
 +extern unsigned char TC_FindMckDivisor(
 +    unsigned int freq,
 +    unsigned int mck,
 +    unsigned int *div,
 +    unsigned int *tcclks);
 +
 +#endif //#ifndef TC_H
 +
 diff --git a/usb-device-cdc-serial-project/Makefile b/usb-device-cdc-serial-project/Makefile new file mode 100644 index 0000000..cf8b126 --- /dev/null +++ b/usb-device-cdc-serial-project/Makefile @@ -0,0 +1,163 @@ +# ----------------------------------------------------------------------------
 +#         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.
 +# ----------------------------------------------------------------------------
 +
 +# 	Makefile for compiling the USB CDC serial project
 +
 +#-------------------------------------------------------------------------------
 +#		User-modifiable options
 +#-------------------------------------------------------------------------------
 +
 +# Chip & board used for compilation
 +# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
 +CHIP  = at91sam7s256
 +BOARD = at91sam7s-ek
 +
 +# Trace level used for compilation
 +# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
 +# TRACE_LEVEL_DEBUG      5
 +# TRACE_LEVEL_INFO       4
 +# TRACE_LEVEL_WARNING    3
 +# TRACE_LEVEL_ERROR      2
 +# TRACE_LEVEL_FATAL      1
 +# TRACE_LEVEL_NO_TRACE   0
 +TRACE_LEVEL = 3
 +
 +# Optimization level, put in comment for debugging
 +OPTIMIZATION = -Os
 +
 +# AT91 library directory
 +AT91LIB = ../at91lib
 +
 +# Output file basename
 +OUTPUT = usb-device-cdc-serial-project-$(BOARD)-$(CHIP)
 +
 +# Compile for all memories available on the board (this sets $(MEMORIES))
 +include $(AT91LIB)/boards/$(BOARD)/board.mak
 +
 +# Output directories
 +BIN = bin
 +OBJ = obj
 +
 +#-------------------------------------------------------------------------------
 +#		Tools
 +#-------------------------------------------------------------------------------
 +
 +# Tool suffix when cross-compiling
 +CROSS_COMPILE = arm-none-eabi-
 +
 +# Compilation tools
 +CC = $(CROSS_COMPILE)gcc
 +SIZE = $(CROSS_COMPILE)size
 +OBJCOPY = $(CROSS_COMPILE)objcopy
 +
 +# Flags
 +INCLUDES = -I$(AT91LIB)/boards/$(BOARD) -I$(AT91LIB)/peripherals 
 +INCLUDES += -I$(AT91LIB)/components -I$(AT91LIB)/usb/device -I$(AT91LIB)
 +
 +CFLAGS = -Wall -mlong-calls -ffunction-sections
 +CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL)
 +ASFLAGS = -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
 +LDFLAGS = -g $(OPTIMIZATION) -nostartfiles -Wl,--gc-sections
 +
 +#-------------------------------------------------------------------------------
 +#		Files
 +#-------------------------------------------------------------------------------
 +
 +# Directories where source files can be found
 +USB = $(AT91LIB)/usb
 +UTILITY = $(AT91LIB)/utility
 +PERIPH = $(AT91LIB)/peripherals
 +BOARDS = $(AT91LIB)/boards
 +
 +VPATH += $(USB)/device/cdc-serial $(USB)/device/core $(USB)/common/core
 +VPATH += $(USB)/common/cdc
 +VPATH += $(UTILITY)
 +VPATH += $(PERIPH)/dbgu $(PERIPH)/aic $(PERIPH)/usart $(PERIPH)/pio $(PERIPH)/pmc
 +VPATH += $(PERIPH)/cp15
 +VPATH += $(BOARDS)/$(BOARD) $(BOARDS)/$(BOARD)/$(CHIP)
 +
 +# Objects built from C source files
 +C_OBJECTS = main.o
 +C_OBJECTS += CDCDSerialDriver.o CDCDSerialDriverDescriptors.o
 +C_OBJECTS += CDCSetControlLineStateRequest.o CDCLineCoding.o
 +C_OBJECTS += USBD_OTGHS.o USBD_UDP.o USBD_UDPHS.o USBDDriver.o
 +C_OBJECTS += USBDCallbacks_Initialized.o
 +C_OBJECTS += USBDCallbacks_Reset.o
 +#C_OBJECTS += USBDCallbacks_Resumed.o
 +#C_OBJECTS += USBDCallbacks_Suspended.o
 +C_OBJECTS += USBDDriverCb_CfgChanged.o
 +C_OBJECTS += USBDDriverCb_IfSettingChanged.o
 +C_OBJECTS += USBSetAddressRequest.o USBGenericDescriptor.o USBInterfaceRequest.o
 +C_OBJECTS += USBGenericRequest.o USBGetDescriptorRequest.o 
 +C_OBJECTS += USBSetConfigurationRequest.o USBFeatureRequest.o
 +C_OBJECTS += USBEndpointDescriptor.o USBConfigurationDescriptor.o
 +C_OBJECTS += led.o string.o stdio.o
 +C_OBJECTS += aic.o dbgu.o usart.o pio.o pio_it.o pmc.o cp15.o
 +C_OBJECTS += board_memories.o board_lowlevel.o
 +
 +# Objects built from Assembly source files
 +ASM_OBJECTS = board_cstartup.o
 +ASM_OBJECTS += cp15_asm.o
 +
 +# Append OBJ and BIN directories to output filename
 +OUTPUT := $(BIN)/$(OUTPUT)
 +
 +#-------------------------------------------------------------------------------
 +#		Rules
 +#-------------------------------------------------------------------------------
 +
 +all: $(BIN) $(OBJ) $(MEMORIES)
 +
 +$(BIN) $(OBJ):
 +	mkdir $@
 +
 +define RULES
 +C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
 +ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
 +
 +$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
 +	$(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/$$@.lds" -o $(OUTPUT)-$$@.elf $$^
 +	$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
 +	$(SIZE) $$^ $(OUTPUT)-$$@.elf
 +
 +$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
 +	$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
 +
 +$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
 +	$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
 +
 +debug_$(1): $(1)
 +	perl ../resources/gdb/debug.pl $(OUTPUT)-$(1).elf
 +
 +endef
 +
 +$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
 +
 +clean:
 +	-rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf
 +
 diff --git a/usb-device-cdc-serial-project/bin/.empty b/usb-device-cdc-serial-project/bin/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/usb-device-cdc-serial-project/bin/.empty diff --git a/usb-device-cdc-serial-project/main.c b/usb-device-cdc-serial-project/main.c new file mode 100644 index 0000000..1f4e1e7 --- /dev/null +++ b/usb-device-cdc-serial-project/main.c @@ -0,0 +1,728 @@ +/* ----------------------------------------------------------------------------
 + *         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 CDC serial converter"
 +///
 +/// !!!Purpose
 +///
 +/// The USB CDC Serial Project will help you to get familiar with the
 +/// USB Device Port(UDP) and USART 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 CDC driver and USART driver.
 +/// - USB CDC driver development based on the AT91 USB Framework.
 +/// - USB enumerate sequence, the standard and class-specific descriptors and
 +///   requests handling.
 +/// - The initialize sequence and usage of UDP interface.
 +/// - The initialize sequence and usage of USART interface with PDC.
 +///
 +/// !See
 +/// - usart: USART interface driver
 +/// - tc: TIMER/COUNTER interface driver
 +/// - usb: USB Framework, USB CDC driver and UDP interface driver
 +///    - "AT91 USB device framework"
 +///       - "USBD API"
 +///    - "cdc-serial"
 +///       - "USB CDC Serial Device"
 +///       - "USB CDC Serial Host Driver"
 +///
 +/// !!!Requirements
 +///
 +/// This package can be used with all Atmel evaluation kits that have both
 +/// UDP and USART 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, the EK appears as a Seriao COM port for the host, after driver
 +/// installation with the offered 6119.inf. Then the host can send or receive
 +/// data through the port with host software. The data stream from the host is
 +/// then sent to the EK, and forward to USART port of AT91SAM chips. The USART
 +/// port of the EK is monitored by the timer and the incoming data will be sent
 +/// to the host.
 +///
 +/// !!!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 CDC Serial 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 (if it's the first time you connect
 +///    an %audio speaker demo board to your host). You can use the inf file
 +///    at91lib\\usb\\device\\cdc-serial\\drv\\6119.inf to install the serial
 +///    port. Then new "AT91 USB to Serial Converter (COMx)" appears in the
 +///    hardware %device list.
 +/// -# You can run hyperterminal to send data to the port. And it can be seen
 +///    at the other hyperterminal connected to the USART port of the EK.
 +///
 +//-----------------------------------------------------------------------------
 +
 +//-----------------------------------------------------------------------------
 +/// \unit
 +///
 +/// !Purpose
 +///
 +/// This file contains all the specific code for the
 +/// usb-device-cdc-serial-project
 +///
 +/// !Contents
 +///
 +/// The code can be roughly broken down as follows:
 +///    - Configuration functions
 +///       - VBus_Configure
 +///       - PIO & Timer configurations in start of main
 +///    - Interrupt handlers
 +///       - ISR_Vbus
 +///       - ISR_Timer0
 +///       - ISR_Usart0
 +///    - Callback functions
 +///       - UsbDataReceived
 +///    - 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 <pio/pio.h>
 +#include <pio/pio_it.h>
 +#include <aic/aic.h>
 +#include <tc/tc.h>
 +#include <usart/usart.h>
 +#include <utility/trace.h>
 +#include <utility/led.h>
 +#include <usb/device/cdc-serial/CDCDSerialDriver.h>
 +#include <usb/device/cdc-serial/CDCDSerialDriverDescriptors.h>
 +#include <pmc/pmc.h>
 +
 +//------------------------------------------------------------------------------
 +//      Definitions
 +//------------------------------------------------------------------------------
 +#ifndef AT91C_ID_TC0
 +    #define AT91C_ID_TC0 AT91C_ID_TC
 +#endif
 +
 +/// Size in bytes of the buffer used for reading data from the USB & USART
 +#define DATABUFFERSIZE \
 +    BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)
 +
 +/// 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;
 +
 +/// List of pins that must be configured for use by the application.
 +static const Pin pins[] = {PIN_USART0_TXD, PIN_USART0_RXD};
 +
 +/// Double-buffer for storing incoming USART data.
 +static unsigned char usartBuffers[2][DATABUFFERSIZE];
 +
 +/// Current USART buffer index.
 +static unsigned char usartCurrentBuffer = 0;
 +
 +/// Buffer for storing incoming USB data.
 +static unsigned char usbBuffer[DATABUFFERSIZE];
 +
 +//------------------------------------------------------------------------------
 +//         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 {
 +        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 ) );
 +}
 +
 +#endif
 +
 +//------------------------------------------------------------------------------
 +//         Internal functions
 +//------------------------------------------------------------------------------
 +
 +//------------------------------------------------------------------------------
 +/// Handles interrupts coming from Timer #0.
 +//------------------------------------------------------------------------------
 +static void ISR_Timer0()
 +{
 +    unsigned char size;
 +    unsigned int status = AT91C_BASE_TC0->TC_SR;
 +
 +    if ((status & AT91C_TC_CPCS) != 0) {
 +    
 +        // Flush PDC buffer
 +        size = DATABUFFERSIZE - AT91C_BASE_US0->US_RCR;
 +        if (size == 0) {
 +
 +            AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 +            return;
 +        }
 +        AT91C_BASE_US0->US_RCR = 0;
 +    
 +        // Send current buffer through the USB
 +        while (CDCDSerialDriver_Write(usartBuffers[usartCurrentBuffer],
 +                                      size, 0, 0) != USBD_STATUS_SUCCESS);
 +    
 +        // Restart read on buffer
 +        USART_ReadBuffer(AT91C_BASE_US0,
 +                         usartBuffers[usartCurrentBuffer],
 +                         DATABUFFERSIZE);
 +        usartCurrentBuffer = 1 - usartCurrentBuffer;
 +        AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 +    }
 +}
 +
 +
 +//------------------------------------------------------------------------------
 +//         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;
 +}
 +
 +
 +//------------------------------------------------------------------------------
 +/// Callback invoked when data has been received on the USB.
 +//------------------------------------------------------------------------------
 +static void UsbDataReceived(unsigned int unused,
 +                            unsigned char status,
 +                            unsigned int received,
 +                            unsigned int remaining)
 +{
 +    // Check that data has been received successfully
 +    if (status == USBD_STATUS_SUCCESS) {
 +
 +        // Send data through USART
 +        while (!USART_WriteBuffer(AT91C_BASE_US0, usbBuffer, received));
 +        AT91C_BASE_US0->US_IER = AT91C_US_TXBUFE;
 +
 +        // Check if bytes have been discarded
 +        if ((received == DATABUFFERSIZE) && (remaining > 0)) {
 +
 +            TRACE_WARNING(
 +                      "UsbDataReceived: %u bytes discarded\n\r",
 +                      remaining);
 +        }
 +    }
 +    else {
 +
 +        TRACE_WARNING( "UsbDataReceived: Transfer error\n\r");
 +    }
 +}
 +
 +//------------------------------------------------------------------------------
 +/// Handles interrupts coming from USART #0.
 +//------------------------------------------------------------------------------
 +static void ISR_Usart0()
 +{
 +    unsigned int status = AT91C_BASE_US0->US_CSR;
 +    unsigned short serialState;
 +
 +    // If USB device is not configured, do nothing
 +    if (USBD_GetState() != USBD_STATE_CONFIGURED) {
 +
 +        AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
 +        return;
 +    }
 +
 +    // Buffer has been read successfully
 +    if ((status & AT91C_US_ENDRX) != 0) {
 +
 +        // Disable timer
 +        AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
 +
 +        // Send buffer through the USB
 +        while (CDCDSerialDriver_Write(usartBuffers[usartCurrentBuffer],
 +                                      DATABUFFERSIZE, 0, 0) != USBD_STATUS_SUCCESS);
 +
 +        // Restart read on buffer
 +        USART_ReadBuffer(AT91C_BASE_US0,
 +                         usartBuffers[usartCurrentBuffer],
 +                         DATABUFFERSIZE);
 +        usartCurrentBuffer = 1 - usartCurrentBuffer;
 +
 +        // Restart timer
 +        AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 +    }
 +
 +    // Buffer has been sent
 +    if ((status & AT91C_US_TXBUFE) != 0) {
 +
 +        // Restart USB read
 +        CDCDSerialDriver_Read(usbBuffer,
 +                              DATABUFFERSIZE,
 +                              (TransferCallback) UsbDataReceived,
 +                              0);
 +        AT91C_BASE_US0->US_IDR = AT91C_US_TXBUFE;
 +    }
 +
 +    // Errors
 +    serialState = CDCDSerialDriver_GetSerialState();
 +
 +    // Overrun
 +    if ((status & AT91C_US_OVER) != 0) {
 +
 +        TRACE_WARNING( "ISR_Usart0: Overrun\n\r");
 +        serialState |= CDCDSerialDriver_STATE_OVERRUN;
 +    }
 +
 +    // Framing error
 +    if ((status & AT91C_US_FRAME) != 0) {
 +
 +        TRACE_WARNING( "ISR_Usart0: Framing error\n\r");
 +        serialState |= CDCDSerialDriver_STATE_FRAMING;
 +    }
 +
 +    CDCDSerialDriver_SetSerialState(serialState);
 +}
 +
 +//------------------------------------------------------------------------------
 +//          Main
 +//------------------------------------------------------------------------------
 +
 +//------------------------------------------------------------------------------
 +/// Initializes drivers and start the USB <-> Serial bridge.
 +//------------------------------------------------------------------------------
 +int main()
 +{
 +    TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
 +    printf("-- USB Device CDC Serial 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);
 +
 +    // Configure USART
 +    PIO_Configure(pins, PIO_LISTSIZE(pins));
 +    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;
 +    AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
 +    USART_Configure(AT91C_BASE_US0,
 +                    USART_MODE_ASYNCHRONOUS,
 +                    115200,
 +                    BOARD_MCK);
 +    USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
 +    USART_SetReceiverEnabled(AT91C_BASE_US0, 1);
 +    AIC_ConfigureIT(AT91C_ID_US0, 0, ISR_Usart0);
 +    AIC_EnableIT(AT91C_ID_US0);
 +
 +    // Configure timer 0
 +    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
 +    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
 +    AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
 +    AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK
 +                             | AT91C_TC_CPCSTOP
 +                             | AT91C_TC_CPCDIS
 +                             | AT91C_TC_WAVESEL_UP_AUTO
 +                             | AT91C_TC_WAVE;
 +    AT91C_BASE_TC0->TC_RC = 0x00FF;
 +    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
 +    AIC_ConfigureIT(AT91C_ID_TC0, 0, ISR_Timer0);
 +    AIC_EnableIT(AT91C_ID_TC0);
 +
 +    // BOT driver initialization
 +    CDCDSerialDriver_Initialize();
 +
 +    // connect if needed
 +    VBUS_CONFIGURE();
 +
 +    // Driver loop
 +    while (1) {
 +
 +        // Device is not configured
 +        if (USBD_GetState() < USBD_STATE_CONFIGURED) {
 +
 +            // Connect pull-up, wait for configuration
 +            USBD_Connect();
 +            while (USBD_GetState() < USBD_STATE_CONFIGURED);
 +
 +            // Start receiving data on the USART
 +            usartCurrentBuffer = 0;
 +            USART_ReadBuffer(AT91C_BASE_US0, usartBuffers[0], DATABUFFERSIZE);
 +            USART_ReadBuffer(AT91C_BASE_US0, usartBuffers[1], DATABUFFERSIZE);
 +            AT91C_BASE_US0->US_IER = AT91C_US_ENDRX
 +                                     | AT91C_US_FRAME
 +                                     | AT91C_US_OVER;
 +            AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
 +
 +            // Start receiving data on the USB
 +            CDCDSerialDriver_Read(usbBuffer,
 +                                  DATABUFFERSIZE,
 +                                  (TransferCallback) UsbDataReceived,
 +                                  0);
 +        }
 +        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;
 +        }
 +    }
 +}
 +
 diff --git a/usb-device-cdc-serial-project/obj/.empty b/usb-device-cdc-serial-project/obj/.empty new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/usb-device-cdc-serial-project/obj/.empty | 
