BeRTOS
|
00001 00042 #include "lcd_32122a.h" 00043 00044 #include "hw/hw_lcd_32122a.h" 00045 00046 #include "cfg/cfg_lcd_32122a.h" 00047 00048 #include <cfg/macros.h> /* BV() */ 00049 #include <cfg/debug.h> 00050 #include <cfg/module.h> 00051 00052 #include <gfx/gfx.h> 00053 00054 #include <drv/timer.h> 00055 #include <drv/pwm.h> 00056 00057 #include <cpu/irq.h> 00058 #include <cpu/types.h> 00059 00060 00062 #define LCD_PAGES 4 00063 00065 #define LCD_PAGESIZE (LCD_WIDTH / 2) 00066 00071 #define LCD_CMD_DISPLAY_ON 0xAF 00072 #define LCD_CMD_DISPLAY_OFF 0xAE 00073 #define LCD_CMD_STARTLINE 0xC0 00074 #define LCD_CMD_PAGEADDR 0xB8 00075 #define LCD_CMD_COLADDR 0x00 00076 #define LCD_CMD_ADC_LEFT 0xA1 00077 #define LCD_CMD_ADC_RIGHT 0xA0 00078 #define LCD_CMD_STATIC_OFF 0xA4 00079 #define LCD_CMD_STATIC_ON 0xA5 00080 #define LCD_CMD_DUTY_32 0xA9 00081 #define LCD_CMD_DUTY_16 0xA8 00082 #define LCD_CMD_RMW_ON 0xE0 00083 #define LCD_CMD_RMW_OFF 0xEE 00084 #define LCD_CMD_RESET 0xE2 00085 00088 /* Status flags */ 00089 #define LCDF_BUSY BV(7) 00090 00091 #if CONFIG_LCD_WAIT 00092 00105 #define WAIT_LCD \ 00106 do { \ 00107 uint8_t status; \ 00108 LCD_DB_IN; \ 00109 do { \ 00110 LCD_SET_RD; \ 00111 LCD_CLR_A0; \ 00112 LCD_SET_E1; \ 00113 LCD_DELAY_READ; \ 00114 status = LCD_READ; \ 00115 LCD_CLR_E1; \ 00116 LCD_SET_A0; \ 00117 LCD_CLR_RD; \ 00118 } while (status & LCDF_BUSY); \ 00119 LCD_DB_OUT; \ 00120 } while (0) 00121 #else /* CONFIG_LCD_WAIT */ 00122 #define WAIT_LCD do {} while(0) 00123 #endif /* CONFIG_LCD_WAIT */ 00124 00125 00132 static uint8_t lcd_raster[RAST_SIZE(LCD_WIDTH, LCD_HEIGHT)]; 00133 00135 struct Bitmap lcd_bitmap; 00136 00137 00138 #if CONFIG_LCD_SOFTINT_REFRESH 00139 00141 static Timer lcd_refresh_timer; 00142 00143 #endif /* CONFIG_LCD_SOFTINT_REFRESH */ 00144 00145 00146 INLINE void lcd_32122_cmd(uint8_t cmd, uint8_t chip) 00147 { 00148 WAIT_LCD; 00149 00150 /* __ __ 00151 * A0 __\____________/__ 00152 * 00153 * R/W __________________ 00154 * ______ 00155 * E1 _____/ \_____ 00156 * 00157 * DATA --<============>-- 00158 */ 00159 LCD_WRITE(cmd); 00160 //LCD_DB_OUT; 00161 LCD_CLR_A0; 00162 LCD_SET_E(chip); 00163 LCD_DELAY_WRITE; 00164 LCD_CLR_E(chip); 00165 LCD_SET_A0; 00166 //LCD_DB_IN; 00167 00168 } 00169 00170 00171 INLINE uint8_t lcd_32122_read(uint8_t chip) 00172 { 00173 uint8_t data; 00174 00175 WAIT_LCD; 00176 00190 LCD_DB_IN; 00191 //LCD_SET_A0; 00192 LCD_SET_RD; 00193 LCD_SET_E(chip); 00194 LCD_DELAY_READ; 00195 data = LCD_READ; 00196 LCD_CLR_E(chip); 00197 LCD_CLR_RD; 00198 //LCD_CLR_A0; 00199 LCD_DB_OUT; 00200 00201 return data; 00202 } 00203 00204 INLINE void lcd_32122_write(uint8_t c, uint8_t chip) 00205 { 00206 WAIT_LCD; 00207 00221 LCD_WRITE(c); 00222 //LCD_DB_OUT; 00223 //LCD_SET_A0; 00224 LCD_SET_E(chip); 00225 LCD_DELAY_WRITE; 00226 LCD_CLR_E(chip); 00227 //LCD_CLR_A0; 00228 //LCD_DB_IN; 00229 } 00230 00231 static void lcd_32122_clear(void) 00232 { 00233 uint8_t page, j; 00234 00235 for (page = 0; page < LCD_PAGES; ++page) 00236 { 00237 lcd_32122_cmd(LCD_CMD_COLADDR, LCDF_E1 | LCDF_E2); 00238 lcd_32122_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); 00239 for (j = 0; j < LCD_PAGESIZE; j++) 00240 lcd_32122_write(0, LCDF_E1 | LCDF_E2); 00241 } 00242 } 00243 00244 00245 static void lcd_32122_writeRaster(const uint8_t *raster) 00246 { 00247 uint8_t page, rows; 00248 const uint8_t *right_raster; 00249 00250 for (page = 0; page < LCD_PAGES; ++page) 00251 { 00252 lcd_32122_cmd(LCD_CMD_PAGEADDR | page, LCDF_E1 | LCDF_E2); 00253 lcd_32122_cmd(LCD_CMD_COLADDR | 0, LCDF_E1 | LCDF_E2); 00254 00255 /* Super optimized lamer loop */ 00256 right_raster = raster + LCD_PAGESIZE; 00257 rows = LCD_PAGESIZE; 00258 do 00259 { 00260 lcd_32122_write(*raster++, LCDF_E1); 00261 lcd_32122_write(*right_raster++, LCDF_E2); 00262 } 00263 while (--rows); 00264 raster = right_raster; 00265 } 00266 } 00267 00268 #if CONFIG_LCD_SOFTINT_REFRESH 00269 00270 static void lcd_32122_refreshSoftint(void) 00271 { 00272 lcd_32122_blitBitmap(&lcd_bitmap); 00273 timer_setDelay(&lcd_refresh_timer, ms_to_ticks(CONFIG_LCD_REFRESH)); 00274 timer_add(&lcd_refresh_timer); 00275 } 00276 00277 #endif /* CONFIG_LCD_SOFTINT_REFRESH */ 00278 00282 void lcd_32122_setPwm(int duty) 00283 { 00284 ASSERT(duty >= LCD_MIN_PWM); 00285 ASSERT(duty <= LCD_MAX_PWM); 00286 00287 pwm_setDuty(LCD_PWM_CH, duty); 00288 pwm_enable(LCD_PWM_CH, true); 00289 } 00290 00294 void lcd_32122_blitBitmap(const Bitmap *bm) 00295 { 00296 lcd_32122_writeRaster(bm->raster); 00297 } 00298 00299 00306 void lcd_32122_init(void) 00307 { 00308 MOD_CHECK(timer); 00309 00310 pwm_init(); 00311 00312 lcd_32122a_hw_bus_init(); 00313 LCD_32122_RESET(); 00314 00315 lcd_32122_cmd(LCD_CMD_RESET, LCDF_E1 | LCDF_E2); 00316 lcd_32122_cmd(LCD_CMD_DISPLAY_ON, LCDF_E1 | LCDF_E2); 00317 lcd_32122_cmd(LCD_CMD_STARTLINE | 0, LCDF_E1 | LCDF_E2); 00318 00319 00320 lcd_32122_clear(); 00321 lcd_32122_setPwm(LCD_DEF_PWM); 00322 00323 gfx_bitmapInit(&lcd_bitmap, lcd_raster, LCD_WIDTH, LCD_HEIGHT); 00324 gfx_bitmapClear(&lcd_bitmap); 00325 00326 #if CONFIG_LCD_SOFTINT_REFRESH 00327 /* Init IRQ driven LCD refresh */ 00328 timer_setSoftint(&lcd_refresh_timer, (Hook)lcd_32122_refreshSoftint, 0); 00329 timer_setDelay(&lcd_refresh_timer, ms_to_ticks(CONFIG_LCD_REFRESH)); 00330 timer_add(&lcd_refresh_timer); 00331 #endif /* CONFIG_LCD_SOFTINT_REFRESH */ 00332 00333 } 00334