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:
valavanisalex
Date:
Thu Feb 16 15:41:00 2017 +0000
Revision:
32:c9643726edca
Parent:
31:8a0c21042f82
Child:
33:d80e568a2e18
Use initialiser lists instead of constructor body

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