Restructure
[liquid-crystal-terminal.git] / terminal / terminal.ino
index 5880acf..7709be2 100644 (file)
@@ -1,146 +1,9 @@
 #include <LiquidCrystal.h>
 
-// LED pins
-#define LEDS_GRN   15 // Analog 1; Common green anode
-#define LEDS_RED   16 // Analog 2; Common red anode
-#define LED1       13 // LED1 cathode
-#define LED2       12 // LED2 cathode
-#define LED3       11 // LED3 cathode
-#define LED4       10 // LED4 cathode
-
-#define LED_OFF   0x00
-#define LED_GRN   0x01
-#define LED_RED   0x02
-#define LED_BLINK 0x04
-
-struct leds {
-       byte a:3;
-       byte b:3;
-       byte c:3;
-       byte d:3;
-       unsigned int counter;
-};
-struct leds leds;
-
-// Button pin
-#define BUTTON     14 // Analog 0; push button
-
-// LCD pins
-#define LCD_REGSEL  3 // Register select
-#define LCD_ENABLE  4 // Chip enable
-#define LCD_D4      5 // Data line
-#define LCD_D5      6 // Data line
-#define LCD_D6      7 // Data line
-#define LCD_D7      8 // Data line
-#define LCD_BL      2 // Backlight
-
-LiquidCrystal lcd(LCD_REGSEL, LCD_ENABLE, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
-
-enum backlight_state {
-       BL_OFF,
-       BL_ON,
-       BL_FLASH
-};
-struct backlight {
-       enum backlight_state state;
-       unsigned int timer;
-};
-struct backlight backlight;
-
-#define COLS 40
-#define ROWS 2
-
-/**
- * Special characters.
- * See https://www.quinapalus.com/hd44780udg.html to make more.
- * Define which ones are used (max. 8) in setup().
- * When they need to be changed at runtime, make sure the cursor is disabled
- * and call setCursor afterwards.
- */
-byte char_music[8] = {0x02,0x03,0x02,0x0e,0x1e,0x0c,0x00};
-byte char_smile[8] = {0x00,0x00,0x0a,0x00,0x11,0x0e,0x00};
-byte char_bar_1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1f};
-byte char_bar_2[8] = {0x00,0x00,0x00,0x00,0x00,0x1f,0x1f};
-byte char_bar_3[8] = {0x00,0x00,0x00,0x00,0x1f,0x1f,0x1f};
-byte char_bar_4[8] = {0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f};
-byte char_bar_5[8] = {0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f};
-byte char_bar_6[8] = {0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
-byte char_bar_7[8] = {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
-byte char_hbar_start_empty[8] = {0x1f,0x10,0x10,0x10,0x10,0x10,0x1f};
-byte char_hbar_start_full[8]  = {0x1f,0x10,0x17,0x17,0x17,0x10,0x1f};
-byte char_hbar_inner_empty[8] = {0x1f,0x00,0x00,0x00,0x00,0x00,0x1f};
-byte char_hbar_inner_half[8]  = {0x1f,0x00,0x1c,0x1c,0x1c,0x00,0x1f};
-byte char_hbar_inner_full[8]  = {0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x1f};
-byte char_hbar_end_empty[8]   = {0x1f,0x01,0x01,0x01,0x01,0x01,0x1f};
-byte char_hbar_end_full[8]    = {0x1f,0x01,0x1d,0x1d,0x1d,0x01,0x1f};
-
-struct terminal {
-       byte x;
-       byte y;
-       char contents[COLS * ROWS];
-};
-
-void redraw(struct terminal *term)
-{
-       lcd.noCursor();
-       lcd.clear();
-       lcd.home();
-       for (byte i = 0; i < COLS * ROWS; i++) {
-               if (i % COLS == 0)
-                       lcd.setCursor(i % COLS, i / COLS);
-               lcd.write(term->contents[i]);
-       }
-       lcd.cursor();
-}
-
-void scroll_up(struct terminal *term)
-{
-       for (byte i = 0; i < COLS * (ROWS - 1); i++)
-               term->contents[i] = term->contents[i + COLS];
-       for (byte i = COLS * (ROWS - 1); i < COLS * ROWS; i++)
-               term->contents[i] = ' ';
-       redraw(term);
-}
-
-/**
- * Special character meanings are defined here.
- */
-void write(struct terminal *term, char ch)
-{
-       switch (ch) {
-               case '\r':
-                       term->x = 0;
-                       lcd.setCursor(term->x, term->y);
-                       break;
-               case '\n':
-                       if (++term->y >= ROWS) {
-                               term->y--;
-                               scroll_up(term);
-                       }
-                       lcd.setCursor(term->x, term->y);
-                       break;
-               case 0x7f:
-                       if (term->x != 0) {
-                               term->x--;
-                               term->contents[term->x + term->y * COLS] = 0x00;
-                               lcd.setCursor(term->x, term->y);
-                               lcd.write(' ');
-                               lcd.setCursor(term->x, term->y);
-                       }
-                       break;
-               default:
-                       term->contents[term->x + term->y * COLS] = ch;
-                       lcd.write(ch);
-                       if (++term->x >= COLS) {
-                               term->x = 0;
-                               if (++term->y >= ROWS) {
-                                       term->y--;
-                                       scroll_up(term);
-                               }
-                               lcd.setCursor(term->x, term->y);
-                       }
-       }
-}
+#include "button.h"
+#include "lcd.h"
+#include "leds.h"
+#include "term.h"
 
 struct terminal term;
 
@@ -148,121 +11,20 @@ char message[] =
        "Beste Mart, van harte gefeliciteerd! \x01\x00\r\n"
        "Hier een herprogrammeerbare terminal. ";
 
-/**
- * Tasks for the LEDs. Needs to be called every few ms(?) for multiplexing.
- * When an LED is blinking and in the off period, it is necessary to call
- * digitalWrite() twice and set the cathode. This ensures that the function
- * takes equally long to return on every iteration, s.t. the blinking duty
- * cycle is exactly 50% and LEDs blink equally bright, regardless of the status
- * of other LEDs.
- */
-void led_tasks()
-{
-       leds.counter++;
-       switch (leds.counter & 0x03) {
-               case 0:
-                       digitalWrite(LED4, 1);
-                       if ((leds.a & LED_BLINK) && leds.counter & 0x4000) {
-                               digitalWrite(LEDS_GRN, 0);
-                               digitalWrite(LEDS_RED, 0);
-                       } else {
-                               digitalWrite(LEDS_GRN, leds.a & 1);
-                               digitalWrite(LEDS_RED, leds.a & 2);
-                       }
-                       digitalWrite(LED1, 0);
-                       break;
-               case 1:
-                       digitalWrite(LED1, 1);
-                       if ((leds.b & LED_BLINK) && leds.counter & 0x4000) {
-                               digitalWrite(LEDS_GRN, 0);
-                               digitalWrite(LEDS_RED, 0);
-                       } else {
-                               digitalWrite(LEDS_GRN, leds.b & 1);
-                               digitalWrite(LEDS_RED, leds.b & 2);
-                       }
-                       digitalWrite(LED2, 0);
-                       break;
-               case 2:
-                       digitalWrite(LED2, 1);
-                       if ((leds.c & LED_BLINK) && leds.counter & 0x4000) {
-                               digitalWrite(LEDS_GRN, 0);
-                               digitalWrite(LEDS_RED, 0);
-                       } else {
-                               digitalWrite(LEDS_GRN, leds.c & 1);
-                               digitalWrite(LEDS_RED, leds.c & 2);
-                       }
-                       digitalWrite(LED3, 0);
-                       break;
-               case 3:
-                       digitalWrite(LED3, 1);
-                       if ((leds.d & LED_BLINK) && leds.counter & 0x4000) {
-                               digitalWrite(LEDS_GRN, 0);
-                               digitalWrite(LEDS_RED, 0);
-                       } else {
-                               digitalWrite(LEDS_GRN, leds.d & 1);
-                               digitalWrite(LEDS_RED, leds.d & 2);
-                       }
-                       digitalWrite(LED4, 0);
-                       break;
-       }
-}
-
-void button_tasks()
-{
-       if (digitalRead(BUTTON)) {
-               bl_flash();
-       }
-}
-
-void bl_tasks()
-{
-       if (backlight.state == BL_FLASH)
-               if (!--backlight.timer)
-                       backlight.state = BL_OFF;
-
-       switch (backlight.state) {
-               case BL_OFF:
-                       digitalWrite(LCD_BL, 0);
-                       break;
-               case BL_FLASH:
-               case BL_ON:
-                       digitalWrite(LCD_BL, 1);
-                       break;
-       }
-}
-
-void bl_flash()
-{
-       backlight.state = BL_FLASH;
-       backlight.timer = (unsigned int) -1;
-}
-
 void setup()
 {
-       lcd.createChar(0, char_music);
-       lcd.createChar(1, char_smile);
-
-       lcd.begin(COLS, ROWS);
-       lcd.blink();
        Serial.begin(115200);
 
+       lcd_setup();
+       leds_setup();
+       button_setup();
+
        for (byte i = 0; i < ROWS * COLS; i++)
                term.contents[i] = ' ';
 
        for (byte i = 0; i < sizeof(message) - 1; i++)
                write(&term, message[i]);
 
-       pinMode(LCD_BL, OUTPUT);
-
-       pinMode(LEDS_GRN, OUTPUT);
-       pinMode(LEDS_RED, OUTPUT);
-       pinMode(LED1, OUTPUT);
-       pinMode(LED2, OUTPUT);
-       pinMode(LED3, OUTPUT);
-       pinMode(LED4, OUTPUT);
-
-       pinMode(BUTTON, INPUT);
-
        leds.a = LED_GRN | LED_BLINK;
        leds.b = LED_RED | LED_BLINK;
        leds.c = LED_GRN | LED_BLINK;
@@ -304,10 +66,7 @@ void handle_character(char c)
                        break;
 
                case S_BACKLIGHT:
-                       if (c == 0x02)
-                               bl_flash();
-                       else
-                               backlight.state = (enum backlight_state) c;
+                       bl_set((enum backlight_state) c);
                        read_state = S_DEFAULT;
                        break;
        }
@@ -315,7 +74,7 @@ void handle_character(char c)
 
 void loop()
 {
-       led_tasks();
+       leds_tasks();
        button_tasks();
        bl_tasks();