1 /*
2  *  Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 //*****************************************************************************
34 //
35 //  camera.c
36 //
37 //  Driver for the camera controller module
38 //
39 //*****************************************************************************
40 
41 //*****************************************************************************
42 //
43 //! \addtogroup camera_api
44 //! @{
45 //
46 //*****************************************************************************
47 
48 #include "inc/hw_types.h"
49 #include "inc/hw_ints.h"
50 #include "inc/hw_memmap.h"
51 #include "inc/hw_camera.h"
52 #include "inc/hw_apps_config.h"
53 #include "interrupt.h"
54 #include "camera.h"
55 
56 //******************************************************************************
57 //
58 //! Resets the Camera core
59 //!
60 //! \param ulBase is the base address of the camera module.
61 //!
62 //! This function resets the camera core
63 //!
64 //! \return None.
65 //
66 //******************************************************************************
CameraReset(unsigned long ulBase)67 void CameraReset(unsigned long ulBase)
68 {
69   //
70   // Reset the camera
71   //
72   HWREG(ulBase + CAMERA_O_CC_SYSCONFIG) = CAMERA_CC_SYSCONFIG_SOFT_RESET;
73 
74   //
75   // Wait for reset completion
76   //
77   while(!(HWREG(ulBase + CAMERA_O_CC_SYSSTATUS)&
78           CAMERA_CC_SYSSTATUS_RESET_DONE2))
79   {
80 
81   }
82 
83 }
84 
85 //******************************************************************************
86 //
87 //! Configures camera parameters
88 //!
89 //! \param ulBase is the base address of the camera module.
90 //! \param ulHSPol sets the HSync polarity
91 //! \param ulVSPol sets the VSync polarity
92 //! \param ulFlags are configuration flags
93 //!
94 //! This function sets different camera parameters.
95 //!
96 //! The parameter \e ulHSPol should be on the follwoing:
97 //! - \b CAM_HS_POL_HI
98 //! - \b CAM_HS_POL_LO
99 //!
100 //! The parameter \e ulVSPol should be on the follwoing:
101 //! - \b CAM_VS_POL_HI
102 //! - \b CAM_VS_POL_LO
103 //!
104 //! The parameter \e ulFlags can be logical OR of one or more of the follwoing
105 //! or 0:
106 //! - \b CAM_PCLK_RISE_EDGE
107 //! - \b CAM_PCLK_FALL_EDGE
108 //! - \b CAM_ORDERCAM_SWAP
109 //! - \b CAM_NOBT_SYNCHRO
110 //! - \b CAM_IF_SYNCHRO
111 //!
112 //! \return None.
113 //
114 //******************************************************************************
CameraParamsConfig(unsigned long ulBase,unsigned long ulHSPol,unsigned long ulVSPol,unsigned long ulFlags)115 void CameraParamsConfig(unsigned long ulBase, unsigned long ulHSPol,
116                         unsigned long ulVSPol, unsigned long ulFlags)
117 {
118   unsigned long ulReg;
119 
120   //
121   // Read the register
122   //
123   ulReg = HWREG(ulBase + CAMERA_O_CC_CTRL);
124 
125   //
126   // Set the requested parameter
127   //
128   ulFlags = (ulFlags|ulHSPol|ulVSPol);
129   ulReg = ((ulReg & ~(CAMERA_CC_CTRL_NOBT_SYNCHRO |
130                    CAMERA_CC_CTRL_NOBT_HS_POL |
131                    CAMERA_CC_CTRL_NOBT_VS_POL |
132                    CAMERA_CC_CTRL_BT_CORRECT  |
133                    CAMERA_CC_CTRL_PAR_ORDERCAM |
134                    CAMERA_CC_CTRL_PAR_CLK_POL )) | ulFlags);
135 
136   //
137   // Write the configuration
138   //
139   HWREG(ulBase + CAMERA_O_CC_CTRL)=ulReg;
140 }
141 
142 
143 //******************************************************************************
144 //
145 //! Set the internal clock divider
146 //!
147 //! \param ulBase is the base address of the camera module.
148 //! \param ulCamClkIn is input to camera module
149 //! \param ulXClk defines the output required
150 //!
151 //! This function sets the internal clock divider based on \e ulCamClkIn to
152 //! generate XCLK as specified be \e ulXClk. Maximum suppoter division is 30
153 //!
154 //! \return None.
155 //
156 //******************************************************************************
CameraXClkConfig(unsigned long ulBase,unsigned long ulCamClkIn,unsigned long ulXClk)157 void CameraXClkConfig(unsigned long ulBase, unsigned long ulCamClkIn,
158                       unsigned long ulXClk)
159 {
160   unsigned long ulReg;
161   unsigned long ucDiv;
162 
163   //
164   // Read the register
165   //
166   ulReg = HWREG(ulBase + CAMERA_O_CC_CTRL_XCLK);
167 
168   //
169   // Mask XCLK divider value
170   //
171   ulReg &= ~(CAMERA_CC_CTRL_XCLK_XCLK_DIV_M);
172 
173   //
174   // Compute the divider
175   //
176   ucDiv = ((ulCamClkIn)/ulXClk);
177 
178   //
179   // Max supported division is 30
180   //
181   if(ucDiv > 30)
182   {
183       return;
184   }
185 
186   //
187   // Set and write back the configuration
188   //
189   ulReg |= ucDiv;
190   HWREG(ulBase + CAMERA_O_CC_CTRL_XCLK) = ulReg;
191 }
192 
193 
194 //******************************************************************************
195 //
196 //! Sets the internal divide in specified mode
197 //!
198 //! \param ulBase is the base address of the camera module.
199 //! \param bXClkFlags decides the divide mode
200 //!
201 //! This function sets the internal divide in specified mode.
202 //!
203 //! The parameter \e bXClkFlags should be one of the following :
204 //!
205 //! - \b CAM_XCLK_STABLE_LO
206 //! - \b CAM_XCLK_STABLE_HI
207 //! - \b CAM_XCLK_DIV_BYPASS
208 //!
209 //! \return None.
210 //
211 //******************************************************************************
CameraXClkSet(unsigned long ulBase,unsigned char bXClkFlags)212 void CameraXClkSet(unsigned long ulBase, unsigned char bXClkFlags)
213 {
214   unsigned long ulReg;
215 
216   //
217   // Read and Mask XTAL Divider config.
218   //
219   ulReg = (HWREG(ulBase + CAMERA_O_CC_CTRL_XCLK) &
220     ~(CAMERA_CC_CTRL_XCLK_XCLK_DIV_M));
221 
222   //
223   // Set config. base on parameter flag
224   //
225   switch(bXClkFlags)
226   {
227 
228   case CAM_XCLK_STABLE_HI : ulReg |= 0x00000001;
229                             break;
230 
231   case CAM_XCLK_DIV_BYPASS: ulReg |= 0x0000001F;
232                             break;
233   }
234 
235   //
236   // Write the config.
237   //
238   HWREG(ulBase + CAMERA_O_CC_CTRL_XCLK) = ulReg;
239 }
240 
241 
242 //******************************************************************************
243 //
244 //! Enable camera DMA
245 //!
246 //! \param ulBase is the base address of the camera module.
247 //!
248 //! This function enables transfer request to DMA from camera. DMA specific
249 //! configuration has to be done seperately.
250 //!
251 //! \return None.
252 //
253 //******************************************************************************
CameraDMAEnable(unsigned long ulBase)254 void CameraDMAEnable(unsigned long ulBase)
255 {
256   //
257   // Enable DMA
258   //
259   HWREG(ulBase + CAMERA_O_CC_CTRL_DMA) |= CAMERA_CC_CTRL_DMA_DMA_EN;
260 }
261 
262 
263 //******************************************************************************
264 //
265 //! Disable camera DMA
266 //!
267 //! \param ulBase is the base address of the camera module.
268 //!
269 //! This function masks transfer request to DMA from camera.
270 //!
271 //! \return None.
272 //
273 //******************************************************************************
CameraDMADisable(unsigned long ulBase)274 void CameraDMADisable(unsigned long ulBase)
275 {
276   //
277   // Disable DMA
278   //
279   HWREG(ulBase + CAMERA_O_CC_CTRL_DMA) &= ~CAMERA_CC_CTRL_DMA_DMA_EN;
280 }
281 
282 
283 
284 //******************************************************************************
285 //
286 //! Sets the FIFO threshold for DMA transfer request
287 //!
288 //! \param ulBase is the base address of the camera module.
289 //! \param ulThreshold specifies the FIFO threshold
290 //!
291 //! This function sets the FIFO threshold for DMA transfer request.
292 //! Parameter \e ulThreshold can range from 1 - 64
293 //!
294 //! \return None.
295 //
296 //******************************************************************************
CameraThresholdSet(unsigned long ulBase,unsigned long ulThreshold)297 void CameraThresholdSet(unsigned long ulBase, unsigned long ulThreshold)
298 {
299   //
300   // Read and Mask DMA threshold field
301   //
302   HWREG(ulBase + CAMERA_O_CC_CTRL_DMA) &= ~CAMERA_CC_CTRL_DMA_FIFO_THRESHOLD_M;
303   //
304   // Write the new threshold value
305   //
306   HWREG(ulBase + CAMERA_O_CC_CTRL_DMA) |= (ulThreshold -1);
307 }
308 
309 
310 //******************************************************************************
311 //
312 //! Register camera interrupt handler
313 //!
314 //! \param ulBase is the base address of the camera module.
315 //! \param pfnHandler hold pointer to interrupt handler
316 //!
317 //! This function registers and enables global camera interrupt from the
318 //! interrupt controller. Individual camera interrupts source
319 //! should be enabled using \sa CameraIntEnable().
320 //!
321 //! \return None.
322 //
323 //******************************************************************************
CameraIntRegister(unsigned long ulBase,void (* pfnHandler)(void))324 void CameraIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
325 {
326     //
327     // Register the interrupt handler.
328     //
329     IntRegister(INT_CAMERA, pfnHandler);
330 
331     //
332     // Enable the Camera interrupt.
333     //
334     IntEnable(INT_CAMERA);
335 }
336 
337 
338 //******************************************************************************
339 //
340 //! Un-Register camera interrupt handler
341 //!
342 //! \param ulBase is the base address of the camera module.
343 //!
344 //! This function unregisters and disables global camera interrupt from the
345 //! interrupt controller.
346 //!
347 //! \return None.
348 //
349 //******************************************************************************
CameraIntUnregister(unsigned long ulBase)350 void CameraIntUnregister(unsigned long ulBase)
351 {
352     //
353     // Disable the interrupt.
354     //
355     IntDisable(INT_CAMERA);
356 
357     //
358     // Unregister the interrupt handler.
359     //
360     IntUnregister(INT_CAMERA);
361 }
362 
363 
364 //******************************************************************************
365 //! Enables individual camera interrupt sources.
366 //!
367 //! \param ulBase is the base address of the camera module.
368 //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
369 //!
370 //! This function enables individual camera interrupt sources.
371 //!
372 //! the parameter \e ulIntFlags should be logical OR of one or more of the
373 //! following:
374 //!
375 //! - \b CAM_INT_DMA
376 //! - \b CAM_INT_FE
377 //! - \b CAM_INT_FSC_ERR
378 //! - \b CAM_INT_FIFO_NOEMPTY
379 //! - \b CAM_INT_FIFO_FULL
380 //! - \b CAM_INT_FIFO_THR
381 //! - \b CAM_INT_FIFO_OF
382 //! - \b CAN_INT_FIFO_UR
383 //!
384 //! \return None.
385 //
386 //******************************************************************************
CameraIntEnable(unsigned long ulBase,unsigned long ulIntFlags)387 void CameraIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
388 {
389   //
390   // unmask Camera DMA done interrupt
391   //
392   if(ulIntFlags & CAM_INT_DMA)
393   {
394     HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_CLR) = ((1<<8));
395   }
396 
397   //
398   // Enable specific camera interrupts
399   //
400   HWREG(ulBase + CAMERA_O_CC_IRQENABLE) |= ulIntFlags;
401 }
402 
403 
404 //******************************************************************************
405 //! Disables individual camera interrupt sources.
406 //!
407 //! \param ulBase is the base address of the camera module.
408 //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
409 //!
410 //! This function disables individual camera interrupt sources.
411 //!
412 //! The parameter \e ulIntFlags should be logical OR of one or more of the
413 //! values as defined in CameraIntEnable().
414 //!
415 //! \return None.
416 //
417 //******************************************************************************
CameraIntDisable(unsigned long ulBase,unsigned long ulIntFlags)418 void CameraIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
419 {
420   //
421   // Mask Camera DMA done interrupt
422   //
423   if(ulIntFlags & CAM_INT_DMA)
424   {
425     HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET) = ((1<<8));
426   }
427 
428   //
429   // Disable specific camera interrupts
430   //
431   HWREG(ulBase + CAMERA_O_CC_IRQENABLE) &= ~ulIntFlags;
432 }
433 
434 //******************************************************************************
435 //
436 //! Returns the current interrupt status,
437 //!
438 //! \param ulBase is the base address of the camera module.
439 //! \param ulBase is the base address of the camera module.
440 //!
441 //! This functions returns the current interrupt status for the camera.
442 //!
443 //! \return Returns the current interrupt status, enumerated as a bit field of
444 //! values described in CameraIntEnable().
445 //******************************************************************************
CameraIntStatus(unsigned long ulBase)446 unsigned long CameraIntStatus(unsigned long ulBase)
447 {
448   unsigned ulIntFlag;
449 
450   //
451   // Read camera interrupt
452   //
453   ulIntFlag = HWREG(ulBase + CAMERA_O_CC_IRQSTATUS);
454 
455   //
456   //
457   // Read camera DMA doner interrupt
458   //
459   if(HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_MASKED) & (1<<8))
460   {
461     ulIntFlag |= CAM_INT_DMA;
462   }
463 
464   //
465   // Return status
466   //
467   return(ulIntFlag);
468 }
469 
470 
471 //******************************************************************************
472 //! Clears individual camera interrupt sources.
473 //!
474 //! \param ulBase is the base address of the camera module.
475 //! \param ulIntFlags is the bit mask of the interrupt sources to be Clears.
476 //!
477 //! This function Clears individual camera interrupt sources.
478 //!
479 //! The parameter \e ulIntFlags should be logical OR of one or more of the
480 //! values as defined in CameraIntEnable().
481 //!
482 //! \return None.
483 //
484 //******************************************************************************
CameraIntClear(unsigned long ulBase,unsigned long ulIntFlags)485 void CameraIntClear(unsigned long ulBase, unsigned long ulIntFlags)
486 {
487   //
488   // Clear DMA done int  status
489   //
490   if(ulIntFlags & CAM_INT_DMA)
491   {
492     HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_ACK) = ((1<<8));
493   }
494 
495   //
496   // Clear the interrupts
497   //
498   HWREG(ulBase + CAMERA_O_CC_IRQSTATUS) = ulIntFlags;
499 }
500 
501 //******************************************************************************
502 //
503 //! Starts image capture
504 //!
505 //! \param ulBase is the base address of the camera module.
506 //!
507 //! This function starts the image capture over the configured camera interface
508 //! This function should be called after configuring the camera module
509 //! completele
510 //!
511 //! \return None.
512 //
513 //******************************************************************************
CameraCaptureStart(unsigned long ulBase)514 void CameraCaptureStart(unsigned long ulBase)
515 {
516   //
517   // Set the mode
518   //
519   HWREG(ulBase + CAMERA_O_CC_CTRL) &= ~0xF;
520 
521   //
522   // Enable image capture
523   //
524   HWREG(ulBase + CAMERA_O_CC_CTRL) |= CAMERA_CC_CTRL_CC_EN;
525 }
526 
527 //******************************************************************************
528 //
529 //! Stops image capture
530 //!
531 //! \param ulBase is the base address of the camera module.
532 //! \param bImmediate is \b true to stop capture imeediately else \b flase.
533 //!
534 //! This function stops the image capture over the camera interface.
535 //! The capture is stopped either immediatelt or at the end of current frame
536 //! based on \e bImmediate parameter.
537 //!
538 //! \return None.
539 //
540 //******************************************************************************
CameraCaptureStop(unsigned long ulBase,tBoolean bImmediate)541 void CameraCaptureStop(unsigned long ulBase, tBoolean bImmediate)
542 {
543   if(bImmediate)
544   {
545     //
546     // Stop capture immediately
547     //
548     HWREG(ulBase + CAMERA_O_CC_CTRL) &= ~CAMERA_CC_CTRL_CC_FRAME_TRIG;
549   }
550   else
551   {
552     //
553     // Stop capture at the end of frame
554     //
555     HWREG(ulBase + CAMERA_O_CC_CTRL) |= CAMERA_CC_CTRL_CC_FRAME_TRIG;
556   }
557 
558   //
559   // Request camera to stop capture
560   //
561   HWREG(ulBase + CAMERA_O_CC_CTRL) &= ~CAMERA_CC_CTRL_CC_EN;
562 }
563 
564 
565 //******************************************************************************
566 //
567 //! Reads the camera buffer (FIFO)
568 //!
569 //! \param ulBase is the base address of the camera module.
570 //! \param pBuffer is the pointer to the read buffer
571 //! \param ucSize specifies the size to data to be read
572 //!
573 //! This function reads the camera buffer (FIFO).
574 //!
575 //! \return None.
576 //
577 //******************************************************************************
CameraBufferRead(unsigned long ulBase,unsigned long * pBuffer,unsigned char ucSize)578 void CameraBufferRead(unsigned long ulBase, unsigned long *pBuffer,
579                    unsigned char ucSize)
580 {
581   unsigned char *pCamBuff;
582   unsigned char i;
583 
584   //
585   // Initilize a pointer to ecamera buffer
586   //
587   pCamBuff = (unsigned char *)CAM_BUFFER_ADDR;
588 
589   //
590   // Read out requested data
591   //
592   for(i=0; i < ucSize; i++)
593   {
594     *(pBuffer+i) = *(pCamBuff + i);
595   }
596 }
597 
598 //*****************************************************************************
599 //
600 // Close the Doxygen group.
601 //! @}
602 //
603 //*****************************************************************************
604