Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of fy15raf by
N5110.cpp
00001 #include "mbed.h" 00002 #include "N5110.h" 00003 00004 // overloaded constructor includes power pin - LCD Vcc connected to GPIO pin 00005 // this constructor works fine with LPC1768 - enough current sourced from GPIO 00006 // to power LCD. Doesn't work well with K64F. 00007 N5110::N5110(PinName const pwrPin, 00008 PinName const scePin, 00009 PinName const rstPin, 00010 PinName const dcPin, 00011 PinName const mosiPin, 00012 PinName const sclkPin, 00013 PinName const ledPin) 00014 : 00015 _spi(new SPI(mosiPin,NC,sclkPin)), // create new SPI instance and initialise 00016 _led(new PwmOut(ledPin)), 00017 _pwr(new DigitalOut(pwrPin)), 00018 _sce(new DigitalOut(scePin)), 00019 _rst(new DigitalOut(rstPin)), 00020 _dc(new DigitalOut(dcPin)) 00021 {} 00022 00023 // overloaded constructor does not include power pin - LCD Vcc must be tied to +3V3 00024 // Best to use this with K64F as the GPIO hasn't sufficient output current to reliably 00025 // drive the LCD. 00026 N5110::N5110(PinName const scePin, 00027 PinName const rstPin, 00028 PinName const dcPin, 00029 PinName const mosiPin, 00030 PinName const sclkPin, 00031 PinName const ledPin) 00032 : 00033 _spi(new SPI(mosiPin,NC,sclkPin)), // create new SPI instance and initialise 00034 _led(new PwmOut(ledPin)), 00035 _pwr(NULL), // pwr not needed so null it to be safe 00036 _sce(new DigitalOut(scePin)), 00037 _rst(new DigitalOut(rstPin)), 00038 _dc(new DigitalOut(dcPin)) 00039 {} 00040 00041 N5110::~N5110() 00042 { 00043 delete _spi; 00044 00045 if(_pwr) { 00046 delete _pwr; 00047 } 00048 00049 delete _led; 00050 delete _sce; 00051 delete _rst; 00052 delete _dc; 00053 } 00054 00055 // initialise function - powers up and sends the initialisation commands 00056 void N5110::init() 00057 { 00058 turnOn(); // power up 00059 reset(); // reset LCD - must be done within 100 ms 00060 initSPI(); 00061 00062 setContrast(0.55); // this may need tuning (say 0.4 to 0.6) 00063 setBias(3); // datasheet - 48:1 mux - don't mess with if you don't know what you're doing! (0 to 7) 00064 setTempCoefficient(0); // datasheet - may need increasing (range 0 to 3) at very low temperatures 00065 normalMode(); // normal video mode by default 00066 00067 clearRAM(); // RAM is undefined at power-up so clear to be sure 00068 clear(); // clear buffer 00069 setBrightness(0.5); 00070 } 00071 00072 // sets normal video mode (black on white) 00073 void N5110::normalMode() 00074 { 00075 sendCommand(0b00100000); // basic instruction 00076 sendCommand(0b00001100); // normal video mode- datasheet 00077 } 00078 00079 // sets normal video mode (white on black) 00080 void N5110::inverseMode() 00081 { 00082 sendCommand(0b00100000); // basic instruction 00083 sendCommand(0b00001101); // inverse video mode - datasheet 00084 } 00085 00086 // function to power up the LCD and backlight - only works when using GPIO to power 00087 void N5110::turnOn() 00088 { 00089 if (_pwr != NULL) { 00090 _pwr->write(1); // apply power 00091 } 00092 } 00093 00094 // function to power down LCD 00095 void N5110::turnOff() 00096 { 00097 clear(); // clear buffer 00098 refresh(); 00099 setBrightness(0.0); // turn backlight off 00100 clearRAM(); // clear RAM to ensure specified current consumption 00101 // send command to ensure we are in basic mode 00102 00103 sendCommand(0b00100000); // basic mode 00104 sendCommand(0b00001000); // clear display 00105 sendCommand(0b00100001); // extended mode 00106 sendCommand(0b00100100); // power down 00107 00108 // if we are powering the LCD using the GPIO then make it low to turn off 00109 if (_pwr != NULL) { 00110 wait_ms(10); // small delay and then turn off the power pin 00111 _pwr->write(0); // turn off power 00112 } 00113 00114 } 00115 00116 // function to change LED backlight brightness 00117 void N5110::setBrightness(float brightness) 00118 { 00119 // check whether brightness is within range 00120 if (brightness < 0.0f) 00121 brightness = 0.0f; 00122 if (brightness > 1.0f) 00123 brightness = 1.0f; 00124 // set PWM duty cycle 00125 _led->write(brightness); 00126 } 00127 00128 void N5110::setContrast(float contrast) { 00129 00130 // enforce limits 00131 if (contrast > 1.0f) 00132 contrast = 1.0f; 00133 else if (contrast < 0.0f) 00134 contrast = 0.0; 00135 00136 // convert to char in range 0 to 127 (i.e. 6 bits) 00137 char ic = char(contrast*127.0f); 00138 00139 sendCommand(0b00100001); // extended instruction set 00140 sendCommand(0b10000000 | ic); // set Vop (which controls contrast) 00141 sendCommand(0b00100000); // back to basic instruction set 00142 } 00143 00144 void N5110::setTempCoefficient(char tc) { 00145 00146 // enforce limits 00147 if (tc>3) { 00148 tc=3; 00149 } 00150 00151 // temperature coefficient may need increasing at low temperatures 00152 00153 sendCommand(0b00100001); // extended instruction set 00154 sendCommand(0b00000100 | tc); 00155 sendCommand(0b00100000); // back to basic instruction set 00156 } 00157 00158 void N5110::setBias(char bias) { 00159 00160 // from data sheet 00161 // bias mux rate 00162 // 0 1:100 00163 // 1 1:80 00164 // 2 1:65 00165 // 3 1:48 (default) 00166 // 4 1:40/1:34 00167 // 5 1:24 00168 // 6 1:18/1:16 00169 // 7 1:10/1:9/1:8 00170 00171 // enforce limits 00172 if (bias>7) { 00173 bias=7; 00174 } 00175 00176 sendCommand(0b00100001); // extended mode instruction 00177 sendCommand(0b00010000 | bias); 00178 sendCommand(0b00100000); // end of extended mode instruction 00179 } 00180 00181 // pulse the active low reset line 00182 void N5110::reset() 00183 { 00184 _rst->write(0); // reset the LCD 00185 _rst->write(1); 00186 } 00187 00188 // function to initialise SPI peripheral 00189 void N5110::initSPI() 00190 { 00191 _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 00192 _spi->frequency(4000000); // maximum of screen is 4 MHz 00193 } 00194 00195 // send a command to the display 00196 void N5110::sendCommand(unsigned char command) 00197 { 00198 _dc->write(0); // set DC low for command 00199 _sce->write(0); // set CE low to begin frame 00200 _spi->write(command); // send command 00201 _dc->write(1); // turn back to data by default 00202 _sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00203 } 00204 00205 // send data to the display at the current XY address 00206 // dc is set to 1 (i.e. data) after sending a command and so should 00207 // be the default mode. 00208 void N5110::sendData(unsigned char data) 00209 { 00210 _sce->write(0); // set CE low to begin frame 00211 _spi->write(data); 00212 _sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00213 } 00214 00215 // this function writes 0 to the 504 bytes to clear the RAM 00216 void N5110::clearRAM() 00217 { 00218 _sce->write(0); //set CE low to begin frame 00219 for(int i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes 00220 _spi->write(0x00); // send 0's 00221 } 00222 _sce->write(1); // set CE high to end frame 00223 } 00224 00225 // function to set the XY address in RAM for subsequenct data write 00226 void N5110::setXYAddress(unsigned int const x, 00227 unsigned int const y) 00228 { 00229 if (x<WIDTH && y<HEIGHT) { // check within range 00230 sendCommand(0b00100000); // basic instruction 00231 sendCommand(0b10000000 | x); // send addresses to display with relevant mask 00232 sendCommand(0b01000000 | y); 00233 } 00234 } 00235 00236 // These functions are used to set, clear and get the value of pixels in the display 00237 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh() 00238 // function must be called after set and clear in order to update the display 00239 void N5110::setPixel(unsigned int const x, 00240 unsigned int const y, 00241 bool const state) 00242 { 00243 if (x<WIDTH && y<HEIGHT) { // check within range 00244 // calculate bank and shift 1 to required position in the data byte 00245 if(state) buffer[x][y/8] |= (1 << y%8); 00246 else buffer[x][y/8] &= ~(1 << y%8); 00247 } 00248 } 00249 00250 void N5110::clearPixel(unsigned int const x, 00251 unsigned int const y) 00252 { 00253 if (x<WIDTH && y<HEIGHT) { // check within range 00254 // calculate bank and shift 1 to required position (using bit clear) 00255 buffer[x][y/8] &= ~(1 << y%8); 00256 } 00257 } 00258 00259 int N5110::getPixel(unsigned int const x, 00260 unsigned int const y) const 00261 { 00262 if (x<WIDTH && y<HEIGHT) { // check within range 00263 // return relevant bank and mask required bit 00264 00265 int pixel = (int) buffer[x][y/8] & (1 << y%8); 00266 00267 if (pixel) 00268 return 1; 00269 else 00270 return 0; 00271 } 00272 00273 return 0; 00274 00275 } 00276 00277 // function to refresh the display 00278 void N5110::refresh() 00279 { 00280 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display 00281 // address auto increments after printing string, so buffer[0][0] will not coincide 00282 // with top-left pixel after priting string 00283 00284 _sce->write(0); //set CE low to begin frame 00285 00286 for(int j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00287 for(int i = 0; i < WIDTH; i++) { 00288 _spi->write(buffer[i][j]); // send buffer 00289 } 00290 } 00291 _sce->write(1); // set CE high to end frame 00292 00293 } 00294 00295 // fills the buffer with random bytes. Can be used to test the display. 00296 // The rand() function isn't seeded so it probably creates the same pattern everytime 00297 void N5110::randomiseBuffer() 00298 { 00299 int i,j; 00300 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00301 for(i = 0; i < WIDTH; i++) { 00302 buffer[i][j] = rand()%256; // generate random byte 00303 } 00304 } 00305 00306 } 00307 00308 // function to print 5x7 font 00309 void N5110::printChar(char const c, 00310 unsigned int const x, 00311 unsigned int const y) 00312 { 00313 if (y<BANKS) { // check if printing in range of y banks 00314 00315 for (int i = 0; i < 5 ; i++ ) { 00316 int pixel_x = x+i; 00317 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83) 00318 break; 00319 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i]; 00320 // array is offset by 32 relative to ASCII, each character is 5 pixels wide 00321 } 00322 00323 } 00324 } 00325 00326 // function to print string at specified position 00327 void N5110::printString(const char *str, 00328 unsigned int const x, 00329 unsigned int const y) 00330 { 00331 if (y<BANKS) { // check if printing in range of y banks 00332 00333 int n = 0 ; // counter for number of characters in string 00334 // loop through string and print character 00335 while(*str) { 00336 00337 // writes the character bitmap data to the buffer, so that 00338 // text and pixels can be displayed at the same time 00339 for (int i = 0; i < 5 ; i++ ) { 00340 int pixel_x = x+i+n*6; 00341 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83) 00342 break; 00343 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i]; 00344 } 00345 str++; // go to next character in string 00346 n++; // increment index 00347 } 00348 } 00349 } 00350 00351 // function to clear the screen buffer 00352 void N5110::clear() 00353 { 00354 memset(buffer,0,sizeof(buffer)); 00355 } 00356 00357 // function to plot array on display 00358 void N5110::plotArray(float const array[]) 00359 { 00360 for (int i=0; i<WIDTH; i++) { // loop through array 00361 // elements are normalised from 0.0 to 1.0, so multiply 00362 // by 47 to convert to pixel range, and subtract from 47 00363 // since top-left is 0,0 in the display geometry 00364 setPixel(i,47 - int(array[i]*47.0f),true); 00365 } 00366 00367 } 00368 00369 // function to draw circle 00370 void N5110:: drawCircle(unsigned int const x0, 00371 unsigned int const y0, 00372 unsigned int const radius, 00373 FillType const fill) 00374 { 00375 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 00376 int x = radius; 00377 int y = 0; 00378 int radiusError = 1-x; 00379 00380 while(x >= y) { 00381 00382 // if transparent, just draw outline 00383 if (fill == FILL_TRANSPARENT) { 00384 setPixel( x + x0, y + y0,true); 00385 setPixel(-x + x0, y + y0,true); 00386 setPixel( y + x0, x + y0,true); 00387 setPixel(-y + x0, x + y0,true); 00388 setPixel(-y + x0, -x + y0,true); 00389 setPixel( y + x0, -x + y0,true); 00390 setPixel( x + x0, -y + y0,true); 00391 setPixel(-x + x0, -y + y0,true); 00392 } else { // drawing filled circle, so draw lines between points at same y value 00393 00394 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill 00395 00396 drawLine(x+x0,y+y0,-x+x0,y+y0,type); 00397 drawLine(y+x0,x+y0,-y+x0,x+y0,type); 00398 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type); 00399 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type); 00400 } 00401 00402 y++; 00403 if (radiusError<0) { 00404 radiusError += 2 * y + 1; 00405 } else { 00406 x--; 00407 radiusError += 2 * (y - x) + 1; 00408 } 00409 } 00410 00411 } 00412 00413 void N5110::drawLine(unsigned int const x0, 00414 unsigned int const y0, 00415 unsigned int const x1, 00416 unsigned int const y1, 00417 unsigned int const type) 00418 { 00419 // Note that the ranges can be negative so we have to turn the input values 00420 // into signed integers first 00421 int const y_range = static_cast<int>(y1) - static_cast<int>(y0); 00422 int const x_range = static_cast<int>(x1) - static_cast<int>(x0); 00423 00424 // if dotted line, set step to 2, else step is 1 00425 unsigned int const step = (type==2) ? 2:1; 00426 00427 // make sure we loop over the largest range to get the most pixels on the display 00428 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels 00429 // or else we'll only end up with 1 pixel in the x column 00430 if ( abs(x_range) > abs(y_range) ) { 00431 00432 // ensure we loop from smallest to largest or else for-loop won't run as expected 00433 unsigned int const start = x_range > 0 ? x0:x1; 00434 unsigned int const stop = x_range > 0 ? x1:x0; 00435 00436 // loop between x pixels 00437 for (unsigned int x = start; x<= stop ; x+=step) { 00438 // do linear interpolation 00439 int const dx = static_cast<int>(x)-static_cast<int>(x0); 00440 unsigned int const y = y0 + y_range * dx / x_range; 00441 00442 // If the line type is '0', this will clear the pixel 00443 // If it is '1' or '2', the pixel will be set 00444 setPixel(x,y, type); 00445 } 00446 } else { 00447 00448 // ensure we loop from smallest to largest or else for-loop won't run as expected 00449 unsigned int const start = y_range > 0 ? y0:y1; 00450 unsigned int const stop = y_range > 0 ? y1:y0; 00451 00452 for (unsigned int y = start; y<= stop ; y+=step) { 00453 // do linear interpolation 00454 int const dy = static_cast<int>(y)-static_cast<int>(y0); 00455 unsigned int const x = x0 + x_range * dy / y_range; 00456 00457 // If the line type is '0', this will clear the pixel 00458 // If it is '1' or '2', the pixel will be set 00459 setPixel(x,y, type); 00460 } 00461 } 00462 00463 } 00464 00465 void N5110::drawRect(unsigned int const x0, 00466 unsigned int const y0, 00467 unsigned int const width, 00468 unsigned int const height, 00469 FillType const fill) 00470 { 00471 if (fill == FILL_TRANSPARENT) { // transparent, just outline 00472 drawLine(x0,y0,x0+(width-1),y0,1); // top 00473 drawLine(x0,y0+(height-1),x0+(width-1),y0+(height-1),1); // bottom 00474 drawLine(x0,y0,x0,y0+(height-1),1); // left 00475 drawLine(x0+(width-1),y0,x0+(width-1),y0+(height-1),1); // right 00476 } else { // filled rectangle 00477 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill 00478 for (int y = y0; y<y0+height; y++) { // loop through rows of rectangle 00479 drawLine(x0,y,x0+(width-1),y,type); // draw line across screen 00480 } 00481 } 00482 } 00483 00484 void N5110::drawSprite(int x0, 00485 int y0, 00486 int nrows, 00487 int ncols, 00488 int *sprite) 00489 { 00490 for (int i = 0; i < nrows; i++) { 00491 for (int j = 0 ; j < ncols ; j++) { 00492 00493 int pixel = *((sprite+i*ncols)+j); 00494 setPixel(x0+j,y0+i, pixel); 00495 } 00496 } 00497 }
Generated on Thu Jul 14 2022 18:15:41 by
