SAMV71 Xplained Ultra Software Package 1.4

main.c

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