BeRTOS
lcd_rit128x96.c
Go to the documentation of this file.
00001 
00038 #include "lcd_rit128x96.h"
00039 
00040 #include "hw/hw_rit128x96.h"
00041 
00042 #include <cfg/debug.h>
00043 #include <cfg/macros.h>
00044 
00045 
00046 /*
00047  * Hard-coded command initialization sequence.
00048  *
00049  * NOTE: the first byte is the size of the command.
00050  */
00051 static const uint8_t init_cmd[] =
00052 {
00053     /* Unlock commands */
00054     3, 0xfd, 0x12, 0xe3,
00055     /* Display off */
00056     2, 0xae, 0xe3,
00057     /* Icon off */
00058     3, 0x94, 0, 0xe3,
00059     /* Multiplex ratio */
00060     3, 0xa8, 95, 0xe3,
00061     /* Contrast */
00062     3, 0x81, 0xb7, 0xe3,
00063     /* Pre-charge current */
00064     3, 0x82, 0x3f, 0xe3,
00065     /* Display Re-map */
00066     3, 0xa0, 0x52, 0xe3,
00067     /* Display Start Line */
00068     3, 0xa1, 0, 0xe3,
00069     /* Display Offset */
00070     3, 0xa2, 0x00, 0xe3,
00071     /* Display Mode Normal */
00072     2, 0xa4, 0xe3,
00073     /* Phase Length */
00074     3, 0xb1, 0x11, 0xe3,
00075     /* Frame frequency */
00076     3, 0xb2, 0x23, 0xe3,
00077     /* Front Clock Divider */
00078     3, 0xb3, 0xe2, 0xe3,
00079     /* Set gray scale table */
00080     17, 0xb8, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 19, 22, 26, 30, 0xe3,
00081     /* Second pre-charge period */
00082     3, 0xbb, 0x01, 0xe3,
00083     /* Pre-charge voltage */
00084     3, 0xbc, 0x3f, 0xe3,
00085     /* Display ON */
00086     2, 0xaf, 0xe3,
00087 };
00088 
00089 /*
00090  * Hard-coded command shutdown sequence.
00091  */
00092 static const uint8_t exit_cmd[] =
00093 {
00094     /* Display OFF */
00095     0xae, 0xe3
00096 };
00097 
00098 /*
00099  * Hard-coded horizontal increment command.
00100  */
00101 static const uint8_t horizontal_inc[] =
00102 {
00103     0xa0, 0x52
00104 };
00105 
00109 static void lcd_dataWrite(const uint8_t *buf, size_t count)
00110 {
00111     while (count--)
00112         LCD_WRITE(*buf++);
00113 }
00114 
00115 /* Turn on the OLED display */
00116 void rit128x96_on(void)
00117 {
00118     unsigned int i;
00119 
00120     /* Loop through the SSD1329 controller initialization sequence */
00121     LCD_SET_COMMAND();
00122     for (i = 0; i < sizeof(init_cmd); i += init_cmd[i] + 1)
00123         lcd_dataWrite(init_cmd + i + 1, init_cmd[i] - 1);
00124 }
00125 
00126 /* Turn off the OLED display */
00127 void rit128x96_off(void)
00128 {
00129     LCD_SET_COMMAND();
00130     lcd_dataWrite(exit_cmd, sizeof(exit_cmd));
00131 }
00132 
00133 static void lcd_start_blit(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
00134 {
00135     uint8_t buffer[3];
00136 
00137     ASSERT((x + width) <= LCD_WIDTH);
00138     ASSERT((y + height) <= LCD_HEIGHT);
00139 
00140     /* Enter command mode */
00141     LCD_SET_COMMAND();
00142 
00143     buffer[0] = 0x15;
00144     buffer[1] = x / 2;
00145     buffer[2] = (x + width - 2) / 2;
00146     lcd_dataWrite(buffer, 3);
00147 
00148     buffer[0] = 0x75;
00149     buffer[1] = y;
00150     buffer[2] = y + height - 1;
00151     lcd_dataWrite(buffer, 3);
00152     lcd_dataWrite((const uint8_t *)&horizontal_inc, sizeof(horizontal_inc));
00153 }
00154 
00155 /* Refresh a raw image on screen */
00156 void rit128x96_blitRaw(const uint8_t *data,
00157         uint8_t x, uint8_t y, uint8_t width, uint8_t height)
00158 {
00159     lcd_start_blit(x, y, width, height);
00160     /*
00161      * Enter data mode and send the encoded image data to the OLED display,
00162      * over the SSI bus.
00163      */
00164     LCD_SET_DATA();
00165     while (height--)
00166     {
00167         /* Write an entire row at once */
00168         lcd_dataWrite(data, width / 2);
00169         data += width / 2;
00170     }
00171 }
00172 
00173 /* Refresh a bitmap on screen */
00174 void rit128x96_blitBitmap(const Bitmap *bm)
00175 {
00176     uint8_t lcd_row[bm->width / 2];
00177     uint8_t mask;
00178     int i, l;
00179 
00180     lcd_start_blit(0, 0, bm->width, bm->height);
00181     /*
00182      * Enter data mode and send the encoded image data to the OLED display,
00183      * over the SSI bus.
00184      */
00185     LCD_SET_DATA();
00186     for (l = 0; l < bm->height / 8; l++)
00187     {
00188         for (mask = 1; mask; mask <<= 1)
00189         {
00190             for (i = 0; i < bm->width; i++)
00191             {
00192                 if (bm->raster[l * bm->width + i] & mask)
00193                     lcd_row[i / 2] |= i & 1 ? 0x0f : 0xf0;
00194                 else
00195                     lcd_row[i / 2] &= i & 1 ? 0xf0 : 0x0f;
00196             }
00197             /* Write an entire row at once */
00198             lcd_dataWrite(lcd_row, sizeof(lcd_row));
00199         }
00200     }
00201 }
00202 
00203 /* Initialize the OLED display */
00204 void rit128x96_init(void)
00205 {
00206     /* Initialize the communication bus */
00207     lcd_rit128x96_hw_bus_init();
00208 
00209     /* Turn on the OLED display */
00210     rit128x96_on();
00211 }