Library for interfacing to Nokia 5110 LCD display (as found on the SparkFun website).

Dependents:   LV7_LCDtest LV7_Grupa5_Tim003_Zadatak1 lv7_Grupa5_Tim008_zad1 LV7_PAI_Grupa5_tim10_Zadatak1 ... more

This library is designed to make it easy to interface an mbed with a Nokia 5110 LCD display.

These can be found at Sparkfun (https://www.sparkfun.com/products/10168) and Adafruit (http://www.adafruit.com/product/338).

The library uses the SPI peripheral on the mbed which means it is much faster sending data to the display than other libraries available on other platforms that use software SPI.

The library can print strings as well as controlling individual pixels, meaning that both text and primitive graphics can be displayed.

Committer:
eencae
Date:
Sat Jan 28 20:25:43 2017 +0000
Revision:
21:4cbdc20fea9f
Parent:
20:8db6aa25f55e
Child:
22:31c54fc61f12
Added overloaded constructor that doesn't include the power pin being connected to GPIO. In this instance, the Vcc of the LCD must be tied directly to +3V3.

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