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:
Wed Nov 01 20:48:05 2017 +0000
Revision:
44:57f9d32fb521
Parent:
43:c2598020fcac
Child:
45:97e54ea40dac
Separated out contrast, bias and temp coefficient methods. Modified init method to take this into account. Can now dynamically control contrast at run-time which makes it easier to account for natural variation between individual LCD displays.

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 44:57f9d32fb521 60 initSPI();
eencae 44:57f9d32fb521 61
eencae 44:57f9d32fb521 62 setContrast(0.40); // this may need tuning (say 0.4 to 0.6)
eencae 44:57f9d32fb521 63 setBias(3); // datasheet - 48:1 mux - don't mess with if you don't know what you're doing!
eencae 44:57f9d32fb521 64 setTempCoefficient(0); // datasheet - may need increasing (range 0 to 3) at very low temperatures
eencae 24:342bdb6679a1 65 normalMode(); // normal video mode by default
eencae 44:57f9d32fb521 66
eencae 44:57f9d32fb521 67 clearRAM(); // RAM is undefined at power-up so clear to be sure
eencae 24:342bdb6679a1 68 clear(); // clear buffer
eencae 24:342bdb6679a1 69 setBrightness(0.5);
eencae 0:d563e74f0ae9 70 }
eencae 13:908644099648 71
eencae 13:908644099648 72 // sets normal video mode (black on white)
eencae 13:908644099648 73 void N5110::normalMode()
eencae 13:908644099648 74 {
eencae 44:57f9d32fb521 75 sendCommand(0b00100000); // basic instruction
eencae 44:57f9d32fb521 76 sendCommand(0b00001100); // normal video mode- datasheet
eencae 1:df68f34cd32d 77 }
eencae 1:df68f34cd32d 78
eencae 13:908644099648 79 // sets normal video mode (white on black)
eencae 13:908644099648 80 void N5110::inverseMode()
eencae 13:908644099648 81 {
eencae 44:57f9d32fb521 82 sendCommand(0b00100000); // basic instruction
eencae 44:57f9d32fb521 83 sendCommand(0b00001101); // inverse video mode - datasheet
eencae 1:df68f34cd32d 84 }
eencae 0:d563e74f0ae9 85
eencae 24:342bdb6679a1 86 // function to power up the LCD and backlight - only works when using GPIO to power
eencae 0:d563e74f0ae9 87 void N5110::turnOn()
eencae 0:d563e74f0ae9 88 {
valavanisalex 29:5bc91bd44c77 89 if (_pwr != NULL) {
valavanisalex 29:5bc91bd44c77 90 _pwr->write(1); // apply power
eencae 24:342bdb6679a1 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 24:342bdb6679a1 97 clear(); // clear buffer
eencae 24:342bdb6679a1 98 refresh();
eencae 24:342bdb6679a1 99 setBrightness(0.0); // turn backlight off
eencae 24:342bdb6679a1 100 clearRAM(); // clear RAM to ensure specified current consumption
eencae 24:342bdb6679a1 101 // send command to ensure we are in basic mode
eencae 44:57f9d32fb521 102
eencae 44:57f9d32fb521 103 sendCommand(0b00100000); // basic mode
eencae 44:57f9d32fb521 104 sendCommand(0b00001000); // clear display
eencae 44:57f9d32fb521 105 sendCommand(0b00100001); // extended mode
eencae 44:57f9d32fb521 106 sendCommand(0b00100100); // power down
eencae 44:57f9d32fb521 107
eencae 24:342bdb6679a1 108 // if we are powering the LCD using the GPIO then make it low to turn off
valavanisalex 29:5bc91bd44c77 109 if (_pwr != NULL) {
eencae 44:57f9d32fb521 110 wait_ms(10); // small delay and then turn off the power pin
valavanisalex 29:5bc91bd44c77 111 _pwr->write(0); // turn off power
eencae 24:342bdb6679a1 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 24:342bdb6679a1 119 // check whether brightness is within range
eencae 24:342bdb6679a1 120 if (brightness < 0.0f)
eencae 24:342bdb6679a1 121 brightness = 0.0f;
eencae 24:342bdb6679a1 122 if (brightness > 1.0f)
eencae 24:342bdb6679a1 123 brightness = 1.0f;
eencae 24:342bdb6679a1 124 // set PWM duty cycle
valavanisalex 29:5bc91bd44c77 125 _led->write(brightness);
eencae 0:d563e74f0ae9 126 }
eencae 0:d563e74f0ae9 127
eencae 44:57f9d32fb521 128 void N5110::setContrast(float contrast) {
eencae 44:57f9d32fb521 129
eencae 44:57f9d32fb521 130 // enforce limits
eencae 44:57f9d32fb521 131 if (contrast > 1.0)
eencae 44:57f9d32fb521 132 contrast = 1.0;
eencae 44:57f9d32fb521 133 else if (contrast < 0.0)
eencae 44:57f9d32fb521 134 contrast = 0.0;
eencae 44:57f9d32fb521 135
eencae 44:57f9d32fb521 136 // convert to char in range 0 to 127 (i.e. 6 bits)
eencae 44:57f9d32fb521 137 char ic = char(contrast*127.0);
eencae 44:57f9d32fb521 138
eencae 44:57f9d32fb521 139 sendCommand(0b00100001); // extended instruction set
eencae 44:57f9d32fb521 140 sendCommand(0b10000000 | ic); // set Vop (which controls contrast)
eencae 44:57f9d32fb521 141 sendCommand(0b00100000); // back to basic instruction set
eencae 44:57f9d32fb521 142 }
eencae 44:57f9d32fb521 143
eencae 44:57f9d32fb521 144 void N5110::setTempCoefficient(char tc) {
eencae 44:57f9d32fb521 145
eencae 44:57f9d32fb521 146 // enforce limits
eencae 44:57f9d32fb521 147 if (tc>3) {
eencae 44:57f9d32fb521 148 tc=3;
eencae 44:57f9d32fb521 149 }
eencae 44:57f9d32fb521 150
eencae 44:57f9d32fb521 151 // temperature coefficient may need increasing at low temperatures
eencae 44:57f9d32fb521 152
eencae 44:57f9d32fb521 153 sendCommand(0b00100001); // extended instruction set
eencae 44:57f9d32fb521 154 sendCommand(0b00000100 | tc);
eencae 44:57f9d32fb521 155 sendCommand(0b00100000); // back to basic instruction set
eencae 44:57f9d32fb521 156 }
eencae 44:57f9d32fb521 157
eencae 44:57f9d32fb521 158 void N5110::setBias(char bias) {
eencae 44:57f9d32fb521 159
eencae 44:57f9d32fb521 160 // from data sheet
eencae 44:57f9d32fb521 161 // bias mux rate
eencae 44:57f9d32fb521 162 // 0 1:100
eencae 44:57f9d32fb521 163 // 1 1:80
eencae 44:57f9d32fb521 164 // 2 1:65
eencae 44:57f9d32fb521 165 // 3 1:48 (default)
eencae 44:57f9d32fb521 166 // 4 1:40/1:34
eencae 44:57f9d32fb521 167 // 5 1:24
eencae 44:57f9d32fb521 168 // 6 1:18/1:16
eencae 44:57f9d32fb521 169 // 7 1:10/1:9/1:8
eencae 44:57f9d32fb521 170
eencae 44:57f9d32fb521 171 // enforce limits
eencae 44:57f9d32fb521 172 if (bias>7) {
eencae 44:57f9d32fb521 173 bias=7;
eencae 44:57f9d32fb521 174 }
eencae 44:57f9d32fb521 175
eencae 44:57f9d32fb521 176 sendCommand(0b00100001); // extended mode instruction
eencae 44:57f9d32fb521 177 sendCommand(0b00010000 | bias);
eencae 44:57f9d32fb521 178 sendCommand(0b00100000); // end of extended mode instruction
eencae 44:57f9d32fb521 179 }
eencae 0:d563e74f0ae9 180
eencae 0:d563e74f0ae9 181 // pulse the active low reset line
eencae 0:d563e74f0ae9 182 void N5110::reset()
eencae 0:d563e74f0ae9 183 {
valavanisalex 29:5bc91bd44c77 184 _rst->write(0); // reset the LCD
valavanisalex 29:5bc91bd44c77 185 _rst->write(1);
eencae 0:d563e74f0ae9 186 }
eencae 0:d563e74f0ae9 187
eencae 0:d563e74f0ae9 188 // function to initialise SPI peripheral
eencae 0:d563e74f0ae9 189 void N5110::initSPI()
eencae 0:d563e74f0ae9 190 {
valavanisalex 29:5bc91bd44c77 191 _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 192 _spi->frequency(4000000); // maximum of screen is 4 MHz
eencae 0:d563e74f0ae9 193 }
eencae 0:d563e74f0ae9 194
eencae 6:adb79338d40f 195 // send a command to the display
eencae 0:d563e74f0ae9 196 void N5110::sendCommand(unsigned char command)
eencae 0:d563e74f0ae9 197 {
valavanisalex 29:5bc91bd44c77 198 _dc->write(0); // set DC low for command
valavanisalex 29:5bc91bd44c77 199 _sce->write(0); // set CE low to begin frame
valavanisalex 29:5bc91bd44c77 200 _spi->write(command); // send command
valavanisalex 29:5bc91bd44c77 201 _dc->write(1); // turn back to data by default
valavanisalex 29:5bc91bd44c77 202 _sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 203 }
eencae 0:d563e74f0ae9 204
eencae 6:adb79338d40f 205 // send data to the display at the current XY address
eencae 6:adb79338d40f 206 // dc is set to 1 (i.e. data) after sending a command and so should
eencae 6:adb79338d40f 207 // be the default mode.
eencae 0:d563e74f0ae9 208 void N5110::sendData(unsigned char data)
eencae 0:d563e74f0ae9 209 {
valavanisalex 29:5bc91bd44c77 210 _sce->write(0); // set CE low to begin frame
valavanisalex 29:5bc91bd44c77 211 _spi->write(data);
valavanisalex 29:5bc91bd44c77 212 _sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 213 }
eencae 0:d563e74f0ae9 214
eencae 0:d563e74f0ae9 215 // this function writes 0 to the 504 bytes to clear the RAM
eencae 0:d563e74f0ae9 216 void N5110::clearRAM()
eencae 0:d563e74f0ae9 217 {
valavanisalex 29:5bc91bd44c77 218 _sce->write(0); //set CE low to begin frame
eencae 24:342bdb6679a1 219 for(int i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes
valavanisalex 29:5bc91bd44c77 220 _spi->write(0x00); // send 0's
eencae 24:342bdb6679a1 221 }
valavanisalex 29:5bc91bd44c77 222 _sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 223 }
eencae 0:d563e74f0ae9 224
eencae 13:908644099648 225 // function to set the XY address in RAM for subsequenct data write
valavanisalex 29:5bc91bd44c77 226 void N5110::setXYAddress(unsigned int const x,
valavanisalex 29:5bc91bd44c77 227 unsigned int const y)
eencae 0:d563e74f0ae9 228 {
valavanisalex 29:5bc91bd44c77 229 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 44:57f9d32fb521 230 sendCommand(0b00100000); // basic instruction
eencae 44:57f9d32fb521 231 sendCommand(0b10000000 | x); // send addresses to display with relevant mask
eencae 44:57f9d32fb521 232 sendCommand(0b01000000 | y);
eencae 24:342bdb6679a1 233 }
eencae 0:d563e74f0ae9 234 }
eencae 0:d563e74f0ae9 235
eencae 6:adb79338d40f 236 // These functions are used to set, clear and get the value of pixels in the display
eencae 6:adb79338d40f 237 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
eencae 6:adb79338d40f 238 // function must be called after set and clear in order to update the display
valavanisalex 29:5bc91bd44c77 239 void N5110::setPixel(unsigned int const x,
valavanisalex 42:596c207519de 240 unsigned int const y,
valavanisalex 42:596c207519de 241 bool const state)
eencae 0:d563e74f0ae9 242 {
valavanisalex 29:5bc91bd44c77 243 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 24:342bdb6679a1 244 // calculate bank and shift 1 to required position in the data byte
valavanisalex 42:596c207519de 245 if(state) buffer[x][y/8] |= (1 << y%8);
valavanisalex 42:596c207519de 246 else buffer[x][y/8] &= ~(1 << y%8);
eencae 24:342bdb6679a1 247 }
eencae 0:d563e74f0ae9 248 }
eencae 0:d563e74f0ae9 249
valavanisalex 29:5bc91bd44c77 250 void N5110::clearPixel(unsigned int const x,
valavanisalex 29:5bc91bd44c77 251 unsigned int const y)
eencae 0:d563e74f0ae9 252 {
valavanisalex 29:5bc91bd44c77 253 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 24:342bdb6679a1 254 // calculate bank and shift 1 to required position (using bit clear)
eencae 24:342bdb6679a1 255 buffer[x][y/8] &= ~(1 << y%8);
eencae 24:342bdb6679a1 256 }
eencae 0:d563e74f0ae9 257 }
eencae 0:d563e74f0ae9 258
valavanisalex 29:5bc91bd44c77 259 int N5110::getPixel(unsigned int const x,
valavanisalex 29:5bc91bd44c77 260 unsigned int const y) const
eencae 0:d563e74f0ae9 261 {
valavanisalex 29:5bc91bd44c77 262 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 24:342bdb6679a1 263 // return relevant bank and mask required bit
eencae 24:342bdb6679a1 264
eencae 24:342bdb6679a1 265 int pixel = (int) buffer[x][y/8] & (1 << y%8);
eencae 24:342bdb6679a1 266
eencae 24:342bdb6679a1 267 if (pixel)
eencae 24:342bdb6679a1 268 return 1;
eencae 24:342bdb6679a1 269 else
eencae 24:342bdb6679a1 270 return 0;
eencae 24:342bdb6679a1 271 }
eencae 24:342bdb6679a1 272
eencae 23:eb7e6632fc9e 273 return 0;
eencae 24:342bdb6679a1 274
eencae 0:d563e74f0ae9 275 }
eencae 0:d563e74f0ae9 276
eencae 6:adb79338d40f 277 // function to refresh the display
eencae 6:adb79338d40f 278 void N5110::refresh()
eencae 0:d563e74f0ae9 279 {
eencae 24:342bdb6679a1 280 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
eencae 24:342bdb6679a1 281 // address auto increments after printing string, so buffer[0][0] will not coincide
eencae 24:342bdb6679a1 282 // with top-left pixel after priting string
eencae 13:908644099648 283
valavanisalex 29:5bc91bd44c77 284 _sce->write(0); //set CE low to begin frame
eencae 13:908644099648 285
eencae 24:342bdb6679a1 286 for(int j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 24:342bdb6679a1 287 for(int i = 0; i < WIDTH; i++) {
valavanisalex 29:5bc91bd44c77 288 _spi->write(buffer[i][j]); // send buffer
eencae 24:342bdb6679a1 289 }
eencae 0:d563e74f0ae9 290 }
valavanisalex 29:5bc91bd44c77 291 _sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 292
eencae 0:d563e74f0ae9 293 }
eencae 0:d563e74f0ae9 294
eencae 6:adb79338d40f 295 // fills the buffer with random bytes. Can be used to test the display.
eencae 6:adb79338d40f 296 // The rand() function isn't seeded so it probably creates the same pattern everytime
eencae 0:d563e74f0ae9 297 void N5110::randomiseBuffer()
eencae 0:d563e74f0ae9 298 {
eencae 24:342bdb6679a1 299 int i,j;
eencae 24:342bdb6679a1 300 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 24:342bdb6679a1 301 for(i = 0; i < WIDTH; i++) {
eencae 24:342bdb6679a1 302 buffer[i][j] = rand()%256; // generate random byte
eencae 24:342bdb6679a1 303 }
eencae 0:d563e74f0ae9 304 }
eencae 0:d563e74f0ae9 305
eencae 0:d563e74f0ae9 306 }
eencae 0:d563e74f0ae9 307
eencae 0:d563e74f0ae9 308 // function to print 5x7 font
valavanisalex 29:5bc91bd44c77 309 void N5110::printChar(char const c,
valavanisalex 29:5bc91bd44c77 310 unsigned int const x,
valavanisalex 29:5bc91bd44c77 311 unsigned int const y)
eencae 0:d563e74f0ae9 312 {
valavanisalex 29:5bc91bd44c77 313 if (y<BANKS) { // check if printing in range of y banks
eencae 18:1af393359298 314
eencae 24:342bdb6679a1 315 for (int i = 0; i < 5 ; i++ ) {
eencae 24:342bdb6679a1 316 int pixel_x = x+i;
eencae 24:342bdb6679a1 317 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
eencae 24:342bdb6679a1 318 break;
eencae 24:342bdb6679a1 319 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i];
eencae 24:342bdb6679a1 320 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
eencae 24:342bdb6679a1 321 }
valavanisalex 29:5bc91bd44c77 322
eencae 23:eb7e6632fc9e 323 }
eencae 0:d563e74f0ae9 324 }
eencae 0:d563e74f0ae9 325
eencae 0:d563e74f0ae9 326 // function to print string at specified position
valavanisalex 29:5bc91bd44c77 327 void N5110::printString(const char *str,
valavanisalex 29:5bc91bd44c77 328 unsigned int const x,
valavanisalex 29:5bc91bd44c77 329 unsigned int const y)
eencae 0:d563e74f0ae9 330 {
valavanisalex 29:5bc91bd44c77 331 if (y<BANKS) { // check if printing in range of y banks
eencae 18:1af393359298 332
eencae 24:342bdb6679a1 333 int n = 0 ; // counter for number of characters in string
eencae 24:342bdb6679a1 334 // loop through string and print character
eencae 24:342bdb6679a1 335 while(*str) {
eencae 0:d563e74f0ae9 336
eencae 24:342bdb6679a1 337 // writes the character bitmap data to the buffer, so that
eencae 24:342bdb6679a1 338 // text and pixels can be displayed at the same time
eencae 24:342bdb6679a1 339 for (int i = 0; i < 5 ; i++ ) {
eencae 24:342bdb6679a1 340 int pixel_x = x+i+n*6;
eencae 24:342bdb6679a1 341 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
eencae 24:342bdb6679a1 342 break;
eencae 24:342bdb6679a1 343 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i];
eencae 24:342bdb6679a1 344 }
eencae 24:342bdb6679a1 345 str++; // go to next character in string
eencae 24:342bdb6679a1 346 n++; // increment index
eencae 24:342bdb6679a1 347 }
eencae 23:eb7e6632fc9e 348 }
eencae 0:d563e74f0ae9 349 }
eencae 0:d563e74f0ae9 350
eencae 24:342bdb6679a1 351 // function to clear the screen buffer
eencae 0:d563e74f0ae9 352 void N5110::clear()
eencae 0:d563e74f0ae9 353 {
eencae 24:342bdb6679a1 354 memset(buffer,0,sizeof(buffer));
eencae 8:40abe5736eca 355 }
eencae 8:40abe5736eca 356
eencae 8:40abe5736eca 357 // function to plot array on display
valavanisalex 29:5bc91bd44c77 358 void N5110::plotArray(float const array[])
eencae 13:908644099648 359 {
eencae 24:342bdb6679a1 360 for (int i=0; i<WIDTH; i++) { // loop through array
eencae 24:342bdb6679a1 361 // elements are normalised from 0.0 to 1.0, so multiply
eencae 24:342bdb6679a1 362 // by 47 to convert to pixel range, and subtract from 47
eencae 24:342bdb6679a1 363 // since top-left is 0,0 in the display geometry
eencae 24:342bdb6679a1 364 setPixel(i,47 - int(array[i]*47.0f));
eencae 24:342bdb6679a1 365 }
eencae 13:908644099648 366
eencae 17:780a542d5f8b 367 }
eencae 13:908644099648 368
eencae 17:780a542d5f8b 369 // function to draw circle
valavanisalex 29:5bc91bd44c77 370 void N5110:: drawCircle(unsigned int const x0,
valavanisalex 29:5bc91bd44c77 371 unsigned int const y0,
valavanisalex 29:5bc91bd44c77 372 unsigned int const radius,
valavanisalex 33:d80e568a2e18 373 FillType const fill)
eencae 17:780a542d5f8b 374 {
eencae 24:342bdb6679a1 375 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
eencae 24:342bdb6679a1 376 int x = radius;
eencae 24:342bdb6679a1 377 int y = 0;
eencae 24:342bdb6679a1 378 int radiusError = 1-x;
eencae 17:780a542d5f8b 379
eencae 24:342bdb6679a1 380 while(x >= y) {
eencae 17:780a542d5f8b 381
eencae 24:342bdb6679a1 382 // if transparent, just draw outline
valavanisalex 33:d80e568a2e18 383 if (fill == FILL_TRANSPARENT) {
eencae 24:342bdb6679a1 384 setPixel( x + x0, y + y0);
eencae 24:342bdb6679a1 385 setPixel(-x + x0, y + y0);
eencae 24:342bdb6679a1 386 setPixel( y + x0, x + y0);
eencae 24:342bdb6679a1 387 setPixel(-y + x0, x + y0);
eencae 24:342bdb6679a1 388 setPixel(-y + x0, -x + y0);
eencae 24:342bdb6679a1 389 setPixel( y + x0, -x + y0);
eencae 24:342bdb6679a1 390 setPixel( x + x0, -y + y0);
eencae 24:342bdb6679a1 391 setPixel(-x + x0, -y + y0);
eencae 24:342bdb6679a1 392 } else { // drawing filled circle, so draw lines between points at same y value
eencae 17:780a542d5f8b 393
valavanisalex 33:d80e568a2e18 394 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill
eencae 17:780a542d5f8b 395
eencae 24:342bdb6679a1 396 drawLine(x+x0,y+y0,-x+x0,y+y0,type);
eencae 24:342bdb6679a1 397 drawLine(y+x0,x+y0,-y+x0,x+y0,type);
eencae 24:342bdb6679a1 398 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type);
eencae 24:342bdb6679a1 399 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type);
eencae 24:342bdb6679a1 400 }
eencae 17:780a542d5f8b 401
eencae 24:342bdb6679a1 402 y++;
eencae 24:342bdb6679a1 403 if (radiusError<0) {
eencae 24:342bdb6679a1 404 radiusError += 2 * y + 1;
eencae 24:342bdb6679a1 405 } else {
eencae 24:342bdb6679a1 406 x--;
eencae 24:342bdb6679a1 407 radiusError += 2 * (y - x) + 1;
eencae 24:342bdb6679a1 408 }
eencae 17:780a542d5f8b 409 }
eencae 17:780a542d5f8b 410
eencae 17:780a542d5f8b 411 }
eencae 17:780a542d5f8b 412
valavanisalex 29:5bc91bd44c77 413 void N5110::drawLine(unsigned int const x0,
valavanisalex 29:5bc91bd44c77 414 unsigned int const y0,
valavanisalex 29:5bc91bd44c77 415 unsigned int const x1,
valavanisalex 29:5bc91bd44c77 416 unsigned int const y1,
valavanisalex 29:5bc91bd44c77 417 unsigned int const type)
eencae 17:780a542d5f8b 418 {
valavanisalex 43:c2598020fcac 419 // Note that the ranges can be negative so we have to turn the input values
valavanisalex 43:c2598020fcac 420 // into signed integers first
valavanisalex 43:c2598020fcac 421 int const y_range = static_cast<int>(y1) - static_cast<int>(y0);
valavanisalex 43:c2598020fcac 422 int const x_range = static_cast<int>(x1) - static_cast<int>(x0);
eencae 17:780a542d5f8b 423
eencae 24:342bdb6679a1 424 // if dotted line, set step to 2, else step is 1
valavanisalex 43:c2598020fcac 425 unsigned int const step = (type==2) ? 2:1;
eencae 17:780a542d5f8b 426
eencae 24:342bdb6679a1 427 // make sure we loop over the largest range to get the most pixels on the display
eencae 24:342bdb6679a1 428 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
eencae 24:342bdb6679a1 429 // or else we'll only end up with 1 pixel in the x column
eencae 24:342bdb6679a1 430 if ( abs(x_range) > abs(y_range) ) {
eencae 17:780a542d5f8b 431
eencae 24:342bdb6679a1 432 // ensure we loop from smallest to largest or else for-loop won't run as expected
valavanisalex 43:c2598020fcac 433 unsigned int const start = x_range > 0 ? x0:x1;
valavanisalex 43:c2598020fcac 434 unsigned int const stop = x_range > 0 ? x1:x0;
eencae 17:780a542d5f8b 435
eencae 24:342bdb6679a1 436 // loop between x pixels
valavanisalex 43:c2598020fcac 437 for (unsigned int x = start; x<= stop ; x+=step) {
eencae 24:342bdb6679a1 438 // do linear interpolation
valavanisalex 43:c2598020fcac 439 int const dx = static_cast<int>(x)-static_cast<int>(x0);
valavanisalex 43:c2598020fcac 440 unsigned int const y = y0 + y_range * dx / x_range;
eencae 17:780a542d5f8b 441
valavanisalex 42:596c207519de 442 // If the line type is '0', this will clear the pixel
valavanisalex 42:596c207519de 443 // If it is '1' or '2', the pixel will be set
valavanisalex 42:596c207519de 444 setPixel(x,y, type);
eencae 24:342bdb6679a1 445 }
eencae 24:342bdb6679a1 446 } else {
eencae 17:780a542d5f8b 447
eencae 24:342bdb6679a1 448 // ensure we loop from smallest to largest or else for-loop won't run as expected
valavanisalex 43:c2598020fcac 449 unsigned int const start = y_range > 0 ? y0:y1;
valavanisalex 43:c2598020fcac 450 unsigned int const stop = y_range > 0 ? y1:y0;
eencae 17:780a542d5f8b 451
valavanisalex 43:c2598020fcac 452 for (unsigned int y = start; y<= stop ; y+=step) {
eencae 24:342bdb6679a1 453 // do linear interpolation
valavanisalex 43:c2598020fcac 454 int const dy = static_cast<int>(y)-static_cast<int>(y0);
valavanisalex 43:c2598020fcac 455 unsigned int const x = x0 + x_range * dy / y_range;
eencae 17:780a542d5f8b 456
valavanisalex 42:596c207519de 457 // If the line type is '0', this will clear the pixel
valavanisalex 42:596c207519de 458 // If it is '1' or '2', the pixel will be set
valavanisalex 42:596c207519de 459 setPixel(x,y, type);
eencae 24:342bdb6679a1 460 }
eencae 17:780a542d5f8b 461 }
eencae 17:780a542d5f8b 462
eencae 17:780a542d5f8b 463 }
eencae 17:780a542d5f8b 464
valavanisalex 29:5bc91bd44c77 465 void N5110::drawRect(unsigned int const x0,
valavanisalex 29:5bc91bd44c77 466 unsigned int const y0,
valavanisalex 29:5bc91bd44c77 467 unsigned int const width,
valavanisalex 29:5bc91bd44c77 468 unsigned int const height,
valavanisalex 33:d80e568a2e18 469 FillType const fill)
eencae 17:780a542d5f8b 470 {
valavanisalex 33:d80e568a2e18 471 if (fill == FILL_TRANSPARENT) { // transparent, just outline
eencae 27:0d8d90936b4c 472 drawLine(x0,y0,x0+(width-1),y0,1); // top
eencae 27:0d8d90936b4c 473 drawLine(x0,y0+(height-1),x0+(width-1),y0+(height-1),1); // bottom
eencae 27:0d8d90936b4c 474 drawLine(x0,y0,x0,y0+(height-1),1); // left
eencae 27:0d8d90936b4c 475 drawLine(x0+(width-1),y0,x0+(width-1),y0+(height-1),1); // right
eencae 24:342bdb6679a1 476 } else { // filled rectangle
valavanisalex 33:d80e568a2e18 477 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill
eencae 27:0d8d90936b4c 478 for (int y = y0; y<y0+height; y++) { // loop through rows of rectangle
eencae 27:0d8d90936b4c 479 drawLine(x0,y,x0+(width-1),y,type); // draw line across screen
eencae 24:342bdb6679a1 480 }
eencae 17:780a542d5f8b 481 }
eencae 35:2d5931a66fba 482 }
eencae 35:2d5931a66fba 483
eencae 36:00ebd449b6f3 484 void N5110::drawSprite(int x0,
valavanisalex 42:596c207519de 485 int y0,
valavanisalex 42:596c207519de 486 int nrows,
valavanisalex 42:596c207519de 487 int ncols,
valavanisalex 42:596c207519de 488 int *sprite)
valavanisalex 43:c2598020fcac 489 {
eencae 36:00ebd449b6f3 490 for (int i = 0; i < nrows; i++) {
eencae 36:00ebd449b6f3 491 for (int j = 0 ; j < ncols ; j++) {
eencae 35:2d5931a66fba 492
eencae 36:00ebd449b6f3 493 int pixel = *((sprite+i*ncols)+j);
valavanisalex 42:596c207519de 494 setPixel(x0+j,y0+i, pixel);
eencae 35:2d5931a66fba 495 }
eencae 35:2d5931a66fba 496 }
valavanisalex 29:5bc91bd44c77 497 }