Skip to content

Instantly share code, notes, and snippets.

@RickKimball
Last active December 12, 2015 02:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RickKimball/4703333 to your computer and use it in GitHub Desktop.
Save RickKimball/4703333 to your computer and use it in GitHub Desktop.
xbmto5110 - convert xbm files to c structures usable with nokia 5110 lcd displays and oPossum nokia5110 template
I'm having some fun using oPossum's msp430 nokia 5110 template code
with my recent $3 ebay 5110 lcd module purchase. oPosssum includes
a builtin font and some sample graphics. I wanted to use some custom
graphics and maybe some other fonts. However, looking around I didn't
find any programs for linux that would create the c structures for
nokia 5510 bitmaps. I'm sure there must be a program out there but
I didn't find any. Turns out it is pretty simple to convert from xbm
to nokia bitmaps.
I like to use the graphics editor called 'gimp' it lets you load
just about any graphics format out there. One of the features it
provides is the ability to save as '.xbm' A '.xbm' file is just an
array of unsigned chars that represent the monochrome ( 1 bit depth
) bitmap. Unfortunately, we can't use this format directly with the
nokia 5110 as it is stored row order.
The host code below (xmbto5110.cpp / lp_logo.xbm ) will take an xbm
file and convert it to something you can use with oPossums nokia
5110 template and its bitmap method.
compile and run:
$ make xbmto5110
$ ./xbmto5100 > logo.inc
Then compile the firmware and download it on your launchpad with an
msp430g2553 chip installed.
$ msp430-gcc -mmcu=msp430g2553 -Os -Wall -g -mdisable-watchdog \
-fdata-sections -ffunction-sections -Wl,--gc-sections test_logo.cpp
$ mspdebug rf2500 "prog a.out"
-rick
links:
http://forum.43oh.com/topic/1769-nokia-5110-c-template-class/
http://forum.43oh.com/topic/3318-xbmto5110c-xbm-image-to-nokia-5110-lcd-bitmap-converter/
/*
* lp_logo - nokia 5110 style bitmap
*
* Generated by xbmto5110 on Feb 3 2013 14:19:20
* Note: visualize the '1' and '0's rotated 90 degrees counterclockwise
*/
static const unsigned char lp_logo[] = {
/* width, height/8 */
56,48/8,
/* rows 0-7 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x00, /* col = 8 00000000 */
0x00, /* col = 9 00000000 */
0x00, /* col = 10 00000000 */
0x00, /* col = 11 00000000 */
0x00, /* col = 12 00000000 */
0x00, /* col = 13 00000000 */
0x00, /* col = 14 00000000 */
0x00, /* col = 15 00000000 */
0x00, /* col = 16 00000000 */
0x00, /* col = 17 00000000 */
0x00, /* col = 18 00000000 */
0x00, /* col = 19 00000000 */
0x00, /* col = 20 00000000 */
0x00, /* col = 21 00000000 */
0x00, /* col = 22 00000000 */
0x00, /* col = 23 00000000 */
0x00, /* col = 24 00000000 */
0x00, /* col = 25 00000000 */
0x00, /* col = 26 00000000 */
0x00, /* col = 27 00000000 */
0x00, /* col = 28 00000000 */
0x00, /* col = 29 00000000 */
0x00, /* col = 30 00000000 */
0x00, /* col = 31 00000000 */
0x00, /* col = 32 00000000 */
0x00, /* col = 33 00000000 */
0x00, /* col = 34 00000000 */
0x80, /* col = 35 10000000 */
0xc0, /* col = 36 11000000 */
0xc0, /* col = 37 11000000 */
0xd0, /* col = 38 11010000 */
0x88, /* col = 39 10001000 */
0x84, /* col = 40 10000100 */
0x02, /* col = 41 00000010 */
0x02, /* col = 42 00000010 */
0x00, /* col = 43 00000000 */
0x01, /* col = 44 00000001 */
0x81, /* col = 45 10000001 */
0x1e, /* col = 46 00011110 */
0x00, /* col = 47 00000000 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
/* rows 8-15 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x00, /* col = 8 00000000 */
0x00, /* col = 9 00000000 */
0x00, /* col = 10 00000000 */
0x00, /* col = 11 00000000 */
0x00, /* col = 12 00000000 */
0xc0, /* col = 13 11000000 */
0xe0, /* col = 14 11100000 */
0xe0, /* col = 15 11100000 */
0xf0, /* col = 16 11110000 */
0xf8, /* col = 17 11111000 */
0xf8, /* col = 18 11111000 */
0xfc, /* col = 19 11111100 */
0xfc, /* col = 20 11111100 */
0xfc, /* col = 21 11111100 */
0xfe, /* col = 22 11111110 */
0xfe, /* col = 23 11111110 */
0xfe, /* col = 24 11111110 */
0xfe, /* col = 25 11111110 */
0xfe, /* col = 26 11111110 */
0x7f, /* col = 27 01111111 */
0x7f, /* col = 28 01111111 */
0x3f, /* col = 29 00111111 */
0x7e, /* col = 30 01111110 */
0x1e, /* col = 31 00011110 */
0x0e, /* col = 32 00001110 */
0x06, /* col = 33 00000110 */
0x0b, /* col = 34 00001011 */
0x0f, /* col = 35 00001111 */
0x0f, /* col = 36 00001111 */
0x1f, /* col = 37 00011111 */
0x3f, /* col = 38 00111111 */
0x3f, /* col = 39 00111111 */
0x7f, /* col = 40 01111111 */
0xff, /* col = 41 11111111 */
0xff, /* col = 42 11111111 */
0x8e, /* col = 43 10001110 */
0x02, /* col = 44 00000010 */
0x00, /* col = 45 00000000 */
0x00, /* col = 46 00000000 */
0x00, /* col = 47 00000000 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
/* rows 16-23 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x00, /* col = 8 00000000 */
0xf0, /* col = 9 11110000 */
0xfc, /* col = 10 11111100 */
0xf7, /* col = 11 11110111 */
0x7f, /* col = 12 01111111 */
0xff, /* col = 13 11111111 */
0xeb, /* col = 14 11101011 */
0x7f, /* col = 15 01111111 */
0xff, /* col = 16 11111111 */
0xeb, /* col = 17 11101011 */
0xbf, /* col = 18 10111111 */
0xff, /* col = 19 11111111 */
0xef, /* col = 20 11101111 */
0xff, /* col = 21 11111111 */
0xff, /* col = 22 11111111 */
0xef, /* col = 23 11101111 */
0xf3, /* col = 24 11110011 */
0xf1, /* col = 25 11110001 */
0xf8, /* col = 26 11111000 */
0xf0, /* col = 27 11110000 */
0xfc, /* col = 28 11111100 */
0xe3, /* col = 29 11100011 */
0xe0, /* col = 30 11100000 */
0xc8, /* col = 31 11001000 */
0x80, /* col = 32 10000000 */
0xc2, /* col = 33 11000010 */
0x01, /* col = 34 00000001 */
0x30, /* col = 35 00110000 */
0x00, /* col = 36 00000000 */
0x88, /* col = 37 10001000 */
0xc4, /* col = 38 11000100 */
0xff, /* col = 39 11111111 */
0xff, /* col = 40 11111111 */
0xff, /* col = 41 11111111 */
0xff, /* col = 42 11111111 */
0xff, /* col = 43 11111111 */
0xff, /* col = 44 11111111 */
0xfe, /* col = 45 11111110 */
0xf8, /* col = 46 11111000 */
0xc0, /* col = 47 11000000 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
/* rows 24-31 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x01, /* col = 8 00000001 */
0x7f, /* col = 9 01111111 */
0xff, /* col = 10 11111111 */
0xff, /* col = 11 11111111 */
0xff, /* col = 12 11111111 */
0xff, /* col = 13 11111111 */
0xff, /* col = 14 11111111 */
0xff, /* col = 15 11111111 */
0xff, /* col = 16 11111111 */
0xfd, /* col = 17 11111101 */
0xff, /* col = 18 11111111 */
0xff, /* col = 19 11111111 */
0xfd, /* col = 20 11111101 */
0xff, /* col = 21 11111111 */
0xfb, /* col = 22 11111011 */
0xff, /* col = 23 11111111 */
0xff, /* col = 24 11111111 */
0xfe, /* col = 25 11111110 */
0xff, /* col = 26 11111111 */
0xff, /* col = 27 11111111 */
0x7f, /* col = 28 01111111 */
0xef, /* col = 29 11101111 */
0xff, /* col = 30 11111111 */
0xff, /* col = 31 11111111 */
0xff, /* col = 32 11111111 */
0xff, /* col = 33 11111111 */
0xbf, /* col = 34 10111111 */
0xfc, /* col = 35 11111100 */
0xfe, /* col = 36 11111110 */
0xbf, /* col = 37 10111111 */
0xff, /* col = 38 11111111 */
0xff, /* col = 39 11111111 */
0xff, /* col = 40 11111111 */
0xff, /* col = 41 11111111 */
0xff, /* col = 42 11111111 */
0xff, /* col = 43 11111111 */
0xff, /* col = 44 11111111 */
0xff, /* col = 45 11111111 */
0xff, /* col = 46 11111111 */
0x2b, /* col = 47 00101011 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
/* rows 32-39 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x00, /* col = 8 00000000 */
0x00, /* col = 9 00000000 */
0x03, /* col = 10 00000011 */
0x07, /* col = 11 00000111 */
0xcf, /* col = 12 11001111 */
0x3f, /* col = 13 00111111 */
0x3f, /* col = 14 00111111 */
0x7f, /* col = 15 01111111 */
0xff, /* col = 16 11111111 */
0xff, /* col = 17 11111111 */
0xff, /* col = 18 11111111 */
0xff, /* col = 19 11111111 */
0xff, /* col = 20 11111111 */
0xff, /* col = 21 11111111 */
0xff, /* col = 22 11111111 */
0xff, /* col = 23 11111111 */
0xff, /* col = 24 11111111 */
0xff, /* col = 25 11111111 */
0xff, /* col = 26 11111111 */
0xff, /* col = 27 11111111 */
0xff, /* col = 28 11111111 */
0xff, /* col = 29 11111111 */
0xff, /* col = 30 11111111 */
0xff, /* col = 31 11111111 */
0xfd, /* col = 32 11111101 */
0xff, /* col = 33 11111111 */
0xff, /* col = 34 11111111 */
0xf6, /* col = 35 11110110 */
0xff, /* col = 36 11111111 */
0xff, /* col = 37 11111111 */
0xfa, /* col = 38 11111010 */
0xef, /* col = 39 11101111 */
0x7f, /* col = 40 01111111 */
0x36, /* col = 41 00110110 */
0x3f, /* col = 42 00111111 */
0x0f, /* col = 43 00001111 */
0x0e, /* col = 44 00001110 */
0x03, /* col = 45 00000011 */
0x00, /* col = 46 00000000 */
0x00, /* col = 47 00000000 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
/* rows 40-47 */
0x00, /* col = 0 00000000 */
0x00, /* col = 1 00000000 */
0x00, /* col = 2 00000000 */
0x00, /* col = 3 00000000 */
0x00, /* col = 4 00000000 */
0x00, /* col = 5 00000000 */
0x00, /* col = 6 00000000 */
0x00, /* col = 7 00000000 */
0x00, /* col = 8 00000000 */
0x00, /* col = 9 00000000 */
0xe0, /* col = 10 11100000 */
0x8e, /* col = 11 10001110 */
0x40, /* col = 12 01000000 */
0x40, /* col = 13 01000000 */
0x20, /* col = 14 00100000 */
0x11, /* col = 15 00010001 */
0x08, /* col = 16 00001000 */
0x1c, /* col = 17 00011100 */
0x11, /* col = 18 00010001 */
0x09, /* col = 19 00001001 */
0x05, /* col = 20 00000101 */
0x03, /* col = 21 00000011 */
0x03, /* col = 22 00000011 */
0x03, /* col = 23 00000011 */
0x07, /* col = 24 00000111 */
0x07, /* col = 25 00000111 */
0x07, /* col = 26 00000111 */
0x07, /* col = 27 00000111 */
0x07, /* col = 28 00000111 */
0x07, /* col = 29 00000111 */
0x07, /* col = 30 00000111 */
0x03, /* col = 31 00000011 */
0x07, /* col = 32 00000111 */
0x03, /* col = 33 00000011 */
0x03, /* col = 34 00000011 */
0x03, /* col = 35 00000011 */
0x00, /* col = 36 00000000 */
0x01, /* col = 37 00000001 */
0x00, /* col = 38 00000000 */
0x00, /* col = 39 00000000 */
0x00, /* col = 40 00000000 */
0x00, /* col = 41 00000000 */
0x00, /* col = 42 00000000 */
0x00, /* col = 43 00000000 */
0x00, /* col = 44 00000000 */
0x00, /* col = 45 00000000 */
0x00, /* col = 46 00000000 */
0x00, /* col = 47 00000000 */
0x00, /* col = 48 00000000 */
0x00, /* col = 49 00000000 */
0x00, /* col = 50 00000000 */
0x00, /* col = 51 00000000 */
0x00, /* col = 52 00000000 */
0x00, /* col = 53 00000000 */
0x00, /* col = 54 00000000 */
0x00, /* col = 55 00000000 */
};
#define lp_logo_width 56
#define lp_logo_height 48
static unsigned char lp_logo_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x21, 0x00, 0x00, 0x00, 0x00, 0x38,
0xfc, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,
0xf8, 0xff, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xfd, 0x0f, 0x00,
0x00, 0x00, 0xff, 0xff, 0xe0, 0x07, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0xc0,
0x07, 0x00, 0x00, 0xe0, 0xff, 0x5f, 0x00, 0x07, 0x00, 0x00, 0xe0, 0xff,
0x07, 0x00, 0x0e, 0x00, 0x00, 0xf8, 0xff, 0x23, 0x84, 0x1f, 0x00, 0x00,
0xf8, 0xff, 0x21, 0x82, 0x3f, 0x00, 0x00, 0xbc, 0xfd, 0x10, 0xc0, 0x3f,
0x00, 0x00, 0xf4, 0xff, 0x94, 0xa0, 0x7f, 0x00, 0x00, 0xbe, 0x6d, 0x1f,
0x88, 0x7f, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x88, 0x7f, 0x00, 0x00, 0xfe,
0xfb, 0xff, 0xc2, 0xff, 0x00, 0x00, 0x6e, 0xff, 0xff, 0xe3, 0xff, 0x00,
0x00, 0xff, 0xff, 0xfd, 0xe7, 0xff, 0x00, 0x00, 0xfe, 0xed, 0xff, 0xf7,
0xff, 0x00, 0x00, 0xfe, 0xbf, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xfe, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xdf, 0xff, 0x7f, 0x00, 0x00,
0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xdb, 0x7f,
0x00, 0x00, 0xfc, 0xff, 0xef, 0xff, 0x7f, 0x00, 0x00, 0xfc, 0xff, 0xff,
0xb7, 0x2d, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xfe, 0x3f, 0x00, 0x00, 0xf8,
0xff, 0xff, 0xbf, 0x1f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xf7, 0x1d, 0x00,
0x00, 0xe0, 0xff, 0xff, 0x7f, 0x07, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff,
0x07, 0x00, 0x00, 0x90, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x10, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0xfc, 0xff, 0x2f, 0x00, 0x00, 0x00,
0x08, 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x12, 0x7f, 0x01, 0x00,
0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00 };
namespace nokia5110 {
unsigned char PNONE;
typedef enum {
lcd_command = 0, // Array of one or more commands
lcd_data = 1, // Array of one or more bytes of data
lcd_data_repeat = 2 // One byte of data repeated
} lcd_cmd_type;
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA,
volatile unsigned char &_CP, unsigned char _DC,
volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
struct Nokia5110
{
void write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type = lcd_data);
void reset(void);
void init(void);
void vert(void);
void home(void);
void pos(unsigned char x, unsigned char y);
void clear(unsigned char x = 0);
void bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h);
inline void bitmap(const unsigned char *bmp, signed char x, signed char y) { bitmap(bmp + 2, x, y, bmp[0], bmp[1]); };
void print(char c);
inline void print(unsigned char x, unsigned char y, char c) { pos(x, y); print(c); };
void print(char *s);
inline void print(unsigned char x, unsigned char y, char *s) { pos(x, y); print(s); };
void printv(unsigned char x, unsigned char y, char *s);
};
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA,
volatile unsigned char &_CP, unsigned char _DC,
volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type)
{
register unsigned mask;
if(&_EP != &PNONE) _EP &= ~_CE;
do {
mask = 0x0080;
do {
if(*cmd & mask) {
_SP |= _DATA;
_SP &= ~_CLK;
} else {
_SP &= ~(_CLK | _DATA);
}
_SP |= _CLK;
mask >>= 1;
} while(!(mask & 1));
if(&_CP == &PNONE) {
__delay_cycles(_DC);
} else {
if(!type) _CP &= ~_DC;
}
if(*cmd & mask) {
_SP |= _DATA;
_SP &= ~_CLK;
} else {
_SP &= ~(_CLK | _DATA);
}
_SP |= _CLK;
if(&_CP != &PNONE) _CP |= _DC;
if(!(type & lcd_data_repeat)) ++cmd;
} while(--len);
if(&_EP != &PNONE) _EP |= _CE;
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::reset(void)
{
// --- Set initial state of CLK, DC and CE as needed
// * = output used for reset
if(&_CP == &PNONE) {
if(&_EP != &PNONE) { // CLK*, DATA, CE
_EP |= _CE;
} // else // CLK*, DATA
} else {
if(&_EP != &PNONE) { // CLK, DATA, DC*, CE
if(&_SP == &_EP) {
_SP |= (_CLK | _CE);
} else {
_SP |= _CLK;
_EP |= _CE;
}
} // else // CLK, DATA, DC*
}
// --- Reset pulse on CLK or DC as needed
if(&_CP == &PNONE) { // No DC port, use CLK to reset
_SP &= ~_CLK;
__delay_cycles(_RST);
_SP |= _CLK;
} else { // Use DC to reset
_CP &= ~_DC;
__delay_cycles(_RST);
_CP |= _DC;
}
__delay_cycles(_RST);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::init(void)
{
static const unsigned char init[] = {
0x20 | 0x01, // Function set - extended instructions enabled
//0x80 | 64, // Set vop (contrast) 0 - 127
0x80 | 70, // Higher contrast improves animation
0x04 | 2, // Temperature control
0x10 | 3, // Set bias system
0x20 | 0x00, // Function set - chip active, horizontal addressing, basic instructions
0x08 | 0x04 // Display control - normal mode
};
write(init, sizeof(init), lcd_command);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::vert(void)
{
static const unsigned char v[] = {
0x20 | 0x02, // Function set - chip active, vertical addressing, basic instructions
};
write(v, sizeof(v), lcd_command);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::home(void)
{
static const unsigned char home[] = { 0x40, 0x80 };
write(home, sizeof(home), lcd_command);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::pos(unsigned char x, unsigned char y)
{
unsigned char c[2];
c[0] = 0x80 | x;
c[1] = 0x40 | y;
write(c, sizeof(c), lcd_command);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::clear(unsigned char x)
{
home();
write(&x, 504 /*84*(48/8)*/, lcd_data_repeat);
home();
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h)
{
unsigned char c[2];
unsigned char ww;
if(x < 0) {
ww = w + x;
bmp -= x;
x = 0;
} else if(x + w >= 84) {
ww = (84 - x);
} else {
ww = w;
}
c[0] = 0x80 | x;
c[1] = 0x40 | y;
while(h--) {
write(c, sizeof(c), lcd_command);
++c[1];
write(bmp, ww);
bmp += w;
}
}
static const unsigned char font[96][5] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, //
{ 0x00, 0x00, 0x5F, 0x00, 0x00 }, // !
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
{ 0x14, 0x7F, 0x14, 0x7F, 0x14 }, // #
{ 0x24, 0x2A, 0x7F, 0x2A, 0x12 }, // $
{ 0x23, 0x13, 0x08, 0x64, 0x62 }, // %
{ 0x36, 0x49, 0x56, 0x20, 0x50 }, // &
{ 0x00, 0x08, 0x07, 0x03, 0x00 }, // '
{ 0x00, 0x1C, 0x22, 0x41, 0x00 }, // (
{ 0x00, 0x41, 0x22, 0x1C, 0x00 }, // )
{ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A }, // *
{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
{ 0x00, 0x40, 0x38, 0x18, 0x00 }, // ,
{ 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
{ 0x00, 0x00, 0x60, 0x60, 0x00 }, // .
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
{ 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x21, 0x41, 0x49, 0x4D, 0x33 }, // 3
{ 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x41, 0x21, 0x11, 0x09, 0x07 }, // 7
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x00, 0x14, 0x00, 0x00 }, // :
{ 0x00, 0x00, 0x40, 0x34, 0x00 }, // ;
{ 0x00, 0x08, 0x14, 0x22, 0x41 }, // <
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
{ 0x3E, 0x41, 0x5D, 0x59, 0x4E }, // @
{ 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A
{ 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
{ 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
{ 0x7F, 0x41, 0x41, 0x41, 0x3E }, // D
{ 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
{ 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
{ 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H
{ 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
{ 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
{ 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
{ 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
{ 0x7F, 0x02, 0x1C, 0x02, 0x7F }, // M
{ 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
{ 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
{ 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
{ 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
{ 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R
{ 0x26, 0x49, 0x49, 0x49, 0x32 }, // S
{ 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
{ 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
{ 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
{ 0x03, 0x04, 0x78, 0x04, 0x03 }, // Y
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
{ 0x00, 0x7F, 0x41, 0x41, 0x41 }, // [
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, // '\'
{ 0x00, 0x41, 0x41, 0x41, 0x7F }, // ]
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
{ 0x80, 0x80, 0x80, 0x80, 0x80 }, // _
{ 0x00, 0x03, 0x07, 0x08, 0x00 }, // '
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
{ 0x7F, 0x28, 0x44, 0x44, 0x38 }, // b
{ 0x38, 0x44, 0x44, 0x44, 0x28 }, // c
{ 0x38, 0x44, 0x44, 0x28, 0x7F }, // d
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
{ 0x00, 0x08, 0x7E, 0x09, 0x02 }, // f
{ 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g
{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
{ 0x00, 0x20, 0x40, 0x40, 0x3D }, // j
{ 0x00, 0x7F, 0x10, 0x28, 0x44 }, // k
{ 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
{ 0x7C, 0x04, 0x78, 0x04, 0x78 }, // m
{ 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
{ 0xFC, 0x18, 0x24, 0x24, 0x18 }, // p
{ 0x18, 0x24, 0x24, 0x18, 0xFC }, // q
{ 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
{ 0x48, 0x54, 0x54, 0x54, 0x24 }, // s
{ 0x04, 0x04, 0x3F, 0x44, 0x24 }, // t
{ 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
{ 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
{ 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
{ 0x4C, 0x90, 0x90, 0x90, 0x7C }, // y
{ 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z
{ 0x00, 0x08, 0x36, 0x41, 0x00 }, // {
{ 0x00, 0x00, 0x77, 0x00, 0x00 }, // |
{ 0x00, 0x41, 0x36, 0x08, 0x00 }, // }
{ 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
{ 0x00, 0x06, 0x09, 0x09, 0x06 } // degrees
};
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::print(char c)
{
write(&font[c - 32][0], 5);
write(&font[0][0], 1);
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::print(char *s)
{
while(*s) {
write(&font[*s - 32][0], 5);
write(&font[0][0], 1);
++s;
}
}
template <volatile unsigned char &_SP, unsigned char _CLK, unsigned char _DATA, volatile unsigned char &_CP, unsigned char _DC, volatile unsigned char &_EP, unsigned char _CE, unsigned _RST>
void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::printv(unsigned char x, unsigned char y, char *s)
{
while(*s) {
pos(x, y);
++y;
write(&font[*s - 32][0], 5);
write(&font[0][0], 1);
++s;
}
}
} // namespace
/*
* test_logo.cpp - msp430 firmware to demo xbmto5110
*
* Author: kimballr
* Date: Jan 30, 2013
* Version: 0.0001
*/
#include <msp430.h>
#include <stdint.h>
#include "nokia_5110.h"
#include "logo.inc"
//using namespace nokia5110;
static const unsigned RXD = BIT2;
static const unsigned SWITCH = BIT3;
static const unsigned LCD_DC = BIT0;
static const unsigned LCD_CE = BIT4;
static const unsigned LCD_CLK = BIT5;
static const unsigned LCD_BACKLIGHT = BIT6; // active low
static const unsigned LCD_DATA = BIT7;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
DCOCTL = CALDCO_16MHZ;
BCSCTL1 = CALBC1_16MHZ;
P1REN = RXD | SWITCH;
P1DIR = LCD_DC | LCD_CE | LCD_CLK | LCD_BACKLIGHT | LCD_DATA;
P1OUT = LCD_CLK | LCD_DC | RXD | SWITCH | LCD_CE | LCD_BACKLIGHT;
nokia5110::Nokia5110<P1OUT, LCD_CLK, LCD_DATA, P1OUT, LCD_DC, P1OUT, LCD_CE, 10000> lcd;
lcd.reset();
lcd.init();
lcd.clear();
P1OUT &= ~LCD_BACKLIGHT; // turn on backlight
lcd.bitmap(lp_logo,(84-56)/2,0);
while(1) {
}
return 0;
}
//============================================================================
// Name: xbmto5110.cpp - host side code to convert .xbm to c
// Author: rick@kimballsoftware.com
// Version: 1.0
// Date: 2-1-2013
// Copyright: copyright (c) 2013 rick@kimballsoftware.com
// License: public domain
// Description: .xbm to nokia 5110 c unsigned array .c
//============================================================================
#include <iostream>
#include <iomanip>
#include <stdint.h>
using namespace std;
/*
* Use gimp to create graphics, save as .xbm using default options
* then include the bitmap(s) you want to convert
*/
#include "lp_logo.xbm"
/*
* getpixel() - return the pixel value at row/col from the bitmap
*
* assumes monochrome uint8_t xbm bitmap
*
*/
unsigned getpixel(unsigned row, unsigned col, unsigned char *bm_bits, unsigned bm_width) {
unsigned byte_offset = (row * ((bm_width + 7) / 8)) + (col / 8);
unsigned bitmask_offset = 1 << (col % 8);
return (bm_bits[byte_offset] & bitmask_offset) ? 1 : 0;
}
/*
* xmb_to_5110 - output new structure in nokia 5110 bitmap format
*
* name - name that will be used for the new bits in col/row order in the output file
* bm - bm_bits from xbm file
*/
void xbm_to_5110(const char *name, unsigned char *bm, unsigned bm_width, unsigned bm_height) {
unsigned row, col;
/*
* flip bitmap bytes from xbm style where each byte is a row by 8 columns of bits to
* 5510 style where each byte is a column by 8 rows of bits
*
* see: nokia 5110 datasheet for details
*/
cout << "/*" << endl;
cout << " * " << name << " - nokia 5110 style bitmap" << endl;
cout << " *" << endl;
cout << " * Generated by xbmto5110 on " << __DATE__ << " " << __TIME__ << endl;
cout << " * Note: visualize the '1' and '0's rotated 90 degrees counterclockwise" << endl;
cout << " */" << endl;
cout << "static const unsigned char " << name << "[] = {" << endl << " /* width, height/8 */"
<< endl << " " << bm_width << "," << bm_height << "/8," << endl << endl;
for (row = 0; row < bm_height; row += 8) {
cout << " /* rows " << row << "-" << (row + 7) << " */" << endl;
for (col = 0; col < bm_width; col++) {
unsigned ucol_8rows = 0; // one column by 8 rows of bits
unsigned indx;
// repack bits into new col order
for (indx = 0; indx < 8; indx++) {
unsigned bit = getpixel(row + indx, col, bm, bm_width);
ucol_8rows |= (bit << indx);
}
cout << " 0x" << setfill('0') << setw(2) << hex << ucol_8rows << ",";
cout << setfill(' ');
cout << " /* col = " << setw(2) << dec << col << " ";
cout << (getpixel(row + 7, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 6, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 5, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 4, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 3, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 2, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 1, col, bm, bm_width) ? '1' : '0');
cout << (getpixel(row + 0, col, bm, bm_width) ? '1' : '0');
cout << " */\n";
}
cout << endl;
}
cout << "};" << endl << endl;
}
int main() {
xbm_to_5110("lp_logo", lp_logo_bits, lp_logo_width, lp_logo_height);
return 0;
}
@oldtopman
Copy link

I'm currently using this with great success on a Nokia 3310 display.
Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment