SAMV71 Xplained Ultra Software Package 1.3

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 /** \cond usb_hid_transfer
00030  *  \page usb_hid_transfer USB HID Transfer Example
00031  *
00032  *  \section Purpose
00033  *
00034  *  The USB HID Transfer Project will help you to get familiar with the
00035  *  USB Device Port(UDP) and PIO interface on SAMv7 Microcontrollers. Also
00036  *  it can help you to be familiar with the USB Framework that is used for
00037  *  rapid development of USB-compliant class drivers such as USB Human
00038  *  Interface Device class (HID).
00039  *
00040  *  \section Requirements
00041  *
00042  *  This package can be used with all Atmel Xplained board that has UDP
00043  *  interface.
00044  *
00045  *  \section Description
00046  *
00047  *  The demo simulates a customized HID device that reports customized data
00048  *  stream, in which informations on LEDs and buttons are packed, to host.
00049  *
00050  *  When an Xplained running this program connected to a host (PC for example), 
00051  *  with USB cable, the Xplained appears as a "USB Human Interface Device" for 
00052  *  the host.Then you can use the client application to read/write on it.
00053  *
00054  *  \section Usage
00055  *
00056  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00057  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00058  *  -# On the computer, open and configure a terminal application
00059  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00060  *    - 115200 bauds
00061  *    - 8 bits of data
00062  *    - No parity
00063  *    - 1 stop bit
00064  *    - No flow control
00065  *  -# Start the application.
00066  *  -# In the terminal window, the following text should appear:
00067  *      \code
00068  *      -- USB Device HID Transfer Project xxx --
00069  *      -- SAMxxxxx-xx
00070  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00071  *      \endcode
00072  *  -# When connecting USB cable to windows, the LED blinks.
00073  *     Then new "HID Transfer Device" appears in the
00074  *     hardware %device list.
00075  *  -# Then you can use the PC program !hidTest.exe to check the !device
00076  *     information and run tests.
00077  *  -# Find the HID Device whose VID is 03EB and PID is 6201, select item type
00078  *     and item to see its attributes.
00079  *  -# Type what you want to send in output edit box, use buttons on the right
00080  *     side to send. You can see data information in debug terminal.
00081  *  -# You can use the buttons above the input edit box to read data from
00082  *     !device of monitor the data, then the data and the status of the buttons
00083  *     on the board is read and the gray buttons is up or down based on the
00084  *     buttons status on the board.
00085  *
00086  *  \section References
00087  *  - usb_hid_transfer/main.c
00088  *  - pio: PIO interface driver
00089  *     - pio.h
00090  *     - pio_it.h
00091  *  - usb: USB Framework, USB HID driver and UDP interface driver
00092  *     - \ref usbd_framework
00093  *        - \ref usbd_api
00094  *     - \ref usbd_hid_tran "hid-Transfer"
00095  *        - \ref usbd_hid_xfr_drv
00096  */
00097 
00098 /**
00099  *  \file
00100  *
00101  *  This file contains all the specific code for the
00102  *  usb_hid_transfer example
00103  */
00104 
00105 /**
00106  *         Headers
00107  */
00108 
00109 #include "board.h"
00110 
00111 #include <HIDDTransferDriver.h>
00112 
00113 #include <stdio.h>
00114 #include <string.h>
00115 
00116 /**
00117  *         Definitions
00118  */
00119 
00120 /** Delay for push-button denounce (ms) */
00121 #define DEBOUNCE_TIME      10
00122 #define NO_PUSHBUTTON
00123 /**
00124  *         External variables
00125  */
00126 
00127 /** HID Transfer driver descriptors */
00128 extern USBDDriverDescriptors hiddTransferDriverDescriptors;
00129 
00130 /**
00131  *         Internal variables
00132  */
00133 
00134 /** Pins for Buttons */
00135 #ifndef NO_PUSHBUTTON
00136 static Pin pinsButtons[] = { PINS_PUSHBUTTONS } ;
00137 #endif
00138 
00139 #ifndef NO_PUSHBUTTON
00140 /**
00141  *  Remote wake-up support (optional)
00142  */
00143 
00144 /** Button for Wake-UP the USB device. */
00145 static const Pin pinWakeUp = PIN_PUSHBUTTON_1 ;
00146 
00147 /**
00148  *  Interrupt service routine for the remote wake-up pin. Starts the debounce
00149  *  sequence.
00150  */
00151 static void WakeUpHandler( const Pin *pin )
00152 {
00153     TRACE_DEBUG( "Wake-up handler\n\r" ) ;
00154 
00155     /* Check current level on the remote wake-up pin */
00156     if ( !PIO_Get( &pinWakeUp ) ) {
00157         HIDDTransferDriver_RemoteWakeUp() ;
00158     }
00159 }
00160 
00161 /**
00162  *  Configures the wake-up pin to generate interrupts.
00163  */
00164 static void _ConfigureWakeUp( void )
00165 {
00166     TRACE_INFO( "Wake-up configuration\n\r" ) ;
00167 
00168     /* Configure PIO */
00169     PIO_Configure( &pinWakeUp, 1 ) ;
00170     PIO_SetDebounceFilter( &pinWakeUp, DEBOUNCE_TIME );
00171     PIO_ConfigureIt( &pinWakeUp, WakeUpHandler ) ;
00172     PIO_EnableIt( &pinWakeUp ) ;
00173 }
00174 #endif
00175 
00176 /*
00177  *         Internal Functions
00178  */
00179 
00180 /**
00181  *  Display the buffer, 8 byte a line
00182  *
00183  *  \param buffer   Pointer to the data location
00184  *  \param dwLen    Size of the data
00185  */
00186 static void _ShowBuffer( uint8_t* pucBuffer, uint32_t dwLen )
00187 {
00188     uint32_t dw ;
00189 
00190     for ( dw = 0 ; dw < dwLen ; dw++ ) {
00191         if ( (dw & 0x7) == 0 ) {
00192             printf( "\n\r" ) ;
00193         }
00194         printf( " %02x", pucBuffer[dw] ) ;
00195     }
00196     printf( "\n\r" ) ;
00197 }
00198 
00199 /*----------------------------------------------------------------------------
00200  *         Callbacks re-implementation
00201  *----------------------------------------------------------------------------*/
00202 
00203 /**
00204  *  Invoked whenever a SETUP request is received from the host. Forwards the
00205  *  request to the standard handler.
00206  */
00207 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00208 {
00209     HIDDTransferDriver_RequestHandler(request);
00210 }
00211 
00212 /**
00213  * Invoked when the configuration of the device changes. Start reading
00214  * output reports.
00215  * \param cfgnum New configuration number.
00216  */
00217 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00218 {
00219     HIDDTransferDriver_ConfigurationChangedHandler(cfgnum);
00220 }
00221 
00222 /**
00223  * Configure USB settings for USB device
00224  */
00225 static void _ConfigureUotghs(void)
00226 {
00227   
00228     /* UTMI parallel mode, High/Full/Low Speed */
00229     /* UUSBCK not used in this configuration (High Speed) */
00230     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00231     /* USB clock register: USB Clock Input is UTMI PLL */
00232     PMC->PMC_USB = PMC_USB_USBS;
00233     /* Enable peripheral clock for USBHS */
00234     PMC_EnablePeripheral(ID_USBHS);    
00235     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00236     /* Enable PLL 480 MHz */
00237     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00238     /* Wait that PLL is considered locked by the PMC */
00239     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00240 
00241     /* IRQ */
00242     NVIC_EnableIRQ(USBHS_IRQn) ;
00243 }
00244 
00245 /**
00246  *  Main function
00247  */
00248 
00249 /**
00250  *  Initializes the system and then monitors buttons, sending the
00251  *  corresponding character when one is pressed.
00252  *  \callgraph
00253  */
00254 int main( void )
00255 {
00256     uint32_t dwCnt=0 ;
00257     uint32_t dwLen ;
00258     uint8_t  iBuffer[64] ;
00259     uint8_t  oBuffer[64] = {0x80} ;
00260     uint8_t  bmLEDs=0 ;
00261     uint8_t  update ;
00262 
00263     /* Disable watchdog */
00264     WDT_Disable( WDT ) ;
00265 
00266     SCB_EnableICache();
00267     SCB_EnableDCache();
00268     
00269     printf( "-- USB Device HID Transfer Project %s --\n\r", SOFTPACK_VERSION ) ;
00270     printf( "-- %s\n\r", BOARD_NAME ) ;
00271     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00272 
00273     /* If they are present, configure Vbus & Wake-up pins */
00274     PIO_InitializeInterrupts( 0 ) ;
00275 
00276     /* If there is on board power, switch it off */
00277     _ConfigureUotghs();
00278 
00279 #ifndef NO_PUSHBUTTON
00280     /* If there is wakeup pin, configure it */
00281     _ConfigureWakeUp() ;
00282 #endif
00283 
00284     /* Configure PINs for LEDs and Buttons */
00285     LED_Configure( LED_YELLOW1 ) ;
00286     LED_Configure( LED_YELLOW0 ) ;
00287     LED_Set( LED_YELLOW0 ) ;
00288     LED_Clear( LED_YELLOW1 ) ;
00289 #ifdef NO_PUSHBUTTON
00290     printf( "-- : DBG key 1 2 used as buttons\n\r" );
00291     printf( "-- : 1st press to push, 2nd press to release\n\r" );
00292 #else
00293     PIO_Configure( pinsButtons, PIO_LISTSIZE( pinsButtons ) ) ;
00294 #endif
00295 
00296     /* HID driver initialization */
00297     HIDDTransferDriver_Initialize( &hiddTransferDriverDescriptors ) ;
00298 
00299     /* connect if needed */
00300      USBD_Connect();
00301 
00302     /* Infinite loop */
00303     while ( 1 ) {
00304         if ( USBD_GetState() < USBD_STATE_CONFIGURED ) {
00305             continue ;
00306         }
00307         update = 0 ;
00308         dwLen = HIDDTransferDriver_Read( iBuffer, 64 ) ;
00309         if ( dwLen ) {
00310             printf( "Data In(%u):",(unsigned int) dwLen ) ;
00311             _ShowBuffer( iBuffer, dwLen ) ;
00312 
00313             bmLEDs = iBuffer[0] ;
00314             update = 1 ;
00315         }
00316         dwLen = HIDDTransferDriver_ReadReport( iBuffer, 64 ) ;
00317         if ( dwLen ) {
00318             printf( "Report In(%u):", (unsigned int)dwLen ) ;
00319             _ShowBuffer( iBuffer, dwLen ) ;
00320 
00321             bmLEDs = iBuffer[0] ;
00322             update = 1 ;
00323         }
00324         /* Update the status of LEDs */
00325         if ( update && (0x80 & bmLEDs) ) {
00326             /* LED1 */
00327             if ( bmLEDs & 0x01 ) {
00328                 LED_Set( LED_YELLOW0 ) ;
00329             } else {
00330                 LED_Clear( LED_YELLOW0 ) ;
00331             }
00332 
00333             /* LED2 */
00334             if ( bmLEDs & 0x02 ) {
00335                 LED_Set( LED_YELLOW1 ) ;
00336             } else {
00337                 LED_Clear( LED_YELLOW1 ) ;
00338             }
00339         }
00340         /* Update the status of the buttons */
00341 #ifdef NO_PUSHBUTTON
00342         if ( DBG_IsRxReady( ) ) {
00343             uint8_t key = DBG_GetChar( ) ;
00344             switch( key ) {
00345             case '1' :
00346                 if (oBuffer[0] & 0x01) oBuffer[0] &= ~0x01u ;
00347                 else                   oBuffer[0] |=  0x01u ;
00348                 break ;
00349             case '2' :
00350                 if (oBuffer[0] & 0x02) oBuffer[0] &= ~0x02u ;
00351                 else                   oBuffer[0] |=  0x02u ;
00352                 break ;
00353             }
00354         }
00355 #else
00356         oBuffer[0] = 0x80 ;
00357         if ( PIO_Get( &pinsButtons[PUSHBUTTON_BP1]) == 0 ) {
00358             oBuffer[0] |= 0x01 ;
00359         }
00360         if ( PIO_Get( &pinsButtons[PUSHBUTTON_BP2] ) == 0 ) {
00361             oBuffer[0] |= 0x02 ;
00362         }
00363 #endif
00364 
00365         sprintf( (char*)&oBuffer[5], ":%04x:%05u!", 
00366                 (unsigned int)dwCnt, (unsigned int)dwCnt ) ;
00367         oBuffer[1] = (uint8_t)(dwCnt) ;
00368         oBuffer[2] = (uint8_t)(dwCnt >> 8) ;
00369         oBuffer[3] = (uint8_t)(dwCnt >> 16) ;
00370         oBuffer[4] = (uint8_t)(dwCnt >> 24) ;
00371         if ( USBD_STATUS_SUCCESS == HIDDTransferDriver_Write( oBuffer, 64, 0, 0 ) ) {
00372             dwCnt ++ ;
00373         }
00374     }
00375 }
00376 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines