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