#include <Wire.h>
#include <pgmspace.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include "fonts.h"
#include "flmuke.h"

#define TFT_CS         D8
#define TFT_RST        D4                                            
#define TFT_DC         D3
#define TFT_BL         D0

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

#define WHITE    0xFFFF
#define BLACK    0x0000
#define ORANGE   0xFBE0

int backlight[5] = {10,30,60,160,220};
byte br=3;

long raw = 0;

double Volts=0;
double resolution=0;

#define ADS1115_I2C_ADDRESS_GND         0x48  // address pin low (GND)
#define ADS1115_I2C_ADDRESS_VDD         0x49  // address pin high (VCC)
#define ADS1115_I2C_ADDRESS_SDA         0x4A  // address pin tied to SDA pin
#define ADS1115_I2C_ADDRESS_SCL         0x4B  // address pin tied to SCL pin
#define ADS1115_I2C_ADDRESS             ADS1115_I2C_ADDRESS_GND

#define ADS1115_ALERT                   D6

#define ADS1115_RA_CONVERSION           0x00
#define ADS1115_RA_CONFIG               0x01
#define ADS1115_RA_LO_THRESH            0x02
#define ADS1115_RA_HI_THRESH            0x03

#define ADS1115_MUX_P0_N1               0b0000000000000000 // default
#define ADS1115_MUX_P0_N3               0b0001000000000000
#define ADS1115_MUX_P1_N3               0b0010000000000000
#define ADS1115_MUX_P2_N3               0b0011000000000000
#define ADS1115_MUX_P0_NG               0b0100000000000000
#define ADS1115_MUX_P1_NG               0b0101000000000000
#define ADS1115_MUX_P2_NG               0b0110000000000000
#define ADS1115_MUX_P3_NG               0b0111000000000000

#define ADS1115_PGA_6144MV              0b0000000000000000
#define ADS1115_PGA_4096MV              0b0000001000000000
#define ADS1115_PGA_2048MV              0b0000010000000000 // default
#define ADS1115_PGA_1024MV              0b0000011000000000
#define ADS1115_PGA_0512MV              0b0000100000000000
#define ADS1115_PGA_0256MV              0b0000101000000000

#define ADS1115_MODE_CONTINUOUS         0b0000000000000000
#define ADS1115_MODE_SINGLESHOT         0b0000000100000000 // default

#define ADS1115_RATE_8                  0b0000000000000000
#define ADS1115_RATE_16                 0b0000000000100000
#define ADS1115_RATE_32                 0b0000000001000000
#define ADS1115_RATE_64                 0b0000000001100000
#define ADS1115_RATE_128                0b0000000010000000 // default
#define ADS1115_RATE_250                0b0000000010100000
#define ADS1115_RATE_475                0b0000000011000000
#define ADS1115_RATE_860                0b0000000011100000

#define ADS1115_COMP_MODE_HYSTERESIS    0b0000000000000000 // default
#define ADS1115_COMP_MODE_WINDOW        0b0000000000010000

#define ADS1115_COMP_POL_ACTIVE_LOW     0b0000000000000000 // default
#define ADS1115_COMP_POL_ACTIVE_HIGH    0b0000000000001000

#define ADS1115_COMP_LAT_NON_LATCHING   0b0000000000000000 // default
#define ADS1115_COMP_LAT_LATCHING       0b0000000000000100

#define ADS1115_COMP_QUE_ASSERT1        0b0000000000000000
#define ADS1115_COMP_QUE_ASSERT2        0b0000000000000001
#define ADS1115_COMP_QUE_ASSERT4        0b0000000000000010
#define ADS1115_COMP_QUE_DISABLE        0b0000000000000011 // default

#define ADS1115_MV_6144                 (187.5000 * 1E-6)
#define ADS1115_MV_4096                 (125.0000 * 1E-6)
#define ADS1115_MV_2048                 ( 62.5000 * 1E-6) // default
#define ADS1115_MV_1024                 ( 31.2500 * 1E-6)
#define ADS1115_MV_0512                 ( 15.6250 * 1E-6)
#define ADS1115_MV_0256                 (  7.8125 * 1E-6)

uint16_t read_register(uint8_t register_address)
{
	uint16_t byte_count, value;

	Wire.beginTransmission(ADS1115_I2C_ADDRESS);
	Wire.write(register_address);
	Wire.endTransmission();

	byte_count = Wire.requestFrom(ADS1115_I2C_ADDRESS, 2);
	value = Wire.read()<<8 | Wire.read();
	return(value);
}

void write_register(uint8_t register_address, uint16_t register_value)
{
	Wire.beginTransmission(ADS1115_I2C_ADDRESS);
	Wire.write(register_address);
	Wire.write((register_value >> 8) & 0xFF);
	Wire.write(register_value & 0x00FF);
	Wire.endTransmission();
}

uint16_t ra_config;

void ads1115_init(uint16_t config)
{
	ra_config = config;

	write_register(ADS1115_RA_CONFIG,
		  config
		| ADS1115_MODE_CONTINUOUS
		| ADS1115_RATE_16
		| ADS1115_COMP_MODE_WINDOW
		| ADS1115_COMP_POL_ACTIVE_LOW
		| ADS1115_COMP_LAT_LATCHING
		| ADS1115_COMP_QUE_ASSERT1
	);
}

float getVoltage()
{
	float voltage;

	if (ra_config & 0x0400) {  // single
		voltage = (uint16_t)read_register(ADS1115_RA_CONVERSION);
	} else {                   // differential
		voltage = (int16_t)read_register(ADS1115_RA_CONVERSION);
	}

	if ((ra_config&ADS1115_PGA_6144MV)==ADS1115_PGA_6144MV) {
		return voltage * ADS1115_MV_6144;
	} else if ((ra_config&ADS1115_PGA_4096MV)==ADS1115_PGA_4096MV) {
		return voltage * ADS1115_MV_4096;
	} else if ((ra_config&ADS1115_PGA_2048MV)==ADS1115_PGA_2048MV) {
		return voltage * ADS1115_MV_2048;
 	} else if ((ra_config&ADS1115_PGA_1024MV)==ADS1115_PGA_1024MV) {
		return voltage * ADS1115_MV_1024;
 	} else if ((ra_config&ADS1115_PGA_0512MV)==ADS1115_PGA_0512MV) {
		return voltage * ADS1115_MV_0512;
 	} else if ((ra_config&ADS1115_PGA_0256MV)==ADS1115_PGA_0256MV) {
		return voltage * ADS1115_MV_0256;
	} else {
		return 0;
	}
}

void setup()
{
	long int  pos;
	uint16_t  color;
	int       x, y;

	Wire.begin();
	pinMode(ADS1115_ALERT, INPUT);

	pinMode(TFT_BL,OUTPUT);
	analogWrite(TFT_BL, 64); // 0 - 255

	tft.init(135, 240);
	tft.setRotation(3);

	for(pos = 0, y = 0;y < 135; y++) {
		for(x = 0; x < 240; x++, pos++) {
			color = pgm_read_word_near(&fluke[pos]);
			tft.drawPixel(x, y, color);
		}
	}
	tft.setFont(&DSEG7_Classic_Bold_34);

	delay(10); 
	ads1115_init(ADS1115_MUX_P0_N1 | ADS1115_PGA_6144MV);

	tft.setTextColor(BLACK);
}

void loop()
{
	char buf[16];
	tft.fillRect(50,52,164,40,0xA5F7);
	sprintf(buf,"%5.3f", getVoltage());
	tft.setCursor(60,86);
	tft.print(buf);
	delay(500);
}
