Updated for mbed: Simple library for interfacing to Nokia 5110 LCD display (as found on the SparkFun website).

Fork of N5110 by Craig Evans

Committer:
eencae
Date:
Tue May 20 19:43:52 2014 +0000
Revision:
9:7701f0126ba7
Parent:
8:40abe5736eca
Child:
10:6f3abb40202b
printString() has been modified. Rather than sending the string to the display using the printChar(), it now writes the character bitmap data to the screen buffer and refreshes the display. This means that pixels and strings can now be used together.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 5:6ea180eef702 1 /**
eencae 5:6ea180eef702 2 @file N5110.cpp
eencae 5:6ea180eef702 3
eencae 5:6ea180eef702 4 @brief Member functions implementations
eencae 5:6ea180eef702 5
eencae 5:6ea180eef702 6 */
eencae 0:d563e74f0ae9 7 #include "mbed.h"
eencae 0:d563e74f0ae9 8 #include "N5110.h"
eencae 0:d563e74f0ae9 9
eencae 2:e93021cfb0a9 10
eencae 1:df68f34cd32d 11 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
eencae 0:d563e74f0ae9 12 {
eencae 0:d563e74f0ae9 13
eencae 0:d563e74f0ae9 14 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
eencae 0:d563e74f0ae9 15 initSPI();
eencae 0:d563e74f0ae9 16
eencae 6:adb79338d40f 17 // set up pins as required
eencae 0:d563e74f0ae9 18 led = new PwmOut(ledPin);
eencae 0:d563e74f0ae9 19 pwr = new DigitalOut(pwrPin);
eencae 0:d563e74f0ae9 20 sce = new DigitalOut(scePin);
eencae 0:d563e74f0ae9 21 rst = new DigitalOut(rstPin);
eencae 0:d563e74f0ae9 22 dc = new DigitalOut(dcPin);
eencae 0:d563e74f0ae9 23
eencae 0:d563e74f0ae9 24 }
eencae 0:d563e74f0ae9 25
eencae 6:adb79338d40f 26 // initialise function - powers up and sends the initialisation commands
eencae 0:d563e74f0ae9 27 void N5110::init()
eencae 0:d563e74f0ae9 28 {
eencae 6:adb79338d40f 29 turnOn(); // power up
eencae 6:adb79338d40f 30 wait_ms(10); // small delay seems to prevent spurious pixels during mbed reset
eencae 6:adb79338d40f 31 reset(); // reset LCD - must be done within 100 ms
eencae 0:d563e74f0ae9 32
eencae 0:d563e74f0ae9 33 // function set - extended
eencae 0:d563e74f0ae9 34 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 35 // Don't completely understand these parameters - they seem to work as they are
eencae 6:adb79338d40f 36 // Consult the datasheet if you need to change them
eencae 1:df68f34cd32d 37 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library
eencae 0:d563e74f0ae9 38 sendCommand(CMD_TC_TEMP_2); // temperature control
eencae 0:d563e74f0ae9 39 sendCommand(CMD_BI_MUX_48); // bias
eencae 0:d563e74f0ae9 40
eencae 0:d563e74f0ae9 41 // function set - basic
eencae 0:d563e74f0ae9 42 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 1:df68f34cd32d 43 normalMode(); // normal video mode by default
eencae 0:d563e74f0ae9 44 sendCommand(CMD_DC_NORMAL_MODE); // black on white
eencae 0:d563e74f0ae9 45
eencae 0:d563e74f0ae9 46 // RAM is undefined at power-up so clear
eencae 0:d563e74f0ae9 47 clearRAM();
eencae 0:d563e74f0ae9 48
eencae 0:d563e74f0ae9 49 }
eencae 1:df68f34cd32d 50
eencae 1:df68f34cd32d 51 // sets normal video mode (black on white)
eencae 1:df68f34cd32d 52 void N5110::normalMode() {
eencae 1:df68f34cd32d 53 sendCommand(CMD_DC_NORMAL_MODE);
eencae 1:df68f34cd32d 54
eencae 1:df68f34cd32d 55 }
eencae 1:df68f34cd32d 56
eencae 1:df68f34cd32d 57 // sets normal video mode (white on black)
eencae 1:df68f34cd32d 58 void N5110::inverseMode() {
eencae 1:df68f34cd32d 59 sendCommand(CMD_DC_INVERT_VIDEO);
eencae 1:df68f34cd32d 60 }
eencae 0:d563e74f0ae9 61
eencae 0:d563e74f0ae9 62 // function to power up the LCD and backlight
eencae 0:d563e74f0ae9 63 void N5110::turnOn()
eencae 0:d563e74f0ae9 64 {
eencae 0:d563e74f0ae9 65 // set brightness of LED - 0.0 to 1.0 - default is 50%
eencae 0:d563e74f0ae9 66 setBrightness(0.5);
eencae 0:d563e74f0ae9 67 pwr->write(1); // apply power
eencae 0:d563e74f0ae9 68 }
eencae 0:d563e74f0ae9 69
eencae 0:d563e74f0ae9 70 // function to power down LCD
eencae 0:d563e74f0ae9 71 void N5110::turnOff()
eencae 0:d563e74f0ae9 72 {
eencae 0:d563e74f0ae9 73 setBrightness(0.0); // turn backlight off
eencae 0:d563e74f0ae9 74 clearRAM(); // clear RAM to ensure specified current consumption
eencae 6:adb79338d40f 75 // send command to ensure we are in basic model
eencae 0:d563e74f0ae9 76 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
eencae 6:adb79338d40f 77 // clear the display
eencae 0:d563e74f0ae9 78 sendCommand(CMD_DC_CLEAR_DISPLAY);
eencae 6:adb79338d40f 79 // enter the extended mode and power down
eencae 0:d563e74f0ae9 80 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
eencae 6:adb79338d40f 81 // small delay and then turn off the power pin
eencae 6:adb79338d40f 82 wait_ms(10);
eencae 0:d563e74f0ae9 83 pwr->write(0);
eencae 0:d563e74f0ae9 84
eencae 0:d563e74f0ae9 85 }
eencae 0:d563e74f0ae9 86
eencae 0:d563e74f0ae9 87 // function to change LED backlight brightness
eencae 0:d563e74f0ae9 88 void N5110::setBrightness(float brightness)
eencae 0:d563e74f0ae9 89 {
eencae 0:d563e74f0ae9 90 // check whether brightness is within range
eencae 0:d563e74f0ae9 91 if (brightness < 0.0)
eencae 0:d563e74f0ae9 92 brightness = 0.0;
eencae 0:d563e74f0ae9 93 if (brightness > 1.0)
eencae 0:d563e74f0ae9 94 brightness = 1.0;
eencae 0:d563e74f0ae9 95 // set PWM duty cycle
eencae 0:d563e74f0ae9 96 led->write(brightness);
eencae 0:d563e74f0ae9 97 }
eencae 0:d563e74f0ae9 98
eencae 0:d563e74f0ae9 99
eencae 0:d563e74f0ae9 100 // pulse the active low reset line
eencae 0:d563e74f0ae9 101 void N5110::reset()
eencae 0:d563e74f0ae9 102 {
eencae 0:d563e74f0ae9 103 rst->write(0); // reset the LCD
eencae 0:d563e74f0ae9 104 rst->write(1);
eencae 0:d563e74f0ae9 105 }
eencae 0:d563e74f0ae9 106
eencae 0:d563e74f0ae9 107 // function to initialise SPI peripheral
eencae 0:d563e74f0ae9 108 void N5110::initSPI()
eencae 0:d563e74f0ae9 109 {
eencae 0:d563e74f0ae9 110 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
eencae 0:d563e74f0ae9 111 spi->frequency(4000000); // maximum of screen is 4 MHz
eencae 0:d563e74f0ae9 112 }
eencae 0:d563e74f0ae9 113
eencae 6:adb79338d40f 114 // send a command to the display
eencae 0:d563e74f0ae9 115 void N5110::sendCommand(unsigned char command)
eencae 0:d563e74f0ae9 116 {
eencae 0:d563e74f0ae9 117 dc->write(0); // set DC low for command
eencae 0:d563e74f0ae9 118 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 119 spi->write(command); // send command
eencae 0:d563e74f0ae9 120 dc->write(1); // turn back to data by default
eencae 0:d563e74f0ae9 121 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 122
eencae 0:d563e74f0ae9 123 }
eencae 0:d563e74f0ae9 124
eencae 6:adb79338d40f 125 // send data to the display at the current XY address
eencae 6:adb79338d40f 126 // dc is set to 1 (i.e. data) after sending a command and so should
eencae 6:adb79338d40f 127 // be the default mode.
eencae 0:d563e74f0ae9 128 void N5110::sendData(unsigned char data)
eencae 0:d563e74f0ae9 129 {
eencae 0:d563e74f0ae9 130 sce->write(0); // set CE low to begin frame
eencae 0:d563e74f0ae9 131 spi->write(data);
eencae 0:d563e74f0ae9 132 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:d563e74f0ae9 133 }
eencae 0:d563e74f0ae9 134
eencae 0:d563e74f0ae9 135 // this function writes 0 to the 504 bytes to clear the RAM
eencae 0:d563e74f0ae9 136 void N5110::clearRAM()
eencae 0:d563e74f0ae9 137 {
eencae 0:d563e74f0ae9 138 int i;
eencae 0:d563e74f0ae9 139 sce->write(0); //set CE low to begin frame
eencae 0:d563e74f0ae9 140 for(i = 0; i < 504; i++) { // 48 x 84 bits = 504 bytes
eencae 0:d563e74f0ae9 141 spi->write(0x00); // send 0's
eencae 0:d563e74f0ae9 142 }
eencae 0:d563e74f0ae9 143 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 144
eencae 0:d563e74f0ae9 145 }
eencae 0:d563e74f0ae9 146
eencae 6:adb79338d40f 147 // function to set the XY address in RAM for subsequenct data write
eencae 0:d563e74f0ae9 148 void N5110::setXYAddress(int x, int y)
eencae 0:d563e74f0ae9 149 {
eencae 0:d563e74f0ae9 150 // check whether address is in range
eencae 0:d563e74f0ae9 151 if (x > 83)
eencae 0:d563e74f0ae9 152 x=83;
eencae 0:d563e74f0ae9 153 if (y > 5)
eencae 0:d563e74f0ae9 154 y=5;
eencae 3:f90dd1042d17 155 if (x < 0)
eencae 3:f90dd1042d17 156 x=0;
eencae 3:f90dd1042d17 157 if (y < 0)
eencae 3:f90dd1042d17 158 y=0;
eencae 0:d563e74f0ae9 159
eencae 3:f90dd1042d17 160 sendCommand(0x80 | x); // send addresses to display with relevant mask
eencae 0:d563e74f0ae9 161 sendCommand(0x40 | y);
eencae 0:d563e74f0ae9 162 }
eencae 0:d563e74f0ae9 163
eencae 6:adb79338d40f 164 // These functions are used to set, clear and get the value of pixels in the display
eencae 6:adb79338d40f 165 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
eencae 6:adb79338d40f 166 // function must be called after set and clear in order to update the display
eencae 0:d563e74f0ae9 167 void N5110::setPixel(int x, int y)
eencae 0:d563e74f0ae9 168 {
eencae 6:adb79338d40f 169 // calculate bank and shift 1 to required position in the data byte
eencae 0:d563e74f0ae9 170 buffer[x][y/8] |= (1 << y%8);
eencae 0:d563e74f0ae9 171 }
eencae 0:d563e74f0ae9 172
eencae 0:d563e74f0ae9 173 void N5110::clearPixel(int x, int y)
eencae 0:d563e74f0ae9 174 {
eencae 0:d563e74f0ae9 175 // calculate bank and shift 1 to required position (using bit clear)
eencae 0:d563e74f0ae9 176 buffer[x][y/8] &= ~(1 << y%8);
eencae 0:d563e74f0ae9 177 }
eencae 0:d563e74f0ae9 178
eencae 7:3010f24e0a81 179 int N5110::getPixel(int x, int y)
eencae 0:d563e74f0ae9 180 {
eencae 0:d563e74f0ae9 181 // return relevant bank and mask required bit
eencae 7:3010f24e0a81 182 return (int) buffer[x][y/8] & (1 << y%8);
eencae 0:d563e74f0ae9 183
eencae 0:d563e74f0ae9 184 }
eencae 0:d563e74f0ae9 185
eencae 6:adb79338d40f 186 // function to refresh the display
eencae 6:adb79338d40f 187 void N5110::refresh()
eencae 0:d563e74f0ae9 188 {
eencae 0:d563e74f0ae9 189 int i,j;
eencae 7:3010f24e0a81 190
eencae 7:3010f24e0a81 191 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
eencae 7:3010f24e0a81 192 // address auto increments after printing string, so buffer[0][0] will not coincide
eencae 7:3010f24e0a81 193 // with top-left pixel after priting string
eencae 7:3010f24e0a81 194
eencae 0:d563e74f0ae9 195 sce->write(0); //set CE low to begin frame
eencae 0:d563e74f0ae9 196
eencae 0:d563e74f0ae9 197 for(j = 0; j < 6; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:d563e74f0ae9 198 for(i = 0; i < 84; i++) {
eencae 0:d563e74f0ae9 199 spi->write(buffer[i][j]); // send buffer
eencae 0:d563e74f0ae9 200 }
eencae 0:d563e74f0ae9 201 }
eencae 0:d563e74f0ae9 202 sce->write(1); // set CE high to end frame
eencae 0:d563e74f0ae9 203
eencae 0:d563e74f0ae9 204 }
eencae 0:d563e74f0ae9 205
eencae 6:adb79338d40f 206 // fills the buffer with random bytes. Can be used to test the display.
eencae 6:adb79338d40f 207 // The rand() function isn't seeded so it probably creates the same pattern everytime
eencae 0:d563e74f0ae9 208 void N5110::randomiseBuffer()
eencae 0:d563e74f0ae9 209 {
eencae 0:d563e74f0ae9 210 int i,j;
eencae 0:d563e74f0ae9 211 for(j = 0; j < 6; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:d563e74f0ae9 212 for(i = 0; i < 84; i++) {
eencae 0:d563e74f0ae9 213 buffer[i][j] = rand()%256; // generate random byte
eencae 0:d563e74f0ae9 214 }
eencae 0:d563e74f0ae9 215 }
eencae 0:d563e74f0ae9 216
eencae 0:d563e74f0ae9 217 }
eencae 0:d563e74f0ae9 218
eencae 0:d563e74f0ae9 219 // function to print 5x7 font
eencae 0:d563e74f0ae9 220 void N5110::printChar(char c)
eencae 0:d563e74f0ae9 221 {
eencae 6:adb79338d40f 222 int i;
eencae 0:d563e74f0ae9 223 // loop through 5 columns
eencae 6:adb79338d40f 224 for (i = 0; i < 5 ; i++ ) {
eencae 6:adb79338d40f 225 sendData(font5x7[(c - 32)*5 + i]);
eencae 0:d563e74f0ae9 226 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
eencae 6:adb79338d40f 227 // the X address is automatically incremented after each data write
eencae 0:d563e74f0ae9 228 }
eencae 1:df68f34cd32d 229 sendData(0); // send an empty byte to introduce space between characters
eencae 0:d563e74f0ae9 230
eencae 0:d563e74f0ae9 231 }
eencae 0:d563e74f0ae9 232
eencae 0:d563e74f0ae9 233 // function to print string at specified position
eencae 0:d563e74f0ae9 234 void N5110::printString(const char * str,int x,int y)
eencae 0:d563e74f0ae9 235 {
eencae 0:d563e74f0ae9 236 int n = 0 ; // counter for number of characters in string
eencae 0:d563e74f0ae9 237 // loop through string and print character
eencae 0:d563e74f0ae9 238 while(*str) {
eencae 0:d563e74f0ae9 239
eencae 9:7701f0126ba7 240 // This is the old version - strings are printed using the printChar function
eencae 9:7701f0126ba7 241 //setXYAddress(x+6*n,y); // leave 1 pixel (6 = 5 + 1) between each character
eencae 9:7701f0126ba7 242 //printChar(*str); // print the char - can probably do *str++ and remove next line
eencae 9:7701f0126ba7 243
eencae 9:7701f0126ba7 244 // the new version writes the character bitmap data to the buffer, so that
eencae 9:7701f0126ba7 245 // text and pixels can be displayed at the same time
eencae 9:7701f0126ba7 246 for (int i = 0; i < 5 ; i++ ) {
eencae 9:7701f0126ba7 247 buffer[x+i+n*6][y] = font5x7[(*str - 32)*5 + i];
eencae 9:7701f0126ba7 248 }
eencae 9:7701f0126ba7 249
eencae 0:d563e74f0ae9 250 str++; // go to next character in string
eencae 0:d563e74f0ae9 251 n++; // increment index
eencae 0:d563e74f0ae9 252 }
eencae 9:7701f0126ba7 253
eencae 9:7701f0126ba7 254 refresh(); // this sends the buffer to the display and sets address (cursor) back to 0,0
eencae 0:d563e74f0ae9 255
eencae 0:d563e74f0ae9 256 }
eencae 0:d563e74f0ae9 257
eencae 6:adb79338d40f 258 // function to clear the screen
eencae 0:d563e74f0ae9 259 void N5110::clear()
eencae 0:d563e74f0ae9 260 {
eencae 6:adb79338d40f 261 clearBuffer(); // clear the buffer then call the refresh function
eencae 6:adb79338d40f 262 refresh();
eencae 0:d563e74f0ae9 263 }
eencae 0:d563e74f0ae9 264
eencae 6:adb79338d40f 265 // function to clear the buffer
eencae 0:d563e74f0ae9 266 void N5110::clearBuffer()
eencae 0:d563e74f0ae9 267 {
eencae 0:d563e74f0ae9 268 int i,j;
eencae 6:adb79338d40f 269 for (i=0; i<84; i++) { // loop through the banks and set the buffer to 0
eencae 0:d563e74f0ae9 270 for (j=0; j<6; j++) {
eencae 0:d563e74f0ae9 271 buffer[i][j]=0;
eencae 0:d563e74f0ae9 272 }
eencae 0:d563e74f0ae9 273 }
eencae 8:40abe5736eca 274 }
eencae 8:40abe5736eca 275
eencae 8:40abe5736eca 276 // function to plot array on display
eencae 8:40abe5736eca 277 void N5110::plotArray(float array[]) {
eencae 8:40abe5736eca 278
eencae 8:40abe5736eca 279 int i;
eencae 8:40abe5736eca 280
eencae 8:40abe5736eca 281 for (i=0; i<84; i++) { // loop through array
eencae 8:40abe5736eca 282 // elements are normalised from 0.0 to 1.0, so multiply
eencae 8:40abe5736eca 283 // by 47 to convert to pixel range, and subtract from 47
eencae 8:40abe5736eca 284 // since top-left is 0,0 in the display geometry
eencae 9:7701f0126ba7 285 setPixel(i,47 - int(array[i]*47.0));
eencae 8:40abe5736eca 286 }
eencae 8:40abe5736eca 287
eencae 8:40abe5736eca 288 refresh();
eencae 8:40abe5736eca 289
eencae 8:40abe5736eca 290
eencae 0:d563e74f0ae9 291 }