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_mouse 00030 * \page usb_hid_mouse USB HID Mouse Example 00031 * 00032 * \section Purpose 00033 * 00034 * The USB HID Mouse Example 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 and have push button or joystick on it. 00044 * 00045 * \section Description 00046 * 00047 * When an Xplained running this program connected to a host (PC for example), 00048 * with USB cable, the Xplained appears as a HID-compliant mouse for the host. 00049 * Then you can use the joystick or buttons on the Xplained to control the 00050 * pointer on the host. * E.g., to move it. 00051 * 00052 * \section Usage 00053 * 00054 * -# Build the program and download it inside the SAM V71 Xplained Ultra board. 00055 * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf 00056 * -# On the computer, open and configure a terminal application 00057 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00058 * - 115200 bauds 00059 * - 8 bits of data 00060 * - No parity 00061 * - 1 stop bit 00062 * - No flow control 00063 * -# Start the application. 00064 * -# In the terminal window, the following text should appear: 00065 * \code 00066 * -- USB Device HID Mouse Project xxx -- 00067 * -- SAMxxxxx-xx 00068 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00069 * \endcode 00070 * -# When connecting USB cable to windows, the 00071 * new "HID Mouse Device" appears in the 00072 * hardware %device list. 00073 * -# Once the device is connected and configured, pressing the joystick or 00074 * the configured board buttons move the cursor. 00075 * 00076 * \section References 00077 * - usb_hid_mouse/main.c 00078 * - pio: PIO interface driver 00079 * - pio.h 00080 * - pio_it.h 00081 * - usb: USB Framework, USB HID driver and UDP interface driver 00082 * - \ref usbd_framework 00083 * - \ref usbd_api 00084 * - hid-mouse 00085 * - \ref usbd_hid_mouse_drv 00086 * 00087 */ 00088 00089 /** 00090 * \file 00091 * 00092 * This file contains all the specific code for the 00093 * usb_hid_mouse 00094 * 00095 * \section Contents 00096 * 00097 * The code can be roughly broken down as follows: 00098 * - Configuration functions 00099 * - USB configuration 00100 * - PIO & Timer configurations in start of main 00101 * - Interrupt handlers 00102 * - The main function, which implements the program behaviour 00103 */ 00104 00105 /*----------------------------------------------------------------------------- 00106 * Headers 00107 *-----------------------------------------------------------------------------*/ 00108 00109 #include "board.h" 00110 00111 #include "USBD.h" 00112 #include "HIDDMouseDriver.h" 00113 00114 #include <string.h> 00115 #include <stdbool.h> 00116 #include <stdint.h> 00117 00118 /*---------------------------------------------------------------------------- 00119 * Definitions 00120 *----------------------------------------------------------------------------*/ 00121 00122 #define NO_PUSHBUTTON 00123 00124 /** Speed of pointer movement X */ 00125 #define SPEED_X 4 00126 00127 /** Speed of pointer movement Y */ 00128 #define SPEED_Y 4 00129 00130 /*---------------------------------------------------------------------------- 00131 * External variables 00132 *----------------------------------------------------------------------------*/ 00133 00134 extern USBDDriverDescriptors hiddMouseDriverDescriptors; 00135 00136 /*---------------------------------------------------------------------------- 00137 * Internal variables 00138 *----------------------------------------------------------------------------*/ 00139 00140 #ifndef NO_PUSHBUTTON 00141 /** List of pinsJoystick (push button) to configure for the application. */ 00142 static Pin pinsJoystick[] = {PINS_PUSHBUTTONS}; 00143 #endif 00144 00145 /*---------------------------------------------------------------------------- 00146 * Remote wake-up support (optional) 00147 *----------------------------------------------------------------------------*/ 00148 00149 00150 /** 00151 * Monitor buttons of joystick status. 00152 * \param pBtnStatus Pointer to button status bitmap. 00153 * \param pDx Pointer to fill x value. 00154 * \param pDy Pointer to fill y value. 00155 */ 00156 static uint8_t _ButtonsMonitor(uint8_t *pBtnStatus, 00157 int8_t *pDx, 00158 int8_t *pDy) 00159 { 00160 uint8_t isChanged = 0; 00161 pBtnStatus = pBtnStatus; /*dummy */ 00162 #ifdef NO_PUSHBUTTON 00163 /* - Movement W S A D */ 00164 if (DBG_IsRxReady()) { 00165 uint8_t key = DBG_GetChar(); 00166 *pDx = 0; *pDy = 0; 00167 switch (key) { 00168 case 'w': case 'W': 00169 *pDy = -SPEED_Y; isChanged = 1; 00170 break; 00171 case 's': case 'S': 00172 *pDy = +SPEED_Y; isChanged = 1; 00173 break; 00174 case 'a': case 'A': 00175 *pDx = -SPEED_X; isChanged = 1; 00176 break; 00177 case 'd': case 'D': 00178 *pDx = +SPEED_X; isChanged = 1; 00179 break; 00180 default: 00181 break; 00182 } 00183 } 00184 #else 00185 /* - Movement buttons, Joystick or Push buttons */ 00186 /* Left */ 00187 if (PIO_Get(&pinsJoystick[JOYSTICK_LEFT]) == 0) { 00188 *pDx = -SPEED_X; 00189 isChanged = 1; 00190 } 00191 /* Right */ 00192 else if (PIO_Get(&pinsJoystick[JOYSTICK_RIGHT]) == 0) { 00193 *pDx = SPEED_X; 00194 isChanged = 1; 00195 } else { 00196 *pDx = 0; 00197 } 00198 #endif 00199 return isChanged; 00200 } 00201 00202 /*---------------------------------------------------------------------------- 00203 * Callbacks re-implementation 00204 *----------------------------------------------------------------------------*/ 00205 00206 /** 00207 * Invoked whenever a SETUP request is received from the host. Forwards the 00208 * request to the standard handler. 00209 */ 00210 void USBDCallbacks_RequestReceived(const USBGenericRequest *request) 00211 { 00212 HIDDMouseDriver_RequestHandler(request); 00213 } 00214 00215 /** 00216 * Invoked when the configuration of the device changes. Start reading 00217 * output reports. 00218 * \param cfgnum New configuration number. 00219 */ 00220 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum) 00221 { 00222 HIDDMouseDriver_ConfigurationChangedHandler(cfgnum); 00223 } 00224 00225 /*---------------------------------------------------------------------------- 00226 * Internal functions 00227 *----------------------------------------------------------------------------*/ 00228 /** 00229 * Configure USB settings for USB device 00230 */ 00231 static void _ConfigureUotghs(void) 00232 { 00233 00234 /* UTMI parallel mode, High/Full/Low Speed */ 00235 /* UUSBCK not used in this configuration (High Speed) */ 00236 PMC->PMC_SCDR = PMC_SCDR_USBCLK; 00237 /* USB clock register: USB Clock Input is UTMI PLL */ 00238 PMC->PMC_USB = PMC_USB_USBS; 00239 /* Enable peripheral clock for USBHS */ 00240 PMC_EnablePeripheral(ID_USBHS); 00241 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE; 00242 /* Enable PLL 480 MHz */ 00243 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF); 00244 /* Wait that PLL is considered locked by the PMC */ 00245 while( !(PMC->PMC_SR & PMC_SR_LOCKU) ); 00246 00247 /* IRQ */ 00248 NVIC_EnableIRQ(USBHS_IRQn) ; 00249 } 00250 00251 /*---------------------------------------------------------------------------- 00252 * Exported function 00253 *----------------------------------------------------------------------------*/ 00254 00255 /** 00256 * usb_hid_mouse application entry. 00257 * 00258 * Initializes the system and then monitors buttons, sending the 00259 * corresponding character when one is pressed. 00260 */ 00261 int main(void) 00262 { 00263 uint8_t bmButtons = 0; 00264 int8_t dX = 0, dY = 0; 00265 uint8_t isChanged; 00266 uint32_t st=0; 00267 00268 /* Disable watchdog */ 00269 WDT_Disable( WDT ); 00270 00271 SCB_EnableICache(); 00272 SCB_EnableDCache(); 00273 00274 printf("-- USB Device HID Mouse Project %s --\n\r", SOFTPACK_VERSION); 00275 printf("-- %s\n\r", BOARD_NAME); 00276 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ; 00277 00278 /* If they are present, configure Vbus & Wake-up pins */ 00279 PIO_InitializeInterrupts(0); 00280 00281 /* Initialize all USB power (off) */ 00282 _ConfigureUotghs(); 00283 00284 #ifdef NO_PUSHBUTTON 00285 printf("-- Press W S A D to move cursor\n\r"); 00286 #else 00287 /* Initialize key statuses and configure push buttons */ 00288 PIO_Configure(pinsJoystick, PIO_LISTSIZE(pinsJoystick)); 00289 #endif 00290 00291 /* HID driver initialization */ 00292 HIDDMouseDriver_Initialize(&hiddMouseDriverDescriptors); 00293 00294 // Start USB stack to authorize VBus monitoring 00295 USBD_Connect(); 00296 00297 /* Infinite loop */ 00298 while (1) { 00299 if (USBD_GetState() < USBD_STATE_CONFIGURED) 00300 continue; 00301 isChanged = _ButtonsMonitor(&bmButtons, &dX, &dY); 00302 00303 if (isChanged) { 00304 uint8_t status; 00305 do { 00306 status = HIDDMouseDriver_ChangePoints(bmButtons, 00307 dX, dY); 00308 } while (status != USBD_STATUS_SUCCESS); 00309 } 00310 } 00311 } 00312 /** \endcond */