SAMV71 Xplained Ultra Software Package 1.3

isi.c

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