]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_AT91SAM3U256_IAR/AT91Lib/peripherals/isi/isi2.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / CORTEX_AT91SAM3U256_IAR / AT91Lib / peripherals / isi / isi2.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2008, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 //------------------------------------------------------------------------------\r
31 //         Headers\r
32 //------------------------------------------------------------------------------\r
33 \r
34 #include <board.h>\r
35 #include <utility/trace.h>\r
36 #include <utility/video.h>\r
37 #include "isi.h"\r
38 \r
39 #if defined (BOARD_ISI_V200)\r
40 \r
41 //-----------------------------------------------------------------------------\r
42 /// Enable ISI\r
43 //-----------------------------------------------------------------------------\r
44 void ISI_Enable(void)\r
45 {\r
46     AT91C_BASE_ISI->ISI_CTRL |= AT91C_ISI_EN_1;\r
47     while( (AT91C_BASE_ISI->ISI_SR & AT91C_ISI_EN_1)!=AT91C_ISI_EN_1);\r
48     AT91C_BASE_ISI->ISI_DMACHER |= AT91C_ISI_P_CH_EN_1;\r
49 }\r
50 \r
51 //-----------------------------------------------------------------------------\r
52 /// Disable ISI\r
53 //-----------------------------------------------------------------------------\r
54 void ISI_Disable(void)\r
55 {\r
56     AT91C_BASE_ISI->ISI_CTRL |= AT91C_ISI_DIS_1;\r
57     AT91C_BASE_ISI->ISI_DMACHDR &= ~AT91C_ISI_P_CH_DIS_1;\r
58 }\r
59 \r
60 //-----------------------------------------------------------------------------\r
61 /// Enable ISI interrupt\r
62 /// \param  flag of interrupt to enable\r
63 //-----------------------------------------------------------------------------\r
64 void ISI_EnableInterrupt(unsigned int flag)\r
65 {\r
66     AT91C_BASE_ISI->ISI_IER = flag;\r
67 }\r
68 \r
69 //-----------------------------------------------------------------------------\r
70 /// Disable ISI interrupt\r
71 /// \param  flag of interrupt to disable\r
72 //-----------------------------------------------------------------------------\r
73 void ISI_DisableInterrupt(unsigned int flag)\r
74 {\r
75     AT91C_BASE_ISI->ISI_IDR = flag;\r
76 }\r
77 \r
78 //-----------------------------------------------------------------------------\r
79 /// Return ISI status register\r
80 /// \return Status of ISI register\r
81 //-----------------------------------------------------------------------------\r
82 unsigned int ISI_StatusRegister(void)\r
83 {\r
84     return(AT91C_BASE_ISI->ISI_SR);\r
85 }\r
86 \r
87 //-----------------------------------------------------------------------------\r
88 /// Enable Codec path for capture next frame\r
89 //-----------------------------------------------------------------------------\r
90 void ISI_CodecPathFull(void)\r
91 {\r
92     // The codec path is enabled and the next frame is captured.\r
93     // Both codec and preview datapaths are working simultaneously\r
94     AT91C_BASE_ISI->ISI_CTRL |= AT91C_ISI_CDC_1;\r
95     AT91C_BASE_ISI->ISI_CFG1 |= AT91C_ISI_FULL;\r
96 }\r
97 \r
98 //-----------------------------------------------------------------------------\r
99 /// Set frame rate\r
100 /// \param  frate frame rate capture\r
101 /// \return \r
102 //-----------------------------------------------------------------------------\r
103 void ISI_SetFrame(unsigned int frate)\r
104 {\r
105     if( frate > 7 ) {\r
106         TRACE_ERROR("FRate too big\n\r");\r
107         frate = 7;\r
108     }\r
109     AT91C_BASE_ISI->ISI_CFG1 |= ((frate<<8) & AT91C_ISI_FRATE);\r
110 }\r
111 \r
112 //-----------------------------------------------------------------------------\r
113 /// Get the number of byte per pixels\r
114 /// \param  bmpRgb BMP type can be YUV or RGB\r
115 /// \return Number of byte for one pixel\r
116 //-----------------------------------------------------------------------------\r
117 unsigned char ISI_BytesForOnePixel(unsigned char bmpRgb)\r
118 {\r
119     unsigned char nbByte_Pixel;\r
120 \r
121     if (bmpRgb == RGB) {\r
122         if ((AT91C_BASE_ISI->ISI_CFG2 & AT91C_ISI_RGB_MODE) == AT91C_ISI_RGB_MODE_RGB_565){\r
123             // RGB: 5:6:5 16bits/pixels\r
124             nbByte_Pixel = 2;\r
125         } \r
126         else {\r
127             // RGB: 8:8:8 24bits/pixels\r
128             nbByte_Pixel = 3;\r
129         }\r
130     } \r
131     else {\r
132         // YUV: 2 pixels for 4 bytes\r
133         nbByte_Pixel = 2;\r
134     }\r
135     return nbByte_Pixel;\r
136 }\r
137 \r
138 //-----------------------------------------------------------------------------\r
139 /// Reset ISI\r
140 //-----------------------------------------------------------------------------\r
141 void ISI_Reset(void)\r
142 {\r
143     unsigned int timeout=0;\r
144 \r
145     // Resets the image sensor interface.\r
146     // Finish capturing the current frame and then shut down the module.\r
147     AT91C_BASE_ISI->ISI_CTRL = AT91C_ISI_SRST_1 | AT91C_ISI_DIS_1;\r
148     // wait Software reset has completed successfully.\r
149     while( (!(volatile int)AT91C_BASE_ISI->ISI_SR & AT91C_ISI_SRST)\r
150         && (timeout < 0x5000) ){\r
151         timeout++;\r
152     }\r
153     if( timeout == 0x5000 ) {\r
154         TRACE_ERROR("ISI-Reset timeout\n\r");\r
155     }\r
156 }\r
157 \r
158 //-----------------------------------------------------------------------------\r
159 /// ISI initialize\r
160 /// \param pVideo structure of video driver\r
161 //-----------------------------------------------------------------------------\r
162 void ISI_Init(AT91PS_VIDEO pVideo)\r
163 {\r
164     ISI_Reset();\r
165 \r
166     // AT91C_ISI_HSYNC_POL    Horizontal synchronisation polarity\r
167     // AT91C_ISI_VSYNC_POL    Vertical synchronisation polarity\r
168     // AT91C_ISI_PIXCLK_POL   Pixel Clock Polarity\r
169 \r
170     // SLD pixel clock periods to wait before the beginning of a line.\r
171     // SFD lines are skipped at the beginning of the frame.\r
172     AT91C_BASE_ISI->ISI_CFG1 |= ((pVideo->Hblank << 16) & AT91C_ISI_SLD)\r
173                               + ((pVideo->Vblank << 24) & AT91C_ISI_SFD);\r
174     TRACE_DEBUG("ISI_CFG1=0x%X\n\r", AT91C_BASE_ISI->ISI_CFG1);\r
175 \r
176     // IM_VSIZE: Vertical size of the Image sensor [0..2047]\r
177     // Vertical size = IM_VSIZE + 1\r
178     // IM_HSIZE: Horizontal size of the Image sensor [0..2047]\r
179     // Horizontal size = IM_HSIZE + 1\r
180     // YCC_SWAP : YCC image data    \r
181     AT91C_BASE_ISI->ISI_CFG2 = ((pVideo->codec_vsize-1) & AT91C_ISI_IM_VSIZE)\r
182                             + (((pVideo->codec_hsize-1) << 16) & AT91C_ISI_IM_HSIZE)\r
183                             + AT91C_ISI_YCC_SWAP_YCC_MODE2;\r
184 \r
185     if (pVideo->rgb_or_yuv == RGB) {\r
186         AT91C_BASE_ISI->ISI_CFG2 |= AT91C_ISI_COL_SPACE | AT91C_ISI_RGB_MODE_RGB_565\r
187             | AT91C_ISI_RGB_CFG_RGB_DEFAULT;\r
188     }\r
189     else {\r
190     //    AT91C_BASE_HISI->ISI_CFG2 &=  ~AT91C_ISI_COL_SPACE;    \r
191     }\r
192     TRACE_DEBUG("ISI_CFG2=0x%X\n\r", AT91C_BASE_ISI->ISI_CFG2);\r
193 \r
194     // Vertical Preview size = PREV_VSIZE + 1 (480 max only in RGB mode).\r
195     // Horizontal Preview size = PREV_HSIZE + 1 (640 max only in RGB mode).    \r
196 #if defined (AT91C_ID_LCDC)\r
197     if( (pVideo->lcd_vsize > 480) || (pVideo->lcd_hsize > 640)) {\r
198         TRACE_ERROR("Size LCD bad define\n\r");\r
199         AT91C_BASE_ISI->ISI_PSIZE = ((BOARD_LCD_HEIGHT-1) & AT91C_ISI_PREV_VSIZE)\r
200                                   + (((BOARD_LCD_WIDTH-1) << 16) & AT91C_ISI_PREV_HSIZE);\r
201     }\r
202     else {\r
203 \r
204         AT91C_BASE_ISI->ISI_PSIZE = ((pVideo->lcd_vsize -1) & AT91C_ISI_PREV_VSIZE)\r
205                                   + (((pVideo->lcd_hsize -1) << 16) & AT91C_ISI_PREV_HSIZE);\r
206     }\r
207 #endif\r
208 \r
209 \r
210     // DEC_FACTOR is 8-bit width, range is from 16 to 255. \r
211     // Values from 0 to 16 do not perform any decimation.\r
212     AT91C_BASE_ISI->ISI_PDECF = (16 * pVideo->codec_hsize) / pVideo->lcd_hsize;\r
213 \r
214     TRACE_DEBUG("codec_hsize: %d\n\r", pVideo->codec_hsize);\r
215     TRACE_DEBUG("lcd_hsize: %d\n\r", pVideo->lcd_hsize);\r
216     TRACE_DEBUG("ISI_PDECF: %d\n\r", AT91C_BASE_ISI->ISI_PDECF);\r
217     if( AT91C_BASE_ISI->ISI_PDECF <16) {\r
218         TRACE_ERROR("ISI_PDECF, forbidden value: %d\n\r", AT91C_BASE_ISI->ISI_PDECF);\r
219         AT91C_BASE_ISI->ISI_PDECF = 16;\r
220     }\r
221 \r
222     AT91C_BASE_ISI->ISI_DMAPDSCR = pVideo->Isi_fbd_base;\r
223     AT91C_BASE_ISI->ISI_DMAPCTRL = AT91C_ISI_P_FETCH_ENABLE;\r
224     AT91C_BASE_ISI->ISI_DMAPADDR = pVideo->lcd_fb_addr;\r
225 \r
226     // C0: Color Space Conversion Matrix Coefficient C0\r
227     // C1: Color Space Conversion Matrix Coefficient C1\r
228     // C2: Color Space Conversion Matrix Coefficient C2\r
229     // C3: Color Space Conversion Matrix Coefficient C3\r
230     AT91C_BASE_ISI->ISI_Y2RSET0  = ( (0x95<< 0) & AT91C_ISI_Y2R_C0)\r
231                                  + ( (0xFF<< 8) & AT91C_ISI_Y2R_C1)\r
232                                  + ( (0x68<<16) & AT91C_ISI_Y2R_C2)\r
233                                  + ( (0x32<<24) & AT91C_ISI_Y2R_C3);\r
234 \r
235     // C4: Color Space Conversion Matrix coefficient C4\r
236     // Yoff: Color Space Conversion Luminance 128 offset\r
237     // Croff: Color Space Conversion Red Chrominance 16 offset\r
238     // Cboff: Color Space Conversion Blue Chrominance 16 offset\r
239     AT91C_BASE_ISI->ISI_Y2RSET1  = ( (0xCC<< 0) & AT91C_ISI_Y2R_C4)\r
240                                  + ( AT91C_ISI_Y2R_YOFF_128)\r
241                                  + ( AT91C_ISI_Y2R_CROFF_16)\r
242                                  + ( AT91C_ISI_Y2R_CBOFF_16);\r
243 }\r
244 \r
245 #endif // defined (BOARD_ISI_V200)\r
246 \r