iforce2d Chris / Mbed 2 deprecated ubxDistanceMeter

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers u8g_dev_ssd1327_96x96_gr.c Source File

u8g_dev_ssd1327_96x96_gr.c

00001 /*
00002 
00003   u8g_dev_ssd1327_96x96_gr.c
00004   
00005   2-Bit (graylevel) Driver for SSD1327 Controller (OLED Display)
00006   Tested with Seedstudio 96x96 Oled (LY120)
00007   http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96
00008 
00009   Universal 8bit Graphics Library
00010   
00011   Copyright (c) 2012, olikraus@gmail.com
00012   All rights reserved.
00013 
00014   Redistribution and use in source and binary forms, with or without modification, 
00015   are permitted provided that the following conditions are met:
00016 
00017   * Redistributions of source code must retain the above copyright notice, this list 
00018     of conditions and the following disclaimer.
00019     
00020   * Redistributions in binary form must reproduce the above copyright notice, this 
00021     list of conditions and the following disclaimer in the documentation and/or other 
00022     materials provided with the distribution.
00023 
00024   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
00025   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
00026   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00027   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00028   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
00029   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00030   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
00031   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
00032   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00033   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
00034   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00035   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00036   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00037   
00038   SSD130x       Monochrom OLED Controller
00039   SSD131x       Character OLED Controller
00040   SSD132x       Graylevel OLED Controller
00041   SSD1331       Color OLED Controller       
00042 
00043 */
00044 
00045 #include "u8g.h"
00046 
00047 #define WIDTH 96
00048 #define HEIGHT 96
00049 #define XOFFSET 8
00050 
00051 /*  
00052   http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96
00053 */
00054 static const uint8_t u8g_dev_ssd1327_2bit_96x96_init_seq[] PROGMEM = {
00055   U8G_ESC_DLY(10),              /* delay 10 ms */
00056   U8G_ESC_CS(0),                 /* disable chip */
00057   U8G_ESC_ADR(0),               /* instruction mode */
00058   U8G_ESC_RST(1),               /* do reset low pulse with (1*16)+2 milliseconds */
00059   U8G_ESC_CS(1),                /* enable chip */
00060   0x0fd, 0x012,         /* unlock display, usually not required because the display is unlocked after reset */
00061   0x0ae,                        /* display off, sleep mode */
00062   0x0a8, 0x05f,         /* multiplex ratio: 0x05f * 1/64 duty */
00063   0x0a1, 0x000,                 /* display start line */
00064   0x0a2, 0x060,                 /* display offset, shift mapping ram counter */
00065   //0x0a2, 0x04c,                   /* NHD: display offset, shift mapping ram counter */
00066   0x0a0, 0x046,             /* remap configuration, vertical address increment, enable nibble remap (upper nibble is left) */
00067   //0x0a0, 0x056,           /* NHD: remap configuration, vertical address increment, enable nibble remap (upper nibble is left) */
00068   0x0ab, 0x001,         /* Enable internal VDD regulator (RESET) */
00069   0x081, 0x053,                 /* contrast, brightness, 0..128, Newhaven: 0x040, LY120 0x053, 0x070 seems also ok */
00070   0x0b1, 0x051,                 /* phase length */
00071   0x0b3, 0x001,                 /* set display clock divide ratio/oscillator frequency */
00072   0x0b9,                    /* use linear lookup table */
00073 #if 0
00074   0x0b8,                                /* set gray scale table */
00075       //0x01, 0x011, 0x022, 0x032, 0x043, 0x054, 0x065, 0x076,
00076       0x01, 0x011, 0x022, 0x032, 0x043, 0x054, 0x077, 0x077,            // 4L mode uses 0, 2, 4, 7
00077 #endif  
00078   0x0bc, 0x008,                     /* pre-charge voltage level */
00079   0x0be, 0x007,                         /* VCOMH voltage */
00080   0x0b6, 0x001,         /* second precharge */
00081   0x0d5, 0x062,         /* enable second precharge, internal vsl (bit0 = 0) */
00082   
00083 #if 0
00084   // the following commands are not used by the SeeedGrayOLED sequence */
00085   0x0ad, 0x002,                     /* master configuration: disable embedded DC-DC, enable internal VCOMH */
00086   0x086,                                /* full current range (0x084, 0x085, 0x086) */
00087   0x0b2, 0x051,                    /* frame frequency (row period) */
00088   0x0b4, 0x002,                    /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
00089   0x0b0, 0x028,                    /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
00090   0x0bf, 0x002|0x00d,           /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
00091 #endif 
00092 
00093   0x0a5,                                 /* all pixel on */
00094   //0x02e,                  /* no scroll (according to SeeedGrayOLED sequence) */
00095   0x0af,                                  /* display on */
00096   U8G_ESC_DLY(100),             /* delay 100 ms */
00097   0x0a4,                                 /* normal display mode */
00098   U8G_ESC_DLY(100),             /* delay 100 ms */
00099   0x0a5,                                 /* all pixel on */
00100   0x0af,                                  /* display on */
00101   U8G_ESC_DLY(100),             /* delay 100 ms */
00102   0x0a4,                                 /* normal display mode */
00103   
00104   0x015,       /* column address... */
00105   0x008,       /* start at column 8, special for the LY120 ??? */
00106   0x037,       /* end at column 55, note: there are two pixel in one column */
00107   
00108   0x075,       /* row address... */
00109   0x008,       
00110   0x05f,       
00111   
00112   U8G_ESC_ADR(1),               /* data mode */
00113   0x000f, 0x000f, 0x0000, 0x0000, 0x000f,0x000f,0x0000,0x0000,
00114   0x000f, 0x000f, 0x0000, 0x0000, 0x000f,0x000f,0x0000,0x0000,
00115   0x000f, 0x000f, 0x0000, 0x0000, 0x000f,0x000f,0x0000,0x0000,
00116   0x000f, 0x000f, 0x0000, 0x0000, 0x000f,0x000f,0x0000,0x0000,
00117   
00118   U8G_ESC_CS(0),             /* disable chip */
00119   U8G_ESC_END                /* end of sequence */
00120 };
00121 
00122 static const uint8_t u8g_dev_ssd1327_2bit_96x96_prepare_page_seq[] PROGMEM = {
00123   U8G_ESC_ADR(0),               /* instruction mode */
00124   U8G_ESC_CS(1),                /* enable chip */
00125   0x015,       /* column address... */
00126   XOFFSET,       /* start at column 8, special for the LY120 ??? */
00127   0x037,       /* end at column 55, note: there are two pixel in one column */
00128   0x075,       /* row address... */
00129   U8G_ESC_END                /* end of sequence */
00130 };
00131 
00132 
00133 static void u8g_dev_ssd1327_2bit_prepare_page(u8g_t *u8g, u8g_dev_t *dev)
00134 {
00135   uint8_t page = ((u8g_pb_t *)(dev->dev_mem))->p.page;
00136   
00137   u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1327_2bit_96x96_prepare_page_seq);
00138   
00139   page <<= 2;
00140   u8g_WriteByte(u8g, dev, page);       /* start at the selected page */
00141   page += 3;
00142   u8g_WriteByte(u8g, dev, page);       /* end within the selected page */  
00143   
00144   u8g_SetAddress(u8g, dev, 1);          /* data mode */
00145 }
00146 
00147 static void u8g_dev_ssd1327_2bit_2x_prepare_page(u8g_t *u8g, u8g_dev_t *dev, uint8_t is_odd)
00148 {
00149   uint8_t page = ((u8g_pb_t *)(dev->dev_mem))->p.page;
00150   
00151   u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1327_2bit_96x96_prepare_page_seq);
00152   
00153   page <<= 1;
00154   page += is_odd;
00155   
00156   page <<= 2;
00157   u8g_WriteByte(u8g, dev, page);       /* start at the selected page */
00158   page += 3;
00159   u8g_WriteByte(u8g, dev, page);       /* end within the selected page */  
00160   
00161   u8g_SetAddress(u8g, dev, 1);          /* data mode */
00162 }
00163 
00164 /* assumes row autoincrement and activated nibble remap */
00165 static  void u8g_dev_ssd1327_2bit_write_4_pixel(u8g_t *u8g, u8g_dev_t *dev, uint8_t left, uint8_t right)
00166 {
00167   uint8_t d, tmp, cnt;
00168   static uint8_t buf[4];
00169   buf[0] = 0;
00170   buf[1] = 0;
00171   buf[2] = 0;
00172   buf[3] = 0;
00173   cnt = 0;
00174   do 
00175   {
00176     if ( left == 0 && right == 0 )
00177       break;
00178     d = left;
00179     d &= 3;
00180     d <<= 4;    
00181     tmp = right;    
00182     tmp &= 3;
00183     d |= tmp;
00184     d <<= 2;
00185     buf[cnt] = d;
00186     left >>= 2;
00187     right >>= 2;
00188     cnt++;
00189   }while ( cnt < 4 );
00190   u8g_WriteSequence(u8g, dev, 4, buf);
00191 }
00192 
00193 static void u8g_dev_ssd1327_2bit_write_buffer(u8g_t *u8g, u8g_dev_t *dev)
00194 {
00195   uint8_t cnt, left, right;
00196   uint8_t *ptr;
00197   u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
00198   
00199   cnt = pb->width;
00200   cnt >>= 1;
00201   ptr = pb->buf;
00202   do
00203   {
00204     left = *ptr++;
00205     right = *ptr++;
00206     u8g_dev_ssd1327_2bit_write_4_pixel(u8g, dev, left, right);
00207     cnt--;
00208   } while( cnt > 0 );
00209 }
00210 
00211 static void u8g_dev_ssd1327_2bit_2x_write_buffer(u8g_t *u8g, u8g_dev_t *dev, uint8_t is_odd)
00212 {
00213   uint8_t cnt, left, right;
00214   uint8_t *ptr;
00215   u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
00216   
00217   ptr = pb->buf;
00218   cnt = pb->width;
00219   if ( is_odd )
00220     ptr += cnt;
00221   cnt >>= 1;
00222   do
00223   {
00224     left = *ptr++;
00225     right = *ptr++;
00226     u8g_dev_ssd1327_2bit_write_4_pixel(u8g, dev, left, right);
00227     cnt--;
00228   } while( cnt > 0 );
00229 }
00230 
00231 uint8_t u8g_dev_ssd1327_96x96_gr_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
00232 {
00233   switch(msg)
00234   {
00235     case U8G_DEV_MSG_INIT:
00236       u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS);
00237       u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1327_2bit_96x96_init_seq);
00238       break;
00239     case U8G_DEV_MSG_STOP:
00240       break;
00241     case U8G_DEV_MSG_PAGE_NEXT:
00242       {
00243         u8g_dev_ssd1327_2bit_prepare_page(u8g, dev);
00244         u8g_dev_ssd1327_2bit_write_buffer(u8g, dev);
00245         u8g_SetChipSelect(u8g, dev, 0);        
00246       }
00247       break;
00248     case U8G_DEV_MSG_CONTRAST:
00249       u8g_SetChipSelect(u8g, dev, 1);
00250       u8g_SetAddress(u8g, dev, 0);          /* instruction mode */
00251       u8g_WriteByte(u8g, dev, 0x081);
00252       u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 1);
00253       u8g_SetChipSelect(u8g, dev, 0);      
00254       return 1;
00255   }
00256   return u8g_dev_pb8v2_base_fn(u8g, dev, msg, arg);
00257 }
00258 
00259 uint8_t u8g_dev_ssd1327_96x96_2x_gr_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
00260 {
00261   switch(msg)
00262   {
00263     case U8G_DEV_MSG_INIT:
00264       u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS);
00265       u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1327_2bit_96x96_init_seq);
00266       break;
00267     case U8G_DEV_MSG_STOP:
00268       break;
00269     case U8G_DEV_MSG_PAGE_NEXT:
00270       {
00271         u8g_dev_ssd1327_2bit_2x_prepare_page(u8g, dev, 0);
00272         u8g_dev_ssd1327_2bit_2x_write_buffer(u8g, dev, 0);
00273         u8g_dev_ssd1327_2bit_2x_prepare_page(u8g, dev, 1);
00274         u8g_dev_ssd1327_2bit_2x_write_buffer(u8g, dev, 1);
00275         u8g_SetChipSelect(u8g, dev, 0);        
00276       }
00277       break;
00278     case U8G_DEV_MSG_CONTRAST:
00279       u8g_SetChipSelect(u8g, dev, 1);
00280       u8g_SetAddress(u8g, dev, 0);          /* instruction mode */
00281       u8g_WriteByte(u8g, dev, 0x081);
00282       u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 1);
00283       u8g_SetChipSelect(u8g, dev, 0);      
00284       return 1;
00285   }
00286   return u8g_dev_pb16v2_base_fn(u8g, dev, msg, arg);
00287 }
00288 
00289 U8G_PB_DEV(u8g_dev_ssd1327_96x96_gr_sw_spi , WIDTH, HEIGHT, 4, u8g_dev_ssd1327_96x96_gr_fn, U8G_COM_SW_SPI);
00290 U8G_PB_DEV(u8g_dev_ssd1327_96x96_gr_hw_spi , WIDTH, HEIGHT, 4, u8g_dev_ssd1327_96x96_gr_fn, U8G_COM_HW_SPI);
00291 U8G_PB_DEV(u8g_dev_ssd1327_96x96_gr_i2c , WIDTH, HEIGHT, 4, u8g_dev_ssd1327_96x96_gr_fn, U8G_COM_SSD_I2C);
00292 
00293 #define DWIDTH (2*WIDTH)
00294 uint8_t u8g_dev_ssd1327_96x96_2x_buf[DWIDTH] U8G_NOCOMMON ; 
00295 u8g_pb_t u8g_dev_ssd1327_96x96_2x_pb = { {8, HEIGHT, 0, 0, 0},  WIDTH, u8g_dev_ssd1327_96x96_2x_buf}; 
00296 u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_sw_spi = { u8g_dev_ssd1327_96x96_2x_gr_fn, &u8g_dev_ssd1327_96x96_2x_pb, U8G_COM_SW_SPI };
00297 u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_hw_spi = { u8g_dev_ssd1327_96x96_2x_gr_fn, &u8g_dev_ssd1327_96x96_2x_pb, U8G_COM_HW_SPI };
00298 u8g_dev_t u8g_dev_ssd1327_96x96_2x_gr_i2c = { u8g_dev_ssd1327_96x96_2x_gr_fn, &u8g_dev_ssd1327_96x96_2x_pb, U8G_COM_SSD_I2C };
00299 
00300