/* Framework for infoscreens */ #include #include #include #include #include #include #include #include #include #include #ifdef DMALLOC #include #endif #define I2C_ADDRESS 0x20 static int i2cdev = 0; static unsigned char screen[LCD_H][LCD_W]; void i2c_get_position(int *position, int *direction, int *backlight) { static int lpos = 0; static int ppos = 0; unsigned char buf; const int overflow_margin = 10; const int max_count = 127; ioctl(i2cdev, I2C_SLAVE, I2C_ADDRESS); if (read(i2cdev, &buf, 1) != 1) perror("pos_read"); if (buf & 0x80) *backlight = 1; else *backlight = 0; buf &= 0x7F; if (buf < overflow_margin && ppos > max_count - overflow_margin) { // Overflow lpos += max_count - ppos + buf; *direction = 1; } else if (buf > max_count - overflow_margin && ppos < overflow_margin) { // Underflow lpos -= max_count - buf + ppos; *direction = 0; } else { lpos += buf - ppos; *direction = (buf > ppos) ? 1 : 0; } lpos = lpos % IS_COUNT; if (lpos < 0) lpos += IS_COUNT; *position = lpos; ppos = buf; } int is_render(int screenno, unsigned char buf[LCD_H][LCD_W]) { fr_title(is_list[screenno].title, screenno + 1, IS_COUNT, buf[0]); return is_list[screenno].render(buf); } void is_renderdisabled(unsigned char buf[LCD_H][LCD_W]) { memset(buf, 0, LCD_BYTES); fr_malign("LCD Display", buf[2], LCD_W); fr_malign("disabled", buf[3], LCD_W); } int is_initdisplay(int screenno) { int r; memset(screen, 0, LCD_BYTES); r = is_render(screenno, screen); lcd_update(screen); return r; } /* Public functions */ void is_initialize() { i2cdev = open("/dev/i2c/0", O_RDWR); is_initdisplay(0); } void is_upkeep() { static int screenno = 0; static int render_disabled = 0; static int next_update = 0; int newpos, direction, backlight; i2c_get_position(&newpos, &direction, &backlight); if (render_disabled) { if (backlight) { render_disabled = 0; screenno = newpos; is_initdisplay(screenno); } return; } else { if (!backlight) { #ifdef DMALLOC fprintf(stderr, "Shutting down (debug build)\n"); exit(1); #endif is_renderdisabled(screen); lcd_update(screen); render_disabled = 1; return; } } if (render_disabled) return; if (newpos == screenno) { if (next_update <= time(NULL)) next_update = is_initdisplay(screenno); return; } unsigned char newscreen[LCD_H][LCD_W] = {{0}}; next_update = is_render(newpos, newscreen); if (direction) lcd_scroll(screen, newscreen, 1); else lcd_scroll(newscreen, screen, 0); memcpy(screen, newscreen, LCD_BYTES); screenno = newpos; }