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