LCD driver is now functional. Close #1.

This commit is contained in:
Travis Goodspeed 2017-09-24 16:06:59 -04:00
parent 89a7dcee9d
commit df6c132e83
6 changed files with 206 additions and 55 deletions

View File

@ -52,10 +52,10 @@ class BSL:
def reset(self):
"""Exits the BSL by resetting the chip."""
self.setTST(True)
self.setRST(True);
time.sleep(0.25);
self.setRST(False);
self.setRST(True);
self.setRST(False);
self.setRST(True);
def crc(self,msg):
"""Returns a two-byte string of the checksum of a message."""

View File

@ -5,7 +5,7 @@ CC = msp430-gcc -mmcu=cc430f6137
BSL = ../bin/cc430-bsl.py
modules=main.o lcd.o
modules=main.o lcd.o lcdtext.o
all: goodwatch.hex

View File

@ -4,45 +4,28 @@
#include <msp430.h>
// LCD Segments
#define LCD_A BIT4
#define LCD_B BIT5
#define LCD_C BIT6
#define LCD_D BIT7
#define LCD_F BIT0
#define LCD_G BIT1
#define LCD_E BIT2
#define LCD_H BIT3
char *lcdm=&LCDM1;
char *lcdbm=&LCDBM1;
//! Clears the LCD memory and blink memory.
int lcd_zero(){
int i=0;
for(i=0; i<=13; i++){
lcdm[i]=0;
lcdbm[i]=0;
}
}
// LCD Segment Mapping for the SBLCDA4; the Casio display will be different.
const unsigned char LCD_Char_Map[] = {
LCD_A+LCD_B+LCD_C+LCD_D+LCD_E+LCD_F, // '0' or 'O'
LCD_B+LCD_C, // '1' or 'I'
LCD_A+LCD_B+LCD_D+LCD_E+LCD_G, // '2' or 'Z'
LCD_A+LCD_B+LCD_C+LCD_D+LCD_G, // '3'
LCD_B+LCD_C+LCD_F+LCD_G, // '4' or 'y'
LCD_A+LCD_C+LCD_D+LCD_F+LCD_G, // '5' or 'S'
LCD_A+LCD_C+LCD_D+LCD_E+LCD_F+LCD_G, // '6' or 'b'
LCD_A+LCD_B+LCD_C, // '7'
LCD_A+LCD_B+LCD_C+LCD_D+LCD_E+LCD_F+LCD_G, // '8' or 'B'
LCD_A+LCD_B+LCD_C+LCD_D+LCD_F+LCD_G, // '9' or 'g'
LCD_A+LCD_B+LCD_C+LCD_E+LCD_F+LCD_G, // 'A' 10
LCD_A+LCD_D+LCD_E+LCD_F, // 'C' 11
LCD_B+LCD_C+LCD_D+LCD_E+LCD_G, // 'd' 12
LCD_A+LCD_D+LCD_E+LCD_F+LCD_G, // 'E' 13
LCD_A+LCD_E+LCD_F+LCD_G, // 'F' 14
LCD_B+LCD_C+LCD_E+LCD_F+LCD_G, // 'H' 15
LCD_B+LCD_C+LCD_D+LCD_E, // 'J' 16
LCD_D+LCD_E+LCD_F, // 'L' 17
LCD_A+LCD_B+LCD_E+LCD_F+LCD_G, // 'P' 18
LCD_B+LCD_C+LCD_D+LCD_E+LCD_F // 'U' 19
};
//! Initialize the LCD memory and populate it with sample text.
int lcd_init() {
int i;
// Select LCD COM pins
P5SEL |= (BIT5 | BIT6 | BIT7);
P5DIR |= (BIT5 | BIT6 | BIT7);
P5SEL |= (/*BIT5 |*/ BIT6 | BIT7);
P5DIR |= (/*BIT5 |*/ BIT6 | BIT7);
// Configure LCD_B
// LCD_FREQ = ACLK/32/4, LCD Mux 4, turn on LCD
@ -54,25 +37,34 @@ int lcd_init() {
REFCTL0 &= ~REFMSTR;
//Select LCD Segments 0-9
LCDBPCTL0 = 0x03FF;
LCDBPCTL1 = 0x0000;
LCDBPCTL0 = 0xFFFF;
LCDBPCTL1 = 0xFFFF;
//LCD Memory
LCDM5 = LCD_Char_Map[15]; //H
LCDM4 = LCD_Char_Map[13]; //E
LCDM3 = LCD_Char_Map[17]; //L
LCDM2 = LCD_Char_Map[17]; //L
LCDM1 = LCD_Char_Map[0]; //0
lcd_zero();
for(i=0;i<13;i++)
lcdbm[i]=0xFF;
//Seems unwired?
lcdm[2]^=0x40;
//Weird top-right thingys.
//lcdm[9]|=0x04;
//lcdm[0x0a]|=0x40;
//lcdm[0x0c]|=0x01;
//Beyond the range.
//lcdm[0x0c]|=0x10;
// Blink Memory
LCDBM5 = LCD_Char_Map[11]; //C
LCDBM4 = LCD_Char_Map[11]; //C
LCDBM3 = LCD_Char_Map[4]; //4
LCDBM2 = LCD_Char_Map[3]; //3
LCDBM1 = LCD_Char_Map[0]; //0
}
//! LCD callback when the CPU wakes.
void lcd_wdt(){
LCDBMEMCTL ^= LCDDISP;
static int i=0, j=0;
//LCDBMEMCTL ^= LCDDISP; // Enable blink memory
lcd_zero();
//lcd_hex(0xdeadbeef);
lcd_hex(0xcafebabe);
}

View File

@ -1,5 +1,11 @@
/* Handy LCD functions for use in other modules.*/
/* IO ports. */
extern char *lcdm;
extern char *lcdbm;
/* Handy LCD functions for use in other modules.*/
extern int lcd_init();
extern int lcd_wdt();
extern int lcd_zero();

153
firmware/lcdtext.c Normal file
View File

@ -0,0 +1,153 @@
#include "lcd.h"
/* Digits look like this, and we index them with 0 being the
leftmost.
AAAAA
F B
F B
F B
GGGGG
E C
E C
E C
DDDDD dp
*/
//This maps the segments of each digit.
// A, B, C, D, E, F, G, dp digit
int map[10][8]={
{0x0b04, 0x0b40, 0x0b20, 0x0b01, 0x0a10, 0x0a20, 0x0b02, 0x0b10}, //7
{0x0940, 0x0a04, 0x0a02, 0x0910, 0x0901, 0x0902, 0x0920, 0x0a01}, //6
{0x0804, 0x0840, 0x0820, 0x0801, 0x0710, 0x0720, 0x0802, 0x0810}, //5
{0x0640, 0x0704, 0x0702, 0x0610, 0x0601, 0x0602, 0x0620, 0x0701}, //4
{0x0504, 0x0540, 0x0520, 0x0501, 0x0410, 0x0420, 0x0502, 0x0510}, //3
{0x0c02, 0x0404, 0x0402, 0x0310, 0x0302, 0x0304, 0x0340, 0x0401}, //2
{0x0204, 0x0220, 0x0210, 0x0201, 0x0110, 0x0120, 0x0202, 0x0301}, //1
{0x0040, 0x0104, 0x0102, 0x0010, 0x0001, 0x0002, 0x0020, 0x0201}, //0
};
enum mappos {A=1, B=2, C=4, D=8, E=0x10, F=0x20, G=0x40, DP=0x80};
int numfont[]={
A|B|C|D|E|F, //0
B|C, //1
A|B|G|E|D, //2
A|B|G|C|D, //3
F|G|B|C, //4
A|F|G|C|D, //5
A|F|G|E|C|D, //6
A|B|C, //7
A|B|C|D|E|F|G, //8
A|B|G|F|C|D, //9
A|F|B|G|E|C, //A
F|E|G|C|D, //B
A|F|E|D, //C
E|G|C|D|B, //D
A|F|E|G|D, //E
A|G|F|E //F
};
#define DRAWPOINT(todraw) lcdm[todraw>>8]|=todraw&0xFF
#define DRAWPOINTB(todraw) lcdbm[todraw>>8]|=todraw&0xFF
void lcd_digit(int pos, int digit){
int segments=numfont[digit];
int bit, todraw;
for(bit=0;bit<8;bit++){
if(segments&(1<<bit)){
DRAWPOINT(map[pos][bit]);
//DRAWPOINTB(map[pos][bit]);
}
}
}
//! Draws hex on the screen.
void lcd_hex(long num){
/* So in an ideal world, we'd have characters arranged nicely into
LCDM[] bytes as some development tools do, but in the real world,
we're pretty much stuck with them as they are physically
arranged.
This function takes a buffer of eight hex characters and displays
them on the screen.
*/
int i;
for(i=0;i<8;i++)
lcd_digit(i,(num>>(4*i))&0xf);
}
//! Activates the colon. 2 for invert.
int setcolon(int on){
if(on==2) //Blink
lcdm[3]^=0x20;
else if(on==1) //On
lcdm[3]|=0x20;
else //Off
lcdm[3]&=~0x20;
}
//! Activates the am. 2 for invert.
int setam(int on){
if(on==2) //Blink
lcdm[0]^=0x04;
else if(on==1) //On
lcdm[0]|=0x04;
else //Off
lcdm[0]&=~0x04;
}
//! Activates the pm. 2 for invert.
int setpm(int on){
if(on==2) //Blink
lcdm[1]^=0x40;
else if(on==1) //On
lcdm[1]|=0x40;
else //Off
lcdm[1]&=~0x40;
}
//! Activates the mult sign. 2 for invert.
int setmult(int on){
if(on==2) //Blink
lcdm[4]^=0x40;
else if(on==1) //On
lcdm[4]|=0x40;
else //Off
lcdm[4]&=~0x40;
}
//! Activates the minus sign. 2 for invert.
int setminus(int on){
if(on==2) //Blink
lcdm[6]^=0x04;
else if(on==1) //On
lcdm[6]|=0x04;
else //Off
lcdm[6]&=~0x04;
}
//! Activates the plus sign. 2 for invert.
int setplus(int on){
if(on==2) //Blink
lcdm[7]^=0x40;
else if(on==1) //On
lcdm[7]|=0x40;
else //Off
lcdm[7]&=~0x40;
}
//! Activates the divide sign. 2 for invert.
int setdivide(int on){
if(on==2) //Blink
lcdm[0xc]^=0x04;
else if(on==1) //On
lcdm[0xc]|=0x04;
else //Off
lcdm[0xc]&=~0x04;
}

View File

@ -12,7 +12,7 @@ int main(void) {
lcd_init();
// Setup and enable WDT 250ms, ACLK, interval timer
// Setup and enable WDT 1000ms, ACLK, interval timer
WDTCTL = WDT_ADLY_1000;
SFRIE1 |= WDTIE;