summaryrefslogtreecommitdiff
path: root/lcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcd.c')
-rw-r--r--lcd.c616
1 files changed, 308 insertions, 308 deletions
diff --git a/lcd.c b/lcd.c
index 508f1a0..076cd8e 100644
--- a/lcd.c
+++ b/lcd.c
@@ -1,308 +1,308 @@
-#include "i2c.h"
-#include "lcd.h"
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define LCD_ENABLE 0x03 /* the 4x40 LCDs have two enable lines - 0x03 enables both at the same time */
-#define LCD_DATA_RAM 128 /* display RAM, in the LCD ICs */
-#define LCD_CG_RAM 64 /* custom character RAM, in the LCD ICs */
-
-#define LCD_chars_total 160
-#define LCD_cols 40
-#define LCD_rows 4 /* 4x40 LCD */
-
-char LCD_Data[LCD_rows][LCD_cols]; /* shadow copy of LCD display in local RAM, to minimize slow I2C writes */
-
-/*** EndHeader */
-
-
-static void break_up_string (char *in_string, int N, char **str1, char **str2, char **str3)
-{
-
-#define SUBSTRING_CNT 3
-
- int input_length;
- int j, k, copypos;
- int n;
-
- char *copy_input;
- char *p;
-
- j=k=copypos=0;
- input_length=strlen(in_string);
- copy_input = g_strdup(in_string);
-
- for (j=0; j<SUBSTRING_CNT; j++) {
-
- gchar *interm_str = g_strnfill (N, 0);
-
- for (k=0; k<N; k++) {
- copypos++; // next symbol
- if (copypos>input_length) {
- break;
- }
- if ((*(copy_input+k)==' ')&&(copypos<input_length)) { // space found
- //find next space
- p=strchr(copy_input+k+1,' ');
- if (p!=NULL) {
- // next space is beyond N char limit for one line
- if((p-copy_input)/sizeof(char)>=N) {
- break;
- }
- } else {
- // No more spaces. Does the last chunk of text fit?
- if (strlen(copy_input+k+1)>N-k) {
- break;
- }
- }
- }
- // valid character, copy to output string
- *(interm_str+k)=*(copy_input+k);
-
- }
- // remove processed part from the input
- if (copypos<=input_length) {
- strcpy(copy_input, in_string+copypos);
- }
- n = strlen(interm_str);
- for ((k=n-1); (k=0); k--) { //trim space
- if (*(interm_str+k)==' ') {
- *(interm_str+k)=0;
- } else {
- break;
- }
- }
- switch (j) {
- case 0:
- *str1 = g_strdup(interm_str);
- break;
- case 1:
- *str2 = g_strdup(interm_str);
- break;
- case 2:
- *str3 = g_strdup(interm_str);
- break;
- }
- g_free(interm_str);
-
- }
-
- g_free(copy_input);
-}
-
-
-
-
-void LCD_clear()
-{
- int i;
- int j;
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0x10 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x10);
-
- /* wait 1.64ms */
- g_usleep(1640);
-
- for (i=0; i<4; ++i)
- for (j=0; j<40; ++j) {
- LCD_Data[i][j]=0;
- }
-
- return;
-}
-
-
-static void LCD_RAM_write(int RAM_start,int row, int col, char *LCD_string)
-{
- /* rows: 0-3, cols: 0-39 */
-
-#define data_level 0x04
-
- int i;
- int cur_row, cur_col;
- int String_length;
- char char_out, enable_one_lcd;
- int ram_location;
- char last_op_a_write;
-
- if (!LCD_string) {
- return;
- }
-
- String_length=strlen(LCD_string);
- enable_one_lcd=0x02;
-
- last_op_a_write=0;
- cur_row=row;
- cur_col=col;
-
- if (cur_row<2) {
- enable_one_lcd=0x02;
- } else {
- enable_one_lcd=0x01;
- }
-
- /* write out the string */
- for (i=0; i<String_length; ++i) {
- if (cur_row<2) {
- enable_one_lcd=0x02;
- } else {
- enable_one_lcd=0x01;
- }
-
- if (LCD_string[i]!=LCD_Data[cur_row][cur_col]) {
- if (!last_op_a_write) {
- /* move to new position */
- ram_location = (cur_row & 1) * 64 + cur_col + RAM_start;
- char_out=ram_location & 0xf0;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
- I2C_Write(PCF8574A+LCD_Port, char_out);
- char_out=ram_location << 4;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
- I2C_Write(PCF8574A+LCD_Port, char_out);
- }
- LCD_Data[cur_row][cur_col]=LCD_string[i];
- char_out=LCD_string[i] & 0xf0;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
- I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
- char_out=LCD_string[i] << 4;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
- I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
- last_op_a_write=1;
- } else {
- last_op_a_write=0;
- }
-
- ++cur_col;
- if (cur_col==40) {
- cur_col=0;
- ++cur_row;
- }
- }
- return;
-}
-
-
-void LCD_write(int row, int col, char *LCD_string)
-{
- LCD_RAM_write(LCD_DATA_RAM, row, col, LCD_string);
- return;
-}
-
-
-static void LCD_make_custom_chars()
-{
- /* define custom LCD characters 2 and 3 (up arrow and down arrow).*/
- /* The up arrow is stored in one LCD controller (for rows 0 and 1) */
- /* The down arrow is stored in the other LCD controller (for rows 2 and 3) */
- LCD_RAM_write(LCD_CG_RAM,0,16,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,17,"\xe");
- LCD_RAM_write(LCD_CG_RAM,0,18,"\x15");
- LCD_RAM_write(LCD_CG_RAM,0,19,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,20,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,21,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,22,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,23,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,24,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,25,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,26,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,27,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,28,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,29,"\x15");
- LCD_RAM_write(LCD_CG_RAM,2,30,"\xe");
- LCD_RAM_write(LCD_CG_RAM,2,31,"\x4");
-// prove that it works - debug only
-// LCD_RAM_write(LCD_DATA_RAM,0,39,"\x2");
-// LCD_RAM_write(LCD_DATA_RAM,3,39,"\x3");
-
- return;
-}
-
-
-void LCD_initialize(void)
-{
- /* Wait 15ms */
- g_usleep(15000);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 4.1ms */
- g_usleep(4100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 100us */
- g_usleep(100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 4.1ms */
- g_usleep(4100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x20);
-
- /*wait 40us */
- g_usleep(40);
-
- I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x20);
- I2C_Write(PCF8574A+LCD_Port, 0x80 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x80);
-
- /* wait 40us */
- g_usleep(40);
-
- LCD_clear();
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0x60 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x60);
-
- /* wait 40us */
- g_usleep(40);
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0xc0 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0xc0);
-
- LCD_make_custom_chars();
-
- return;
-}
-
-
-void LCD_display_error_message(char *response)
-{
- char *row0 = NULL;
- char *row1 = NULL;
- char *row2 = NULL;
-
-// Error_Screen=1; //FIXME
-
- break_up_string (response, LCD_cols, &row0, &row1, &row2);
-
- LCD_clear();
- LCD_write(0,0,row0);
- LCD_write(1,0,row1);
- LCD_write(2,0,row2);
- LCD_write(3,0,Press_Change_Message);
-
- g_free (row0);
- g_free (row1);
- g_free (row2);
-
- return;
-}
-
-
-
+#include "i2c.h"
+#include "lcd.h"
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LCD_ENABLE 0x03 /* the 4x40 LCDs have two enable lines - 0x03 enables both at the same time */
+#define LCD_DATA_RAM 128 /* display RAM, in the LCD ICs */
+#define LCD_CG_RAM 64 /* custom character RAM, in the LCD ICs */
+
+#define LCD_chars_total 160
+#define LCD_cols 40
+#define LCD_rows 4 /* 4x40 LCD */
+
+char LCD_Data[LCD_rows][LCD_cols]; /* shadow copy of LCD display in local RAM, to minimize slow I2C writes */
+
+/*** EndHeader */
+
+
+static void break_up_string (char *in_string, int N, char **str1, char **str2, char **str3)
+{
+
+#define SUBSTRING_CNT 3
+
+ int input_length;
+ int j, k, copypos;
+ int n;
+
+ char *copy_input;
+ char *p;
+
+ j=k=copypos=0;
+ input_length=strlen(in_string);
+ copy_input = g_strdup(in_string);
+
+ for (j=0; j<SUBSTRING_CNT; j++) {
+
+ gchar *interm_str = g_strnfill (N, 0);
+
+ for (k=0; k<N; k++) {
+ copypos++; // next symbol
+ if (copypos>input_length) {
+ break;
+ }
+ if ((*(copy_input+k)==' ')&&(copypos<input_length)) { // space found
+ //find next space
+ p=strchr(copy_input+k+1,' ');
+ if (p!=NULL) {
+ // next space is beyond N char limit for one line
+ if((p-copy_input)/sizeof(char)>=N) {
+ break;
+ }
+ } else {
+ // No more spaces. Does the last chunk of text fit?
+ if (strlen(copy_input+k+1)>N-k) {
+ break;
+ }
+ }
+ }
+ // valid character, copy to output string
+ *(interm_str+k)=*(copy_input+k);
+
+ }
+ // remove processed part from the input
+ if (copypos<=input_length) {
+ strcpy(copy_input, in_string+copypos);
+ }
+ n = strlen(interm_str);
+ for ((k=n-1); (k=0); k--) { //trim space
+ if (*(interm_str+k)==' ') {
+ *(interm_str+k)=0;
+ } else {
+ break;
+ }
+ }
+ switch (j) {
+ case 0:
+ *str1 = g_strdup(interm_str);
+ break;
+ case 1:
+ *str2 = g_strdup(interm_str);
+ break;
+ case 2:
+ *str3 = g_strdup(interm_str);
+ break;
+ }
+ g_free(interm_str);
+
+ }
+
+ g_free(copy_input);
+}
+
+
+
+
+void LCD_clear()
+{
+ int i;
+ int j;
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0x10 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x10);
+
+ /* wait 1.64ms */
+ g_usleep(1640);
+
+ for (i=0; i<4; ++i)
+ for (j=0; j<40; ++j) {
+ LCD_Data[i][j]=0;
+ }
+
+ return;
+}
+
+
+static void LCD_RAM_write(int RAM_start,int row, int col, char *LCD_string)
+{
+ /* rows: 0-3, cols: 0-39 */
+
+#define data_level 0x04
+
+ int i;
+ int cur_row, cur_col;
+ int String_length;
+ char char_out, enable_one_lcd;
+ int ram_location;
+ char last_op_a_write;
+
+ if (!LCD_string) {
+ return;
+ }
+
+ String_length=strlen(LCD_string);
+ enable_one_lcd=0x02;
+
+ last_op_a_write=0;
+ cur_row=row;
+ cur_col=col;
+
+ if (cur_row<2) {
+ enable_one_lcd=0x02;
+ } else {
+ enable_one_lcd=0x01;
+ }
+
+ /* write out the string */
+ for (i=0; i<String_length; ++i) {
+ if (cur_row<2) {
+ enable_one_lcd=0x02;
+ } else {
+ enable_one_lcd=0x01;
+ }
+
+ if (LCD_string[i]!=LCD_Data[cur_row][cur_col]) {
+ if (!last_op_a_write) {
+ /* move to new position */
+ ram_location = (cur_row & 1) * 64 + cur_col + RAM_start;
+ char_out=ram_location & 0xf0;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
+ I2C_Write(PCF8574A+LCD_Port, char_out);
+ char_out=ram_location << 4;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
+ I2C_Write(PCF8574A+LCD_Port, char_out);
+ }
+ LCD_Data[cur_row][cur_col]=LCD_string[i];
+ char_out=LCD_string[i] & 0xf0;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
+ I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
+ char_out=LCD_string[i] << 4;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
+ I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
+ last_op_a_write=1;
+ } else {
+ last_op_a_write=0;
+ }
+
+ ++cur_col;
+ if (cur_col==40) {
+ cur_col=0;
+ ++cur_row;
+ }
+ }
+ return;
+}
+
+
+void LCD_write(int row, int col, char *LCD_string)
+{
+ LCD_RAM_write(LCD_DATA_RAM, row, col, LCD_string);
+ return;
+}
+
+
+static void LCD_make_custom_chars()
+{
+ /* define custom LCD characters 2 and 3 (up arrow and down arrow).*/
+ /* The up arrow is stored in one LCD controller (for rows 0 and 1) */
+ /* The down arrow is stored in the other LCD controller (for rows 2 and 3) */
+ LCD_RAM_write(LCD_CG_RAM,0,16,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,17,"\xe");
+ LCD_RAM_write(LCD_CG_RAM,0,18,"\x15");
+ LCD_RAM_write(LCD_CG_RAM,0,19,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,20,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,21,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,22,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,23,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,24,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,25,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,26,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,27,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,28,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,29,"\x15");
+ LCD_RAM_write(LCD_CG_RAM,2,30,"\xe");
+ LCD_RAM_write(LCD_CG_RAM,2,31,"\x4");
+// prove that it works - debug only
+// LCD_RAM_write(LCD_DATA_RAM,0,39,"\x2");
+// LCD_RAM_write(LCD_DATA_RAM,3,39,"\x3");
+
+ return;
+}
+
+
+void LCD_initialize(void)
+{
+ /* Wait 15ms */
+ g_usleep(15000);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 4.1ms */
+ g_usleep(4100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 100us */
+ g_usleep(100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 4.1ms */
+ g_usleep(4100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x20);
+
+ /*wait 40us */
+ g_usleep(40);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x20);
+ I2C_Write(PCF8574A+LCD_Port, 0x80 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x80);
+
+ /* wait 40us */
+ g_usleep(40);
+
+ LCD_clear();
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0x60 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x60);
+
+ /* wait 40us */
+ g_usleep(40);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0xc0 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0xc0);
+
+ LCD_make_custom_chars();
+
+ return;
+}
+
+
+void LCD_display_error_message(char *response)
+{
+ char *row0 = NULL;
+ char *row1 = NULL;
+ char *row2 = NULL;
+
+// Error_Screen=1; //FIXME
+
+ break_up_string (response, LCD_cols, &row0, &row1, &row2);
+
+ LCD_clear();
+ LCD_write(0,0,row0);
+ LCD_write(1,0,row1);
+ LCD_write(2,0,row2);
+ LCD_write(3,0,Press_Change_Message);
+
+ g_free (row0);
+ g_free (row1);
+ g_free (row2);
+
+ return;
+}
+
+
+