#include <Arduino.h>
#include "FFG3105.h"
#include "Streaming.h"

#define SDA_PIN 33
#define SCL_PIN 32

// Commands: NOP, Wake, Sleep, Lock, Unlock, Reset, Program
uint16_t NOP = 0;
uint16_t WAKE = 1;
uint16_t SLEEP = 2;
uint16_t PROGRAM = 3;
uint16_t LOCK = 5;   // bits 5:4 have to be set properly
uint16_t UNLOCK = 6; // bits 5:4 have to be set properly
uint16_t RESET = 7;
// Measure
uint16_t C_VOLTAGE = 0x0104;
uint16_t C_TEMP = 0x0204;
uint16_t C_ALL = 0x0304;

// INIT
FFG3105::FFG3105(void)
{
    Wire.begin(SDA_PIN, SCL_PIN);
}

uint16_t FFG3105::readVoltage()
{
    uint16_t registerData;
    Wire.beginTransmission(I2C_ADDR_WRITE); // set sensor target
    Wire.write(CELL_VOLTAGE);               // set memory pointer
    Wire.endTransmission();
    // delete this comment – it was only needed for blog layout.
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData = Wire.read();
    registerData <<= 8;
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData += Wire.read();
    // you could add more data reads here if you request more than one byte
    return registerData;
}

uint16_t FFG3105::readTemperature()
{
    uint16_t registerData;
    Wire.beginTransmission(I2C_ADDR_WRITE); // set sensor target
    Wire.write(PACK_TEMPERATURE);           // set memory pointer
    Wire.endTransmission();
    // delete this comment – it was only needed for blog layout.
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData = Wire.read();
    registerData <<= 8;
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData += Wire.read();
    // you could add more data reads here if you request more than one byte
    return registerData;
}

void FFG3105::wake()
{
    Wire.beginTransmission(I2C_ADDR_WRITE);
    Wire.write(CONTROL);
    Wire.write(WAKE);
    Wire.write(0);
    Wire.endTransmission();
}

void FFG3105::sleep()
{
    Wire.beginTransmission(I2C_ADDR_WRITE);
    Wire.write(CONTROL);
    Wire.write(SLEEP);
    Wire.write(0);
    Wire.endTransmission();
}

void FFG3105::reset()
{
    Wire.beginTransmission(I2C_ADDR_WRITE);
    Wire.write(CONTROL);
    Wire.write(RESET);
    Wire.write(0);
    Wire.endTransmission();
}

uint16_t FFG3105::test()
{
    Wire.beginTransmission(I2C_ADDR_READ);
    Wire.write(PART_ID);
    Wire.endTransmission();

    uint16_t registerData;
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData = Wire.read();
    registerData <<= 8;
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData += Wire.read();
    return registerData;
}

/**
 * @brief Start measuring voltage and temperature
 *
 */
void FFG3105::measuring()
{
    Wire.beginTransmission(I2C_ADDR_WRITE);
    Wire.write(CONTROL);
    Wire.write(C_ALL);
    // Wire.write(0);
    Wire.endTransmission();
}

uint16_t FFG3105::readStatus()
{
    uint16_t registerData;
    Wire.beginTransmission(I2C_ADDR_WRITE); // set sensor target
    Wire.write(STATUS);                     // set memory pointer
    Wire.endTransmission();
    // delete this comment – it was only needed for blog layout.
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData = Wire.read();
    registerData <<= 8;
    Wire.requestFrom(I2C_ADDR_READ, 1); // request one byte
    registerData += Wire.read();
    // you could add more data reads here if you request more than one byte
    return registerData;
}
