- Main Page
- Data Structures
- Files

# lcdc_vga_example.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00030 /* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
    00031  *
    00032  * Redistribution and use in source and binary forms, with or without
    00033  * modification, are permitted provided that the following conditions are met=
    00034  *
    00035  * 1. Redistributions of source code must retain the above copyright notice,
    00036  * this list of conditions and the following disclaimer.
    00037  *
    00038  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00039  * this list of conditions and the following disclaimer in the documentation
    00040  * and/or other materials provided with the distribution.
    00041  *
    00042  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00043  * from this software without specific prior written permission.
    00044  *
    00045  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00046  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00047  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
    00048  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00049  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00050  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00051  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00052  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00053  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00054  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00055  */
    00056
    00102 #include "usart.h"
    00103 #include "gpio.h"
    00104 #include "board.h"
    00105 #include "lcdc.h"
    00106 #include <string.h>
    00107 #include <avr32/io.h>
    00108 #include "sdramc_at32ap7000.h"
    00109 #include "ap7_errno.h"
    00110 #include "print_funcs.h"
    00111 #include "pm_at32ap7000.h"
    00112 #include "bmp_lib.h"
    00113
    00114 /* The configurations available. Notation is
    00115  * {horizontal size}_{vertical size}_{refresh rate}
    00116  */
    00117 #define CONF_640_480_60    640
    00118 #define CONF_800_600_60    800
    00119 #define CONF_1024_768_60  1024
    00120 /* Select configuration */
    00121 #define VGA_CONFIGURATION CONF_800_600_60
    00122
    00123 /* Enable disable the display configurations here */
    00124
    00125 #define BITMAP_FILE_ADDRESS 0xA0400000
    00126
    00127 /* Refresh rate of SDRAM in number of bus clocks */
    00128 #define REFRESH_RATE 1170
    00129
    00130 volatile avr32_usart_t *usart = &AVR32_USART1;
    00131 int display_bm(lcdc_conf_t *lcdc_conf, void * file_start);
    00132
    00134 static lcdc_conf_t lcdc_vga_std_conf = {
    00135
    00136   .dmabaddr1= 0x10000000,
    00137   .dmabaddr2= 0,
    00138   .burst_length= 4,
    00139   .xres= 640,
    00140   .yres= 480,
    00141   .set2dmode= LCDC_MODE_2D_OFF,
    00142   .virtual_xres= 0,
    00143   .virtual_yres= 0,
    00144   .frame_rate= 60,
    00145   .lcdcclock= 25000000,
    00146   .guard_time= 2,
    00147   .memor= LCDC_BIG_ENDIAN,
    00148   .ifwidth= 0,
    00149   .scanmod= LCDC_SINGLE_SCAN,
    00150   .distype= LCDC_TFT,
    00151   .invvd= LCDC_NORMAL,
    00152   .invframe= LCDC_NORMAL,
    00153   .invline= LCDC_NORMAL,
    00154   .invclk= LCDC_INVERTED,
    00155   .invdval= LCDC_NORMAL,
    00156   .clkmod= LCDC_ALWAYS_ACTIVE,
    00157   .pixelsize= LCDC_BPP_24,
    00158   .ctrstval= 0x0f,
    00159   .ctrst_ena= LCDC_DISABLED,
    00160   .ctrst_pol= LCDC_NORMAL,
    00161   .ctrst_ps= LCDC_PRE_HALF,
    00162   .mval= 0,
    00163   .mmode= LCDC_EACH_FRAME,
    00164   .hpw= 64,/* Should be 96 but LCD Controller supports only up to 64 */
    00165   .hbp= 48,
    00166   .hfp= 16,
    00167   .vpw= 2,
    00168   .vbp= 33,
    00169   .vfp= 10,
    00170   .vhdly= 0,
    00171 };
    00173 static lcdc_conf_t lcdc_800_600_60_conf = {
    00174
    00175   .dmabaddr1= 0x10000000,
    00176   .dmabaddr2= 0,
    00177   .burst_length= 4,
    00178   .xres= 800,
    00179   .yres= 600,
    00180   .set2dmode= LCDC_MODE_2D_OFF,
    00181   .virtual_xres= 0,
    00182   .virtual_yres= 0,
    00183   .frame_rate= 60,
    00184   .lcdcclock= 40000000,
    00185   .guard_time= 2,
    00186   .memor= LCDC_BIG_ENDIAN,
    00187   .ifwidth= 0,
    00188   .scanmod= LCDC_SINGLE_SCAN,
    00189   .distype= LCDC_TFT,
    00190   .invvd= LCDC_NORMAL,
    00191   .invframe= LCDC_INVERTED,
    00192   .invline= LCDC_NORMAL,
    00193   .invclk= LCDC_INVERTED,
    00194   .invdval= LCDC_NORMAL,
    00195   .clkmod= LCDC_ALWAYS_ACTIVE,
    00196   .pixelsize= LCDC_BPP_24,
    00197   .ctrstval= 0x0f,
    00198   .ctrst_ena= LCDC_DISABLED,
    00199   .ctrst_pol= LCDC_NORMAL,
    00200   .ctrst_ps= LCDC_PRE_HALF,
    00201   .mval= 0,
    00202   .mmode= LCDC_EACH_FRAME,
    00203   .hpw= 64, /* should be 80 but LCD Controller supports only up to 64 */
    00204   .hbp= 126,
    00205   .hfp= 46,
    00206   .vpw= 4,
    00207   .vbp= 17,
    00208   .vfp= 3,
    00209   .vhdly= 0,
    00210 };
    00212 static lcdc_conf_t lcdc_1024_768_60_conf = {
    00213   .dmabaddr1= 0x10000000,
    00214   .dmabaddr2= 0,
    00215   .burst_length= 4,
    00216   .xres= 1024,
    00217   .yres= 768,
    00218   .set2dmode= LCDC_MODE_2D_OFF,
    00219   .virtual_xres= 0,
    00220   .virtual_yres= 0,
    00221   .frame_rate= 60,
    00222   .lcdcclock= 64000000,
    00223   .guard_time= 2,
    00224   .memor= LCDC_BIG_ENDIAN,
    00225   .ifwidth= 0,
    00226   .scanmod= LCDC_SINGLE_SCAN,
    00227   .distype= LCDC_TFT,
    00228   .invvd= LCDC_NORMAL,
    00229   .invframe= LCDC_INVERTED,
    00230   .invline= LCDC_NORMAL,
    00231   .invclk= LCDC_INVERTED,
    00232   .invdval= LCDC_NORMAL,
    00233   .clkmod= LCDC_ALWAYS_ACTIVE,
    00234   .pixelsize= LCDC_BPP_16,
    00235   .ctrstval= 0x0f,
    00236   .ctrst_ena= LCDC_DISABLED,
    00237   .ctrst_pol= LCDC_NORMAL,
    00238   .ctrst_ps= LCDC_PRE_HALF,
    00239   .mval= 0,
    00240   .mmode= LCDC_EACH_FRAME,
    00241   .hpw= 64, /* Should be 104 but LCD controller supports only up to 64 */
    00242   .hbp= 152,
    00243   .hfp= 48,
    00244   .vpw= 4,
    00245   .vbp= 23,
    00246   .vfp= 3,
    00247   .vhdly= 0,
    00248 };
    00249
    00253 void lcdc_pio_config(void){
    00254   /* CC and MOD signals are not used for the video DAC and are not connected to
    00255   * the monitor interface
    00256   */
    00257     static const gpio_map_t lcdc_pio_map = {
    00258       { AVR32_LCDC_DVAL_0_0_PIN, AVR32_LCDC_DVAL_0_0_FUNCTION },
    00259       { AVR32_LCDC_HSYNC_0_PIN, AVR32_LCDC_HSYNC_0_FUNCTION },
    00260       { AVR32_LCDC_PCLK_0_PIN, AVR32_LCDC_PCLK_0_FUNCTION },
    00261       { AVR32_LCDC_PWR_0_PIN, AVR32_LCDC_PWR_0_FUNCTION },
    00262       { AVR32_LCDC_VSYNC_0_PIN, AVR32_LCDC_VSYNC_0_FUNCTION },
    00263       { AVR32_LCDC_DATA_0_0_PIN, AVR32_LCDC_DATA_0_0_FUNCTION },
    00264       { AVR32_LCDC_DATA_1_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00265       { AVR32_LCDC_DATA_2_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00266       { AVR32_LCDC_DATA_3_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00267       { AVR32_LCDC_DATA_4_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00268       { AVR32_LCDC_DATA_5_PIN, AVR32_LCDC_DATA_5_FUNCTION },
    00269       { AVR32_LCDC_DATA_6_PIN, AVR32_LCDC_DATA_6_FUNCTION },
    00270       { AVR32_LCDC_DATA_7_PIN, AVR32_LCDC_DATA_7_FUNCTION },
    00271       { AVR32_LCDC_DATA_8_0_PIN, AVR32_LCDC_DATA_8_0_FUNCTION },
    00272       { AVR32_LCDC_DATA_9_0_PIN, AVR32_LCDC_DATA_9_0_FUNCTION },
    00273       { AVR32_LCDC_DATA_10_0_PIN, AVR32_LCDC_DATA_10_0_FUNCTION },
    00274       { AVR32_LCDC_DATA_11_0_PIN, AVR32_LCDC_DATA_11_0_FUNCTION },
    00275       { AVR32_LCDC_DATA_12_0_PIN, AVR32_LCDC_DATA_12_0_FUNCTION },
    00276       { AVR32_LCDC_DATA_13_PIN, AVR32_LCDC_DATA_13_FUNCTION },
    00277       { AVR32_LCDC_DATA_14_PIN, AVR32_LCDC_DATA_14_FUNCTION },
    00278       { AVR32_LCDC_DATA_15_PIN, AVR32_LCDC_DATA_15_FUNCTION },
    00279       { AVR32_LCDC_DATA_16_0_PIN, AVR32_LCDC_DATA_16_0_FUNCTION },
    00280       { AVR32_LCDC_DATA_17_0_PIN, AVR32_LCDC_DATA_17_0_FUNCTION },
    00281       { AVR32_LCDC_DATA_18_0_PIN, AVR32_LCDC_DATA_18_0_FUNCTION },
    00282       { AVR32_LCDC_DATA_19_0_PIN, AVR32_LCDC_DATA_19_0_FUNCTION },
    00283       { AVR32_LCDC_DATA_20_0_PIN, AVR32_LCDC_DATA_20_0_FUNCTION },
    00284       { AVR32_LCDC_DATA_21_0_PIN, AVR32_LCDC_DATA_21_0_FUNCTION },
    00285       { AVR32_LCDC_DATA_22_PIN, AVR32_LCDC_DATA_22_FUNCTION },
    00286       { AVR32_LCDC_DATA_23_PIN, AVR32_LCDC_DATA_23_FUNCTION }
    00287
    00288   };
    00289   gpio_enable_module(lcdc_pio_map, 31);
    00290 }
    00291
    00296 void fill_frame_buffer (lcdc_conf_t *lcdc_conf)
    00297 {
    00298   unsigned int k,l,x,y;
    00299   unsigned char * framePtr;
    00300
    00301   framePtr = (unsigned char *) (lcdc_conf->dmabaddr1 | 0xA0000000);
    00302
    00303   if(lcdc_conf->pixelsize == LCDC_BPP_24){
    00304   for (l=0; l < lcdc_conf->yres; l++){
    00305     for (k=0; k < lcdc_conf->xres; k++)
    00306     {
    00307       x = (256 * l) / lcdc_conf->yres;
    00308       y = (256 * k) / lcdc_conf->xres;
    00309       *framePtr++ = x;
    00310       *framePtr++ = y;
    00311       *framePtr++ = 256 - (x + y) / 2;
    00312     }
    00313   }
    00314   }
    00315   if(lcdc_conf->pixelsize == LCDC_BPP_16){
    00316     for (l=0; l < lcdc_conf->yres; l++){
    00317       for (k=0; k < lcdc_conf->xres; k++)
    00318       {
    00319         x = (32 * l) / lcdc_conf->yres;
    00320         y = (32 * k) / lcdc_conf->xres;
    00321         /* 1-5-5-5 format */
    00322         *framePtr++ = (x << 2) | (y >> 3);
    00323         *framePtr++ = (y << 5) | (32 - (x + y) / 2);
    00324       }
    00325     }
    00326   }
    00327 }
    00328
    00329 int main (void)
    00330 {
    00331   volatile struct avr32_smc_t *smc = &AVR32_SMC;
    00332   lcdc_conf_t *lcdc_conf;
    00333
    00334   // Reset PM. Makes sure we get the expected clocking after a soft reset (e.g.: JTAG reset)
    00335   pm_reset();
    00336
    00337   /* set up SMC for higher frequencies */
    00338   smc->cs[0].mode = 0x00031103;
    00339   smc->cs[0].cycle = 0x000c000d;
    00340   smc->cs[0].pulse = 0x0b0a0906;
    00341   smc->cs[0].setup = 0x00010002;
    00342
    00343   // Start PLL0 giving 150 MHz clock
    00344   pm_pll_opt_t pll_opt = {
    00345     .pll_id = 0,
    00346     .mul = 15,
    00347     .div = 2,
    00348     .osc_id = 0,
    00349     .count = 16,
    00350     .wait_for_lock = 1,
    00351   };
    00352   pm_start_pll(&pll_opt);
    00353
    00354   // Divide HSB by 2, PBB by 4 and PBA by 4 to keep them below maximum ratings
    00355   pm_set_clock_domain_scaler(PM_HSB_DOMAIN, 2);
    00356   pm_set_clock_domain_scaler(PM_PBB_DOMAIN, 4);
    00357   pm_set_clock_domain_scaler(PM_PBA_DOMAIN, 4);
    00358
    00359   pm_set_mclk_source(PM_PLL0);
    00360
    00361   /* Initialize default debug usart */
    00362   init_dbg_rs232(pm_read_module_freq_hz(PM_PBA_USART1));
    00363
    00364   sdramc_init(pm_read_module_freq_hz(PM_PBB_HSDRAMC));
    00365
    00366   switch (VGA_CONFIGURATION)
    00367   {
    00368   case CONF_640_480_60:
    00369       lcdc_conf = &lcdc_vga_std_conf;
    00370       /* 25MHz pixel clock */
    00371       pll_opt.mul = 25;
    00372       pll_opt.div = 12;
    00373       break;
    00374   case CONF_800_600_60:
    00375       lcdc_conf = &lcdc_800_600_60_conf;
    00376       /* 40 MHz pixel clock */
    00377       pll_opt.mul = 10;
    00378       pll_opt.div = 3;
    00379       break;
    00380   case CONF_1024_768_60:
    00381       lcdc_conf = &lcdc_1024_768_60_conf;
    00382       /* 63,5 MHz pixel clock */
    00383       pll_opt.mul = 37;
    00384       pll_opt.div = 7;
    00385       break;
    00386   default:
    00387       print_dbg("Invalid or missing VGA configuration\n");
    00388       break;
    00389   }
    00390
    00391   print_dbg( "Setting up PLL1 for LCD Controller\n");
    00392   print_dbg(" -> PLL1 ... ");
    00393   pll_opt.pll_id = 1;
    00394   pll_opt.osc_id = 1;
    00395   pll_opt.count = 16;
    00396   pm_start_pll(&pll_opt);
    00397   print_dbg("OK\n");
    00398
    00399   /* clear framebuffer */
    00400   memset((void *)lcdc_conf->dmabaddr1, 0, lcdc_conf->xres * lcdc_conf->yres * lcdc_conf->pixelsize / 8);
    00401
    00402   fill_frame_buffer(lcdc_conf);
    00403
    00404   display_bm(lcdc_conf, ((void *) BITMAP_FILE_ADDRESS));
    00405
    00406   print_dbg("Setting up LCD controller\n");
    00407   lcdc_pio_config();
    00408
    00409   /* Power manager setup
    00410   * Enable CLOCK for LCDC in HSBMASK
    00411   */
    00412   pm_enable_module(PM_HSB_LCDC);
    00413   /* Feed generic clock for LCD Controller from PLL1 */
    00414   pm_gen_clk_opt_t gen_clk_opt = {
    00415     .clock_source = PM_PLL1,
    00416     .divider = 0,
    00417   };
    00418   pm_start_generic_clock(7, &gen_clk_opt);
    00419
    00420   lcdc_init(lcdc_conf);
    00421   print_dbg("Setup complete\n");
    00422
    00423   while(1);
    00424 }