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_gray USB Video Gray Scale 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, MT9V022 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 Gray 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_gray/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 example usb_video_gray
00102  *
00103  * \section Contents
00104  *
00105  * The code can be roughly broken down as follows:
00106  *    - Configuration functions
00107  *       - Configure TWI
00108  *       - Configure pins for OV sensor 
00109  *       - Configure ISI controller 
00110  *    - Interrupt handlers
00111  *       - TWI_Handler
00112  *    - The main function, which implements the program behaviour
00113  */
00114 
00115 /*----------------------------------------------------------------------------
00116  *        Headers
00117  *----------------------------------------------------------------------------*/
00118 
00119 #include "board.h"
00120 
00121 #include <USBDescriptors.h>
00122 #include <USBRequests.h>
00123 #include "USBD.h"
00124 #include <USBD_HAL.h>
00125 #include <USBDDriver.h>
00126 #include <VIDEODescriptors.h>
00127 #include <USBVideo.h>
00128 
00129 #include <stdint.h>
00130 #include <stdio.h>
00131 #include <string.h>
00132 #include <assert.h> 
00133 
00134 /*----------------------------------------------------------------------------
00135  *        Local definitions
00136  *----------------------------------------------------------------------------*/
00137 
00138 #define VIDEO_WIDTH     320
00139 #define VIDEO_HEIGHT    240
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 #define CAMX_MT9V022_SLAVE_ADDR  (0x30>>1)
00152 
00153 /** ISI DMA buffer base address */
00154 #define ISI_BASE    SDRAM_CS_ADDR 
00155 
00156 /** ISI DMA buffer base address */
00157 #define USB_BASE    (ISI_BASE + VIDEO_WIDTH * VIDEO_HEIGHT) 
00158 
00159 /** Frame Buffer Descriptors , it depends on size of external memory, more 
00160         is better */
00161 #define ISI_MAX_PREV_BUFFER    10
00162 
00163 /*----------------------------------------------------------------------------
00164  *          External variables
00165  *----------------------------------------------------------------------------*/
00166 
00167 extern const USBDDriverDescriptors usbdDriverDescriptors;
00168 
00169 /*----------------------------------------------------------------------------
00170  *        Local variables
00171  *----------------------------------------------------------------------------*/
00172 
00173 /** ISI pins to configure. */
00174 const Pin pinsTWI[] = BOARD_PINS_TWI_ISI;
00175 const Pin pin_ISI_RST = BOARD_ISI_RST;
00176 const Pin pin_ISI_PWD = BOARD_ISI_PWD;
00177 const Pin pPinsISI[]= {BOARD_ISI_PINS};
00178 
00179 /** TWI driver instance.*/
00180 static Twid twid;
00181 
00182 COMPILER_WORD_ALIGNED ISI_FrameBufferDescriptors  preBufDescList;
00183 
00184 COMPILER_WORD_ALIGNED 
00185     static uint8_t pXfrBuffers[FRAME_PACKET_SIZE_HS*(ISO_HIGH_BW_MODE+1)][1];
00186 
00187 /** Xfr Maximum packet size */
00188 static uint32_t frmMaxPktSize = FRAME_PACKET_SIZE_HS*(ISO_HIGH_BW_MODE+1);
00189 
00190 /** Alternate interfaces */
00191 static uint8_t bAlternateInterfaces[4];
00192 
00193 /** Probe & Commit Controls */
00194 
00195 static USBVideoProbeData viddProbeData =
00196 {
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 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     if((status & ISI_SR_PXFR_DONE) && (imr & ISI_IMR_PXFR_DONE)) {
00284         if (ISI->ISI_DMA_P_ADDR != (uint32_t)ISI_BASE + (wImageWidth * wImageHeight  )) return;
00285         ISI_DisableInterrupt(ISI_IDR_PXFR_DONE);
00286         ISI_DmaChannelDisable(ISI_DMA_CHDR_P_CH_DIS);
00287         y2yuv();
00288         ISI_DmaChannelEnable(ISI_DMA_CHER_P_CH_EN);
00289         ISI_EnableInterrupt(ISI_IER_PXFR_DONE);
00290         IsiPrevBuffIndex++;
00291         if (IsiPrevBuffIndex == ISI_MAX_PREV_BUFFER) IsiPrevBuffIndex = 0;
00292     }
00293 }
00294 
00295 /**
00296  * \brief TWI initialization.
00297  */
00298 static void _twiInit(void)
00299 {
00300     /* Configure TWI pins. */
00301     PIO_Configure(pinsTWI, PIO_LISTSIZE(pinsTWI));
00302     /* Enable TWI peripheral clock */
00303     PMC_EnablePeripheral(BOARD_ID_TWI_ISI);
00304     /* Configure TWI */
00305     TWI_ConfigureMaster(BOARD_BASE_TWI_ISI, TWCK, BOARD_MCK);
00306     TWID_Initialize(&twid, BOARD_BASE_TWI_ISI);
00307  
00308     /* Configure TWI interrupts */
00309     NVIC_ClearPendingIRQ(TWIHS0_IRQn);
00310     NVIC_EnableIRQ(TWIHS0_IRQn);
00311 }
00312 
00313 /**
00314  * \brief ISI PCK initialization.
00315  */
00316 static void _isiPckInit(void) 
00317 {
00318     /* Configure ISI pins. */
00319     PIO_Configure(pPinsISI, PIO_LISTSIZE(pPinsISI));
00320 
00321     /* Disable programmable clock 1 output */
00322     REG_PMC_SCDR = PMC_SCER_PCK0;
00323     /* Enable the DAC master clock */
00324     PMC->PMC_PCK[0] = PMC_PCK_CSS_PLLA_CLK | (9 << 4);
00325     /* Enable programmable clock 0 output */
00326     REG_PMC_SCER = PMC_SCER_PCK0;
00327     /* Wait for the PCKRDY0 bit to be set in the PMC_SR register*/
00328     while ((REG_PMC_SR & PMC_SR_PCKRDY0) == 0);
00329     /* ISI PWD OFF*/
00330     PIO_Clear(&pin_ISI_PWD);
00331     PIO_Clear(&pin_ISI_RST);
00332 }
00333  
00334 /**
00335  * \brief ISI  initialization.
00336  */
00337 static void _isiInit(void)
00338 {
00339     /* Enable ISI peripheral clock */
00340     PMC_EnablePeripheral(ID_ISI);
00341     /* Reset ISI peripheral */
00342     ISI_Reset();
00343     /* Set the windows blank */
00344     ISI_SetBlank(0, 0);
00345     /* Set vertical and horizontal Size of the Image Sensor for preview path*/
00346     ISI_SetSensorSize(wImageWidth/2, wImageHeight);
00347     /* Set preview size to fit LCD */
00348     ISI_setPreviewSize(wImageWidth/2, wImageHeight);
00349     /* calculate scaler factor automatically. */
00350     ISI_calcScalerFactor();
00351     /*  Set data stream in RGB format.*/
00352     ISI_setInputStream(RGB_INPUT);
00353     ISI_RgbPixelMapping(1);
00354     /* Configure DMA for preview path. */
00355     preBufDescList.Current = (uint32_t)ISI_BASE ;
00356     preBufDescList.Control = ISI_DMA_P_CTRL_P_FETCH ;
00357     preBufDescList.Next    = (uint32_t)&preBufDescList;
00358     ISI_setDmaInPreviewPath((uint32_t)&preBufDescList, ISI_DMA_P_CTRL_P_FETCH,(uint32_t)ISI_BASE);
00359 }
00360 
00361 /*------------ USB Video Device Functions ------------*/
00362 /**
00363  * Max packet size calculation for High bandwidth transfer\n
00364  * - Mode 1: last packet is <epSize+1> ~ <epSize*2> bytes\n
00365  * - Mode 2: last packet is <epSize*2+1> ~ <epSize*3> bytes
00366  */
00367 static void VIDD_UpdateHighBWMaxPacketSize(void)
00368 {
00369     
00370 #if (ISO_HIGH_BW_MODE == 1 || ISO_HIGH_BW_MODE == 2)
00371     uint32_t frmSiz = frmW*frmH*2 + FRAME_PAYLOAD_HDR_SIZE;
00372     uint32_t pktSiz = FRAME_PACKET_SIZE_HS*(ISO_HIGH_BW_MODE+1);
00373     uint32_t nbLast = frmSiz % pktSiz;
00374     while(1) {
00375         nbLast = frmSiz % pktSiz;
00376         if (nbLast == 0 || nbLast > (FRAME_PACKET_SIZE_HS*ISO_HIGH_BW_MODE))
00377             break;
00378         pktSiz --;
00379     }
00380     frmMaxPktSize = pktSiz;
00381 #else
00382     frmMaxPktSize = FRAME_PACKET_SIZE_HS; // EP size
00383 #endif
00384 }
00385 
00386 /**
00387  * Send USB control status.
00388  */
00389 static void VIDD_StatusStage(void)
00390 {
00391     USBVideoProbeData *pProbe = (USBVideoProbeData *)pControlBuffer;
00392     viddProbeData.bFormatIndex = pProbe->bFormatIndex;
00393     viddProbeData.bFrameIndex  = pProbe->bFrameIndex;
00394     viddProbeData.dwFrameInterval = pProbe->dwFrameInterval;
00395     //viddProbeData.dwMaxVideoFrameSize = pProbe->dwMaxVideoFrameSize;
00396     switch (pProbe->bFrameIndex) {
00397     case 1: frmW = VIDCAMD_FW_1; frmH = VIDCAMD_FH_1; break;
00398     case 2: frmW = VIDCAMD_FW_2; frmH = VIDCAMD_FH_2; break;
00399     case 3: frmW = VIDCAMD_FW_3; frmH = VIDCAMD_FH_3; break;
00400     }
00401     VIDD_UpdateHighBWMaxPacketSize();
00402     USBD_Write(0, 0, 0, 0, 0);
00403 }
00404 
00405 /**
00406  * Handle SetCUR request for USB Video Device.
00407  */
00408 static void VIDD_SetCUR(const USBGenericRequest *pReq)
00409 {
00410     uint8_t bCS = USBVideoRequest_GetControlSelector(pReq);
00411     uint32_t len;
00412     TRACE_INFO_WP("SetCUR(%d) ", pReq->wLength);
00413     if (pReq->wIndex == VIDCAMD_StreamInterfaceNum) {
00414         TRACE_INFO_WP("VS ");
00415         switch(bCS) {
00416         case VS_PROBE_CONTROL:
00417             TRACE_INFO_WP("PROBE ");
00418             len = sizeof(USBVideoProbeData);
00419             if (pReq->wLength < len) len = pReq->wLength;
00420             USBD_Read(0, pControlBuffer, len, (TransferCallback)VIDD_StatusStage, 0);
00421             break;
00422         case VS_COMMIT_CONTROL:
00423             TRACE_INFO_WP("COMMIT ");
00424             len = sizeof(USBVideoProbeData);
00425             if (pReq->wLength < len) len = pReq->wLength;
00426             USBD_Read(0, pControlBuffer, len, (TransferCallback)VIDD_StatusStage, 0);
00427         default: USBD_Stall(0);
00428         }
00429     } else if (pReq->wIndex == VIDCAMD_ControlInterfaceNum) {
00430         TRACE_INFO_WP("VC ");
00431     }
00432     else USBD_Stall(0);
00433 }
00434 
00435 /**
00436  * Handle GetCUR request for USB Video Device.
00437  */
00438 static void VIDD_GetCUR(const USBGenericRequest *pReq)
00439 {
00440     uint8_t bCS = USBVideoRequest_GetControlSelector(pReq);
00441     uint32_t len;
00442     TRACE_INFO_WP("GetCUR(%d) ", pReq->wLength);
00443     if (pReq->wIndex == VIDCAMD_StreamInterfaceNum) {
00444         TRACE_INFO_WP("VS ");
00445         switch(bCS) {
00446         case VS_PROBE_CONTROL:
00447             TRACE_INFO_WP("PROBE ");
00448             len = sizeof(USBVideoProbeData);
00449             if (pReq->wLength < len) len = pReq->wLength;
00450             USBD_Write(0, &viddProbeData, len, 0, 0);
00451             break;
00452         case VS_COMMIT_CONTROL: /* Returns current state of VS I/F */
00453             TRACE_INFO_WP("COMMIT ");
00454             USBD_Write(0, &bAlternateInterfaces[VIDCAMD_StreamInterfaceNum], 1, 0, 0);
00455             break;
00456         default: USBD_Stall(0);
00457         }
00458     } else if (pReq->wIndex == VIDCAMD_ControlInterfaceNum) {
00459         TRACE_INFO_WP("VC ");
00460     }
00461     else USBD_Stall(0);
00462 }
00463 
00464 /**
00465  * Handle GetDEF request for USB Video Device.
00466  */
00467 static void VIDD_GetDEF(const USBGenericRequest *pReq)
00468 {
00469     printf("GetDEF(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00470 }
00471 
00472 /**
00473  * Handle GetINFO request for USB Video Device.
00474  */
00475 static void VIDD_GetINFO(const USBGenericRequest *pReq)
00476 {
00477     printf("GetINFO(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00478 }
00479 
00480 /**
00481  * Handle GetMIN request for USB Video Device.
00482  */
00483 static void VIDD_GetMIN(const USBGenericRequest *pReq)
00484 {
00485     printf("GetMin(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00486     VIDD_GetCUR(pReq);
00487 }
00488 
00489 /**
00490  * Handle GetMAX request for USB Video Device.
00491  */
00492 static void VIDD_GetMAX(const USBGenericRequest *pReq)
00493 {
00494     printf("GetMax(%x,%x,%d)\n\r", pReq->wIndex, pReq->wValue, pReq->wLength);
00495     VIDD_GetCUR(pReq);
00496 }
00497 
00498 /**
00499  * Handle GetRES request for USB Video Device.
00500  */
00501 static void VIDD_GetRES(const USBGenericRequest *pReq)
00502 {
00503     printf("GetRES(%x,%x,%d) ", pReq->wIndex, pReq->wValue, pReq->wLength);
00504 }
00505 
00506 /**
00507  * Callback that invoked when USB packet is sent.
00508  */
00509 static void VIDD_PayloadSent(void* pArg, uint8_t bStat)
00510 {
00511     uint32_t pktSize;
00512     pArg = pArg; bStat = bStat;
00513     uint8_t *pX = pXfrBuffers[0];
00514 
00515     uint32_t frmSize = FRAME_BUFFER_SIZEC(frmW, frmH);
00516     uint8_t *pV = pVideoBufffers;
00517     USBVideoPayloadHeader *pHdr = (USBVideoPayloadHeader *)pX;
00518     uint32_t maxPktSize = USBD_IsHighSpeed() ? (frmMaxPktSize)
00519                                          : (FRAME_PACKET_SIZE_FS);
00520     pktSize = frmSize - frmI;
00521     pHdr->bHeaderLength     = FRAME_PAYLOAD_HDR_SIZE;
00522     pHdr->bmHeaderInfo.B    = 0;
00523     if (pktSize > maxPktSize - pHdr->bHeaderLength)
00524         pktSize = maxPktSize - pHdr->bHeaderLength;
00525     pV = &pV[frmI];
00526     frmI += pktSize;
00527     pHdr->bmHeaderInfo.bm.FID = (frmC & 1);
00528     if (frmI >= frmSize) {
00529         frmC ++; 
00530         frmI = 0;
00531         pHdr->bmHeaderInfo.bm.EoF = 1;
00532     
00533         if (bFrameXfring) {
00534             bFrameXfring = 0;
00535         }
00536     } else {
00537         pHdr->bmHeaderInfo.bm.EoF = 0;
00538 
00539         if (bFrameXfring == 0) {
00540             bFrameXfring = 1;
00541             pVideoBufffers = (uint8_t*)USB_BASE + UsbPrevBuffIndex * (VIDEO_WIDTH*VIDEO_HEIGHT*2);
00542             UsbPrevBuffIndex ++; 
00543             if (UsbPrevBuffIndex == ISI_MAX_PREV_BUFFER) UsbPrevBuffIndex = 0;
00544             
00545         }
00546     }
00547     pHdr->bmHeaderInfo.bm.EOH =  1;
00548     USBD_HAL_WrWithHdr(VIDCAMD_IsoInEndpointNum, pHdr, 
00549             pHdr->bHeaderLength, pV, pktSize);
00550 }
00551 
00552 /**
00553  * Configure USB settings for USB device
00554  */
00555 static void _ConfigureUotghs(void)
00556 {
00557     /* UTMI parallel mode, High/Full/Low Speed */
00558     /* UUSBCK not used in this configuration (High Speed) */
00559     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00560     /* USB clock register: USB Clock Input is UTMI PLL */
00561     PMC->PMC_USB = PMC_USB_USBS;
00562     /* Enable peripheral clock for USBHS */
00563     PMC_EnablePeripheral(ID_USBHS);
00564     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00565     /* Enable PLL 480 MHz */
00566     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00567     /* Wait that PLL is considered locked by the PMC */
00568     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00569 
00570     /* IRQ */
00571     NVIC_EnableIRQ(USBHS_IRQn) ;
00572 }
00573 
00574 /**
00575  *  Invoked whenever a SETUP request is received from the host. Forwards the
00576  *  request to the standard handler.
00577  */
00578 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00579 {
00580     USBDDriver *pUsbd = USBD_GetDriver();
00581     /* STD requests */
00582     if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS) {
00583         USBDDriver_RequestHandler(pUsbd, request);
00584         return;
00585     }
00586     /* Video requests */
00587     TRACE_INFO_WP("Vid ");
00588     switch (USBGenericRequest_GetRequest(request)) {
00589     case VIDGenericRequest_SETCUR:  VIDD_SetCUR (request);  break;
00590     case VIDGenericRequest_GETCUR:  VIDD_GetCUR (request);  break;
00591     case VIDGenericRequest_GETDEF:  VIDD_GetDEF (request);  break;
00592     case VIDGenericRequest_GETINFO: VIDD_GetINFO(request);  break;
00593     case VIDGenericRequest_GETMIN:  VIDD_GetMIN (request);  break;
00594     case VIDGenericRequest_GETMAX:  VIDD_GetMAX (request);  break;
00595     case VIDGenericRequest_GETRES:  VIDD_GetRES (request);  break;
00596     default:
00597         TRACE_WARNING("REQ: %x %x %x %x\n\r",
00598             USBGenericRequest_GetType(request),
00599             USBGenericRequest_GetRequest(request),
00600             USBGenericRequest_GetValue(request),
00601             USBGenericRequest_GetLength(request));
00602         USBD_Stall(0);
00603     }
00604     TRACE_INFO_WP("\n\r");
00605 }
00606 
00607 /**
00608  * Invoked whenever the active setting of an interface is changed by the
00609  * host. Reset streaming interface.
00610  * \param interface Interface number.
00611  * \param setting Newly active setting.
00612  */
00613 void USBDDriverCallbacks_InterfaceSettingChanged( uint8_t interface, uint8_t setting )
00614 {
00615     if (interface != VIDCAMD_StreamInterfaceNum) return;
00616     if (setting) {
00617         bVideoON = 1;
00618         frmC = 0;   frmI = 0;
00619     } else {
00620         bVideoON = 0;
00621         bFrameXfring = 0;
00622     }
00623     memory_sync();
00624     USBD_HAL_ResetEPs(1 << VIDCAMD_IsoInEndpointNum, USBRC_CANCELED, 1);
00625 }
00626 
00627 /**
00628  * \brief Generic ISI & OV sensor initialization
00629  */
00630 static void _PreviewMode( void )
00631 {
00632     IsiPrevBuffIndex = 0;
00633     UsbPrevBuffIndex = 0;
00634     ISI_SetSensorSize(frmW/2, frmH);
00635     ISI_setPreviewSize(frmW/2, frmH);
00636     /* calculate scaler factor automatically. */
00637     ISI_calcScalerFactor();
00638     ISI_DisableInterrupt(0xFFFFFFFF);
00639     ISI_DmaChannelDisable(ISI_DMA_CHDR_C_CH_DIS);
00640     ISI_DmaChannelEnable(ISI_DMA_CHER_P_CH_EN);
00641     ISI_EnableInterrupt( ISI_IER_PXFR_DONE );
00642     /* Configure ISI interrupts */
00643     NVIC_ClearPendingIRQ(ISI_IRQn);
00644     NVIC_EnableIRQ(ISI_IRQn);
00645     ISI_Enable();
00646 }
00647 
00648 /*----------------------------------------------------------------------------
00649  *        Global functions
00650  *----------------------------------------------------------------------------*/
00651 
00652 /**
00653  * \brief Application entry point for ISI USB video example.
00654  *
00655  * \return Unused (ANSI-C compatibility).
00656  */
00657 extern int main( void )
00658 {
00659     uint8_t reg = 0x0;
00660     uint8_t val = 0xFD;
00661     USBDDriver *pUsbd = USBD_GetDriver();
00662 
00663     /* Enable I and D cache */
00664     SCB_EnableICache();
00665     SCB_EnableDCache();
00666     
00667     /* Enable SDRAM for Frame buffer */
00668     BOARD_ConfigureSdram();
00669     
00670     WDT_Disable( WDT ) ;
00671 
00672     /* Output example information */
00673     printf( "-- USB VIDEO Gray Example %s --\n\r", SOFTPACK_VERSION ) ;
00674     printf( "-- %s\n\r", BOARD_NAME ) ;
00675     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00676     
00677         /* Configure Time Tick */
00678     TimeTick_Configure();
00679     
00680     /* TWI Initialize */
00681     _twiInit();
00682     
00683     /* ISI PCK clock Initialize */
00684     _isiPckInit();
00685     PIO_Set(&pin_ISI_RST);
00686 
00687     TWID_Write(&twid, CAMX_MT9V022_SLAVE_ADDR, 0x03, 1, &reg, 1, 0);
00688     TWID_Write(&twid, CAMX_MT9V022_SLAVE_ADDR, 1, 1, &val, 1, 0);
00689     if (sensor_setup(&twid, &mt9v022Profile, QVGA) != SENSOR_OK){
00690         printf("-E- Sensor setup failed.");
00691         while (1);
00692     }
00693     
00694     /* Retrieve sensor output format and size */
00695     sensor_get_output(&wImageFormat, &wImageWidth, &wImageHeight, QVGA);
00696     printf("wImageWidth = %d, %d ", wImageWidth, wImageHeight);
00697     
00698     /* ISI Initialize */
00699     _isiInit();
00700     
00701     /* Interrupt priority */
00702     NVIC_SetPriority( ISI_IRQn, 0 );
00703     NVIC_SetPriority( USBHS_IRQn, 2 );
00704     
00705     /* Initialize all USB power (off) */
00706     _ConfigureUotghs();
00707    
00708     /* USB Driver Initialize */
00709     USBDDriver_Initialize(pUsbd, &usbdDriverDescriptors, bAlternateInterfaces);
00710     USBD_Init();
00711     
00712     /* Start USB stack to authorize VBus monitoring */
00713     USBD_Connect();
00714     while ( 1 ) {
00715         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00716             continue;
00717         }
00718         if (bVidON && !bVideoON) {
00719             bVidON = 0;
00720             ISI_Disable();
00721             printf("vidE \n\r");
00722         }
00723         if (!bVidON && bVideoON) {
00724             bVidON = 1;
00725             NVIC_ClearPendingIRQ(USBHS_IRQn);
00726             NVIC_DisableIRQ(USBHS_IRQn);
00727             _PreviewMode();
00728             /* Start USB Streaming */
00729             USBD_HAL_SetTransferCallback(VIDCAMD_IsoInEndpointNum, (TransferCallback)VIDD_PayloadSent, 0);
00730             NVIC_EnableIRQ(USBHS_IRQn);
00731             VIDD_PayloadSent(NULL, USBD_STATUS_SUCCESS);
00732             printf("vidS\n\r");
00733         }
00734     }
00735 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines