Fork of Chris Styles' C12832 LCD driver

Dependents:   co657_lcdplay co657_nrf52_beacons door_lock co657_IoT

Fork of C12832 by Chris Styles

Committer:
co657_frmb
Date:
Fri Nov 27 22:45:20 2015 +0000
Revision:
22:7accdf0bfc18
Parent:
20:dbee79303f9a
Some updates for drawing optimisation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chris 15:67dfa5550b73 1 /* mbed library for the mbed Lab Board 128*32 pixel LCD
chris 15:67dfa5550b73 2 * use C12832 controller
chris 15:67dfa5550b73 3 * Copyright (c) 2012 Peter Drescher - DC2PD
chris 15:67dfa5550b73 4 * Released under the MIT License: http://mbed.org/license/mit
chris 15:67dfa5550b73 5 *
chris 15:67dfa5550b73 6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
chris 15:67dfa5550b73 7 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
chris 15:67dfa5550b73 8 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
chris 15:67dfa5550b73 9 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
chris 15:67dfa5550b73 10 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
chris 15:67dfa5550b73 11 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
chris 15:67dfa5550b73 12 * THE SOFTWARE.
chris 15:67dfa5550b73 13 */
chris 15:67dfa5550b73 14
chris 15:67dfa5550b73 15 // 13.10.12 initial design
chris 15:67dfa5550b73 16 // 25.10.12 add autorefresh of screen
chris 15:67dfa5550b73 17 // 25.10.12 add standart font
chris 15:67dfa5550b73 18 // 20.12.12 add bitmap graphics
chris 15:67dfa5550b73 19
co657_frmb 18:8c294697c901 20 // Assorted changes/updates by Fred Barnes, University of Kent <frmb@kent.ac.uk>
co657_frmb 18:8c294697c901 21 // 31.10.15 minor bugfixes, some drawing optimisation
co657_frmb 18:8c294697c901 22
chris 15:67dfa5550b73 23 // optional defines :
chris 15:67dfa5550b73 24 // #define debug_lcd 1
chris 15:67dfa5550b73 25
chris 15:67dfa5550b73 26 #include "C12832.h"
chris 15:67dfa5550b73 27 #include "mbed.h"
chris 15:67dfa5550b73 28 #include "stdio.h"
chris 15:67dfa5550b73 29 #include "Small_7.h"
chris 15:67dfa5550b73 30
chris 15:67dfa5550b73 31 #define BPP 1 // Bits per pixel
chris 15:67dfa5550b73 32
chris 15:67dfa5550b73 33
chris 16:7de323fa46fe 34 C12832::C12832(PinName mosi, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name)
chris 15:67dfa5550b73 35 : _spi(mosi,NC,sck),_reset(reset),_A0(a0),_CS(ncs),GraphicsDisplay(name)
chris 15:67dfa5550b73 36 {
chris 15:67dfa5550b73 37 orientation = 1;
chris 15:67dfa5550b73 38 draw_mode = NORMAL;
chris 15:67dfa5550b73 39 char_x = 0;
chris 15:67dfa5550b73 40 lcd_reset();
chris 15:67dfa5550b73 41 }
chris 15:67dfa5550b73 42
chris 15:67dfa5550b73 43
chris 16:7de323fa46fe 44 int C12832::width()
chris 15:67dfa5550b73 45 {
chris 15:67dfa5550b73 46 if (orientation == 0 || orientation == 2) return 32;
chris 15:67dfa5550b73 47 else return 128;
chris 15:67dfa5550b73 48 }
chris 15:67dfa5550b73 49
chris 16:7de323fa46fe 50 int C12832::height()
chris 15:67dfa5550b73 51 {
chris 15:67dfa5550b73 52 if (orientation == 0 || orientation == 2) return 128;
chris 15:67dfa5550b73 53 else return 32;
chris 15:67dfa5550b73 54 }
chris 15:67dfa5550b73 55
chris 15:67dfa5550b73 56
chris 16:7de323fa46fe 57 void C12832::invert(unsigned int o)
chris 15:67dfa5550b73 58 {
chris 15:67dfa5550b73 59 if(o == 0) wr_cmd(0xA6);
chris 15:67dfa5550b73 60 else wr_cmd(0xA7);
chris 15:67dfa5550b73 61 }
chris 15:67dfa5550b73 62
chris 15:67dfa5550b73 63
chris 16:7de323fa46fe 64 void C12832::set_contrast(unsigned int o)
chris 15:67dfa5550b73 65 {
chris 15:67dfa5550b73 66 contrast = o;
chris 15:67dfa5550b73 67 wr_cmd(0x81); // set volume
chris 15:67dfa5550b73 68 wr_cmd(o & 0x3F);
chris 15:67dfa5550b73 69 }
chris 15:67dfa5550b73 70
chris 16:7de323fa46fe 71 unsigned int C12832::get_contrast(void)
chris 15:67dfa5550b73 72 {
chris 15:67dfa5550b73 73 return(contrast);
chris 15:67dfa5550b73 74 }
chris 15:67dfa5550b73 75
chris 15:67dfa5550b73 76
chris 15:67dfa5550b73 77 // write command to lcd controller
chris 15:67dfa5550b73 78
chris 16:7de323fa46fe 79 void C12832::wr_cmd(unsigned char cmd)
chris 15:67dfa5550b73 80 {
chris 15:67dfa5550b73 81 _A0 = 0;
chris 15:67dfa5550b73 82 _CS = 0;
chris 15:67dfa5550b73 83 _spi.write(cmd);
chris 15:67dfa5550b73 84 _CS = 1;
chris 15:67dfa5550b73 85 }
chris 15:67dfa5550b73 86
chris 15:67dfa5550b73 87 // write data to lcd controller
chris 15:67dfa5550b73 88
chris 16:7de323fa46fe 89 void C12832::wr_dat(unsigned char dat)
chris 15:67dfa5550b73 90 {
chris 15:67dfa5550b73 91 _A0 = 1;
chris 15:67dfa5550b73 92 _CS = 0;
chris 15:67dfa5550b73 93 _spi.write(dat);
chris 15:67dfa5550b73 94 _CS = 1;
chris 15:67dfa5550b73 95 }
chris 15:67dfa5550b73 96
chris 15:67dfa5550b73 97 // reset and init the lcd controller
chris 15:67dfa5550b73 98
chris 16:7de323fa46fe 99 void C12832::lcd_reset()
chris 15:67dfa5550b73 100 {
chris 15:67dfa5550b73 101
chris 15:67dfa5550b73 102 _spi.format(8,3); // 8 bit spi mode 3
chris 15:67dfa5550b73 103 _spi.frequency(20000000); // 19,2 Mhz SPI clock
chris 15:67dfa5550b73 104 _A0 = 0;
chris 15:67dfa5550b73 105 _CS = 1;
chris 15:67dfa5550b73 106 _reset = 0; // display reset
chris 15:67dfa5550b73 107 wait_us(50);
chris 15:67dfa5550b73 108 _reset = 1; // end reset
chris 15:67dfa5550b73 109 wait_ms(5);
chris 15:67dfa5550b73 110
chris 15:67dfa5550b73 111 /* Start Initial Sequence ----------------------------------------------------*/
chris 15:67dfa5550b73 112
chris 15:67dfa5550b73 113 wr_cmd(0xAE); // display off
chris 15:67dfa5550b73 114 wr_cmd(0xA2); // bias voltage
chris 15:67dfa5550b73 115
chris 15:67dfa5550b73 116 wr_cmd(0xA0);
chris 15:67dfa5550b73 117 wr_cmd(0xC8); // colum normal
chris 15:67dfa5550b73 118
chris 15:67dfa5550b73 119 wr_cmd(0x22); // voltage resistor ratio
chris 15:67dfa5550b73 120 wr_cmd(0x2F); // power on
chris 15:67dfa5550b73 121 //wr_cmd(0xA4); // LCD display ram
chris 15:67dfa5550b73 122 wr_cmd(0x40); // start line = 0
chris 15:67dfa5550b73 123 wr_cmd(0xAF); // display ON
chris 15:67dfa5550b73 124
chris 15:67dfa5550b73 125 wr_cmd(0x81); // set contrast
chris 15:67dfa5550b73 126 wr_cmd(0x17); // set contrast
chris 15:67dfa5550b73 127
chris 15:67dfa5550b73 128 wr_cmd(0xA6); // display normal
chris 15:67dfa5550b73 129
chris 15:67dfa5550b73 130
chris 15:67dfa5550b73 131 // clear and update LCD
chris 15:67dfa5550b73 132 memset(buffer,0x00,512); // clear display buffer
chris 15:67dfa5550b73 133 copy_to_lcd();
chris 15:67dfa5550b73 134 auto_up = 1; // switch on auto update
chris 15:67dfa5550b73 135 // dont do this by default. Make the user call
chris 15:67dfa5550b73 136 //claim(stdout); // redirekt printf to lcd
chris 15:67dfa5550b73 137 locate(0,0);
chris 15:67dfa5550b73 138 set_font((unsigned char*)Small_7); // standart font
chris 15:67dfa5550b73 139 }
chris 15:67dfa5550b73 140
chris 15:67dfa5550b73 141 // set one pixel in buffer
chris 15:67dfa5550b73 142
co657_frmb 18:8c294697c901 143 void C12832::pixel (int x, int y, int color)
chris 15:67dfa5550b73 144 {
co657_frmb 18:8c294697c901 145 if ((x >= 128) || (y >= 32) || (x < 0) || (y < 0)) {
co657_frmb 18:8c294697c901 146 /* out of bounds */
co657_frmb 18:8c294697c901 147 return;
co657_frmb 18:8c294697c901 148 }
chris 15:67dfa5550b73 149
co657_frmb 18:8c294697c901 150 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 151 if (color == 0) {
co657_frmb 19:de1f73b31288 152 buffer[x + ((y & ~7) << 4)] &= ~(1 << (y & 0x07)); // erase pixel
co657_frmb 18:8c294697c901 153 } else {
co657_frmb 19:de1f73b31288 154 buffer[x + ((y & ~7) << 4)] |= (1 << (y & 0x07)); // set pixel
co657_frmb 18:8c294697c901 155 }
chris 15:67dfa5550b73 156 } else { // XOR mode
co657_frmb 18:8c294697c901 157 if (color == 1) {
co657_frmb 19:de1f73b31288 158 buffer[x + ((y & ~7) << 4)] ^= (1 << (y & 0x07)); // xor pixel
co657_frmb 18:8c294697c901 159 }
co657_frmb 18:8c294697c901 160 }
co657_frmb 18:8c294697c901 161 }
co657_frmb 18:8c294697c901 162
co657_frmb 18:8c294697c901 163 /* plots a pixel, but without bounds checking (assumed to be done elsewhere) */
co657_frmb 18:8c294697c901 164 void C12832::pixel_nochk (int x, int y, int colour)
co657_frmb 18:8c294697c901 165 {
co657_frmb 18:8c294697c901 166 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 167 if (colour == 0) {
co657_frmb 19:de1f73b31288 168 buffer[x + ((y & ~7) << 4)] &= ~(1 << (y & 0x07)); // erase pixel
co657_frmb 18:8c294697c901 169 } else {
co657_frmb 19:de1f73b31288 170 buffer[x + ((y & ~7) << 4)] |= (1 << (y & 0x07)); // set pixel
co657_frmb 18:8c294697c901 171 }
co657_frmb 18:8c294697c901 172 } else { // XOR mode
co657_frmb 18:8c294697c901 173 if (colour == 1) {
co657_frmb 19:de1f73b31288 174 buffer[x + ((y & ~7) << 4)] ^= (1 << (y & 0x07)); // xor pixel
co657_frmb 18:8c294697c901 175 }
chris 15:67dfa5550b73 176 }
chris 15:67dfa5550b73 177 }
chris 15:67dfa5550b73 178
chris 15:67dfa5550b73 179 // update lcd
chris 15:67dfa5550b73 180
chris 16:7de323fa46fe 181 void C12832::copy_to_lcd(void)
chris 15:67dfa5550b73 182 {
chris 15:67dfa5550b73 183
chris 15:67dfa5550b73 184 int i=0;
chris 15:67dfa5550b73 185
chris 15:67dfa5550b73 186 //page 0
chris 15:67dfa5550b73 187 wr_cmd(0x00); // set column low nibble 0
chris 15:67dfa5550b73 188 wr_cmd(0x10); // set column hi nibble 0
chris 15:67dfa5550b73 189 wr_cmd(0xB0); // set page address 0
chris 15:67dfa5550b73 190 _A0 = 1;
chris 15:67dfa5550b73 191 for(i=0; i<128; i++) {
chris 15:67dfa5550b73 192 wr_dat(buffer[i]);
chris 15:67dfa5550b73 193 }
chris 15:67dfa5550b73 194
chris 15:67dfa5550b73 195 // page 1
chris 15:67dfa5550b73 196 wr_cmd(0x00); // set column low nibble 0
chris 15:67dfa5550b73 197 wr_cmd(0x10); // set column hi nibble 0
chris 15:67dfa5550b73 198 wr_cmd(0xB1); // set page address 1
chris 15:67dfa5550b73 199 _A0 = 1;
chris 15:67dfa5550b73 200 for(i=128; i<256; i++) {
chris 15:67dfa5550b73 201 wr_dat(buffer[i]);
chris 15:67dfa5550b73 202 }
chris 15:67dfa5550b73 203
chris 15:67dfa5550b73 204 //page 2
chris 15:67dfa5550b73 205 wr_cmd(0x00); // set column low nibble 0
chris 15:67dfa5550b73 206 wr_cmd(0x10); // set column hi nibble 0
chris 15:67dfa5550b73 207 wr_cmd(0xB2); // set page address 2
chris 15:67dfa5550b73 208 _A0 = 1;
chris 15:67dfa5550b73 209 for(i=256; i<384; i++) {
chris 15:67dfa5550b73 210 wr_dat(buffer[i]);
chris 15:67dfa5550b73 211 }
chris 15:67dfa5550b73 212
chris 15:67dfa5550b73 213 //page 3
chris 15:67dfa5550b73 214 wr_cmd(0x00); // set column low nibble 0
chris 15:67dfa5550b73 215 wr_cmd(0x10); // set column hi nibble 0
chris 15:67dfa5550b73 216 wr_cmd(0xB3); // set page address 3
chris 15:67dfa5550b73 217 _A0 = 1;
chris 15:67dfa5550b73 218
chris 15:67dfa5550b73 219 _CS = 0;
chris 15:67dfa5550b73 220
chris 15:67dfa5550b73 221 for(i=384; i<512; i++) {
chris 15:67dfa5550b73 222 wr_dat(buffer[i]);
chris 15:67dfa5550b73 223 }
chris 15:67dfa5550b73 224
chris 15:67dfa5550b73 225 }
chris 15:67dfa5550b73 226
co657_frmb 18:8c294697c901 227 void C12832::cls (void)
chris 15:67dfa5550b73 228 {
co657_frmb 18:8c294697c901 229 memset (buffer, 0x00, 512); // clear display buffer
co657_frmb 18:8c294697c901 230 if (auto_up) {
co657_frmb 18:8c294697c901 231 copy_to_lcd();
co657_frmb 18:8c294697c901 232 }
chris 15:67dfa5550b73 233 }
chris 15:67dfa5550b73 234
co657_frmb 18:8c294697c901 235 /*
co657_frmb 18:8c294697c901 236 * based on Foley and van Dam, Computer Graphics Principles and Practice,
co657_frmb 18:8c294697c901 237 * Second edition in C, Fig 3.8
co657_frmb 18:8c294697c901 238 *
co657_frmb 18:8c294697c901 239 * Adapted back into C from David Wood's occam implementation (line.occ).
co657_frmb 18:8c294697c901 240 */
co657_frmb 18:8c294697c901 241 void C12832::line (int x0, int y0, int x1, int y1, int colour)
chris 15:67dfa5550b73 242 {
co657_frmb 18:8c294697c901 243 int dx = x1 - x0;
co657_frmb 18:8c294697c901 244 int dy = y1 - y0;
co657_frmb 18:8c294697c901 245 int x, y, a_dx, s_x, a_dy, s_y;
co657_frmb 18:8c294697c901 246 int d, strt, diag;
chris 15:67dfa5550b73 247
co657_frmb 18:8c294697c901 248
co657_frmb 18:8c294697c901 249 if (dx == 0) {
co657_frmb 18:8c294697c901 250 /* vertical line */
co657_frmb 18:8c294697c901 251 if (y0 > y1) {
co657_frmb 18:8c294697c901 252 vline (x0, y1, y0, colour);
co657_frmb 18:8c294697c901 253 } else {
co657_frmb 18:8c294697c901 254 vline (x0, y0, y1, colour);
co657_frmb 18:8c294697c901 255 }
co657_frmb 17:67f9ca828270 256 return;
co657_frmb 18:8c294697c901 257 }
co657_frmb 18:8c294697c901 258 if (dy == 0) {
co657_frmb 18:8c294697c901 259 /* horizontal line */
co657_frmb 18:8c294697c901 260 if (x0 > x1) {
co657_frmb 18:8c294697c901 261 hline (x1, y0, x0, colour);
co657_frmb 18:8c294697c901 262 } else {
co657_frmb 18:8c294697c901 263 hline (x0, y0, x1, colour);
co657_frmb 18:8c294697c901 264 }
co657_frmb 18:8c294697c901 265 return;
co657_frmb 18:8c294697c901 266 }
co657_frmb 18:8c294697c901 267
co657_frmb 18:8c294697c901 268 if ((x0 >= 128) || (x0 < 0) || (y0 >= 32) || (y0 < 0)) {
co657_frmb 18:8c294697c901 269 /* starts outside raster, so abort */
co657_frmb 17:67f9ca828270 270 return;
co657_frmb 17:67f9ca828270 271 }
co657_frmb 18:8c294697c901 272
co657_frmb 18:8c294697c901 273 x = x0;
co657_frmb 18:8c294697c901 274 y = y0;
chris 15:67dfa5550b73 275 if (dx > 0) {
co657_frmb 18:8c294697c901 276 a_dx = dx; s_x = 1;
chris 15:67dfa5550b73 277 } else {
co657_frmb 18:8c294697c901 278 a_dx = -dx; s_x = -1;
co657_frmb 18:8c294697c901 279 }
co657_frmb 18:8c294697c901 280 if (dy > 0) {
co657_frmb 18:8c294697c901 281 a_dy = dy; s_y = 1;
co657_frmb 18:8c294697c901 282 } else {
co657_frmb 18:8c294697c901 283 a_dy = -dy; s_y = -1;
chris 15:67dfa5550b73 284 }
co657_frmb 18:8c294697c901 285
co657_frmb 18:8c294697c901 286 if (a_dx > a_dy) {
co657_frmb 18:8c294697c901 287 strt = a_dy * 2; /* straight */
co657_frmb 18:8c294697c901 288 diag = strt - (2 * a_dx); /* diagonal */
co657_frmb 18:8c294697c901 289 d = strt - a_dx;
chris 15:67dfa5550b73 290
co657_frmb 20:dbee79303f9a 291 while ((a_dx >= 0) && (x >= 0) && (x < 128)) {
co657_frmb 18:8c294697c901 292 pixel_nochk (x, y, colour);
co657_frmb 18:8c294697c901 293 x += s_x;
co657_frmb 18:8c294697c901 294 a_dx--;
co657_frmb 18:8c294697c901 295
co657_frmb 18:8c294697c901 296 if (d <= 0) {
co657_frmb 18:8c294697c901 297 d += strt;
co657_frmb 18:8c294697c901 298 } else {
co657_frmb 18:8c294697c901 299 d += diag;
co657_frmb 18:8c294697c901 300 y += s_y;
co657_frmb 20:dbee79303f9a 301 if ((y < 0) || (y >= 32)) {
co657_frmb 20:dbee79303f9a 302 break; /* while() */
co657_frmb 20:dbee79303f9a 303 }
co657_frmb 18:8c294697c901 304 }
co657_frmb 18:8c294697c901 305 }
chris 15:67dfa5550b73 306 } else {
co657_frmb 18:8c294697c901 307 strt = a_dx * 2; /* straight */
co657_frmb 18:8c294697c901 308 diag = strt - (2 * a_dy); /* diagonal */
co657_frmb 18:8c294697c901 309 d = strt - a_dy;
co657_frmb 18:8c294697c901 310
co657_frmb 20:dbee79303f9a 311 while ((a_dy >= 0) && (y >= 0) && (y < 32)) {
co657_frmb 18:8c294697c901 312 pixel_nochk (x, y, colour);
co657_frmb 18:8c294697c901 313 y += s_y;
co657_frmb 18:8c294697c901 314 a_dy--;
co657_frmb 18:8c294697c901 315
co657_frmb 18:8c294697c901 316 if (d <= 0) {
co657_frmb 18:8c294697c901 317 d += strt;
co657_frmb 18:8c294697c901 318 } else {
co657_frmb 18:8c294697c901 319 d += diag;
co657_frmb 18:8c294697c901 320 x += s_x;
co657_frmb 20:dbee79303f9a 321 if ((x < 0) || (x >= 128)) {
co657_frmb 20:dbee79303f9a 322 break; /* while() */
co657_frmb 20:dbee79303f9a 323 }
co657_frmb 18:8c294697c901 324 }
co657_frmb 18:8c294697c901 325 }
chris 15:67dfa5550b73 326 }
chris 15:67dfa5550b73 327
co657_frmb 17:67f9ca828270 328 if (auto_up) {
co657_frmb 17:67f9ca828270 329 copy_to_lcd ();
co657_frmb 17:67f9ca828270 330 }
co657_frmb 17:67f9ca828270 331 }
co657_frmb 17:67f9ca828270 332
co657_frmb 18:8c294697c901 333 /* Note: x1 >= x0 */
co657_frmb 18:8c294697c901 334 void C12832::hline (int x0, int y0, int x1, int colour)
co657_frmb 17:67f9ca828270 335 {
co657_frmb 18:8c294697c901 336 int x;
co657_frmb 18:8c294697c901 337 int yoff;
co657_frmb 18:8c294697c901 338 uint8_t ybit;
co657_frmb 18:8c294697c901 339
co657_frmb 18:8c294697c901 340 if (((x0 < 0) && (x1 < 0)) || ((x0 >= 128) && (x1 >= 128)) || (y0 < 0) || (y0 >= 32)) {
co657_frmb 18:8c294697c901 341 return; /* completely outside */
co657_frmb 18:8c294697c901 342 }
co657_frmb 18:8c294697c901 343 if (x0 < 0) {
co657_frmb 18:8c294697c901 344 x0 = 0;
co657_frmb 18:8c294697c901 345 } else if (x1 >= 128) {
co657_frmb 18:8c294697c901 346 x1 = 127;
co657_frmb 18:8c294697c901 347 }
co657_frmb 18:8c294697c901 348
co657_frmb 19:de1f73b31288 349 yoff = ((y0 & ~7) << 4);
co657_frmb 18:8c294697c901 350 ybit = (1 << (y0 & 0x07));
co657_frmb 17:67f9ca828270 351
co657_frmb 18:8c294697c901 352 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 353 if (colour == 0) {
co657_frmb 18:8c294697c901 354 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 355 buffer[x + yoff] &= ~ybit; // erase pixel
co657_frmb 18:8c294697c901 356 }
co657_frmb 18:8c294697c901 357 } else {
co657_frmb 18:8c294697c901 358 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 359 buffer[x + yoff] |= ybit; // set pixel
co657_frmb 18:8c294697c901 360 }
co657_frmb 18:8c294697c901 361 }
co657_frmb 18:8c294697c901 362 } else { // XOR mode
co657_frmb 18:8c294697c901 363 if (colour == 1) {
co657_frmb 18:8c294697c901 364 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 365 buffer[x + yoff] ^= ybit; // xor pixel
co657_frmb 18:8c294697c901 366 }
co657_frmb 18:8c294697c901 367 }
co657_frmb 18:8c294697c901 368 }
co657_frmb 18:8c294697c901 369
co657_frmb 18:8c294697c901 370 if (auto_up) {
co657_frmb 18:8c294697c901 371 copy_to_lcd ();
co657_frmb 18:8c294697c901 372 }
co657_frmb 18:8c294697c901 373 }
co657_frmb 18:8c294697c901 374
co657_frmb 18:8c294697c901 375 /* Note: y1 >= y0 */
co657_frmb 18:8c294697c901 376 void C12832::vline (int x0, int y0, int y1, int colour)
co657_frmb 18:8c294697c901 377 {
co657_frmb 18:8c294697c901 378 if (((y0 < 0) && (y1 < 0)) || ((y0 >= 32) && (y1 >= 32)) || (x0 < 0) || (x0 >= 128)) {
co657_frmb 18:8c294697c901 379 return; /* completely outside */
co657_frmb 18:8c294697c901 380 }
co657_frmb 18:8c294697c901 381 if (y0 < 0) {
co657_frmb 18:8c294697c901 382 y0 = 0;
co657_frmb 18:8c294697c901 383 } else if (y1 >= 32) {
co657_frmb 18:8c294697c901 384 y1 = 31;
co657_frmb 17:67f9ca828270 385 }
co657_frmb 18:8c294697c901 386
co657_frmb 18:8c294697c901 387 if ((y0 & ~0x07) == (y1 & ~0x07)) {
co657_frmb 18:8c294697c901 388 /* first and last pixels are in the same byte */
co657_frmb 18:8c294697c901 389 uint8_t ybits = ((1 << ((y1 & 0x07) + 1)) - 1) ^ ((1 << (y0 & 0x07)) - 1);
co657_frmb 19:de1f73b31288 390 int yoff = (y0 & ~7) << 4; /* same as y1 */
co657_frmb 18:8c294697c901 391
co657_frmb 18:8c294697c901 392 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 393 if (colour == 1) {
co657_frmb 18:8c294697c901 394 buffer[x0 + yoff] |= ybits;
co657_frmb 18:8c294697c901 395 } else {
co657_frmb 18:8c294697c901 396 buffer[x0 + yoff] &= ~ybits;
co657_frmb 18:8c294697c901 397 }
co657_frmb 18:8c294697c901 398 } else { /* XOR mode */
co657_frmb 18:8c294697c901 399 buffer[x0 + yoff] ^= ybits;
co657_frmb 18:8c294697c901 400 }
co657_frmb 18:8c294697c901 401 } else {
co657_frmb 18:8c294697c901 402 uint8_t st_ybits = (0xff << (y0 & 0x07));
co657_frmb 18:8c294697c901 403 uint8_t sp_ybits = ((1 << ((y1 & 0x07) + 1)) - 1);
co657_frmb 19:de1f73b31288 404 int st_yoff = (y0 & ~7) << 4;
co657_frmb 19:de1f73b31288 405 int sp_yoff = (y1 & ~7) << 4;
co657_frmb 18:8c294697c901 406
co657_frmb 18:8c294697c901 407 /* fill in first byte */
co657_frmb 18:8c294697c901 408 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 409 if (colour == 1) {
co657_frmb 18:8c294697c901 410 buffer[x0 + st_yoff] |= st_ybits;
co657_frmb 18:8c294697c901 411 } else {
co657_frmb 18:8c294697c901 412 buffer[x0 + st_yoff] &= ~st_ybits;
co657_frmb 18:8c294697c901 413 }
co657_frmb 18:8c294697c901 414 } else { /* XOR mode */
co657_frmb 18:8c294697c901 415 buffer[x0 + st_yoff] ^= st_ybits;
co657_frmb 18:8c294697c901 416 }
co657_frmb 18:8c294697c901 417 for (st_yoff += 128; st_yoff < sp_yoff; st_yoff += 128) {
co657_frmb 18:8c294697c901 418 /* intervening bytes 0xff */
co657_frmb 18:8c294697c901 419 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 420 if (colour == 1) {
co657_frmb 18:8c294697c901 421 buffer[x0 + st_yoff] = 0xff;
co657_frmb 18:8c294697c901 422 } else {
co657_frmb 18:8c294697c901 423 buffer[x0 + st_yoff] = 0x00;
co657_frmb 18:8c294697c901 424 }
co657_frmb 18:8c294697c901 425 } else { /* XOR mode */
co657_frmb 18:8c294697c901 426 buffer[x0 + st_yoff] ^= 0xff;
co657_frmb 18:8c294697c901 427 }
co657_frmb 18:8c294697c901 428 }
co657_frmb 18:8c294697c901 429 /* and the last byte */
co657_frmb 18:8c294697c901 430 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 431 if (colour == 1) {
co657_frmb 18:8c294697c901 432 buffer[x0 + sp_yoff] |= sp_ybits;
co657_frmb 18:8c294697c901 433 } else {
co657_frmb 18:8c294697c901 434 buffer[x0 + sp_yoff] &= ~sp_ybits;
co657_frmb 18:8c294697c901 435 }
co657_frmb 18:8c294697c901 436 } else { /* XOR mode */
co657_frmb 18:8c294697c901 437 buffer[x0 + sp_yoff] ^= sp_ybits;
co657_frmb 18:8c294697c901 438 }
co657_frmb 18:8c294697c901 439 }
co657_frmb 18:8c294697c901 440
co657_frmb 17:67f9ca828270 441 if (auto_up) {
co657_frmb 17:67f9ca828270 442 copy_to_lcd ();
co657_frmb 17:67f9ca828270 443 }
co657_frmb 17:67f9ca828270 444 }
co657_frmb 17:67f9ca828270 445
chris 16:7de323fa46fe 446 void C12832::rect(int x0, int y0, int x1, int y1, int color)
chris 15:67dfa5550b73 447 {
chris 15:67dfa5550b73 448
chris 15:67dfa5550b73 449 if (x1 > x0) line(x0,y0,x1,y0,color);
chris 15:67dfa5550b73 450 else line(x1,y0,x0,y0,color);
chris 15:67dfa5550b73 451
chris 15:67dfa5550b73 452 if (y1 > y0) line(x0,y0,x0,y1,color);
chris 15:67dfa5550b73 453 else line(x0,y1,x0,y0,color);
chris 15:67dfa5550b73 454
chris 15:67dfa5550b73 455 if (x1 > x0) line(x0,y1,x1,y1,color);
chris 15:67dfa5550b73 456 else line(x1,y1,x0,y1,color);
chris 15:67dfa5550b73 457
chris 15:67dfa5550b73 458 if (y1 > y0) line(x1,y0,x1,y1,color);
chris 15:67dfa5550b73 459 else line(x1,y1,x1,y0,color);
chris 15:67dfa5550b73 460
chris 15:67dfa5550b73 461 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 462 }
chris 15:67dfa5550b73 463
chris 16:7de323fa46fe 464 void C12832::fillrect(int x0, int y0, int x1, int y1, int color)
chris 15:67dfa5550b73 465 {
co657_frmb 19:de1f73b31288 466 int l,i;
chris 15:67dfa5550b73 467 if(x0 > x1) {
chris 15:67dfa5550b73 468 i = x0;
chris 15:67dfa5550b73 469 x0 = x1;
chris 15:67dfa5550b73 470 x1 = i;
chris 15:67dfa5550b73 471 }
chris 15:67dfa5550b73 472
chris 15:67dfa5550b73 473 if(y0 > y1) {
chris 15:67dfa5550b73 474 i = y0;
chris 15:67dfa5550b73 475 y0 = y1;
chris 15:67dfa5550b73 476 y1 = i;
chris 15:67dfa5550b73 477 }
chris 15:67dfa5550b73 478
chris 15:67dfa5550b73 479 for(l = x0; l<= x1; l ++) {
co657_frmb 19:de1f73b31288 480 vline (l, y0, y1, color);
chris 15:67dfa5550b73 481 }
chris 15:67dfa5550b73 482 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 483 }
chris 15:67dfa5550b73 484
chris 15:67dfa5550b73 485
chris 15:67dfa5550b73 486
chris 16:7de323fa46fe 487 void C12832::circle(int x0, int y0, int r, int color)
chris 15:67dfa5550b73 488 {
chris 15:67dfa5550b73 489
chris 15:67dfa5550b73 490 int draw_x0, draw_y0;
chris 15:67dfa5550b73 491 int draw_x1, draw_y1;
chris 15:67dfa5550b73 492 int draw_x2, draw_y2;
chris 15:67dfa5550b73 493 int draw_x3, draw_y3;
chris 15:67dfa5550b73 494 int draw_x4, draw_y4;
chris 15:67dfa5550b73 495 int draw_x5, draw_y5;
chris 15:67dfa5550b73 496 int draw_x6, draw_y6;
chris 15:67dfa5550b73 497 int draw_x7, draw_y7;
chris 15:67dfa5550b73 498 int xx, yy;
chris 15:67dfa5550b73 499 int di;
chris 15:67dfa5550b73 500 //WindowMax();
chris 15:67dfa5550b73 501 if (r == 0) { /* no radius */
chris 15:67dfa5550b73 502 return;
chris 15:67dfa5550b73 503 }
chris 15:67dfa5550b73 504
chris 15:67dfa5550b73 505 draw_x0 = draw_x1 = x0;
chris 15:67dfa5550b73 506 draw_y0 = draw_y1 = y0 + r;
chris 15:67dfa5550b73 507 if (draw_y0 < height()) {
chris 15:67dfa5550b73 508 pixel(draw_x0, draw_y0, color); /* 90 degree */
chris 15:67dfa5550b73 509 }
chris 15:67dfa5550b73 510
chris 15:67dfa5550b73 511 draw_x2 = draw_x3 = x0;
chris 15:67dfa5550b73 512 draw_y2 = draw_y3 = y0 - r;
chris 15:67dfa5550b73 513 if (draw_y2 >= 0) {
chris 15:67dfa5550b73 514 pixel(draw_x2, draw_y2, color); /* 270 degree */
chris 15:67dfa5550b73 515 }
chris 15:67dfa5550b73 516
chris 15:67dfa5550b73 517 draw_x4 = draw_x6 = x0 + r;
chris 15:67dfa5550b73 518 draw_y4 = draw_y6 = y0;
chris 15:67dfa5550b73 519 if (draw_x4 < width()) {
chris 15:67dfa5550b73 520 pixel(draw_x4, draw_y4, color); /* 0 degree */
chris 15:67dfa5550b73 521 }
chris 15:67dfa5550b73 522
chris 15:67dfa5550b73 523 draw_x5 = draw_x7 = x0 - r;
chris 15:67dfa5550b73 524 draw_y5 = draw_y7 = y0;
chris 15:67dfa5550b73 525 if (draw_x5>=0) {
chris 15:67dfa5550b73 526 pixel(draw_x5, draw_y5, color); /* 180 degree */
chris 15:67dfa5550b73 527 }
chris 15:67dfa5550b73 528
chris 15:67dfa5550b73 529 if (r == 1) {
chris 15:67dfa5550b73 530 return;
chris 15:67dfa5550b73 531 }
chris 15:67dfa5550b73 532
chris 15:67dfa5550b73 533 di = 3 - 2*r;
chris 15:67dfa5550b73 534 xx = 0;
chris 15:67dfa5550b73 535 yy = r;
chris 15:67dfa5550b73 536 while (xx < yy) {
chris 15:67dfa5550b73 537
chris 15:67dfa5550b73 538 if (di < 0) {
chris 15:67dfa5550b73 539 di += 4*xx + 6;
chris 15:67dfa5550b73 540 } else {
chris 15:67dfa5550b73 541 di += 4*(xx - yy) + 10;
chris 15:67dfa5550b73 542 yy--;
chris 15:67dfa5550b73 543 draw_y0--;
chris 15:67dfa5550b73 544 draw_y1--;
chris 15:67dfa5550b73 545 draw_y2++;
chris 15:67dfa5550b73 546 draw_y3++;
chris 15:67dfa5550b73 547 draw_x4--;
chris 15:67dfa5550b73 548 draw_x5++;
chris 15:67dfa5550b73 549 draw_x6--;
chris 15:67dfa5550b73 550 draw_x7++;
chris 15:67dfa5550b73 551 }
chris 15:67dfa5550b73 552 xx++;
chris 15:67dfa5550b73 553 draw_x0++;
chris 15:67dfa5550b73 554 draw_x1--;
chris 15:67dfa5550b73 555 draw_x2++;
chris 15:67dfa5550b73 556 draw_x3--;
chris 15:67dfa5550b73 557 draw_y4++;
chris 15:67dfa5550b73 558 draw_y5++;
chris 15:67dfa5550b73 559 draw_y6--;
chris 15:67dfa5550b73 560 draw_y7--;
chris 15:67dfa5550b73 561
chris 15:67dfa5550b73 562 if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
chris 15:67dfa5550b73 563 pixel(draw_x0, draw_y0, color);
chris 15:67dfa5550b73 564 }
chris 15:67dfa5550b73 565
chris 15:67dfa5550b73 566 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
chris 15:67dfa5550b73 567 pixel(draw_x1, draw_y1, color);
chris 15:67dfa5550b73 568 }
chris 15:67dfa5550b73 569
chris 15:67dfa5550b73 570 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
chris 15:67dfa5550b73 571 pixel(draw_x2, draw_y2, color);
chris 15:67dfa5550b73 572 }
chris 15:67dfa5550b73 573
chris 15:67dfa5550b73 574 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
chris 15:67dfa5550b73 575 pixel(draw_x3, draw_y3, color);
chris 15:67dfa5550b73 576 }
chris 15:67dfa5550b73 577
chris 15:67dfa5550b73 578 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
chris 15:67dfa5550b73 579 pixel(draw_x4, draw_y4, color);
chris 15:67dfa5550b73 580 }
chris 15:67dfa5550b73 581
chris 15:67dfa5550b73 582 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
chris 15:67dfa5550b73 583 pixel(draw_x5, draw_y5, color);
chris 15:67dfa5550b73 584 }
chris 15:67dfa5550b73 585 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
chris 15:67dfa5550b73 586 pixel(draw_x6, draw_y6, color);
chris 15:67dfa5550b73 587 }
chris 15:67dfa5550b73 588 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
chris 15:67dfa5550b73 589 pixel(draw_x7, draw_y7, color);
chris 15:67dfa5550b73 590 }
chris 15:67dfa5550b73 591 }
chris 15:67dfa5550b73 592 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 593 }
chris 15:67dfa5550b73 594
chris 16:7de323fa46fe 595 void C12832::fillcircle(int x, int y, int r, int color)
chris 15:67dfa5550b73 596 {
chris 15:67dfa5550b73 597 int i,up;
chris 15:67dfa5550b73 598 up = auto_up;
chris 15:67dfa5550b73 599 auto_up = 0; // off
chris 15:67dfa5550b73 600 for (i = 0; i <= r; i++)
chris 15:67dfa5550b73 601 circle(x,y,i,color);
chris 15:67dfa5550b73 602 auto_up = up;
chris 15:67dfa5550b73 603 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 604 }
chris 15:67dfa5550b73 605
chris 16:7de323fa46fe 606 void C12832::setmode(int mode)
chris 15:67dfa5550b73 607 {
chris 15:67dfa5550b73 608 draw_mode = mode;
chris 15:67dfa5550b73 609 }
chris 15:67dfa5550b73 610
chris 16:7de323fa46fe 611 void C12832::locate(int x, int y)
chris 15:67dfa5550b73 612 {
chris 15:67dfa5550b73 613 char_x = x;
chris 15:67dfa5550b73 614 char_y = y;
chris 15:67dfa5550b73 615 }
chris 15:67dfa5550b73 616
chris 15:67dfa5550b73 617
chris 15:67dfa5550b73 618
chris 16:7de323fa46fe 619 int C12832::columns()
chris 15:67dfa5550b73 620 {
chris 15:67dfa5550b73 621 return width() / font[1];
chris 15:67dfa5550b73 622 }
chris 15:67dfa5550b73 623
chris 15:67dfa5550b73 624
chris 15:67dfa5550b73 625
chris 16:7de323fa46fe 626 int C12832::rows()
chris 15:67dfa5550b73 627 {
chris 15:67dfa5550b73 628 return height() / font[2];
chris 15:67dfa5550b73 629 }
chris 15:67dfa5550b73 630
chris 15:67dfa5550b73 631
chris 15:67dfa5550b73 632
chris 16:7de323fa46fe 633 int C12832::_putc(int value)
chris 15:67dfa5550b73 634 {
chris 15:67dfa5550b73 635 if (value == '\n') { // new line
chris 15:67dfa5550b73 636 char_x = 0;
chris 15:67dfa5550b73 637 char_y = char_y + font[2];
chris 15:67dfa5550b73 638 if (char_y >= height() - font[2]) {
chris 15:67dfa5550b73 639 char_y = 0;
chris 15:67dfa5550b73 640 }
chris 15:67dfa5550b73 641 } else {
chris 15:67dfa5550b73 642 character(char_x, char_y, value);
chris 15:67dfa5550b73 643 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 644 }
chris 15:67dfa5550b73 645 return value;
chris 15:67dfa5550b73 646 }
chris 15:67dfa5550b73 647
chris 16:7de323fa46fe 648 void C12832::character(int x, int y, int c)
chris 15:67dfa5550b73 649 {
chris 15:67dfa5550b73 650 unsigned int hor,vert,offset,bpl,j,i,b;
chris 15:67dfa5550b73 651 unsigned char* zeichen;
chris 15:67dfa5550b73 652 unsigned char z,w;
chris 15:67dfa5550b73 653
chris 15:67dfa5550b73 654 if ((c < 31) || (c > 127)) return; // test char range
chris 15:67dfa5550b73 655
chris 15:67dfa5550b73 656 // read font parameter from start of array
chris 15:67dfa5550b73 657 offset = font[0]; // bytes / char
chris 15:67dfa5550b73 658 hor = font[1]; // get hor size of font
chris 15:67dfa5550b73 659 vert = font[2]; // get vert size of font
chris 15:67dfa5550b73 660 bpl = font[3]; // bytes per line
chris 15:67dfa5550b73 661
chris 15:67dfa5550b73 662 if (char_x + hor > width()) {
chris 15:67dfa5550b73 663 char_x = 0;
chris 15:67dfa5550b73 664 char_y = char_y + vert;
chris 15:67dfa5550b73 665 if (char_y >= height() - font[2]) {
chris 15:67dfa5550b73 666 char_y = 0;
chris 15:67dfa5550b73 667 }
chris 15:67dfa5550b73 668 }
chris 15:67dfa5550b73 669
chris 15:67dfa5550b73 670 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
chris 15:67dfa5550b73 671 w = zeichen[0]; // width of actual char
chris 15:67dfa5550b73 672 // construct the char into the buffer
chris 15:67dfa5550b73 673 for (j=0; j<vert; j++) { // vert line
chris 15:67dfa5550b73 674 for (i=0; i<hor; i++) { // horz line
chris 15:67dfa5550b73 675 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
chris 15:67dfa5550b73 676 b = 1 << (j & 0x07);
chris 15:67dfa5550b73 677 if (( z & b ) == 0x00) {
chris 15:67dfa5550b73 678 pixel(x+i,y+j,0);
chris 15:67dfa5550b73 679 } else {
chris 15:67dfa5550b73 680 pixel(x+i,y+j,1);
chris 15:67dfa5550b73 681 }
chris 15:67dfa5550b73 682
chris 15:67dfa5550b73 683 }
chris 15:67dfa5550b73 684 }
chris 15:67dfa5550b73 685
chris 15:67dfa5550b73 686 char_x += w;
chris 15:67dfa5550b73 687 }
chris 15:67dfa5550b73 688
chris 15:67dfa5550b73 689
chris 16:7de323fa46fe 690 void C12832::set_font(unsigned char* f)
chris 15:67dfa5550b73 691 {
chris 15:67dfa5550b73 692 font = f;
chris 15:67dfa5550b73 693 }
chris 15:67dfa5550b73 694
chris 16:7de323fa46fe 695 void C12832::set_auto_up(unsigned int up)
chris 15:67dfa5550b73 696 {
chris 15:67dfa5550b73 697 if(up ) auto_up = 1;
chris 15:67dfa5550b73 698 else auto_up = 0;
chris 15:67dfa5550b73 699 }
chris 15:67dfa5550b73 700
chris 16:7de323fa46fe 701 unsigned int C12832::get_auto_up(void)
chris 15:67dfa5550b73 702 {
chris 15:67dfa5550b73 703 return (auto_up);
chris 15:67dfa5550b73 704 }
chris 15:67dfa5550b73 705
chris 16:7de323fa46fe 706 void C12832::print_bm(Bitmap bm, int x, int y)
chris 15:67dfa5550b73 707 {
chris 15:67dfa5550b73 708 int h,v,b;
chris 15:67dfa5550b73 709 char d;
chris 15:67dfa5550b73 710
chris 15:67dfa5550b73 711 for(v=0; v < bm.ySize; v++) { // lines
chris 15:67dfa5550b73 712 for(h=0; h < bm.xSize; h++) { // pixel
chris 15:67dfa5550b73 713 if(h + x > 127) break;
chris 15:67dfa5550b73 714 if(v + y > 31) break;
chris 15:67dfa5550b73 715 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
chris 15:67dfa5550b73 716 b = 0x80 >> (h & 0x07);
chris 15:67dfa5550b73 717 if((d & b) == 0) {
chris 15:67dfa5550b73 718 pixel(x+h,y+v,0);
chris 15:67dfa5550b73 719 } else {
chris 15:67dfa5550b73 720 pixel(x+h,y+v,1);
chris 15:67dfa5550b73 721 }
chris 15:67dfa5550b73 722 }
chris 15:67dfa5550b73 723 }
chris 15:67dfa5550b73 724
chris 15:67dfa5550b73 725 }
chris 15:67dfa5550b73 726
chris 15:67dfa5550b73 727