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
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
00137
00138
00139
00140 #define TWCK 400000
00141
00142
00143 #define BOARD_PINS_TWI_ISI PINS_TWI0
00144
00145
00146 #define BOARD_ID_TWI_ISI ID_TWIHS0
00147
00148 #define BOARD_BASE_TWI_ISI TWIHS0
00149
00150
00151 #define ISI_BASE SDRAM_CS_ADDR
00152
00153
00154
00155 #define ISI_MAX_PREV_BUFFER 12
00156
00157
00158
00159
00160
00161 extern const USBDDriverDescriptors usbdDriverDescriptors;
00162
00163
00164
00165
00166
00167
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
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
00183 static uint32_t frmMaxPktSize = FRAME_PACKET_SIZE_HS*(ISO_HIGH_BW_MODE+1);
00184
00185
00186 static uint8_t bAlternateInterfaces[4];
00187
00188
00189
00190 static USBVideoProbeData viddProbeData =
00191 {
00192 0,
00193 0x01,
00194 0x01,
00195 FRAME_INTERVALC(4),
00196 0,
00197 0,
00198 10000,
00199 0,
00200 100,
00201 FRAME_BUFFER_SIZEC(800, 600),
00202 FRAME_PACKET_SIZE_FS
00203 };
00204
00205
00206
00207 static uint8_t pControlBuffer[32];
00208
00209
00210 static uint32_t frmI = 0;
00211
00212 static uint32_t frmC;
00213
00214
00215 static uint32_t frmW = 320, frmH = 240;
00216
00217
00218 static uint8_t bFrameXfring = 0;
00219
00220
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
00229 static uint32_t wImageWidth, wImageHeight;
00230
00231
00232 static sensorOutputFormat_t wImageFormat;
00233
00234 extern const sensorProfile_t ov7740Profile;
00235
00236
00237
00238 static uint8_t *pVideoBufffers = (uint8_t *)ISI_BASE;
00239
00240
00241
00242
00243
00244
00245
00246 void TWIHS0_Handler( void )
00247 {
00248 TWID_Handler( &twid ) ;
00249 }
00250
00251
00252
00253
00254 void ISI_Handler(void)
00255 {
00256
00257 if(ISI_StatusRegister() & ISI_SR_PXFR_DONE) {
00258
00259 displayFrameAddr = preBufDescList[IsiPrevBuffIndex].Current;
00260 IsiPrevBuffIndex++;
00261 if( IsiPrevBuffIndex == ISI_MAX_PREV_BUFFER )
00262 IsiPrevBuffIndex = 0;
00263 }
00264 }
00265
00266
00267
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
00284
00285 static void _twiInit(void)
00286 {
00287
00288 PIO_Configure(pinsTWI, PIO_LISTSIZE(pinsTWI));
00289
00290 PMC_EnablePeripheral(BOARD_ID_TWI_ISI);
00291
00292 TWI_ConfigureMaster(BOARD_BASE_TWI_ISI, TWCK, BOARD_MCK);
00293 TWID_Initialize(&twid, BOARD_BASE_TWI_ISI);
00294
00295
00296 NVIC_ClearPendingIRQ(TWIHS0_IRQn);
00297 NVIC_EnableIRQ(TWIHS0_IRQn);
00298 }
00299
00300
00301
00302
00303 static void _isiPckInit(void)
00304 {
00305
00306 PIO_Configure(pPinsISI, PIO_LISTSIZE(pPinsISI));
00307
00308
00309 REG_PMC_SCDR = PMC_SCER_PCK0;
00310
00311 PMC->PMC_PCK[0] = PMC_PCK_CSS_PLLA_CLK | (9 << 4);
00312
00313 REG_PMC_SCER = PMC_SCER_PCK0;
00314
00315 while ((REG_PMC_SR & PMC_SR_PCKRDY0) == 0);
00316
00317 PIO_Clear(&pin_ISI_PWD);
00318 PIO_Clear(&pin_ISI_RST);
00319 }
00320
00321
00322
00323
00324 static void _isiInit(void)
00325 {
00326
00327 PMC_EnablePeripheral(ID_ISI);
00328
00329 _isi_AllocateFBD();
00330
00331 ISI_Reset();
00332
00333 ISI_SetBlank(0, 0);
00334
00335 ISI_SetSensorSize(wImageWidth, wImageHeight);
00336
00337 ISI_setInputStream(RGB_INPUT);
00338
00339
00340 ISI_setPreviewSize(frmW, frmH);
00341
00342 ISI_calcScalerFactor();
00343
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
00350 void TC0_Handler(void)
00351 {
00352 REG_TC0_SR0;
00353 }
00354
00355
00356
00357
00358 static void _ConfigureTc(void)
00359 {
00360 uint32_t div;
00361 uint32_t tcclks;
00362
00363
00364 PMC_EnablePeripheral(ID_TC0);
00365
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
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
00380
00381
00382
00383
00384
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;
00402 #endif
00403 }
00404
00405
00406
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
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
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
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:
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
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
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
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
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
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
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
00577
00578
00579
00580
00581
00582 static void _ConfigureUotghs(void)
00583 {
00584
00585
00586 PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00587
00588 PMC->PMC_USB = PMC_USB_USBS;
00589
00590 PMC_EnablePeripheral(ID_USBHS);
00591 USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00592
00593 PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00594
00595 while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00596
00597
00598 NVIC_EnableIRQ(USBHS_IRQn) ;
00599 }
00600
00601
00602
00603
00604
00605 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00606 {
00607 USBDDriver *pUsbd = USBD_GetDriver();
00608
00609 if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS) {
00610 USBDDriver_RequestHandler(pUsbd, request);
00611 return;
00612 }
00613
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
00636
00637
00638
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
00656
00657 static void _PreviewMode( void )
00658 {
00659 IsiPrevBuffIndex = 0;
00660 UsbPrevBuffIndex = 0;
00661 ISI_SetSensorSize(frmW, frmH);
00662 ISI_setPreviewSize(frmW, frmH);
00663
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
00670 NVIC_ClearPendingIRQ(ISI_IRQn);
00671 NVIC_EnableIRQ(ISI_IRQn);
00672 ISI_Enable();
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 extern int main( void )
00685 {
00686 uint8_t key;
00687 USBDDriver *pUsbd = USBD_GetDriver();
00688
00689
00690 SCB_EnableICache();
00691 SCB_EnableDCache();
00692
00693 TimeTick_Configure();
00694
00695 BOARD_ConfigureSdram();
00696
00697 WDT_Disable( WDT ) ;
00698
00699
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
00705 _twiInit();
00706
00707
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
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
00727 _isiInit();
00728
00729
00730 NVIC_SetPriority( ISI_IRQn, 0 );
00731 NVIC_SetPriority( USBHS_IRQn, 2 );
00732
00733
00734 _ConfigureUotghs();
00735
00736
00737 USBDDriver_Initialize(pUsbd, &usbdDriverDescriptors, bAlternateInterfaces);
00738 USBD_Init();
00739
00740
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
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 }