spirilis 1,265 Posted June 2, 2013 Share Posted June 2, 2013 I put this together to get the ball rolling for proper support for the Nokia 1202 LCD display detailed in the discussion & links here -- http://forum.43oh.com/topic/3724-43oh-nokia-1202-lcd-display-boosterpack/ This breaks out the Nokia 1202 driver primitives into a library of C functions which call upon a 9-bit SPI function & chipselect driving expression/function that the user must supply (as a #define to whatever you use) near the top of the driver file (ste2007.c). For now I've taken the USCI SPI driver from my MSPRF24 library and doctored it up to support 9-bit SPI, doing a manual bit-bang on the USCI_B port for the 9th bit and then letting the USCI hardware clock out the other 8 bits. But first, pic: Main code for that (using msp430g2553): #include <msp430.h> #include <stdint.h> #include "usci_spi.h" #include "ste2007.h" #include "font_5x7.h" int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; // SMCLK = DCO/2 (8MHz) //__delay_cycles(8000); // Short delay to let the LCD wake up -- turns out this isn't necessary // Chip select P2DIR |= BIT0; P2OUT |= BIT0; // Drive it high to disable LCD // Backlight P2DIR |= BIT5; P2OUT |= BIT5; // Turn on backlight spi_init(); ste2007_init(); ste2007_invert(0); // Normal display, not inverted. ste2007_putchar(0, 0, font_5x7['!'-32]); ste2007_putchar(-1, 0, font_5x7['A'-32]); ste2007_putchar(-1, 0, font_5x7['C'-32]); ste2007_putchar(-1, 0, font_5x7['D'-32]); ste2007_putchar(-1, 0, font_5x7['~'-32]); ste2007_putchar(0, 1, font_5x7['M'-32]); ste2007_putchar(-1, 1, font_5x7['y'-32]); ste2007_putchar(-1, 1, font_5x7[' '-32]); ste2007_putchar(-1, 1, font_5x7['n'-32]); ste2007_putchar(-1, 1, font_5x7['a'-32]); ste2007_putchar(-1, 1, font_5x7['m'-32]); ste2007_putchar(-1, 1, font_5x7['e'-32]); ste2007_putchar(-1, 1, font_5x7[' '-32]); ste2007_putchar(-1, 1, font_5x7['i'-32]); ste2007_putchar(-1, 1, font_5x7['s'-32]); ste2007_putchar(0, 2, font_5x7['E'-32]); ste2007_putchar(-1, 2, font_5x7['r'-32]); ste2007_putchar(-1, 2, font_5x7['i'-32]); ste2007_putchar(-1, 2, font_5x7['c'-32]); ste2007_putchar(-1, 2, font_5x7['.'-32]); ste2007_contrast(10); // A little lighter than the default LPM4; return 0; } void test_chipselect(uint8_t onoff) { P2OUT = (P2OUT & ~BIT0) | (onoff & 0x01); } Function prototypes for the ste2007 driver functions: /* Library functions */ void ste2007_issuecmd(uint8_t, uint8_t, uint8_t); void ste2007_issue_compoundcmd(uint8_t, uint8_t, uint8_t); void ste2007_init(); void ste2007_clear(); void ste2007_setxy(uint8_t, uint8_t); // X is pixel column from 0 to 95, Y is page address from 0 to 8 void ste2007_write(const void *, uint16_t); // Write to current DDRAM cursor void ste2007_invert(uint8_t); // Invert display (0 = normal, 1 = invert) void ste2007_powersave(uint8_t); // Powersave (0 = active mode, 1 = powersave ~1-3uA mode) void ste2007_contrast(uint8_t); // Electronic Volume setting, 0-31 (16 is default) void ste2007_refreshrate(uint8_t); // Refresh rate of LCD controller, supported values 65/70/75/80, 65Hz is default. void ste2007_putchar(int16_t, int16_t, const void *); /* Write 5 bytes + a zero byte to the specified text * cursor address X coordinate is 0-15 and is multiplied * by 6 to derive graphical column address. * **Specifying a number < 0 (e.g. -1) for either address * skips the ste2007_setxy() call and writes the * character to the current DDRAM cursor address. */ Current codebase: msp1202_v0.1.zip larsie and bluehash 2 Quote Link to post Share on other sites
spirilis 1,265 Posted June 2, 2013 Author Share Posted June 2, 2013 I had peeled off the white backing when I first soldered mine on, in retrospect that was a mistake... the backlight probably looks nicer with that white cover on the back to help disperse the light. Anyway, this is just the basic primitives so a framebuffer driver of sorts can be developed to sit on top. And those new Value Line chips (G2955 et al) could probably support a graphical framebuffer for a true graphical experience... FYI- The LCD has 8 full lines of 8 bits, then a 9th line with only 4 bits available. I believe in the default setup the Least-Significant-Bit of each byte written to the DDRAM sets the topmost pixel of that column, and the MSB sets the bottommost pixel. Quote Link to post Share on other sites
spirilis 1,265 Posted June 2, 2013 Author Share Posted June 2, 2013 FYI- Reversing the display completely involves: ste2007_issuecmd(STE2007_CMD_SEGMENTDIR, 1, STE2007_MASK_SEGMENTDIR); ste2007_issuecmd(STE2007_CMD_COMDIR, 8, STE2007_MASK_COMDIR); (the COMDIR command only pays attention to bit #3 while SEGMENTDIR is configured by bit#0) Good to know that if you do solder the display upside down for any reason (even intentionally for practical fitment purposes; not thinking boosterpacks here, but rather folks incorporating it into their own design), it can be flipped (rotated 180 degrees) in software. Otherwise, the default (SEGMENTDIR=0, COMDIR=0) setting looks right-side up when the solder connector is on the top. Quote Link to post Share on other sites
spirilis 1,265 Posted June 2, 2013 Author Share Posted June 2, 2013 Took the text terminal framebuffer code from my rxokaya lib -- https://github.com/spirilis/rxokaya -- and adapted it for the MSP430 with this Nokia 1202 display. It stores a 128-byte framebuffer, 16 * 8, and supports software-based terminal scrolling. Example: #include <msp430.h> #include <stdint.h> #include "chargen.h" #include "usci_spi.h" int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; // SMCLK = DCO/2 (8MHz) //__delay_cycles(8000); // Short delay to let the LCD wake up -- turns out this isn't necessary // Chip select P2DIR |= BIT0; P2OUT |= BIT0; // Drive it high to disable LCD // Backlight P2DIR |= BIT5; P2OUT |= BIT5; // Turn on backlight spi_init(); msp1202_init(); msp1202_puts("Hi there my\n"); msp1202_puts("name is Eric.\n"); while(1) { __delay_cycles(16000000); msp1202_puts("txt 1"); __delay_cycles(16000000); msp1202_puts("txt 2"); } LPM4; return 0; } void test_chipselect(uint8_t onoff) { P2OUT = (P2OUT & ~BIT0) | (onoff & 0x01); } Result: Need to add a simple function to set the cursor position (never did that for rxokaya either), it'll shift the msp1202_x and _y variables and erase/move the cursor as well. Updated codebase: msp1202_v0.3.zip This stuff is in the "terminal" subdirectory, chargen.c / chargen.h adds this code. It wraps ste2007_init() so you just have to run msp1202_init(). edit: Added a msp1202_move(x, y) function, tested it & it works. Deleted the v0.2 version I'd uploaded and replaced it with v0.3 which has this function now. larsie and bluehash 2 Quote Link to post Share on other sites
bluehash 1,581 Posted June 2, 2013 Share Posted June 2, 2013 This is awesome. Thanks spirilis. Quote Link to post Share on other sites
spirilis 1,265 Posted June 2, 2013 Author Share Posted June 2, 2013 Another release--added a "terminal_lite" subdir to the main project now with chargen_nofb.c, chargen_nofb.h -- a variant with no framebuffer and substantially less RAM usage (it should use about 2 bytes worth of global for the current X,Y position).Since there is no framebuffer and the Nokia 1202 has no MISO line pinned out for us to read the DDRAM (even though the STE2007 IC inside technically does have the pin I think), there is no graceful scrolling; hitting the end of the display causes the cursor to return to position 0,0 and start overwriting what's already there.The msp1202_move(x,y) function does exist.Cursor support is there. FYI commenting out "#define MSP1202_USE_CURSOR 1" from chargen_fb.h is how you disable the cursor. (likewise in the terminal/ version of the lib, comment that out in chargen.h) It must be commented out, not just set to 0 or something else.Another implication of no framebuffer is every change forces an immediate CS=0, 9-bit SPI I/O, CS=1 operation so in theory its operation may be less efficient--as in, more chatty on the SPI bus. I doubt anyone will care.So with this version of the lib + commenting out MSP1202_USE_CURSOR you have a pretty basic low-RAM-footprint path to using these LCDs and laying things out any way you like (so long as the whole LCD is used as a 16x8 text block; if you want to add graphics you can go behind the library's back and perform direct ste2007_* calls e.g. to draw a window around a certain area, just know that the library may overwrite your graphics if its cursor makes it there)v0.4: msp1202_v0.4.zip bluehash 1 Quote Link to post Share on other sites
spirilis 1,265 Posted June 3, 2013 Author Share Posted June 3, 2013 Got the code up here now: https://github.com/spirilis/msp1202 larsie 1 Quote Link to post Share on other sites
xxx1 35 Posted June 3, 2013 Share Posted June 3, 2013 Good work @@spirilis. spirilis 1 Quote Link to post Share on other sites
spirilis 1,265 Posted June 3, 2013 Author Share Posted June 3, 2013 Git version now has printf() support from @@oPossum 's tiny printf code. Named it lcd_printf() since mspgcc throws a fit due to the fact that printf() already exists in its libc I think. Likewise chargen.c, chargen_nofb.c declare an lcd_putc() and lcd_puts() which it uses. Include "lcd_printf.h" to utilize this, and a "test_printf.c" exists to demo it. bluehash 1 Quote Link to post Share on other sites
spirilis 1,265 Posted July 30, 2013 Author Share Posted July 30, 2013 Haven't been doing much msp430 stuff the past 2 weeks courtesy of issues at my house, but just now I got G2955 (G2xx4/G2xx5) support in the usci_spi.c portion of my "msp1202" library and a test g2955 app in the terminal/ subdir. Using RobG's G2955 launchpad board. Main change is the USCI_B ports include P3.1,3.2,3.3 and P3SEL2 needs to be *cleared* to enable the USCI function, not set like the G2xx3's. Pin layout is different on the outer pins too so I had to modify the pin used for chipselect & backlight. Test code: #include <msp430.h> #include <stdint.h> #include "chargen.h" #include "usci_spi.h" int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_1; // SMCLK = DCO/2 (8MHz) //__delay_cycles(8000); // Short delay to let the LCD wake up -- turns out this isn't necessary // Chip select P4SEL &= ~BIT2; P4SEL2 &= ~BIT2; P4DIR |= BIT2; P4OUT |= BIT2; // Drive it high to disable LCD // Backlight P2DIR |= BIT4; P2OUT &= ~BIT4; // Turn on backlight spi_init(); msp1202_init(); ste2007_contrast(8); msp1202_puts("Hi there my\n"); msp1202_puts("name is Eric.\n"); msp1202_move(8, 0); while(1) { __delay_cycles(16000000); msp1202_puts("txt 1"); __delay_cycles(16000000); msp1202_puts("txt 2"); } LPM4; return 0; } void test_chipselect(uint8_t onoff) { P4OUT = (P4OUT & ~BIT2) | ((onoff & 0x01) << 2); } Pics: bluehash, larsie and RobG 3 Quote Link to post Share on other sites
larsie 121 Posted October 15, 2013 Share Posted October 15, 2013 Really nice work on the drivers. I seem to have gotten a display that won't reverse. In my design I have to reverse the direction, and the first batch of LCDs I bought worked fine with ste2007_issuecmd(STE2007_CMD_SEGMENTDIR, 1, STE2007_MASK_SEGMENTDIR);ste2007_issuecmd(STE2007_CMD_COMDIR, 8, STE2007_MASK_COMDIR); But then the second set of LCDs won't write left-to-right when upside down. It always writes left-to-right correct-way-up. Anybody know a work-around? Could it be I have a slightly different driver??? Quote Link to post Share on other sites
spirilis 1,265 Posted October 15, 2013 Author Share Posted October 15, 2013 That's strange! Haven't seen that but then I've only used like 3 of my LCDs so far. Quote Link to post Share on other sites
RobG 1,892 Posted October 15, 2013 Share Posted October 15, 2013 I came across 3 different models and I did notice different behavior during init. Quote Link to post Share on other sites
matseng 0 Posted November 8, 2013 Share Posted November 8, 2013 I've got the same problem with the 50 lcds I bought. One of my boards have the LCD mounted rotated 180 degrees and this problem is really annoying. For the next batch of the pcb I'll have to make sure the display is oriented normally if the settings can't be trusted. :-( (disclaimer - I'm not a 430 user, mostly pic & avr stuff in my designs) I seem to have gotten a display that won't reverse. In my design I have to reverse the direction, and the first batch of LCDs I bought worked fine with ste2007_issuecmd(STE2007_CMD_SEGMENTDIR, 1, STE2007_MASK_SEGMENTDIR);ste2007_issuecmd(STE2007_CMD_COMDIR, 8, STE2007_MASK_COMDIR); But then the second set of LCDs won't write left-to-right when upside down. It always writes left-to-right correct-way-up. Anybody know a work-around? Could it be I have a slightly different driver??? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.