camif.c
上传用户:jankzhpno
上传日期:2022-08-03
资源大小:4763k
文件大小:28k
源码类别:

Windows CE

开发平台:

Visual C++

  1. /************************************************************
  2. File Name : camif.c
  3. Descriptions
  4.  -S3C2440 camera test routines & basic libraries
  5. History
  6.  - July 23, 2003. Draft Version 0.0 by purnnamu
  7.  - Janualy 15, 2004. Modifed by Boaz
  8. Copyright 2004 SAMSUNG Electronics.
  9. However, Anybody can use this code without our permission.  
  10. *************************************************************/
  11. #include "def.h"
  12. #include "option.h"
  13. #include "2440addr.h"
  14. #include "2440lib.h"
  15. #include "camif.h"
  16. #include "camproset.h" // for camera setting
  17. extern unsigned char camera_pic_240x320[];
  18. #define LCD_XSIZE_TFT  LCD_WIDTH
  19. #define LCD_YSIZE_TFT  LCD_HEIGHT
  20. #define SCR_XSIZE_TFT  LCD_WIDTH
  21. #define SCR_YSIZE_TFT  LCD_HEIGHT
  22. // GPB1/TOUT1 for Backlight control(PWM)
  23. #define GPB1_TO_OUT()   (rGPBUP &= 0xfffd, rGPBCON &= 0xfffffff3, rGPBCON |= 0x00000004)
  24. #define GPB1_TO_1()     (rGPBDAT |= 0x0002)
  25. #define GPB1_TO_0()     (rGPBDAT &= 0xfffd)
  26. volatile static unsigned short LCD_BUFFER_CAM[SCR_YSIZE_TFT][SCR_XSIZE_TFT];
  27. //*****************************************************************************
  28. volatile U32 camTestMode;
  29. volatile U32 camCodecCaptureCount;
  30. volatile U32 camPviewCaptureCount;
  31. volatile U32 camCodecStatus;
  32. volatile U32 camPviewStatus;
  33. volatile U32 amount;
  34. U32 save_GPJCON, save_GPJDAT, save_GPJUP;
  35. U8 flagCaptured_P = 0;
  36. U8 flagCaptured_C = 0;
  37. int Test_OV9650(void); //capbily
  38. /**************************************************************
  39. LCD视频和控制信号输出或者停止,1开启视频输出
  40. **************************************************************/
  41. static void Lcd_EnvidOnOff(int onoff)
  42. {
  43.     if(onoff==1)
  44. rLCDCON1|=1; // ENVID=ON
  45.     else
  46. rLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off
  47. }
  48. /**************************************************************
  49. TFT LCD 电源控制引脚使能
  50. **************************************************************/
  51. static void Lcd_PowerEnable(int invpwren,int pwren)
  52. {
  53.     //GPG4 is setted as LCD_PWREN
  54.     rGPGUP=rGPGUP&(~(1<<4))|(1<<4); // Pull-up disable
  55.     rGPGCON=rGPGCON&(~(3<<8))|(3<<8); //GPG4=LCD_PWREN
  56.     rGPGDAT = rGPGDAT | (1<<4) ;
  57. // invpwren=pwren;
  58.     //Enable LCD POWER ENABLE Function
  59.     rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3);   // PWREN
  60.     rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5);   // INVPWREN
  61. }
  62. //*****************************************************************************
  63. static void LCD_Init(void)
  64. {
  65. #define M5D(n) ((n)&0x1fffff)
  66. #define LCD_ADDR ((U32)LCD_BUFFER_CAM)
  67. rLCDCON1 = (LCD_PIXCLOCK << 8) | (3 <<  5) | (12 << 1);
  68.     rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0);
  69.     rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH  - 1) <<  8) | (LCD_LEFT_MARGIN << 0);
  70.     rLCDCON4 = (13 <<  8) | (LCD_HSYNC_LEN << 0);
  71. #if !defined(LCD_CON5)
  72. #    define LCD_CON5 ((1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0))
  73. #endif
  74.     rLCDCON5   =  LCD_CON5;
  75.     rLCDSADDR1 = ((LCD_ADDR >> 22) << 21) | ((M5D(LCD_ADDR >> 1)) <<  0);
  76.     rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1);
  77.     rLCDSADDR3 = LCD_WIDTH;        
  78.     rLCDINTMSK |= 3;
  79.    rTCONSEL   &= (~7);
  80.  
  81. rGPCCON = 0xaaaaaaaaU;
  82. rGPCUP  = 0xffffU; 
  83.     rTPAL     = 0x0;
  84.     rTCONSEL &= ~((1<<4) | 1);
  85.     rLCDCON1  |= 1;
  86.     rGPGCON = 1<<8;
  87.     rGPGDAT = 1<<4;
  88.     
  89.     rGPCUP  = 0x00000000;
  90.     rGPCCON = 0xaaaa02a9; 
  91.  
  92.     rGPDUP  = 0x00000000;
  93.     rGPDCON=0xaaaaaaaa; //Initialize VD[15:8]
  94. LcdBkLtSet( 70 ) ;
  95. Lcd_PowerEnable(0, 1);
  96.     Lcd_EnvidOnOff(1); //turn on vedio
  97. }
  98. static void Lcd_ClearScr( U32 c)
  99. {
  100. unsigned int x,y ;
  101.     for( y = 0 ; y < SCR_YSIZE_TFT ; y++ )
  102.     {
  103.      for( x = 0 ; x < SCR_XSIZE_TFT ; x++ )
  104.      {
  105. LCD_BUFFER_CAM[y][x] = c ;
  106.      }
  107.     }
  108. }
  109. //*****************************************************************************
  110. static void Paint_Bmp(int x0,int y0,int h,int l,unsigned char bmp[])
  111. {
  112. int x,y;
  113. U32 c;
  114. int p = 0;
  115.     for( y = y0 ; y < l ; y++ )
  116.     {
  117.      for( x = x0 ; x < h ; x++ )
  118.      {
  119.      c = bmp[p+1] | (bmp[p]<<8) ;
  120. if ( ( (x0+x) < SCR_XSIZE_TFT) && ( (y0+y) < SCR_YSIZE_TFT) )
  121.  LCD_BUFFER_CAM[y0+y][x0+x] = c ;
  122.      p = p + 2 ;
  123.      }
  124.     }
  125. }
  126. void Camera_Test(void)
  127. {
  128. int i;
  129. Uart_Printf("nCamera Preview Testn");
  130. #if defined(LCD_VGA1024768)
  131. TFT_LCD_Init();
  132. return ;
  133. #endif
  134. CamReset();
  135. // Initializing camif
  136. rCLKCON |= (1<<19); // enable camclk
  137. CamPortSet();
  138. //ChangeUPllValue(60, 4, 1); // UPLL clock = 96MHz, PLL input 16.9344MHz
  139. //--- capbily
  140. ChangeUPllValue(56, 2, 1); // UPLL clock = 96MHz, PLL input 12MHz
  141. //---
  142. rCLKDIVN|=(1<<3); // UCLK 48MHz setting for UPLL 96MHz
  143. // 0:48MHz, 1:24MHz, 2:16MHz, 3:12MHz...
  144. // Camera clock = UPLL/[(CAMCLK_DIV+1)X2]
  145. switch(USED_CAM_TYPE)
  146. {
  147. case CAM_AU70H :
  148. if (AU70H_VIDEO_SIZE==1152)
  149. SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock for SXGA
  150. if (AU70H_VIDEO_SIZE==640)
  151. SetCAMClockDivider(CAMCLK16000000); //Set Camera Clock for VGA
  152. break;
  153. case CAM_S5X3A1 :
  154. SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock for SXGA
  155. break;
  156. default :  // 24MHz
  157. SetCAMClockDivider(CAMCLK24000000); //Set Camera Clock 24MHz s5x532, ov7620
  158. break;
  159. }
  160. #if (USED_CAM_TYPE==CAM_OV7620) //capbily
  161. i = Test_OV9650();
  162. if( i )
  163. {
  164. Uart_Printf("nTest is failed!!!n");
  165. return ;
  166. }
  167. #else
  168. // Initializing camera module
  169. CamModuleReset(); // s5x532 must do this..
  170. Delay(100); // ready time of s5x433, s5x532 IIC interface. needed...
  171. CameraModuleSetting();
  172. #endif
  173. Uart_Printf("Initializing end...n");
  174. Test_CamPreview() ;
  175. Uart_Printf("nCamera Preview Test Endn");
  176. // CamModuleReset(); // s5x532 must do this..
  177. rCLKCON &= ~(1<<19); // disable camclk
  178. TFT_LCD_Init() ; //
  179. }
  180. void CamPortSet(void)
  181. {
  182. save_GPJCON = rGPJCON;
  183. save_GPJDAT = rGPJDAT;
  184. save_GPJUP = rGPJUP;
  185. rGPJCON = 0x2aaaaaa;
  186. rGPJDAT = 0;
  187. rGPJUP = 0;
  188. //--- capbily
  189. rGPGCON &= ~(3<<24);
  190. rGPGCON |= 1<<24;
  191. rGPGUP  |= 1<<12;
  192. #if (USED_CAM_TYPE==CAM_OV7620)
  193. rGPGDAT &= ~(1<<12);
  194. #else
  195. rGPGDAT |= 1<<12;
  196. #endif
  197. //---
  198. }
  199. void CamPortReturn(void)
  200. {
  201. rGPJCON = save_GPJCON;
  202. rGPJDAT = save_GPJDAT;
  203. rGPJUP = save_GPJUP;
  204. }
  205. void CamPreviewIntUnmask(void)
  206. {
  207.     rINTSUBMSK &= ~(BIT_SUB_CAM_P);//INT CAMERA Port A ENABLE 
  208.     rINTMSK &= ~(BIT_CAM);
  209. }
  210. void CamCodecIntUnmask(void)
  211. {
  212.     rINTSUBMSK &= ~(BIT_SUB_CAM_C);//INT CAMERA Port B ENABLE 
  213.     rINTMSK &= ~(BIT_CAM);
  214. }
  215. void CamPreviewIntMask(void)
  216. {
  217.     rINTSUBMSK |= BIT_SUB_CAM_P;//INT CAMERA Port A ENABLE 
  218.     rINTMSK |= (BIT_CAM);
  219. }
  220. void CamCodecIntMask(void)
  221. {
  222.     rINTSUBMSK |= BIT_SUB_CAM_C;//INT CAMERA Port B ENABLE 
  223.     rINTMSK |= (BIT_CAM);
  224. }
  225. /******************************************************
  226.  *                                                                       *    
  227.  *                       camera interface initialization                     *
  228.  *                                                                             *     
  229.  *******************************************************/
  230. void CamReset(void)
  231. {
  232. rCIGCTRL |= (1<<31); //camera I/F soft reset
  233. Delay(10);
  234. rCIGCTRL &= ~(1<<31);
  235. }
  236. void CamModuleReset(void)
  237. {
  238. switch(USED_CAM_TYPE)
  239. {
  240. case CAM_OV7620 : // reset - active high
  241. //case CAM_S5X532 : // reset - active low, but H/W inverted.. so, in this case active high, masked by capbily
  242. case CAM_S5X433 : // reset - active low, but H/W inverted.. so, in this case active high
  243. case CAM_S5X3A1 : // reset - active low, but H/W inverted.. so, in this case active high
  244. rCIGCTRL |= (1<<30);   //external camera reset high
  245. Delay(30);
  246. rCIGCTRL &= ~(1<<30); //external camera reset low
  247. break;
  248. case CAM_S5X532 : // reset - active low, move here by capbily
  249. case CAM_AU70H : // reset - active low
  250. default :
  251. rCIGCTRL &= ~(1<<30); //external camera reset low
  252. Delay(10);
  253. rCIGCTRL |= (1<<30); //external camera reset high
  254. break;
  255. }
  256. }
  257. // 0:48MHz, 1:24MHz, 2:16MHz, 3:12MHz...
  258. // Camera clock = UPLL/[(CAMCLK_DIV+1)X2]
  259. void SetCAMClockDivider(int divn) 
  260. {
  261. rCAMDIVN = (rCAMDIVN & ~(0xf))|(1<<4)|(divn); // CAMCLK is divided..
  262. }
  263. /* Description of Parameters
  264. CoDstWidth: Destination Width of Codec Path
  265. CoDstHeight: Destination Height of Codec Path
  266. PrDstWidth: Destination Width of Preview Path
  267. PrDstHeight: Destination Height of Preview Path
  268. WinHorOffset: Size of Window Offset for Horizontal Direction
  269. WinVerOffset: Size of Window Offset for Vertical Direction
  270. CoFrameBuffer: Start Address for Codec DMA
  271. PrFrameBuffer: Start Address for Previe DMA
  272. */
  273. void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 PrDstWidth, U32 PrDstHeight, 
  274. U32 WinHorOffset, U32 WinVerOffset,  U32 CoFrameBuffer, U32 PrFrameBuffer)
  275. {
  276. U32 WinOfsEn;
  277. U32 divisor, multiplier;
  278. U32 MainBurstSizeY, RemainedBurstSizeY, MainBurstSizeC, RemainedBurstSizeC, MainBurstSizeRGB, RemainedBurstSizeRGB;
  279. U32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
  280. U32 SrcWidth, SrcHeight;
  281. U32 ScaleUp_H_Co, ScaleUp_V_Co, ScaleUp_H_Pr, ScaleUp_V_Pr;
  282. //constant for calculating codec dma address
  283. if(CAM_CODEC_OUTPUT)
  284. divisor=2; //CCIR-422
  285. else
  286. divisor=4; //CCIR-420
  287. //constant for calculating preview dma address
  288. if(CAM_PVIEW_OUTPUT)
  289. multiplier=4;
  290. else
  291. multiplier=2;
  292. if(WinHorOffset==0 && WinVerOffset==0)
  293. WinOfsEn=0;
  294. else
  295. WinOfsEn=1;
  296. SrcWidth=CAM_SRC_HSIZE-WinHorOffset*2;
  297. SrcHeight=CAM_SRC_VSIZE-WinVerOffset*2;
  298. if(SrcWidth>=CoDstWidth) ScaleUp_H_Co=0; //down
  299. else ScaleUp_H_Co=1; //up
  300. if(SrcHeight>=CoDstHeight) ScaleUp_V_Co=0;
  301. else ScaleUp_V_Co=1;
  302. if(SrcWidth>=PrDstWidth) ScaleUp_H_Pr=0; //down
  303. else ScaleUp_H_Pr=1; //up
  304. if(SrcHeight>=PrDstHeight) ScaleUp_V_Pr=0;   // edited 040225
  305. else ScaleUp_V_Pr=1;
  306. ////////////////// common control setting
  307. rCIGCTRL |= (1<<26)|(0<<27); // inverse PCLK, test pattern
  308. //--- capbily
  309. //rCIGCTRL |= (0<<26)|(0<<27); // don't inverse PCLK, test pattern
  310. //---
  311. rCIWDOFST = (1<<30)|(0xf<<12); // clear overflow 
  312. rCIWDOFST = 0;
  313. rCIWDOFST=(WinOfsEn<<31)|(WinHorOffset<<16)|(WinVerOffset);
  314. rCISRCFMT=(CAM_ITU601<<31)|(0<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_YCBYCR<<14)|(CAM_SRC_VSIZE);
  315. //--- capbily
  316. //rCISRCFMT=(CAM_ITU601<<31)|(1<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_YCBYCR<<14)|(CAM_SRC_VSIZE);
  317. //---
  318. ////////////////// codec port setting
  319. if (CAM_CODEC_4PP)
  320. {
  321. rCICOYSA1=CoFrameBuffer;
  322. rCICOYSA2=rCICOYSA1+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
  323. rCICOYSA3=rCICOYSA2+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
  324. rCICOYSA4=rCICOYSA3+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
  325. rCICOCBSA1=rCICOYSA1+CoDstWidth*CoDstHeight;
  326. rCICOCBSA2=rCICOYSA2+CoDstWidth*CoDstHeight;
  327. rCICOCBSA3=rCICOYSA3+CoDstWidth*CoDstHeight;
  328. rCICOCBSA4=rCICOYSA4+CoDstWidth*CoDstHeight;
  329. rCICOCRSA1=rCICOCBSA1+CoDstWidth*CoDstHeight/divisor;
  330. rCICOCRSA2=rCICOCBSA2+CoDstWidth*CoDstHeight/divisor;
  331. rCICOCRSA3=rCICOCBSA3+CoDstWidth*CoDstHeight/divisor;
  332. rCICOCRSA4=rCICOCBSA4+CoDstWidth*CoDstHeight/divisor;
  333. }
  334. else
  335. {
  336. rCICOYSA1=CoFrameBuffer;
  337. rCICOYSA2=rCICOYSA1;
  338. rCICOYSA3=rCICOYSA1;
  339. rCICOYSA4=rCICOYSA1;
  340. rCICOCBSA1=rCICOYSA1+CoDstWidth*CoDstHeight;
  341. rCICOCBSA2=rCICOCBSA1;
  342. rCICOCBSA3=rCICOCBSA1;
  343. rCICOCBSA4=rCICOCBSA1;
  344. rCICOCRSA1=rCICOCBSA1+CoDstWidth*CoDstHeight/divisor;
  345. rCICOCRSA2=rCICOCRSA1;
  346. rCICOCRSA3=rCICOCRSA1;
  347. rCICOCRSA4=rCICOCRSA1;
  348. }
  349. rCICOTRGFMT=(CAM_CODEC_IN_422<<31)|(CAM_CODEC_OUTPUT<<30)|(CoDstWidth<<16)|(CAM_FLIP_180<<14)|(CoDstHeight);
  350. CalculateBurstSize(CoDstWidth, &MainBurstSizeY, &RemainedBurstSizeY);
  351. CalculateBurstSize(CoDstWidth/2, &MainBurstSizeC, &RemainedBurstSizeC);
  352. rCICOCTRL=(MainBurstSizeY<<19)|(RemainedBurstSizeY<<14)|(MainBurstSizeC<<9)|(RemainedBurstSizeC<<4);
  353. CalculatePrescalerRatioShift(SrcWidth, CoDstWidth, &PreHorRatio, &H_Shift);
  354. CalculatePrescalerRatioShift(SrcHeight, CoDstHeight, &PreVerRatio, &V_Shift);
  355. MainHorRatio=(SrcWidth<<8)/(CoDstWidth<<H_Shift);
  356. MainVerRatio=(SrcHeight<<8)/(CoDstHeight<<V_Shift);
  357.     
  358. rCICOSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
  359. rCICOSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio); 
  360. rCICOSCCTRL=(CAM_SCALER_BYPASS_OFF<<31)|(ScaleUp_H_Co<<30)|(ScaleUp_V_Co<<29)|(MainHorRatio<<16)|(MainVerRatio);
  361. rCICOTAREA=CoDstWidth*CoDstHeight;
  362. ///////////////// preview port setting
  363. if (CAM_PVIEW_4PP) // codec view mode
  364. {
  365. rCIPRCLRSA1=PrFrameBuffer;
  366. rCIPRCLRSA2=rCIPRCLRSA1+PrDstWidth*PrDstHeight*multiplier;
  367. rCIPRCLRSA3=rCIPRCLRSA2+PrDstWidth*PrDstHeight*multiplier;
  368. rCIPRCLRSA4=rCIPRCLRSA3+PrDstWidth*PrDstHeight*multiplier;
  369. }
  370. else // direct preview mode
  371. {
  372. rCIPRCLRSA1 = (U32)LCD_BUFFER_CAM;
  373. rCIPRCLRSA2 = (U32)LCD_BUFFER_CAM;
  374. rCIPRCLRSA3 = (U32)LCD_BUFFER_CAM;
  375. rCIPRCLRSA4 = (U32)LCD_BUFFER_CAM;
  376. }
  377. rCIPRTRGFMT=(PrDstWidth<<16)|(CAM_FLIP_180<<14)|(PrDstHeight);
  378. if (CAM_PVIEW_OUTPUT==CAM_RGB24B)
  379. CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
  380. else // RGB16B
  381. CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
  382.     rCIPRCTRL=(MainBurstSizeRGB<<19)|(RemainedBurstSizeRGB<<14);
  383. CalculatePrescalerRatioShift(SrcWidth, PrDstWidth, &PreHorRatio, &H_Shift);
  384. CalculatePrescalerRatioShift(SrcHeight, PrDstHeight, &PreVerRatio, &V_Shift);
  385. MainHorRatio=(SrcWidth<<8)/(PrDstWidth<<H_Shift);
  386. MainVerRatio=(SrcHeight<<8)/(PrDstHeight<<V_Shift);
  387. rCIPRSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);  
  388. rCIPRSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
  389. rCIPRSCCTRL=(1<<31)|(CAM_PVIEW_OUTPUT<<30)|(ScaleUp_H_Pr<<29)|(ScaleUp_V_Pr<<28)|(MainHorRatio<<16)|(MainVerRatio);
  390.     
  391. rCIPRTAREA= PrDstWidth*PrDstHeight;
  392. }
  393. /********************************************************
  394.  CalculateBurstSize - Calculate the busrt lengths
  395.  
  396.  Description:
  397.  - dstHSize: the number of the byte of H Size.
  398.  
  399. */
  400. void CalculateBurstSize(U32 hSize,U32 *mainBurstSize,U32 *remainedBurstSize)
  401. {
  402. U32 tmp;
  403. tmp=(hSize/4)%16;
  404. switch(tmp) {
  405. case 0:
  406. *mainBurstSize=16;
  407. *remainedBurstSize=16;
  408. break;
  409. case 4:
  410. *mainBurstSize=16;
  411. *remainedBurstSize=4;
  412. break;
  413. case 8:
  414. *mainBurstSize=16;
  415. *remainedBurstSize=8;
  416. break;
  417. default: 
  418. tmp=(hSize/4)%8;
  419. switch(tmp) {
  420. case 0:
  421. *mainBurstSize=8;
  422. *remainedBurstSize=8;
  423. break;
  424. case 4:
  425. *mainBurstSize=8;
  426. *remainedBurstSize=4;
  427. default:
  428. *mainBurstSize=4;
  429. tmp=(hSize/4)%4;
  430. *remainedBurstSize= (tmp) ? tmp: 4;
  431. break;
  432. }
  433. break;
  434. }          
  435. }
  436. /********************************************************
  437.  CalculatePrescalerRatioShift - none
  438.  
  439.  Description:
  440.  - none
  441.  
  442. */
  443. void CalculatePrescalerRatioShift(U32 SrcSize, U32 DstSize, U32 *ratio,U32 *shift)
  444. {
  445. if(SrcSize>=64*DstSize) {
  446. Uart_Printf("ERROR: out of the prescaler range: SrcSize/DstSize = %d(< 64)n",SrcSize/DstSize);
  447. while(1);
  448. }
  449. else if(SrcSize>=32*DstSize) {
  450. *ratio=32;
  451. *shift=5;
  452. }
  453. else if(SrcSize>=16*DstSize) {
  454. *ratio=16;
  455. *shift=4;
  456. }
  457. else if(SrcSize>=8*DstSize) {
  458. *ratio=8;
  459. *shift=3;
  460. }
  461. else if(SrcSize>=4*DstSize) {
  462. *ratio=4;
  463. *shift=2;
  464. }
  465. else if(SrcSize>=2*DstSize) {
  466. *ratio=2;
  467. *shift=1;
  468. }
  469. else {
  470. *ratio=1;
  471. *shift=0;
  472. }    
  473. }
  474. /********************************************************
  475.  CamCaptureStart - Start camera capture operation.
  476.  
  477.  Description:
  478.  - mode= CAM_CODEC_CAPTURE_ENABLE_BIT or CAM_PVIEW_CAPTURE_ENABLE_BIT or both
  479.   
  480. */
  481. void CamCaptureStart(U32 mode)
  482.     
  483. if(mode&CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT) {
  484. camCodecStatus=CAM_STARTED;
  485. rCICOSCCTRL|=CAM_CODEC_SACLER_START_BIT;
  486. }
  487. if(mode&CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT) {
  488. camPviewStatus=CAM_STARTED;
  489. rCIPRSCCTRL|=CAM_PVIEW_SACLER_START_BIT;
  490. }
  491. if(mode&CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT) {
  492. camCodecStatus=CAM_STARTED;
  493. rCICOSCCTRL|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT;
  494. }
  495. rCIIMGCPT|=CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT|mode;
  496. }
  497. void CamCaptureStop(void)
  498. {
  499. camCodecStatus=CAM_STOP_ISSUED;
  500. camPviewStatus=CAM_STOP_ISSUED;
  501. }
  502. void _CamCodecStopHw(void)
  503. {
  504. rCICOSCCTRL &= ~CAM_CODEC_SACLER_START_BIT; //stop codec scaler.
  505. rCIIMGCPT &= ~CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT; //stop capturing for codec scaler.
  506. if(!(rCIIMGCPT & CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT))
  507. rCIIMGCPT &= ~CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT; //stop capturing for preview scaler if needed.
  508. rCICOCTRL |= (1<<2); //Enable last IRQ at the end of frame capture.
  509.        //NOTE:LastIrqEn bit should be set after clearing CAPTURE_ENABLE_BIT & SCALER_START_BIT
  510. }
  511. void _CamPviewStopHw(void)
  512. {
  513. rCIPRSCCTRL &= ~CAM_PVIEW_SACLER_START_BIT; //stop preview scaler.
  514. rCIIMGCPT &= ~CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT; //stop capturing for preview scaler.
  515. if(!(rCIIMGCPT&CAM_CODEC_SCALER_CAPTURE_ENABLE_BIT))
  516. rCIIMGCPT &= ~CAM_CAMIF_GLOBAL_CAPTURE_ENABLE_BIT; //stop capturing for codec scaler if needed.
  517. rCIPRCTRL |= (1<<2); //Enable last IRQ at the end of frame capture.
  518.         //NOTE:LastIrqEn bit should be set after clearing CAPTURE_ENABLE_BIT & SCALER_START_BIT
  519. }
  520. void __irq CamIsr(void)
  521. {
  522. U32 completedFrameIndex;
  523. if (rSUBSRCPND&BIT_SUB_CAM_C)
  524. {
  525. //Uart_Printf("[C]");
  526. rGPFDAT ^= 1<<5; //capbily
  527. CamCodecIntMask();
  528. rSUBSRCPND |= BIT_SUB_CAM_C;
  529. ClearPending(BIT_CAM);
  530. switch(camCodecStatus) {
  531. case CAM_STOP_ISSUED:
  532. _CamCodecStopHw();
  533. camCodecStatus=CAM_LAST_CAPTURING;
  534. Uart_Printf("cr=%xn", rCICOCTRL);
  535. //Uart_Printf("cS1n");
  536. break;
  537. case CAM_LAST_CAPTURING:
  538. camCodecStatus=CAM_STOPPED;
  539. CamCodecIntMask();
  540. //Uart_Printf("cS2n");
  541. return;
  542. case CAM_STARTED:
  543. flagCaptured_C = 1;
  544. // _CamCodecStopHw();
  545. if(camTestMode&CAM_TEST_MODE_CODEC) {
  546. if(camCodecCaptureCount>0) 
  547. completedFrameIndex=(((rCICOSTATUS>>26)&0x3)+4-2)%4;   
  548. //Uart_Printf("FrameIndex:%dn",completedFrameIndex);
  549. }
  550. else {
  551. //Uart_Printf("Just Capturing without display");
  552. }
  553. break;
  554. case CAM_CODEC_SCALER_BYPASS_STATE:
  555. //Uart_Printf("cBPn");
  556. break;
  557. default:
  558. break;
  559. }
  560. CamCodecIntUnmask();
  561.     camCodecCaptureCount++;  
  562. }
  563. else
  564. {
  565. //Uart_Printf("[P]");
  566. rGPFDAT ^= 1<<4; //capbily
  567. CamPreviewIntMask();
  568. rSUBSRCPND |= BIT_SUB_CAM_P;
  569. ClearPending(BIT_CAM) ;
  570. switch(camPviewStatus) {
  571. case CAM_STOP_ISSUED:
  572. _CamPviewStopHw();
  573. camPviewStatus=CAM_LAST_CAPTURING;  
  574. Uart_Printf("pr=%xn", rCIPRCTRL);
  575. //Uart_Printf("pS1n");
  576. break;
  577. case CAM_LAST_CAPTURING:
  578. camPviewStatus=CAM_STOPPED;
  579. CamPreviewIntMask();
  580. //Uart_Printf("pS2n"); 
  581. return;
  582. case CAM_STARTED:
  583. flagCaptured_P = 1;
  584. if(camTestMode&CAM_TEST_MODE_PVIEW) {
  585. if(camPviewCaptureCount >0) 
  586. completedFrameIndex=(((rCIPRSTATUS>>26)&0x3)+4-2)%4;
  587. //Uart_Printf("FrameIndex:%dn",completedFrameIndex);
  588. }
  589. else {
  590. //Uart_Printf("Preview Image Capturedn");
  591. default:
  592. break;
  593. CamPreviewIntUnmask();
  594. camPviewCaptureCount++;
  595. }
  596. }
  597. /******************************************************************************
  598.  *                                                                            *    
  599.  *                   camera interface interrupts & controls                   *
  600.  *                                                                            *     
  601.  ******************************************************************************/
  602. U32 Conv_YCbCr_Rgb(U8 y0, U8 y1, U8 cb0, U8 cr0)  // second solution... by junon
  603. {
  604. // bit order is
  605. // YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0].
  606. int r0, g0, b0, r1, g1, b1;
  607. U32 rgb0, rgb1, rgb;
  608.  
  609. #if 1 // 4 frames/s @192MHz, 12MHz ; 6 frames/s @450MHz, 12MHz
  610. r0 = YCbCrtoR(y0, cb0, cr0);
  611. g0 = YCbCrtoG(y0, cb0, cr0);
  612. b0 = YCbCrtoB(y0, cb0, cr0);
  613. r1 = YCbCrtoR(y1, cb0, cr0);
  614. g1 = YCbCrtoG(y1, cb0, cr0);
  615. b1 = YCbCrtoB(y1, cb0, cr0);
  616. #endif
  617. if (r0>255 ) r0 = 255;
  618. if (r0<0) r0 = 0;
  619. if (g0>255 ) g0 = 255;
  620. if (g0<0) g0 = 0;
  621. if (b0>255 ) b0 = 255;
  622. if (b0<0) b0 = 0;
  623. if (r1>255 ) r1 = 255;
  624. if (r1<0) r1 = 0;
  625. if (g1>255 ) g1 = 255;
  626. if (g1<0) g1 = 0;
  627. if (b1>255 ) b1 = 255;
  628. if (b1<0) b1 = 0;
  629. // 5:6:5 16bit format
  630. rgb0 = (((U16)r0>>3)<<11) | (((U16)g0>>2)<<5) | (((U16)b0>>3)<<0); //RGB565.
  631. rgb1 = (((U16)r1>>3)<<11) | (((U16)g1>>2)<<5) | (((U16)b1>>3)<<0); //RGB565.
  632. rgb = (rgb1<<16) | rgb0;
  633. return(rgb);
  634. }
  635. void Display_Cam_Image(U32 size_x, U32 size_y)
  636. {
  637. U8 *buffer_y, *buffer_cb, *buffer_cr;
  638. U8 y0,y1,cb0,cr0;
  639. int r0,r1,g0,g1,b0,b1;
  640. U32 rgb_data0, rgb_data1; 
  641. U32 x, y;
  642. int temp;
  643. if (CAM_CODEC_4PP)
  644. temp = (((rCICOSTATUS>>26)&0x3)+4-2)%4; // current frame memory block
  645. else
  646. temp = 4;
  647. //Uart_Printf("Current Frame memory %dn", temp);
  648. switch (temp) // current frame mem - 2
  649. {
  650. case 0:
  651. buffer_y = (U8 *)rCICOYSA1;
  652. buffer_cb = (U8 *)rCICOCBSA1;
  653. buffer_cr = (U8 *)rCICOCRSA1;
  654. break;
  655. case 1:
  656. buffer_y = (U8 *)rCICOYSA2;
  657. buffer_cb = (U8 *)rCICOCBSA2;
  658. buffer_cr = (U8 *)rCICOCRSA2;
  659. break;
  660. case 2:
  661. buffer_y = (U8 *)rCICOYSA3;
  662. buffer_cb = (U8 *)rCICOCBSA3;
  663. buffer_cr = (U8 *)rCICOCRSA3;
  664. break;
  665. case 3:
  666. buffer_y = (U8 *)rCICOYSA4;
  667. buffer_cb = (U8 *)rCICOCBSA4;
  668. buffer_cr = (U8 *)rCICOCRSA4;
  669. break;
  670. default :
  671. buffer_y = (U8 *)rCICOYSA1;
  672. buffer_cb = (U8 *)rCICOCBSA1;
  673. buffer_cr = (U8 *)rCICOCRSA1;
  674. break;
  675. }
  676. //Uart_Printf("End setting : Y-0x%x, Cb-0x%x, Cr-0x%xn", buffer_y, buffer_cb, buffer_cr);
  677. #if 0
  678. // for checking converting time 
  679. rGPGCON = (rGPGCON&~(1<<23))|(1<<22); //EINT19 -> GPG11 output
  680. rGPGUP |= (1<<11);
  681. rGPGDAT &= ~(1<<11);
  682. Delay(90);
  683. rGPGDAT |=(1<<11);
  684. rgb_data0 = 0;
  685. #endif
  686. #if CAM_CODEC_OUTPUT==CAM_CCIR420
  687. for (y=0;y<size_y;y++) // YCbCr 4:2:0 format
  688. {
  689. for (x=0;x<size_x;x+=2)
  690. {
  691. rgb_data0 = Conv_YCbCr_Rgb(*buffer_y++, *buffer_y++, *buffer_cb++, *buffer_cr++);
  692. frameBuffer16BitTft240320[y][x/2] = rgb_data0;
  693. if ( (x==(size_x-2)) && ((y%2)==0) ) // when x is last pixel & y is even number
  694. {
  695. buffer_cb -= size_x/2;
  696. buffer_cr -= size_x/2;
  697. }
  698. }
  699. #else
  700. for (y=0;y<size_y;y++) // YCbCr 4:2:2 format
  701. {
  702. for (x=0;x<size_x;x+=2)
  703. rgb_data0 = Conv_YCbCr_Rgb(*buffer_y++, *buffer_y++, *buffer_cb++, *buffer_cr++);
  704. //frameBuffer16BitTft240320[y][x/2] = rgb_data0;
  705. //--- capbily
  706. //frameBuffer16BitTft240320是32位的数组!!!
  707. //in HWSWP=1 16BPP mode d0~d15 is 1st pixel, d16~d31 is 2nd
  708. //in HWSWP=0 16BPP mode d0~d15 is 2nd pixel, d16~d31 is 1st
  709. // U16 lt;
  710. //Uart_Printf("%x,%xn", *buffer_cb, *buffer_cr);
  711. //测试只输出Y(亮度)
  712. // lt = (*buffer_y++)>>3;
  713. // rgb_data0  = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
  714. // lt = (*buffer_y++)>>3;
  715. // rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
  716. //测试只输出U
  717. // lt   = (*buffer_cb)>>3;
  718. // rgb_data0  = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
  719. // lt   = (*buffer_cb++)>>3;
  720. // rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
  721. //测试只输出V
  722. // lt   = (*buffer_cr)>>3;
  723. // rgb_data0  = ((lt<<11)|(lt<<5)|(lt))<<16; //1st pixel
  724. // lt   = (*buffer_cr++)>>3;
  725. // rgb_data0 |= (lt<<11)|(lt<<5)|(lt); //2nd pixel
  726. //测试ov9650固定输出U=0x1f,V=0x70的模式
  727. // rgb_data0  = *buffer_y++<<24; //1st pixel
  728. // rgb_data0 |= *buffer_cb++<<16;
  729. // rgb_data0 |= *buffer_y++<<8; //2nd pixel
  730. // rgb_data0 |= *buffer_cr++;
  731. // rgb_data0 &= ~0xff00f800;
  732. // rgb_data0 |= 0x0700;
  733. //测试ov9650输出RGB565格式
  734. // rgb_data0  = *buffer_y++<<24; //1st pixel
  735. // rgb_data0 |= *buffer_cb++<<16;
  736. // rgb_data0 |= *buffer_y++<<8; //2nd pixel
  737. // rgb_data0 |= *buffer_cr++;
  738. //RGB高低交换
  739. // rgb_data0  = *buffer_cb++<<24; //1st pixel
  740. // rgb_data0 |= *buffer_y++<<16;
  741. // rgb_data0 |= *buffer_cr++<<8; //2nd pixel
  742. // rgb_data0 |= *buffer_y++;
  743. // rgb_data0 &= 0xf800f800; //red   only
  744. // rgb_data0 &= 0x07e007e0; //green only
  745. // rgb_data0 &= 0x001f001f; //blue  only
  746. LCD_BUFFER_CAM[y][x/2] = rgb_data0;
  747. //Uart_Printf("%08xn", rgb_data0);
  748. //---
  749. }
  750. #endif
  751. // memcpy((unsigned char*)0x30100000,  frameBuffer16BitTft240320, 320*240*2); // QCIF=178*144*2
  752. #if 0
  753. rGPGDAT &= ~(1<<11);
  754. Delay(30);
  755. rGPGDAT |=(1<<11);
  756. rGPGCON = (rGPGCON&~(1<<22))|(1<<23); // GPG11 output -> EINT19
  757. #endif
  758. }
  759. #if 0
  760. void Display_Cam_Image(int offset_x, int offset_y, int size_x, int size_y)
  761. {
  762. U8* CamFrameAddr, LcdFrameAddr;
  763. int i, temp;
  764. Lcd_MoveViewPort(offset_x, offset_y, USED_LCD_TYPE);
  765. switch(camPviewCaptureCount%4)
  766. {
  767. case 2 : 
  768. temp = rCIPRCLRSA1;
  769. break;
  770. case 3 : 
  771. temp = rCIPRCLRSA2;
  772. break;
  773. case 0 : 
  774. temp = rCIPRCLRSA3;
  775. break;
  776. case 1 :
  777. default:
  778. temp = rCIPRCLRSA4;
  779. break;
  780. }
  781. *CamFrameAddr = temp;
  782. *LcdFrameAddr = LCD_BUFFER_CAM;
  783. for(i=0;i<size_y;i++)
  784. {
  785. memcpy(LcdFrameAddr, CamFrameAddr, size_x*2);
  786. *LcdFrameAddr += size_x*4; // added virtual screen
  787. *CamFrameAddr += size_x*2; 
  788. }
  789. }
  790. #endif
  791. void Test_CamPreview(void)
  792. {
  793. U8 flag;
  794. U32 i,j,k,value;
  795. Uart_Printf("nNow Start Camera Previewn");
  796. //camera global variables
  797. camTestMode=CAM_TEST_MODE_PVIEW;
  798. camCodecCaptureCount=0;
  799. camPviewCaptureCount=0;
  800. camPviewStatus=CAM_STOPPED;
  801. camCodecStatus=CAM_STOPPED;
  802. flagCaptured_P=0;
  803. LCD_Init();
  804. #if defined(LCD_N35) || defined(LCD_T35)
  805. Paint_Bmp(0, 0, 240, 320, camera_pic_240x320);
  806. #endif
  807. Uart_Printf( "preview sc control = %xn" , rCIPRSCCTRL ) ;
  808. // Initialize Camera interface
  809. switch(USED_CAM_TYPE)
  810. {
  811. case CAM_S5X532 : // defualt for test : data-falling edge, ITU601, YCbCr
  812. CamInit(640, 480, 240, 320, 112, 20,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  813. break;
  814. case CAM_S5X3A1 : // defualt for test : data-falling edge, YCbCr
  815. CamInit(640, 480, 240, 320, 120, 100, CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  816. rCISRCFMT = rCISRCFMT & ~(1<<31); // ITU656
  817. // rCIGCTRL &= ~(1<<26); // inverse PCLK, test pattern
  818. break;
  819. //--- add by capbily
  820. case CAM_OV7620:
  821. #if defined(LCD_N35) || defined(LCD_T35)
  822. CamInit(240, 180, 240, 180, 100, 100,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  823. #elif defined(LCD_A70)
  824. CamInit(800, 480, 800, 480, 0, 0,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  825. #elif defined(LCD_L80)
  826. CamInit(640, 480, 640, 480, 0, 0,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  827. #elif defined(LCD_VGA1024768)
  828. CamInit(640, 480, 320, 240, 0, 0,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  829. #endif
  830. break;
  831. //---
  832. default : 
  833. CamInit(640, 480, 320, 240, 0, 0,  CAM_FRAMEBUFFER_C, CAM_FRAMEBUFFER_P);
  834. break;
  835. }
  836. Uart_Printf("preview sc control = %xn", rCIPRSCCTRL);
  837. // Start Capture
  838. rSUBSRCPND |= BIT_SUB_CAM_C|BIT_SUB_CAM_P;
  839. ClearPending(BIT_CAM);
  840. pISR_CAM = (U32)CamIsr;    
  841. CamPreviewIntUnmask();
  842. CamCaptureStart(CAM_PVIEW_SCALER_CAPTURE_ENABLE_BIT);
  843. Uart_Printf("Press 'ESC' key to exit!n");
  844. while (1)
  845. {
  846. if (flagCaptured_P)
  847. {
  848. flagCaptured_P = 0;
  849. // Uart_Printf("Enter Cam A port, count = %dn",camCodecCaptureCount);
  850. }
  851. if ( Uart_GetKey() == ESC_KEY ) break;
  852. }
  853.     
  854. CamCaptureStop();
  855. Uart_Printf("nWait until the current frame capture is completed.n");
  856. while(camPviewStatus!=CAM_STOPPED)
  857. if (Uart_GetKey()== 'r') break;
  858. Uart_Printf("CIS format = %xn", rCISRCFMT);
  859. Uart_Printf("image cap = %xn", rCIIMGCPT);
  860. Uart_Printf("preview sc control = %xn", rCIPRSCCTRL);
  861. Uart_Printf("preview control = %xn", rCIPRCTRL);
  862. Uart_Printf("codec sc control = %xn", rCICOSCCTRL);
  863. Uart_Printf("codec control = %xn", rCICOCTRL);
  864. Uart_Printf("pr addr1 = %xn", rCIPRCLRSA1);
  865. Uart_Printf("pr addr2 = %xn", rCIPRCLRSA2);
  866. Uart_Printf("camCodecCaptureCount=%dn",camCodecCaptureCount);
  867. Uart_Printf("camPviewCaptureCount=%dn",camPviewCaptureCount);
  868. // CamPreviewIntMask();
  869. }