SAMV71 Xplained Ultra Software Package 1.5

main.c

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