SAMV71 Xplained Ultra Software Package 1.4

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     uint32_t val;
00213     val = _ISI_GetCFG2_Workaround();
00214     val &= (~ISI_CFG2_IM_VSIZE_Msk);
00215     val &= (~ISI_CFG2_IM_HSIZE_Msk);
00216     // IM_VSIZE: Vertical size of the Image sensor [0..2047]
00217     // Vertical size = IM_VSIZE + 1
00218     // IM_HSIZE: Horizontal size of the Image sensor [0..2047]
00219     // Horizontal size = IM_HSIZE + 1
00220     ISI->ISI_CFG2 &= (~ISI_CFG2_IM_VSIZE_Msk);
00221     ISI->ISI_CFG2 &= (~ISI_CFG2_IM_HSIZE_Msk);
00222     ISI->ISI_CFG2 = val | ISI_CFG2_IM_VSIZE(vSize - 1) | ISI_CFG2_IM_HSIZE(hSize - 1);
00223 }
00224 
00225 /**
00226  * \brief Defines RGB pattern when RGB_MODE is set to 1.
00227  * \param wRgbPixelMapping  RGB pattern
00228  */
00229 void ISI_RgbPixelMapping(uint32_t wRgbPixelMapping)
00230 {
00231     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_CFG_Msk);
00232     if (wRgbPixelMapping != ISI_CFG2_RGB_CFG_DEFAULT)
00233         ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wRgbPixelMapping 
00234             | ISI_CFG2_RGB_MODE; 
00235     else 
00236         ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround();
00237 }
00238 
00239 /**
00240  * \brief Enables RGB swap
00241  * \param swapMode  0: D7-R7, 1: D0-R7
00242  */
00243 void ISI_RgbSwapMode(uint32_t swapMode)
00244 {
00245     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_RGB_SWAP);
00246     if(swapMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_RGB_SWAP;
00247 }
00248  
00249 /**
00250  * \brief Defines YCrCb swap format.
00251  * \param wYuvSwapMode YUV Swap format
00252  */
00253 void ISI_YCrCbFormat(uint32_t wYuvSwapMode)
00254 {
00255     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_YCC_SWAP_Msk);
00256     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | wYuvSwapMode;
00257 }
00258 
00259 /**
00260  * \brief Input image is assumed to be grayscale-coded.
00261  * \param wPixelFormat  0: 2 pixels per word, 1:1 pixel per word.
00262  */
00263 void ISI_setGrayScaleMode(uint32_t wPixelFormat)
00264 {
00265     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GRAYSCALE ;
00266     if(wPixelFormat) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_GS_MODE;
00267     
00268 }
00269 
00270 /**
00271  * \brief Set data stream format.
00272  * \param wStreamMode  0: YUV input, 1: RGB 8:8:8/5:6:5 input
00273  */
00274 void ISI_setInputStream(uint32_t wStreamMode)
00275 {
00276     ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() & (~ISI_CFG2_COL_SPACE);
00277     if(wStreamMode) ISI->ISI_CFG2 = _ISI_GetCFG2_Workaround() | ISI_CFG2_COL_SPACE;
00278 }
00279 
00280 /**
00281  * \brief Set preview size.
00282  * \param hSize  Horizontal Preview size  (640 max only in RGB mode).
00283  * \param vSize  Vertical Preview size  (480 max only in RGB mode).
00284  */
00285 void ISI_setPreviewSize(uint32_t hSize, uint32_t vSize)
00286 {
00287     if (hSize > 640) hSize = 640;
00288     if (vSize > 480) vSize = 480;
00289     ISI->ISI_PSIZE = ISI_PSIZE_PREV_VSIZE(vSize - 1) | ISI_PSIZE_PREV_HSIZE(hSize - 1);
00290 }
00291 
00292 /**
00293  * \brief calculate scaler factor automatically.
00294  * \note The sensor size and preview size for LCD was configured before this setting.
00295  */
00296 void ISI_calcScalerFactor(void)
00297 {
00298     uint32_t hLcdSize, hSensorSize;
00299     uint32_t hRatio;
00300     hLcdSize = ((ISI->ISI_PSIZE & ISI_PSIZE_PREV_HSIZE_Msk) >> ISI_PSIZE_PREV_HSIZE_Pos) +1 ;
00301     hSensorSize = ((_ISI_GetCFG2_Workaround() & ISI_CFG2_IM_HSIZE_Msk ) 
00302             >> ISI_CFG2_IM_HSIZE_Pos) + 1;
00303     hRatio = 1600 * hSensorSize / hLcdSize;
00304     ISI->ISI_PDECF = (hRatio/100);
00305 }
00306 
00307 /**
00308  * \brief Configure DMA for preview path.
00309  * \param baseFrameBufDesc  Preview Descriptor Address.
00310  * \param dmaCtrl  DMA Preview Control.
00311  * \param frameBufferStartAddr  DMA Preview Base Address.
00312  */
00313 void ISI_setDmaInPreviewPath(uint32_t baseFrameBufDesc, 
00314         uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
00315 {
00316     ISI->ISI_DMA_P_DSCR = baseFrameBufDesc;
00317     ISI->ISI_DMA_P_CTRL = dmaCtrl;
00318     ISI->ISI_DMA_P_ADDR = frameBufferStartAddr;
00319 }
00320 
00321 /**
00322  * \brief Configure DMA for Codec path.
00323  * \param baseFrameBufDesc  Preview Descriptor Address.
00324  * \param dmaCtrl  DMA Preview Control.
00325  * \param frameBufferStartAddr  DMA Preview Base Address.
00326  */
00327 void ISI_setDmaInCodecPath(uint32_t baseFrameBufDesc, 
00328         uint32_t dmaCtrl, uint32_t frameBufferStartAddr)
00329 {
00330     ISI->ISI_DMA_C_DSCR = baseFrameBufDesc;
00331     ISI->ISI_DMA_C_CTRL = dmaCtrl;
00332     ISI->ISI_DMA_C_ADDR = frameBufferStartAddr;
00333 }
00334  
00335 /**
00336  * \brief ISI set matrix for YUV to RGB color space for preview path.
00337  * \param yuv2rgb structure of YUV to RBG parameters.
00338  */
00339 void ISI_SetMatrix4Yuv2Rgb (ISI_Y2R* yuv2rgb)
00340 {
00341    ISI->ISI_Y2R_SET0 = ISI_Y2R_SET0_C0(yuv2rgb->C0)
00342                      | ISI_Y2R_SET0_C1(yuv2rgb->C1)
00343                      | ISI_Y2R_SET0_C2(yuv2rgb->C2)
00344                      | ISI_Y2R_SET0_C3(yuv2rgb->C3);
00345                      
00346    ISI->ISI_Y2R_SET1 = ISI_Y2R_SET1_C4(yuv2rgb->C4)
00347                      | ((yuv2rgb->Yoff == 1)? ISI_Y2R_SET1_Yoff: 0)
00348                      | ((yuv2rgb->Croff == 1)? ISI_Y2R_SET1_Croff: 0)
00349                      | ((yuv2rgb->Cboff == 1)? ISI_Y2R_SET1_Cboff: 0);
00350 }
00351 
00352 /**
00353  * \brief ISI set matrix for RGB to YUV color space for codec path.
00354  * \param rgb2yuv structure of RGB to YUV parameters.
00355  */
00356 void ISI_SetMatrix4Rgb2Yuv (ISI_R2Y* rgb2yuv)
00357 {
00358     ISI->ISI_R2Y_SET0 = ISI_R2Y_SET0_C0(rgb2yuv->C0) 
00359                       | ISI_R2Y_SET0_C1(rgb2yuv->C1)
00360                       | ISI_R2Y_SET0_C2(rgb2yuv->C2)
00361                       | ((rgb2yuv->Roff == 1)? ISI_R2Y_SET0_Roff: 0);
00362                  
00363     ISI->ISI_R2Y_SET1 = ISI_R2Y_SET1_C3(rgb2yuv->C3) 
00364                       | ISI_R2Y_SET1_C4(rgb2yuv->C4)
00365                       | ISI_R2Y_SET1_C5(rgb2yuv->C5)
00366                       | ((rgb2yuv->Goff == 1)? ISI_R2Y_SET1_Goff: 0);
00367                  
00368     ISI->ISI_R2Y_SET2 = ISI_R2Y_SET2_C6(rgb2yuv->C6) 
00369                       | ISI_R2Y_SET2_C7(rgb2yuv->C7)
00370                       | ISI_R2Y_SET2_C8(rgb2yuv->C8)
00371                       | ((rgb2yuv->Boff == 1)? ISI_R2Y_SET2_Boff: 0);
00372 }
00373 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines