Selaa lähdekoodia

Graphical LCD is usable (not fully utilized)

k4be 1 vuosi sitten
vanhempi
commit
127dd9d74b
7 muutettua tiedostoa jossa 226 lisäystä ja 45 poistoa
  1. 4 2
      README.md
  2. 4 3
      soft/Makefile
  3. 185 17
      soft/UC1601S-I2C.c
  4. 13 14
      soft/UC1601S-I2C.h
  5. 13 2
      soft/display.c
  6. 3 5
      soft/main.c
  7. 4 2
      soft/main.h

+ 4 - 2
README.md

@@ -6,12 +6,12 @@ cd optiboot
 make install
 ```
 
-Second, program with software.
+Second, program the main software.
 
 Alphanumeric display version:
 ```
 cd soft
-make install PROGPORT=COM16
+make install PROGPORT=COM16 LCD=alnum
 ```
 
 Graphical display version:
@@ -19,3 +19,5 @@ Graphical display version:
 cd soft
 make install PROGPORT=COM16 LCD=graphic
 ```
+
+Warning: remember to ```make clean``` when switching between versions.

+ 4 - 3
soft/Makefile

@@ -29,8 +29,10 @@ ADEFS	=
 ifeq ($(LCD),graphic)
 CSRC	+= UC1601S-I2C.c
 DEFS	+= LCD_GRAPHIC
-else
+endif
+ifeq ($(LCD),alnum)
 CSRC	+= HD44780-I2C.c
+DEFS	+= LCD_ALNUM
 endif
 
 ### Warning contorls
@@ -67,8 +69,7 @@ PROJECT   := $(OBJDIR)/$(PROJECT)
 CFLAGS += -g$(DEBUG)
 CFLAGS += -mmcu=$(DEVICE)
 CFLAGS += -O$(OPTIMIZE) -mcall-prologues
-CFLAGS += $(addprefix -W,$(WARNINGS))
-# --param=min-pagesize=0
+CFLAGS += $(addprefix -W,$(WARNINGS)) --param=min-pagesize=0
 CFLAGS += $(addprefix -I,$(INCDIRS))
 CFLAGS += $(addprefix -D,$(DEFS))
 CFLAGS += -Wp,-MM,-MP,-MT,$(OBJDIR)/$(*F).o,-MF,$(OBJDIR)/$(*F).d

+ 185 - 17
soft/UC1601S-I2C.c

@@ -1,51 +1,219 @@
 #include "UC1601S-I2C.h"
+#include <avr/pgmspace.h>
+
+__flash const unsigned char FontLookup [][5] = {
+	{ 0x00, 0x00, 0x00, 0x00, 0x00 },  // sp
+	{ 0x00, 0x00, 0x2f, 0x00, 0x00 },   // !
+	{ 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
+	{ 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
+	{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
+	{ 0xc4, 0xc8, 0x10, 0x26, 0x46 },   // %
+	{ 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
+	{ 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
+	{ 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
+	{ 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
+	{ 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
+	{ 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
+	{ 0x00, 0x00, 0x50, 0x30, 0x00 },   // ,
+	{ 0x10, 0x10, 0x10, 0x10, 0x10 },   // -
+	{ 0x00, 0x60, 0x60, 0x00, 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, 0x45, 0x4B, 0x31 },   // 3
+	{ 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
+	{ 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
+	{ 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
+	{ 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
+	{ 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
+	{ 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
+	{ 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
+	{ 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
+	{ 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
+	{ 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
+	{ 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
+	{ 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
+	{ 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
+	{ 0x7E, 0x11, 0x11, 0x11, 0x7E },   // A
+	{ 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
+	{ 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
+	{ 0x7F, 0x41, 0x41, 0x22, 0x1C },   // 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, 0x0C, 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
+	{ 0x46, 0x49, 0x49, 0x49, 0x31 },   // 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
+	{ 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
+	{ 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
+	{ 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
+	{ 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // 55
+	{ 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
+	{ 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
+	{ 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
+	{ 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
+	{ 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
+	{ 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
+	{ 0x38, 0x44, 0x44, 0x44, 0x28 },   // c
+	{ 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
+	{ 0x38, 0x54, 0x54, 0x54, 0x18 },   // e
+	{ 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
+	{ 0x0C, 0x52, 0x52, 0x52, 0x3E },   // g
+	{ 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
+	{ 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
+	{ 0x20, 0x40, 0x44, 0x3D, 0x00 },   // j
+	{ 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
+	{ 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
+	{ 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
+	{ 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
+	{ 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
+	{ 0x7C, 0x14, 0x14, 0x14, 0x08 },   // p
+	{ 0x08, 0x14, 0x14, 0x18, 0x7C },   // q
+	{ 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
+	{ 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
+	{ 0x04, 0x3F, 0x44, 0x40, 0x20 },   // 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
+	{ 0x0C, 0x50, 0x50, 0x50, 0x3C },   // y
+	{ 0x44, 0x64, 0x54, 0x4C, 0x44 },   // z
+	{ 0x7F, 0x50, 0x48, 0x44, 0x40 },   // Ł \x7b
+	{ 0x44, 0x64, 0x56, 0x4D, 0x44 },   // ź \x7c
+	{ 0x38, 0x54, 0xd4, 0x54, 0x18 },   // ę \x7d
+	{ 0x48, 0x54, 0x56, 0x55, 0x20 },   // ś \x7e
+	{ 0x20, 0x54, 0x54, 0xd4, 0x78 },   // ą \x7f
+	{ 0x38, 0x44, 0x46, 0x45, 0x28 },   // ć \x80
+	{ 0x00, 0x49, 0x7F, 0x44, 0x00 },   // ł \x81
+	{ 0xfe, 0x43, 0x43, 0x43, 0xfe },	// 0/3 \x82
+	{ 0xfe, 0xe3, 0xe3, 0xe3, 0xfe },	// 1/3 \x83
+	{ 0xfe, 0xfb, 0xfb, 0xfb, 0xfe },	// 2/3 \x84
+	{ 0xfe, 0xff, 0xff, 0xff, 0xfe },	// 3/3 \x85
+};
+/*
+__flash const unsigned char custom_chars[] = {
+	0b00000, /* 0x01 down arrow *//*
+	0b00100,
+	0b00100,
+	0b00100,
+	0b10101,
+	0b01110,
+	0b00100,
+	0b00000,
+	
+	0b00000, /* 0x02 up arrow *//*
+	0b00100,
+	0b01110,
+	0b10101,
+	0b00100,
+	0b00100,
+	0b00100,
+	0b00000,
+};*/
 
 void uc1601s_write_command(unsigned char cmd) {
-	expander_set_bit_no_send(UC1601S_CS_PORT, UC1601S_CS, 0);
 	expander_set_bit_no_send(UC1601S_CD_PORT, UC1601S_CD, 0);
 	exp_output[0] = cmd;
 	expander_write(0);
 	expander_set_bit(UC1601S_WR_PORT, UC1601S_WR, 0);
-	expander_set_bit(UC1601S_WR_PORT, UC1601S_WR, 1);
-	expander_set_bit(UC1601S_CS_PORT, UC1601S_CS, 1);
+	expander_set_bit_no_send(UC1601S_WR_PORT, UC1601S_WR, 1);
+	expander_set_bit(UC1601S_CD_PORT, UC1601S_CD, 1);
 }
 
 void uc1601s_write_data(unsigned char data) {
-	expander_set_bit_no_send(UC1601S_CS_PORT, UC1601S_CS, 0);
-	expander_set_bit(UC1601S_CD_PORT, UC1601S_CD, 1);
 	exp_output[0] = data;
 	expander_write(0);
 	expander_set_bit(UC1601S_WR_PORT, UC1601S_WR, 0);
 	expander_set_bit(UC1601S_WR_PORT, UC1601S_WR, 1);
-	expander_set_bit(UC1601S_CS_PORT, UC1601S_CS, 1);
 }
 
 unsigned char uc1601s_read_data(void) {
 	unsigned char out;
 	UC1601S_DATA_INPUT();
-	expander_set_bit_no_send(UC1601S_CS_PORT, UC1601S_CS, 0);
-	expander_set_bit_no_send(UC1601S_CD_PORT, UC1601S_CD, 1);
 	expander_set_bit(UC1601S_RD_PORT, UC1601S_RD, 0);
 	out = expander_read_byte(0, 0);
-	expander_set_bit_no_send(UC1601S_RD_PORT, UC1601S_RD, 1);
-	expander_set_bit(UC1601S_CS_PORT, UC1601S_CS, 1);
+	expander_set_bit(UC1601S_RD_PORT, UC1601S_RD, 1);
 	UC1601S_DATA_OUTPUT();
 	return out;
 }
 
-#define UC1601S_INTERNAL_VLCD	0x6
+#define LCD_COM_COUNT	32
+#define LCD_ROW_COUNT	(LCD_COM_COUNT/8)
+#define LCD_COL_COUNT	128
+
+#define UC1601S_MY		0x4
+#define UC1601S_MX		0x2
 
 void LCD_Initialize(void) {
+	expander_set_bit_no_send(UC1601S_CS_PORT, UC1601S_CS, 0);
 	expander_set_bit(UC1601S_RST_PORT, UC1601S_RST, 1);
 	_delay_ms(5);
 	expander_set_bit_no_send(UC1601S_RD_PORT, UC1601S_RD, 1);
 	expander_set_bit(UC1601S_WR_PORT, UC1601S_WR, 1);
 	UC1601S_DATA_OUTPUT();
-//	uc1601s_system_reset();
-	uc1601s_set_lcd_bias_ratio(UC1601S_BIAS_RATIO_8);
-	uc1601s_set_vbias(0xee);
-	uc1601s_set_display_enable(1);
 	uc1601s_set_power_control(UC1601S_INTERNAL_VLCD);
-	uc1601s_set_all_pixel_on(1);
-	_delay_ms(2);
+	uc1601s_set_lcd_bias_ratio(UC1601S_BIAS_RATIO_7);
+	uc1601s_set_com_end(LCD_COM_COUNT-1);
+	uc1601s_set_lcd_mapping(UC1601S_MY);
+	uc1601s_set_vbias(230);
+	uc1601s_set_display_enable(1);
 }
+
+void LCD_Clear(void) {
+	unsigned int col, row;
+	
+	for (row=0; row<LCD_ROW_COUNT; row++) {
+		uc1601s_set_page_address(row);
+		uc1601s_set_column_address(0);
+		for (col=0; col<LCD_COL_COUNT; col++) {
+			uc1601s_write_data(0);
+		}
+	}
+}
+
+void LCD_GoTo(unsigned char x, unsigned char y) {
+	uc1601s_set_page_address(y);
+	uc1601s_set_column_address(x*6);
+}
+
+
+void LCD_WriteTextP(__flash const char *t) {
+	char c;
+	while ((c = pgm_read_byte(t))) {
+		LCD_WriteChar(c);
+		t++;
+	}
+}
+
+void LCD_WriteText(const char *t) {
+	while (*t) {
+		LCD_WriteChar(*t);
+		t++;
+	}
+}
+
+void LCD_WriteChar(char c) {
+	unsigned char col;
+	
+	c -= ' ';
+	for (col = 0; col < 5; col++) {
+		uc1601s_write_data(FontLookup[(int)c][col]);
+	}
+	uc1601s_write_data(0);
+}
+

+ 13 - 14
soft/UC1601S-I2C.h

@@ -5,11 +5,6 @@
 #include "expander.h"
 
 #define LCD_WriteCommand(x)
-#define LCD_WriteData(x)
-#define LCD_Clear()
-#define LCD_GoTo(x,y)
-#define LCD_WriteTextP(x)
-#define LCD_WriteText(x)
 
 #define UC1601S_CA30	0x00
 #define UC1601S_CA74	0x10
@@ -33,6 +28,12 @@
 #define UC1601S_DST	0xf2
 #define UC1601S_DEN	0xf3
 
+#define UC1601S_INTERNAL_VLCD	0x6
+#define UC1601S_BIAS_RATIO_6	0x0
+#define UC1601S_BIAS_RATIO_7	0x1
+#define UC1601S_BIAS_RATIO_8	0x2
+#define UC1601S_BIAS_RATIO_9	0x3
+
 #define UC1601S_DATA_OUTPUT() 	expander_set_dir(0, 0x00, 0x00)
 #define UC1601S_DATA_INPUT() 	expander_set_dir(0, 0xFF, 0x00)
 
@@ -51,11 +52,16 @@ void uc1601s_write_command(unsigned char cmd);
 void uc1601s_write_data(unsigned char data);
 unsigned char uc1601s_read_data(void);
 void LCD_Initialize(void);
+void LCD_Clear(void);
+void LCD_GoTo(unsigned char x, unsigned char y);
+void LCD_WriteTextP(__flash const char *t);
+void LCD_WriteText(const char *t);
+void LCD_WriteChar(char c);
+#define LCD_WriteData(c) LCD_WriteChar(c)
 
 static inline void uc1601s_set_column_address(unsigned char addr) {
 	uc1601s_write_command(UC1601S_CA30 | (addr&0x0f));
 	uc1601s_write_command(UC1601S_CA74 | (addr>>4));
-	uc1601s_read_data();
 }
 
 static inline void uc1601s_set_temp_compensation(unsigned char tc) {
@@ -76,7 +82,6 @@ static inline void uc1601s_set_scroll_line(unsigned char sl) {
 static inline void uc1601s_set_page_address(unsigned char pa) {
 	pa &= 0x0f;
 	uc1601s_write_command(UC1601S_PA | pa);
-	uc1601s_read_data();
 }
 
 static inline void uc1601s_set_vbias(unsigned char pm) {
@@ -115,8 +120,7 @@ static inline void uc1601s_set_display_enable(unsigned char dc) {
 }
 
 static inline void uc1601s_set_lcd_mapping(unsigned char lc) {
-	lc &= 0x3;
-	lc <<= 1;
+	lc &= 0x6;
 	uc1601s_write_command(UC1601S_LC21 | lc);
 }
 
@@ -124,11 +128,6 @@ static inline void uc1601s_system_reset(void) {
 	uc1601s_write_command(UC1601S_SYSTEMRESET);
 }
 
-#define UC1601S_BIAS_RATIO_6	0x0
-#define UC1601S_BIAS_RATIO_7	0x1
-#define UC1601S_BIAS_RATIO_8	0x2
-#define UC1601S_BIAS_RATIO_9	0x3
-
 static inline void uc1601s_set_lcd_bias_ratio(unsigned char br) {
 	br &= 0x3;
 	uc1601s_write_command(UC1601S_BR | br);

+ 13 - 2
soft/display.c

@@ -5,6 +5,7 @@
 #include "working_modes.h"
 #include "timec.h"
 
+#ifndef LCD_GRAPHIC
 __flash const unsigned char battery_states[][8] = {
 	{
 		0b01110,
@@ -67,19 +68,21 @@ __flash const unsigned char custom_chars[] = {
 	0b00100,
 	0b00000,
 };
+#endif /* LCD_GRAPHIC */
 
 struct disp_s disp;
 
 void disp_init(void) { /* send custom characters starting with 0x01 */
+#ifndef LCD_GRAPHIC
 	unsigned char i;
 	LCD_WriteCommand(0x40 + 8); // 0x01
 	for(i=0; i<sizeof(custom_chars); i++){
 		LCD_WriteData(custom_chars[i]);
 	};
+#endif /* LCD_GRAPHIC */
 }
 
 void battery_state_display(void) {
-	unsigned char i;
 	unsigned char index;
 	if (System.bat_volt > 4.0)
 		index = 0;
@@ -89,12 +92,18 @@ void battery_state_display(void) {
 		index = 2;
 	else
 		index = 3;
-	
+
+#ifdef LCD_GRAPHIC
+	LCD_GoTo(15,0);
+	LCD_WriteChar(0x82 + index);
+#else
+	unsigned char i;
 	LCD_WriteCommand(0x40 + 0); // 0x00
 
 	for(i=0; i<8; i++){
 		LCD_WriteData(battery_states[index][i]);
 	};
+#endif /* LCD_GRAPHIC */
 }
 
 static inline void disp_line(unsigned char i, __flash const char *text) {
@@ -285,7 +294,9 @@ void display_refresh(unsigned char changed) {
 			len++;
 			LCD_WriteData(' ');
 		}
+#ifndef LCD_GRAPHIC
 		LCD_WriteData(0); /* battery symbol */
+#endif
 		LCD_GoTo(0,1);
 		len = strlen(disp.line2);
 		LCD_WriteText(disp.line2);

+ 3 - 5
soft/main.c

@@ -239,14 +239,12 @@ void ioinit (void)
 	I2C_init();
 	expander_init(0, 0x00, 0x00); /* all as outputs */
 	
-	while (1) {
-	
 	LCD_Initialize();
 	LCD_Clear();
-	
+
+	LCD_GoTo(0,0);
+
 	wdt_reset();
-	
-	}
 
 	sei();
 	

+ 4 - 2
soft/main.h

@@ -8,10 +8,12 @@
 #include "expander.h"
 #include "settings.h"
 
-#ifdef LCD_GRAPHIC
+#if defined(LCD_GRAPHIC)
 #include "UC1601S-I2C.h"
-#else
+#elif defined(LCD_ALNUM)
 #include "HD44780-I2C.h"
+#else
+#error No LCD type defined
 #endif
 
 #define	IVT_SYNC	180			/* f_sync() interval (0:no periodic sync) [sec] */