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_iad_cdc_hid
00031  * \page usb_iad_cdc_hid USB CDC(Serial)+HID(Keyboard) Example
00032  *
00033  * \section Purpose
00034  *
00035  * The USB CDCHID Project will help you to get familiar with the
00036  * USB Device Port(UDP)interface .Also it can help you to be familiar with the USB
00037  * Framework that is used for rapid development of USB-compliant class
00038  * drivers such as USB Communication Device class (CDC), and how to combine
00039  * two USB functions to a single composite device (such as CDC + 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 win_drv_update Windows Driver Update
00047  *
00048  * The composite device is generally supported by Microsoft windows, but some
00049  * patches are needed for muti-interface functions such as CDC & Audio.
00050  *
00051  * \section Description
00052  *
00053  * This demo simulates a USB composite device that has USB Serial RS232
00054  * Converter and USB HID Keyboard functions.
00055  *
00056  * When the board running this program connected to a host (PC for example), with
00057  * USB cable, host will notice the attachment of a USB device. No device
00058  * driver offered for the device now.
00059  *
00060  * \section Usage
00061  *
00062  *  -# Build the program and download it inside the board.
00063  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00064  * -# On the computer, open and configure a terminal application
00065  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00066  *   - 115200 baud rate
00067  *   - 8 bits of data
00068  *   - No parity
00069  *   - 1 stop bit
00070  *   - No flow control
00071  * -# Start the application.
00072  * -# In the terminal window, the following text should appear:
00073  *     \code
00074  *     -- USB CDC HID Device Project xxx --
00075  *     -- SAMxxxxx-xx
00076  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00077  *     \endcode
00078  * -# When connecting USB cable to windows, the LED blinks, and the host
00079  *    reports a new USB device attachment.
00080  * -# For the windows driver installation and the test functions, please
00081  *      refer to "USB CDC serial converter" &
00082  *      "USB HID Keyboard Project".
00083  * -# You can use the inf file
00084  *    libraries\\usb\\device\\composite\\drv\\CompositeCDCSerial.inf
00085  *    to install the CDC serial  port.
00086  *
00087  * \section Reference
00088  * - usb_iad_cdc_hid/main.c
00089  * - pio: Pin configurations and peripheral configure.
00090  * - usb: USB Device Framework, USB CDC driver and UDP interface driver
00091  *    - \ref usbd_framework
00092  *        - \ref usbd_api
00093  *    - \ref usbd_composite "composite"
00094  *       - \ref usbd_composite_drv
00095  *    - \ref usbd_hid "hid" \\ \ref usbd_hid_key "hid-keyboard"
00096  *       - \ref usbd_hid_kbd_drv
00097  *    - \ref usbd_cdc "cdc-serial"
00098  *       - \ref usbd_cdc_serial_drv
00099  * - projects:
00100  *    - \ref usb_hid_keyboard
00101  *    - \ref usb_cdc_serial
00102  *
00103  */
00104 
00105 /**
00106  * \file
00107  *
00108  * This file contains all the specific code for the
00109  * usb_iad_cdc_hid project
00110  */
00111 
00112 /*----------------------------------------------------------------------------
00113  *        Headers
00114  *----------------------------------------------------------------------------*/
00115 
00116 #include "board.h"
00117 
00118 #include <USBD_Config.h>
00119 #include <USBD_LEDs.h>
00120 
00121 #include <CDCHIDDDriver.h>
00122 #include <CDCDSerial.h>
00123 #include <HIDDKeyboard.h>
00124 
00125 #include <string.h>
00126 #include <stdbool.h>
00127 #include <stdint.h>
00128 #include <stdio.h>
00129 
00130 /*---------------------------------------------------------------------------
00131  *      Definitions
00132  *---------------------------------------------------------------------------*/
00133 #define NO_PUSHBUTTON
00134 /** Number of keys used in the example. */
00135 #define NUM_KEYS                    2
00136 
00137 /** Number of non-modifiers keys. */
00138 #define NUM_NORMAL_KEYS             1
00139 
00140 /** Number of modifier keys. */
00141 #define NUM_MODIFIER_KEYS           (NUM_KEYS - NUM_NORMAL_KEYS)
00142 
00143 /** NumLock LED index. */
00144 #define LED_NUMLOCK                 USBD_LEDOTHER
00145 
00146 /** Size in bytes of the packet used for reading data from USB */
00147 #define DATAPACKETSIZE \
00148     CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)
00149 
00150 /** Size in bytes of the buffer used for reading data from the USB & USART */
00151 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00152 
00153 /*----------------------------------------------------------------------------
00154  *      External variables
00155  *----------------------------------------------------------------------------*/
00156 
00157 extern const USBDDriverDescriptors cdchiddDriverDescriptors;
00158 
00159 /*---------------------------------------------------------------------------
00160  *      Internal variables
00161  *---------------------------------------------------------------------------*/
00162 
00163 /** Buffer for storing incoming USB data. */
00164 COMPILER_ALIGNED(32) static unsigned char usbSerialBuffer0[DATABUFFERSIZE];
00165 
00166 /** Serial port opened */
00167 static unsigned char isSerialPortON = 0;
00168 
00169 /*- HID */
00170 
00171 #ifdef NO_PUSHBUTTON
00172 #else
00173 /** List of pinsPushButtons to configure for the application. */
00174 static Pin pinsPushButtons[] = {PINS_PUSHBUTTONS};
00175 #endif
00176 
00177 /** Array of key codes produced by each button. */
00178 static uint8_t keyCodes[NUM_KEYS] = {
00179     HIDKeypad_A,
00180     HIDKeypad_NUMLOCK,
00181 };
00182 
00183 /** Current status (pressed or not) for each key. */
00184 static uint8_t keyStatus[NUM_KEYS];
00185 
00186 /*-----------------------------------------------------------------------------
00187  *         Callback re-implementation
00188  *-----------------------------------------------------------------------------*/
00189 
00190 
00191 
00192 /**
00193  * Invoked when the configuration of the device changes. Parse used endpoints.
00194  * \param cfgnum New configuration number.
00195  */
00196 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00197 {
00198     CDCHIDDDriver_ConfigurationChangedHandler(cfgnum);
00199 }
00200 
00201 /**
00202  * Invoked when a new SETUP request is received from the host. Forwards the
00203  * request to the Mass Storage device driver handler function.
00204  * \param request  Pointer to a USBGenericRequest instance.
00205  */
00206 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00207 {
00208     CDCHIDDDriver_RequestHandler(request);
00209 }
00210 
00211 /*----------------------------------------------------------------------------
00212  *         Callbacks
00213  *----------------------------------------------------------------------------*/
00214 
00215 /**
00216  * Invoked when the CDC ControlLineState is changed
00217  * \param DTR   New DTR value.
00218  * \param RTS   New RTS value.
00219  */
00220 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00221                                         uint8_t RTS)
00222 {
00223     isSerialPortON = DTR;
00224     RTS = RTS; /* dummy */
00225 }
00226 
00227 /**
00228  * Invoked when the status of the keyboard LEDs changes. Turns the num. lock
00229  * LED on or off.
00230  * \param numLockStatus Indicates the current status of the num. lock key.
00231  * \param capsLockStatus Indicates the current status of the caps lock key.
00232  * \param scrollLockStatus Indicates the current status of the scroll lock key
00233  */
00234 void HIDDKeyboardCallbacks_LedsChanged(
00235     uint8_t numLockStatus,
00236     uint8_t capsLockStatus,
00237     uint8_t scrollLockStatus)
00238 {
00239     capsLockStatus = capsLockStatus;
00240     scrollLockStatus = scrollLockStatus;
00241 
00242     /* Num. lock */
00243     if (numLockStatus)
00244         LED_Set(LED_NUMLOCK);
00245     else
00246         LED_Clear(LED_NUMLOCK);
00247 }
00248 
00249 /*---------------------------------------------------------------------------
00250  *         Internal functions
00251  *---------------------------------------------------------------------------*/
00252 
00253 /**
00254  * Monitor keyboard buttons & Update key status in HID driver
00255  */
00256 static void _HIDDKeyboardProcessKeys(void)
00257 {
00258     uint32_t i;
00259     uint8_t pressedKeys[NUM_KEYS];
00260     uint8_t pressedKeysSize = 0;
00261     uint8_t releasedKeys[NUM_KEYS];
00262     uint8_t releasedKeysSize = 0;
00263 
00264     /* Monitor buttons */
00265 #ifdef NO_PUSHBUTTON
00266 
00267     if (DBG_IsRxReady()) {
00268         uint8_t key = DBG_GetChar();
00269 
00270         switch (key) {
00271         case '1': case '2':
00272             i = key - '1';
00273 
00274             if (keyStatus[i]) {
00275                 /* Key press simulation */
00276                 TRACE_INFO("Key %u pressed\n\r", (unsigned int)i);
00277                 keyStatus[i] = 0;
00278                 pressedKeys[pressedKeysSize] = keyCodes[i];
00279                 pressedKeysSize ++;
00280                 HIDDKeyboard_RemoteWakeUp();
00281             } else {
00282                 /* Key release simulation */
00283                 TRACE_INFO("Key %u released\n\r", (unsigned int)i);
00284                 keyStatus[i] = 1;
00285                 releasedKeys[releasedKeysSize] = keyCodes[i];
00286                 releasedKeysSize++;
00287             }
00288 
00289             break;
00290 
00291         default: DBG_PutChar(key);
00292         }
00293     }
00294 
00295 #else
00296 
00297     for (i = 0; i < PIO_LISTSIZE(pinsPushButtons); i++) {
00298         /* Check if button state has changed */
00299         uint8_t isButtonPressed = PIO_Get(&(pinsPushButtons[i]));
00300 
00301         if (isButtonPressed != keyStatus[i]) {
00302             /* Update button state */
00303             if (!isButtonPressed) {
00304                 /* Key has been pressed */
00305                 TRACE_INFO("Key %u has been pressed\n\r", i);
00306                 keyStatus[i] = 0;
00307                 pressedKeys[pressedKeysSize] = keyCodes[i];
00308                 pressedKeysSize++;
00309                 HIDDKeyboard_RemoteWakeUp();
00310             } else {
00311                 /* Key has been released */
00312                 TRACE_INFO("Key %u has been released\n\r", i);
00313                 keyStatus[i] = 1;
00314                 releasedKeys[releasedKeysSize] = keyCodes[i];
00315                 releasedKeysSize++;
00316             }
00317         }
00318     }
00319 
00320 #endif
00321 
00322     /* Update key status in the HID driver if necessary */
00323     if ((pressedKeysSize != 0) || (releasedKeysSize != 0)) {
00324         uint8_t status;
00325 
00326         do {
00327             status = HIDDKeyboard_ChangeKeys(pressedKeys,
00328                                              pressedKeysSize,
00329                                              releasedKeys,
00330                                              releasedKeysSize);
00331         } while (status != USBD_STATUS_SUCCESS);
00332     }
00333 }
00334 
00335 /**
00336  * Configure USBHS settings for USB device
00337  */
00338 static void _ConfigureUotghs(void)
00339 {
00340     /* UTMI parallel mode, High/Full/Low Speed */
00341     /* UUSBCK not used in this configuration (High Speed) */
00342     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00343     /* USB clock register: USB Clock Input is UTMI PLL */
00344     PMC->PMC_USB = PMC_USB_USBS;
00345     /* Enable peripheral clock for USBHS */
00346     PMC_EnablePeripheral(ID_USBHS);
00347     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00348     /* Enable PLL 480 MHz */
00349     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00350 
00351     /* Wait that PLL is considered locked by the PMC */
00352     while (!(PMC->PMC_SR & PMC_SR_LOCKU));
00353 
00354     /* IRQ */
00355     NVIC_EnableIRQ(USBHS_IRQn);
00356 }
00357 
00358 /*---------------------------------------------------------------------------
00359  *         Exported function
00360  *---------------------------------------------------------------------------*/
00361 /**
00362  * Initializes drivers and start the USB CDCHID device.
00363  */
00364 int main(void)
00365 {
00366     uint8_t usbConnected = 0, serialON = 0;
00367 
00368     /* Disable watchdog */
00369     WDT_Disable(WDT);
00370 
00371     SCB_EnableICache();
00372     SCB_EnableDCache();
00373 
00374     printf("-- USB CDC HID Device Project %s --\n\r", SOFTPACK_VERSION);
00375     printf("-- %s\n\r", BOARD_NAME);
00376     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00377             COMPILER_NAME);
00378 
00379     /* If they are present, configure Vbus & Wake-up pins */
00380     PIO_InitializeInterrupts(0);
00381 
00382     /* If there is on board power, switch it off */
00383     _ConfigureUotghs();
00384 
00385     /* ----- HID Function Initialize */
00386 #ifdef NO_PUSHBUTTON
00387     printf("-- : DBG key 1 2 used as buttons\n\r");
00388     printf("-- : 1st press to push, 2nd press to release\n\r");
00389 #else
00390     /* Initialize key statuses and configure push buttons */
00391     PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
00392 #endif
00393     memset(keyStatus, 1, NUM_KEYS);
00394 
00395     /* Configure LEDs */
00396     LED_Configure(LED_NUMLOCK);
00397 
00398 
00399     /* USB CDCHID driver initialization */
00400     CDCHIDDDriver_Initialize(&cdchiddDriverDescriptors);
00401 
00402     /* connect if needed */
00403     USBD_Connect();
00404 
00405     /* Driver loop */
00406     while (1) {
00407         /* Device is not configured */
00408         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00409             if (usbConnected) {
00410                 printf("-I- USB Disconnect/Suspend\n\r");
00411                 usbConnected = 0;
00412                 /* Serial port closed */
00413                 isSerialPortON = 0;
00414             }
00415         } else {
00416             if (usbConnected == 0) {
00417                 printf("-I- USB Connect\n\r");
00418                 usbConnected = 1;
00419             }
00420 
00421             if (!serialON && isSerialPortON) {
00422                 printf("-I- SerialPort ON\n\r");
00423                 /* Start receiving data on the USB */
00424                 CDCDSerial_Read(usbSerialBuffer0,
00425                                 DATAPACKETSIZE,
00426                                 0,
00427                                 0);
00428                 serialON = 1;
00429             } else if (serialON && !isSerialPortON) {
00430                 printf("-I- SeriaoPort OFF\n\r");
00431                 serialON = 0;
00432             }
00433 
00434             _HIDDKeyboardProcessKeys();
00435         }
00436     }
00437 }
00438 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines