ELEC2645 (2018/19) / Mbed 2 deprecated el18w2w1

Dependencies:   mbed

Committer:
wuweilong
Date:
Wed May 08 20:08:17 2019 +0000
Revision:
10:ae5f62a1e40e
version1

Who changed what in which revision?

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