00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
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
00136
00137
00138 #define VIDEO_WIDTH 320
00139 #define VIDEO_HEIGHT 240
00140
00141
00142 #define TWCK 400000
00143
00144
00145 #define BOARD_PINS_TWI_ISI PINS_TWI0
00146
00147
00148 #define BOARD_ID_TWI_ISI ID_TWIHS0
00149
00150 #define BOARD_BASE_TWI_ISI TWIHS0
00151 #define CAMX_MT9V022_SLAVE_ADDR (0x30>>1)
00152
00153
00154 #define ISI_BASE SDRAM_CS_ADDR
00155
00156
00157 #define USB_BASE (ISI_BASE + VIDEO_WIDTH * VIDEO_HEIGHT)
00158
00159
00160
00161 #define ISI_MAX_PREV_BUFFER 10
00162
00163
00164
00165
00166
00167 extern const USBDDriverDescriptors usbdDriverDescriptors;
00168
00169
00170
00171
00172
00173
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
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
00188 static uint32_t frmMaxPktSize = FRAME_PACKET_SIZE_HS*(ISO_HIGH_BW_MODE+1);
00189
00190
00191 static uint8_t bAlternateInterfaces[4];
00192
00193
00194
00195 static USBVideoProbeData viddProbeData =
00196 {
00197 0,
00198 0x01,
00199 0x01,
00200 FRAME_INTERVALC(4),
00201 0,
00202 0,
00203 10000,
00204 0,
00205 100,
00206 FRAME_BUFFER_SIZEC(800, 600),
00207 FRAME_PACKET_SIZE_FS
00208 };
00209
00210
00211
00212 static uint8_t pControlBuffer[32];
00213
00214
00215 static uint32_t frmI = 0;
00216
00217 static uint32_t frmC;
00218
00219
00220 static uint32_t frmW = VIDEO_WIDTH, frmH = VIDEO_HEIGHT;
00221
00222
00223 static uint8_t bFrameXfring = 0;
00224
00225
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
00234 static uint32_t wImageWidth, wImageHeight;
00235
00236
00237 static sensorOutputFormat_t wImageFormat;
00238
00239 extern const sensorProfile_t mt9v022Profile;
00240
00241
00242
00243 static uint8_t *pVideoBufffers = (uint8_t *)USB_BASE;
00244
00245
00246
00247
00248
00249
00250
00251 void TWIHS0_Handler( void )
00252 {
00253 TWID_Handler( &twid ) ;
00254 }
00255
00256
00257
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
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
00297
00298 static void _twiInit(void)
00299 {
00300
00301 PIO_Configure(pinsTWI, PIO_LISTSIZE(pinsTWI));
00302
00303 PMC_EnablePeripheral(BOARD_ID_TWI_ISI);
00304
00305 TWI_ConfigureMaster(BOARD_BASE_TWI_ISI, TWCK, BOARD_MCK);
00306 TWID_Initialize(&twid, BOARD_BASE_TWI_ISI);
00307
00308
00309 NVIC_ClearPendingIRQ(TWIHS0_IRQn);
00310 NVIC_EnableIRQ(TWIHS0_IRQn);
00311 }
00312
00313
00314
00315
00316 static void _isiPckInit(void)
00317 {
00318
00319 PIO_Configure(pPinsISI, PIO_LISTSIZE(pPinsISI));
00320
00321
00322 REG_PMC_SCDR = PMC_SCER_PCK0;
00323
00324 PMC->PMC_PCK[0] = PMC_PCK_CSS_PLLA_CLK | (9 << 4);
00325
00326 REG_PMC_SCER = PMC_SCER_PCK0;
00327
00328 while ((REG_PMC_SR & PMC_SR_PCKRDY0) == 0);
00329
00330 PIO_Clear(&pin_ISI_PWD);
00331 PIO_Clear(&pin_ISI_RST);
00332 }
00333
00334
00335
00336
00337 static void _isiInit(void)
00338 {
00339
00340 PMC_EnablePeripheral(ID_ISI);
00341
00342 ISI_Reset();
00343
00344 ISI_SetBlank(0, 0);
00345
00346 ISI_SetSensorSize(wImageWidth/2, wImageHeight);
00347
00348 ISI_setPreviewSize(wImageWidth/2, wImageHeight);
00349
00350 ISI_calcScalerFactor();
00351
00352 ISI_setInputStream(RGB_INPUT);
00353 ISI_RgbPixelMapping(1);
00354
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
00362
00363
00364
00365
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;
00383 #endif
00384 }
00385
00386
00387
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
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
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
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:
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
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
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
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
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
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
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
00554
00555 static void _ConfigureUotghs(void)
00556 {
00557
00558
00559 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00560
00561 PMC->PMC_USB = PMC_USB_USBS;
00562
00563 PMC_EnablePeripheral(ID_USBHS);
00564 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00565
00566 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00567
00568 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00569
00570
00571 NVIC_EnableIRQ(USBHS_IRQn) ;
00572 }
00573
00574
00575
00576
00577
00578 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00579 {
00580 USBDDriver *pUsbd = USBD_GetDriver();
00581
00582 if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS) {
00583 USBDDriver_RequestHandler(pUsbd, request);
00584 return;
00585 }
00586
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
00609
00610
00611
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
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
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
00643 NVIC_ClearPendingIRQ(ISI_IRQn);
00644 NVIC_EnableIRQ(ISI_IRQn);
00645 ISI_Enable();
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 extern int main( void )
00658 {
00659 uint8_t reg = 0x0;
00660 uint8_t val = 0xFD;
00661 USBDDriver *pUsbd = USBD_GetDriver();
00662
00663
00664 SCB_EnableICache();
00665 SCB_EnableDCache();
00666
00667
00668 BOARD_ConfigureSdram();
00669
00670 WDT_Disable( WDT ) ;
00671
00672
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
00678 TimeTick_Configure();
00679
00680
00681 _twiInit();
00682
00683
00684 _isiPckInit();
00685 PIO_Set(&pin_ISI_RST);
00686
00687 TWID_Write(&twid, CAMX_MT9V022_SLAVE_ADDR, 0x03, 1, ®, 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
00695 sensor_get_output(&wImageFormat, &wImageWidth, &wImageHeight, QVGA);
00696 printf("wImageWidth = %d, %d ", wImageWidth, wImageHeight);
00697
00698
00699 _isiInit();
00700
00701
00702 NVIC_SetPriority( ISI_IRQn, 0 );
00703 NVIC_SetPriority( USBHS_IRQn, 2 );
00704
00705
00706 _ConfigureUotghs();
00707
00708
00709 USBDDriver_Initialize(pUsbd, &usbdDriverDescriptors, bAlternateInterfaces);
00710 USBD_Init();
00711
00712
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
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 }