Simple library for interfacing to Nokia 5110 LCD display (as found on the SparkFun website). Edited to include additional feaatures, such as 2d array loading, multiple screen buffers, and better backlight control

Dependencies:   N5110

Dependents:   Main_code_ver18

Fork of N5110 by Craig Evans

Committer:
el14pjgn
Date:
Mon May 09 14:18:12 2016 +0000
Revision:
18:d2140be00144
Parent:
17:780a542d5f8b
Expanded to include 2d array printing, backlight setting adjustment, and other similar features.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 5:6ea180eef702 1 /**
eencae 5:6ea180eef702 2 @file N5110.cpp
eencae 5:6ea180eef702 3
eencae 5:6ea180eef702 4 @brief Member functions implementations
eencae 5:6ea180eef702 5
eencae 5:6ea180eef702 6 */
eencae 0:d563e74f0ae9 7 #include "mbed.h"
eencae 0:d563e74f0ae9 8 #include "N5110.h"
eencae 0:d563e74f0ae9 9
eencae 2:e93021cfb0a9 10
eencae 1:df68f34cd32d 11 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
eencae 0:d563e74f0ae9 12 {
eencae 13:908644099648 13
eencae 0:d563e74f0ae9 14 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
eencae 13:908644099648 15 initSPI();
eencae 13:908644099648 16
eencae 6:adb79338d40f 17 // set up pins as required
eencae 0:d563e74f0ae9 18 led = new PwmOut(ledPin);
eencae 0:d563e74f0ae9 19 pwr = new DigitalOut(pwrPin);
eencae 0:d563e74f0ae9 20 sce = new DigitalOut(scePin);
eencae 0:d563e74f0ae9 21 rst = new DigitalOut(rstPin);
eencae 0:d563e74f0ae9 22 dc = new DigitalOut(dcPin);
el14pjgn 18:d2140be00144 23 bufferFrameEdit = 1;
el14pjgn 18:d2140be00144 24 bufferFrameDisplay = 1;
eencae 0:d563e74f0ae9 25
eencae 0:d563e74f0ae9 26 }
eencae 0:d563e74f0ae9 27
eencae 6:adb79338d40f 28 // initialise function - powers up and sends the initialisation commands
eencae 0:d563e74f0ae9 29 void N5110::init()
eencae 0:d563e74f0ae9 30 {
eencae 6:adb79338d40f 31 turnOn(); // power up
eencae 6:adb79338d40f 32 wait_ms(10); // small delay seems to prevent spurious pixels during mbed reset
eencae 6:adb79338d40f 33 reset(); // reset LCD - must be done within 100 ms
eencae 0:d563e74f0ae9 34
eencae 0:d563e74f0ae9 35 // function set - extended
eencae 0:d563e74f0ae9 36 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 37 // Don't completely understand these parameters - they seem to work as they are
eencae 6:adb79338d40f 38 // Consult the datasheet if you need to change them
eencae 1:df68f34cd32d 39 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library
eencae 0:d563e74f0ae9 40 sendCommand(CMD_TC_TEMP_2); // temperature control
eencae 0:d563e74f0ae9 41 sendCommand(CMD_BI_MUX_48); // bias
eencae 0:d563e74f0ae9 42
eencae 0:d563e74f0ae9 43 // function set - basic
eencae 0:d563e74f0ae9 44 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 1:df68f34cd32d 45 normalMode(); // normal video mode by default
eencae 0:d563e74f0ae9 46 sendCommand(CMD_DC_NORMAL_MODE); // black on white
eencae 0:d563e74f0ae9 47
eencae 0:d563e74f0ae9 48 // RAM is undefined at power-up so clear
eencae 0:d563e74f0ae9 49 clearRAM();
eencae 0:d563e74f0ae9 50
eencae 0:d563e74f0ae9 51 }
eencae 13:908644099648 52
eencae 13:908644099648 53 // sets normal video mode (black on white)
eencae 13:908644099648 54 void N5110::normalMode()
eencae 13:908644099648 55 {
eencae 13:908644099648 56 sendCommand(CMD_DC_NORMAL_MODE);
eencae 13:908644099648 57
eencae 1:df68f34cd32d 58 }
eencae 1:df68f34cd32d 59
eencae 13:908644099648 60 // sets normal video mode (white on black)
eencae 13:908644099648 61 void N5110::inverseMode()
eencae 13:908644099648 62 {
eencae 13:908644099648 63 sendCommand(CMD_DC_INVERT_VIDEO);
eencae 1:df68f34cd32d 64 }
eencae 0:d563e74f0ae9 65
eencae 0:d563e74f0ae9 66 // function to power up the LCD and backlight
eencae 0:d563e74f0ae9 67 void N5110::turnOn()
eencae 0:d563e74f0ae9 68 {
eencae 0:d563e74f0ae9 69 // set brightness of LED - 0.0 to 1.0 - default is 50%
eencae 0:d563e74f0ae9 70 setBrightness(0.5);
eencae 0:d563e74f0ae9 71 pwr->write(1); // apply power
eencae 0:d563e74f0ae9 72 }
eencae 0:d563e74f0ae9 73
eencae 0:d563e74f0ae9 74 // function to power down LCD
eencae 0:d563e74f0ae9 75 void N5110::turnOff()
eencae 0:d563e74f0ae9 76 {
eencae 0:d563e74f0ae9 77 setBrightness(0.0); // turn backlight off
eencae 0:d563e74f0ae9 78 clearRAM(); // clear RAM to ensure specified current consumption
eencae 10:6f3abb40202b 79 // send command to ensure we are in basic mode
eencae 0:d563e74f0ae9 80 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 6:adb79338d40f 81 // clear the display
eencae 0:d563e74f0ae9 82 sendCommand(CMD_DC_CLEAR_DISPLAY);
eencae 6:adb79338d40f 83 // enter the extended mode and power down
eencae 0:d563e74f0ae9 84 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 85 // small delay and then turn off the power pin
eencae 6:adb79338d40f 86 wait_ms(10);
eencae 0:d563e74f0ae9 87 pwr->write(0);
eencae 0:d563e74f0ae9 88
eencae 0:d563e74f0ae9 89 }
eencae 0:d563e74f0ae9 90
eencae 0:d563e74f0ae9 91 // function to change LED backlight brightness
eencae 0:d563e74f0ae9 92 void N5110::setBrightness(float brightness)
eencae 0:d563e74f0ae9 93 {
eencae 0:d563e74f0ae9 94 // check whether brightness is within range
eencae 0:d563e74f0ae9 95 if (brightness < 0.0)
eencae 0:d563e74f0ae9 96 brightness = 0.0;
eencae 0:d563e74f0ae9 97 if (brightness > 1.0)
eencae 0:d563e74f0ae9 98 brightness = 1.0;
eencae 0:d563e74f0ae9 99 // set PWM duty cycle
eencae 0:d563e74f0ae9 100 led->write(brightness);
eencae 0:d563e74f0ae9 101 }
eencae 0:d563e74f0ae9 102
el14pjgn 18:d2140be00144 103 // function to change LED backlight PWM frequency
el14pjgn 18:d2140be00144 104 void N5110::setPwmFreq(float freq)
el14pjgn 18:d2140be00144 105 {
el14pjgn 18:d2140be00144 106 led->period_us(freq);
el14pjgn 18:d2140be00144 107 }
el14pjgn 18:d2140be00144 108
eencae 0:d563e74f0ae9 109
eencae 0:d563e74f0ae9 110 // pulse the active low reset line
eencae 0:d563e74f0ae9 111 void N5110::reset()
eencae 0:d563e74f0ae9 112 {
eencae 0:d563e74f0ae9 113 rst->write(0); // reset the LCD
eencae 0:d563e74f0ae9 114 rst->write(1);
eencae 0:d563e74f0ae9 115 }
eencae 0:d563e74f0ae9 116
eencae 0:d563e74f0ae9 117 // function to initialise SPI peripheral
eencae 0:d563e74f0ae9 118 void N5110::initSPI()
eencae 0:d563e74f0ae9 119 {
eencae 0:d563e74f0ae9 120 spi->format(8,1); // 8 bits, Mode 1 - polarity 0, phase 1 - base value of clock is 0, data captured on falling edge/propagated on rising edge
eencae 0:d563e74f0ae9 121 spi->frequency(4000000); // maximum of screen is 4 MHz
eencae 0:d563e74f0ae9 122 }
eencae 0:d563e74f0ae9 123
eencae 6:adb79338d40f 124 // send a command to the display
eencae 0:d563e74f0ae9 125 void N5110::sendCommand(unsigned char command)
eencae 0:d563e74f0ae9 126 {
eencae 0:d563e74f0ae9 127 dc->write(0); // set DC low for command
eencae 0:d563e74f0ae9 128 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 129 spi->write(command); // send command
eencae 0:d563e74f0ae9 130 dc->write(1); // turn back to data by default
eencae 0:d563e74f0ae9 131 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 132
eencae 0:d563e74f0ae9 133 }
eencae 0:d563e74f0ae9 134
eencae 6:adb79338d40f 135 // send data to the display at the current XY address
eencae 6:adb79338d40f 136 // dc is set to 1 (i.e. data) after sending a command and so should
eencae 6:adb79338d40f 137 // be the default mode.
eencae 0:d563e74f0ae9 138 void N5110::sendData(unsigned char data)
eencae 0:d563e74f0ae9 139 {
eencae 0:d563e74f0ae9 140 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 141 spi->write(data);
eencae 0:d563e74f0ae9 142 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 143 }
eencae 0:d563e74f0ae9 144
eencae 0:d563e74f0ae9 145 // this function writes 0 to the 504 bytes to clear the RAM
eencae 0:d563e74f0ae9 146 void N5110::clearRAM()
eencae 0:d563e74f0ae9 147 {
eencae 0:d563e74f0ae9 148 int i;
eencae 0:d563e74f0ae9 149 sce->write(0); //set CE low to begin frame
eencae 17:780a542d5f8b 150 for(i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes
eencae 0:d563e74f0ae9 151 spi->write(0x00); // send 0's
eencae 0:d563e74f0ae9 152 }
eencae 0:d563e74f0ae9 153 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 154
eencae 0:d563e74f0ae9 155 }
eencae 0:d563e74f0ae9 156
eencae 13:908644099648 157 // function to set the XY address in RAM for subsequenct data write
eencae 0:d563e74f0ae9 158 void N5110::setXYAddress(int x, int y)
eencae 0:d563e74f0ae9 159 {
eencae 17:780a542d5f8b 160 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
eencae 17:780a542d5f8b 161 sendCommand(0x80 | x); // send addresses to display with relevant mask
eencae 17:780a542d5f8b 162 sendCommand(0x40 | y);
eencae 17:780a542d5f8b 163 }
eencae 0:d563e74f0ae9 164 }
eencae 0:d563e74f0ae9 165
el14pjgn 18:d2140be00144 166 void N5110::selectBuffer(int type,int buffer)
el14pjgn 18:d2140be00144 167 {
el14pjgn 18:d2140be00144 168 switch(type) {
el14pjgn 18:d2140be00144 169 case 1: //display
el14pjgn 18:d2140be00144 170 bufferFrameDisplay = buffer;
el14pjgn 18:d2140be00144 171 break;
el14pjgn 18:d2140be00144 172 case 2: //editable
el14pjgn 18:d2140be00144 173 bufferFrameEdit = buffer;
el14pjgn 18:d2140be00144 174 break;
el14pjgn 18:d2140be00144 175 case 3: //both
el14pjgn 18:d2140be00144 176 bufferFrameEdit = buffer;
el14pjgn 18:d2140be00144 177 bufferFrameDisplay = buffer;
el14pjgn 18:d2140be00144 178 break;
el14pjgn 18:d2140be00144 179 }
el14pjgn 18:d2140be00144 180 }
el14pjgn 18:d2140be00144 181
eencae 6:adb79338d40f 182 // These functions are used to set, clear and get the value of pixels in the display
eencae 6:adb79338d40f 183 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
eencae 6:adb79338d40f 184 // function must be called after set and clear in order to update the display
el14pjgn 18:d2140be00144 185 void N5110::writePixel(int x, int y, int v)
el14pjgn 18:d2140be00144 186 {
el14pjgn 18:d2140be00144 187 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
el14pjgn 18:d2140be00144 188 // calculate bank and shift 1 to required position in the data byte
el14pjgn 18:d2140be00144 189 if(v==1) {
el14pjgn 18:d2140be00144 190 buffer[x][y/8][bufferFrameEdit] |= (1 << y%8);
el14pjgn 18:d2140be00144 191 }
el14pjgn 18:d2140be00144 192 if(v==0) {
el14pjgn 18:d2140be00144 193 buffer[x][y/8][bufferFrameEdit] &= ~(1 << y%8);
el14pjgn 18:d2140be00144 194 }
el14pjgn 18:d2140be00144 195 }
el14pjgn 18:d2140be00144 196 }
el14pjgn 18:d2140be00144 197
eencae 0:d563e74f0ae9 198 void N5110::setPixel(int x, int y)
eencae 0:d563e74f0ae9 199 {
eencae 17:780a542d5f8b 200 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
eencae 17:780a542d5f8b 201 // calculate bank and shift 1 to required position in the data byte
el14pjgn 18:d2140be00144 202 buffer[x][y/8][bufferFrameEdit] |= (1 << y%8);
eencae 17:780a542d5f8b 203 }
eencae 0:d563e74f0ae9 204 }
eencae 0:d563e74f0ae9 205
eencae 0:d563e74f0ae9 206 void N5110::clearPixel(int x, int y)
eencae 0:d563e74f0ae9 207 {
eencae 17:780a542d5f8b 208 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
eencae 17:780a542d5f8b 209 // calculate bank and shift 1 to required position (using bit clear)
el14pjgn 18:d2140be00144 210 buffer[x][y/8][bufferFrameEdit] &= ~(1 << y%8);
eencae 17:780a542d5f8b 211 }
eencae 0:d563e74f0ae9 212 }
eencae 0:d563e74f0ae9 213
eencae 7:3010f24e0a81 214 int N5110::getPixel(int x, int y)
eencae 0:d563e74f0ae9 215 {
eencae 17:780a542d5f8b 216 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
eencae 17:780a542d5f8b 217 // return relevant bank and mask required bit
el14pjgn 18:d2140be00144 218 return (int) buffer[x][y/8][bufferFrameEdit] & (1 << y%8);
eencae 17:780a542d5f8b 219 } else {
eencae 17:780a542d5f8b 220 return 0;
eencae 17:780a542d5f8b 221 }
eencae 0:d563e74f0ae9 222 }
eencae 0:d563e74f0ae9 223
eencae 6:adb79338d40f 224 // function to refresh the display
eencae 6:adb79338d40f 225 void N5110::refresh()
eencae 0:d563e74f0ae9 226 {
eencae 0:d563e74f0ae9 227 int i,j;
eencae 13:908644099648 228
eencae 7:3010f24e0a81 229 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
eencae 7:3010f24e0a81 230 // address auto increments after printing string, so buffer[0][0] will not coincide
eencae 7:3010f24e0a81 231 // with top-left pixel after priting string
eencae 13:908644099648 232
eencae 0:d563e74f0ae9 233 sce->write(0); //set CE low to begin frame
eencae 0:d563e74f0ae9 234
eencae 17:780a542d5f8b 235 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 17:780a542d5f8b 236 for(i = 0; i < WIDTH; i++) {
el14pjgn 18:d2140be00144 237 spi->write(buffer[i][j][bufferFrameDisplay]); // send buffer
eencae 0:d563e74f0ae9 238 }
eencae 0:d563e74f0ae9 239 }
eencae 0:d563e74f0ae9 240 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 241
eencae 0:d563e74f0ae9 242 }
eencae 0:d563e74f0ae9 243
eencae 6:adb79338d40f 244 // fills the buffer with random bytes. Can be used to test the display.
eencae 6:adb79338d40f 245 // The rand() function isn't seeded so it probably creates the same pattern everytime
eencae 0:d563e74f0ae9 246 void N5110::randomiseBuffer()
eencae 0:d563e74f0ae9 247 {
eencae 0:d563e74f0ae9 248 int i,j;
eencae 17:780a542d5f8b 249 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 17:780a542d5f8b 250 for(i = 0; i < WIDTH; i++) {
el14pjgn 18:d2140be00144 251 buffer[i][j][bufferFrameEdit] = rand()%256; // generate random byte
eencae 0:d563e74f0ae9 252 }
eencae 0:d563e74f0ae9 253 }
eencae 0:d563e74f0ae9 254
eencae 0:d563e74f0ae9 255 }
eencae 0:d563e74f0ae9 256
eencae 0:d563e74f0ae9 257 // function to print 5x7 font
eencae 13:908644099648 258 void N5110::printChar(char c,int x,int y)
eencae 0:d563e74f0ae9 259 {
eencae 13:908644099648 260 for (int i = 0; i < 5 ; i++ ) {
el14pjgn 18:d2140be00144 261 buffer[x+i][y][bufferFrameEdit] = font5x7[(c - 32)*5 + i];
eencae 17:780a542d5f8b 262 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
eencae 0:d563e74f0ae9 263 }
eencae 17:780a542d5f8b 264
eencae 17:780a542d5f8b 265 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
eencae 0:d563e74f0ae9 266 }
eencae 0:d563e74f0ae9 267
eencae 0:d563e74f0ae9 268 // function to print string at specified position
eencae 0:d563e74f0ae9 269 void N5110::printString(const char * str,int x,int y)
eencae 0:d563e74f0ae9 270 {
eencae 0:d563e74f0ae9 271 int n = 0 ; // counter for number of characters in string
eencae 0:d563e74f0ae9 272 // loop through string and print character
eencae 0:d563e74f0ae9 273 while(*str) {
eencae 0:d563e74f0ae9 274
eencae 13:908644099648 275 // writes the character bitmap data to the buffer, so that
eencae 9:7701f0126ba7 276 // text and pixels can be displayed at the same time
eencae 9:7701f0126ba7 277 for (int i = 0; i < 5 ; i++ ) {
el14pjgn 18:d2140be00144 278 buffer[x+i+n*6][y][bufferFrameEdit] = font5x7[(*str - 32)*5 + i];
eencae 9:7701f0126ba7 279 }
eencae 13:908644099648 280
eencae 0:d563e74f0ae9 281 str++; // go to next character in string
eencae 0:d563e74f0ae9 282 n++; // increment index
eencae 0:d563e74f0ae9 283 }
eencae 13:908644099648 284
eencae 9:7701f0126ba7 285 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
eencae 0:d563e74f0ae9 286
eencae 0:d563e74f0ae9 287 }
eencae 0:d563e74f0ae9 288
eencae 6:adb79338d40f 289 // function to clear the screen
eencae 0:d563e74f0ae9 290 void N5110::clear()
eencae 0:d563e74f0ae9 291 {
eencae 6:adb79338d40f 292 clearBuffer(); // clear the buffer then call the refresh function
eencae 6:adb79338d40f 293 refresh();
eencae 0:d563e74f0ae9 294 }
eencae 0:d563e74f0ae9 295
eencae 6:adb79338d40f 296 // function to clear the buffer
eencae 0:d563e74f0ae9 297 void N5110::clearBuffer()
eencae 0:d563e74f0ae9 298 {
eencae 0:d563e74f0ae9 299 int i,j;
eencae 17:780a542d5f8b 300 for (i=0; i<WIDTH; i++) { // loop through the banks and set the buffer to 0
eencae 17:780a542d5f8b 301 for (j=0; j<BANKS; j++) {
el14pjgn 18:d2140be00144 302 buffer[i][j][bufferFrameEdit]=0;
el14pjgn 18:d2140be00144 303 }
el14pjgn 18:d2140be00144 304 }
el14pjgn 18:d2140be00144 305 }
el14pjgn 18:d2140be00144 306
el14pjgn 18:d2140be00144 307 // function to write array to buffer
el14pjgn 18:d2140be00144 308 void N5110::plotArray2d(bool array2d[][HEIGHT])
el14pjgn 18:d2140be00144 309 {
el14pjgn 18:d2140be00144 310 int i,j;
el14pjgn 18:d2140be00144 311 for (i=0; i<=WIDTH; i++) { // loop through the banks and copy data across
el14pjgn 18:d2140be00144 312 for (j=0; j<=HEIGHT; j++) {
el14pjgn 18:d2140be00144 313 writePixel(i,j,array2d[i][j]);
eencae 0:d563e74f0ae9 314 }
eencae 0:d563e74f0ae9 315 }
el14pjgn 18:d2140be00144 316 refresh();
el14pjgn 18:d2140be00144 317 }
el14pjgn 18:d2140be00144 318
el14pjgn 18:d2140be00144 319 // function to write offset 3d array to buffer
el14pjgn 18:d2140be00144 320 void N5110::plotArray3d(bool array3d[][50][2],int z,int off_x, int off_y)
el14pjgn 18:d2140be00144 321 {
el14pjgn 18:d2140be00144 322 int i,j;
el14pjgn 18:d2140be00144 323 for (i=0; i<=WIDTH; i++) { // loop through the banks and copy data across
el14pjgn 18:d2140be00144 324 for (j=0; j<=HEIGHT; j++) {
el14pjgn 18:d2140be00144 325 writePixel(i,j,array3d[i-off_x][j-off_y][z]);
el14pjgn 18:d2140be00144 326 }
el14pjgn 18:d2140be00144 327 }
el14pjgn 18:d2140be00144 328 refresh();
eencae 8:40abe5736eca 329 }
eencae 8:40abe5736eca 330
eencae 8:40abe5736eca 331 // function to plot array on display
eencae 13:908644099648 332 void N5110::plotArray(float array[])
eencae 13:908644099648 333 {
eencae 13:908644099648 334
eencae 8:40abe5736eca 335 int i;
eencae 13:908644099648 336
eencae 17:780a542d5f8b 337 for (i=0; i<WIDTH; i++) { // loop through array
eencae 8:40abe5736eca 338 // elements are normalised from 0.0 to 1.0, so multiply
eencae 8:40abe5736eca 339 // by 47 to convert to pixel range, and subtract from 47
eencae 8:40abe5736eca 340 // since top-left is 0,0 in the display geometry
eencae 9:7701f0126ba7 341 setPixel(i,47 - int(array[i]*47.0));
eencae 13:908644099648 342 }
eencae 13:908644099648 343
eencae 8:40abe5736eca 344 refresh();
eencae 13:908644099648 345
eencae 17:780a542d5f8b 346 }
eencae 13:908644099648 347
eencae 17:780a542d5f8b 348 // function to draw circle
eencae 17:780a542d5f8b 349 void N5110:: drawCircle(int x0,int y0,int radius,int fill)
eencae 17:780a542d5f8b 350 {
eencae 17:780a542d5f8b 351 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
eencae 17:780a542d5f8b 352 int x = radius;
eencae 17:780a542d5f8b 353 int y = 0;
eencae 17:780a542d5f8b 354 int radiusError = 1-x;
eencae 17:780a542d5f8b 355
eencae 17:780a542d5f8b 356 while(x >= y) {
eencae 17:780a542d5f8b 357
eencae 17:780a542d5f8b 358 // if transparent, just draw outline
eencae 17:780a542d5f8b 359 if (fill == 0) {
eencae 17:780a542d5f8b 360 setPixel( x + x0, y + y0);
eencae 17:780a542d5f8b 361 setPixel(-x + x0, y + y0);
eencae 17:780a542d5f8b 362 setPixel( y + x0, x + y0);
eencae 17:780a542d5f8b 363 setPixel(-y + x0, x + y0);
eencae 17:780a542d5f8b 364 setPixel(-y + x0, -x + y0);
eencae 17:780a542d5f8b 365 setPixel( y + x0, -x + y0);
eencae 17:780a542d5f8b 366 setPixel( x + x0, -y + y0);
eencae 17:780a542d5f8b 367 setPixel(-x + x0, -y + y0);
eencae 17:780a542d5f8b 368 } else { // drawing filled circle, so draw lines between points at same y value
eencae 17:780a542d5f8b 369
eencae 17:780a542d5f8b 370 int type = (fill==1) ? 1:0; // black or white fill
eencae 17:780a542d5f8b 371
eencae 17:780a542d5f8b 372 drawLine(x+x0,y+y0,-x+x0,y+y0,type);
eencae 17:780a542d5f8b 373 drawLine(y+x0,x+y0,-y+x0,x+y0,type);
eencae 17:780a542d5f8b 374 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type);
eencae 17:780a542d5f8b 375 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type);
eencae 17:780a542d5f8b 376 }
eencae 17:780a542d5f8b 377
eencae 17:780a542d5f8b 378
eencae 17:780a542d5f8b 379 y++;
eencae 17:780a542d5f8b 380 if (radiusError<0) {
eencae 17:780a542d5f8b 381 radiusError += 2 * y + 1;
eencae 17:780a542d5f8b 382 } else {
eencae 17:780a542d5f8b 383 x--;
eencae 17:780a542d5f8b 384 radiusError += 2 * (y - x) + 1;
eencae 17:780a542d5f8b 385 }
eencae 17:780a542d5f8b 386 }
eencae 17:780a542d5f8b 387
eencae 17:780a542d5f8b 388 refresh();
eencae 17:780a542d5f8b 389 }
eencae 17:780a542d5f8b 390
eencae 17:780a542d5f8b 391 void N5110::drawLine(int x0,int y0,int x1,int y1,int type)
eencae 17:780a542d5f8b 392 {
eencae 17:780a542d5f8b 393 int y_range = y1-y0; // calc range of y and x
eencae 17:780a542d5f8b 394 int x_range = x1-x0;
eencae 17:780a542d5f8b 395 int start,stop,step;
eencae 17:780a542d5f8b 396
eencae 17:780a542d5f8b 397 // if dotted line, set step to 2, else step is 1
eencae 17:780a542d5f8b 398 step = (type==2) ? 2:1;
eencae 17:780a542d5f8b 399
eencae 17:780a542d5f8b 400 // make sure we loop over the largest range to get the most pixels on the display
eencae 17:780a542d5f8b 401 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
eencae 17:780a542d5f8b 402 // or else we'll only end up with 1 pixel in the x column
eencae 17:780a542d5f8b 403 if ( abs(x_range) > abs(y_range) ) {
eencae 17:780a542d5f8b 404
eencae 17:780a542d5f8b 405 // ensure we loop from smallest to largest or else for-loop won't run as expected
eencae 17:780a542d5f8b 406 start = x1>x0 ? x0:x1;
eencae 17:780a542d5f8b 407 stop = x1>x0 ? x1:x0;
eencae 17:780a542d5f8b 408
eencae 17:780a542d5f8b 409 // loop between x pixels
eencae 17:780a542d5f8b 410 for (int x = start; x<= stop ; x+=step) {
eencae 17:780a542d5f8b 411 // do linear interpolation
eencae 17:780a542d5f8b 412 int y = y0 + (y1-y0)*(x-x0)/(x1-x0);
eencae 17:780a542d5f8b 413
eencae 17:780a542d5f8b 414 if (type == 0) // if 'white' line, turn off pixel
eencae 17:780a542d5f8b 415 clearPixel(x,y);
eencae 17:780a542d5f8b 416 else
eencae 17:780a542d5f8b 417 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
eencae 17:780a542d5f8b 418 }
eencae 17:780a542d5f8b 419 } else {
eencae 17:780a542d5f8b 420
eencae 17:780a542d5f8b 421 // ensure we loop from smallest to largest or else for-loop won't run as expected
eencae 17:780a542d5f8b 422 start = y1>y0 ? y0:y1;
eencae 17:780a542d5f8b 423 stop = y1>y0 ? y1:y0;
eencae 17:780a542d5f8b 424
eencae 17:780a542d5f8b 425 for (int y = start; y<= stop ; y+=step) {
eencae 17:780a542d5f8b 426 // do linear interpolation
eencae 17:780a542d5f8b 427 int x = x0 + (x1-x0)*(y-y0)/(y1-y0);
eencae 17:780a542d5f8b 428
eencae 17:780a542d5f8b 429 if (type == 0) // if 'white' line, turn off pixel
eencae 17:780a542d5f8b 430 clearPixel(x,y);
eencae 17:780a542d5f8b 431 else
eencae 17:780a542d5f8b 432 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
eencae 17:780a542d5f8b 433
eencae 17:780a542d5f8b 434 }
eencae 17:780a542d5f8b 435 }
eencae 17:780a542d5f8b 436
eencae 17:780a542d5f8b 437 refresh();
eencae 17:780a542d5f8b 438 }
eencae 17:780a542d5f8b 439
eencae 17:780a542d5f8b 440 void N5110::drawRect(int x0,int y0,int width,int height,int fill)
eencae 17:780a542d5f8b 441 {
eencae 17:780a542d5f8b 442
eencae 17:780a542d5f8b 443 if (fill == 0) { // transparent, just outline
eencae 17:780a542d5f8b 444 drawLine(x0,y0,x0+width,y0,1); // top
eencae 17:780a542d5f8b 445 drawLine(x0,y0+height,x0+width,y0+height,1); // bottom
eencae 17:780a542d5f8b 446 drawLine(x0,y0,x0,y0+height,1); // left
eencae 17:780a542d5f8b 447 drawLine(x0+width,y0,x0+width,y0+height,1); // right
eencae 17:780a542d5f8b 448 } else { // filled rectangle
eencae 17:780a542d5f8b 449 int type = (fill==1) ? 1:0; // black or white fill
eencae 17:780a542d5f8b 450 for (int y = y0; y<= y0+height; y++) { // loop through rows of rectangle
eencae 17:780a542d5f8b 451 drawLine(x0,y,x0+width,y,type); // draw line across screen
eencae 17:780a542d5f8b 452 }
eencae 17:780a542d5f8b 453 }
eencae 17:780a542d5f8b 454
eencae 17:780a542d5f8b 455 }