Change sketch name and path master
authorIvan <ivan@soc.ninja>
Tue, 29 Mar 2016 08:05:26 +0000 (10:05 +0200)
committerIvan <ivan@soc.ninja>
Tue, 29 Mar 2016 08:05:26 +0000 (10:05 +0200)
code/softspi_eink/softspi_eink.ino [new file with mode: 0644]
code/softspi_eink/softspi_eink.ino/softspi_eink.ino.ino [deleted file]

diff --git a/code/softspi_eink/softspi_eink.ino b/code/softspi_eink/softspi_eink.ino
new file mode 100644 (file)
index 0000000..a2238bc
--- /dev/null
@@ -0,0 +1,885 @@
+// -*- mode: c++ -*-
+// Copyright 2013 Pervasive Displays, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied.  See the License for the specific language
+// governing permissions and limitations under the License.
+
+
+// An example of the SdFatSoftSpi template class.
+// This example is for an Adafruit Data Logging Shield on a Mega.
+// Software SPI is required on Mega since this shield connects to pins 10-13.
+// This example will also run on an Uno and other boards using software SPI.
+//
+
+#include "RTClib.h"
+
+RTC_DS1307 rtc;
+
+#include <SPI.h>
+#include "SdFat.h"
+//
+// Pin numbers in templates must be constants.
+const uint8_t SOFT_MISO_PIN = A2;
+const uint8_t SOFT_MOSI_PIN = A3;
+const uint8_t SOFT_SCK_PIN  = 2;
+//
+// Chip select may be constant or RAM variable.
+const uint8_t SD_CHIP_SELECT_PIN = 3;
+
+// SdFat software SPI template
+SdFatSoftSpi<SOFT_MISO_PIN, SOFT_MOSI_PIN, SOFT_SCK_PIN> sd;
+
+// Test file.
+SdFile file;
+
+
+
+
+#include <Arduino.h>
+#include <inttypes.h>
+#include <ctype.h>
+
+// required libraries
+#include <SPI.h>
+#include <FLASH.h>
+#include <EPD2.h>
+#include <Wire.h>
+#include <LM75.h>
+
+// Change this for different display size
+// supported sizes: 144 200 270
+#define SCREEN_SIZE 270
+
+
+// no futher changed below this point
+
+// set up images from screen size2
+#if (SCREEN_SIZE == 144)
+#define EPD_SIZE EPD_1_44
+#define SECTORS_USED 1
+
+#elif (SCREEN_SIZE == 200)
+#define EPD_SIZE EPD_2_0
+#define SECTORS_USED 1
+
+#elif (SCREEN_SIZE == 270)
+#define EPD_SIZE EPD_2_7
+#define SECTORS_USED 2
+
+#else
+#error "Unknown EPB size: Change the #define SCREEN_SIZE to a supported value"
+#endif
+
+#define COMMAND_VERSION "1"
+
+
+// Arduino IO layout
+//const int Pin_TEMPERATURE = A0; // Temperature is handled by LM75 over I2C and not an analog pin
+const uint8_t Pin_PANEL_ON = 5;
+const uint8_t Pin_BORDER = 10;
+const uint8_t Pin_DISCHARGE = 4;
+//const int Pin_PWM = 5;    // Not used by COG v2
+const uint8_t Pin_RESET = 6;
+const uint8_t Pin_BUSY = 7;
+const uint8_t Pin_EPD_CS = 8;
+const uint8_t Pin_FLASH_CS = 9;
+const uint8_t Pin_SW2 = 12;
+const uint8_t Pin_RED_LED = 13;
+
+
+// LED anode through resistor to I/O pin
+// LED cathode to Ground
+#define LED_ON  HIGH
+#define LED_OFF LOW
+
+// pre-processor convert to string
+#define MAKE_STRING1(X) #X
+#define MAKE_STRING(X) MAKE_STRING1(X)
+
+
+// function prototypes
+static void epd_power_flash_access(bool state);
+//static void flash_info(void);
+static void flash_read(void *buffer, uint32_t address, uint16_t length);
+
+static uint16_t xbm_count;
+static bool xbm_parser(uint8_t *b);
+
+
+static uint8_t Serial_getc();
+static uint16_t Serial_gethex(bool echo);
+static void Serial_puthex(uint32_t n, int bits);
+static void Serial_puthex_byte(uint8_t n);
+static void Serial_puthex_word(uint16_t n);
+static void Serial_puthex_double(uint32_t n);
+//static void Serial_hex_dump(uint32_t address, const void *buffer, uint16_t length);
+void displayCurrentImage();
+
+
+// define the E-Ink display
+EPD_Class EPD(EPD_SIZE, Pin_PANEL_ON, Pin_BORDER, Pin_DISCHARGE, Pin_RESET, Pin_BUSY, Pin_EPD_CS);
+
+
+static uint8_t Serial_getcc() {
+
+    while (file.available() == false) {
+    }
+
+    char readed;
+    //int result=
+    file.read(&readed,1);
+    
+    //Serial.print("Result: ");
+    //Serial.println(result);
+
+    //Serial.print("Readed: ");
+    //Serial.print((char)readed);
+
+    //FatPos_t position;
+
+    //file.getpos(&position);
+
+    //Serial.print("Position: ");
+    //Serial.println(position.position);
+
+    return readed;
+
+
+}
+
+
+static uint16_t Serial_gethexx(bool echo) {
+  uint16_t acc = 0;
+  for (;;) {
+
+    uint8_t c = Serial_getcc();
+
+    if (c >= '0' && c <= '9') {
+      c -= '0';
+    } else if (c >= 'a' && c <= 'f') {
+      c -= 'a' - 10;
+    } else if (c >= 'A' && c <= 'F') {
+      c -= 'A' - 10;
+    } else {
+      return acc;
+    }
+    if (echo) {
+      Serial_puthex(c, 4);
+    }
+    acc <<= 4;
+    acc += c;
+  }
+}
+
+
+
+uint16_t currentCard=1; // 1-2499
+uint16_t level=10;
+bool currentType=0; // 0 = card; 1 = exp
+         
+
+void eraseSector(uint32_t sector) {
+  //Serial.println("Erasing sector " + String(sector) );
+//  uint32_t sector = Serial_gethex(true);
+  epd_power_flash_access(true);
+  FLASH.write_enable();
+  FLASH.sector_erase(sector << 12);
+  FLASH.write_disable();
+  epd_power_flash_access(false);
+}
+
+void storeHistory() {
+
+    DateTime now = rtc.now();
+
+    file.open("HIST.TXT", O_RDWR | O_CREAT | O_AT_END);
+    file.print(now.unixtime());
+    file.print(" ");
+    file.println(currentCard);
+    file.close();
+  
+}
+
+void pressButton(uint8_t num) {
+
+// 1 - RANDOM
+// 2 - EXPLAIN
+// 3 - NEXT
+// 4 - PREV
+
+eraseSector(0);
+eraseSector(1);
+int rndcard;
+
+  switch (num) {
+
+      case 1:
+
+        randomSeed(millis());
+        //currentCard=random(1,1499);
+
+        do rndcard=random(1,level);
+        while (rndcard == currentCard);
+                
+        currentCard=rndcard;
+        currentType=0;
+
+        storeHistory();
+
+
+      break;
+
+      case 2:
+
+        currentType=!currentType;
+
+      break;
+
+      case 3:
+
+        //if ( currentCard < 1499 )
+        if ( currentCard < level )
+          currentCard++;
+        else
+          currentCard=1;
+          
+        currentType=0;
+        storeHistory();
+
+      break;
+
+      case 4:
+
+        if ( currentCard >1 )
+          currentCard--;
+          else
+          currentCard=level;
+          //currentCard=2499;
+          
+        currentType=0;
+        storeHistory();
+
+      break;
+    
+  }
+
+      uploadCurrentImage();
+      //displayCurrentImage(currentType);
+      displayCurrentImage(0);
+
+  
+}
+
+void uploadCurrentImage() {
+
+
+    int32_t address = 0;
+
+    address <<= 12;
+    xbm_count = 0;
+    //Serial.println();
+    //Serial.println("start upload...");
+
+
+    char path[22];
+
+   if ( currentCard > 2000 )
+      if (!currentType)
+        sprintf(path, "2001-2500/CARD%i.XBM",currentCard);
+      else
+        sprintf(path, "EXP2001-2500/EXP%i.XBM",currentCard);
+
+    else if ( currentCard > 1500 )
+     if (!currentType)
+      sprintf(path, "1501-2000/CARD%i.XBM",currentCard);
+      else
+        sprintf(path, "EXP1501-2000/EXP%i.XBM",currentCard);
+
+    else if ( currentCard > 1000 )
+     if (!currentType)
+      sprintf(path, "1001-1500/CARD%i.XBM",currentCard);
+      else
+        sprintf(path, "EXP1001-1500/EXP%i.XBM",currentCard);
+
+    else if ( currentCard > 500 )
+      if (!currentType)
+      sprintf(path, "501-1000/CARD%i.XBM",currentCard);
+      else
+        sprintf(path, "EXP501-1000/EXP%i.XBM",currentCard);
+    else
+     if (!currentType)
+      sprintf(path, "1-500/CARD%i.XBM",currentCard);
+      else
+        sprintf(path, "EXP1-500/EXP%i.XBM",currentCard);
+
+      
+
+//Serial.print("path ");
+Serial.println(path);
+
+
+    file.open(path, O_READ);
+
+    epd_power_flash_access(true);
+    for (;;) {
+      uint8_t buffer[16];
+      uint16_t count = 0;
+      for (int i = 0; i < sizeof(buffer); ++i, ++count) {
+        if (!xbm_parser(&buffer[i])) {
+          break;
+        }
+      }
+  
+      
+      FLASH.write_enable();
+      FLASH.write(address, buffer, count);
+      address += count;
+      if (sizeof(buffer) != count) {
+        break;
+      }
+  
+  }
+
+  file.close();
+
+}
+
+void displayCurrentImage( bool clean ) {
+
+  uint32_t address = 0;
+  address <<= 12;
+
+ //Serial.print("Displaying image at address ");
+ //Serial.println(address);
+    
+  EPD.begin();
+  if (!EPD) {
+     // Serial.print("---- EPD error = ");
+      Serial.print(EPD.error());
+      //Serial.println("");
+      return;
+  }
+  //int t = LM75.read();
+  EPD.setFactor(LM75.read());
+  
+  if ( clean ) {
+    
+    EPD.frame_cb_13(address, flash_read, EPD_inverse);
+    EPD.frame_stage2();
+    
+  }
+  
+  EPD.frame_cb_13(address, flash_read, EPD_normal);
+  EPD.end();
+}
+
+// I/O setup
+void setup() {
+  pinMode(Pin_RED_LED, OUTPUT);
+  pinMode(Pin_SW2, INPUT);
+  //pinMode(Pin_TEMPERATURE, INPUT);
+  //pinMode(Pin_PWM, OUTPUT);
+  pinMode(Pin_BUSY, INPUT);
+  pinMode(Pin_RESET, OUTPUT);
+  pinMode(Pin_PANEL_ON, OUTPUT);
+  pinMode(Pin_DISCHARGE, OUTPUT);
+  pinMode(Pin_BORDER, OUTPUT);
+  pinMode(Pin_EPD_CS, OUTPUT);
+  pinMode(Pin_FLASH_CS, OUTPUT);
+
+  digitalWrite(Pin_RED_LED, LOW);
+  //digitalWrite(Pin_PWM, LOW);  // not actually used - set low so can use current eval board unmodified
+  digitalWrite(Pin_RESET, LOW);
+  digitalWrite(Pin_PANEL_ON, LOW);
+  digitalWrite(Pin_DISCHARGE, LOW);
+  digitalWrite(Pin_BORDER, LOW);
+  digitalWrite(Pin_EPD_CS, LOW);
+  digitalWrite(Pin_FLASH_CS, HIGH);
+
+  Serial.begin(9600);
+
+
+if (!sd.begin(SD_CHIP_SELECT_PIN)) {
+    sd.initErrorHalt();
+  }
+
+    rtc.begin();
+
+    if (! rtc.isrunning())
+      // following line sets the RTC to the date & time this sketch was compiled
+      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
+
+/*  Serial.println();
+  Serial.println();
+  Serial.println("Command G2 version: " COMMAND_VERSION);
+  Serial.println("Display: " MAKE_STRING(EPD_SIZE));
+  Serial.println();*/
+
+  FLASH.begin(Pin_FLASH_CS);
+ // flash_info();
+
+  // configure temperature sensor
+  Wire.begin();
+  LM75.begin();
+
+
+/*
+  Serial.println("History:");
+
+  file.open("HIST.TXT", O_READ);
+  int data;
+  while ((data = file.read()) >= 0) {
+    Serial.write(data);
+  }
+  file.close();
+*/
+
+  char levelChar[4];
+  uint8_t nlevel=0;
+
+  Serial.print("Level: ");
+  file.open("LVL.TXT", O_READ);
+  while ((data = file.read()) >= 0) {
+    //Serial.write(data);
+    levelChar[nlevel++]=data;
+    //nlevel++;
+  }
+  file.close();
+  levelChar[nlevel]='\0';
+  level=atoi(levelChar);
+  Serial.println(level);
+
+
+  /*file.open("LVL.TXT", O_RDWR | O_CREAT );
+  file.rewind();
+  file.print("15");
+  file.close();*/
+
+  
+}
+
+// main loop
+void loop() {
+
+
+/*
+Analog read values for each resistor / button
+1023
+625
+277
+108
+
+*/
+
+
+  delay(25);
+
+  int option = analogRead(A0);
+  //Serial.println(option);
+
+  if ( option == 0 )
+    return;
+
+    if ( option > 1000 ) {
+      Serial.println("1");
+      pressButton(1);
+      delay(250);
+    }
+    else if ( option > 600 ) {
+      Serial.println("2");
+      pressButton(2);
+      delay(250);
+    }
+    else if ( option > 200 ) {
+      Serial.println("3");
+      pressButton(3);
+      delay(250);
+    }
+    else if ( option > 90 ) {
+      Serial.println("4");
+      pressButton(4);
+      delay(250);
+    }
+  
+  //Serial.println();
+  //Serial.print("C:");
+  //uint8_t c = Serial_getc();
+  //if (!isprint(c)) {
+  //  return;
+  //}
+  //Serial.write(c);
+  //Serial.println();
+  //switch (c) {
+
+   // case '1':pressButton(1);break;
+  //  case '2':pressButton(2);break;
+   // case '3':pressButton(3);break;
+  //  case '4':pressButton(4);break;
+    
+    
+    /*
+  case 'h':
+  case 'H':
+  case '?':
+    Serial.println();
+    Serial.println("h          - this command");
+    Serial.println("d<ss> <ll> - dump sector in hex, ll * 16 bytes");
+    Serial.println("e<ss>      - erase sector to 0xff");
+    Serial.println("u<ss>      - upload XBM to sector");
+    Serial.println("i<ss>      - display an image on white screen");
+    Serial.println("l          - search for non-empty sectors");
+    Serial.println("w          - clear screen to white");
+    Serial.println("f          - dump FLASH identification");
+    Serial.println("t          - show temperature");
+    break;*/
+/*
+  case 'd':
+  {
+    uint16_t sector = Serial_gethex(true);
+    Serial.print(' ');
+    uint16_t count = Serial_gethex(true);
+    if (0 == count) {
+      count = 1;
+    }
+    Serial.println();
+    Serial.print("sector: ");
+    Serial_puthex_byte(sector);
+    Serial.println();
+    uint32_t address = sector;
+    address <<= 12;
+    epd_power_flash_access(true);
+    for (uint16_t i = 0; i < count; ++i) {
+      uint8_t buffer[16];
+      FLASH.read(buffer, address, sizeof(buffer));
+      Serial_hex_dump(address, buffer, sizeof(buffer));
+      address += sizeof(buffer);
+    }
+    epd_power_flash_access(false);
+    break;
+  }
+
+  case 'e':
+  {
+    uint32_t sector = Serial_gethex(true);
+    epd_power_flash_access(true);
+    FLASH.write_enable();
+    FLASH.sector_erase(sector << 12);
+    FLASH.write_disable();
+    epd_power_flash_access(false);
+    break;
+  }
+
+  case 'u':
+  {
+    uint32_t address = Serial_gethex(true);
+    address <<= 12;
+    xbm_count = 0;
+    Serial.println();
+    Serial.println("start upload...");
+
+
+    char path[25];
+
+    if ( currentCard > 2000 )
+      String("2001-2500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
+
+    else if ( currentCard > 1500 )
+      String("1501-2000/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
+
+    else if ( currentCard > 1000 )
+      String("1001-1500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
+
+    else if ( currentCard > 500 )
+      String("501-1000/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
+
+    else
+      String("1-500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
+
+
+    file.open(path, O_READ);
+
+    currentCard++;
+
+     // if (!file.open("1-500/CARD100.XBM", O_READ)) {
+  //  sd.errorHalt(F("open XBM file failed"));
+    //}
+
+    epd_power_flash_access(true);
+    for (;;) {
+      uint8_t buffer[16];
+      uint16_t count = 0;
+      for (int i = 0; i < sizeof(buffer); ++i, ++count) {
+        if (!xbm_parser(&buffer[i])) {
+          break;
+        }
+      }
+
+  
+      
+      FLASH.write_enable();
+      FLASH.write(address, buffer, count);
+      address += count;
+      if (sizeof(buffer) != count) {
+        break;
+      }
+    }
+
+    FLASH.write_disable();
+    epd_power_flash_access(false);
+
+    Serial.println();
+    Serial.print(" read = ");
+    Serial_puthex_word(xbm_count);
+    if (128 * 96 / 8 == xbm_count) {
+      Serial.print(" 128x96 1.44");
+    } else if (200 * 96 / 8 == xbm_count) {
+      Serial.print(" 200x96 2.0");
+    } else if (264L * 176 / 8 == xbm_count) {
+      Serial.print(" 264x176 2.7");
+    } else {
+      Serial.print(" invalid image");
+    }
+    Serial.println();
+    file.close();
+    break;
+  }
+
+  case 'i':
+  {
+    uint32_t address = Serial_gethex(true);
+    address <<= 12;
+    EPD.begin();
+    if (!EPD) {
+      Serial.print("EPD error = ");
+      Serial.print(EPD.error());
+      Serial.println("");
+      break;
+    }
+    int t = LM75.read();
+    EPD.setFactor(t);
+    EPD.frame_cb_13(address, flash_read, EPD_inverse);
+    EPD.frame_stage2();
+    EPD.frame_cb_13(address, flash_read, EPD_normal);
+    EPD.end();
+    break;
+  }
+
+  case 'l':
+  {
+    Serial.println();
+    uint16_t per_line = 0;
+    for (uint16_t sector = 0; sector <= 0xff; ++sector) {
+      for (uint16_t i = 0; i < 4096; i += 16) {
+        uint8_t buffer[16];
+        uint32_t address = sector;
+        address <<= 12;
+        address += i;
+        FLASH.read(buffer, address, sizeof(buffer));
+        bool flag = false;
+        for (uint16_t j = 0; j < sizeof(buffer); ++j) {
+          if (0xff != buffer[j]) {
+            flag = true;
+            break;
+          }
+        }
+        if (flag) {
+          Serial_puthex_byte(sector);
+          if (++per_line >= 16) {
+            Serial.println();
+            per_line = 0;
+          } else {
+            Serial.print(' ');
+          }
+          break;
+        }
+      }
+
+    }
+    if (0 != per_line) {
+      Serial.println();
+    }
+    break;
+  }
+
+  case 'f':
+  {
+    Serial.println();
+    flash_info();
+    break;
+  }
+
+  case 'w':
+  {
+    EPD.begin();
+    if (!EPD) {
+      Serial.print("EPD error = ");
+      Serial.print(EPD.error());
+      Serial.println("");
+      break;
+    }
+
+    int t = LM75.read();
+    EPD.setFactor(t);
+    EPD.clear();
+    EPD.end();
+    break;
+  }*/
+
+ /* case 't':
+  {
+    Serial.println();
+    Serial.print("Temperature = ");
+    Serial.print(LM75.read());
+    Serial.print(" Celcius");
+    Serial.println();
+
+    break;
+  }*/
+
+ // default:
+  //  Serial.println();
+    //Serial.println("error");
+
+  //}
+}
+
+
+static void epd_power_flash_access(bool state) {
+  if (state) {
+    // turn on panel, but hold reset to prevent SPI loading
+    digitalWrite(Pin_RESET, HIGH);
+    digitalWrite(Pin_EPD_CS, HIGH);
+    digitalWrite(Pin_PANEL_ON, HIGH);
+  } else {
+    // turn off panel, after FLASH access
+    digitalWrite(Pin_RESET, LOW);
+    digitalWrite(Pin_EPD_CS, LOW);
+    digitalWrite(Pin_PANEL_ON, LOW);
+  }
+}
+/*
+static void flash_info(void) {
+  uint8_t maufacturer;
+  uint16_t device;
+
+  epd_power_flash_access(true);
+
+  if (FLASH.available()) {
+    Serial.println("FLASH chip detected OK");
+  } else {
+    Serial.println("unsupported FLASH chip");
+  }
+
+  FLASH.info(&maufacturer, &device);
+  Serial.print("FLASH: manufacturer = ");
+  Serial_puthex_byte(maufacturer);
+  Serial.print(" device = ");
+  Serial_puthex_word(device);
+  Serial.println();
+
+  epd_power_flash_access(false);
+}
+*/
+
+static void flash_read(void *buffer, uint32_t address, uint16_t length) {
+  FLASH.read(buffer, address, length);
+}
+
+
+static bool xbm_parser(uint8_t *b) {
+  for (;;) {
+    //Serial.println(xbm_count);
+    uint8_t c = Serial_getcc();
+    if ('0' == c && 'x' == Serial_getcc()) {
+      *b = Serial_gethexx(false);
+      ++xbm_count;
+      if (0 == (xbm_count & 0x07)) {
+        digitalWrite(Pin_RED_LED, !digitalRead(Pin_RED_LED));
+      }
+      return true;
+    } else if (';' == c) {
+      break;
+    }
+
+    
+  }
+  digitalWrite(Pin_RED_LED, LED_OFF);
+  return false;
+}
+
+
+// miscellaneous serial interface routines
+
+static uint8_t Serial_getc() {
+  while (0 == Serial.available()) {
+  }
+  return Serial.read();
+}
+
+
+/*
+static uint16_t Serial_gethex(bool echo) {
+  uint16_t acc = 0;
+  for (;;) {
+
+    uint8_t c = Serial_getc();
+
+    if (c >= '0' && c <= '9') {
+      c -= '0';
+    } else if (c >= 'a' && c <= 'f') {
+      c -= 'a' - 10;
+    } else if (c >= 'A' && c <= 'F') {
+      c -= 'A' - 10;
+    } else {
+      return acc;
+    }
+    if (echo) {
+      Serial_puthex(c, 4);
+    }
+    acc <<= 4;
+    acc += c;
+  }
+}
+*/
+
+/*
+static void Serial_puthex(uint32_t n, int bits) {
+  for (int i = bits - 4; i >= 0; i -= 4) {
+    char nibble = ((n >> i) & 0x0f) + '0';
+    if (nibble > '9') {
+      nibble += 'a' - '9' - 1;
+    }
+    Serial.print(nibble);
+  }
+}
+
+
+static void Serial_puthex_byte(uint8_t n) {
+  Serial_puthex(n, 8);
+}
+
+
+static void Serial_puthex_word(uint16_t n) {
+  Serial_puthex(n, 16);
+}
+
+
+static void Serial_puthex_double(uint32_t n) {
+  Serial_puthex(n, 32);
+}
+*/
+
diff --git a/code/softspi_eink/softspi_eink.ino/softspi_eink.ino.ino b/code/softspi_eink/softspi_eink.ino/softspi_eink.ino.ino
deleted file mode 100644 (file)
index a2238bc..0000000
+++ /dev/null
@@ -1,885 +0,0 @@
-// -*- mode: c++ -*-
-// Copyright 2013 Pervasive Displays, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at:
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-// express or implied.  See the License for the specific language
-// governing permissions and limitations under the License.
-
-
-// An example of the SdFatSoftSpi template class.
-// This example is for an Adafruit Data Logging Shield on a Mega.
-// Software SPI is required on Mega since this shield connects to pins 10-13.
-// This example will also run on an Uno and other boards using software SPI.
-//
-
-#include "RTClib.h"
-
-RTC_DS1307 rtc;
-
-#include <SPI.h>
-#include "SdFat.h"
-//
-// Pin numbers in templates must be constants.
-const uint8_t SOFT_MISO_PIN = A2;
-const uint8_t SOFT_MOSI_PIN = A3;
-const uint8_t SOFT_SCK_PIN  = 2;
-//
-// Chip select may be constant or RAM variable.
-const uint8_t SD_CHIP_SELECT_PIN = 3;
-
-// SdFat software SPI template
-SdFatSoftSpi<SOFT_MISO_PIN, SOFT_MOSI_PIN, SOFT_SCK_PIN> sd;
-
-// Test file.
-SdFile file;
-
-
-
-
-#include <Arduino.h>
-#include <inttypes.h>
-#include <ctype.h>
-
-// required libraries
-#include <SPI.h>
-#include <FLASH.h>
-#include <EPD2.h>
-#include <Wire.h>
-#include <LM75.h>
-
-// Change this for different display size
-// supported sizes: 144 200 270
-#define SCREEN_SIZE 270
-
-
-// no futher changed below this point
-
-// set up images from screen size2
-#if (SCREEN_SIZE == 144)
-#define EPD_SIZE EPD_1_44
-#define SECTORS_USED 1
-
-#elif (SCREEN_SIZE == 200)
-#define EPD_SIZE EPD_2_0
-#define SECTORS_USED 1
-
-#elif (SCREEN_SIZE == 270)
-#define EPD_SIZE EPD_2_7
-#define SECTORS_USED 2
-
-#else
-#error "Unknown EPB size: Change the #define SCREEN_SIZE to a supported value"
-#endif
-
-#define COMMAND_VERSION "1"
-
-
-// Arduino IO layout
-//const int Pin_TEMPERATURE = A0; // Temperature is handled by LM75 over I2C and not an analog pin
-const uint8_t Pin_PANEL_ON = 5;
-const uint8_t Pin_BORDER = 10;
-const uint8_t Pin_DISCHARGE = 4;
-//const int Pin_PWM = 5;    // Not used by COG v2
-const uint8_t Pin_RESET = 6;
-const uint8_t Pin_BUSY = 7;
-const uint8_t Pin_EPD_CS = 8;
-const uint8_t Pin_FLASH_CS = 9;
-const uint8_t Pin_SW2 = 12;
-const uint8_t Pin_RED_LED = 13;
-
-
-// LED anode through resistor to I/O pin
-// LED cathode to Ground
-#define LED_ON  HIGH
-#define LED_OFF LOW
-
-// pre-processor convert to string
-#define MAKE_STRING1(X) #X
-#define MAKE_STRING(X) MAKE_STRING1(X)
-
-
-// function prototypes
-static void epd_power_flash_access(bool state);
-//static void flash_info(void);
-static void flash_read(void *buffer, uint32_t address, uint16_t length);
-
-static uint16_t xbm_count;
-static bool xbm_parser(uint8_t *b);
-
-
-static uint8_t Serial_getc();
-static uint16_t Serial_gethex(bool echo);
-static void Serial_puthex(uint32_t n, int bits);
-static void Serial_puthex_byte(uint8_t n);
-static void Serial_puthex_word(uint16_t n);
-static void Serial_puthex_double(uint32_t n);
-//static void Serial_hex_dump(uint32_t address, const void *buffer, uint16_t length);
-void displayCurrentImage();
-
-
-// define the E-Ink display
-EPD_Class EPD(EPD_SIZE, Pin_PANEL_ON, Pin_BORDER, Pin_DISCHARGE, Pin_RESET, Pin_BUSY, Pin_EPD_CS);
-
-
-static uint8_t Serial_getcc() {
-
-    while (file.available() == false) {
-    }
-
-    char readed;
-    //int result=
-    file.read(&readed,1);
-    
-    //Serial.print("Result: ");
-    //Serial.println(result);
-
-    //Serial.print("Readed: ");
-    //Serial.print((char)readed);
-
-    //FatPos_t position;
-
-    //file.getpos(&position);
-
-    //Serial.print("Position: ");
-    //Serial.println(position.position);
-
-    return readed;
-
-
-}
-
-
-static uint16_t Serial_gethexx(bool echo) {
-  uint16_t acc = 0;
-  for (;;) {
-
-    uint8_t c = Serial_getcc();
-
-    if (c >= '0' && c <= '9') {
-      c -= '0';
-    } else if (c >= 'a' && c <= 'f') {
-      c -= 'a' - 10;
-    } else if (c >= 'A' && c <= 'F') {
-      c -= 'A' - 10;
-    } else {
-      return acc;
-    }
-    if (echo) {
-      Serial_puthex(c, 4);
-    }
-    acc <<= 4;
-    acc += c;
-  }
-}
-
-
-
-uint16_t currentCard=1; // 1-2499
-uint16_t level=10;
-bool currentType=0; // 0 = card; 1 = exp
-         
-
-void eraseSector(uint32_t sector) {
-  //Serial.println("Erasing sector " + String(sector) );
-//  uint32_t sector = Serial_gethex(true);
-  epd_power_flash_access(true);
-  FLASH.write_enable();
-  FLASH.sector_erase(sector << 12);
-  FLASH.write_disable();
-  epd_power_flash_access(false);
-}
-
-void storeHistory() {
-
-    DateTime now = rtc.now();
-
-    file.open("HIST.TXT", O_RDWR | O_CREAT | O_AT_END);
-    file.print(now.unixtime());
-    file.print(" ");
-    file.println(currentCard);
-    file.close();
-  
-}
-
-void pressButton(uint8_t num) {
-
-// 1 - RANDOM
-// 2 - EXPLAIN
-// 3 - NEXT
-// 4 - PREV
-
-eraseSector(0);
-eraseSector(1);
-int rndcard;
-
-  switch (num) {
-
-      case 1:
-
-        randomSeed(millis());
-        //currentCard=random(1,1499);
-
-        do rndcard=random(1,level);
-        while (rndcard == currentCard);
-                
-        currentCard=rndcard;
-        currentType=0;
-
-        storeHistory();
-
-
-      break;
-
-      case 2:
-
-        currentType=!currentType;
-
-      break;
-
-      case 3:
-
-        //if ( currentCard < 1499 )
-        if ( currentCard < level )
-          currentCard++;
-        else
-          currentCard=1;
-          
-        currentType=0;
-        storeHistory();
-
-      break;
-
-      case 4:
-
-        if ( currentCard >1 )
-          currentCard--;
-          else
-          currentCard=level;
-          //currentCard=2499;
-          
-        currentType=0;
-        storeHistory();
-
-      break;
-    
-  }
-
-      uploadCurrentImage();
-      //displayCurrentImage(currentType);
-      displayCurrentImage(0);
-
-  
-}
-
-void uploadCurrentImage() {
-
-
-    int32_t address = 0;
-
-    address <<= 12;
-    xbm_count = 0;
-    //Serial.println();
-    //Serial.println("start upload...");
-
-
-    char path[22];
-
-   if ( currentCard > 2000 )
-      if (!currentType)
-        sprintf(path, "2001-2500/CARD%i.XBM",currentCard);
-      else
-        sprintf(path, "EXP2001-2500/EXP%i.XBM",currentCard);
-
-    else if ( currentCard > 1500 )
-     if (!currentType)
-      sprintf(path, "1501-2000/CARD%i.XBM",currentCard);
-      else
-        sprintf(path, "EXP1501-2000/EXP%i.XBM",currentCard);
-
-    else if ( currentCard > 1000 )
-     if (!currentType)
-      sprintf(path, "1001-1500/CARD%i.XBM",currentCard);
-      else
-        sprintf(path, "EXP1001-1500/EXP%i.XBM",currentCard);
-
-    else if ( currentCard > 500 )
-      if (!currentType)
-      sprintf(path, "501-1000/CARD%i.XBM",currentCard);
-      else
-        sprintf(path, "EXP501-1000/EXP%i.XBM",currentCard);
-    else
-     if (!currentType)
-      sprintf(path, "1-500/CARD%i.XBM",currentCard);
-      else
-        sprintf(path, "EXP1-500/EXP%i.XBM",currentCard);
-
-      
-
-//Serial.print("path ");
-Serial.println(path);
-
-
-    file.open(path, O_READ);
-
-    epd_power_flash_access(true);
-    for (;;) {
-      uint8_t buffer[16];
-      uint16_t count = 0;
-      for (int i = 0; i < sizeof(buffer); ++i, ++count) {
-        if (!xbm_parser(&buffer[i])) {
-          break;
-        }
-      }
-  
-      
-      FLASH.write_enable();
-      FLASH.write(address, buffer, count);
-      address += count;
-      if (sizeof(buffer) != count) {
-        break;
-      }
-  
-  }
-
-  file.close();
-
-}
-
-void displayCurrentImage( bool clean ) {
-
-  uint32_t address = 0;
-  address <<= 12;
-
- //Serial.print("Displaying image at address ");
- //Serial.println(address);
-    
-  EPD.begin();
-  if (!EPD) {
-     // Serial.print("---- EPD error = ");
-      Serial.print(EPD.error());
-      //Serial.println("");
-      return;
-  }
-  //int t = LM75.read();
-  EPD.setFactor(LM75.read());
-  
-  if ( clean ) {
-    
-    EPD.frame_cb_13(address, flash_read, EPD_inverse);
-    EPD.frame_stage2();
-    
-  }
-  
-  EPD.frame_cb_13(address, flash_read, EPD_normal);
-  EPD.end();
-}
-
-// I/O setup
-void setup() {
-  pinMode(Pin_RED_LED, OUTPUT);
-  pinMode(Pin_SW2, INPUT);
-  //pinMode(Pin_TEMPERATURE, INPUT);
-  //pinMode(Pin_PWM, OUTPUT);
-  pinMode(Pin_BUSY, INPUT);
-  pinMode(Pin_RESET, OUTPUT);
-  pinMode(Pin_PANEL_ON, OUTPUT);
-  pinMode(Pin_DISCHARGE, OUTPUT);
-  pinMode(Pin_BORDER, OUTPUT);
-  pinMode(Pin_EPD_CS, OUTPUT);
-  pinMode(Pin_FLASH_CS, OUTPUT);
-
-  digitalWrite(Pin_RED_LED, LOW);
-  //digitalWrite(Pin_PWM, LOW);  // not actually used - set low so can use current eval board unmodified
-  digitalWrite(Pin_RESET, LOW);
-  digitalWrite(Pin_PANEL_ON, LOW);
-  digitalWrite(Pin_DISCHARGE, LOW);
-  digitalWrite(Pin_BORDER, LOW);
-  digitalWrite(Pin_EPD_CS, LOW);
-  digitalWrite(Pin_FLASH_CS, HIGH);
-
-  Serial.begin(9600);
-
-
-if (!sd.begin(SD_CHIP_SELECT_PIN)) {
-    sd.initErrorHalt();
-  }
-
-    rtc.begin();
-
-    if (! rtc.isrunning())
-      // following line sets the RTC to the date & time this sketch was compiled
-      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
-
-/*  Serial.println();
-  Serial.println();
-  Serial.println("Command G2 version: " COMMAND_VERSION);
-  Serial.println("Display: " MAKE_STRING(EPD_SIZE));
-  Serial.println();*/
-
-  FLASH.begin(Pin_FLASH_CS);
- // flash_info();
-
-  // configure temperature sensor
-  Wire.begin();
-  LM75.begin();
-
-
-/*
-  Serial.println("History:");
-
-  file.open("HIST.TXT", O_READ);
-  int data;
-  while ((data = file.read()) >= 0) {
-    Serial.write(data);
-  }
-  file.close();
-*/
-
-  char levelChar[4];
-  uint8_t nlevel=0;
-
-  Serial.print("Level: ");
-  file.open("LVL.TXT", O_READ);
-  while ((data = file.read()) >= 0) {
-    //Serial.write(data);
-    levelChar[nlevel++]=data;
-    //nlevel++;
-  }
-  file.close();
-  levelChar[nlevel]='\0';
-  level=atoi(levelChar);
-  Serial.println(level);
-
-
-  /*file.open("LVL.TXT", O_RDWR | O_CREAT );
-  file.rewind();
-  file.print("15");
-  file.close();*/
-
-  
-}
-
-// main loop
-void loop() {
-
-
-/*
-Analog read values for each resistor / button
-1023
-625
-277
-108
-
-*/
-
-
-  delay(25);
-
-  int option = analogRead(A0);
-  //Serial.println(option);
-
-  if ( option == 0 )
-    return;
-
-    if ( option > 1000 ) {
-      Serial.println("1");
-      pressButton(1);
-      delay(250);
-    }
-    else if ( option > 600 ) {
-      Serial.println("2");
-      pressButton(2);
-      delay(250);
-    }
-    else if ( option > 200 ) {
-      Serial.println("3");
-      pressButton(3);
-      delay(250);
-    }
-    else if ( option > 90 ) {
-      Serial.println("4");
-      pressButton(4);
-      delay(250);
-    }
-  
-  //Serial.println();
-  //Serial.print("C:");
-  //uint8_t c = Serial_getc();
-  //if (!isprint(c)) {
-  //  return;
-  //}
-  //Serial.write(c);
-  //Serial.println();
-  //switch (c) {
-
-   // case '1':pressButton(1);break;
-  //  case '2':pressButton(2);break;
-   // case '3':pressButton(3);break;
-  //  case '4':pressButton(4);break;
-    
-    
-    /*
-  case 'h':
-  case 'H':
-  case '?':
-    Serial.println();
-    Serial.println("h          - this command");
-    Serial.println("d<ss> <ll> - dump sector in hex, ll * 16 bytes");
-    Serial.println("e<ss>      - erase sector to 0xff");
-    Serial.println("u<ss>      - upload XBM to sector");
-    Serial.println("i<ss>      - display an image on white screen");
-    Serial.println("l          - search for non-empty sectors");
-    Serial.println("w          - clear screen to white");
-    Serial.println("f          - dump FLASH identification");
-    Serial.println("t          - show temperature");
-    break;*/
-/*
-  case 'd':
-  {
-    uint16_t sector = Serial_gethex(true);
-    Serial.print(' ');
-    uint16_t count = Serial_gethex(true);
-    if (0 == count) {
-      count = 1;
-    }
-    Serial.println();
-    Serial.print("sector: ");
-    Serial_puthex_byte(sector);
-    Serial.println();
-    uint32_t address = sector;
-    address <<= 12;
-    epd_power_flash_access(true);
-    for (uint16_t i = 0; i < count; ++i) {
-      uint8_t buffer[16];
-      FLASH.read(buffer, address, sizeof(buffer));
-      Serial_hex_dump(address, buffer, sizeof(buffer));
-      address += sizeof(buffer);
-    }
-    epd_power_flash_access(false);
-    break;
-  }
-
-  case 'e':
-  {
-    uint32_t sector = Serial_gethex(true);
-    epd_power_flash_access(true);
-    FLASH.write_enable();
-    FLASH.sector_erase(sector << 12);
-    FLASH.write_disable();
-    epd_power_flash_access(false);
-    break;
-  }
-
-  case 'u':
-  {
-    uint32_t address = Serial_gethex(true);
-    address <<= 12;
-    xbm_count = 0;
-    Serial.println();
-    Serial.println("start upload...");
-
-
-    char path[25];
-
-    if ( currentCard > 2000 )
-      String("2001-2500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
-
-    else if ( currentCard > 1500 )
-      String("1501-2000/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
-
-    else if ( currentCard > 1000 )
-      String("1001-1500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
-
-    else if ( currentCard > 500 )
-      String("501-1000/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
-
-    else
-      String("1-500/CARD"+String(currentCard)+".XBM").toCharArray(path,25);
-
-
-    file.open(path, O_READ);
-
-    currentCard++;
-
-     // if (!file.open("1-500/CARD100.XBM", O_READ)) {
-  //  sd.errorHalt(F("open XBM file failed"));
-    //}
-
-    epd_power_flash_access(true);
-    for (;;) {
-      uint8_t buffer[16];
-      uint16_t count = 0;
-      for (int i = 0; i < sizeof(buffer); ++i, ++count) {
-        if (!xbm_parser(&buffer[i])) {
-          break;
-        }
-      }
-
-  
-      
-      FLASH.write_enable();
-      FLASH.write(address, buffer, count);
-      address += count;
-      if (sizeof(buffer) != count) {
-        break;
-      }
-    }
-
-    FLASH.write_disable();
-    epd_power_flash_access(false);
-
-    Serial.println();
-    Serial.print(" read = ");
-    Serial_puthex_word(xbm_count);
-    if (128 * 96 / 8 == xbm_count) {
-      Serial.print(" 128x96 1.44");
-    } else if (200 * 96 / 8 == xbm_count) {
-      Serial.print(" 200x96 2.0");
-    } else if (264L * 176 / 8 == xbm_count) {
-      Serial.print(" 264x176 2.7");
-    } else {
-      Serial.print(" invalid image");
-    }
-    Serial.println();
-    file.close();
-    break;
-  }
-
-  case 'i':
-  {
-    uint32_t address = Serial_gethex(true);
-    address <<= 12;
-    EPD.begin();
-    if (!EPD) {
-      Serial.print("EPD error = ");
-      Serial.print(EPD.error());
-      Serial.println("");
-      break;
-    }
-    int t = LM75.read();
-    EPD.setFactor(t);
-    EPD.frame_cb_13(address, flash_read, EPD_inverse);
-    EPD.frame_stage2();
-    EPD.frame_cb_13(address, flash_read, EPD_normal);
-    EPD.end();
-    break;
-  }
-
-  case 'l':
-  {
-    Serial.println();
-    uint16_t per_line = 0;
-    for (uint16_t sector = 0; sector <= 0xff; ++sector) {
-      for (uint16_t i = 0; i < 4096; i += 16) {
-        uint8_t buffer[16];
-        uint32_t address = sector;
-        address <<= 12;
-        address += i;
-        FLASH.read(buffer, address, sizeof(buffer));
-        bool flag = false;
-        for (uint16_t j = 0; j < sizeof(buffer); ++j) {
-          if (0xff != buffer[j]) {
-            flag = true;
-            break;
-          }
-        }
-        if (flag) {
-          Serial_puthex_byte(sector);
-          if (++per_line >= 16) {
-            Serial.println();
-            per_line = 0;
-          } else {
-            Serial.print(' ');
-          }
-          break;
-        }
-      }
-
-    }
-    if (0 != per_line) {
-      Serial.println();
-    }
-    break;
-  }
-
-  case 'f':
-  {
-    Serial.println();
-    flash_info();
-    break;
-  }
-
-  case 'w':
-  {
-    EPD.begin();
-    if (!EPD) {
-      Serial.print("EPD error = ");
-      Serial.print(EPD.error());
-      Serial.println("");
-      break;
-    }
-
-    int t = LM75.read();
-    EPD.setFactor(t);
-    EPD.clear();
-    EPD.end();
-    break;
-  }*/
-
- /* case 't':
-  {
-    Serial.println();
-    Serial.print("Temperature = ");
-    Serial.print(LM75.read());
-    Serial.print(" Celcius");
-    Serial.println();
-
-    break;
-  }*/
-
- // default:
-  //  Serial.println();
-    //Serial.println("error");
-
-  //}
-}
-
-
-static void epd_power_flash_access(bool state) {
-  if (state) {
-    // turn on panel, but hold reset to prevent SPI loading
-    digitalWrite(Pin_RESET, HIGH);
-    digitalWrite(Pin_EPD_CS, HIGH);
-    digitalWrite(Pin_PANEL_ON, HIGH);
-  } else {
-    // turn off panel, after FLASH access
-    digitalWrite(Pin_RESET, LOW);
-    digitalWrite(Pin_EPD_CS, LOW);
-    digitalWrite(Pin_PANEL_ON, LOW);
-  }
-}
-/*
-static void flash_info(void) {
-  uint8_t maufacturer;
-  uint16_t device;
-
-  epd_power_flash_access(true);
-
-  if (FLASH.available()) {
-    Serial.println("FLASH chip detected OK");
-  } else {
-    Serial.println("unsupported FLASH chip");
-  }
-
-  FLASH.info(&maufacturer, &device);
-  Serial.print("FLASH: manufacturer = ");
-  Serial_puthex_byte(maufacturer);
-  Serial.print(" device = ");
-  Serial_puthex_word(device);
-  Serial.println();
-
-  epd_power_flash_access(false);
-}
-*/
-
-static void flash_read(void *buffer, uint32_t address, uint16_t length) {
-  FLASH.read(buffer, address, length);
-}
-
-
-static bool xbm_parser(uint8_t *b) {
-  for (;;) {
-    //Serial.println(xbm_count);
-    uint8_t c = Serial_getcc();
-    if ('0' == c && 'x' == Serial_getcc()) {
-      *b = Serial_gethexx(false);
-      ++xbm_count;
-      if (0 == (xbm_count & 0x07)) {
-        digitalWrite(Pin_RED_LED, !digitalRead(Pin_RED_LED));
-      }
-      return true;
-    } else if (';' == c) {
-      break;
-    }
-
-    
-  }
-  digitalWrite(Pin_RED_LED, LED_OFF);
-  return false;
-}
-
-
-// miscellaneous serial interface routines
-
-static uint8_t Serial_getc() {
-  while (0 == Serial.available()) {
-  }
-  return Serial.read();
-}
-
-
-/*
-static uint16_t Serial_gethex(bool echo) {
-  uint16_t acc = 0;
-  for (;;) {
-
-    uint8_t c = Serial_getc();
-
-    if (c >= '0' && c <= '9') {
-      c -= '0';
-    } else if (c >= 'a' && c <= 'f') {
-      c -= 'a' - 10;
-    } else if (c >= 'A' && c <= 'F') {
-      c -= 'A' - 10;
-    } else {
-      return acc;
-    }
-    if (echo) {
-      Serial_puthex(c, 4);
-    }
-    acc <<= 4;
-    acc += c;
-  }
-}
-*/
-
-/*
-static void Serial_puthex(uint32_t n, int bits) {
-  for (int i = bits - 4; i >= 0; i -= 4) {
-    char nibble = ((n >> i) & 0x0f) + '0';
-    if (nibble > '9') {
-      nibble += 'a' - '9' - 1;
-    }
-    Serial.print(nibble);
-  }
-}
-
-
-static void Serial_puthex_byte(uint8_t n) {
-  Serial_puthex(n, 8);
-}
-
-
-static void Serial_puthex_word(uint16_t n) {
-  Serial_puthex(n, 16);
-}
-
-
-static void Serial_puthex_double(uint32_t n) {
-  Serial_puthex(n, 32);
-}
-*/
-