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

Fork of N5110 by Craig Evans

Committer:
eencae
Date:
Wed Feb 01 16:26:22 2017 +0000
Revision:
23:eb7e6632fc9e
Parent:
22:31c54fc61f12
Child:
24:342bdb6679a1
Check for NULL pointer on pwrPin, use memset to zero out buffer. Ensure all pointers initialised to allow use with 'new' operator.

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