diff options
Diffstat (limited to 'lcd.c')
-rw-r--r-- | lcd.c | 616 |
1 files changed, 308 insertions, 308 deletions
@@ -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; +} + + + |