iLLD_TC27xC  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_0_1_0_10
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 "I2c/I2c/IfxI2c_I2c.h"
31 #include "string.h"
32 #include "Src/Std/IfxSrc.h"
33 
34 /******************************************************************************/
35 /*----------------------------------Macros------------------------------------*/
36 /******************************************************************************/
37 
38 #define IFXCIF_CAM_ALIGN(size, align) ((((size) / (align)) * (align)) + ((((size) % (align)) != 0) ? (align) : 0))
39 
40 #define IFXCIF_CAM_MEM_ALIGN(size) IFXCIF_CAM_ALIGN(size, IFXCIF_CAM_MEM_ALIGN_SIZE)
41 
42 /** \addtogroup IfxLld_Cif_Cam_camEnumerations
43  * \{ */
44 
45 /******************************************************************************/
46 /*-----------------------Private Function Prototypes--------------------------*/
47 /******************************************************************************/
48 
49 /**
50  * \param cam cam handle
51  */
52 static IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
53 
54 /** \} */
55 
56 /** \addtogroup IfxLld_Cif_Cam_camFunctions
57  * \{ */
58 /******************************************************************************/
59 /*------------------------Inline Function Prototypes--------------------------*/
60 /******************************************************************************/
61 
62 /**
63  */
65 
66 /**
67  * \return None
68  */
70 
71 /** \brief initializes GPIO Ports for image capturing
72  * \return None
73  */
75 
76 /**
77  */
79 
80 /**
81  * \param cam cam handle
82  */
84 
85 /******************************************************************************/
86 /*-----------------------Private Function Prototypes--------------------------*/
87 /******************************************************************************/
88 
89 /** \brief OVT OV10630 sensor Camera SensorcConfig subroutine , Config file is preloaded to pflash
90  */
91 static IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config);
92 
93 /** \brief Initialises the CIF for image capturing
94  * \param cam cam handel
95  * \return None
96  */
97 static void IfxCif_Cam_initCif(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
98 
99 /**
100  * \return None
101  */
102 static void IfxCif_Cam_initCifDownscaler(const IfxCif_Cam_Downscaling *ds);
103 
104 /**
105  * \param cam cam handle
106  * \return None
107  */
108 static void IfxCif_Cam_initCifExtraPath(const IfxCif_Cam *cam, IfxCif_ExtraPath ep, const IfxCif_Cam_Config *config);
109 
110 /**
111  * \return None
112  */
113 static void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config);
114 
115 /**
116  * \return None
117  */
118 static void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config);
119 
120 /**
121  * \param cam cam handle
122  * \return None
123  */
124 static void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config);
125 
126 /** \brief Enables CIF and EMEM and initialises all memory to 0
127  * \return None
128  */
129 static void IfxCif_Cam_initEmem(void);
130 
131 /** \} */
132 
133 /******************************************************************************/
134 /*---------------------Inline Function Implementations------------------------*/
135 /******************************************************************************/
136 
138 {
139  float32 fbytes = (float32)bytes * frames;
140  uint32 ubytes = (uint32)__roundf(fbytes);
141 
142  return Ifx_AlignOn32(ubytes);
143 }
144 
145 
147 {
148  m->hSize = mcfg->hSize;
149  m->vSize = mcfg->vSize;
150  m->hOffset = mcfg->hOffset;
151  m->vOffset = mcfg->vOffset;
152 }
153 
154 
156 {
157  /* Setup the P00.0..9, P02.0..8 pad drivers */
158  IfxPort_setGroupPadDriver(&MODULE_P02, 0, 0x01FFU, padDriver);
159  IfxPort_setGroupPadDriver(&MODULE_P00, 0, 0x03FFU, padDriver);
160 
161  //CIF Data Lines
162  /* P02.0 .. 8 as input for CIFD0..D8 */
163  /* P00.0 .. 6 as input for CIFD9..D15 */
164  IfxPort_setGroupModeInput(&MODULE_P02, 0, 0x01FFU, inputMode);
165  IfxPort_setGroupModeInput(&MODULE_P00, 0, 0x007FU, inputMode);
166 
167  //CIF synchronisation lines
168  IfxPort_setPinModeInput(&MODULE_P00, 8, inputMode); // CIFVSNC
169  IfxPort_setPinModeInput(&MODULE_P00, 9, inputMode); // CIFHSNC
170  IfxPort_setPinModeInput(&MODULE_P00, 7, inputMode); // CIFCLK
171 }
172 
173 
175 {
176  return (MODULE_SCU.CHIPID.B.EEA != 0) ? TRUE : FALSE;
177 }
178 
179 
181 {
182  return cam->memAreas.y.size + cam->memAreas.cb.size + cam->memAreas.cr.size;
183 }
184 
185 
186 /******************************************************************************/
187 /*-------------------------Function Implementations---------------------------*/
188 /******************************************************************************/
189 
191 {
192  (void)cam;
193  MODULE_CIF.JPE.STATUS_ICR.U = 0xFFFFFFFFUL;
194  MODULE_CIF.MI.ICR.U = 0xFFFFFFFFUL;
195  MODULE_CIF.ISP.ICR.U = 0xFFFFFFFFUL;
196 }
197 
198 
200 {
203 
204  if (cam->ispMode == IfxCif_Cam_IspMode_raw)
205  {
207  }
208  else
209  {
211  }
212 }
213 
214 
216 {
221 }
222 
223 
225 {
226  const IfxCif_Cam_PictureInfo *m = NULL_PTR;
227 
228  if (z <= IfxCif_ExtraPath_5)
229  {
230  m = &(cam->memAreas.ep[z].image);
231  }
232 
233  return m;
234 }
235 
236 
238 {
239  boolean result = FALSE;
240 
242  {
243  // event for sending JPEG encoded image
246 
247  if (((IfxCif_Cam_JfifHeader *)nextAddress)->app0 == 0xE0FF)
248  {
249  // correct JPEG header was detected.
250  *address = IfxCif_Cam_getLastFrameAddress(cam);
251  *size = IfxCif_Cam_getJpegEncodedSize(cam);
252  }
253  else
254  {}
255  }
256 
257  return result;
258 }
259 
260 
261 IfxCif_Cam_Status IfxCif_Cam_init(IfxCif_Cam *cam, const IfxCif_Cam_Config *config, boolean initCam)
262 {
263  /* Try allocating image areas for EMEM */
264  IfxCif_Cam_Status result = IfxCif_Cam_initMemSize(cam, config);
265 
266  /* Check if EMEM is available */
268  {
270  }
271  else
272  {
273  IfxCif_Cam_initEmem();
274  }
275 
276  /* Initialse camera if needed */
277  if ((result == IfxCif_Cam_Status_ok) && (initCam != FALSE))
278  {
279  result = IfxCif_Cam_initCamera(config);
280  }
281 
282  /* Finally, initialise the CIF */
283  if (result == IfxCif_Cam_Status_ok)
284  {
286  {
288  }
289 
291  IfxCif_Cam_initCif(cam, config);
292  }
293 
294  cam->configResult = result;
295 
296  return result;
297 }
298 
299 
300 static IfxCif_Cam_Status IfxCif_Cam_initCamera(const IfxCif_Cam_Config *config)
301 {
303  IfxI2c_I2c i2c;
304  IfxI2c_I2c_Device i2cDev;
305 
306  { /* Initialise I2C module as master */
307  IfxI2c_I2c_Config config;
308  IfxI2c_I2c_initConfig(&config, &MODULE_I2C0);
309 
310  const IfxI2c_Pins pins = {
314  };
315 
316  config.pins = &pins;
317  config.baudrate = 400000; // 400 kHz
318  IfxI2c_I2c_initModule(&i2c, &config);
319 
320  IfxI2c_I2c_deviceConfig i2cDeviceConfig;
321  IfxI2c_I2c_initDeviceConfig(&i2cDeviceConfig, &i2c); // Device config for Bus of i2c handle
322 
323  i2cDeviceConfig.deviceAddress = 0x90;
324  IfxI2c_I2c_initDevice(&i2cDeviceConfig, &i2cDev);
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], 4) == 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  { // invalid setting, the vSize and vOffset is outside the ISP acquisition
411  IFXCIF_DEBUG;
412  }
413 
418 
419  if (config->ispMode == IfxCif_Cam_IspMode_raw)
420  {
423  }
424  else
425  {
427  }
428 
429  if ((mcfg->hSize + mcfg->hOffset) > common->ispIn.hSize)
430  { // invalid setting, the hSize and hOffset is outside the ISP acquisition
431  __debug();
432  }
433 
435  IfxCif_setEpCroppingPictureSizes(ep, mcfg->hSize, mcfg->vSize);
438  IfxCif_setEpInitSize(ep, cam->memAreas.ep[ep].size);
440  }
441 }
442 
443 
444 static void IfxCif_Cam_initCifIspUnit(const IfxCif_Cam_Config *config)
445 {
446  const IfxCif_Cam_Common *common = config->common;
447 
449 
452 
453  if (config->ispRawBpp == 8)
454  {
457  }
458  else if (config->ispRawBpp == 10)
459  {
462  }
463  else if (config->ispRawBpp == 12)
464  {
467  }
468  else if (config->ispRawBpp == 14)
469  {
472  }
473  else if (config->ispRawBpp == 16)
474  {
477  }
478  else
479  {
480  __debug();
481  }
482 
486 
487  if (config->ispMode == IfxCif_Cam_IspMode_raw)
488  {
492 
493  // the followings are ignored, but set to default
497  }
498  else if ((config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
499  || (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar))
500  {
503  IfxCif_setIspAcquisitionSizes(common->ispIn.hSize * 2, common->ispIn.vSize);
504 
508  }
509  else
510  { // undefined
511  IFXCIF_DEBUG;
512  }
513 
515  IfxCif_setIspPictureSizes(common->ispIn.hSize, common->ispIn.vSize);
517 
521 
523 
525  //IfxCif_setIspInterruptEnableState(IfxCif_IspInterruptSources_IspTurnedOff, IfxCif_State_Enabled);
526 
527  if (common->ispInterrupt.priority > 0)
528  {
529  volatile Ifx_SRC_SRCR *srcr = &SRC_CIFISP;
530  IfxSrc_init(srcr, common->ispInterrupt.provider, common->ispInterrupt.priority);
531  IfxSrc_enable(srcr);
532  }
533 }
534 
535 
536 static void IfxCif_Cam_initCifJpegEncoder(const IfxCif_Cam_Config *config)
537 {
538  const IfxCif_Cam_JpegTables *jpeTables = config->common->jpegTables;
539 
541 
542  /* Select encoding table */
546 
547  /* Programming encoding table */
554 
555  /* JPEG Codec Image Size */
556  const IfxCif_Cam_MemConfig *mcfg = &(config->common->mainPath);
557 
558  if (config->ispMode == IfxCif_Cam_IspMode_raw)
559  {
561  }
562  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
563  {
565  }
566  else
567  {
568  IFXCIF_DEBUG;
569  }
570 
571  /* JPE Header Mode Definition Register */
573 
574  /* JPE Status Interrupt Mask Register */
576  //IfxCif_setJpeInterruptEnableState(IfxCif_JpeInterruptSources_HeaderGenerationComplete, IfxCif_State_Enabled);
577 
578  /* JPE Command To Start Stream Header Generation Register */
580 
581  /* JPE Start Command To Start JFIF Stream Encoding Register */
585 
586  /* JPE Automatic Configuration Update Register */
588 }
589 
590 
591 static void IfxCif_Cam_initCifMemInterface(const IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
592 {
594 
595  if (config->ispMode == IfxCif_Cam_IspMode_raw)
596  {
599 
600  if (config->ispRawBpp > 8)
601  {
603  }
604  else
605  {
607  }
608  }
609  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
610  {
614  }
615  else
616  {
617  IFXCIF_DEBUG;
618  }
619 
624 
626  //IfxCif_setMiInterruptEnableState(IfxCif_MiInterruptSources_FillMainPictureY, IfxCif_State_Enabled);
627 }
628 
629 
630 static void IfxCif_Cam_initEmem(void)
631 {
633  __nop();
634 
636  {
637  /* apply unlock sequence */
641  /* wait one cycle for unlock */
642  __nop();
643  }
644 
646 
647 #if IFXCIF_CAM_INITIALIZE_EMEM
648  {
649  uint64 *pmem;
650  uint32 i;
651 
652  /* initialize the whole EMEM with 0 */
653  pmem = (uint64 *)IFXEMEM_START_ADDR_CPU;
654 
655  for (i = 0; (uint64)i < (IFXEMEM_SIZE / 8); i += 1)
656  {
657  *(pmem++) = 0;
658  }
659  }
660 #endif
661 }
662 
663 
664 static IfxCif_Cam_Status IfxCif_Cam_initMemSize(IfxCif_Cam *cam, const IfxCif_Cam_Config *config)
665 {
667  IfxCif_Cam_MemAreas *m = &cam->memAreas;
668  const IfxCif_Cam_Common *common = config->common;
669  const IfxCif_Cam_MemConfig *mcfg = &(common->mainPath);
670 
671  cam->nextFreeAddress = 0x00000000;
672  cam->availMemSize = 0x00100000;
673  cam->cif = &MODULE_CIF;
674  cam->emem = &MODULE_EMEM;
675  cam->configResult = 0;
676  cam->totalMemSize = 0;
677  cam->ispMode = config->ispMode;
678  cam->jfif = NULL_PTR;
679 
680  memset(m, 0, sizeof(IfxCif_Cam_MemAreas));
681 
682  uint32 numPixels = mcfg->hSize * mcfg->vSize;
683 
684  /* Calculate MainPath memory usage information ------------------------------------ */
685  if (config->ispMode == IfxCif_Cam_IspMode_raw)
686  {
687  cam->ispBpp = (config->ispRawBpp > 8) ? 2 : 1;
688  m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
689  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
690  m->cb.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
691  m->cr.size = 0 + IFXCIF_CAM_MEM_GAPSIZE;
692  }
693  else if (config->ispMode == IfxCif_Cam_IspMode_yuvInterleaved)
694  {
695  cam->ispBpp = 2;
696  m->y.size = IfxCif_Cam_calcMem(numPixels * cam->ispBpp, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
697  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
698  m->cb.size = 0;
699  m->cr.size = m->cb.size;
700  }
701  else if (config->ispMode == IfxCif_Cam_IspMode_yuvPlanar)
702  {
703  __debug(); // not tested!
704  cam->ispBpp = 2;
705  m->y.size = IfxCif_Cam_calcMem(numPixels, mcfg->memFactor) + IFXCIF_CAM_MEM_GAPSIZE;
706  IfxCif_Cam_initPictInfo(&m->y.image, mcfg);
707  m->cb.size = m->y.size / 2;
708  m->cr.size = m->cb.size;
709  }
710 
712 
713  if (common->jpegEnabled != 0)
714  {
715  cam->memAreas.y.size = Ifx_AlignOn32(cam->memAreas.y.size / 8);
716  }
717 
718  m->cb.start = (Ifx_AddressValue)((uint32)m->y.start + m->y.size);
719  m->cr.start = (Ifx_AddressValue)((uint32)m->cb.start + m->cb.size);
720 
722 
725 
726  /* Calculate ExtraPath 1 memory usage information --------------------------------- */
727  IfxCif_Cam_MemInfo *mep = &(m->ep[z]);
728  mcfg = &common->extraPaths[z];
729  mep->start = nextStart;
730  mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
731  IfxCif_Cam_initPictInfo(&mep->image, mcfg);
732 
733  if (config->downscaling != NULL_PTR)
734  {
735  const IfxCif_Cam_Downscaling *downscaling = config->downscaling;
736 
737  if (downscaling->enabled)
738  {
739  // NOTE: preliminary version (using 2x or 4x downscaling only)
740  // It should be possible to compute the size from the given parameters
741  if ((downscaling->sizeFactor != 4) && (downscaling->sizeFactor != 2))
742  {
743  IFXCIF_DEBUG;
744  }
745 
746  mep->size /= (downscaling->sizeFactor * downscaling->sizeFactor);
747 
749  {
750  mep->image.hSize /= downscaling->sizeFactor;
751  }
752 
754  {
755  mep->image.vSize /= downscaling->sizeFactor;
756  }
757  }
758  }
759 
762 
763  /* Calculate ExtraPath 2..5 memory usage information ------------------------------ */
764  for (z = IfxCif_ExtraPath_2; z <= IfxCif_ExtraPath_5; z++)
765  {
766  mep = &(m->ep[z]);
767  mcfg = &common->extraPaths[z];
768  mep->start = nextStart;
769  mep->size = IfxCif_Cam_calcMem(cam->ispBpp * (mcfg->vSize * mcfg->hSize), mcfg->memFactor);
770  IfxCif_Cam_initPictInfo(&mep->image, mcfg);
773  }
774 
775  /* Total memory usage ------------------------------------------------------------- */
776  if (cam->totalMemSize <= cam->availMemSize)
777  { //if enough memory available.....
778  cam->availMemSize -= cam->totalMemSize;
779 
780  if (cam->nextFreeAddress == 0)
781  {
783  }
784 
786  }
787  else
788  {
789  IFXCIF_DEBUG;
791  }
792 
793  return result;
794 }
795 
796 
798 {
799  (void)cam;
803 }
804 
805 
806 void IfxCif_Cam_startCapture(const IfxCif_Cam *cam, uint8 frames)
807 {
808  (void)cam;
815 }
816 
817 
819 {
820  (void)cam;
823 }