lcdc_vga_example.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00035 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00036  *
00037  * Redistribution and use in source and binary forms, with or without
00038  * modification, are permitted provided that the following conditions are met:
00039  *
00040  * 1. Redistributions of source code must retain the above copyright notice,
00041  * this list of conditions and the following disclaimer.
00042  *
00043  * 2. Redistributions in binary form must reproduce the above copyright notice,
00044  * this list of conditions and the following disclaimer in the documentation
00045  * and/or other materials provided with the distribution.
00046  *
00047  * 3. The name of ATMEL may not be used to endorse or promote products derived
00048  * from this software without specific prior written permission.
00049  *
00050  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00051  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00052  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
00053  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00054  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00055  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00056  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00057  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00058  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00059  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00060  */
00061 #include "usart.h"
00062 #include "pio.h"
00063 #include "lcdc.h"
00064 #include <string.h>
00065 #include <avr32/io.h>
00066 #include "sdram.h"
00067 #include "errno.h"
00068 
00069 
00070 /* Enable disable the display configurations here */
00071 /* #define CONF_640_480_60 */
00072 #define CONF_800_600_60
00073 /* #define CONF_1024_768_60 */
00074 
00075 #define BITMAP_FILE_ADDRESS 0xA0400000
00076 
00077 #define CPU_FAMILY      "AVR32_AP"
00078 #define CPU_TYPE        "AT32AP7000"
00079 #define MAX_FREQ        150000000
00080 
00081 #define DEFAULT_FREQ    OSC0_FREQ
00082 #define DEFAULT_UART    UART_A
00083 
00084 /* Define the on-board oscillators in Hz */
00085 #define OSC0_FREQ       20000000
00086 #define OSC1_FREQ       12000000
00087 
00088 /* Timeout for PLL */
00089 #define PLL_TIMEOUT 500000 
00090 /* Define the on-board memory sizes */
00091 #define SDRAM_SIZE      8
00092 
00093 /* Define the peripheral names */
00094 #define UART_A  AVR32_USART1
00095 #define UART_C  AVR32_USART3
00096 #define IRDA    AVR32_USART2
00097 
00098 /* Refresh rate of SDRAM in number of bus clocks */ 
00099 #define REFRESH_RATE 1170
00100 
00101 static const struct sdram_info sdram = {
00102         .phys_addr      = AVR32_EBI1_ADDRESS,
00103         .bus_width      = 32,
00104         .rows           = 11,
00105         .cols           = 8,
00106         .banks          = 2,
00107         .cas            = 3,
00108         .twr            = 2,
00109         .trc            = 7,
00110         .trp            = 2,
00111         .trcd           = 2,
00112         .tras           = 5,
00113         .txsr           = 5,
00114 };
00115 
00116 volatile avr32_usart_t *usart = &AVR32_USART1;
00117 int display_bm(lcdc_conf_t *lcdc_conf, void * file_start);
00118 
00119 void usart_print(volatile struct avr32_usart_t * usart, char *str)
00120 {
00121         while (*str != '\0')
00122                 usart_putchar(usart, *str++);
00123 }
00124 
00125 void usart_printHex(volatile avr32_usart_t * usart, const unsigned long n)
00126 {
00127         char tmp[9];
00128         int i;
00129 
00130         for (i = 0; i < 8; i++) {
00131                 unsigned long nibble;
00132 
00133                 nibble = (n >> (28 - 4 * i)) & 0x0F;
00134 
00135                 if (nibble < 10) {
00136                         tmp[i] = nibble + '0';
00137                 } else {
00138                         tmp[i] = nibble - 10 + 'a';
00139                 }
00140         }
00141 
00142         tmp[8] = 0;
00143         usart_print(usart, tmp);
00144 }
00145 
00146 static int mt481c2m32b2tg_init(const sdram_info *info)
00147 {
00148         volatile unsigned long *sdram = (unsigned long *) info->phys_addr;
00149         volatile avr32_sdramc_t *sdramc = &AVR32_SDRAMC;
00150         unsigned long dummy_read;
00151         unsigned int i;
00152 
00153         if ( sdram_init(info) )
00154                 return INVALID_ARGUMENT;
00155 
00156         /* Precharge All command is issued to the SDRAM */
00157         sdramc->mr = MODE_PRECHARGE;
00158         dummy_read = sdramc->mr;
00159         sdram[0] = 0;
00160 
00161         /* Provide eight auto-refresh (CBR) cycles */
00162         sdramc->mr = MODE_AUTOREFRESH;
00163         dummy_read = sdramc->mr;
00164         for (i = 0; i < 8; i++)
00165         {
00166                 sdram[0] = 0;
00167         }
00168         
00169         /* CAS from info struct, burst length 1, serial burst type */
00170         sdramc->mr = MODE_LOAD_MR;
00171         dummy_read = sdramc->mr;
00172         sdram[0x020] = 0;
00173 
00174         /* A Normal Mode command is provided, 3 clocks after tMRD is met. */
00175         dummy_read = sdramc->mr;
00176         sdramc->mr = MODE_NORMAL;
00177         dummy_read = sdramc->mr;
00178         sdram[0] = 0;
00179         
00180         /* Write refresh rate into SDRAMC refresh timer count register */
00181         sdramc->tr = REFRESH_RATE;
00182 
00183         return SUCCESS;
00184 }
00185 
00186 static int init_uart_a(int module_frequ)
00187 { 
00188         struct usart_options_t opt;
00189         volatile struct avr32_usart_t *usart = &AVR32_USART1;
00190 
00191         avr32_piomap_t usart_piomap = {                            \
00192                 {AVR32_USART1_RXD_0_PIN, AVR32_USART1_RXD_0_FUNCTION}, \
00193                 {AVR32_USART1_TXD_0_PIN, AVR32_USART1_TXD_0_FUNCTION}   \
00194         };
00195 
00196         /* Set options for the USART */
00197         opt.baudrate = 115200;
00198         opt.charlength = 8;
00199         opt.paritytype = USART_NO_PARITY;
00200         opt.stopbits = USART_1_STOPBIT;
00201         opt.channelmode = USART_NORMAL_CHMODE;
00202 
00203         /* Initialize it in RS232 mode */
00204         if(usart_init_rs232(usart, &opt, module_frequ ) )
00205                 return INVALID_ARGUMENT;
00206 
00207         /* Setup pio for USART */
00208         pio_enable_module(usart_piomap, 2);
00209 
00210         return SUCCESS;
00211 }
00212 
00213 int board_init( void )
00214 {
00215         volatile struct avr32_usart_t *usart = &AVR32_USART1;
00216         volatile struct avr32_pm_t *pm = &AVR32_PM;
00217         volatile struct avr32_smc_t * smc = &AVR32_SMC;
00218         volatile struct avr32_hmatrix_t * phm = &AVR32_HMATRIX;
00219         unsigned int timeout = PLL_TIMEOUT;
00220 
00221         /* Initialize USART */
00222         if(init_uart_a(20000000))
00223                 return INVALID_ARGUMENT;
00224         usart_print(usart, "STK1000 initialization:\n");
00225         usart_print(usart, " -> USART ... OK\n");
00226         /* reset usart before clock change */
00227         usart_reset(usart);
00228 
00229         
00230         /* SLOT_CYCLE -> max burst cycles (slow bursts can be broken)
00231         * DEFMSTR_TYPE -> 0 No default master, 1 last default master, 
00232         * 2 fixed master
00233         * FIXED_DEFMSTR -> master number (5 = LCD Controller)
00234         * ARBT -> 0 round robin, 1 fixed priority
00235         */
00236         
00237         phm->scfg[4] = ((16 << AVR32_HMATRIX_SCFG4_SLOT_CYCLE_OFFSET) 
00238                 & AVR32_HMATRIX_SCFG4_SLOT_CYCLE_MASK) 
00239                 | ((2 << AVR32_HMATRIX_SCFG4_DEFMSTR_TYPE_OFFSET) 
00240                 & AVR32_HMATRIX_SCFG4_DEFMSTR_TYPE_OFFSET) 
00241                 | ((5 << AVR32_HMATRIX_SCFG4_FIXED_DEFMSTR_OFFSET 
00242                 & AVR32_HMATRIX_SCFG4_FIXED_DEFMSTR_OFFSET)) 
00243                 | ((1 << AVR32_HMATRIX_SCFG4_ARBT_OFFSET));
00244         
00245         /* Set maximum priority to LCD Controller */
00246         phm->prs[4].pras = 0x00F00000;
00247                 
00248         /* set up SMC for higher frequencies */
00249         smc->cs[0].mode = 0x00031103;
00250         smc->cs[0].cycle = 0x000c000d;
00251         smc->cs[0].pulse = 0x0b0a0906;
00252         smc->cs[0].setup = 0x00010002;
00253         
00254         pm->pll0 = (0 << AVR32_PM_PLL0_PLLOSC_OFFSET) 
00255                 | ( (15 - 1) << AVR32_PM_PLL0_PLLMUL_OFFSET)
00256                 | ( (2 - 1) << AVR32_PM_PLL0_PLLDIV_OFFSET) 
00257                 | ( 16 << AVR32_PM_PLL0_PLLCOUNT_OFFSET) 
00258                 | ( 0x4 << AVR32_PM_PLL0_PLLOPT_OFFSET) 
00259                 | ( 1 << AVR32_PM_PLL0_PLLEN_OFFSET);
00260         
00261         /* Wait until pll has locked or a timeout elapsed*/
00262         while(!(pm->isr & (1 << AVR32_PM_ISR_LOCK0_OFFSET))
00263                 && (timeout != 0)){
00264                 timeout--;
00265         }
00266         
00267         if(timeout == 0){
00268                 usart_print(usart, "ERROR: PLL did not lock");
00269                 return -1;
00270         }
00271 
00272         pm->cksel = (1 << AVR32_PM_CKSEL_HSBDIV_OFFSET) 
00273                 | ( 0 << AVR32_PM_CKSEL_HSBSEL_OFFSET) 
00274                 | ( 1 << AVR32_PM_CKSEL_PBADIV_OFFSET) 
00275                 | ( 1 << AVR32_PM_CKSEL_PBASEL_OFFSET) 
00276                 | ( 1 << AVR32_PM_CKSEL_PBBDIV_OFFSET) 
00277                 | ( 1 << AVR32_PM_CKSEL_PBBSEL_OFFSET);
00278 
00279         pm->mcctrl = 0x2;
00280         
00281         if(init_uart_a(37500000)) /* reinitialize due to clock change */
00282                 return INVALID_ARGUMENT;
00283         usart_print(usart, "OK\n");
00284         
00285         /* Initialize SDRAMC */
00286         usart_print(usart, " -> SDRAM ... ");
00287         if (mt481c2m32b2tg_init(&sdram) )
00288                 return ERROR;
00289         usart_print(usart, "OK\n");
00290 
00291         /* Done. Print frequency and return */
00292         usart_print(usart, "STK1000 is successfully initialized");
00293 
00294         return 0;
00295 }
00297 lcdc_conf_t lcdc_vga_std_conf = {
00298                 
00299         dmabaddr1: 0x10000000,
00300         dmabaddr2: 0,
00301         burst_length: 4,
00302         xres: 640,
00303         yres: 480,
00304         set2dmode: MODE_2D_OFF,
00305         virtual_xres: 0,
00306         virtual_yres: 0,
00307         frame_rate: 60,
00308         lcdcclock: 25000000,
00309         guard_time: 2,
00310         memor: BIG_ENDIAN,
00311         ifwidth: 0,
00312         scanmod: SINGLE_SCAN,
00313         distype: TFT,
00314         invvd: NORMAL,
00315         invframe: NORMAL,
00316         invline: NORMAL,
00317         invclk: INVERTED,
00318         invdval: NORMAL,
00319         clkmod: ALWAYS_ACTIVE,
00320         pixelsize: BPP_24,
00321         ctrstval: 0x0f,
00322         ctrst_ena: DISABLED,
00323         ctrst_pol: NORMAL,
00324         ctrst_ps: PRE_HALF,
00325         mval: 0,
00326         mmode: EACH_FRAME,
00327         hpw: 64,/* Should be 96 but LCD Controller supports only up to 64 */
00328         hbp: 48,
00329         hfp: 16,
00330         vpw: 2, 
00331         vbp: 33,
00332         vfp: 10,
00333         vhdly: 0,
00334 };
00336 lcdc_conf_t lcdc_800_600_60_conf = {
00337                 
00338         dmabaddr1: 0x10000000,
00339         dmabaddr2: 0,
00340         burst_length: 4,
00341         xres: 800,
00342         yres: 600,
00343         set2dmode: MODE_2D_OFF,
00344         virtual_xres: 0,
00345         virtual_yres: 0,
00346         frame_rate: 60,
00347         lcdcclock: 40000000,
00348         guard_time: 2,
00349         memor: BIG_ENDIAN,
00350         ifwidth: 0,
00351         scanmod: SINGLE_SCAN,
00352         distype: TFT,
00353         invvd: NORMAL,
00354         invframe: INVERTED,
00355         invline: NORMAL,
00356         invclk: INVERTED,
00357         invdval: NORMAL,
00358         clkmod: ALWAYS_ACTIVE,
00359         pixelsize: BPP_24,
00360         ctrstval: 0x0f,
00361         ctrst_ena: DISABLED,
00362         ctrst_pol: NORMAL,
00363         ctrst_ps: PRE_HALF,
00364         mval: 0,
00365         mmode: EACH_FRAME,
00366         hpw: 64, /* should be 80 but LCD Controller supports only up to 64 */
00367         hbp: 126,
00368         hfp: 46,
00369         vpw: 4, 
00370         vbp: 17,
00371         vfp: 3,
00372         vhdly: 0,
00373 };
00375 lcdc_conf_t lcdc_1024_768_60_conf = {
00376                 
00377         dmabaddr1: 0x10000000,
00378         dmabaddr2: 0,
00379         burst_length: 4,
00380         xres: 1024,
00381         yres: 768,
00382         set2dmode: MODE_2D_OFF,
00383         virtual_xres: 0,
00384         virtual_yres: 0,
00385         frame_rate: 60,
00386         lcdcclock: 64000000,
00387         guard_time: 2,
00388         memor: BIG_ENDIAN,
00389         ifwidth: 0,
00390         scanmod: SINGLE_SCAN,
00391         distype: TFT,
00392         invvd: NORMAL,
00393         invframe: INVERTED,
00394         invline: NORMAL,
00395         invclk: INVERTED,
00396         invdval: NORMAL,
00397         clkmod: ALWAYS_ACTIVE,
00398         pixelsize: BPP_16,
00399         ctrstval: 0x0f,
00400         ctrst_ena: DISABLED,
00401         ctrst_pol: NORMAL,
00402         ctrst_ps: PRE_HALF,
00403         mval: 0,
00404         mmode: EACH_FRAME,
00405         hpw: 64, /* Should be 104 but LCD controller supports only up to 64 */
00406         hbp: 152,
00407         hfp: 48,
00408         vpw: 4, 
00409         vbp: 23,
00410         vfp: 3,
00411         vhdly: 0,
00412 };
00413 
00417 void lcdc_pio_config(void){
00418         /* CC and MOD signals are not used for the video DAC and are not connected to 
00419         * the monitor interface
00420         */
00421                 avr32_piomap_t piomap = {
00422                         { AVR32_LCDC_DVAL_0_0_PIN, AVR32_LCDC_DVAL_0_0_FUNCTION },
00423                         { AVR32_LCDC_HSYNC_0_PIN, AVR32_LCDC_HSYNC_0_FUNCTION },
00424                         { AVR32_LCDC_PCLK_0_PIN, AVR32_LCDC_PCLK_0_FUNCTION },
00425                         { AVR32_LCDC_PWR_0_PIN, AVR32_LCDC_PWR_0_FUNCTION },
00426                         { AVR32_LCDC_VSYNC_0_PIN, AVR32_LCDC_VSYNC_0_FUNCTION },
00427                         { AVR32_LCDC_DATA_0_0_PIN, AVR32_LCDC_DATA_0_0_FUNCTION },
00428                         { AVR32_LCDC_DATA_1_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
00429                         { AVR32_LCDC_DATA_2_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
00430                         { AVR32_LCDC_DATA_3_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
00431                         { AVR32_LCDC_DATA_4_0_PIN, AVR32_LCDC_DATA_1_0_FUNCTION },
00432                         { AVR32_LCDC_DATA_5_PIN, AVR32_LCDC_DATA_5_FUNCTION },
00433                         { AVR32_LCDC_DATA_6_PIN, AVR32_LCDC_DATA_6_FUNCTION },
00434                         { AVR32_LCDC_DATA_7_PIN, AVR32_LCDC_DATA_7_FUNCTION },
00435                         { AVR32_LCDC_DATA_8_0_PIN, AVR32_LCDC_DATA_8_0_FUNCTION },
00436                         { AVR32_LCDC_DATA_9_0_PIN, AVR32_LCDC_DATA_9_0_FUNCTION },
00437                         { AVR32_LCDC_DATA_10_0_PIN, AVR32_LCDC_DATA_10_0_FUNCTION },
00438                         { AVR32_LCDC_DATA_11_0_PIN, AVR32_LCDC_DATA_11_0_FUNCTION },
00439                         { AVR32_LCDC_DATA_12_0_PIN, AVR32_LCDC_DATA_12_0_FUNCTION },
00440                         { AVR32_LCDC_DATA_13_PIN, AVR32_LCDC_DATA_13_FUNCTION },
00441                         { AVR32_LCDC_DATA_14_PIN, AVR32_LCDC_DATA_14_FUNCTION },
00442                         { AVR32_LCDC_DATA_15_PIN, AVR32_LCDC_DATA_15_FUNCTION },
00443                         { AVR32_LCDC_DATA_16_0_PIN, AVR32_LCDC_DATA_16_0_FUNCTION },
00444                         { AVR32_LCDC_DATA_17_0_PIN, AVR32_LCDC_DATA_17_0_FUNCTION },
00445                         { AVR32_LCDC_DATA_18_0_PIN, AVR32_LCDC_DATA_18_0_FUNCTION },
00446                         { AVR32_LCDC_DATA_19_0_PIN, AVR32_LCDC_DATA_19_0_FUNCTION },
00447                         { AVR32_LCDC_DATA_20_0_PIN, AVR32_LCDC_DATA_20_0_FUNCTION },
00448                         { AVR32_LCDC_DATA_21_0_PIN, AVR32_LCDC_DATA_21_0_FUNCTION },
00449                         { AVR32_LCDC_DATA_22_PIN, AVR32_LCDC_DATA_22_FUNCTION },
00450                         { AVR32_LCDC_DATA_23_PIN, AVR32_LCDC_DATA_23_FUNCTION }
00451                         
00452         };
00453         pio_enable_module(piomap, 31);
00454         
00455 }
00460 void fill_frame_buffer (lcdc_conf_t *lcdc_conf)
00461 {
00462         
00463         unsigned int k,l,x,y;
00464         unsigned char * framePtr;
00465         unsigned short tmp;
00466         
00467         framePtr = (unsigned char *) (lcdc_conf->dmabaddr1 | 0xA0000000);
00468         
00469         if(lcdc_conf->pixelsize == BPP_24){
00470         for (l=0; l < lcdc_conf->yres; l++){
00471                 for (k=0; k < lcdc_conf->xres; k++) 
00472                 {
00473                         x = (255 * l) / lcdc_conf->yres;
00474                         y = (255 * k) / lcdc_conf->xres;
00475                         *framePtr++ = x;
00476                         *framePtr++ = y;
00477                         *framePtr++ = 255 - (x + y) / 2;
00478                 }
00479         }
00480         }
00481         if(lcdc_conf->pixelsize == BPP_16){
00482                 for (l=0; l < lcdc_conf->yres; l++){
00483                         for (k=0; k < lcdc_conf->xres; k++)
00484                         {
00485                                 x = (32 * l) / lcdc_conf->yres;
00486                                 y = (32 * k) / lcdc_conf->xres;
00487                                 /* 1-5-5-5 format */
00488                                 tmp =  (((32 - (x + y) / 2) << 10)& 0x0007C00) | ((y << 5) & 0x000003E0) | (x & 0x0000001F);
00489                                 *framePtr = tmp;
00490                                 framePtr += 2;
00491                         }
00492                 }
00493         }
00494 }
00495 int main (void)
00496 {
00497         volatile avr32_pm_t *pm = &AVR32_PM;
00498         lcdc_conf_t * lcdc_conf;
00499         unsigned char mul, div;
00500         
00501 #ifdef CONF_640_480_60
00502         lcdc_conf = &lcdc_vga_std_conf;
00503         /* 25MHz pixel clock */
00504         mul = 25;
00505         div = 12;
00506 #endif
00507 #ifdef CONF_800_600_60
00508         lcdc_conf = &lcdc_800_600_60_conf;
00509         /* 40 MHz pixel clock */
00510         mul = 10;
00511         div = 3;
00512 #endif
00513 #ifdef CONF_1024_768_60
00514         lcdc_conf = &lcdc_1024_768_60_conf;
00515         /* 63,5 MHz pixel clock */
00516         mul = 37;
00517         div = 7;
00518 #endif
00519         
00520         board_init();
00521         usart_print(usart, "board init complete\n");
00522         
00523         usart_print(usart, "Setting up PLL1 for LCD Controller\n");
00524         usart_print(usart, " -> PLL1 ... ");
00525         pm->pll1 = (1 << AVR32_PM_PLL1_PLLOSC_OFFSET) |
00526                                 ( (mul - 1) << AVR32_PM_PLL1_PLLMUL_OFFSET) |
00527                                 ( (div - 1) << AVR32_PM_PLL1_PLLDIV_OFFSET) |
00528                                 ( 16 << AVR32_PM_PLL1_PLLCOUNT_OFFSET) |
00529                                 ( 0x4 << AVR32_PM_PLL1_PLLOPT_OFFSET) |
00530                                 ( 1 << AVR32_PM_PLL1_PLLEN_OFFSET);
00531                         
00532         while(!(pm->isr & (1 << AVR32_PM_ISR_LOCK1_OFFSET)));
00533         usart_print(usart, "OK\n");
00534         
00535         /* clear framebuffer */
00536         memset((void *)lcdc_conf->dmabaddr1, 0, lcdc_conf->xres * lcdc_conf->yres * lcdc_conf->pixelsize / 8);
00537         
00538         fill_frame_buffer(lcdc_conf);
00539         display_bm(lcdc_conf, ((void *) BITMAP_FILE_ADDRESS));
00540         
00541         usart_print(usart, "Setting up LCD controller\n");
00542         lcdc_pio_config();
00543         
00544         /* Power manager setup 
00545         * Enable CLOCK for LCDC in HSBMASK
00546         */
00547         pm->hsb_mask |= 0x00000080;
00548         /* Feed generic clock for LCD Controller from PLL1 */
00549         pm->gcctrl[7] |= 0x00000007;
00550         
00551         lcdc_init(lcdc_conf);
00552         usart_print(usart, "Setup complete\n");
00553         while(1);
00554         
00555         return 0;
00556 }

Generated on Wed May 7 16:03:17 2008 for AVR32114 Using the AVR32 LCD Controller by  doxygen 1.5.3-20071008