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 N5110 by
N5110.cpp
00001 /** 00002 @file N5110.cpp 00003 00004 @brief Member functions implementations 00005 00006 */ 00007 #include "mbed.h" 00008 #include "N5110.h" 00009 00010 00011 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin) 00012 { 00013 00014 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise 00015 initSPI(); 00016 00017 // set up pins as required 00018 led = new PwmOut(ledPin); 00019 pwr = new DigitalOut(pwrPin); 00020 sce = new DigitalOut(scePin); 00021 rst = new DigitalOut(rstPin); 00022 dc = new DigitalOut(dcPin); 00023 bufferFrameEdit = 1; 00024 bufferFrameDisplay = 1; 00025 00026 } 00027 00028 // initialise function - powers up and sends the initialisation commands 00029 void N5110::init() 00030 { 00031 turnOn(); // power up 00032 wait_ms(10); // small delay seems to prevent spurious pixels during mbed reset 00033 reset(); // reset LCD - must be done within 100 ms 00034 00035 // function set - extended 00036 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE); 00037 // Don't completely understand these parameters - they seem to work as they are 00038 // Consult the datasheet if you need to change them 00039 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library 00040 sendCommand(CMD_TC_TEMP_2); // temperature control 00041 sendCommand(CMD_BI_MUX_48); // bias 00042 00043 // function set - basic 00044 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE); 00045 normalMode(); // normal video mode by default 00046 sendCommand(CMD_DC_NORMAL_MODE); // black on white 00047 00048 // RAM is undefined at power-up so clear 00049 clearRAM(); 00050 00051 } 00052 00053 // sets normal video mode (black on white) 00054 void N5110::normalMode() 00055 { 00056 sendCommand(CMD_DC_NORMAL_MODE); 00057 00058 } 00059 00060 // sets normal video mode (white on black) 00061 void N5110::inverseMode() 00062 { 00063 sendCommand(CMD_DC_INVERT_VIDEO); 00064 } 00065 00066 // function to power up the LCD and backlight 00067 void N5110::turnOn() 00068 { 00069 // set brightness of LED - 0.0 to 1.0 - default is 50% 00070 setBrightness(0.5); 00071 pwr->write(1); // apply power 00072 } 00073 00074 // function to power down LCD 00075 void N5110::turnOff() 00076 { 00077 setBrightness(0.0); // turn backlight off 00078 clearRAM(); // clear RAM to ensure specified current consumption 00079 // send command to ensure we are in basic mode 00080 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE); 00081 // clear the display 00082 sendCommand(CMD_DC_CLEAR_DISPLAY); 00083 // enter the extended mode and power down 00084 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE); 00085 // small delay and then turn off the power pin 00086 wait_ms(10); 00087 pwr->write(0); 00088 00089 } 00090 00091 // function to change LED backlight brightness 00092 void N5110::setBrightness(float brightness) 00093 { 00094 // check whether brightness is within range 00095 if (brightness < 0.0) 00096 brightness = 0.0; 00097 if (brightness > 1.0) 00098 brightness = 1.0; 00099 // set PWM duty cycle 00100 led->write(brightness); 00101 } 00102 00103 // function to change LED backlight PWM frequency 00104 void N5110::setPwmFreq(float freq) 00105 { 00106 led->period_us(freq); 00107 } 00108 00109 00110 // pulse the active low reset line 00111 void N5110::reset() 00112 { 00113 rst->write(0); // reset the LCD 00114 rst->write(1); 00115 } 00116 00117 // function to initialise SPI peripheral 00118 void N5110::initSPI() 00119 { 00120 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 00121 spi->frequency(4000000); // maximum of screen is 4 MHz 00122 } 00123 00124 // send a command to the display 00125 void N5110::sendCommand(unsigned char command) 00126 { 00127 dc->write(0); // set DC low for command 00128 sce->write(0); // set CE low to begin frame 00129 spi->write(command); // send command 00130 dc->write(1); // turn back to data by default 00131 sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00132 00133 } 00134 00135 // send data to the display at the current XY address 00136 // dc is set to 1 (i.e. data) after sending a command and so should 00137 // be the default mode. 00138 void N5110::sendData(unsigned char data) 00139 { 00140 sce->write(0); // set CE low to begin frame 00141 spi->write(data); 00142 sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00143 } 00144 00145 // this function writes 0 to the 504 bytes to clear the RAM 00146 void N5110::clearRAM() 00147 { 00148 int i; 00149 sce->write(0); //set CE low to begin frame 00150 for(i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes 00151 spi->write(0x00); // send 0's 00152 } 00153 sce->write(1); // set CE high to end frame 00154 00155 } 00156 00157 // function to set the XY address in RAM for subsequenct data write 00158 void N5110::setXYAddress(int x, int y) 00159 { 00160 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00161 sendCommand(0x80 | x); // send addresses to display with relevant mask 00162 sendCommand(0x40 | y); 00163 } 00164 } 00165 00166 void N5110::selectBuffer(int type,int buffer) 00167 { 00168 switch(type) { 00169 case 1: //display 00170 bufferFrameDisplay = buffer; 00171 break; 00172 case 2: //editable 00173 bufferFrameEdit = buffer; 00174 break; 00175 case 3: //both 00176 bufferFrameEdit = buffer; 00177 bufferFrameDisplay = buffer; 00178 break; 00179 } 00180 } 00181 00182 // These functions are used to set, clear and get the value of pixels in the display 00183 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh() 00184 // function must be called after set and clear in order to update the display 00185 void N5110::writePixel(int x, int y, int v) 00186 { 00187 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00188 // calculate bank and shift 1 to required position in the data byte 00189 if(v==1) { 00190 buffer[x][y/8][bufferFrameEdit] |= (1 << y%8); 00191 } 00192 if(v==0) { 00193 buffer[x][y/8][bufferFrameEdit] &= ~(1 << y%8); 00194 } 00195 } 00196 } 00197 00198 void N5110::setPixel(int x, int y) 00199 { 00200 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00201 // calculate bank and shift 1 to required position in the data byte 00202 buffer[x][y/8][bufferFrameEdit] |= (1 << y%8); 00203 } 00204 } 00205 00206 void N5110::clearPixel(int x, int y) 00207 { 00208 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00209 // calculate bank and shift 1 to required position (using bit clear) 00210 buffer[x][y/8][bufferFrameEdit] &= ~(1 << y%8); 00211 } 00212 } 00213 00214 int N5110::getPixel(int x, int y) 00215 { 00216 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00217 // return relevant bank and mask required bit 00218 return (int) buffer[x][y/8][bufferFrameEdit] & (1 << y%8); 00219 } else { 00220 return 0; 00221 } 00222 } 00223 00224 // function to refresh the display 00225 void N5110::refresh() 00226 { 00227 int i,j; 00228 00229 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display 00230 // address auto increments after printing string, so buffer[0][0] will not coincide 00231 // with top-left pixel after priting string 00232 00233 sce->write(0); //set CE low to begin frame 00234 00235 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00236 for(i = 0; i < WIDTH; i++) { 00237 spi->write(buffer[i][j][bufferFrameDisplay]); // send buffer 00238 } 00239 } 00240 sce->write(1); // set CE high to end frame 00241 00242 } 00243 00244 // fills the buffer with random bytes. Can be used to test the display. 00245 // The rand() function isn't seeded so it probably creates the same pattern everytime 00246 void N5110::randomiseBuffer() 00247 { 00248 int i,j; 00249 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00250 for(i = 0; i < WIDTH; i++) { 00251 buffer[i][j][bufferFrameEdit] = rand()%256; // generate random byte 00252 } 00253 } 00254 00255 } 00256 00257 // function to print 5x7 font 00258 void N5110::printChar(char c,int x,int y) 00259 { 00260 for (int i = 0; i < 5 ; i++ ) { 00261 buffer[x+i][y][bufferFrameEdit] = font5x7[(c - 32)*5 + i]; 00262 // array is offset by 32 relative to ASCII, each character is 5 pixels wide 00263 } 00264 00265 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0 00266 } 00267 00268 // function to print string at specified position 00269 void N5110::printString(const char * str,int x,int y) 00270 { 00271 int n = 0 ; // counter for number of characters in string 00272 // loop through string and print character 00273 while(*str) { 00274 00275 // writes the character bitmap data to the buffer, so that 00276 // text and pixels can be displayed at the same time 00277 for (int i = 0; i < 5 ; i++ ) { 00278 buffer[x+i+n*6][y][bufferFrameEdit] = font5x7[(*str - 32)*5 + i]; 00279 } 00280 00281 str++; // go to next character in string 00282 n++; // increment index 00283 } 00284 00285 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0 00286 00287 } 00288 00289 // function to clear the screen 00290 void N5110::clear() 00291 { 00292 clearBuffer(); // clear the buffer then call the refresh function 00293 refresh(); 00294 } 00295 00296 // function to clear the buffer 00297 void N5110::clearBuffer() 00298 { 00299 int i,j; 00300 for (i=0; i<WIDTH; i++) { // loop through the banks and set the buffer to 0 00301 for (j=0; j<BANKS; j++) { 00302 buffer[i][j][bufferFrameEdit]=0; 00303 } 00304 } 00305 } 00306 00307 // function to write array to buffer 00308 void N5110::plotArray2d(bool array2d[][HEIGHT]) 00309 { 00310 int i,j; 00311 for (i=0; i<=WIDTH; i++) { // loop through the banks and copy data across 00312 for (j=0; j<=HEIGHT; j++) { 00313 writePixel(i,j,array2d[i][j]); 00314 } 00315 } 00316 refresh(); 00317 } 00318 00319 // function to write offset 3d array to buffer 00320 void N5110::plotArray3d(bool array3d[][50][2],int z,int off_x, int off_y) 00321 { 00322 int i,j; 00323 for (i=0; i<=WIDTH; i++) { // loop through the banks and copy data across 00324 for (j=0; j<=HEIGHT; j++) { 00325 writePixel(i,j,array3d[i-off_x][j-off_y][z]); 00326 } 00327 } 00328 refresh(); 00329 } 00330 00331 // function to plot array on display 00332 void N5110::plotArray(float array[]) 00333 { 00334 00335 int i; 00336 00337 for (i=0; i<WIDTH; i++) { // loop through array 00338 // elements are normalised from 0.0 to 1.0, so multiply 00339 // by 47 to convert to pixel range, and subtract from 47 00340 // since top-left is 0,0 in the display geometry 00341 setPixel(i,47 - int(array[i]*47.0)); 00342 } 00343 00344 refresh(); 00345 00346 } 00347 00348 // function to draw circle 00349 void N5110:: drawCircle(int x0,int y0,int radius,int fill) 00350 { 00351 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 00352 int x = radius; 00353 int y = 0; 00354 int radiusError = 1-x; 00355 00356 while(x >= y) { 00357 00358 // if transparent, just draw outline 00359 if (fill == 0) { 00360 setPixel( x + x0, y + y0); 00361 setPixel(-x + x0, y + y0); 00362 setPixel( y + x0, x + y0); 00363 setPixel(-y + x0, x + y0); 00364 setPixel(-y + x0, -x + y0); 00365 setPixel( y + x0, -x + y0); 00366 setPixel( x + x0, -y + y0); 00367 setPixel(-x + x0, -y + y0); 00368 } else { // drawing filled circle, so draw lines between points at same y value 00369 00370 int type = (fill==1) ? 1:0; // black or white fill 00371 00372 drawLine(x+x0,y+y0,-x+x0,y+y0,type); 00373 drawLine(y+x0,x+y0,-y+x0,x+y0,type); 00374 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type); 00375 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type); 00376 } 00377 00378 00379 y++; 00380 if (radiusError<0) { 00381 radiusError += 2 * y + 1; 00382 } else { 00383 x--; 00384 radiusError += 2 * (y - x) + 1; 00385 } 00386 } 00387 00388 refresh(); 00389 } 00390 00391 void N5110::drawLine(int x0,int y0,int x1,int y1,int type) 00392 { 00393 int y_range = y1-y0; // calc range of y and x 00394 int x_range = x1-x0; 00395 int start,stop,step; 00396 00397 // if dotted line, set step to 2, else step is 1 00398 step = (type==2) ? 2:1; 00399 00400 // make sure we loop over the largest range to get the most pixels on the display 00401 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels 00402 // or else we'll only end up with 1 pixel in the x column 00403 if ( abs(x_range) > abs(y_range) ) { 00404 00405 // ensure we loop from smallest to largest or else for-loop won't run as expected 00406 start = x1>x0 ? x0:x1; 00407 stop = x1>x0 ? x1:x0; 00408 00409 // loop between x pixels 00410 for (int x = start; x<= stop ; x+=step) { 00411 // do linear interpolation 00412 int y = y0 + (y1-y0)*(x-x0)/(x1-x0); 00413 00414 if (type == 0) // if 'white' line, turn off pixel 00415 clearPixel(x,y); 00416 else 00417 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel 00418 } 00419 } else { 00420 00421 // ensure we loop from smallest to largest or else for-loop won't run as expected 00422 start = y1>y0 ? y0:y1; 00423 stop = y1>y0 ? y1:y0; 00424 00425 for (int y = start; y<= stop ; y+=step) { 00426 // do linear interpolation 00427 int x = x0 + (x1-x0)*(y-y0)/(y1-y0); 00428 00429 if (type == 0) // if 'white' line, turn off pixel 00430 clearPixel(x,y); 00431 else 00432 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel 00433 00434 } 00435 } 00436 00437 refresh(); 00438 } 00439 00440 void N5110::drawRect(int x0,int y0,int width,int height,int fill) 00441 { 00442 00443 if (fill == 0) { // transparent, just outline 00444 drawLine(x0,y0,x0+width,y0,1); // top 00445 drawLine(x0,y0+height,x0+width,y0+height,1); // bottom 00446 drawLine(x0,y0,x0,y0+height,1); // left 00447 drawLine(x0+width,y0,x0+width,y0+height,1); // right 00448 } else { // filled rectangle 00449 int type = (fill==1) ? 1:0; // black or white fill 00450 for (int y = y0; y<= y0+height; y++) { // loop through rows of rectangle 00451 drawLine(x0,y,x0+width,y,type); // draw line across screen 00452 } 00453 } 00454 00455 }
Generated on Sat Jul 16 2022 08:49:27 by
1.7.2
