/*
  Name:    PhotometerPRO.ino
  Author:  Roman Schönfeld & Daniel Hausherr
*/

/***********************************************************************************************
  This work is licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) License.

  You are free to:

  Share — copy and redistribute the material in any medium or format
  Adapt — remix, transform, and build upon the material
  for any purpose, even commercially.

  The licensor cannot revoke these freedoms as long as you follow the license terms.

  Under the following terms:

  Attribution — You must give appropriate credit, provide a link to the license, and indicate if
  changes were made. You may do so in any reasonable manner, but not in any way that suggests
  the licensor endorses you or your use.

  No additional restrictions — You may not apply legal terms or technological measures that
  legally restrict others from doing anything the license permits.

  Credits:
  Laboratory for Physics and Illumination Technologies,
  University of Applied Sciences Southern Westfalia
  Germany

  Make Light! Support by the BMBF in the development of this device is gratefully acknowledged
***************************************************************************************************/
#include "Display.h"
#include "SauronPlus.h"

// Declare Variables
io_expander             current_io;
integrationTime         current_time;
attenuation             current_attenuation;

volatile uint8_t count_for_ready_pin = 0;
volatile bool ready_pin_state_high = false;

void readyPinRising () {
  ready_pin_state_high = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(_READY_PIN, INPUT);

  pinMode(_SW_EN, OUTPUT);
  pinMode(_SW_A0, OUTPUT);
  pinMode(_SW_A1, OUTPUT);
  pinMode(_BL, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(_READY_PIN), readyPinRising, RISING);

  // Initialisiere Display
  init_tft();

  // Initialisiere I2C Bus
  init_device();

  set_brightness_tft(_TFT_BRIGHTNESS_HIGH);

  set_text_size_tft(2);
  set_cursor_tft(64, 55);
  print_text_tft((char*)".", WHITE);
}

void loop() {
  Serial.println(current_attenuation);
  static int16_t digits[] = {0, 0, 0, 0, 0, 0};
  static int16_t prevDigits[] = { -1, -1, -1, -1, -1, -1};
  static uint16_t digitPos[] = {32, 44, 56, 74, 86, 98};
  static double current_in_microa = 0.0d, tmp_digit = 0.0d;
  static int MeasurementValueUnit = -1, PrevMeasurementValueUnit = -1;
  static float TMP_MeasurementValue = 0.f;

  // auto range
  define_matching_range();

  if ((get_value_in_current(&current_in_microa) == 0))
  {
    for(MeasurementValueUnit=-6;MeasurementValueUnit<=15;MeasurementValueUnit+=3)
    {
      TMP_MeasurementValue = current_in_microa * pow(10, MeasurementValueUnit);
      if(TMP_MeasurementValue > 1)
        break;
    }

    digits[0] = (int16_t)(TMP_MeasurementValue / 100.0d);
    tmp_digit = (double)digits[0] * 100.0d;

    digits[1] = (int16_t)((TMP_MeasurementValue - tmp_digit) / 10.0d);
    tmp_digit = tmp_digit + ((double)digits[1] * 10.0d);

    digits[2] = (int16_t)(TMP_MeasurementValue - tmp_digit);
    tmp_digit = tmp_digit + (double)digits[2];

    digits[3] = (int16_t)((TMP_MeasurementValue - tmp_digit) * 10.0d);
    tmp_digit = tmp_digit + ((double)digits[3] / 10.0d);

    digits[4] = (int16_t)((TMP_MeasurementValue - tmp_digit) * 100.0d);
    tmp_digit = tmp_digit + ((double)digits[4] / 100.0d);
    
    digits[5] = (int16_t)((TMP_MeasurementValue - tmp_digit) * 1000.0d);
    
    for (uint8_t i = 0; i < 6; i++)
    {
      if ((prevDigits[i] != digits[i]))
      {
        set_cursor_tft(digitPos[i], 55);

        if (prevDigits[i] != -1)
        {
          print_value_tft(prevDigits[i], BLACK);
          set_cursor_tft(digitPos[i], 55);
        }

        print_value_tft(prevDigits[i] = digits[i], WHITE);
      }
    }
    
    if(PrevMeasurementValueUnit != MeasurementValueUnit)
    {
      set_cursor_tft(112, 55);
      switch (PrevMeasurementValueUnit)
      {
        case -6: print_text_tft(" A", BLACK); break;
        case -3: print_text_tft("mA", BLACK); break;
        case  0: print_text_tft("uA", BLACK); break;
        case  3: print_text_tft("nA", BLACK); break;
        case  6: print_text_tft("pA", BLACK); break;
        case  9: print_text_tft("fA", BLACK); break;
        default: print_text_tft("--", BLACK); break;
      }
  
      set_cursor_tft(112, 55);
      switch (PrevMeasurementValueUnit = MeasurementValueUnit)
      {
        case -6: print_text_tft(" A", RED); break;
        case -3: print_text_tft("mA", RED); break;
        case  0: print_text_tft("uA", RED); break;
        case  3: print_text_tft("nA", RED); break;
        case  6: print_text_tft("pA", RED); break;
        case  9: print_text_tft("fA", RED); break;
        default: print_text_tft("--", RED); break;
      }
    }
  }

  delay(1000);
}
