This Library for DOGS-102 Graphic LCD module. Based on Igor Skochinsky's "DOGLCDDemo" program.

Dependents:   DOGS102_Example1 DOGS102_Example2

Fork of DOGLCDDemo by Igor Skochinsky

Committer:
ban4jp
Date:
Sat May 03 16:04:16 2014 +0000
Revision:
1:2145a74df666
Parent:
0:2a5dccfd318f
Change to library, and Support DOGS-102 Graphic LCD module.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
igorsk 0:2a5dccfd318f 1 #include "DogLCD.h"
igorsk 0:2a5dccfd318f 2
igorsk 0:2a5dccfd318f 3 // macro to make sure x falls into range from low to high (inclusive)
igorsk 0:2a5dccfd318f 4 #define CLAMP(x, low, high) { if ( (x) < (low) ) x = (low); if ( (x) > (high) ) x = (high); } while (0);
igorsk 0:2a5dccfd318f 5
igorsk 0:2a5dccfd318f 6 void DogLCD::_send_commands(const unsigned char* buf, size_t size)
igorsk 0:2a5dccfd318f 7 {
igorsk 0:2a5dccfd318f 8 // for commands, A0 is low
ban4jp 1:2145a74df666 9 #ifdef READJUST_SPI_FREQUENCY
igorsk 0:2a5dccfd318f 10 _spi.format(8,0);
igorsk 0:2a5dccfd318f 11 _spi.frequency(10000000);
ban4jp 1:2145a74df666 12 #endif
igorsk 0:2a5dccfd318f 13 _cs = 0;
igorsk 0:2a5dccfd318f 14 _a0 = 0;
igorsk 0:2a5dccfd318f 15 while ( size-- > 0 )
igorsk 0:2a5dccfd318f 16 _spi.write(*buf++);
igorsk 0:2a5dccfd318f 17 _cs = 1;
igorsk 0:2a5dccfd318f 18 }
igorsk 0:2a5dccfd318f 19
igorsk 0:2a5dccfd318f 20 void DogLCD::_send_data(const unsigned char* buf, size_t size)
igorsk 0:2a5dccfd318f 21 {
igorsk 0:2a5dccfd318f 22 // for data, A0 is high
ban4jp 1:2145a74df666 23 #ifdef READJUST_SPI_FREQUENCY
igorsk 0:2a5dccfd318f 24 _spi.format(8,0);
igorsk 0:2a5dccfd318f 25 _spi.frequency(10000000);
ban4jp 1:2145a74df666 26 #endif
igorsk 0:2a5dccfd318f 27 _cs = 0;
igorsk 0:2a5dccfd318f 28 _a0 = 1;
igorsk 0:2a5dccfd318f 29 while ( size-- > 0 )
igorsk 0:2a5dccfd318f 30 _spi.write(*buf++);
igorsk 0:2a5dccfd318f 31 _cs = 1;
igorsk 0:2a5dccfd318f 32 _a0 = 0;
igorsk 0:2a5dccfd318f 33 }
igorsk 0:2a5dccfd318f 34
igorsk 0:2a5dccfd318f 35 // set column and page number
igorsk 0:2a5dccfd318f 36 void DogLCD::_set_xy(int x, int y)
igorsk 0:2a5dccfd318f 37 {
igorsk 0:2a5dccfd318f 38 //printf("_set_xy(%d,%d)\n", x, y);
igorsk 0:2a5dccfd318f 39 CLAMP(x, 0, LCDWIDTH-1);
igorsk 0:2a5dccfd318f 40 CLAMP(y, 0, LCDPAGES-1);
igorsk 0:2a5dccfd318f 41 unsigned char cmd[3];
igorsk 0:2a5dccfd318f 42 cmd[0] = 0xB0 | (y&0xF);
ban4jp 1:2145a74df666 43 cmd[1] = (x&0xF);
ban4jp 1:2145a74df666 44 cmd[2] = 0x10 | ((x>>4)&0xF);
igorsk 0:2a5dccfd318f 45 _send_commands(cmd, 3);
igorsk 0:2a5dccfd318f 46 }
igorsk 0:2a5dccfd318f 47
igorsk 0:2a5dccfd318f 48 // initialize and turn on the display
igorsk 0:2a5dccfd318f 49 void DogLCD::init()
igorsk 0:2a5dccfd318f 50 {
igorsk 0:2a5dccfd318f 51 const unsigned char init_seq[] = {
igorsk 0:2a5dccfd318f 52 0x40, //Display start line 0
igorsk 0:2a5dccfd318f 53 0xa1, //ADC reverse
igorsk 0:2a5dccfd318f 54 0xc0, //Normal COM0...COM63
igorsk 0:2a5dccfd318f 55 0xa6, //Display normal
igorsk 0:2a5dccfd318f 56 0xa2, //Set Bias 1/9 (Duty 1/65)
igorsk 0:2a5dccfd318f 57 0x2f, //Booster, Regulator and Follower On
igorsk 0:2a5dccfd318f 58 0xf8, //Set internal Booster to 4x
igorsk 0:2a5dccfd318f 59 0x00,
igorsk 0:2a5dccfd318f 60 0x27, //Contrast set
igorsk 0:2a5dccfd318f 61 0x81,
ban4jp 1:2145a74df666 62 0x09,
igorsk 0:2a5dccfd318f 63 0xac, //No indicator
igorsk 0:2a5dccfd318f 64 0x00,
igorsk 0:2a5dccfd318f 65 0xaf, //Display on
igorsk 0:2a5dccfd318f 66 };
ban4jp 1:2145a74df666 67 #ifndef READJUST_SPI_FREQUENCY
ban4jp 1:2145a74df666 68 _spi.format(8,0);
ban4jp 1:2145a74df666 69 _spi.frequency(10000000);
ban4jp 1:2145a74df666 70 #endif
igorsk 0:2a5dccfd318f 71 //printf("Reset=L\n");
igorsk 0:2a5dccfd318f 72 _reset = 0;
ban4jp 1:2145a74df666 73 _cs = 1;
ban4jp 1:2145a74df666 74 wait_ms(1);
ban4jp 1:2145a74df666 75 #ifdef ENABLE_DOGLCD_POWERCTL
igorsk 0:2a5dccfd318f 76 //printf("Power=H\n");
igorsk 0:2a5dccfd318f 77 _power = 1;
igorsk 0:2a5dccfd318f 78 //wait_ms(1);
ban4jp 1:2145a74df666 79 #endif
igorsk 0:2a5dccfd318f 80 //printf("Reset=H\n");
igorsk 0:2a5dccfd318f 81 _reset = 1;
ban4jp 1:2145a74df666 82 wait_ms(5);
igorsk 0:2a5dccfd318f 83 //printf("Sending init commands\n");
igorsk 0:2a5dccfd318f 84 _send_commands(init_seq, sizeof(init_seq));
igorsk 0:2a5dccfd318f 85 }
igorsk 0:2a5dccfd318f 86
igorsk 0:2a5dccfd318f 87 void DogLCD::send_pic(const unsigned char* data)
igorsk 0:2a5dccfd318f 88 {
igorsk 0:2a5dccfd318f 89 //printf("Sending picture\n");
igorsk 0:2a5dccfd318f 90 for (int i=0; i<LCDPAGES; i++)
igorsk 0:2a5dccfd318f 91 {
igorsk 0:2a5dccfd318f 92 _set_xy(0, i);
igorsk 0:2a5dccfd318f 93 _send_data(data + i*LCDWIDTH, LCDWIDTH);
igorsk 0:2a5dccfd318f 94 }
igorsk 0:2a5dccfd318f 95 }
igorsk 0:2a5dccfd318f 96
igorsk 0:2a5dccfd318f 97 void DogLCD::clear_screen()
igorsk 0:2a5dccfd318f 98 {
igorsk 0:2a5dccfd318f 99 //printf("Clear screen\n");
igorsk 0:2a5dccfd318f 100 memset(_framebuffer, 0, sizeof(_framebuffer));
igorsk 0:2a5dccfd318f 101 if ( _updating == 0 )
igorsk 0:2a5dccfd318f 102 {
igorsk 0:2a5dccfd318f 103 send_pic(_framebuffer);
igorsk 0:2a5dccfd318f 104 }
igorsk 0:2a5dccfd318f 105 }
igorsk 0:2a5dccfd318f 106
igorsk 0:2a5dccfd318f 107 void DogLCD::all_on(bool on)
igorsk 0:2a5dccfd318f 108 {
igorsk 0:2a5dccfd318f 109 //printf("Sending all on %d\n", on);
igorsk 0:2a5dccfd318f 110 unsigned char cmd = 0xA4 | (on ? 1 : 0);
igorsk 0:2a5dccfd318f 111 _send_commands(&cmd, 1);
igorsk 0:2a5dccfd318f 112 }
igorsk 0:2a5dccfd318f 113
igorsk 0:2a5dccfd318f 114 void DogLCD::pixel(int x, int y, int colour)
igorsk 0:2a5dccfd318f 115 {
igorsk 0:2a5dccfd318f 116 CLAMP(x, 0, LCDWIDTH-1);
igorsk 0:2a5dccfd318f 117 CLAMP(y, 0, LCDHEIGHT-1);
igorsk 0:2a5dccfd318f 118 int page = y / 8;
igorsk 0:2a5dccfd318f 119 unsigned char mask = 1<<(y%8);
igorsk 0:2a5dccfd318f 120 unsigned char *byte = &_framebuffer[page*LCDWIDTH + x];
igorsk 0:2a5dccfd318f 121 if ( colour == 0 )
igorsk 0:2a5dccfd318f 122 *byte &= ~mask; // clear pixel
igorsk 0:2a5dccfd318f 123 else
igorsk 0:2a5dccfd318f 124 *byte |= mask; // set pixel
igorsk 0:2a5dccfd318f 125 if ( !_updating )
igorsk 0:2a5dccfd318f 126 {
igorsk 0:2a5dccfd318f 127 _set_xy(x, page);
igorsk 0:2a5dccfd318f 128 _send_data(byte, 1);
igorsk 0:2a5dccfd318f 129 }
igorsk 0:2a5dccfd318f 130 }
igorsk 0:2a5dccfd318f 131
igorsk 0:2a5dccfd318f 132 void DogLCD::fill(int x, int y, int width, int height, int colour)
igorsk 0:2a5dccfd318f 133 {
igorsk 0:2a5dccfd318f 134 /*
igorsk 0:2a5dccfd318f 135 If we need to fill partial pages at the top:
igorsk 0:2a5dccfd318f 136
igorsk 0:2a5dccfd318f 137 ......+---+---+.....
igorsk 0:2a5dccfd318f 138 ^ | = | = | = : don't touch
igorsk 0:2a5dccfd318f 139 | | = | = | * : update
igorsk 0:2a5dccfd318f 140 y%8 | = | = |
igorsk 0:2a5dccfd318f 141 | | = | = |
igorsk 0:2a5dccfd318f 142 v | = | = |
igorsk 0:2a5dccfd318f 143 y----> | * | * |
igorsk 0:2a5dccfd318f 144 | * | * |
igorsk 0:2a5dccfd318f 145 | * | * |
igorsk 0:2a5dccfd318f 146 +---+---+
igorsk 0:2a5dccfd318f 147 */
igorsk 0:2a5dccfd318f 148 //printf("fill(x=%d, y=%d, width=%d, height=%d, colour=%x)\n", x, y, width, height, colour);
igorsk 0:2a5dccfd318f 149 CLAMP(x, 0, LCDWIDTH-1);
igorsk 0:2a5dccfd318f 150 CLAMP(y, 0, LCDHEIGHT-1);
igorsk 0:2a5dccfd318f 151 CLAMP(width, 0, LCDWIDTH - x);
igorsk 0:2a5dccfd318f 152 CLAMP(height, 0, LCDHEIGHT - y);
igorsk 0:2a5dccfd318f 153 int page = y/8;
igorsk 0:2a5dccfd318f 154 int firstpage = page;
igorsk 0:2a5dccfd318f 155 int partpage = y%8;
igorsk 0:2a5dccfd318f 156 if ( partpage != 0 )
igorsk 0:2a5dccfd318f 157 {
igorsk 0:2a5dccfd318f 158 // we need to process partial bytes in the top page
igorsk 0:2a5dccfd318f 159 unsigned char mask = (1<<partpage) - 1; // this mask has 1s for bits we need to leave
igorsk 0:2a5dccfd318f 160 unsigned char *bytes = &_framebuffer[page*LCDWIDTH + x];
igorsk 0:2a5dccfd318f 161 for ( int i = 0; i < width; i++, bytes++ )
igorsk 0:2a5dccfd318f 162 {
igorsk 0:2a5dccfd318f 163 // clear "our" bits
igorsk 0:2a5dccfd318f 164 *bytes &= mask;
igorsk 0:2a5dccfd318f 165 if ( colour != 0 )
igorsk 0:2a5dccfd318f 166 *bytes |= ~mask; // set our bits
igorsk 0:2a5dccfd318f 167 }
igorsk 0:2a5dccfd318f 168 height -= partpage;
igorsk 0:2a5dccfd318f 169 page++;
igorsk 0:2a5dccfd318f 170 }
igorsk 0:2a5dccfd318f 171 while ( height >= 8 )
igorsk 0:2a5dccfd318f 172 {
igorsk 0:2a5dccfd318f 173 memset(&_framebuffer[page*LCDWIDTH + x], colour == 0 ? 0 : 0xFF, width);
igorsk 0:2a5dccfd318f 174 page++;
igorsk 0:2a5dccfd318f 175 height -= 8;
igorsk 0:2a5dccfd318f 176 }
igorsk 0:2a5dccfd318f 177 if ( height != 0 )
igorsk 0:2a5dccfd318f 178 {
igorsk 0:2a5dccfd318f 179 // we need to process partial bytes in the bottom page
igorsk 0:2a5dccfd318f 180 unsigned char mask = ~((1<<partpage) - 1); // this mask has 1s for bits we need to leave
igorsk 0:2a5dccfd318f 181 unsigned char *bytes = &_framebuffer[page*LCDWIDTH + x];
igorsk 0:2a5dccfd318f 182 for ( int i = 0; i < width; i++, bytes++ )
igorsk 0:2a5dccfd318f 183 {
igorsk 0:2a5dccfd318f 184 // clear "our" bits
igorsk 0:2a5dccfd318f 185 *bytes &= mask;
igorsk 0:2a5dccfd318f 186 if ( colour != 0 )
igorsk 0:2a5dccfd318f 187 *bytes |= ~mask; // set our bits
igorsk 0:2a5dccfd318f 188 }
igorsk 0:2a5dccfd318f 189 page++;
igorsk 0:2a5dccfd318f 190 }
igorsk 0:2a5dccfd318f 191 //printf("_updating=%d\n", _updating);
igorsk 0:2a5dccfd318f 192 if ( !_updating )
igorsk 0:2a5dccfd318f 193 {
igorsk 0:2a5dccfd318f 194 int laststpage = page;
igorsk 0:2a5dccfd318f 195 for ( page = firstpage; page < laststpage; page++)
igorsk 0:2a5dccfd318f 196 {
igorsk 0:2a5dccfd318f 197 //printf("setting x=%d, page=%d\n", x, page);
igorsk 0:2a5dccfd318f 198 _set_xy(x, page);
igorsk 0:2a5dccfd318f 199 //printf("sending %d bytes at offset %x\n", width, page*LCDWIDTH + x);
igorsk 0:2a5dccfd318f 200 _send_data(&_framebuffer[page*LCDWIDTH + x], width);
igorsk 0:2a5dccfd318f 201 }
igorsk 0:2a5dccfd318f 202 }
igorsk 0:2a5dccfd318f 203 }
igorsk 0:2a5dccfd318f 204
igorsk 0:2a5dccfd318f 205 void DogLCD::beginupdate()
igorsk 0:2a5dccfd318f 206 {
igorsk 0:2a5dccfd318f 207 _updating++;
igorsk 0:2a5dccfd318f 208 //printf("beginupdate: %d\n", _updating);
igorsk 0:2a5dccfd318f 209 }
igorsk 0:2a5dccfd318f 210
igorsk 0:2a5dccfd318f 211 void DogLCD::endupdate()
igorsk 0:2a5dccfd318f 212 {
igorsk 0:2a5dccfd318f 213 _updating--;
igorsk 0:2a5dccfd318f 214 //printf("endupdate: %d\n", _updating);
igorsk 0:2a5dccfd318f 215 if ( _updating == 0 )
igorsk 0:2a5dccfd318f 216 {
igorsk 0:2a5dccfd318f 217 send_pic(_framebuffer);
igorsk 0:2a5dccfd318f 218 }
igorsk 0:2a5dccfd318f 219 }