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 Jan 22 12:50:25 2020 +0000
Revision:
50:e73cd097fdcb
Parent:
49:93355c01e261
Child:
51:32f9ffeafb6d
Added overloaded constructor for Gamepad2

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