Final tidy of code following installation of new sensor, more comments added prior to submission

Dependencies:   mbed

Committer:
legstar85
Date:
Fri Jan 21 14:26:56 2022 +0000
Revision:
13:5ad65a688f3f
Updated due to issues with using Start Temp variable later in program now resolved. Doxygen completed and folders in place correctly

Who changed what in which revision?

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