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