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 /**
00031  * \page usb_video_gray USB Video Gray Scale Example
00032  *
00033  * \section Purpose
00034  *
00035  * The USB Video Example will help you to get familiar with the
00036  * USB Device Port(UDP) and ISI interface on SAMV7/E7 Microcontrollers.
00037  *
00038  * \section Requirements
00039  *
00040  * This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board
00041  * - On-board ISI interface.
00042  * - External sensor, in the example, MT9V022 sensor could be used.
00043  * It does data conversion, if necessary, before the storage in memory
00044  * through DMA. The ISI supports color CMOS image sensor and grayscale image
00045  * sensors with a reduced set of functionalities.
00046  * When an EK running this program connected to a host (PC for example), with
00047  * USB cable, the EK appears as a video camera for the host.
00048  *
00049  * \note
00050  * For the limitation of external memory size, this example only support for
00051  * QVGA format.
00052  * \section Description
00053  *
00054  * The USB video can help you to be familiar with the ISI (Image Sensor
00055  * Interface) to connects a CMOS-type image sensor to the processor and
00056  * provides image capture in various formats.
00057  *
00058  * \section Usage
00059  *
00060  * -# Build the program and download it inside the board.
00061  *    Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00062  * -# On the computer, open and configure a terminal application
00063  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00064  *   - 115200 baud rate
00065  *   - 8 bits of data
00066  *   - No parity
00067  *   - 1 stop bit
00068  *   - No flow control
00069  * -# Start the application.
00070  * -# In the terminal window, the following text should appear:
00071  *     \code
00072  *     -- USB Video Gray Example xxx --
00073  *     -- SAMxxxxx-xx
00074  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00075  *     \endcode
00076  * -# When connecting USB cable to windows, the
00077  *    new "xxx USB Device" appears in the
00078  *    hardware %device list.
00079  * -# Once the device is connected and configured on windows XP,
00080  *    "USB Video Device" will appear in "My Computer", you can double click
00081  *    it to preview with default resolution - QVGA.
00082  * -# Other video camera programs can also be used to monitor the capture
00083  *    output. The demo is tested on windows XP through "AmCap.exe".
00084  *
00085  * \section References
00086  * - usb_video_gray/main.c
00087  * - pio: PIO interface driver
00088  *    - pio.h
00089  *    - pio_it.h
00090  * - usb: USB Framework and UDP interface driver
00091  *    - \ref usbd_framework
00092  *       - \ref usbd_api
00093  *    - \ref usb_core
00094  *    \if usb_video_sim
00095  *    - \ref usb_video_sim
00096  *    \endif
00097  */
00098 
00099 /**
00100  * \file
00101  *
00102  * This file contains all the specific code for example usb_video_gray
00103  *
00104  * \section Contents
00105  *
00106  * The code can be roughly broken down as follows:
00107  *    - Configuration functions
00108  *       - Configure TWI
00109  *       - Configure pins for OV sensor
00110  *       - Configure ISI controller
00111  *    - Interrupt handlers
00112  *       - TWI_Handler
00113  *    - The main function, which implements the program behaviour
00114  */
00115 
00116 /*----------------------------------------------------------------------------
00117  *        Headers
00118  *----------------------------------------------------------------------------*/
00119 
00120 #include "board.h"
00121 
00122 #include <USBDescriptors.h>
00123 #include <USBRequests.h>
00124 #include "USBD.h"
00125 #include <USBD_HAL.h>
00126 #include <USBDDriver.h>
00127 #include <VIDEODescriptors.h>
00128 #include <USBVideo.h>
00129 
00130 #include <stdint.h>
00131 #include <stdio.h>
00132 #include <string.h>
00133 #include <assert.h>
00134 
00135 /*----------------------------------------------------------------------------
00136  *        Local definitions
00137  *----------------------------------------------------------------------------*/
00138 
00139 #define VIDEO_WIDTH     320
00140 #define VIDEO_HEIGHT    240
00141 
00142 /** TWI clock frequency in Hz. */
00143 #define TWCK            400000
00144 
00145 /** TWI Pins definition */
00146 #define BOARD_PINS_TWI_ISI PINS_TWI0
00147 
00148 /** TWI peripheral ID for Sensor configuration */
00149 #define BOARD_ID_TWI_ISI        ID_TWIHS0
00150 /** TWI base address for Sensor configuration */
00151 #define BOARD_BASE_TWI_ISI      TWIHS0
00152 #define CAMX_MT9V022_SLAVE_ADDR  (0x30>>1)
00153 
00154 /** ISI DMA buffer base address */
00155 #define ISI_BASE    SDRAM_CS_ADDR
00156 
00157 /** ISI DMA buffer base address */
00158 #define USB_BASE    (ISI_BASE + VIDEO_WIDTH * VIDEO_HEIGHT)
00159 
00160 /** Frame Buffer Descriptors , it depends on size of external memory, more
00161         is better */
00162 #define ISI_MAX_PREV_BUFFER    10
00163 
00164 /*----------------------------------------------------------------------------
00165  *          External variables
00166  *----------------------------------------------------------------------------*/
00167 
00168 extern const USBDDriverDescriptors usbdDriverDescriptors;
00169 
00170 /*----------------------------------------------------------------------------
00171  *        Local variables
00172  *----------------------------------------------------------------------------*/
00173 
00174 /** ISI pins to configure. */
00175 const Pin pinsTWI[] = BOARD_PINS_TWI_ISI;
00176 const Pin pin_ISI_RST = BOARD_ISI_RST;
00177 const Pin pin_ISI_PWD = BOARD_ISI_PWD;
00178 const Pin pPinsISI[] = {BOARD_ISI_PINS};
00179 
00180 /** TWI driver instance.*/
00181 static Twid twid;
00182 
00183 COMPILER_ALIGNED(32) ISI_FrameBufferDescriptors  preBufDescList;
00184 
00185 COMPILER_ALIGNED(32)
00186 static uint8_t pXfrBuffers[FRAME_PACKET_SIZE_HS * (ISO_HIGH_BW_MODE + 1)][1];
00187 
00188 /** Xfr Maximum packet size */
00189 static uint32_t frmMaxPktSize = FRAME_PACKET_SIZE_HS * (ISO_HIGH_BW_MODE + 1);
00190 
00191 /** Alternate interfaces */
00192 static uint8_t bAlternateInterfaces[4];
00193 
00194 /** Probe & Commit Controls */
00195 
00196 static USBVideoProbeData viddProbeData = {
00197     0, /* bmHint: All parameters fixed: sent by host */
00198     0x01,   /* bFormatIndex: Format #1 */
00199     0x01,   /* bFrameIndex: Frame #1 */
00200     FRAME_INTERVALC(4), /* dwFrameInterval: in 100ns */
00201     0, /* wKeyFrameRate: not used */
00202     0, /* wPFrameRate: not used */
00203     10000, /* wCompQuality: highest */
00204     0, /* wCompWindowSize: ?K */
00205     100, /* wDelay: Internal VS latency in ms */
00206     FRAME_BUFFER_SIZEC(800, 600), /* dwMaxVideoFrameSize: in bytes */
00207     FRAME_PACKET_SIZE_FS /* dwMaxPayloadTransferSize: in bytes */
00208 };
00209 
00210 /** Buffer for USB requests data */
00211 
00212 COMPILER_ALIGNED(32) static uint8_t pControlBuffer[32];
00213 
00214 /** Byte index in frame */
00215 static uint32_t frmI = 0;
00216 /** Frame count */
00217 static uint32_t frmC;
00218 
00219 /** Frame size: Width, Height */
00220 static uint32_t frmW = VIDEO_WIDTH, frmH = VIDEO_HEIGHT;
00221 
00222 /** USB transferring frame data */
00223 static uint8_t bFrameXfring = 0;
00224 
00225 /** USB Streaming interface ON */
00226 static volatile uint8_t bVideoON = 0;
00227 static volatile uint8_t bVidON = 0;
00228 static volatile uint8_t IsiPrevBuffIndex;
00229 static volatile uint8_t UsbPrevBuffIndex;
00230 static volatile uint32_t delay;
00231 static volatile uint32_t displayFrameAddr;
00232 
00233 /* Image size in preview mode */
00234 static uint32_t wImageWidth, wImageHeight;
00235 
00236 /* Image output format */
00237 static sensorOutputFormat_t wImageFormat;
00238 
00239 extern const sensorProfile_t mt9v022Profile;
00240 
00241 /** Video buffers */
00242 
00243 static uint8_t *pVideoBufffers = (uint8_t *)USB_BASE;
00244 
00245 /*----------------------------------------------------------------------------
00246  *        Local functions
00247  *----------------------------------------------------------------------------*/
00248 /**
00249  * \brief TWI interrupt handler. Forwards the interrupt to the TWI driver handler.
00250  */
00251 void TWIHS0_Handler(void)
00252 {
00253     TWID_Handler(&twid);
00254 }
00255 
00256 /**
00257  * \brief Convert gray scale pixel to YUV format for displaying through USB video.
00258  */
00259 static void y2yuv(void)
00260 {
00261     uint16_t i, j;
00262     uint8_t *s;
00263     uint8_t *p;
00264     s = (uint8_t *)ISI_BASE;
00265     p = (uint8_t *)USB_BASE + IsiPrevBuffIndex * (VIDEO_WIDTH * VIDEO_HEIGHT * 2);
00266 
00267     for (i = 0; i < wImageWidth; i++) {
00268         for (j = 0; j < wImageHeight; j++) {
00269             *p++ = *s++;
00270             *p++ = 0x80;
00271         }
00272     }
00273 }
00274 
00275 /**
00276  * \brief ISI interrupt handler.
00277  */
00278 void ISI_Handler(void)
00279 {
00280     uint32_t status, imr;
00281     status = ISI->ISI_SR;
00282     imr = ISI->ISI_IMR;
00283 
00284     if ((status & ISI_SR_PXFR_DONE) && (imr & ISI_IMR_PXFR_DONE)) {
00285         if (ISI->ISI_DMA_P_ADDR != (uint32_t)ISI_BASE + (wImageWidth * wImageHeight))
00286             return;
00287 
00288         ISI_DisableInterrupt(ISI_IDR_PXFR_DONE);
00289         ISI_DmaChannelDisable(ISI_DMA_CHDR_P_CH_DIS);
00290         y2yuv();
00291         ISI_DmaChannelEnable(ISI_DMA_CHER_P_CH_EN);
00292         ISI_EnableInterrupt(ISI_IER_PXFR_DONE);
00293         IsiPrevBuffIndex++;
00294 
00295         if (IsiPrevBuffIndex == ISI_MAX_PREV_BUFFER) IsiPrevBuffIndex = 0;
00296     }
00297 }
00298 
00299 /**
00300  * \brief TWI initialization.
00301  */
00302 static void _twiInit(void)
00303 {
00304     /* Configure TWI pins. */
00305     PIO_Configure(pinsTWI, PIO_LISTSIZE(pinsTWI));
00306     /* Enable TWI peripheral clock */
00307     PMC_EnablePeripheral(BOARD_ID_TWI_ISI);
00308     /* Configure TWI */
00309     TWI_ConfigureMaster(BOARD_BASE_TWI_ISI, TWCK, BOARD_MCK);
00310     TWID_Initialize(&twid, BOARD_BASE_TWI_ISI);
00311 
00312     /* Configure TWI interrupts */
00313     NVIC_ClearPendingIRQ(TWIHS0_IRQn);
00314     NVIC_EnableIRQ(TWIHS0_IRQn);
00315 }
00316 
00317 /**
00318  * \brief ISI PCK initialization.
00319  */
00320 static void _isiPckInit(void)
00321 {
00322     /* Configure ISI pins. */
00323     PIO_Configure(pPinsISI, PIO_LISTSIZE(pPinsISI));
00324 
00325     /* Disable programmable clock 1 output */
00326     REG_PMC_SCDR = PMC_SCER_PCK0;
00327     /* Enable the DAC master clock */
00328     PMC->PMC_PCK[0] = PMC_PCK_CSS_PLLA_CLK | (9 << 4);
00329     /* Enable programmable clock 0 output */
00330     REG_PMC_SCER = PMC_SCER_PCK0;
00331 
00332     /* Wait for the PCKRDY0 bit to be set in the PMC_SR register*/
00333     while ((REG_PMC_SR & PMC_SR_PCKRDY0) == 0);
00334 
00335     /* ISI PWD OFF*/
00336     PIO_Clear(&pin_ISI_PWD);
00337     PIO_Clear(&pin_ISI_RST);
00338 }
00339 
00340 /**
00341  * \brief ISI  initialization.
00342  */
00343 static void _isiInit(void)
00344 {
00345     /* Enable ISI peripheral clock */
00346     PMC_EnablePeripheral(ID_ISI);
00347     /* Reset ISI peripheral */
00348     ISI_Reset();
00349     /* Set the windows blank */
00350     ISI_SetBlank(0, 0);
00351     /* Set vertical and horizontal Size of the Image Sensor for preview path*/
00352     ISI_SetSensorSize(wImageWidth / 2, wImageHeight);
00353     /* Set preview size to fit LCD */
00354     ISI_setPreviewSize(wImageWidth / 2, wImageHeight);
00355     /* calculate scaler factor automatically. */
00356     ISI_calcScalerFactor();
00357     /*  Set data stream in RGB format.*/
00358     ISI_setInputStream(RGB_INPUT);
00359     ISI_RgbPixelMapping(1);
00360     /* Configure DMA for preview path. */
00361     preBufDescList.Current = (uint32_t)ISI_BASE;
00362     preBufDescList.Control = ISI_DMA_P_CTRL_P_FETCH;
00363     preBufDescList.Next    = (uint32_t)&preBufDescList;
00364     SCB_CleanDCache_by_Addr((uint32_t *)&preBufDescList, sizeof(preBufDescList));
00365     ISI_setDmaInPreviewPath((uint32_t)&preBufDescList, ISI_DMA_P_CTRL_P_FETCH,
00366                             (uint32_t)ISI_BASE);
00367 }
00368 
00369 /*------------ USB Video Device Functions ------------*/
00370 /**
00371  * Max packet size calculation for High bandwidth transfer\n
00372  * - Mode 1: last packet is <epSize+1> ~ <epSize*2> bytes\n
00373  * - Mode 2: last packet is <epSize*2+1> ~ <epSize*3> bytes
00374  */
00375 static void VIDD_UpdateHighBWMaxPacketSize(void)
00376 {
00377 
00378 #if (ISO_HIGH_BW_MODE == 1 || ISO_HIGH_BW_MODE == 2)
00379     uint32_t frmSiz = frmW * frmH * 2 + FRAME_PAYLOAD_HDR_SIZE;
00380     uint32_t pktSiz = FRAME_PACKET_SIZE_HS * (ISO_HIGH_BW_MODE + 1);
00381     uint32_t nbLast = frmSiz % pktSiz;
00382 
00383     while (1) {
00384         nbLast = frmSiz % pktSiz;
00385 
00386         if (nbLast == 0 || nbLast > (FRAME_PACKET_SIZE_HS * ISO_HIGH_BW_MODE))
00387             break;
00388 
00389         pktSiz --;
00390     }
00391 
00392     frmMaxPktSize = pktSiz;
00393 #else
00394     frmMaxPktSize = FRAME_PACKET_SIZE_HS; // EP size
00395 #endif
00396 }
00397 
00398 /**
00399  * Send USB control status.
00400  */
00401 static void VIDD_StatusStage(void)
00402 {
00403     USBVideoProbeData *pProbe = (USBVideoProbeData *)pControlBuffer;
00404     viddProbeData.bFormatIndex = pProbe->bFormatIndex;
00405     viddProbeData.bFrameIndex  = pProbe->bFrameIndex;
00406     viddProbeData.dwFrameInterval = pProbe->dwFrameInterval;
00407 
00408     //viddProbeData.dwMaxVideoFrameSize = pProbe->dwMaxVideoFrameSize;
00409     switch (pProbe->bFrameIndex) {
00410     case 1: frmW = VIDCAMD_FW_1; frmH = VIDCAMD_FH_1; break;
00411 
00412     case 2: frmW = VIDCAMD_FW_2; frmH = VIDCAMD_FH_2; break;
00413 
00414     case 3: frmW = VIDCAMD_FW_3; frmH = VIDCAMD_FH_3; break;
00415     }
00416 
00417     VIDD_UpdateHighBWMaxPacketSize();
00418     USBD_Write(0, 0, 0, 0, 0);
00419 }
00420 
00421 /**
00422  * Handle SetCUR request for USB Video Device.
00423  */
00424 static void VIDD_SetCUR(const USBGenericRequest *pReq)
00425 {
00426     uint8_t bCS = USBVideoRequest_GetControlSelector(pReq);
00427     uint32_t len;
00428     TRACE_INFO_WP("SetCUR(%d) ", pReq->wLength);
00429 
00430     if (pReq->wIndex == VIDCAMD_StreamInterfaceNum) {
00431         TRACE_INFO_WP("VS ");
00432 
00433         switch (bCS) {
00434         case VS_PROBE_CONTROL:
00435             TRACE_INFO_WP("PROBE ");
00436             len = sizeof(USBVideoProbeData);
00437 
00438             if (pReq->wLength < len) len = pReq->wLength;
00439 
00440             USBD_Read(0, pControlBuffer, len, (TransferCallback)VIDD_StatusStage, 0);
00441             break;
00442 
00443         case VS_COMMIT_CONTROL:
00444             TRACE_INFO_WP("COMMIT ");
00445             len = sizeof(USBVideoProbeData);
00446 
00447             if (pReq->wLength < len) len = pReq->wLength;
00448 
00449             USBD_Read(0, pControlBuffer, len, (TransferCallback)VIDD_StatusStage, 0);
00450 
00451         default: USBD_Stall(0);
00452         }
00453     } else if (pReq->wIndex == VIDCAMD_ControlInterfaceNum) {
00454         TRACE_INFO_WP("VC ");
00455     }
00456     else USBD_Stall(0);
00457 }
00458 
00459 /**
00460  * Handle GetCUR request for USB Video Device.
00461  */
00462 static void VIDD_GetCUR(const USBGenericRequest *pReq)
00463 {
00464     uint8_t bCS = USBVideoRequest_GetControlSelector(pReq);
00465     uint32_t len;
00466     TRACE_INFO_WP("GetCUR(%d) ", pReq->wLength);
00467 
00468     if (pReq->wIndex == VIDCAMD_StreamInterfaceNum) {
00469         TRACE_INFO_WP("VS ");
00470 
00471         switch (bCS) {
00472         case VS_PROBE_CONTROL:
00473             TRACE_INFO_WP("PROBE ");
00474             len = sizeof(USBVideoProbeData);
00475 
00476             if (pReq->wLength < len) len = pReq->wLength;
00477 
00478             USBD_Write(0, &viddProbeData, len, 0, 0);
00479             break;
00480 
00481         case VS_COMMIT_CONTROL: /* Returns current state of VS I/F */
00482             TRACE_INFO_WP("COMMIT ");
00483             USBD_Write(0, &bAlternateInterfaces[VIDCAMD_StreamInterfaceNum], 1, 0, 0);
00484             break;
00485 
00486         default: USBD_Stall(0);
00487         }
00488     } else if (pReq->wIndex == VIDCAMD_ControlInterfaceNum){
00489       TRACE_INFO_WP("VC ");
00490     }
00491     else USBD_Stall(0);
00492 }
00493 
00494 /**
00495  * Handle GetDEF request for USB Video Device.
00496  */
00497 static void VIDD_GetDEF(const USBGenericRequest *pReq)
00498 {
00499     printf("GetDEF(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00500 }
00501 
00502 /**
00503  * Handle GetINFO request for USB Video Device.
00504  */
00505 static void VIDD_GetINFO(const USBGenericRequest *pReq)
00506 {
00507     printf("GetINFO(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00508 }
00509 
00510 /**
00511  * Handle GetMIN request for USB Video Device.
00512  */
00513 static void VIDD_GetMIN(const USBGenericRequest *pReq)
00514 {
00515     printf("GetMin(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00516     VIDD_GetCUR(pReq);
00517 }
00518 
00519 /**
00520  * Handle GetMAX request for USB Video Device.
00521  */
00522 static void VIDD_GetMAX(const USBGenericRequest *pReq)
00523 {
00524     printf("GetMax(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00525     VIDD_GetCUR(pReq);
00526 }
00527 
00528 /**
00529  * Handle GetRES request for USB Video Device.
00530  */
00531 static void VIDD_GetRES(const USBGenericRequest *pReq)
00532 {
00533     printf("GetRES(%x,%x,%d) ", pReq->wIndex, pReq->wValue, pReq->wLength);
00534 }
00535 
00536 /**
00537  * Callback that invoked when USB packet is sent.
00538  */
00539 static void VIDD_PayloadSent(void *pArg, uint8_t bStat)
00540 {
00541     uint32_t pktSize;
00542     pArg = pArg; bStat = bStat;
00543     uint8_t *pX = pXfrBuffers[0];
00544 
00545     uint32_t frmSize = FRAME_BUFFER_SIZEC(frmW, frmH);
00546     uint8_t *pV = pVideoBufffers;
00547     USBVideoPayloadHeader *pHdr = (USBVideoPayloadHeader *)pX;
00548     uint32_t maxPktSize = USBD_IsHighSpeed() ? (frmMaxPktSize)
00549                           : (FRAME_PACKET_SIZE_FS);
00550     pktSize = frmSize - frmI;
00551     pHdr->bHeaderLength     = FRAME_PAYLOAD_HDR_SIZE;
00552     pHdr->bmHeaderInfo.B    = 0;
00553 
00554     if (pktSize > maxPktSize - pHdr->bHeaderLength)
00555         pktSize = maxPktSize - pHdr->bHeaderLength;
00556 
00557     pV = &pV[frmI];
00558     frmI += pktSize;
00559     pHdr->bmHeaderInfo.bm.FID = (frmC & 1);
00560 
00561     if (frmI >= frmSize) {
00562         frmC ++;
00563         frmI = 0;
00564         pHdr->bmHeaderInfo.bm.EoF = 1;
00565 
00566         if (bFrameXfring)
00567             bFrameXfring = 0;
00568     } else {
00569         pHdr->bmHeaderInfo.bm.EoF = 0;
00570 
00571         if (bFrameXfring == 0) {
00572             bFrameXfring = 1;
00573             pVideoBufffers = (uint8_t *)USB_BASE + UsbPrevBuffIndex *
00574                              (VIDEO_WIDTH * VIDEO_HEIGHT * 2);
00575             UsbPrevBuffIndex ++;
00576 
00577             if (UsbPrevBuffIndex == ISI_MAX_PREV_BUFFER) UsbPrevBuffIndex = 0;
00578 
00579         }
00580     }
00581 
00582     pHdr->bmHeaderInfo.bm.EOH =  1;
00583     USBD_HAL_WrWithHdr(VIDCAMD_IsoInEndpointNum, pHdr,
00584                        pHdr->bHeaderLength, pV, pktSize);
00585 }
00586 
00587 /**
00588  * Configure USB settings for USB device
00589  */
00590 static void _ConfigureUotghs(void)
00591 {
00592     /* UTMI parallel mode, High/Full/Low Speed */
00593     /* UUSBCK not used in this configuration (High Speed) */
00594     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00595     /* USB clock register: USB Clock Input is UTMI PLL */
00596     PMC->PMC_USB = PMC_USB_USBS;
00597     /* Enable peripheral clock for USBHS */
00598     PMC_EnablePeripheral(ID_USBHS);
00599     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00600     /* Enable PLL 480 MHz */
00601     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00602 
00603     /* Wait that PLL is considered locked by the PMC */
00604     while (!(PMC->PMC_SR & PMC_SR_LOCKU));
00605 
00606     /* IRQ */
00607     NVIC_EnableIRQ(USBHS_IRQn);
00608 }
00609 
00610 /**
00611  *  Invoked whenever a SETUP request is received from the host. Forwards the
00612  *  request to the standard handler.
00613  */
00614 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00615 {
00616     USBDDriver *pUsbd = USBD_GetDriver();
00617 
00618     /* STD requests */
00619     if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS) {
00620         USBDDriver_RequestHandler(pUsbd, request);
00621         return;
00622     }
00623 
00624     /* Video requests */
00625     TRACE_INFO_WP("Vid ");
00626 
00627     switch (USBGenericRequest_GetRequest(request)) {
00628     case VIDGenericRequest_SETCUR:  VIDD_SetCUR (request);  break;
00629 
00630     case VIDGenericRequest_GETCUR:  VIDD_GetCUR (request);  break;
00631 
00632     case VIDGenericRequest_GETDEF:  VIDD_GetDEF (request);  break;
00633 
00634     case VIDGenericRequest_GETINFO: VIDD_GetINFO(request);  break;
00635 
00636     case VIDGenericRequest_GETMIN:  VIDD_GetMIN (request);  break;
00637 
00638     case VIDGenericRequest_GETMAX:  VIDD_GetMAX (request);  break;
00639 
00640     case VIDGenericRequest_GETRES:  VIDD_GetRES (request);  break;
00641 
00642     default:
00643         TRACE_WARNING("REQ: %x %x %x %x\n\r",
00644                       USBGenericRequest_GetType(request),
00645                       USBGenericRequest_GetRequest(request),
00646                       USBGenericRequest_GetValue(request),
00647                       USBGenericRequest_GetLength(request));
00648         USBD_Stall(0);
00649     }
00650 
00651     TRACE_INFO_WP("\n\r");
00652 }
00653 
00654 /**
00655  * Invoked whenever the active setting of an interface is changed by the
00656  * host. Reset streaming interface.
00657  * \param interface Interface number.
00658  * \param setting Newly active setting.
00659  */
00660 void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface,
00661         uint8_t setting)
00662 {
00663     if (interface != VIDCAMD_StreamInterfaceNum) return;
00664 
00665     if (setting) {
00666         bVideoON = 1;
00667         frmC = 0;   frmI = 0;
00668     } else {
00669         bVideoON = 0;
00670         bFrameXfring = 0;
00671     }
00672 
00673     memory_sync();
00674     USBD_HAL_ResetEPs(1 << VIDCAMD_IsoInEndpointNum, USBRC_CANCELED, 1);
00675 }
00676 
00677 /**
00678  * \brief Generic ISI & OV sensor initialization
00679  */
00680 static void _PreviewMode(void)
00681 {
00682     IsiPrevBuffIndex = 0;
00683     UsbPrevBuffIndex = 0;
00684     ISI_SetSensorSize(frmW / 2, frmH);
00685     ISI_setPreviewSize(frmW / 2, frmH);
00686     /* calculate scaler factor automatically. */
00687     ISI_calcScalerFactor();
00688     ISI_DisableInterrupt(0xFFFFFFFF);
00689     ISI_DmaChannelDisable(ISI_DMA_CHDR_C_CH_DIS);
00690     ISI_DmaChannelEnable(ISI_DMA_CHER_P_CH_EN);
00691     ISI_EnableInterrupt(ISI_IER_PXFR_DONE);
00692     /* Configure ISI interrupts */
00693     NVIC_ClearPendingIRQ(ISI_IRQn);
00694     NVIC_EnableIRQ(ISI_IRQn);
00695     ISI_Enable();
00696 }
00697 
00698 /*----------------------------------------------------------------------------
00699  *        Global functions
00700  *----------------------------------------------------------------------------*/
00701 
00702 /**
00703  * \brief Application entry point for ISI USB video example.
00704  *
00705  * \return Unused (ANSI-C compatibility).
00706  */
00707 extern int main(void)
00708 {
00709     uint8_t reg = 0x0;
00710     uint8_t val = 0xFD;
00711     USBDDriver *pUsbd = USBD_GetDriver();
00712 
00713     /* Enable I and D cache */
00714     SCB_EnableICache();
00715     SCB_EnableDCache();
00716 
00717     /* Enable SDRAM for Frame buffer */
00718     BOARD_ConfigureSdram();
00719 
00720     WDT_Disable(WDT);
00721 
00722     /* Output example information */
00723     printf("-- USB VIDEO Gray Example %s --\n\r", SOFTPACK_VERSION);
00724     printf("-- %s\n\r", BOARD_NAME);
00725     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00726             COMPILER_NAME);
00727 
00728     /* Configure Time Tick */
00729     TimeTick_Configure();
00730 
00731     /* TWI Initialize */
00732     _twiInit();
00733 
00734     /* ISI PCK clock Initialize */
00735     _isiPckInit();
00736     PIO_Set(&pin_ISI_RST);
00737 
00738     TWID_Write(&twid, CAMX_MT9V022_SLAVE_ADDR, 0x03, 1, &reg, 1, 0);
00739     TWID_Write(&twid, CAMX_MT9V022_SLAVE_ADDR, 1, 1, &val, 1, 0);
00740 
00741     if (sensor_setup(&twid, &mt9v022Profile, QVGA) != SENSOR_OK) {
00742         printf("-E- Sensor setup failed.");
00743 
00744         while (1);
00745     }
00746 
00747     /* Retrieve sensor output format and size */
00748     sensor_get_output(&wImageFormat, &wImageWidth, &wImageHeight, QVGA);
00749     printf("wImageWidth = %d, %d ", (int)wImageWidth, (int)wImageHeight);
00750 
00751     /* ISI Initialize */
00752     _isiInit();
00753 
00754     /* Interrupt priority */
00755     NVIC_SetPriority(ISI_IRQn, 0);
00756     NVIC_SetPriority(USBHS_IRQn, 2);
00757 
00758     /* Initialize all USB power (off) */
00759     _ConfigureUotghs();
00760 
00761     /* USB Driver Initialize */
00762     USBDDriver_Initialize(pUsbd, &usbdDriverDescriptors, bAlternateInterfaces);
00763     USBD_Init();
00764 
00765     /* Start USB stack to authorize VBus monitoring */
00766     USBD_Connect();
00767 
00768     while (1) {
00769         if (USBD_GetState() < USBD_STATE_CONFIGURED)
00770             continue;
00771 
00772         if (bVidON && !bVideoON) {
00773             bVidON = 0;
00774             ISI_Disable();
00775             printf("vidE \n\r");
00776         }
00777 
00778         if (!bVidON && bVideoON) {
00779             bVidON = 1;
00780             NVIC_ClearPendingIRQ(USBHS_IRQn);
00781             NVIC_DisableIRQ(USBHS_IRQn);
00782             _PreviewMode();
00783             /* Start USB Streaming */
00784             USBD_HAL_SetTransferCallback(VIDCAMD_IsoInEndpointNum,
00785                                          (TransferCallback)VIDD_PayloadSent, 0);
00786             NVIC_EnableIRQ(USBHS_IRQn);
00787             VIDD_PayloadSent(NULL, USBD_STATUS_SUCCESS);
00788             printf("vidS\n\r");
00789         }
00790     }
00791 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines