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.
DogLCD.cpp
00001 #include "DogLCD.h" 00002 00003 // macro to make sure x falls into range from low to high (inclusive) 00004 #define CLAMP(x, low, high) { if ( (x) < (low) ) x = (low); if ( (x) > (high) ) x = (high); } while (0); 00005 00006 void DogLCD::_send_commands(const unsigned char* buf, size_t size) 00007 { 00008 // for commands, A0 is low 00009 _spi.format(8,0); 00010 _spi.frequency(10000000); 00011 _cs = 0; 00012 _a0 = 0; 00013 while ( size-- > 0 ) 00014 _spi.write(*buf++); 00015 _cs = 1; 00016 } 00017 00018 void DogLCD::_send_data(const unsigned char* buf, size_t size) 00019 { 00020 // for data, A0 is high 00021 _spi.format(8,0); 00022 _spi.frequency(10000000); 00023 _cs = 0; 00024 _a0 = 1; 00025 while ( size-- > 0 ) 00026 _spi.write(*buf++); 00027 _cs = 1; 00028 _a0 = 0; 00029 } 00030 00031 // set column and page number 00032 void DogLCD::_set_xy(int x, int y) 00033 { 00034 //printf("_set_xy(%d,%d)\n", x, y); 00035 CLAMP(x, 0, LCDWIDTH-1); 00036 CLAMP(y, 0, LCDPAGES-1); 00037 unsigned char cmd[3]; 00038 cmd[0] = 0xB0 | (y&0xF); 00039 cmd[1] = 0x10 | (x&0xF); 00040 cmd[2] = (x>>4)&0xF; 00041 _send_commands(cmd, 3); 00042 } 00043 00044 // initialize and turn on the display 00045 void DogLCD::init() 00046 { 00047 const unsigned char init_seq[] = { 00048 0x40, //Display start line 0 00049 0xa1, //ADC reverse 00050 0xc0, //Normal COM0...COM63 00051 0xa6, //Display normal 00052 0xa2, //Set Bias 1/9 (Duty 1/65) 00053 0x2f, //Booster, Regulator and Follower On 00054 0xf8, //Set internal Booster to 4x 00055 0x00, 00056 0x27, //Contrast set 00057 0x81, 00058 0x16, 00059 0xac, //No indicator 00060 0x00, 00061 0xaf, //Display on 00062 }; 00063 //printf("Reset=L\n"); 00064 _reset = 0; 00065 //printf("Power=H\n"); 00066 _power = 1; 00067 //wait_ms(1); 00068 //printf("Reset=H\n"); 00069 _reset = 1; 00070 //wait(5); 00071 //printf("Sending init commands\n"); 00072 _send_commands(init_seq, sizeof(init_seq)); 00073 } 00074 00075 void DogLCD::send_pic(const unsigned char* data) 00076 { 00077 //printf("Sending picture\n"); 00078 for (int i=0; i<LCDPAGES; i++) 00079 { 00080 _set_xy(0, i); 00081 _send_data(data + i*LCDWIDTH, LCDWIDTH); 00082 } 00083 } 00084 00085 void DogLCD::clear_screen() 00086 { 00087 //printf("Clear screen\n"); 00088 memset(_framebuffer, 0, sizeof(_framebuffer)); 00089 if ( _updating == 0 ) 00090 { 00091 send_pic(_framebuffer); 00092 } 00093 } 00094 00095 void DogLCD::all_on(bool on) 00096 { 00097 //printf("Sending all on %d\n", on); 00098 unsigned char cmd = 0xA4 | (on ? 1 : 0); 00099 _send_commands(&cmd, 1); 00100 } 00101 00102 void DogLCD::pixel(int x, int y, int colour) 00103 { 00104 CLAMP(x, 0, LCDWIDTH-1); 00105 CLAMP(y, 0, LCDHEIGHT-1); 00106 int page = y / 8; 00107 unsigned char mask = 1<<(y%8); 00108 unsigned char *byte = &_framebuffer[page*LCDWIDTH + x]; 00109 if ( colour == 0 ) 00110 *byte &= ~mask; // clear pixel 00111 else 00112 *byte |= mask; // set pixel 00113 if ( !_updating ) 00114 { 00115 _set_xy(x, page); 00116 _send_data(byte, 1); 00117 } 00118 } 00119 00120 void DogLCD::fill(int x, int y, int width, int height, int colour) 00121 { 00122 /* 00123 If we need to fill partial pages at the top: 00124 00125 ......+---+---+..... 00126 ^ | = | = | = : don't touch 00127 | | = | = | * : update 00128 y%8 | = | = | 00129 | | = | = | 00130 v | = | = | 00131 y----> | * | * | 00132 | * | * | 00133 | * | * | 00134 +---+---+ 00135 */ 00136 //printf("fill(x=%d, y=%d, width=%d, height=%d, colour=%x)\n", x, y, width, height, colour); 00137 CLAMP(x, 0, LCDWIDTH-1); 00138 CLAMP(y, 0, LCDHEIGHT-1); 00139 CLAMP(width, 0, LCDWIDTH - x); 00140 CLAMP(height, 0, LCDHEIGHT - y); 00141 int page = y/8; 00142 int firstpage = page; 00143 int partpage = y%8; 00144 if ( partpage != 0 ) 00145 { 00146 // we need to process partial bytes in the top page 00147 unsigned char mask = (1<<partpage) - 1; // this mask has 1s for bits we need to leave 00148 unsigned char *bytes = &_framebuffer[page*LCDWIDTH + x]; 00149 for ( int i = 0; i < width; i++, bytes++ ) 00150 { 00151 // clear "our" bits 00152 *bytes &= mask; 00153 if ( colour != 0 ) 00154 *bytes |= ~mask; // set our bits 00155 } 00156 height -= partpage; 00157 page++; 00158 } 00159 while ( height >= 8 ) 00160 { 00161 memset(&_framebuffer[page*LCDWIDTH + x], colour == 0 ? 0 : 0xFF, width); 00162 page++; 00163 height -= 8; 00164 } 00165 if ( height != 0 ) 00166 { 00167 // we need to process partial bytes in the bottom page 00168 unsigned char mask = ~((1<<partpage) - 1); // this mask has 1s for bits we need to leave 00169 unsigned char *bytes = &_framebuffer[page*LCDWIDTH + x]; 00170 for ( int i = 0; i < width; i++, bytes++ ) 00171 { 00172 // clear "our" bits 00173 *bytes &= mask; 00174 if ( colour != 0 ) 00175 *bytes |= ~mask; // set our bits 00176 } 00177 page++; 00178 } 00179 //printf("_updating=%d\n", _updating); 00180 if ( !_updating ) 00181 { 00182 int laststpage = page; 00183 for ( page = firstpage; page < laststpage; page++) 00184 { 00185 //printf("setting x=%d, page=%d\n", x, page); 00186 _set_xy(x, page); 00187 //printf("sending %d bytes at offset %x\n", width, page*LCDWIDTH + x); 00188 _send_data(&_framebuffer[page*LCDWIDTH + x], width); 00189 } 00190 } 00191 } 00192 00193 void DogLCD::beginupdate() 00194 { 00195 _updating++; 00196 //printf("beginupdate: %d\n", _updating); 00197 } 00198 00199 void DogLCD::endupdate() 00200 { 00201 _updating--; 00202 //printf("endupdate: %d\n", _updating); 00203 if ( _updating == 0 ) 00204 { 00205 send_pic(_framebuffer); 00206 } 00207 }
Generated on Fri Jul 15 2022 20:49:26 by
1.7.2