- Main Page
- Data Structures
- Files

# lcdc_moving_bitmap_example.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00032 /* Copyright (C) 2006-2008, Atmel Corporation All rights reserved.
    00033  *
    00034  * Redistribution and use in source and binary forms, with or without
    00035  * modification, are permitted provided that the following conditions are met =
    00036  *
    00037  * 1. Redistributions of source code must retain the above copyright notice,
    00038  * this list of conditions and the following disclaimer.
    00039  *
    00040  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00041  * this list of conditions and the following disclaimer in the documentation
    00042  * and/or other materials provided with the distribution.
    00043  *
    00044  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00045  * from this software without specific prior written permission.
    00046  *
    00047  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00048  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00049  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
    00050  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00051  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00052  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00053  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00054  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00055  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00056  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00057  */
    00058
    00111 #include <string.h>
    00112 #include "usart.h"
    00113 #include "gpio.h"
    00114 #include "spi_at32ap7000.h"
    00115 #include "lcdc.h"
    00116 #include "board.h"
    00117 #include "ltv350qv.h"
    00118 #include "bmp_lib.h"
    00119 #include "print_funcs.h"
    00120 #include "pm_at32ap7000.h"
    00121 #include "sdramc_at32ap7000.h"
    00122
    00123 extern void usdelay(unsigned long usec);
    00124
    00125 int increment_frame_base(lcdc_conf_t *lcdc_conf, int pixel, int line);
    00126 void lcd_pio_config(void);
    00127 void init_spiMaster(volatile avr32_spi_t * spi, long cpuHz);
    00128
    00129 #define SWITCHES_MASK 0x000000FF
    00130 #define SWITCH0 0x00000001
    00131 #define SWITCH1 0x00000002
    00132 #define SWITCH2 0x00000004
    00133 #define SWITCH3 0x00000008
    00134
    00136 #define BITMAP_FILE_ADDRESS 0x00400000
    00137
    00139 static lcdc_conf_t ltv350qv_conf = {
    00140   .dmabaddr1 = 0x10000000,
    00141   .dmabaddr2 = 0,
    00142   .burst_length = 4,
    00143   .xres = 320,
    00144   .yres = 240,
    00145   .set2dmode = LCDC_MODE_2D_ON,
    00146   .virtual_xres = 640,
    00147   .virtual_yres = 480,
    00148   .frame_rate = 75,
    00149   .lcdcclock = 40000000,
    00150   .guard_time = 2,
    00151   .memor = LCDC_BIG_ENDIAN,
    00152   .ifwidth = 0,
    00153   .scanmod = LCDC_SINGLE_SCAN,
    00154   .distype = LCDC_TFT,
    00155   .invvd = LCDC_NORMAL,
    00156   .invframe = LCDC_INVERTED,
    00157   .invline = LCDC_INVERTED,
    00158   .invclk = LCDC_INVERTED,
    00159   .invdval = LCDC_INVERTED,
    00160   .clkmod = LCDC_ALWAYS_ACTIVE,
    00161   .pixelsize = LCDC_BPP_32,
    00162   .ctrstval = 0x0f,
    00163   .ctrst_ena = LCDC_ENABLED,
    00164   .ctrst_pol = LCDC_NORMAL,
    00165   .ctrst_ps = LCDC_PRE_HALF,
    00166   .mval = 0,
    00167   .mmode = LCDC_EACH_FRAME,
    00168   .hpw = 16,
    00169   .hbp = 15,
    00170   .hfp = 33,
    00171   .vpw = 1,
    00172   .vbp = 10,
    00173   .vfp = 10,
    00174   .vhdly = 0,
    00175 };
    00176
    00182 void init_spiMaster(volatile avr32_spi_t * spi, long cpuHz)
    00183 {
    00184   gpio_map_t spi_piomap = {          \
    00185     {AVR32_SPI0_SCK_0_PIN, AVR32_SPI0_SCK_0_FUNCTION},  \
    00186     {AVR32_SPI0_MISO_0_PIN, AVR32_SPI0_MISO_0_FUNCTION},  \
    00187     {AVR32_SPI0_MOSI_0_PIN, AVR32_SPI0_MOSI_0_FUNCTION},  \
    00188     {AVR32_SPI0_NPCS_0_PIN, AVR32_SPI0_NPCS_0_FUNCTION},  \
    00189     {AVR32_SPI0_NPCS_1_PIN, AVR32_SPI0_NPCS_1_FUNCTION},  \
    00190     {AVR32_SPI0_NPCS_2_PIN, AVR32_SPI0_NPCS_2_FUNCTION},  \
    00191     {AVR32_SPI0_NPCS_3_PIN, AVR32_SPI0_NPCS_3_FUNCTION},  \
    00192   };
    00193   gpio_enable_module(spi_piomap, 7);
    00194
    00195   spi_options_t spiOptions = {
    00196     .reg = 1,
    00197     .baudrate = 1500000,
    00198     .bits = 8,
    00199     .spck_delay = 0,
    00200     .trans_delay = 0,
    00201     .stay_act = 1,
    00202     .spi_mode = 3,
    00203     .modfdis = 0,
    00204   };
    00205
    00206   /* Initialize as master */
    00207   spi_initMaster(spi, &spiOptions);
    00208
    00209   /* Set master mode; variable_ps, pcs_decode, delay */
    00210   spi_selectionMode(spi, 0, 0, 0);
    00211   /* Select slave chip 1 (SPI_NPCS1) */
    00212   spi_selectChip(spi, 1);
    00213   spi_setupChipReg(spi, &spiOptions, cpuHz);
    00214   spi_enable(spi);
    00215 }
    00216
    00220 void lcd_pio_config(void){
    00221     gpio_map_t piomap = {
    00222       { AVR32_LCDC_CC_0_0_PIN, AVR32_LCDC_CC_0_0_FUNCTION },
    00223       { AVR32_LCDC_DVAL_0_0_PIN, AVR32_LCDC_DVAL_0_0_FUNCTION },
    00224       { AVR32_LCDC_HSYNC_0_PIN, AVR32_LCDC_HSYNC_0_FUNCTION },
    00225       { AVR32_LCDC_MODE_0_0_PIN, AVR32_LCDC_MODE_0_0_FUNCTION },
    00226       { AVR32_LCDC_PCLK_0_PIN, AVR32_LCDC_PCLK_0_FUNCTION },
    00227       { AVR32_LCDC_PWR_0_PIN, AVR32_LCDC_PWR_0_FUNCTION },
    00228       { AVR32_LCDC_VSYNC_0_PIN, AVR32_LCDC_VSYNC_0_FUNCTION },
    00229       { AVR32_LCDC_DATA_0_0_PIN, AVR32_LCDC_DATA_0_0_FUNCTION },
    00230       { AVR32_LCDC_DATA_1_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00231       { AVR32_LCDC_DATA_2_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00232       { AVR32_LCDC_DATA_3_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00233       { AVR32_LCDC_DATA_4_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
    00234       { AVR32_LCDC_DATA_5_PIN, AVR32_LCDC_DATA_5_FUNCTION },
    00235       { AVR32_LCDC_DATA_6_PIN, AVR32_LCDC_DATA_6_FUNCTION },
    00236       { AVR32_LCDC_DATA_7_PIN, AVR32_LCDC_DATA_7_FUNCTION },
    00237       { AVR32_LCDC_DATA_8_0_PIN, AVR32_LCDC_DATA_8_0_FUNCTION },
    00238       { AVR32_LCDC_DATA_9_0_PIN, AVR32_LCDC_DATA_9_0_FUNCTION },
    00239       { AVR32_LCDC_DATA_10_0_PIN, AVR32_LCDC_DATA_10_0_FUNCTION },
    00240       { AVR32_LCDC_DATA_11_0_PIN, AVR32_LCDC_DATA_11_0_FUNCTION },
    00241       { AVR32_LCDC_DATA_12_0_PIN, AVR32_LCDC_DATA_12_0_FUNCTION },
    00242       { AVR32_LCDC_DATA_13_PIN, AVR32_LCDC_DATA_13_FUNCTION },
    00243       { AVR32_LCDC_DATA_14_PIN, AVR32_LCDC_DATA_14_FUNCTION },
    00244       { AVR32_LCDC_DATA_15_PIN, AVR32_LCDC_DATA_15_FUNCTION },
    00245       { AVR32_LCDC_DATA_16_0_PIN, AVR32_LCDC_DATA_16_0_FUNCTION },
    00246       { AVR32_LCDC_DATA_17_0_PIN, AVR32_LCDC_DATA_17_0_FUNCTION },
    00247       { AVR32_LCDC_DATA_18_0_PIN, AVR32_LCDC_DATA_18_0_FUNCTION },
    00248       { AVR32_LCDC_DATA_19_0_PIN, AVR32_LCDC_DATA_19_0_FUNCTION },
    00249       { AVR32_LCDC_DATA_20_0_PIN, AVR32_LCDC_DATA_20_0_FUNCTION },
    00250       { AVR32_LCDC_DATA_21_0_PIN, AVR32_LCDC_DATA_21_0_FUNCTION },
    00251       { AVR32_LCDC_DATA_22_PIN, AVR32_LCDC_DATA_22_FUNCTION },
    00252       { AVR32_LCDC_DATA_23_PIN, AVR32_LCDC_DATA_23_FUNCTION }
    00253
    00254   };
    00255   gpio_enable_module(piomap, 31);
    00256 }
    00257
    00258
    00270 int increment_frame_base(lcdc_conf_t *lcdc_conf, int pixel, int line){
    00271
    00272   volatile avr32_lcdc_t *plcdc = &AVR32_LCDC;
    00273   unsigned long base1;
    00274
    00275   /* increment frame pointer by lines */
    00276   base1 = plcdc->dmabaddr1 + lcdc_conf->virtual_xres * lcdc_conf->pixelsize / 8 * line;
    00277   /* increment frame pointer by pixel */
    00278   base1 += 4 * pixel;
    00279
    00280   /* do not allow to move the viewing area out of the virtual frame buffer */
    00281   if((base1 >= lcdc_conf->dmabaddr1 ) &&
    00282       base1 <= (lcdc_conf->dmabaddr1 + lcdc_conf->virtual_xres * lcdc_conf->pixelsize / 8 * (lcdc_conf->virtual_yres - lcdc_conf->yres) ))
    00283     plcdc->dmabaddr1 = base1;
    00284   else
    00285     return -1;
    00286
    00287   /* update DMA configuration DMAUPDT */
    00288   plcdc->dmacon |=  (1 << AVR32_LCDC_DMACON_DMAUPDT_OFFSET);
    00289   return 0;
    00290 }
    00291
    00299 int main (void)
    00300 {
    00301   volatile avr32_spi_t * spi = &AVR32_SPI0;
    00302   unsigned int input;
    00303   volatile avr32_pio_t *piob = &AVR32_PIOB;
    00304
    00305   // Reset PM. Makes sure we get the expected clocking after a soft reset (e.g.: JTAG reset)
    00306   pm_reset();
    00307
    00308   // Start PLL0 giving 80 MHz clock
    00309   pm_pll_opt_t pll_opt = {
    00310     .pll_id = 0,
    00311     .mul = 4,
    00312     .div = 1,
    00313     .osc_id = 0,
    00314     .count = 16,
    00315     .wait_for_lock = 1,
    00316   };
    00317   pm_start_pll(&pll_opt);
    00318
    00319   // Divide HSB by 2, PBB by 2 and PBA by 4 to keep them below maximum ratings
    00320   pm_set_clock_domain_scaler(PM_HSB_DOMAIN, 2);
    00321   pm_set_clock_domain_scaler(PM_PBB_DOMAIN, 2);
    00322   pm_set_clock_domain_scaler(PM_PBA_DOMAIN, 4);
    00323
    00324   pm_set_mclk_source(PM_PLL0);
    00325
    00326   /* Init debug serial line */
    00327   init_dbg_rs232(pm_read_module_freq_hz(PM_PBA_USART1));
    00328
    00329   print_dbg("\nCPU running at ");
    00330   print_dbg_ulong(pm_get_mclk_freq_hz()/1000000);
    00331   print_dbg(" MHz\n");
    00332
    00333   sdramc_init(pm_read_module_freq_hz(PM_PBB_HSDRAMC));
    00334
    00335   piob->per = SWITCHES_MASK;
    00336   piob->codr = SWITCHES_MASK;
    00337   lcd_pio_config();
    00338
    00339   print_dbg("Board init complete\n");
    00340
    00341   print_dbg("Setting up SPI for LTV350QV panel\n");
    00342   init_spiMaster(spi, pm_read_module_freq_hz(PM_PBA_SPI0));
    00343   print_dbg("Initializing LTV350QV panel\n");
    00344   ltv350qv_power_on(spi, 1);
    00345   print_dbg("Setting up LCD controller\n");
    00346
    00347   print_dbg("Enabling LCD controller\n");
    00348   /* Power manager setup
    00349   * Enable CLOCK for LCDC in HSBMASK
    00350   */
    00351   pm_enable_module(PM_HSB_LCDC);
    00352   /* Enable generic clock PLL0 for LCD controller pixel clock*/
    00353   pm_gen_clk_opt_t gen_clk_opt = {
    00354     .clock_source = PM_PLL0,
    00355     .divider = 2,
    00356   };
    00357   pm_start_generic_clock(7, &gen_clk_opt);
    00358
    00359   print_dbg("Initializing LCD controller\n");
    00360   lcdc_init(&ltv350qv_conf);
    00361
    00362   print_dbg("Clearing the frame buffer\n");
    00363   memset((void *)ltv350qv_conf.dmabaddr1, 0, ltv350qv_conf.virtual_xres * ltv350qv_conf.virtual_yres * ltv350qv_conf.pixelsize / 8);
    00364
    00365   print_dbg("Filling the frame buffer\n");
    00366   /* print the image into the virtual framebuffer */
    00367   display_virtual_bm(&ltv350qv_conf, ((void *) BITMAP_FILE_ADDRESS));
    00368
    00369   while(1){
    00370
    00371     usdelay(100000);
    00372     /* get input from the switches */
    00373     input = ~( piob->pdsr & SWITCHES_MASK);
    00374
    00375     if(input & SWITCH0){
    00376       increment_frame_base(&ltv350qv_conf, 10, 0);
    00377     }
    00378     if(input & SWITCH1){
    00379       increment_frame_base(&ltv350qv_conf, -10, 0);
    00380     }
    00381     if(input & SWITCH2){
    00382       increment_frame_base(&ltv350qv_conf, 0, -10);
    00383     }
    00384     if(input & SWITCH3){
    00385       increment_frame_base(&ltv350qv_conf, 0, 10);
    00386     }
    00387   }
    00388 }
    00389