BeRTOS
lcd_32122a.c
Go to the documentation of this file.
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