Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
u8g_dev_ssd1322_nhd31oled_gr.c
00001 /* 00002 00003 u8g_dev_ssd1322_nhd31oled_gr.c 00004 00005 2-Bit (4L) Driver for SSD1322 Controller (OLED Display) 00006 Tested with NHD-3.12-25664 00007 00008 Universal 8bit Graphics Library 00009 00010 Copyright (c) 2012, olikraus@gmail.com 00011 All rights reserved. 00012 00013 Redistribution and use in source and binary forms, with or without modification, 00014 are permitted provided that the following conditions are met: 00015 00016 * Redistributions of source code must retain the above copyright notice, this list 00017 of conditions and the following disclaimer. 00018 00019 * Redistributions in binary form must reproduce the above copyright notice, this 00020 list of conditions and the following disclaimer in the documentation and/or other 00021 materials provided with the distribution. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 00024 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 00025 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00026 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 00028 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00029 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00030 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00031 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00033 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00034 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00035 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 00037 SSD130x Monochrom OLED Controller 00038 SSD131x Character OLED Controller 00039 SSD132x Graylevel OLED Controller 00040 SSD1331 Color OLED Controller 00041 00042 */ 00043 00044 #include "u8g.h" 00045 00046 /* width must be multiple of 8, largest value is 248 unless u8g 16 bit mode is enabled */ 00047 #if defined(U8G_16BIT) 00048 #define WIDTH 256 00049 #else 00050 #define WIDTH 248 00051 #endif 00052 #define HEIGHT 64 00053 //#define PAGE_HEIGHT 8 00054 00055 /* 00056 http://www.newhavendisplay.com/app_notes/OLED_25664.txt 00057 http://www.newhavendisplay.com/forum/viewtopic.php?f=15&t=3758 00058 */ 00059 00060 static const uint8_t u8g_dev_ssd1322_2bit_nhd_312_init_seq[] PROGMEM = { 00061 U8G_ESC_DLY(10), /* delay 10 ms */ 00062 U8G_ESC_CS(0), /* disable chip */ 00063 U8G_ESC_ADR(0), /* instruction mode */ 00064 U8G_ESC_RST(1), /* do reset low pulse with (1*16)+2 milliseconds */ 00065 U8G_ESC_CS(1), /* enable chip */ 00066 00067 U8G_ESC_DLY(100), /* delay 100 ms */ 00068 U8G_ESC_DLY(100), /* delay 100 ms */ 00069 00070 U8G_ESC_ADR(0), /* instruction mode */ 00071 0x0fd, /* lock command */ 00072 U8G_ESC_ADR(1), /* data mode */ 00073 0x012, /* unlock */ 00074 00075 U8G_ESC_ADR(0), /* instruction mode */ 00076 0x0ae, /* display off, sleep mode */ 00077 00078 U8G_ESC_ADR(0), /* instruction mode */ 00079 0x0b3, 00080 U8G_ESC_ADR(1), /* data mode */ 00081 0x091, /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */ 00082 00083 U8G_ESC_ADR(0), /* instruction mode */ 00084 0x0ca, /* multiplex ratio */ 00085 U8G_ESC_ADR(1), /* data mode */ 00086 0x03f, /* 1/64 Duty (0x0F~0x3F) */ 00087 00088 U8G_ESC_ADR(0), /* instruction mode */ 00089 0x0a2, 00090 U8G_ESC_ADR(1), /* data mode */ 00091 0x000, /* display offset, shift mapping ram counter */ 00092 00093 U8G_ESC_ADR(0), /* instruction mode */ 00094 0x0a1, 00095 U8G_ESC_ADR(1), /* data mode */ 00096 0x000, /* display start line */ 00097 00098 U8G_ESC_ADR(0), /* instruction mode */ 00099 0x0a0, /* Set Re-Map / Dual COM Line Mode */ 00100 U8G_ESC_ADR(1), /* data mode */ 00101 0x014, /* was 0x014 */ 00102 0x011, /* was 0x011 */ 00103 00104 U8G_ESC_ADR(0), /* instruction mode */ 00105 0x0ab, 00106 U8G_ESC_ADR(1), /* data mode */ 00107 0x001, /* Enable Internal VDD Regulator */ 00108 00109 U8G_ESC_ADR(0), /* instruction mode */ 00110 0x0b4, /* Display Enhancement A */ 00111 U8G_ESC_ADR(1), /* data mode */ 00112 0x0a0, 00113 0x005|0x0fd, 00114 00115 U8G_ESC_ADR(0), /* instruction mode */ 00116 0x0c1, /* contrast */ 00117 U8G_ESC_ADR(1), /* data mode */ 00118 0x09f, 00119 00120 U8G_ESC_ADR(0), /* instruction mode */ 00121 0x0c7, /* Set Scale Factor of Segment Output Current Control */ 00122 U8G_ESC_ADR(1), /* data mode */ 00123 0x00f, 00124 00125 U8G_ESC_ADR(0), /* instruction mode */ 00126 0x0b9, /* linear gray scale */ 00127 00128 U8G_ESC_ADR(0), /* instruction mode */ 00129 0x0b1, /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment */ 00130 U8G_ESC_ADR(1), /* data mode */ 00131 0x0e2, 00132 00133 U8G_ESC_ADR(0), /* instruction mode */ 00134 0x0d1, /* Display Enhancement B */ 00135 U8G_ESC_ADR(1), /* data mode */ 00136 0x082|0x020, 00137 0x020, 00138 00139 U8G_ESC_ADR(0), /* instruction mode */ 00140 0x0bb, /* precharge voltage */ 00141 U8G_ESC_ADR(1), /* data mode */ 00142 0x01f, 00143 00144 U8G_ESC_ADR(0), /* instruction mode */ 00145 0x0b6, /* precharge period */ 00146 U8G_ESC_ADR(1), /* data mode */ 00147 0x008, 00148 00149 U8G_ESC_ADR(0), /* instruction mode */ 00150 0x0be, /* vcomh */ 00151 U8G_ESC_ADR(1), /* data mode */ 00152 0x007, 00153 00154 U8G_ESC_ADR(0), /* instruction mode */ 00155 0x0a6, /* normal display */ 00156 00157 U8G_ESC_ADR(0), /* instruction mode */ 00158 0x0a9, /* exit partial display */ 00159 00160 U8G_ESC_ADR(0), /* instruction mode */ 00161 0x0af, /* display on */ 00162 00163 00164 U8G_ESC_CS(0), /* disable chip */ 00165 U8G_ESC_END /* end of sequence */ 00166 }; 00167 00168 static const uint8_t u8g_dev_ssd1322_2bit_nhd_312_prepare_page_seq[] PROGMEM = { 00169 U8G_ESC_ADR(0), /* instruction mode */ 00170 U8G_ESC_CS(1), /* enable chip */ 00171 0x015, /* column address... */ 00172 U8G_ESC_ADR(1), /* data mode */ 00173 0x01c, /* start at column 0 */ 00174 0x05b, /* end column */ 00175 U8G_ESC_ADR(0), /* instruction mode */ 00176 0x075, /* row address... */ 00177 U8G_ESC_ADR(1), /* data mode */ 00178 U8G_ESC_END /* end of sequence */ 00179 }; 00180 00181 static void u8g_dev_ssd1322_2bit_prepare_row(u8g_t *u8g, u8g_dev_t *dev, uint8_t delta_row) 00182 { 00183 uint8_t row = ((u8g_pb_t *)(dev->dev_mem))->p.page; 00184 00185 row *= ((u8g_pb_t *)(dev->dev_mem))->p.page_height; 00186 row += delta_row; 00187 00188 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1322_2bit_nhd_312_prepare_page_seq); 00189 00190 u8g_WriteByte(u8g, dev, row); /* start at the selected row */ 00191 u8g_WriteByte(u8g, dev, row+1); /* end within the selected row */ 00192 00193 u8g_SetAddress(u8g, dev, 0); /* instruction mode mode */ 00194 u8g_WriteByte(u8g, dev, 0x05c); /* write to ram */ 00195 u8g_SetAddress(u8g, dev, 1); /* data mode */ 00196 } 00197 00198 static const uint8_t u8g_dev_ssd13xx_sleep_on[] PROGMEM = { 00199 U8G_ESC_ADR(0), /* instruction mode */ 00200 U8G_ESC_CS(1), /* enable chip */ 00201 0x0ae, /* display off */ 00202 U8G_ESC_CS(1), /* disable chip */ 00203 U8G_ESC_END /* end of sequence */ 00204 }; 00205 00206 static const uint8_t u8g_dev_ssd13xx_sleep_off[] PROGMEM = { 00207 U8G_ESC_ADR(0), /* instruction mode */ 00208 U8G_ESC_CS(1), /* enable chip */ 00209 0x0af, /* display on */ 00210 U8G_ESC_DLY(50), /* delay 50 ms */ 00211 U8G_ESC_CS(1), /* disable chip */ 00212 U8G_ESC_END /* end of sequence */ 00213 }; 00214 00215 uint8_t u8g_dev_ssd1322_nhd31oled_gr_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) 00216 { 00217 switch(msg) 00218 { 00219 case U8G_DEV_MSG_INIT: 00220 u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); 00221 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1322_2bit_nhd_312_init_seq); 00222 break; 00223 case U8G_DEV_MSG_STOP: 00224 break; 00225 case U8G_DEV_MSG_PAGE_NEXT: 00226 { 00227 uint8_t i; 00228 u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); 00229 uint8_t *p = pb->buf; 00230 u8g_uint_t cnt; 00231 cnt = pb->width; 00232 cnt >>= 2; 00233 00234 for( i = 0; i < pb->p.page_height; i++ ) 00235 { 00236 u8g_dev_ssd1322_2bit_prepare_row(u8g, dev, i); /* this will also enable chip select */ 00237 #if !defined(U8G_16BIT) 00238 u8g_WriteByte(u8g, dev, 0x00); 00239 u8g_WriteByte(u8g, dev, 0x00); 00240 #endif 00241 u8g_WriteSequence4LTo16GrDevice(u8g, dev, cnt, p); 00242 #if !defined(U8G_16BIT) 00243 u8g_WriteByte(u8g, dev, 0x00); 00244 u8g_WriteByte(u8g, dev, 0x00); 00245 #endif 00246 u8g_SetChipSelect(u8g, dev, 0); 00247 p+=cnt; 00248 } 00249 } 00250 break; 00251 case U8G_DEV_MSG_CONTRAST: 00252 u8g_SetChipSelect(u8g, dev, 1); 00253 u8g_SetAddress(u8g, dev, 0); /* instruction mode */ 00254 u8g_WriteByte(u8g, dev, 0x081); 00255 u8g_SetAddress(u8g, dev, 1); /* data mode */ 00256 u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 1); 00257 u8g_SetChipSelect(u8g, dev, 0); 00258 break; 00259 case U8G_DEV_MSG_SLEEP_ON: 00260 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); 00261 return 1; 00262 case U8G_DEV_MSG_SLEEP_OFF: 00263 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); 00264 return 1; 00265 } 00266 return u8g_dev_pb8h2_base_fn(u8g, dev, msg, arg); 00267 } 00268 00269 00270 uint8_t u8g_dev_ssd1322_nhd31oled_2x_gr_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) 00271 { 00272 switch(msg) 00273 { 00274 case U8G_DEV_MSG_INIT: 00275 u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); 00276 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd1322_2bit_nhd_312_init_seq); 00277 break; 00278 case U8G_DEV_MSG_STOP: 00279 break; 00280 case U8G_DEV_MSG_PAGE_NEXT: 00281 { 00282 uint8_t i; 00283 u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); 00284 uint8_t *p = pb->buf; 00285 u8g_uint_t cnt; 00286 cnt = pb->width; 00287 cnt >>= 3; 00288 00289 for( i = 0; i < pb->p.page_height; i++ ) 00290 { 00291 u8g_dev_ssd1322_2bit_prepare_row(u8g, dev, i); /* this will also enable chip select */ 00292 #if !defined(U8G_16BIT) 00293 u8g_WriteByte(u8g, dev, 0x00); 00294 u8g_WriteByte(u8g, dev, 0x00); 00295 #endif 00296 u8g_WriteSequence4LTo16GrDevice(u8g, dev, cnt, p); 00297 #if !defined(U8G_16BIT) 00298 u8g_WriteByte(u8g, dev, 0x00); 00299 u8g_WriteByte(u8g, dev, 0x00); 00300 #endif 00301 u8g_SetChipSelect(u8g, dev, 0); 00302 p+=cnt; 00303 } 00304 } 00305 break; 00306 case U8G_DEV_MSG_CONTRAST: 00307 u8g_SetChipSelect(u8g, dev, 1); 00308 u8g_SetAddress(u8g, dev, 0); /* instruction mode */ 00309 u8g_WriteByte(u8g, dev, 0x081); 00310 u8g_SetAddress(u8g, dev, 1); /* data mode */ 00311 u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 1); 00312 u8g_SetChipSelect(u8g, dev, 0); 00313 break; 00314 case U8G_DEV_MSG_SLEEP_ON: 00315 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_on); 00316 return 1; 00317 case U8G_DEV_MSG_SLEEP_OFF: 00318 u8g_WriteEscSeqP(u8g, dev, u8g_dev_ssd13xx_sleep_off); 00319 return 1; 00320 } 00321 return u8g_dev_pb16h2_base_fn(u8g, dev, msg, arg); 00322 } 00323 00324 00325 U8G_PB_DEV(u8g_dev_ssd1322_nhd31oled_gr_sw_spi , WIDTH, HEIGHT, 4, u8g_dev_ssd1322_nhd31oled_gr_fn, U8G_COM_SW_SPI); 00326 U8G_PB_DEV(u8g_dev_ssd1322_nhd31oled_gr_hw_spi , WIDTH, HEIGHT, 4, u8g_dev_ssd1322_nhd31oled_gr_fn, U8G_COM_HW_SPI); 00327 U8G_PB_DEV(u8g_dev_ssd1322_nhd31oled_gr_parallel , WIDTH, HEIGHT, 4, u8g_dev_ssd1322_nhd31oled_gr_fn, U8G_COM_FAST_PARALLEL); 00328 00329 00330 #define DWIDTH (WIDTH*2) 00331 uint8_t u8g_dev_ssd1322_nhd31oled_2x_gr_buf[DWIDTH] U8G_NOCOMMON ; 00332 u8g_pb_t u8g_dev_ssd1322_nhd31oled_2x_gr_pb = { {8, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_ssd1322_nhd31oled_2x_gr_buf}; 00333 u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_gr_sw_spi = { u8g_dev_ssd1322_nhd31oled_2x_gr_fn, &u8g_dev_ssd1322_nhd31oled_2x_gr_pb, U8G_COM_SW_SPI }; 00334 u8g_dev_t u8g_dev_ssd1322_nhd31oled_2x_gr_hw_spi = { u8g_dev_ssd1322_nhd31oled_2x_gr_fn, &u8g_dev_ssd1322_nhd31oled_2x_gr_pb, U8G_COM_HW_SPI }; 00335 00336
Generated on Tue Jul 12 2022 17:30:57 by
1.7.2