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:
Tue Feb 07 11:24:32 2017 +0000
Revision:
26:36be85c20ef4
Parent:
24:342bdb6679a1
Child:
27:0d8d90936b4c
Updated docs.

Who changed what in which revision?

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