SAM3S8/SD8 Software Package: examples_usb/usb_hid_msd/main.c Source File

SAM3S8/SD8 Software Package 1.2

# main.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2008, 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
    00030 /**
    00031  * \page usb_hid_msd USB Composite HID+MSD Example
    00032  *
    00033  * \section Purpose
    00034  *
    00035  * The USB COMPOSITE Project will help you to get familiar with the
    00036  * USB Device Port(UDP)interface and also some of the other interfaces in
    00037  * SAM microcontrollers. Also it can help you to be familiar with the USB
    00038  * Framework that is used for rapid development of USB-compliant class
    00039  * drivers such as USB Communication Device class (CDC), and how to combine
    00040  * two USB functions to a single composite device (such as CDC + MSD).
    00041  *
    00042  * \section Related
    00043  * - pio: Pin configurations and peripheral configure.
    00044  * - memories: Storage Media interface for MSD
    00045  * - usb: USB Device Framework, USB CDC driver and UDP interface driver
    00046  *    - \ref usbd_framework
    00047  *        - \ref usbd_api
    00048  *    - \ref usbd_composite "composite"
    00049  *       - \ref usbd_composite_drv
    00050  *    - \ref usbd_hid "hid" \\ \ref usbd_hid_key "hid-keyboard"
    00051  *       - \ref usbd_hid_kbd_drv
    00052  *    - \ref usbd_msd "massstorage"
    00053  *       - \ref usbd_msd_drv
    00054  * - projects:
    00055  *    - \ref usb_hid_keyboard
    00056  *    - \ref usb_massstorage
    00057  *
    00058  * You can find following information depends on your needs:
    00059  * - Sample usage of USB Device Framework.
    00060  * - USB COMPOSITE device and functions driver development based on the
    00061  *   USB Device Framework and other re-usable class driver code.
    00062  * - USB enumerate sequence, the standard and class-specific descriptors and
    00063  *   requests handling.
    00064  * - The initialize sequence and usage of UDP interface.
    00065  *
    00066  * \section Requirements
    00067  *
    00068  * This package can be used with some of Atmel evaluation kits that have UDP
    00069  * interface, depending on the functions included.
    00070  *
    00071  *  \section win_drv_update Windows Driver Update
    00072  *
    00073  * The composite device is generally supported by Microsoft windows, but some
    00074  * patches are needed for muti-interface functions such as CDC & Audio. The
    00075  * example composite devices are tested under windows XP (SP3). For CDC
    00076  * serial port, additional windows driver file (CompositeCDCSerial.inf) can
    00077  * be found at libraries\\usb\\device\\composite\\drv.
    00078  *
    00079  * The following is alternate update to fix the composite device support
    00080  * on windows XP:
    00081  *
    00082  * \subsection install_win_sp3 Install Windows Service Pack 3 (SP3)
    00083  *
    00084  * All the fixes for USB generic driver are included in window XP service pack
    00085  * 3. It can be found at
    00086  * http://technet.microsoft.com/zh-cn/windows/bb794714(en-us).aspx .
    00087  *
    00088  * \subsection install_win_hotfix Install Windows Hot Fixes
    00089  *
    00090  * Two hot fixes are necessary for window to recognize the composite device
    00091  * correctly:
    00092  *
    00093  * -# http://support.microsoft.com/kb/814560
    00094  * -# http://support.microsoft.com/kb/918365
    00095  *
    00096  * \section Description
    00097  *
    00098  * When an EK running this program connected to a host (PC for example), with
    00099  * USB cable, host will notice the attachment of a USB %device. No %device
    00100  * driver offered for the %device now.
    00101  *
    00102  * \section Usage
    00103  *
    00104  * -# Build the program and download it inside the evaluation board. Please
    00105  *    refer to the
    00106  *    <a href="http://www.atmel.com/dyn/resources/prod_documents/6421B.pdf">
    00107  *    SAM-BA User Guide</a>, the
    00108  *    <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
    00109  *    GNU-Based Software Development</a> application note or to the
    00110  *    <a href="http://www.iar.com/website1/1.0.1.0/78/1/">
    00111  *    IAR EWARM User and reference guides</a>, depending on your chosen solution.
    00112  * -# On the computer, open and configure a terminal application
    00113  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
    00114  *   - 115200 bauds
    00115  *   - 8 bits of data
    00116  *   - No parity
    00117  *   - 1 stop bit
    00118  *   - No flow control
    00119  * -# Start the application.
    00120  * -# In the terminal window, the following text should appear:
    00121  *     \code
    00122  *     -- USB HID MSD Device Example xxx --
    00123  *     -- xxxxxx-xx
    00124  *     -- Compiled: xxx xx xxxx xx:xx:xx --
    00125  *     \endcode
    00126  * -# When connecting USB cable to windows, the LED blinks, and the host
    00127  *    reports a new USB %device attachment.
    00128  * -# For the windows driver installation and the test functions, please
    00129  *      refer to "USB HID Keyboard Example" &
    00130  *      "USB Device Mass Storage Example".
    00131  *
    00132  */
    00133
    00134 /**
    00135  * \file
    00136  *
    00137  * This file contains all the specific code for the
    00138  * usb_hid_msd
    00139  *
    00140  * \section Contents
    00141  *
    00142  * The code can be roughly broken down as follows:
    00143  *    - Configuration functions
    00144  *       - VBus_Configure
    00145  *       - PIO configurations in start of main
    00146  *    - Interrupt handlers
    00147  *       - ISR_Vbus
    00148  *    - Callback functions
    00149  *       - USBDCallbacks_RequestReceived
    00150  *    - The main function, which implements the program behavior
    00151  */
    00152
    00153 /*----------------------------------------------------------------------------
    00154  *        Headers
    00155  *----------------------------------------------------------------------------*/
    00156
    00157 #include "board.h"
    00158
    00159 #include <memories.h>
    00160
    00161 #include <include/USBD_Config.h>
    00162 #include <include/USBD_LEDs.h>
    00163
    00164 #include <HIDMSDDriver.h>
    00165 #include <HIDDKeyboard.h>
    00166 #include <MSDFunction.h>
    00167
    00168 #include <string.h>
    00169 #include <stdbool.h>
    00170 #include <stdint.h>
    00171 #include <stdio.h>
    00172
    00173 /*---------------------------------------------------------------------------
    00174  *      Definitions
    00175  *---------------------------------------------------------------------------*/
    00176
    00177 /** Master clock frequency in Hz */
    00178 #define MCK                         BOARD_MCK
    00179
    00180 /** Number of keys used in the example. */
    00181 #define NUM_KEYS                    2
    00182
    00183 /** Number of non-modifiers keys. */
    00184 #define NUM_NORMAL_KEYS             1
    00185
    00186 /** Number of modifier keys. */
    00187 #define NUM_MODIFIER_KEYS           (NUM_KEYS - NUM_NORMAL_KEYS)
    00188
    00189 /** Num lock LED index. */
    00190 #define LED_NUMLOCK                 USBD_LEDOTHER
    00191
    00192
    00193 /** Maximum number of LUNs which can be defined. */
    00194 #define MAX_LUNS            1
    00195 /** Media index for different disks */
    00196 #define DRV_NAND            0    /**< Nand flash */
    00197
    00198 /** Size of one block in bytes. */
    00199 #define BLOCK_SIZE          512
    00200
    00201 /** Size of the MSD IO buffer in bytes (6K, more the better). */
    00202 #define MSD_BUFFER_SIZE     (12*BLOCK_SIZE)
    00203
    00204 /** Size of the reserved Nand Flash (4M) */
    00205 #define NF_RESERVE_SIZE     (4*1024*1024)
    00206
    00207 /** Size of the managed Nand Flash (128M) */
    00208 #define NF_MANAGED_SIZE     (128*1024*1024)
    00209
    00210 /** Delay loop for MSD refresh */
    00211 #define MSD_REFRESH_LOOP    500000
    00212
    00213 /*----------------------------------------------------------------------------
    00214  *        External variables
    00215  *----------------------------------------------------------------------------*/
    00216
    00217 /** Descriptor list for device enumeration */
    00218 extern const USBDDriverDescriptors hidmsddDriverDescriptors;
    00219
    00220 /*----------------------------------------------------------------------------
    00221  *        Global variables
    00222  *----------------------------------------------------------------------------*/
    00223
    00224 /*- HID */
    00225 /** List of pinsPushButtons to configure for the applicatino. */
    00226 static Pin pinsPushButtons[] = {PINS_PUSHBUTTONS};
    00227
    00228 /** Array of key codes produced by each button. */
    00229 static uint8_t keyCodes[NUM_KEYS] = {
    00230     HIDKeypad_A,
    00231     HIDKeypad_NUMLOCK,
    00232     //HIDKeypad_9,
    00233     //HIDKeypad_RIGHTSHIFT
    00234 };
    00235
    00236 /** Current status (pressed or not) for each key. */
    00237 static uint8_t keyStatus[NUM_KEYS];
    00238
    00239 /*- MSD */
    00240 /** Available medias. */
    00241 Media medias[MAX_LUNS];
    00242
    00243 /** Device LUNs. */
    00244 MSDLun luns[MAX_LUNS];
    00245
    00246 /** LUN read/write buffer. */
    00247 uint8_t msdBuffer[MSD_BUFFER_SIZE];
    00248
    00249 /** Total data write to disk */
    00250 uint32_t msdWriteTotal = 0;
    00251 /** Delay for data write refresh */
    00252 uint32_t msdRefreshDelay = MSD_REFRESH_LOOP;
    00253
    00254 /** Pins used to access to nandflash. */
    00255 static const Pin pPinsNf[] = {PINS_NANDFLASH};
    00256 /** Nandflash device structure. */
    00257 static struct TranslatedNandFlash translatedNf;
    00258 /** Address for transferring command bytes to the nandflash. */
    00259 static uint32_t cmdBytesAddr = BOARD_NF_COMMAND_ADDR;
    00260 /** Address for transferring address bytes to the nandflash. */
    00261 static uint32_t addrBytesAddr = BOARD_NF_ADDRESS_ADDR;
    00262 /** Address for transferring data bytes to the nandflash. */
    00263 static uint32_t dataBytesAddr = BOARD_NF_DATA_ADDR;
    00264 /** Nandflash chip enable pin. */
    00265 static const Pin nfCePin = BOARD_NF_CE_PIN;
    00266 /** Nandflash ready/busy pin. */
    00267 static const Pin nfRbPin = BOARD_NF_RB_PIN;
    00268
    00269 /*----------------------------------------------------------------------------
    00270  *         Remote wake-up support (optional)
    00271  *----------------------------------------------------------------------------*/
    00272
    00273 /*----------------------------------------------------------------------------
    00274  *         VBus monitoring (optional)
    00275  *----------------------------------------------------------------------------*/
    00276
    00277 /** VBus pin instance. */
    00278 static const Pin pinVbus = PIN_USB_VBUS;
    00279
    00280 /**
    00281  * \brief Handles interrupts coming from PIO controllers.
    00282  */
    00283 static void ISR_Vbus(const Pin *pPin)
    00284 {
    00285     /* Stop warning */
    00286     pPin = pPin;
    00287
    00288     /* Check current level on VBus */
    00289     if (PIO_Get(&pinVbus)) {
    00290
    00291         TRACE_INFO("VBUS conn\n\r");
    00292         USBD_Connect();
    00293     }
    00294     else {
    00295
    00296         TRACE_INFO("VBUS discon\n\r");
    00297         USBD_Disconnect();
    00298     }
    00299 }
    00300
    00301 /**
    00302  * Configures the VBus pin to trigger an interrupt when the level on that pin
    00303  * changes.
    00304  */
    00305 static void VBus_Configure( void )
    00306 {
    00307     TRACE_INFO("VBus configuration\n\r");
    00308
    00309     /* Configure PIO */
    00310     PIO_Configure(&pinVbus, 1);
    00311     PIO_ConfigureIt(&pinVbus, ISR_Vbus);
    00312     PIO_EnableIt(&pinVbus);
    00313
    00314     /* Check current level on VBus */
    00315     if (PIO_Get(&pinVbus)) {
    00316
    00317         /* if VBUS present, force the connect */
    00318         TRACE_INFO("conn\n\r");
    00319         USBD_Connect();
    00320     }
    00321     else {
    00322         USBD_Disconnect();
    00323     }
    00324 }
    00325
    00326 /*-----------------------------------------------------------------------------
    00327  *         Callback re-implementation
    00328  *-----------------------------------------------------------------------------*/
    00329
    00330 /**
    00331  * Invoked after the USB driver has been initialized. By default, configures
    00332  * the UDP/UDPHS interrupt.
    00333  */
    00334 void USBDCallbacks_Initialized(void)
    00335 {
    00336     NVIC_EnableIRQ(UDP_IRQn);
    00337 }
    00338
    00339 /**
    00340  * Invoked when the configuration of the device changes. Parse used endpoints.
    00341  * \param cfgnum New configuration number.
    00342  */
    00343 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
    00344 {
    00345     HIDMSDDriver_ConfigurationChangedHandler(cfgnum);
    00346 }
    00347
    00348 /**
    00349  * Invoked when a new SETUP request is received from the host. Forwards the
    00350  * request to the Mass Storage device driver handler function.
    00351  * \param request  Pointer to a USBGenericRequest instance.
    00352  */
    00353 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
    00354 {
    00355     HIDMSDDriver_RequestHandler(request);
    00356 }
    00357
    00358 /*----------------------------------------------------------------------------
    00359  *         Callbacks
    00360  *----------------------------------------------------------------------------*/
    00361
    00362 /**
    00363  * Invoked when the MSD finish a READ/WRITE.
    00364  * \param flowDirection 1 - device to host (READ10)
    00365  *                      0 - host to device (WRITE10)
    00366  * \param dataLength Length of data transferred in bytes.
    00367  * \param fifoNullCount Times that FIFO is NULL to wait
    00368  * \param fifoFullCount Times that FIFO is filled to wait
    00369  */
    00370 static void MSDCallbacks_Data(uint8_t flowDirection,
    00371                        uint32_t  dataLength,
    00372                        uint32_t  fifoNullCount,
    00373                        uint32_t  fifoFullCount)
    00374 {
    00375     /* Stop warning */
    00376     fifoNullCount = fifoNullCount;
    00377     fifoFullCount = fifoFullCount;
    00378
    00379     if (!flowDirection) {
    00380
    00381         msdWriteTotal += dataLength;
    00382     }
    00383 }
    00384
    00385 /*---------------------------------------------------------------------------
    00386  *         Internal functions
    00387  *---------------------------------------------------------------------------*/
    00388
    00389 /**
    00390  * Invoked when the status of the keyboard LEDs changes. Turns the num. lock
    00391  * LED on or off.
    00392  * \param numLockStatus Indicates the current status of the num. lock key.
    00393  * \param capsLockStatus Indicates the current status of the caps lock key.
    00394  * \param scrollLockStatus Indicates the current status of the scroll lock key
    00395  */
    00396 void HIDDKeyboardCallbacks_LedsChanged(
    00397     uint8_t numLockStatus,
    00398     uint8_t capsLockStatus,
    00399     uint8_t scrollLockStatus)
    00400 {
    00401     /* Stop warning */
    00402     capsLockStatus = capsLockStatus;
    00403     scrollLockStatus = scrollLockStatus;
    00404
    00405     /* Num. lock */
    00406     if (numLockStatus) {
    00407
    00408         LED_Set(LED_NUMLOCK);
    00409     }
    00410     else {
    00411
    00412         LED_Clear(LED_NUMLOCK);
    00413     }
    00414 }
    00415
    00416 /*---------------------------------------------------------------------------
    00417  *         Internal functions
    00418  *---------------------------------------------------------------------------*/
    00419
    00420 /**
    00421  * Monitor keyboard buttons & Update key status in HID driver
    00422  */
    00423 static void HIDDKeyboardProcessKeys(void)
    00424 {
    00425     uint32_t i;
    00426     uint8_t pressedKeys[NUM_KEYS];
    00427     uint8_t pressedKeysSize = 0;
    00428     uint8_t releasedKeys[NUM_KEYS];
    00429     uint8_t releasedKeysSize = 0;
    00430
    00431     /* Monitor buttons */
    00432     for (i=0; i < PIO_LISTSIZE(pinsPushButtons); i++) {
    00433
    00434         /* Check if button state has changed */
    00435         uint8_t isButtonPressed = PIO_Get(&(pinsPushButtons[i]));
    00436         if (isButtonPressed != keyStatus[i]) {
    00437
    00438             /* Update button state */
    00439             if (!isButtonPressed) {
    00440
    00441                 /* Key has been pressed */
    00442                 TRACE_INFO("-I- Key %u has been pressed\n\r", (unsigned int)i);
    00443                 keyStatus[i] = 0;
    00444                 pressedKeys[pressedKeysSize] = keyCodes[i];
    00445                 pressedKeysSize++;
    00446                 HIDDKeyboard_RemoteWakeUp();
    00447             }
    00448             else {
    00449
    00450                 /* Key has been released */
    00451                 TRACE_INFO("-I- Key %u has been released\n\r", (unsigned int)i);
    00452                 keyStatus[i] = 1;
    00453                 releasedKeys[releasedKeysSize] = keyCodes[i];
    00454                 releasedKeysSize++;
    00455             }
    00456         }
    00457     }
    00458
    00459     /* Update key status in the HID driver if necessary */
    00460     if ((pressedKeysSize != 0) || (releasedKeysSize != 0)) {
    00461
    00462         uint8_t status;
    00463
    00464         do {
    00465
    00466             status = HIDDKeyboard_ChangeKeys(pressedKeys,
    00467                                              pressedKeysSize,
    00468                                              releasedKeys,
    00469                                              releasedKeysSize);
    00470         }
    00471         while (status != USBD_STATUS_SUCCESS);
    00472     }
    00473 }
    00474
    00475 /**
    00476  * Initialize Nand Flash for LUN
    00477  */
    00478 static void NandFlashInitialize(void)
    00479 {
    00480     uint8_t nfRc;
    00481     uint16_t nfBaseBlock = 0;
    00482     struct RawNandFlash *pRaw = (struct RawNandFlash*)&translatedNf;
    00483     struct NandFlashModel *pModel = (struct NandFlashModel*)&translatedNf;
    00484     uint32_t nfMamagedSize;
    00485     uint32_t inputDelay = BOARD_MCK / 16;
    00486
    00487     /* Configure SMC for NandFlash (8-bit) */
    00488     BOARD_ConfigureNandFlash(SMC);
    00489     /* Configure PIO for Nand Flash */
    00490     PIO_Configure(pPinsNf, PIO_LISTSIZE(pPinsNf));
    00491
    00492     /* Nand Flash Initialize (ALL flash mapped) */
    00493     nfRc = RawNandFlash_Initialize(pRaw,
    00494                                    0,
    00495                                    cmdBytesAddr,
    00496                                    addrBytesAddr,
    00497                                    dataBytesAddr,
    00498                                    nfCePin,
    00499                                    nfRbPin);
    00500     if (nfRc) {
    00501         printf("Nand not found\n\r");
    00502         return;
    00503     }
    00504     else {
    00505         printf("NF\tNb Blocks %d\n\r",
    00506                NandFlashModel_GetDeviceSizeInBlocks(pModel));
    00507         printf("\tBlock Size %dK\n\r",
    00508                (int)NandFlashModel_GetBlockSizeInBytes(pModel)/1024);
    00509         printf("\tPage Size %d\n\r",
    00510                NandFlashModel_GetPageDataSize(pModel));
    00511         nfBaseBlock =
    00512             NF_RESERVE_SIZE / NandFlashModel_GetBlockSizeInBytes(pModel);
    00513     }
    00514     printf("NF disk will use area from %dM(B%d)\n\r",
    00515            NF_RESERVE_SIZE/1024/1024, nfBaseBlock);
    00516     printf("!! Erase the NF Disk? (y/n):");
    00517     while(1) {
    00518         if(UART_IsRxReady()) {
    00519             char key = UART_GetChar();
    00520             UART_PutChar(key);
    00521             if (key == 'y') {
    00522                 if (nfRc == 0) {
    00523                     uint32_t block;
    00524                     printf(" Erase from %d ... ", nfBaseBlock);
    00525                     for (block = nfBaseBlock;
    00526                      block < NandFlashModel_GetDeviceSizeInBlocks(pModel);
    00527                      block ++) {
    00528                         RawNandFlash_EraseBlock(pRaw, block);
    00529                     }
    00530                     printf("OK");
    00531                 }
    00532             }
    00533             printf("\n\r");
    00534             break;
    00535         }
    00536         if (inputDelay -- == 0) {
    00537             printf("No\n\r");
    00538             break;
    00539         }
    00540     }
    00541     nfMamagedSize = ((NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024) > NF_MANAGED_SIZE/1024/1024) ? \
    00542                         NF_MANAGED_SIZE/1024/1024 : (NandFlashModel_GetDeviceSizeInMBytes(pModel) - NF_RESERVE_SIZE/1024/1024);
    00543     if (TranslatedNandFlash_Initialize(&translatedNf,
    00544                                        0,
    00545                                        cmdBytesAddr,
    00546                                        addrBytesAddr,
    00547                                        dataBytesAddr,
    00548                                        nfCePin,
    00549                                        nfRbPin,
    00550                                        nfBaseBlock, nfMamagedSize * 1024 * 1024/NandFlashModel_GetBlockSizeInBytes(pModel))) {
    00551         printf("Nand init error\n\r");
    00552         return;
    00553     }
    00554
    00555     /* Media initialize */
    00556     MEDNandFlash_Initialize(&medias[DRV_NAND], &translatedNf);
    00557
    00558     /* Initialize LUN */
    00559     LUN_Init(&(luns[DRV_NAND]), &(medias[DRV_NAND]),
    00560              msdBuffer, MSD_BUFFER_SIZE,
    00561              0, 0, 0, 0,
    00562              MSDCallbacks_Data);
    00563 }
    00564
    00565 /**
    00566  * Initialize MSD Media & LUNs
    00567  */
    00568 static void MemoriesInitialize(void)
    00569 {
    00570     uint32_t i ;
    00571
    00572     /* Reset all LUNs */
    00573     for (i = 0; i < MAX_LUNS; i ++)
    00574         LUN_Init(&luns[i], 0, 0, 0, 0, 0, 0, 0, 0);
    00575
    00576     /* TODO: Add LUN Init here */
    00577
    00578     /* Nand Flash Init */
    00579     NandFlashInitialize();
    00580 }
    00581
    00582 /**
    00583  * \brief Configure 48MHz Clock for USB
    00584  */
    00585 static void ConfigureUsbClock(void)
    00586 {
    00587     /* Enable PLLA for USB */
    00588     PMC->CKGR_PLLAR = CKGR_PLLAR_STUCKTO1
    00589                     | CKGR_PLLAR_DIVA(1)
    00590                     | CKGR_PLLAR_MULA(7)
    00591                     | CKGR_PLLAR_PLLACOUNT_Msk;
    00592     while((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
    00593     /* USB Clock uses PLLA */
    00594     PMC->PMC_USB = PMC_USB_USBDIV(1);       /* /2   */
    00595 }
    00596
    00597 /*---------------------------------------------------------------------------
    00598  *         Exported function
    00599  *---------------------------------------------------------------------------*/
    00600
    00601 /*---------------------------------------------------------------------------
    00602  *          Main
    00603  *---------------------------------------------------------------------------*/
    00604
    00605 /**
    00606  * Initializes drivers and start the USB composite device.
    00607  */
    00608 int main(void)
    00609 {
    00610     uint8_t usbConnected = 0;
    00611
    00612     /* Disable watchdog */
    00613     WDT_Disable(WDT);
    00614
    00615     printf("-- USB HID MSD Device Example %s --\n\r", SOFTPACK_VERSION);
    00616     printf("-- %s\n\r", BOARD_NAME);
    00617     printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
    00618
    00619     /* If they are present, configure Vbus & Wake-up pins */
    00620     PIO_InitializeInterrupts(0);
    00621
    00622     /* Enable UPLL for USB */
    00623     ConfigureUsbClock();
    00624
    00625     /* ----- HID Function Initialize */
    00626     /* Initialize key statuses and configure push buttons */
    00627     PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
    00628     memset(keyStatus, 1, NUM_KEYS);
    00629
    00630     /* Configure LEDs */
    00631     LED_Configure(LED_NUMLOCK);
    00632
    00633     MemoriesInitialize();
    00634
    00635     /* USB COMPOSITE driver initialization */
    00636     HIDMSDDriver_Initialize(&hidmsddDriverDescriptors, luns, MAX_LUNS);
    00637
    00638     /* connect if needed */
    00639     VBus_Configure();
    00640
    00641     /* Driver loop */
    00642     while (1) {
    00643
    00644         /* Device is not configured */
    00645         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
    00646
    00647             if (usbConnected) {
    00648                 printf("-I- USB Disconnect/Suspend\n\r");
    00649                 usbConnected = 0;
    00650             }
    00651         }
    00652         else {
    00653
    00654             if (usbConnected == 0) {
    00655                 printf("-I- USB Connect\n\r");
    00656                 usbConnected = 1;
    00657             }
    00658             HIDDKeyboardProcessKeys();
    00659             MSDFunction_StateMachine();
    00660
    00661             if (msdRefreshDelay -- > 0) {
    00662                 msdRefreshDelay = MSD_REFRESH_LOOP;
    00663                 if ((msdWriteTotal < 5 * 1024) && (msdWriteTotal > 0)) {
    00664                     MED_Flush(&medias[DRV_NAND]);
    00665                 }
    00666                 msdWriteTotal = 0;
    00667             }
    00668         }
    00669     }
    00670 }
    00671

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines