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 00012 00013 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin) 00014 { 00015 00016 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise 00017 initSPI(); 00018 00019 // set up pins as required 00020 led = new PwmOut(ledPin); 00021 pwr = new DigitalOut(pwrPin); 00022 sce = new DigitalOut(scePin); 00023 rst = new DigitalOut(rstPin); 00024 dc = new DigitalOut(dcPin); 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 00104 // pulse the active low reset line 00105 void N5110::reset() 00106 { 00107 rst->write(0); // reset the LCD 00108 rst->write(1); 00109 } 00110 00111 // function to initialise SPI peripheral 00112 void N5110::initSPI() 00113 { 00114 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 00115 spi->frequency(4000000); // maximum of screen is 4 MHz 00116 } 00117 00118 // send a command to the display 00119 void N5110::sendCommand(unsigned char command) 00120 { 00121 dc->write(0); // set DC low for command 00122 sce->write(0); // set CE low to begin frame 00123 spi->write(command); // send command 00124 dc->write(1); // turn back to data by default 00125 sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00126 00127 } 00128 00129 // send data to the display at the current XY address 00130 // dc is set to 1 (i.e. data) after sending a command and so should 00131 // be the default mode. 00132 void N5110::sendData(unsigned char data) 00133 { 00134 sce->write(0); // set CE low to begin frame 00135 spi->write(data); 00136 sce->write(1); // set CE high to end frame (expected for transmission of single byte) 00137 } 00138 00139 // this function writes 0 to the 504 bytes to clear the RAM 00140 void N5110::clearRAM() 00141 { 00142 int i; 00143 sce->write(0); //set CE low to begin frame 00144 for(i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes 00145 spi->write(0x00); // send 0's 00146 } 00147 sce->write(1); // set CE high to end frame 00148 00149 } 00150 00151 // function to set the XY address in RAM for subsequenct data write 00152 void N5110::setXYAddress(int x, int y) 00153 { 00154 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00155 sendCommand(0x80 | x); // send addresses to display with relevant mask 00156 sendCommand(0x40 | y); 00157 } 00158 } 00159 00160 // These functions are used to set, clear and get the value of pixels in the display 00161 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh() 00162 // function must be called after set and clear in order to update the display 00163 void N5110::setPixel(int x, int y) 00164 { 00165 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00166 // calculate bank and shift 1 to required position in the data byte 00167 buffer[x][y/8] |= (1 << y%8); 00168 } 00169 } 00170 00171 void N5110::clearPixel(int x, int y) 00172 { 00173 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00174 // calculate bank and shift 1 to required position (using bit clear) 00175 buffer[x][y/8] &= ~(1 << y%8); 00176 } 00177 } 00178 00179 int N5110::getPixel(int x, int y) 00180 { 00181 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range 00182 // return relevant bank and mask required bit 00183 return (int) buffer[x][y/8] & (1 << y%8); 00184 // note this does not necessarily return 1 - a non-zero number represents a pixel 00185 } else { 00186 return 0; 00187 } 00188 } 00189 00190 // function to refresh the display 00191 void N5110::refresh() 00192 { 00193 int i,j; 00194 00195 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display 00196 // address auto increments after printing string, so buffer[0][0] will not coincide 00197 // with top-left pixel after priting string 00198 00199 sce->write(0); //set CE low to begin frame 00200 00201 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00202 for(i = 0; i < WIDTH; i++) { 00203 spi->write(buffer[i][j]); // send buffer 00204 } 00205 } 00206 sce->write(1); // set CE high to end frame 00207 00208 } 00209 00210 // fills the buffer with random bytes. Can be used to test the display. 00211 // The rand() function isn't seeded so it probably creates the same pattern everytime 00212 void N5110::randomiseBuffer() 00213 { 00214 int i,j; 00215 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing 00216 for(i = 0; i < WIDTH; i++) { 00217 buffer[i][j] = rand()%256; // generate random byte 00218 } 00219 } 00220 00221 } 00222 00223 // function to print 5x7 font 00224 void N5110::printChar(char c,int x,int y) 00225 { 00226 if (y>=0 && y<BANKS) { // check if printing in range of y banks 00227 00228 for (int i = 0; i < 5 ; i++ ) { 00229 int pixel_x = x+i; 00230 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83) 00231 break; 00232 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i]; 00233 // array is offset by 32 relative to ASCII, each character is 5 pixels wide 00234 } 00235 00236 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0 00237 } 00238 } 00239 00240 // function to print string at specified position 00241 void N5110::printString(const char * str,int x,int y) 00242 { 00243 if (y>=0 && y<BANKS) { // check if printing in range of y banks 00244 00245 int n = 0 ; // counter for number of characters in string 00246 // loop through string and print character 00247 while(*str) { 00248 00249 // writes the character bitmap data to the buffer, so that 00250 // text and pixels can be displayed at the same time 00251 for (int i = 0; i < 5 ; i++ ) { 00252 int pixel_x = x+i+n*6; 00253 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83) 00254 break; 00255 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i]; 00256 } 00257 00258 str++; // go to next character in string 00259 00260 n++; // increment index 00261 00262 } 00263 00264 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0 00265 } 00266 } 00267 00268 // function to clear the screen 00269 void N5110::clear() 00270 { 00271 clearBuffer(); // clear the buffer then call the refresh function 00272 refresh(); 00273 } 00274 00275 // function to clear the buffer 00276 void N5110::clearBuffer() 00277 { 00278 int i,j; 00279 for (i=0; i<WIDTH; i++) { // loop through the banks and set the buffer to 0 00280 for (j=0; j<BANKS; j++) { 00281 buffer[i][j]=0; 00282 } 00283 } 00284 } 00285 00286 // function to plot array on display 00287 void N5110::plotArray(float array[]) 00288 { 00289 00290 int i; 00291 00292 for (i=0; i<WIDTH; i++) { // loop through array 00293 // elements are normalised from 0.0 to 1.0, so multiply 00294 // by 47 to convert to pixel range, and subtract from 47 00295 // since top-left is 0,0 in the display geometry 00296 setPixel(i,47 - int(array[i]*47.0)); 00297 } 00298 00299 refresh(); 00300 00301 } 00302 00303 // function to draw circle 00304 void N5110:: drawCircle(int x0,int y0,int radius,int fill) 00305 { 00306 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm 00307 int x = radius; 00308 int y = 0; 00309 int radiusError = 1-x; 00310 00311 while(x >= y) { 00312 00313 // if transparent, just draw outline 00314 if (fill == 0) { 00315 setPixel( x + x0, y + y0); 00316 setPixel(-x + x0, y + y0); 00317 setPixel( y + x0, x + y0); 00318 setPixel(-y + x0, x + y0); 00319 setPixel(-y + x0, -x + y0); 00320 setPixel( y + x0, -x + y0); 00321 setPixel( x + x0, -y + y0); 00322 setPixel(-x + x0, -y + y0); 00323 } else { // drawing filled circle, so draw lines between points at same y value 00324 00325 int type = (fill==1) ? 1:0; // black or white fill 00326 00327 drawLine(x+x0,y+y0,-x+x0,y+y0,type); 00328 drawLine(y+x0,x+y0,-y+x0,x+y0,type); 00329 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type); 00330 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type); 00331 } 00332 00333 00334 y++; 00335 if (radiusError<0) { 00336 radiusError += 2 * y + 1; 00337 } else { 00338 x--; 00339 radiusError += 2 * (y - x) + 1; 00340 } 00341 } 00342 00343 } 00344 00345 void N5110::drawLine(int x0,int y0,int x1,int y1,int type) 00346 { 00347 int y_range = y1-y0; // calc range of y and x 00348 int x_range = x1-x0; 00349 int start,stop,step; 00350 00351 // if dotted line, set step to 2, else step is 1 00352 step = (type==2) ? 2:1; 00353 00354 // make sure we loop over the largest range to get the most pixels on the display 00355 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels 00356 // or else we'll only end up with 1 pixel in the x column 00357 if ( abs(x_range) > abs(y_range) ) { 00358 00359 // ensure we loop from smallest to largest or else for-loop won't run as expected 00360 start = x1>x0 ? x0:x1; 00361 stop = x1>x0 ? x1:x0; 00362 00363 // loop between x pixels 00364 for (int x = start; x<= stop ; x+=step) { 00365 // do linear interpolation 00366 int y = y0 + (y1-y0)*(x-x0)/(x1-x0); 00367 00368 if (type == 0) // if 'white' line, turn off pixel 00369 clearPixel(x,y); 00370 else 00371 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel 00372 } 00373 } else { 00374 00375 // ensure we loop from smallest to largest or else for-loop won't run as expected 00376 start = y1>y0 ? y0:y1; 00377 stop = y1>y0 ? y1:y0; 00378 00379 for (int y = start; y<= stop ; y+=step) { 00380 // do linear interpolation 00381 int x = x0 + (x1-x0)*(y-y0)/(y1-y0); 00382 00383 if (type == 0) // if 'white' line, turn off pixel 00384 clearPixel(x,y); 00385 else 00386 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel 00387 00388 } 00389 } 00390 00391 } 00392 00393 void N5110::drawRect(int x0,int y0,int width,int height,int fill) 00394 { 00395 00396 if (fill == 0) { // transparent, just outline 00397 drawLine(x0,y0,x0+width,y0,1); // top 00398 drawLine(x0,y0+height,x0+width,y0+height,1); // bottom 00399 drawLine(x0,y0,x0,y0+height,1); // left 00400 drawLine(x0+width,y0,x0+width,y0+height,1); // right 00401 } else { // filled rectangle 00402 int type = (fill==1) ? 1:0; // black or white fill 00403 for (int y = y0; y<= y0+height; y++) { // loop through rows of rectangle 00404 drawLine(x0,y,x0+width,y,type); // draw line across screen 00405 } 00406 } 00407 00408 }
Generated on Sat Jul 16 2022 21:35:30 by
