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:
Sun Nov 01 23:09:05 2015 +0000
Revision:
19:de1f73b31288
Parent:
18:8c294697c901
Child:
20:dbee79303f9a
Some small optimisations.

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 18:8c294697c901 291 while ((a_dx >= 0) && (x >= 0) && (x < 128) && (y >= 0) && (y < 32)) {
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 18:8c294697c901 301 }
co657_frmb 18:8c294697c901 302 }
chris 15:67dfa5550b73 303 } else {
co657_frmb 18:8c294697c901 304 strt = a_dx * 2; /* straight */
co657_frmb 18:8c294697c901 305 diag = strt - (2 * a_dy); /* diagonal */
co657_frmb 18:8c294697c901 306 d = strt - a_dy;
co657_frmb 18:8c294697c901 307
co657_frmb 18:8c294697c901 308 while ((a_dy >= 0) && (x >= 0) && (x < 128) && (y >= 0) && (y < 32)) {
co657_frmb 18:8c294697c901 309 pixel_nochk (x, y, colour);
co657_frmb 18:8c294697c901 310 y += s_y;
co657_frmb 18:8c294697c901 311 a_dy--;
co657_frmb 18:8c294697c901 312
co657_frmb 18:8c294697c901 313 if (d <= 0) {
co657_frmb 18:8c294697c901 314 d += strt;
co657_frmb 18:8c294697c901 315 } else {
co657_frmb 18:8c294697c901 316 d += diag;
co657_frmb 18:8c294697c901 317 x += s_x;
co657_frmb 18:8c294697c901 318 }
co657_frmb 18:8c294697c901 319 }
chris 15:67dfa5550b73 320 }
chris 15:67dfa5550b73 321
co657_frmb 17:67f9ca828270 322 if (auto_up) {
co657_frmb 17:67f9ca828270 323 copy_to_lcd ();
co657_frmb 17:67f9ca828270 324 }
co657_frmb 17:67f9ca828270 325 }
co657_frmb 17:67f9ca828270 326
co657_frmb 18:8c294697c901 327 /* Note: x1 >= x0 */
co657_frmb 18:8c294697c901 328 void C12832::hline (int x0, int y0, int x1, int colour)
co657_frmb 17:67f9ca828270 329 {
co657_frmb 18:8c294697c901 330 int x;
co657_frmb 18:8c294697c901 331 int yoff;
co657_frmb 18:8c294697c901 332 uint8_t ybit;
co657_frmb 18:8c294697c901 333
co657_frmb 18:8c294697c901 334 if (((x0 < 0) && (x1 < 0)) || ((x0 >= 128) && (x1 >= 128)) || (y0 < 0) || (y0 >= 32)) {
co657_frmb 18:8c294697c901 335 return; /* completely outside */
co657_frmb 18:8c294697c901 336 }
co657_frmb 18:8c294697c901 337 if (x0 < 0) {
co657_frmb 18:8c294697c901 338 x0 = 0;
co657_frmb 18:8c294697c901 339 } else if (x1 >= 128) {
co657_frmb 18:8c294697c901 340 x1 = 127;
co657_frmb 18:8c294697c901 341 }
co657_frmb 18:8c294697c901 342
co657_frmb 19:de1f73b31288 343 yoff = ((y0 & ~7) << 4);
co657_frmb 18:8c294697c901 344 ybit = (1 << (y0 & 0x07));
co657_frmb 17:67f9ca828270 345
co657_frmb 18:8c294697c901 346 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 347 if (colour == 0) {
co657_frmb 18:8c294697c901 348 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 349 buffer[x + yoff] &= ~ybit; // erase pixel
co657_frmb 18:8c294697c901 350 }
co657_frmb 18:8c294697c901 351 } else {
co657_frmb 18:8c294697c901 352 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 353 buffer[x + yoff] |= ybit; // set pixel
co657_frmb 18:8c294697c901 354 }
co657_frmb 18:8c294697c901 355 }
co657_frmb 18:8c294697c901 356 } else { // XOR mode
co657_frmb 18:8c294697c901 357 if (colour == 1) {
co657_frmb 18:8c294697c901 358 for (x=x0; x<=x1; x++) {
co657_frmb 18:8c294697c901 359 buffer[x + yoff] ^= ybit; // xor pixel
co657_frmb 18:8c294697c901 360 }
co657_frmb 18:8c294697c901 361 }
co657_frmb 18:8c294697c901 362 }
co657_frmb 18:8c294697c901 363
co657_frmb 18:8c294697c901 364 if (auto_up) {
co657_frmb 18:8c294697c901 365 copy_to_lcd ();
co657_frmb 18:8c294697c901 366 }
co657_frmb 18:8c294697c901 367 }
co657_frmb 18:8c294697c901 368
co657_frmb 18:8c294697c901 369 /* Note: y1 >= y0 */
co657_frmb 18:8c294697c901 370 void C12832::vline (int x0, int y0, int y1, int colour)
co657_frmb 18:8c294697c901 371 {
co657_frmb 18:8c294697c901 372 if (((y0 < 0) && (y1 < 0)) || ((y0 >= 32) && (y1 >= 32)) || (x0 < 0) || (x0 >= 128)) {
co657_frmb 18:8c294697c901 373 return; /* completely outside */
co657_frmb 18:8c294697c901 374 }
co657_frmb 18:8c294697c901 375 if (y0 < 0) {
co657_frmb 18:8c294697c901 376 y0 = 0;
co657_frmb 18:8c294697c901 377 } else if (y1 >= 32) {
co657_frmb 18:8c294697c901 378 y1 = 31;
co657_frmb 17:67f9ca828270 379 }
co657_frmb 18:8c294697c901 380
co657_frmb 18:8c294697c901 381 if ((y0 & ~0x07) == (y1 & ~0x07)) {
co657_frmb 18:8c294697c901 382 /* first and last pixels are in the same byte */
co657_frmb 18:8c294697c901 383 uint8_t ybits = ((1 << ((y1 & 0x07) + 1)) - 1) ^ ((1 << (y0 & 0x07)) - 1);
co657_frmb 19:de1f73b31288 384 int yoff = (y0 & ~7) << 4; /* same as y1 */
co657_frmb 18:8c294697c901 385
co657_frmb 18:8c294697c901 386 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 387 if (colour == 1) {
co657_frmb 18:8c294697c901 388 buffer[x0 + yoff] |= ybits;
co657_frmb 18:8c294697c901 389 } else {
co657_frmb 18:8c294697c901 390 buffer[x0 + yoff] &= ~ybits;
co657_frmb 18:8c294697c901 391 }
co657_frmb 18:8c294697c901 392 } else { /* XOR mode */
co657_frmb 18:8c294697c901 393 buffer[x0 + yoff] ^= ybits;
co657_frmb 18:8c294697c901 394 }
co657_frmb 18:8c294697c901 395 } else {
co657_frmb 18:8c294697c901 396 uint8_t st_ybits = (0xff << (y0 & 0x07));
co657_frmb 18:8c294697c901 397 uint8_t sp_ybits = ((1 << ((y1 & 0x07) + 1)) - 1);
co657_frmb 19:de1f73b31288 398 int st_yoff = (y0 & ~7) << 4;
co657_frmb 19:de1f73b31288 399 int sp_yoff = (y1 & ~7) << 4;
co657_frmb 18:8c294697c901 400
co657_frmb 18:8c294697c901 401 /* fill in first byte */
co657_frmb 18:8c294697c901 402 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 403 if (colour == 1) {
co657_frmb 18:8c294697c901 404 buffer[x0 + st_yoff] |= st_ybits;
co657_frmb 18:8c294697c901 405 } else {
co657_frmb 18:8c294697c901 406 buffer[x0 + st_yoff] &= ~st_ybits;
co657_frmb 18:8c294697c901 407 }
co657_frmb 18:8c294697c901 408 } else { /* XOR mode */
co657_frmb 18:8c294697c901 409 buffer[x0 + st_yoff] ^= st_ybits;
co657_frmb 18:8c294697c901 410 }
co657_frmb 18:8c294697c901 411 for (st_yoff += 128; st_yoff < sp_yoff; st_yoff += 128) {
co657_frmb 18:8c294697c901 412 /* intervening bytes 0xff */
co657_frmb 18:8c294697c901 413 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 414 if (colour == 1) {
co657_frmb 18:8c294697c901 415 buffer[x0 + st_yoff] = 0xff;
co657_frmb 18:8c294697c901 416 } else {
co657_frmb 18:8c294697c901 417 buffer[x0 + st_yoff] = 0x00;
co657_frmb 18:8c294697c901 418 }
co657_frmb 18:8c294697c901 419 } else { /* XOR mode */
co657_frmb 18:8c294697c901 420 buffer[x0 + st_yoff] ^= 0xff;
co657_frmb 18:8c294697c901 421 }
co657_frmb 18:8c294697c901 422 }
co657_frmb 18:8c294697c901 423 /* and the last byte */
co657_frmb 18:8c294697c901 424 if (draw_mode == NORMAL) {
co657_frmb 18:8c294697c901 425 if (colour == 1) {
co657_frmb 18:8c294697c901 426 buffer[x0 + sp_yoff] |= sp_ybits;
co657_frmb 18:8c294697c901 427 } else {
co657_frmb 18:8c294697c901 428 buffer[x0 + sp_yoff] &= ~sp_ybits;
co657_frmb 18:8c294697c901 429 }
co657_frmb 18:8c294697c901 430 } else { /* XOR mode */
co657_frmb 18:8c294697c901 431 buffer[x0 + sp_yoff] ^= sp_ybits;
co657_frmb 18:8c294697c901 432 }
co657_frmb 18:8c294697c901 433 }
co657_frmb 18:8c294697c901 434
co657_frmb 17:67f9ca828270 435 if (auto_up) {
co657_frmb 17:67f9ca828270 436 copy_to_lcd ();
co657_frmb 17:67f9ca828270 437 }
co657_frmb 17:67f9ca828270 438 }
co657_frmb 17:67f9ca828270 439
chris 16:7de323fa46fe 440 void C12832::rect(int x0, int y0, int x1, int y1, int color)
chris 15:67dfa5550b73 441 {
chris 15:67dfa5550b73 442
chris 15:67dfa5550b73 443 if (x1 > x0) line(x0,y0,x1,y0,color);
chris 15:67dfa5550b73 444 else line(x1,y0,x0,y0,color);
chris 15:67dfa5550b73 445
chris 15:67dfa5550b73 446 if (y1 > y0) line(x0,y0,x0,y1,color);
chris 15:67dfa5550b73 447 else line(x0,y1,x0,y0,color);
chris 15:67dfa5550b73 448
chris 15:67dfa5550b73 449 if (x1 > x0) line(x0,y1,x1,y1,color);
chris 15:67dfa5550b73 450 else line(x1,y1,x0,y1,color);
chris 15:67dfa5550b73 451
chris 15:67dfa5550b73 452 if (y1 > y0) line(x1,y0,x1,y1,color);
chris 15:67dfa5550b73 453 else line(x1,y1,x1,y0,color);
chris 15:67dfa5550b73 454
chris 15:67dfa5550b73 455 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 456 }
chris 15:67dfa5550b73 457
chris 16:7de323fa46fe 458 void C12832::fillrect(int x0, int y0, int x1, int y1, int color)
chris 15:67dfa5550b73 459 {
co657_frmb 19:de1f73b31288 460 int l,i;
chris 15:67dfa5550b73 461 if(x0 > x1) {
chris 15:67dfa5550b73 462 i = x0;
chris 15:67dfa5550b73 463 x0 = x1;
chris 15:67dfa5550b73 464 x1 = i;
chris 15:67dfa5550b73 465 }
chris 15:67dfa5550b73 466
chris 15:67dfa5550b73 467 if(y0 > y1) {
chris 15:67dfa5550b73 468 i = y0;
chris 15:67dfa5550b73 469 y0 = y1;
chris 15:67dfa5550b73 470 y1 = i;
chris 15:67dfa5550b73 471 }
chris 15:67dfa5550b73 472
chris 15:67dfa5550b73 473 for(l = x0; l<= x1; l ++) {
co657_frmb 19:de1f73b31288 474 vline (l, y0, y1, color);
chris 15:67dfa5550b73 475 }
chris 15:67dfa5550b73 476 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 477 }
chris 15:67dfa5550b73 478
chris 15:67dfa5550b73 479
chris 15:67dfa5550b73 480
chris 16:7de323fa46fe 481 void C12832::circle(int x0, int y0, int r, int color)
chris 15:67dfa5550b73 482 {
chris 15:67dfa5550b73 483
chris 15:67dfa5550b73 484 int draw_x0, draw_y0;
chris 15:67dfa5550b73 485 int draw_x1, draw_y1;
chris 15:67dfa5550b73 486 int draw_x2, draw_y2;
chris 15:67dfa5550b73 487 int draw_x3, draw_y3;
chris 15:67dfa5550b73 488 int draw_x4, draw_y4;
chris 15:67dfa5550b73 489 int draw_x5, draw_y5;
chris 15:67dfa5550b73 490 int draw_x6, draw_y6;
chris 15:67dfa5550b73 491 int draw_x7, draw_y7;
chris 15:67dfa5550b73 492 int xx, yy;
chris 15:67dfa5550b73 493 int di;
chris 15:67dfa5550b73 494 //WindowMax();
chris 15:67dfa5550b73 495 if (r == 0) { /* no radius */
chris 15:67dfa5550b73 496 return;
chris 15:67dfa5550b73 497 }
chris 15:67dfa5550b73 498
chris 15:67dfa5550b73 499 draw_x0 = draw_x1 = x0;
chris 15:67dfa5550b73 500 draw_y0 = draw_y1 = y0 + r;
chris 15:67dfa5550b73 501 if (draw_y0 < height()) {
chris 15:67dfa5550b73 502 pixel(draw_x0, draw_y0, color); /* 90 degree */
chris 15:67dfa5550b73 503 }
chris 15:67dfa5550b73 504
chris 15:67dfa5550b73 505 draw_x2 = draw_x3 = x0;
chris 15:67dfa5550b73 506 draw_y2 = draw_y3 = y0 - r;
chris 15:67dfa5550b73 507 if (draw_y2 >= 0) {
chris 15:67dfa5550b73 508 pixel(draw_x2, draw_y2, color); /* 270 degree */
chris 15:67dfa5550b73 509 }
chris 15:67dfa5550b73 510
chris 15:67dfa5550b73 511 draw_x4 = draw_x6 = x0 + r;
chris 15:67dfa5550b73 512 draw_y4 = draw_y6 = y0;
chris 15:67dfa5550b73 513 if (draw_x4 < width()) {
chris 15:67dfa5550b73 514 pixel(draw_x4, draw_y4, color); /* 0 degree */
chris 15:67dfa5550b73 515 }
chris 15:67dfa5550b73 516
chris 15:67dfa5550b73 517 draw_x5 = draw_x7 = x0 - r;
chris 15:67dfa5550b73 518 draw_y5 = draw_y7 = y0;
chris 15:67dfa5550b73 519 if (draw_x5>=0) {
chris 15:67dfa5550b73 520 pixel(draw_x5, draw_y5, color); /* 180 degree */
chris 15:67dfa5550b73 521 }
chris 15:67dfa5550b73 522
chris 15:67dfa5550b73 523 if (r == 1) {
chris 15:67dfa5550b73 524 return;
chris 15:67dfa5550b73 525 }
chris 15:67dfa5550b73 526
chris 15:67dfa5550b73 527 di = 3 - 2*r;
chris 15:67dfa5550b73 528 xx = 0;
chris 15:67dfa5550b73 529 yy = r;
chris 15:67dfa5550b73 530 while (xx < yy) {
chris 15:67dfa5550b73 531
chris 15:67dfa5550b73 532 if (di < 0) {
chris 15:67dfa5550b73 533 di += 4*xx + 6;
chris 15:67dfa5550b73 534 } else {
chris 15:67dfa5550b73 535 di += 4*(xx - yy) + 10;
chris 15:67dfa5550b73 536 yy--;
chris 15:67dfa5550b73 537 draw_y0--;
chris 15:67dfa5550b73 538 draw_y1--;
chris 15:67dfa5550b73 539 draw_y2++;
chris 15:67dfa5550b73 540 draw_y3++;
chris 15:67dfa5550b73 541 draw_x4--;
chris 15:67dfa5550b73 542 draw_x5++;
chris 15:67dfa5550b73 543 draw_x6--;
chris 15:67dfa5550b73 544 draw_x7++;
chris 15:67dfa5550b73 545 }
chris 15:67dfa5550b73 546 xx++;
chris 15:67dfa5550b73 547 draw_x0++;
chris 15:67dfa5550b73 548 draw_x1--;
chris 15:67dfa5550b73 549 draw_x2++;
chris 15:67dfa5550b73 550 draw_x3--;
chris 15:67dfa5550b73 551 draw_y4++;
chris 15:67dfa5550b73 552 draw_y5++;
chris 15:67dfa5550b73 553 draw_y6--;
chris 15:67dfa5550b73 554 draw_y7--;
chris 15:67dfa5550b73 555
chris 15:67dfa5550b73 556 if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
chris 15:67dfa5550b73 557 pixel(draw_x0, draw_y0, color);
chris 15:67dfa5550b73 558 }
chris 15:67dfa5550b73 559
chris 15:67dfa5550b73 560 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
chris 15:67dfa5550b73 561 pixel(draw_x1, draw_y1, color);
chris 15:67dfa5550b73 562 }
chris 15:67dfa5550b73 563
chris 15:67dfa5550b73 564 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
chris 15:67dfa5550b73 565 pixel(draw_x2, draw_y2, color);
chris 15:67dfa5550b73 566 }
chris 15:67dfa5550b73 567
chris 15:67dfa5550b73 568 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
chris 15:67dfa5550b73 569 pixel(draw_x3, draw_y3, color);
chris 15:67dfa5550b73 570 }
chris 15:67dfa5550b73 571
chris 15:67dfa5550b73 572 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
chris 15:67dfa5550b73 573 pixel(draw_x4, draw_y4, color);
chris 15:67dfa5550b73 574 }
chris 15:67dfa5550b73 575
chris 15:67dfa5550b73 576 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
chris 15:67dfa5550b73 577 pixel(draw_x5, draw_y5, color);
chris 15:67dfa5550b73 578 }
chris 15:67dfa5550b73 579 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
chris 15:67dfa5550b73 580 pixel(draw_x6, draw_y6, color);
chris 15:67dfa5550b73 581 }
chris 15:67dfa5550b73 582 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
chris 15:67dfa5550b73 583 pixel(draw_x7, draw_y7, color);
chris 15:67dfa5550b73 584 }
chris 15:67dfa5550b73 585 }
chris 15:67dfa5550b73 586 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 587 }
chris 15:67dfa5550b73 588
chris 16:7de323fa46fe 589 void C12832::fillcircle(int x, int y, int r, int color)
chris 15:67dfa5550b73 590 {
chris 15:67dfa5550b73 591 int i,up;
chris 15:67dfa5550b73 592 up = auto_up;
chris 15:67dfa5550b73 593 auto_up = 0; // off
chris 15:67dfa5550b73 594 for (i = 0; i <= r; i++)
chris 15:67dfa5550b73 595 circle(x,y,i,color);
chris 15:67dfa5550b73 596 auto_up = up;
chris 15:67dfa5550b73 597 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 598 }
chris 15:67dfa5550b73 599
chris 16:7de323fa46fe 600 void C12832::setmode(int mode)
chris 15:67dfa5550b73 601 {
chris 15:67dfa5550b73 602 draw_mode = mode;
chris 15:67dfa5550b73 603 }
chris 15:67dfa5550b73 604
chris 16:7de323fa46fe 605 void C12832::locate(int x, int y)
chris 15:67dfa5550b73 606 {
chris 15:67dfa5550b73 607 char_x = x;
chris 15:67dfa5550b73 608 char_y = y;
chris 15:67dfa5550b73 609 }
chris 15:67dfa5550b73 610
chris 15:67dfa5550b73 611
chris 15:67dfa5550b73 612
chris 16:7de323fa46fe 613 int C12832::columns()
chris 15:67dfa5550b73 614 {
chris 15:67dfa5550b73 615 return width() / font[1];
chris 15:67dfa5550b73 616 }
chris 15:67dfa5550b73 617
chris 15:67dfa5550b73 618
chris 15:67dfa5550b73 619
chris 16:7de323fa46fe 620 int C12832::rows()
chris 15:67dfa5550b73 621 {
chris 15:67dfa5550b73 622 return height() / font[2];
chris 15:67dfa5550b73 623 }
chris 15:67dfa5550b73 624
chris 15:67dfa5550b73 625
chris 15:67dfa5550b73 626
chris 16:7de323fa46fe 627 int C12832::_putc(int value)
chris 15:67dfa5550b73 628 {
chris 15:67dfa5550b73 629 if (value == '\n') { // new line
chris 15:67dfa5550b73 630 char_x = 0;
chris 15:67dfa5550b73 631 char_y = char_y + font[2];
chris 15:67dfa5550b73 632 if (char_y >= height() - font[2]) {
chris 15:67dfa5550b73 633 char_y = 0;
chris 15:67dfa5550b73 634 }
chris 15:67dfa5550b73 635 } else {
chris 15:67dfa5550b73 636 character(char_x, char_y, value);
chris 15:67dfa5550b73 637 if(auto_up) copy_to_lcd();
chris 15:67dfa5550b73 638 }
chris 15:67dfa5550b73 639 return value;
chris 15:67dfa5550b73 640 }
chris 15:67dfa5550b73 641
chris 16:7de323fa46fe 642 void C12832::character(int x, int y, int c)
chris 15:67dfa5550b73 643 {
chris 15:67dfa5550b73 644 unsigned int hor,vert,offset,bpl,j,i,b;
chris 15:67dfa5550b73 645 unsigned char* zeichen;
chris 15:67dfa5550b73 646 unsigned char z,w;
chris 15:67dfa5550b73 647
chris 15:67dfa5550b73 648 if ((c < 31) || (c > 127)) return; // test char range
chris 15:67dfa5550b73 649
chris 15:67dfa5550b73 650 // read font parameter from start of array
chris 15:67dfa5550b73 651 offset = font[0]; // bytes / char
chris 15:67dfa5550b73 652 hor = font[1]; // get hor size of font
chris 15:67dfa5550b73 653 vert = font[2]; // get vert size of font
chris 15:67dfa5550b73 654 bpl = font[3]; // bytes per line
chris 15:67dfa5550b73 655
chris 15:67dfa5550b73 656 if (char_x + hor > width()) {
chris 15:67dfa5550b73 657 char_x = 0;
chris 15:67dfa5550b73 658 char_y = char_y + vert;
chris 15:67dfa5550b73 659 if (char_y >= height() - font[2]) {
chris 15:67dfa5550b73 660 char_y = 0;
chris 15:67dfa5550b73 661 }
chris 15:67dfa5550b73 662 }
chris 15:67dfa5550b73 663
chris 15:67dfa5550b73 664 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
chris 15:67dfa5550b73 665 w = zeichen[0]; // width of actual char
chris 15:67dfa5550b73 666 // construct the char into the buffer
chris 15:67dfa5550b73 667 for (j=0; j<vert; j++) { // vert line
chris 15:67dfa5550b73 668 for (i=0; i<hor; i++) { // horz line
chris 15:67dfa5550b73 669 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
chris 15:67dfa5550b73 670 b = 1 << (j & 0x07);
chris 15:67dfa5550b73 671 if (( z & b ) == 0x00) {
chris 15:67dfa5550b73 672 pixel(x+i,y+j,0);
chris 15:67dfa5550b73 673 } else {
chris 15:67dfa5550b73 674 pixel(x+i,y+j,1);
chris 15:67dfa5550b73 675 }
chris 15:67dfa5550b73 676
chris 15:67dfa5550b73 677 }
chris 15:67dfa5550b73 678 }
chris 15:67dfa5550b73 679
chris 15:67dfa5550b73 680 char_x += w;
chris 15:67dfa5550b73 681 }
chris 15:67dfa5550b73 682
chris 15:67dfa5550b73 683
chris 16:7de323fa46fe 684 void C12832::set_font(unsigned char* f)
chris 15:67dfa5550b73 685 {
chris 15:67dfa5550b73 686 font = f;
chris 15:67dfa5550b73 687 }
chris 15:67dfa5550b73 688
chris 16:7de323fa46fe 689 void C12832::set_auto_up(unsigned int up)
chris 15:67dfa5550b73 690 {
chris 15:67dfa5550b73 691 if(up ) auto_up = 1;
chris 15:67dfa5550b73 692 else auto_up = 0;
chris 15:67dfa5550b73 693 }
chris 15:67dfa5550b73 694
chris 16:7de323fa46fe 695 unsigned int C12832::get_auto_up(void)
chris 15:67dfa5550b73 696 {
chris 15:67dfa5550b73 697 return (auto_up);
chris 15:67dfa5550b73 698 }
chris 15:67dfa5550b73 699
chris 16:7de323fa46fe 700 void C12832::print_bm(Bitmap bm, int x, int y)
chris 15:67dfa5550b73 701 {
chris 15:67dfa5550b73 702 int h,v,b;
chris 15:67dfa5550b73 703 char d;
chris 15:67dfa5550b73 704
chris 15:67dfa5550b73 705 for(v=0; v < bm.ySize; v++) { // lines
chris 15:67dfa5550b73 706 for(h=0; h < bm.xSize; h++) { // pixel
chris 15:67dfa5550b73 707 if(h + x > 127) break;
chris 15:67dfa5550b73 708 if(v + y > 31) break;
chris 15:67dfa5550b73 709 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
chris 15:67dfa5550b73 710 b = 0x80 >> (h & 0x07);
chris 15:67dfa5550b73 711 if((d & b) == 0) {
chris 15:67dfa5550b73 712 pixel(x+h,y+v,0);
chris 15:67dfa5550b73 713 } else {
chris 15:67dfa5550b73 714 pixel(x+h,y+v,1);
chris 15:67dfa5550b73 715 }
chris 15:67dfa5550b73 716 }
chris 15:67dfa5550b73 717 }
chris 15:67dfa5550b73 718
chris 15:67dfa5550b73 719 }
chris 15:67dfa5550b73 720
chris 15:67dfa5550b73 721