SAMV71 Xplained Ultra Software Package 1.5

isi.c

00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /*----------------------------------------------------------------------------
00031  *        Headers
00032  *----------------------------------------------------------------------------*/
00033 
00034 #include "chip.h"
00035 
00036 /*----------------------------------------------------------------------------
00037  *        Local functions
00038  *----------------------------------------------------------------------------*/
00039 
00040 /**
00041  * \brief Workaround for ISI CFG2 register read.
00042  * \note The ISI_CFG2[31:27] can be written correctly, because the input writing
00043  * data are assigned directly to the internal control bits as specified,
00044  * the mismatch only happens in reading operation.
00045  * [31:28] are shift right 1 bit, so [31:27] can be read from [30:27].
00046  */
00047 __STATIC_INLINE uint32_t _ISI_GetCFG2_Workaround(void)
00048 {
00049     uint32_t wrongfield;
00050     wrongfield = ISI->ISI_CFG2 >> (ISI_CFG2_YCC_SWAP_Pos - 1);
00051     return (ISI->ISI_CFG2 & 0x07FFFFFF) | (wrongfield << ISI_CFG2_YCC_SWAP_Pos);
00052 }
00053 
00054 /*----------------------------------------------------------------------------
00055  *        Export functions
00056  *----------------------------------------------------------------------------*/
00057 
00058 /**
00059  * \brief Enable ISI
00060  */
00061 void ISI_Enable(void)
00062 {
00063     ISI->ISI_CR |= ISI_CR_ISI_EN;
00064 
00065     while ((ISI->ISI_SR & ISI_CR_ISI_EN) != ISI_CR_ISI_EN);
00066 }
00067 
00068 /**
00069  * \brief Enable ISI Dma channel
00070  * \param  channel to be enabled
00071  */
00072 void ISI_DmaChannelEnable(uint32_t channel)
00073 {
00074     ISI->ISI_DMA_CHER |= channel;
00075 }
00076 
00077 /**
00078  * \brief Disable ISI Dma channel
00079  * \param  channel to be disabled
00080  */
00081 void ISI_DmaChannelDisable(uint32_t channel)
00082 {
00083     ISI->ISI_DMA_CHDR |= channel;
00084 }
00085 
00086 /**
00087  * \brief Disable ISI
00088  */
00089 void ISI_Disable(void)
00090 {
00091     /* Write one to this field to disable the module */
00092     ISI->ISI_CR |= ISI_CR_ISI_DIS;
00093 
00094     /* Software must poll DIS_DONE field in the ISI_STATUS register to verify that the command
00095     has successfully completed.*/
00096     while ((ISI->ISI_SR & ISI_SR_DIS_DONE) != ISI_SR_DIS_DONE);
00097 }
00098 
00099 
00100 /**
00101  * \brief Enable ISI interrupt
00102  * \param  flag of interrupt to enable
00103  */
00104 void ISI_EnableInterrupt(uint32_t flag)
00105 {
00106     ISI->ISI_IER = flag;
00107 }
00108 
00109 /**
00110  * \brief Disable ISI interrupt
00111  * \param  flag of interrupt to disable
00112  */
00113 void ISI_DisableInterrupt(uint32_t flag)
00114 {
00115     ISI->ISI_IDR = flag;
00116 }
00117 
00118 /**
00119  * \brief Return ISI status register
00120  * \return Status of ISI register
00121  */
00122 uint32_t ISI_StatusRegister(void)
00123 {
00124     return (ISI->ISI_SR);
00125 }
00126 
00127 /**
00128  * \brief Enable Codec path for capture next frame
00129  */
00130 void ISI_CodecPathFull(void)
00131 {
00132     // The codec path is enabled and the next frame is captured.
00133     // Both codec and preview data-paths are working simultaneously
00134     ISI->ISI_CR |= ISI_CR_ISI_CDC;
00135     ISI->ISI_CFG1 |= ISI_CFG1_FULL;
00136 }
00137 
00138 /**
00139  * \brief Set frame rate
00140  * \param frame frame rate capture
00141  */
00142 void ISI_SetFrameRate(uint32_t frame)
00143 {
00144     if (frame > 7) {
00145         TRACE_ERROR("rate too big\n\r");
00146         frame = 7;
00147     }
00148 
00149     ISI->ISI_CFG1 |= ISI_CFG1_FRATE(frame);
00150 }
00151 
00152 /**
00153  * \brief Get the number of byte per pixels
00154  * \param bmpRgb BMP type can be YUV or RGB
00155  */
00156 uint8_t ISI_BytesForOnePixel(uint8_t bmpRgb)
00157 {
00158     uint8_t nbByte_Pixel;
00159 
00160     if (bmpRgb == RGB) {
00161         if ((_ISI_GetCFG2_Workaround() & ISI_CFG2_RGB_MODE) == ISI_CFG2_RGB_MODE) {
00162             // RGB: 5:6:5 16bits/pixels
00163             nbByte_Pixel = 2;
00164         } else {
00165             // RGB: 8:8:8 24bits/pixels
00166             nbByte_Pixel = 3;
00167         }
00168     } else {
00169         // YUV: 2 pixels for 4 bytes
00170         nbByte_Pixel = 2;
00171     }
00172 
00173     return nbByte_Pixel;
00174 }
00175 
00176 /**
00177  * \brief Reset ISI
00178  */
00179 void ISI_Reset(void)
00180 {
00181     uint32_t timeout = 0;
00182 
00183     // Resets the image sensor interface.
00184     // Finish capturing the current frame and then shut down the module.
00185     ISI->ISI_CR = ISI_CR_ISI_SRST | ISI_CR_ISI_DIS;
00186 
00187     // wait Software reset has completed successfully.
00188     while ((!(ISI->ISI_SR & ISI_SR_SRST))
00189             && (timeout < 0x5000))
00190         timeout++;
00191 
00192     if (timeout == 0x5000)
00193         TRACE_ERROR("ISI-Reset timeout\n\r");
00194 }
00195 
00196 
00197 /**
00198  * \brief Set the windows blank
00199  * \param hBlank  pixel clock periods to wait before the beginning of a line.
00200  * \param vBlank  lines are skipped at the beginning of the frame.
00201  */
00202 void ISI_SetBlank(uint8_t hBlank, uint8_t vBlank)
00203 {
00204     ISI->ISI_CFG1 |= ISI_CFG1_SLD(hBlank) + ISI_CFG1_SFD(vBlank);
00205 }
00206 
00207 
00208 /**
00209  * \brief Set vertical and horizontal Size of the Image Sensor
00210  * \param hSize  Horizontal size of the Image sensor [0..2047].
00211  * \param vSize  Vertical size of the Image sensor [0..2047].
00212  */
00213 void ISI_SetSensorSize(uint32_t hSize, uint32_t vSize)
00214 {
00215     uint32_t val;
00216     val = _ISI_GetCFG2_Workaround();
00217     val &= (~ISI_CFG2_IM_VSIZE_Msk);
00218     val &= (~ISI_CFG2_IM_HSIZE_Msk);
00219     // IM_VSIZE: Vertical size of the Image sensor [0..2047]
00220     // Vertical size = IM_VSIZE + 1
00221     // IM_HSIZE: Horizontal size of the Image sensor [0..2047]
00222     // Horizontal size = IM_HSIZE + 1
00223     ISI->ISI_CFG2 &= (~ISI_CFG2_IM_VSIZE_Msk);
00224     ISI->ISI_CFG2 &= (~ISI_CFG2_IM_HSIZE_Msk);
00225     ISI->ISI_CFG2 = val | ISI_CFG2_IM_VSIZE(vSize - 1) | ISI_CFG2_IM_HSIZE(
00226                         hSize - 1);
00227 }
00228 
00229 /**
00230  * \brief Defines RGB pattern when RGB_MODE is set to 1.
00231  * \param wRgbPixelMapping  RGB pattern
00232  */
00233 void ISI_RgbPixelMapping(uint32_t wRgbPixelMapping)
00234 {
00235     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_CFG_Msk);
00236 
00237     if (wRgbPixelMapping != ISI_CFG2_RGB_CFG_DEFAULT)
00238         ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wRgbPixelMapping
00239                         | ISI_CFG2_RGB_MODE;
00240     else
00241         ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround();
00242 }
00243 
00244 /**
00245  * \brief Enables RGB swap
00246  * \param swapMode  0: D7-R7, 1: D0-R7
00247  */
00248 void ISI_RgbSwapMode(uint32_t swapMode)
00249 {
00250     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_SWAP);
00251 
00252     if (swapMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_RGB_SWAP;
00253 }
00254 
00255 /**
00256  * \brief Defines YCrCb swap format.
00257  * \param wYuvSwapMode YUV Swap format
00258  */
00259 void ISI_YCrCbFormat(uint32_t wYuvSwapMode)
00260 {
00261     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_YCC_SWAP_Msk);
00262     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wYuvSwapMode;
00263 }
00264 
00265 /**
00266  * \brief Input image is assumed to be grayscale-coded.
00267  * \param wPixelFormat  0: 2 pixels per word, 1:1 pixel per word.
00268  */
00269 void ISI_setGrayScaleMode(uint32_t wPixelFormat)
00270 {
00271     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GRAYSCALE;
00272 
00273     if (wPixelFormat) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GS_MODE;
00274 
00275 }
00276 
00277 /**
00278  * \brief Set data stream format.
00279  * \param wStreamMode  0: YUV input, 1: RGB 8:8:8/5:6:5 input
00280  */
00281 void ISI_setInputStream(uint32_t wStreamMode)
00282 {
00283     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_COL_SPACE);
00284 
00285     if (wStreamMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_COL_SPACE;
00286 }
00287 
00288 /**
00289  * \brief Set preview size.
00290  * \param hSize  Horizontal Preview size  (640 max only in RGB mode).
00291  * \param vSize  Vertical Preview size  (480 max only in RGB mode).
00292  */
00293 void ISI_setPreviewSize(uint32_t hSize, uint32_t vSize)
00294 {
00295     if (hSize > 640) hSize = 640;
00296 
00297     if (vSize > 480) vSize = 480;
00298 
00299     ISI->ISI_PSIZE = ISI_PSIZE_PREV_VSIZE(vSize - 1) | ISI_PSIZE_PREV_HSIZE(
00300                          hSize - 1);
00301 }
00302 
00303 /**
00304  * \brief calculate scaler factor automatically.
00305  * \note The sensor size and preview size for LCD was configured before this setting.
00306  */
00307 void ISI_calcScalerFactor(void)
00308 {
00309     uint32_t hLcdSize, hSensorSize;
00310     uint32_t hRatio;
00311     hLcdSize = ((ISI->ISI_PSIZE & ISI_PSIZE_PREV_HSIZE_Msk) >>
00312                 ISI_PSIZE_PREV_HSIZE_Pos) + 1;
00313     hSensorSize = ((_ISI_GetCFG2_Workaround() & ISI_CFG2_IM_HSIZE_Msk)
00314                    >> ISI_CFG2_IM_HSIZE_Pos) + 1;
00315     hRatio = 1600 * hSensorSize / hLcdSize;
00316     ISI->ISI_PDECF = (hRatio / 100);
00317 }
00318 
00319 /**
00320  * \brief Configure DMA for preview path.
00321  * \param baseFrameBufDesc  Preview Descriptor Address.
00322  * \param dmaCtrl  DMA Preview Control.
00323  * \param frameBufferStartAddr  DMA Preview Base Address.
00324  */
00325 void ISI_setDmaInPreviewPath(uint32_t baseFrameBufDesc,
00326                              uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
00327 {
00328     ISI->ISI_DMA_P_DSCR = baseFrameBufDesc;
00329     ISI->ISI_DMA_P_CTRL = dmaCtrl;
00330     ISI->ISI_DMA_P_ADDR = frameBufferStartAddr;
00331 }
00332 
00333 /**
00334  * \brief Configure DMA for Codec path.
00335  * \param baseFrameBufDesc  Preview Descriptor Address.
00336  * \param dmaCtrl  DMA Preview Control.
00337  * \param frameBufferStartAddr  DMA Preview Base Address.
00338  */
00339 void ISI_setDmaInCodecPath(uint32_t baseFrameBufDesc,
00340                            uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
00341 {
00342     ISI->ISI_DMA_C_DSCR = baseFrameBufDesc;
00343     ISI->ISI_DMA_C_CTRL = dmaCtrl;
00344     ISI->ISI_DMA_C_ADDR = frameBufferStartAddr;
00345 }
00346 
00347 /**
00348  * \brief ISI set matrix for YUV to RGB color space for preview path.
00349  * \param yuv2rgb structure of YUV to RBG parameters.
00350  */
00351 void ISI_SetMatrix4Yuv2Rgb (ISI_Y2R *yuv2rgb)
00352 {
00353     ISI->ISI_Y2R_SET0 = ISI_Y2R_SET0_C0(yuv2rgb->C0)
00354                         | ISI_Y2R_SET0_C1(yuv2rgb->C1)
00355                         | ISI_Y2R_SET0_C2(yuv2rgb->C2)
00356                         | ISI_Y2R_SET0_C3(yuv2rgb->C3);
00357 
00358     ISI->ISI_Y2R_SET1 = ISI_Y2R_SET1_C4(yuv2rgb->C4)
00359                         | ((yuv2rgb->Yoff == 1) ? ISI_Y2R_SET1_Yoff : 0)
00360                         | ((yuv2rgb->Croff == 1) ? ISI_Y2R_SET1_Croff : 0)
00361                         | ((yuv2rgb->Cboff == 1) ? ISI_Y2R_SET1_Cboff : 0);
00362 }
00363 
00364 /**
00365  * \brief ISI set matrix for RGB to YUV color space for codec path.
00366  * \param rgb2yuv structure of RGB to YUV parameters.
00367  */
00368 void ISI_SetMatrix4Rgb2Yuv (ISI_R2Y *rgb2yuv)
00369 {
00370     ISI->ISI_R2Y_SET0 = ISI_R2Y_SET0_C0(rgb2yuv->C0)
00371                         | ISI_R2Y_SET0_C1(rgb2yuv->C1)
00372                         | ISI_R2Y_SET0_C2(rgb2yuv->C2)
00373                         | ((rgb2yuv->Roff == 1) ? ISI_R2Y_SET0_Roff : 0);
00374 
00375     ISI->ISI_R2Y_SET1 = ISI_R2Y_SET1_C3(rgb2yuv->C3)
00376                         | ISI_R2Y_SET1_C4(rgb2yuv->C4)
00377                         | ISI_R2Y_SET1_C5(rgb2yuv->C5)
00378                         | ((rgb2yuv->Goff == 1) ? ISI_R2Y_SET1_Goff : 0);
00379 
00380     ISI->ISI_R2Y_SET2 = ISI_R2Y_SET2_C6(rgb2yuv->C6)
00381                         | ISI_R2Y_SET2_C7(rgb2yuv->C7)
00382                         | ISI_R2Y_SET2_C8(rgb2yuv->C8)
00383                         | ((rgb2yuv->Boff == 1) ? ISI_R2Y_SET2_Boff : 0);
00384 }
00385 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines