/**
 * @file PowerParameters.h
 * @author Phillip Kühne
 * @brief
 * @version 0.1
 * @date 2024-11-28
 *
 * @copyright (c) 2024
 *
 */

#ifndef PowerParameters_h
#define PowerParameters_h

#include <cstdint>
namespace PowerParameters {

struct Battery {
  // Datasheet values
  static constexpr float CELL_CAPACITY_MAH = 120;
  static constexpr float CELL_VOLTAGE_NOMINAL = 3.7;
  struct DISCHARGE_CURVE {
    static constexpr float REFERENCE_CURRENT_A = 0.063925;
    static constexpr int NUM_POINTS = 22;
    static constexpr float VOLTAGES[NUM_POINTS] = {
        3.7426, 3.6110, 3.5621, 3.5027, 3.4826, 3.4391, 3.4005,
        3.3674, 3.3387, 3.3137, 3.2846, 3.2400, 3.2212, 3.1949,
        3.1749, 3.1575, 3.1148, 3.0967, 3.0234, 2.9689, 2.8903};
    static constexpr int CHARGE_STATES[NUM_POINTS] = {
        100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50,
        45,  40, 35, 30, 25, 20, 15, 10, 5,  0};
  };

  // Derived values
  static constexpr float CELL_CHARGE_FULL_COLOUMB = CELL_CAPACITY_MAH * 3.6;
  static constexpr float CELL_ENERGY_FULL_JOULES =
      CELL_CAPACITY_MAH * CELL_VOLTAGE_NOMINAL * 3.6;
  static constexpr float CELL_CURRENT_1C_MA = CELL_CAPACITY_MAH;
  static constexpr float CELL_CURRENT_2C_MA = CELL_CAPACITY_MAH * 2;
  struct BAT_ADC {
    static constexpr float VOLTAGE_DIVIDER_R12 = 27e3;
    static constexpr float VOLTAGE_DIVIDER_R13 = 10e3;
    static constexpr float VOLTAGE_DIVIDER_FACTOR =
        (VOLTAGE_DIVIDER_R12 + VOLTAGE_DIVIDER_R13) / VOLTAGE_DIVIDER_R13;
  };

  // Configuration
  static constexpr int AVERAGING_SAMPLES = 20;
};

// Factors concerning Buck-Boost-Converter
static constexpr float BUCK_BOOST_EFFICIENCY = 0.9;

/*
 * The current consumptions in milliamperes of the different components are
 * defined here. These values are measured on 3,3 Volts, and need to be
 * converted to currents actually occuring at the battery.
 */
struct CurrentConsumptions {
  static constexpr float CURRENT_ESP_BASE = 37.42;
  static constexpr float CURRENT_ESP_LOAD = 88.43;
  static constexpr float CURRENT_ESP_AVG =
      (CURRENT_ESP_BASE + CURRENT_ESP_LOAD) / 2;
  // WiFi current consumptions
  static constexpr float CURRENT_WIFI_BASE = 64.58;
  static constexpr float CURRENT_WIFI_PEAK = 128;
  // RGB LED quiescent current
  static constexpr float CURRENT_LED_RGB_BASE = 0.7;
  // RGB LED per channel current during PWM on-time.
  static constexpr float CURRENT_LED_RGB_CHAN_T_ON = 16;
  static constexpr float CURRENT_SENSOR_RGBW = 0.2;
  static constexpr float CURRENT_LED_IR_BOTTOM = 100;
  static constexpr float CURRENT_LED_IR_FRONT = 180.7;
  // Phototransistor current when active and illuminated.
  static constexpr float CURRENT_PT = 0.33005;
  // Average value, as internal behaviour can not non-expensively and
  // accurately be observed from code.
  static constexpr float CURRENT_DISPLAY = 9;
  // Per motor current during PWM on-time.
  static constexpr float CURRENT_MOTOR_T_ON = 130;
  // Current of IMU when activated.
  static constexpr float CURRENT_IMU = 0.55;
  // LED Current. Placeholder.
  static constexpr float CURRENT_UV_LED = 200;
};

/*
 * Single consumer current limit up to which requests are granted no matter
 * what. The idea is, that this will allow Sensors (with their miniscule power
 * draw) to always be granted power, which should massively improve behaviour.
 */
static constexpr float CURRENT_INSIGNIFICANT = 1;

struct PinConfig {
  static constexpr int BAT_ADC = 10;
  static constexpr int BAT_ADC_EN = 9;
  static constexpr int VUSB_SENS = 38;
  static constexpr int BAT_CHG_STAT = 39;
};

enum PowerConsumers {
  ESP,
  WIFI,
  LED_RGB_TOP_LEFT,
  LED_RGB_TOP_RIGHT,
  LED_RGB_BOTTOM,
  RGBW_SENSOR,
  LED_IR_BOTTOM,
  LED_IR_FRONT,
  PT_IR,
  PT_DL,
  LED_UV,
  DISPLAY_OLED,
  MOTOR_LEFT,
  MOTOR_RIGHT,
  IMU
};

static constexpr uint32_t POWER_STATE_UPDATE_INTERVAL_MS = 10;

}; // namespace PowerParameters

#endif // Consumptions_h