// SPDX-License-Identifier: GPL-3.0-or-later
// Board: EDCO Prism v0.1 (LuxLibre reference design #4, hardware/edco-prism/), Ø22 x 83.0 mm (head Ø28).
//
// EDCO Prism: a sealed 18350 light whose beam is white or any colour. Four LEDs, one in each cavity of a 24 mm
// quad TIR optic (Carclo 10623 frosted medium spot; 10621 clear for a narrower beam): white Luminus SST-20-W Gen 2
// (6500 K, G1, 3.0 A maximum) on the main channel, and red Luminus SST-10-R (621 nm, 1.5 A maximum), green
// ams OSRAM OSCONIQ P 3030 GT QSSPA1.13 (528 nm, 1.3 A maximum) and blue Luminus SST-20-B (450 nm, 3 A maximum)
// on the colour beam (LX_HAS_COLOR), all on a 24 mm four-channel copper DTP board. No laser, no radio; a waterproof
// USB-C socket in the side of the head is the only way in (charging, firmware, the settings page over the
// ESP32-C3's USB serial/JTAG port).
// White channel: the EDCO Mini / EDCO v0.1 power stage: TPS62095 4 A buck in the TLV333 current loop (20 mOhm
// sense, VSET 2.2 k / 100 k: 100 % duty = 3552 mA), DW01A + a dual N-MOSFET path in the cell minus.
// Colour channels: a TPS63020 buck-boost (VSON-14 3 x 4 mm, LCSC C15483; 1.8-5.5 V in, set to 3.45 V by its
// feedback divider, 4 A switch limit) feeds three linear current sinks (TLV9064 quad op-amp, an N-MOSFET and a
// 100 mOhm sense resistor each). Their set points come from an MCP4728 4-channel 12-bit I2C DAC (VDD reference:
// code 4095 = 1200 mA); its fourth channel enables the TPS63020 while any colour LED is on. The rail sits just
// above the green and blue LEDs' forward voltage, so the colours stay constant down to an empty cell and the sinks
// stay cool (red: about 1 V across its sink).
// Cell: Keeppower UH1835P 18350: 1200 mAh claimed (1100 minimum), 10 A continuous (confirmed in an independent
// test), 35.0 x 18.3 mm flat top, no protection board; nickel strips to both ends. The bay takes 18.6 x 35.3 mm.
// Charger: TI BQ24050 at about 1 A (LCSC C2859551), as EDCO Mini; its status and control pins map to CHG_STAT /
// CHG_DONE / CHG_SET when the board is drawn.
// One button (stainless cap on a sealed, translucent membrane) on GPIO3; the RGB indicator lights the membrane
// from below (halo) and shows the colour beam's colour when it changes. NTC 100 k B4250 on the main board next to
// the head insert.
// The pin map below is the planned one: confirm it against the schematic when the boards are drawn.
#pragma once

#define LX_BOARD_NAME "EDCO Prism v0.1"

#define LX_TICK_MS 10
#define LX_STORAGE_SIZE 256          // NVS blob
#define LX_HAS_CONSOLE 1             // USB-Serial-JTAG: the settings page and the console
#define LX_HAS_AUX_RGB 1             // halo under the button membrane
#define LX_HAS_LASER 0
#define LX_HAS_SIDE 0
#define LX_HAS_COLOR 1               // red, green and blue LEDs in the same optic (5 clicks from off)
#define LX_HAS_CHARGER 1
#define LX_HAS_TEMP 1
#define LX_BAT_CELLS 1

// White channel: LEDC 13-bit PWM -> RC filter -> current set point; 100 % duty = 3552 mA.
// Level 150 = 2850 mA: the LED's 3000 mA maximum less the 5 % worst-case tolerance of the current loop, as in
// EDCO v0.1 and EDCO Mini. 95 % of the LED maximum is above the 80 % of LED-2 (a "Should" rule): turbo is timed
// and regulated.
#define LX_OUT_MIN_Q16 23            // level 1 = 1 mA
#define LX_MAIN_MAX_MA 2850
#define LX_LED_VF0_MV 2800           // SST-20 Gen 2: V = 2.80 V + 0.15 V/A x I (3.0 V at 1.5 A, datasheet typical)
#define LX_LED_RS_MOHM 150
#define LX_DRIVER_EFF_PCT 87         // TPS62095 + inductor + sense + protection FETs at 3 A (estimate)
#if LX_MAIN_MAX_MA * 105 > 3000 * 100
#error "EDCO Prism: with the current loop's 5 % worst-case tolerance LX_MAIN_MAX_MA must stay at or below 2857"
#endif

