00001
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "lcdc.h"
00046 #include "print_funcs.h"
00047
00057 int lcdc_init(lcdc_conf_t* lcdc_conf)
00058 {
00059 volatile avr32_lcdc_t *plcdc = &AVR32_LCDC;
00060 unsigned char valid_data_lines = 0;
00061 unsigned char pixel_size = 0;
00062 unsigned char clkval = 0;
00063 unsigned int pixel_clock_theo = 0;
00064 unsigned short lineval, hozval;
00065
00066
00067 plcdc->pwrcon &= ~(1 << AVR32_LCDC_PWRCON_PWR_OFFSET);
00068 plcdc->dmacon &= ~(1 << AVR32_LCDC_DMACON_DMAEN_OFFSET);
00069
00070
00071 if(lcdc_conf->distype != LCDC_TFT){
00072 switch(lcdc_conf->scanmod){
00073 case LCDC_SINGLE_SCAN:
00074 switch(lcdc_conf->ifwidth){
00075 case LCDC_IF_WIDTH4:
00076 valid_data_lines = 4;
00077 break;
00078 case LCDC_IF_WIDTH8:
00079 valid_data_lines = 8;
00080 break;
00081 default:
00082 return -1;
00083 }
00084
00085 case LCDC_DUAL_SCAN:
00086 switch(lcdc_conf->ifwidth){
00087 case LCDC_IF_WIDTH8:
00088 valid_data_lines = 4;
00089 break;
00090 case LCDC_IF_WIDTH16:
00091 valid_data_lines = 8;
00092 break;
00093 default:
00094 return -1;
00095 }
00096 default:
00097 return -1;
00098 }
00099 }
00100
00101 lineval = lcdc_conf->yres - 1;
00102 switch(lcdc_conf->distype){
00103 case LCDC_STN_MONO:
00104 hozval = (lcdc_conf->xres / valid_data_lines) - 1;
00105 break;
00106 case LCDC_STN_COLOR:
00107 hozval = (lcdc_conf->xres * 3 / valid_data_lines) - 1;
00108 break;
00109 case LCDC_TFT:
00110 hozval = lcdc_conf->xres - 1;
00111 break;
00112 default:
00113 return -1;
00114 }
00115 plcdc->lcdfrmcfg = (lineval & AVR32_LCDC_LINEVAL_MASK) |
00116 ((hozval << AVR32_LCDC_HOZVAL) & AVR32_LCDC_HOZVAL_MASK);
00117
00118
00119 switch(lcdc_conf->distype){
00120 case LCDC_STN_MONO:
00121 pixel_clock_theo = lcdc_conf->frame_rate * lcdc_conf->xres * lcdc_conf->yres / valid_data_lines;
00122 break;
00123 case LCDC_STN_COLOR:
00124 pixel_clock_theo = lcdc_conf->frame_rate * lcdc_conf->xres * lcdc_conf->yres * 3 / valid_data_lines;
00125 break;
00126 case LCDC_TFT:
00127 pixel_clock_theo = lcdc_conf->frame_rate * lcdc_conf->xres * lcdc_conf->yres;
00128 break;
00129 default:
00130 return -1;
00131 }
00132 clkval = (lcdc_conf->lcdcclock / (2 * pixel_clock_theo));
00133 if (clkval == 0) {
00134 plcdc->lcdcon1 = 1;
00135 } else {
00136 plcdc->lcdcon1 = ((clkval - 1) << AVR32_LCDC_LCDCON1_CLKVAL) & AVR32_LCDC_LCDCON1_CLKVAL_MASK;
00137 }
00138
00139
00140 switch(lcdc_conf->pixelsize){
00141 case 1: pixel_size = 0;break;
00142 case 2: pixel_size = 1;break;
00143 case 4: pixel_size = 2;break;
00144 case 8: pixel_size = 3;break;
00145 case 16: pixel_size = 4;break;
00146 case 24: pixel_size = 5;break;
00147 case 32: pixel_size = 6;break;
00148 default:
00149 return -1;
00150 }
00151 plcdc->lcdcon2 = (lcdc_conf->distype & AVR32_LCDC_LCDCON2_DISTYPE_MASK) |
00152 ((lcdc_conf->scanmod << AVR32_LCDC_LCDCON2_SCANMOD) & AVR32_LCDC_LCDCON2_SCANMOD_MASK) |
00153 ((lcdc_conf->ifwidth << AVR32_LCDC_LCDCON2_IFWIDTH) & AVR32_LCDC_LCDCON2_IFWIDTH_MASK) |
00154 ((lcdc_conf->invvd << AVR32_LCDC_LCDCON2_INVVD) & AVR32_LCDC_LCDCON2_INVVD_MASK) |
00155 ((lcdc_conf->invframe << AVR32_LCDC_LCDCON2_INVFRAME) & AVR32_LCDC_LCDCON2_INVFRAME_MASK) |
00156 ((pixel_size << AVR32_LCDC_LCDCON2_PIXELSIZE) & AVR32_LCDC_LCDCON2_PIXELSIZE_MASK) |
00157 ((lcdc_conf->invline << AVR32_LCDC_LCDCON2_INVLINE) & AVR32_LCDC_LCDCON2_INVLINE_MASK) |
00158 ((lcdc_conf->invclk << AVR32_LCDC_LCDCON2_INVCLK) & AVR32_LCDC_LCDCON2_INVCLK_MASK) |
00159 ((lcdc_conf->invdval << AVR32_LCDC_LCDCON2_INVDVAL) & AVR32_LCDC_LCDCON2_INVDVAL_MASK) |
00160 ((lcdc_conf->clkmod << AVR32_LCDC_LCDCON2_CLKMOD) & AVR32_LCDC_LCDCON2_CLKMOD_MASK) |
00161 ((lcdc_conf->memor << AVR32_LCDC_LCDCON2_MEMOR) & AVR32_LCDC_LCDCON2_MEMOR_MASK);
00162
00163
00164 plcdc->lcdtim1 = (lcdc_conf->vfp & AVR32_LCDC_LCDTIM1_VFP_MASK) |
00165 ((lcdc_conf->vbp << AVR32_LCDC_LCDTIM1_VBP) & AVR32_LCDC_LCDTIM1_VBP_MASK) |
00166 (((lcdc_conf->vpw - 1) << AVR32_LCDC_LCDTIM1_VPW) & AVR32_LCDC_LCDTIM1_VPW_MASK) |
00167 ((lcdc_conf->vhdly << AVR32_LCDC_LCDTIM1_VHDLY) & AVR32_LCDC_LCDTIM1_VHDLY_MASK);
00168
00169 plcdc->lcdtim2 = (lcdc_conf->hbp & AVR32_LCDC_HBP_MASK) |
00170 (((lcdc_conf->hpw - 1) << AVR32_LCDC_LCDTIM2_HPW) & AVR32_LCDC_LCDTIM2_HPW_MASK) |
00171 ((lcdc_conf->hfp << AVR32_LCDC_LCDTIM2_HFP) & AVR32_LCDC_LCDTIM2_HFP_MASK);
00172
00173
00174 plcdc->idr = 0xFFFFFFFF;
00175
00176
00177 plcdc->lcdmval = (lcdc_conf->mval & AVR32_LCDC_LCDMVAL_MVAL_MASK) |
00178 ((lcdc_conf->mmode << AVR32_LCDC_LCDMVAL_MMODE_OFFSET) & AVR32_LCDC_LCDMVAL_MMODE_MASK);
00179
00180
00181 plcdc->contrast_val = lcdc_conf->ctrstval;
00182 plcdc->contrast_ctr = (lcdc_conf->ctrst_ps & AVR32_LCDC_CONTRAST_CTR_PS_MASK) |
00183 ((lcdc_conf->ctrst_pol << AVR32_LCDC_CONTRAST_CTR_POL_OFFSET) & AVR32_LCDC_CONTRAST_CTR_POL_MASK) |
00184 ((lcdc_conf->ctrst_ena << AVR32_LCDC_CONTRAST_CTR_ENA_OFFSET) & AVR32_LCDC_CONTRAST_CTR_ENA_MASK);
00185
00186
00187 int lcd_fifo_size = lcdc_conf->scanmod ? 256 : 512;
00188 plcdc->lcdfifo = lcd_fifo_size - (2 * lcdc_conf->burst_length + 3);
00189
00190
00191 plcdc->dmabaddr1 = lcdc_conf->dmabaddr1;
00192 if(lcdc_conf->scanmod == LCDC_DUAL_SCAN){
00193 plcdc->dmabaddr2 = lcdc_conf->dmabaddr2;
00194 }
00195
00196
00197
00198 plcdc->dmafrmcfg = ((((lcdc_conf->xres * lcdc_conf->yres * lcdc_conf->pixelsize) + 31 )/ 32) & AVR32_LCDC_DMAFRMCFG_FRMSIZE_MASK) |
00199 (((lcdc_conf->burst_length - 1) << AVR32_LCDC_DMAFRMCFG_BRSTLEN) & AVR32_LCDC_DMAFRMCFG_BRSTLEN_MASK);
00200
00201
00202 if(lcdc_conf->set2dmode){
00203
00204 plcdc->dma2dcfg = ((lcdc_conf->virtual_xres - lcdc_conf->xres) * (lcdc_conf->pixelsize / 8)) & AVR32_LCDC_DMA2DCFG_ADDRINC_MASK;
00205 }
00206
00207
00208 while (plcdc->dmacon & AVR32_LCDC_DMACON_DMABUSY);
00209
00210
00211 if(lcdc_conf->set2dmode){
00212 plcdc->dmacon = (1 << AVR32_LCDC_DMACON_DMAEN_OFFSET) |
00213 (1 << AVR32_LCDC_DMACON_DMAUPDT_OFFSET) |
00214 (1 << AVR32_LCDC_DMACON_DMA2DEN_OFFSET);
00215 }
00216 else{
00217 plcdc->dmacon = (1 << AVR32_LCDC_DMACON_DMAEN_OFFSET) |
00218 (1 << AVR32_LCDC_DMACON_DMAUPDT_OFFSET);
00219 }
00220
00221 plcdc->pwrcon |= (lcdc_conf->guard_time << AVR32_LCDC_PWRCON_GUARD_TIME_OFFSET) & AVR32_LCDC_PWRCON_GUARD_TIME_MASK;
00222
00223
00224 while (plcdc->PWRCON.busy == 1);
00225 plcdc->PWRCON.pwr = 1;
00226
00227 return 0;
00228 }