iLLD_TC27xD  1.0
IfxCif_Cam.c
Go to the documentation of this file.
1 /**
2  * \file IfxCif_Cam.c
3  * \brief CIF CAM details
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxCif_Cam.h"
30 #include "Src/Std/IfxSrc.h"
31 
32 /******************************************************************************/
33 /*----------------------------------Macros------------------------------------*/
34 /******************************************************************************/
35 
36 #define IFXCIF_CAM_ALIGN(size, align) ((((size) / (align)) * (align)) + ((((size) % (align)) != 0) ? (align) : 0))
37 
38 #define IFXCIF_CAM_MEM_ALIGN(size) IFXCIF_CAM_ALIGN(size, IFXCIF_CAM_MEM_ALIGN_SIZE)
39 
40 /** \addtogroup IfxLld_Cif_Cam_camEnumerations
41  * \{ */
42 
43 /******************************************************************************/
44 /*-----------------------Private Function Prototypes--------------------------*/
45 /******************************************************************************/
46 
47 /**
48  * \param cam cam handle
49  */
50 static IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
51 
52 /** \} */
53 
54 /** \addtogroup IfxLld_Cif_Cam_camFunctions
55  * \{ */
56 /******************************************************************************/
57 /*------------------------Inline Function Prototypes--------------------------*/
58 /******************************************************************************/
59 
60 /**
61  */
63 
64 /**
65  * \return None
66  */
68 
69 /** \brief initializes GPIO Ports for image capturing
70  * \return None
71  */
73 
74 /**
75  */
77 
78 /**
79  * \param cam cam handle
80  */
82 
83 /******************************************************************************/
84 /*-----------------------Private Function Prototypes--------------------------*/
85 /******************************************************************************/
86 
87 /** \brief OVT OV10630 sensor Camera SensorcConfig subroutine , Config file is preloaded to pflash
88  */
89 static IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config);
90 
91 /** \brief Initialises the CIF for image capturing
92  * \param cam cam handel
93  * \return None
94  */
95 static void IfxCif_Cam_initCif(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
96 
97 /**
98  * \return None
99  */
100 static void IfxCif_Cam_initCifDownscaler(const IfxCif_Cam_Downscaling *ds);
101 
102 /**
103  * \param cam cam handle
104  * \return None
105  */
106 static void IfxCif_Cam_initCifExtraPath(const IfxCif_Cam *cam, IfxCif_ExtraPath ep, const IfxCif_Cam_Config *config);
107 
108 /**
109  * \return None
110  */
111 static void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config);
112 
113 /**
114  * \return None
115  */
116 static void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config);
117 
118 /**
119  * \param cam cam handle
120  * \return None
121  */
122 static void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
123 
124 /** \brief Enables CIF and EMEM and initialises all memory to 0
125  * \return None
126  */
127 static void IfxCif_Cam_initEmem(void);
128 
129 /** \} */
130 
131 /******************************************************************************/
132 /*---------------------Inline Function Implementations------------------------*/
133 /******************************************************************************/
134 
136 {
137  float32 fbytes = (float32)bytes * frames;
138  uint32 ubytes = (uint32)__roundf(fbytes);
139 
140  return Ifx_AlignOn32(ubytes);
141 }
142 
143 
145 {
146  m->hSize = mcfg->hSize;
147  m->vSize = mcfg->vSize;
148  m->hOffset = mcfg->hOffset;
149  m->vOffset = mcfg->vOffset;
150 }
151 
152 
154 {
155  /* Setup the P00.0..9, P02.0..8 pad drivers */
156  IfxPort_setGroupPadDriver(&MODULE_P02, 0, 0x01FFU, padDriver);
157  IfxPort_setGroupPadDriver(&MODULE_P00, 0, 0x03FFU, padDriver);
158 
159  /* CIF Data Lines */
160  /* P02.0 .. 8 as input for CIFD0..D8 */
161  /* P00.0 .. 6 as input for CIFD9..D15 */
162  IfxPort_setGroupModeInput(&MODULE_P02, 0, 0x01FFU, inputMode);
163  IfxPort_setGroupModeInput(&MODULE_P00, 0, 0x007FU, inputMode);
164 
165  /* CIF synchronisation lines */
166  IfxPort_setPinModeInput(&MODULE_P00, 8, inputMode); /* CIFVSNC */
167  IfxPort_setPinModeInput(&MODULE_P00, 9, inputMode); /* CIFHSNC */
168  IfxPort_setPinModeInput(&MODULE_P00, 7, inputMode); /* CIFCLK */
169 }
170 
171 
173 {
174  return (MODULE_SCU.CHIPID.B.EEA != 0) ? TRUE : FALSE;
175 }
176 
177 
179 {
180  return cam->memAreas.y.size + cam->memAreas.cb.size + cam->memAreas.cr.size;
181 }
182 
183 
184 /******************************************************************************/
185 /*-------------------------Function Implementations---------------------------*/
186 /******************************************************************************/
187 
189 {
190  (void)cam;
191  MODULE_CIF.JPE.STATUS_ICR.U = 0xFFFFFFFFUL;
192  MODULE_CIF.MI.ICR.U = 0xFFFFFFFFUL;
193  MODULE_CIF.ISP.ICR.U = 0xFFFFFFFFUL;
194 }
195 
196 
198 {
201 
202  if (cam->ispMode == IfxCif_Cam_IspMode_raw)
203  {
205  }
206  else
207  {
209  }
210 }
211 
212 
214 {
219 }
220 
221 
223 {
224  const IfxCif_Cam_PictureInfo *m = NULL_PTR;
225 
226  if (z <= IfxCif_ExtraPath_5)
227  {
228  m = &(cam->memAreas.ep[z].image);
229  }
230 
231  return m;
232 }
233 
234 
236 {
237  boolean result = FALSE;
238 
240  {
241  /* event for sending JPEG encoded image */
244 
245  if (((IfxCif_Cam_JfifHeader *)nextAddress)->app0 == 0xE0FF)
246  {
247  /* correct JPEG header was detected. */
248  *address = IfxCif_Cam_getLastFrameAddress(cam);
249  *size = IfxCif_Cam_getJpegEncodedSize(cam);
250  result = TRUE;
251  }
252  else
253  {}
254  }
255 
256  return result;
257 }
258 
259 
260 IfxCif_Cam_Status IfxCif_Cam_init(IfxCif_Cam *cam, const IfxCif_Cam_Config *config, boolean initCam)
261 {
262  /* Try allocating image areas for EMEM */
263  IfxCif_Cam_Status result = IfxCif_Cam_initMemSize(cam, config);
264 
265  /* Check if EMEM is available */
267  {
269  }
270  else
271  {
272  IfxCif_Cam_initEmem();
273  }
274 
275  /* Initialse camera if needed */
276  if ((result == IfxCif_Cam_Status_ok) && (initCam != FALSE))
277  {
278  result = IfxCif_Cam_initCamera(config);
279  }
280 
281  /* Finally, initialise the CIF */
282  if (result == IfxCif_Cam_Status_ok)
283  {
285  {
287  }
288 
290  IfxCif_Cam_initCif(cam, config);
291  }
292 
293  cam->configResult = result;
294 
295  return result;
296 }
297 
298 
299 static IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config)
300 {
302  IfxI2c_I2c i2c;
303  IfxI2c_I2c_Device i2cDev;
304 
305  { /* Initialise I2C module as master */
306  IfxI2c_I2c_Config i2cConfig;
307  IfxI2c_I2c_initConfig(&i2cConfig, &MODULE_I2C0);
308 
309  const IfxI2c_Pins pins = {
313  };
314 
315  i2cConfig.pins = &pins;
316  i2cConfig.baudrate = 400000; /* 400 kHz */
317  IfxI2c_I2c_initModule(&i2c, &i2cConfig);
318 
319  IfxI2c_I2c_deviceConfig i2cDeviceConfig;
320  IfxI2c_I2c_initDeviceConfig(&i2cDeviceConfig, &i2c); /* Device config for Bus of i2c handle */
321 
322  /* device address is obtained from the setup data table */
323  i2cDeviceConfig.deviceAddress = (0xFFU & config->setupDataTable[0]);
324  IfxI2c_I2c_initDevice(&i2cDev, &i2cDeviceConfig);
325  }
326 
327  /* Send camera configuration array */
328  {
329  uint32 count;
330 
331  for (count = 0; count < config->setupDataCount && result == IfxCif_Cam_Status_ok; count++)
332  {
333  uint32 nakCnt = 0; /* counts the NAKs */
334 
335  while (IfxI2c_I2c_write(&i2cDev, ((uint8 *)&(config->setupDataTable[count])) + 1, 3) == IfxI2c_I2c_Status_nak)
336  {
337  nakCnt++;
338 
339  if (nakCnt >= IFXCIF_MAX_I2CNAK) /* ~400 - 500 us */
340  {
342  break;
343  }
344  }
345  }
346  }
347 
348  return result;
349 }
350 
351 
352 static void IfxCif_Cam_initCif(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
353 {
354  const IfxCif_Cam_Common *common = config->common;
355 
358 
359  //IfxCif_setInternalClockMode(IfxCif_Submodules_Debug, IfxCif_State_Enabled);
360  //IfxCif_setInternalClockMode(IfxCif_Submodules_SecurityWatchdog, IfxCif_State_Enabled);
361 
362  IfxCif_Cam_initCifDownscaler(config->downscaling);
363  IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_1, config);
364  IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_2, config);
365  IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_3, config);
366  IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_4, config);
367  IfxCif_Cam_initCifExtraPath(cam, IfxCif_ExtraPath_5, config);
368 
369  IfxCif_Cam_initCifMemInterface(cam, config);
370  IfxCif_Cam_initCifIspUnit(config);
371 
372  if (common->jpegEnabled)
373  {
375  }
376  else
377  {
379  }
380 
381  if (common->jpegTables != NULL_PTR)
382  {
383  IfxCif_Cam_initCifJpegEncoder(config);
384  }
385 }
386 
387 
388 static void IfxCif_Cam_initCifDownscaler(const IfxCif_Cam_Downscaling *ds)
389 {
390  if (ds != NULL_PTR)
391  {
396  }
397 }
398 
399 
400 static void IfxCif_Cam_initCifExtraPath(const IfxCif_Cam *cam, IfxCif_ExtraPath ep, const IfxCif_Cam_Config *config)
401 {
402  const IfxCif_Cam_Common *common = config->common;
403  const IfxCif_Cam_MemConfig *mcfg = &(common->extraPaths[ep]);
404 
405  /* configuration of extra path is requested when each {hSize, vSize, memFactor} is positive. */
406 
407  if ((mcfg->hSize > 0) && (mcfg->vSize > 0) && (mcfg->memFactor > 0))
408  {
409  if ((mcfg->vSize + mcfg->vOffset) > common->ispIn.vSize)
410  {
411  /* invalid setting, the vSize and vOffset is outside the ISP acquisition */
412  IFXCIF_DEBUG;
413  }
414 
419 
420  if (config->ispMode == IfxCif_Cam_IspMode_raw)
421  {
424  }
425  else
426  {
428  }
429 
430  if ((mcfg->hSize + mcfg->hOffset) > common->ispIn.hSize)
431  {
432  /* invalid setting, the hSize and hOffset is outside the ISP acquisition */
433  IFXCIF_DEBUG;
434  }
435 
437  IfxCif_setEpCroppingPictureSizes(ep, mcfg->hSize, mcfg->vSize);
440  IfxCif_setEpInitSize(ep, cam->memAreas.ep[ep].size);
442  }
443 }
444 
445 
446 static void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config)
447 {
448  const IfxCif_Cam_Common *common = config->common;
449 
451 
454 
455  if (config->ispRawBpp == 8)
456  {
459  }
460  else if (config->ispRawBpp == 10)
461  {
464  }
465  else if (config->ispRawBpp == 12)
466  {
469  }
470  else if (config->ispRawBpp == 14)
471  {
474  }
475  else if (config->ispRawBpp == 16)
476  {
479  }
480  else
481  {
482  IFXCIF_DEBUG;
483  }
484 
488 
489  if (config->ispMode == IfxCif_Cam_IspMode_raw)
490  {
494 
495  /* the followings are ignored, but set to default */
499  }
500  else if ((config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
501  || (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar))
502  {
505  IfxCif_setIspAcquisitionSizes(common->ispIn.hSize * 2, common->ispIn.vSize);
506 
510  }
511  else
512  {
513  /* undefined */
514  IFXCIF_DEBUG;
515  }
516 
518  IfxCif_setIspPictureSizes(common->ispIn.hSize, common->ispIn.vSize);
520 
524 
526 
528  //IfxCif_setIspInterruptEnableState(IfxCif_IspInterruptSources_IspTurnedOff, IfxCif_State_Enabled);
529 
530  if (common->ispInterrupt.priority > 0)
531  {
532  volatile Ifx_SRC_SRCR *srcr = &SRC_CIFISP;
533  IfxSrc_init(srcr, common->ispInterrupt.provider, common->ispInterrupt.priority);
534  IfxSrc_enable(srcr);
535  }
536 }
537 
538 
539 static void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config)
540 {
541  const IfxCif_Cam_JpegTables *jpeTables = config->common->jpegTables;
542 
544 
545  /* Select encoding table */
549 
550  /* Programming encoding table */
557 
558  /* JPEG Codec Image Size */
559  const IfxCif_Cam_MemConfig *mcfg = &(config->common->mainPath);
560 
561  if (config->ispMode == IfxCif_Cam_IspMode_raw)
562  {
564  }
565  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
566  {
568  }
569  else
570  {
571  IFXCIF_DEBUG;
572  }
573 
574  /* JPE Header Mode Definition Register */
576 
577  /* JPE Status Interrupt Mask Register */
579  //IfxCif_setJpeInterruptEnableState(IfxCif_JpeInterruptSources_HeaderGenerationComplete, IfxCif_State_Enabled);
580 
581  /* JPE Command To Start Stream Header Generation Register */
583 
584  /* JPE Start Command To Start JFIF Stream Encoding Register */
588 
589  /* JPE Automatic Configuration Update Register */
591 }
592 
593 
594 static void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
595 {
597 
598  if (config->ispMode == IfxCif_Cam_IspMode_raw)
599  {
602 
603  if (config->ispRawBpp > 8)
604  {
606  }
607  else
608  {
610  }
611  }
612  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
613  {
617  }
618  else
619  {
620  IFXCIF_DEBUG;
621  }
622 
627 
629  //IfxCif_setMiInterruptEnableState(IfxCif_MiInterruptSources_FillMainPictureY, IfxCif_State_Enabled);
630 }
631 
632 
633 static void IfxCif_Cam_initEmem(void)
634 {
636  __nop();
637 
639  {
640  /* apply unlock sequence */
644  /* wait one cycle for unlock */
645  __nop();
646  }
647 
649 
650 #if IFXCIF_CAM_INITIALIZE_EMEM
651  {
652  uint64 *pmem;
653  uint32 i;
654 
655  /* initialize the whole EMEM with 0 */
656  pmem = (uint64 *)IFXEMEM_START_ADDR_CPU;
657 
658  for (i = 0; (uint64)i < (IFXEMEM_SIZE / 8); i += 1)
659  {
660  *(pmem++) = 0;
661  }
662  }
663 #endif
664 }
665 
666 
667 static IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
668 {
670  IfxCif_Cam_MemAreas *m = &cam->memAreas;
671  const IfxCif_Cam_Common *common = config->common;
672  const IfxCif_Cam_MemConfig *mcfg = &(common->mainPath);
673 
674  cam->nextFreeAddress = 0x00000000;
675  cam->availMemSize = 0x00100000;
676  cam->cif = &MODULE_CIF;
677  cam->emem = &MODULE_EMEM;
678  cam->configResult = 0;
679  cam->totalMemSize = 0;
680  cam->ispMode = config->ispMode;
681  cam->jfif = NULL_PTR;
682 
683  memset(m, 0, sizeof(IfxCif_Cam_MemAreas));
684 
685  uint32 numPixels = mcfg->hSize * mcfg->vSize;
686 
687  /* Calculate MainPath memory usage information ------------------------------------ */
688  if (config->ispMode == IfxCif_Cam_IspMode_raw)
689  {
690  cam->ispBpp = (config->ispRawBpp > 8) ? 2 : 1;
691  m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
692  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
693  m->cb.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
694  m->cr.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
695  }
696  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
697  {
698  cam->ispBpp = 2;
699  m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
700  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
701  m->cb.size = 0;
702  m->cr.size = m->cb.size;
703  }
704  else if (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar)
705  {
706  IFXCIF_DEBUG; /* not tested! */
707  cam->ispBpp = 2;
708  m->y.size = IfxCif_Cam_calcMem(numPixels, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
709  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
710  m->cb.size = m->y.size / 2;
711  m->cr.size = m->cb.size;
712  }
713 
715 
716  if (common->jpegEnabled != 0)
717  {
718  cam->memAreas.y.size = Ifx_AlignOn32(cam->memAreas.y.size / 8);
719  }
720 
721  m->cb.start = (Ifx_AddressValue)((uint32)m->y.start + m->y.size);
722  m->cr.start = (Ifx_AddressValue)((uint32)m->cb.start + m->cb.size);
723 
725 
728 
729  /* Calculate ExtraPath 1 memory usage information --------------------------------- */
730  IfxCif_Cam_MemInfo *mep = &(m->ep[z]);
731  mcfg = &common->extraPaths[z];
732  mep->start = nextStart;
733  mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
734  IfxCif_Cam_initPictInfo(&mep->image, mcfg);
735 
736  if (config->downscaling != NULL_PTR)
737  {
738  const IfxCif_Cam_Downscaling *downscaling = config->downscaling;
739 
740  if (downscaling->enabled)
741  {
742  /* NOTE: preliminary version (using 2x or 4x downscaling only) */
743  /* It should be possible to compute the size from the given parameters */
744  if ((downscaling->sizeFactor != 4) && (downscaling->sizeFactor != 2))
745  {
746  IFXCIF_DEBUG;
747  }
748 
749  mep->size /= (downscaling->sizeFactor * downscaling->sizeFactor);
750 
752  {
753  mep->image.hSize /= downscaling->sizeFactor;
754  }
755 
757  {
758  mep->image.vSize /= downscaling->sizeFactor;
759  }
760  }
761  }
762 
765 
766  /* Calculate ExtraPath 2..5 memory usage information ------------------------------ */
767  for (z = IfxCif_ExtraPath_2; z <= IfxCif_ExtraPath_5; z++)
768  {
769  mep = &(m->ep[z]);
770  mcfg = &common->extraPaths[z];
771  mep->start = nextStart;
772  mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
773  IfxCif_Cam_initPictInfo(&mep->image, mcfg);
776  }
777 
778  /* Total memory usage ------------------------------------------------------------- */
779  if (cam->totalMemSize <= cam->availMemSize)
780  {
781  /* if enough memory available..... */
782  cam->availMemSize -= cam->totalMemSize;
783 
784  if (cam->nextFreeAddress == 0)
785  {
787  }
788 
790  }
791  else
792  {
793  IFXCIF_DEBUG;
795  }
796 
797  return result;
798 }
799 
800 
802 {
803  (void)cam;
807 }
808 
809 
810 void IfxCif_Cam_startCapture(const IfxCif_Cam *cam, uint8 frames)
811 {
812  (void)cam;
819 }
820 
821 
823 {
824  (void)cam;
827 }