// Colour channels: 1000 mA per colour LED at most (red 1.5 A, green 1.3 A, blue 3 A maximum: 1 A keeps the green
// LED at 77 % of its rating and the three sinks cool), 2000 mA for the three together (the TPS63020's output
// at a low cell: a white or a mixed colour is scaled down to it).
#define LX_COLOR_FULL_MA 1200        // at DAC code 4095: 3.3 V x 3.6 k / 99.0 k / 100 mOhm
#define LX_COLOR_MAX_MA 1000
#define LX_COLOR_SUM_MA 2000
#define LX_COLOR_RAIL_MV 3450        // TPS63020 output
#define LX_COLOR_RAIL_EFF_PCT 90     // TPS63020 at 1-2 A, 3.0-4.2 V in (estimate from TI's curves)

// ---- ESP32-C3FH4 pin map (EDCO Mini without the side lights, plus the I2C bus for the colour DAC) ----
#define LX_ESP_GPIO_VBAT_ADC 0       // ADC1_CH0, VBAT / 2
#define LX_ESP_GPIO_NTC_ADC 1        // ADC1_CH1, 100 k to 3V3, NTC to GND
#define LX_ESP_GPIO_RGB_B 2          // halo blue, active low (strap pin, 10 k pull-up)
#define LX_ESP_GPIO_BTN 3            // low = pressed (internal pull-up), wake-up
#define LX_ESP_GPIO_CHG_STAT 4       // charger status, low = charging
#define LX_ESP_GPIO_CHG_DONE 5       // charger status, low = charge complete
#define LX_ESP_GPIO_LED_PWM 6        // LEDC -> white current set point
#define LX_ESP_GPIO_LED_EN 7         // high = white driver on (100 k pull-down)
#define LX_ESP_GPIO_RGB_G 8          // halo green, active low (strap pin, 10 k pull-up)
#define LX_ESP_GPIO_I2C_SDA 9        // MCP4728 (strap pin: the bus's 10 k pull-up keeps it high at reset)
#define LX_ESP_GPIO_I2C_SCL 10
#define LX_ESP_COLOR_DAC_ADDR 0x60
#define LX_ESP_GPIO_CHG_SET 20       // charger control: low = charge, floating = trickle, high = off
#define LX_ESP_GPIO_RGB_R 21         // halo red, active low
#define LX_ESP_LED_FULL_MA 3552      // current at 100 % duty: 3.3 V x 2.2 k / 102.2 k / 20 mOhm
#define LX_ESP_VBAT_DIV 2
#define LX_ESP_NTC_RFIX 100000L
#define LX_ESP_NTC_R25 100000L
#define LX_ESP_NTC_BETA 4250L

// ---- defaults: the modes layout for one button (the EDCO levels) ----
#define LX_DEF_UI_STYLE 1            // hold steps Low -> Medium -> High (UI_STYLE 0 = smooth ramp)
#define LX_DEF_RAMP_FLOOR 22         // moon 3 mA (colour beam: 0.2 % of the colour current)
#define LX_DEF_MODE_CNT 3
#define LX_DEF_MODE_1 70             // low 40 mA (colour beam: 2.7 % = 27 mA)
#define LX_DEF_MODE_2 104            // medium 244 mA (colour beam: 16 % = 163 mA)
#define LX_DEF_MODE_3 138            // high 1501 mA (colour beam: the full 1000 mA)
#define LX_DEF_MEM_LEVEL 70
#define LX_DEF_TURBO_LVL 150         // turbo 2850 mA
#define LX_DEF_TURBO_S 60
#define LX_DEF_TURBO_DOWN 138        // back to high after the turbo time
#define LX_DEF_TURBO_ALL 1           // turbo also lights red, green and blue (white from the three colours)
#define LX_DEF_BLINKY 0              // beacon / SOS / strobe off by default (BLINKY over USB)
#define LX_DEF_LOCK_MOON 0
#define LX_DEF_THM_LIMIT 48          // sensor = head node in the simulator: the body (held) stays below 48 degC (THM-1)
#define LX_DEF_THM_LEAD 10           // the regulator looks 10 s ahead (as EDCO Mini)
#define LX_DEF_THM_SHUTDN 80
#define LX_DEF_LVP_WARN 3200
#define LX_DEF_LVP_CUT 3000
#define LX_DEF_BAT_RINT 75           // UH1835P about 45 mOhm DC (estimate) + strips + protection FETs + copper
#define LX_DEF_BAT_MAX_MA 7000       // 70 % of the UH1835P's 10 A (BAT-1); turbo with the colour LEDs draws about 5.5 A
#define LX_DEF_CHG_MAXLVL 121        // light while USB is connected: about 600 mA
#define LX_BAT_OCV_MV 4200, 4050, 3950, 3860, 3770, 3680, 3610, 3540, 3470, 3380, 3000
#define LX_DEF_BLINK_LVL 70
#define LX_DEF_COLOR_SET 135         // 2 clicks step through red, green, blue and the custom colour
#define LX_DEF_COL_R 100             // custom colour: amber at first
#define LX_DEF_COL_G 35
#define LX_DEF_COL_B 0

// ---- LED flux, optic and body model (simulator only: make sim BOARD=edco-prism) ----
// White: SST-20 Gen 2 6500 K G1 at Tj 85 degC (the EDCO v0.1 table): 190 lm at 0.35 A, 354 at 0.7 A, 680 at
// 1.5 A, 857 at 2 A, 1156 at 3 A are the datasheet's correlated bin minima; 1.0 A is interpolated.
#define LX_LED_LM_MA 0, 350, 700, 1000, 1500, 2000, 3000
#define LX_LED_LM    0, 190, 354, 485, 680, 857, 1156
#define LX_OPTIC_PCT 85              // Carclo 10623 frosted medium: 84.6 % (XP-E) / 84.7 % (XP-G), Carclo's figures
// Colour LEDs, red / green / blue: V = VF0 + RS x I and the lumens at the LED at 1000 mA (estimates from the
// datasheets' 350 mA values: SST-10-R 360 mW typ = about 68 lm at 620 nm, 2.1 V; OSCONIQ P 3030 GT 143 lm, 2.7 V;
// SST-20-B 710 mW typ at 450 nm = about 18 lm, 2.8 V; raised to 1 A with typical droop and a hot red LED)
#define LX_SIM_COLOR_VF0_MV 1960, 2480, 2650
#define LX_SIM_COLOR_RS_MOHM 400, 620, 430
#define LX_SIM_COLOR_LM 150, 320, 40
#define LX_SIM_COLOR_DROP_MOHM 130   // 100 mOhm sense resistor + the sink FET
// Body from the EDCO Prism CAD (hardware/edco-prism/cad/edco_prism_interface.json; 6061 0.896 J/gK, copper 0.385 J/gK):
//  head  = bezel 5.09 g + head insert 4.64 g + body in front of the step (band, finned head section) 18.52 g =
//          28.25 g of aluminium (25.31 J/K) + copper LED board 6.49 g (2.50 J/K) = 27.81 J/K
//  body  = the tube behind the step with the tail tab, 12.32 g = 11.04 J/K (sled, board, button and cell not counted)
//  head to body: one piece of aluminium; tube section 80 mm2 (d22 / d19.2, less the flats), 43.1 mm long,
//                L / (3 k A) = 1.08 K/W, 1.1 K/W
//  body to air: 7291 mm2 (with the head fins) plus the bezel fins (about 250 mm2) x 11 W/m2K = 12.1 K/W
//  Sensor lag 4 s: the NTC sits on the main board 1-2 mm behind the head insert.
#define LX_SIM_CAPACITY_MAH 1100
#define LX_SIM_RINT_MOHM 70
#define LX_SIM_C_HEAD_MJ 27810       // mJ/K
#define LX_SIM_C_BODY_MJ 11040       // mJ/K
#define LX_SIM_R_HEAD_BODY_MK 1100   // mK/W
#define LX_SIM_R_BODY_AMB_MK 12100   // mK/W
#define LX_SIM_SENSOR_TAU_MS 4000
#define LX_SIM_DROP_MOHM 128         // battery (under load) to LED at 100 % duty (as EDCO v0.1)
#define LX_SIM_OCV_V 2.50, 3.05, 3.25, 3.38, 3.47, 3.54, 3.61, 3.68, 3.77, 3.86, 3.95, 4.05, 4.20
#define LX_SIM_CHARGE_MA 1000        // charge current (constant until 90 %, then tapering: a rough CC/CV)
#define LX_SIM_MCU_UA 10000          // ESP32-C3 at 80 MHz idling between 10 ms ticks, regulator and op-amps: about
                                     // 10 mA (estimate, as EDCO Mini); asleep 0.3 mA
#if LX_MAIN_MAX_MA > LX_ESP_LED_FULL_MA
#error "LX_MAIN_MAX_MA above the driver's full scale"
#endif
#if LX_COLOR_MAX_MA > LX_COLOR_FULL_MA
#error "LX_COLOR_MAX_MA above the colour sinks' full scale"
#endif
