/**
 * @file cal_tables_rom.c
 * @brief ROM-extracted calibration data for the VP44 PWM controller (compact).
 *
 * AUTO-GENERATED by tools/extract_calibration.py
 * Source ROM: rom_eeprom_dump_0000-9FFF_004002.bin
 * Calibration base (RWA4): 0x9C28
 * Flash anchor: 0x9618
 * Generated: 2026-04-20 13:49:45
 *
 * DO NOT EDIT — regenerate with:
 *   python tools/extract_calibration.py rom_eeprom_dump_0000-9FFF_004002.bin --target compact
 */
#include "cal_tables_rom.h"

/* == Submap table data ==
 *
 * Per-submap x-arrays (consumed by s_eval via descriptor.x), Y-table
 * payloads used by s_combine (2D) and s_refine (1D), and the runtime
 * descriptor array. Definitions come first so the pwm_cal_rom /
 * pwm_flash_rom literals below can reference the Y-table statics by name.
 */

/* max_error descriptor at CAL+0x0136:
 *   flags=0x0000, input_var=0x0040 (rpm), count=4, x_ptr=0x9DFC */
static const int16_t submap_max_error_x[] = {10066, 3565, 1678, 0};
static const int16_t submap_max_error_y[] = {1536, 1365, 853, 85};

/* pwm_A descriptor at CAL+0x0140:
 *   flags=0x0000, input_var=0x0040 (rpm), count=6, x_ptr=0x9E36 */
static const int16_t submap_pwm_A_x[] = {20972, 15099, 10066, 3565, 1678, 0};
static const int16_t submap_pwm_A_y[] = {1536, 1365, 1195, 853, 427, 85};

/* pwm_B descriptor at CAL+0x0148:
 *   flags=0x0000, input_var=0x0046 (some form of target/demand angle), count=7, x_ptr=0x9E42 */
static const int16_t submap_pwm_B_x[] = {1536, 1365, 1195, 853, 427, 85, 0};
static const int16_t submap_pwm_B_y[] = {819, 737, 492, 0, 41, 49, 82};

/* shape_eval descriptor at CAL+0x0152:
 *   flags=0x0000, input_var=0x0142 (voltage), count=4, x_ptr=0x9E50 */
static const int16_t submap_shape_eval_x[] = {819, 737, 492, 0};
static const int16_t submap_shape_eval_y[] = {41, 49, 82, 102};

/* sp0_A descriptor at CAL+0x015C:
 *   flags=0x0000, input_var=0x0040 (rpm), count=9, x_ptr=0x9E0C */
static const int16_t submap_sp0_A_x[] = {20972, 16777, 14680, 12583, 10486, 8389, 6291, 4194, 0};
static const int16_t submap_sp0_A_y[] = {12583, 0, 960, 640, 320, 0, 5968, 5088, 4928};

/* sp0_B descriptor at CAL+0x0164:
 *   flags=0x0000, input_var=0x0044 (inj qty. demand), count=4, x_ptr=0x9E22 */
static const int16_t submap_sp0_B_x[] = {960, 640, 320, 0};
static const int16_t submap_sp0_B_y[] = {5968, 5088, 4928, 0};

/* sp1_B descriptor at CAL+0x016C:
 *   flags=0x0000, input_var=0x0146 (some form of temperature), count=4, x_ptr=0x9E2A */
static const int16_t submap_sp1_B_x[] = {5968, 5088, 4928, 0};
static const int16_t submap_sp1_B_y[] = {256, 0, 20972, 15099};

/* sp2_B descriptor at CAL+0x0174:
 *   flags=0x0000, input_var=0x0042 (angle inj qty. decrease comman), count=2, x_ptr=0x9E32 */
static const int16_t submap_sp2_B_x[] = {256, 0};
static const int16_t submap_sp2_B_y[] = {20972, 15099};

/* sp2_A descriptor at CAL+0x017C:
 *   flags=0x0000, input_var=0x0040 (rpm), count=2, x_ptr=0x9E1E */
static const int16_t submap_sp2_A_x[] = {12583, 0};
static const int16_t submap_sp2_A_y[] = {960, 640};

/* y_pair_0 @ 0x9EB4: 9x4 = 36 int16 words */
static const int16_t pwm_y_y_pair_0_data[] = {2912, 2526, 2333, 2206, 2067, 1878, 1708, 1539, 1374, 2696, 2442, 2315, 2185, 2068, 1891, 1736, 1555, 1407, 2655, 2383, 2247, 2111, 1981, 1845, 1725, 1497, 1349, 2526, 2312, 2204, 2064, 1939, 1828, 1733, 1475, 1336};

/* y_pair_1 @ 0x9EFC: 9x4 = 36 int16 words */
static const int16_t pwm_y_y_pair_1_data[] = {166, 93, 50, 11, 22, (int16_t)0xFFF2, (int16_t)0xFFBF, (int16_t)0xFF9E, (int16_t)0xFF5F, 13, 7, 4, 1, 2, (int16_t)0xFFFF, (int16_t)0xFFFB, (int16_t)0xFFF8, (int16_t)0xFFE7, 0, 0, 0, 0, 0, 0, 0, 0, 0, (int16_t)0xFCEC, (int16_t)0xFE46, (int16_t)0xFF12, (int16_t)0xFFCA, (int16_t)0xFF98, 66, 308, 467, 762};

/* y_pair_2 @ 0x9F44: 2x2 = 4 int16 words */
static const int16_t pwm_y_y_pair_2_data[] = {0, 0, 0, 0};

/* pwm_y_table @ 0x9E60: 6x7 = 42 int16 words */
static const int16_t pwm_y_pwm_y_table_data[] = {205, 205, 205, 205, 205, 205, 880, 799, 573, 512, 205, 205, 1106, 983, 758, 594, 205, 205, 1536, 1392, 1085, 778, 287, 205, 2559, 2150, 1740, 1392, 594, 205, 3481, 3174, 2518, 2252, 983, 205, 3890, 3890, 3890, 3890, 3890, 3890};

/* shape_y_table @ 0x9E58: 4x1 = 4 int16 words */
static const int16_t pwm_y_shape_y_table_data[] = {41, 49, 82, 102};

/* Runtime-mutable descriptor array. `input_ptr` is resolved at
 * boot by pwm_bind_submap_inputs(&rt, pwm_submap_descrs,
 * PWM_SUBMAP_COUNT). The enum is declared in cal_tables_rom.h. */
pwm_submap_descr_t pwm_submap_descrs[PWM_SUBMAP_COUNT] = {
    [PWM_SUBMAP_PWM_A] = { .flags=0x0000, .input_ptr=NULL, .count=6, .x=submap_pwm_A_x, .input_addr=0x0040 },
    [PWM_SUBMAP_PWM_B] = { .flags=0x0000, .input_ptr=NULL, .count=7, .x=submap_pwm_B_x, .input_addr=0x0046 },
    [PWM_SUBMAP_SHAPE_EVAL] = { .flags=0x0000, .input_ptr=NULL, .count=4, .x=submap_shape_eval_x, .input_addr=0x0142 },
    [PWM_SUBMAP_SP0_A] = { .flags=0x0000, .input_ptr=NULL, .count=9, .x=submap_sp0_A_x, .input_addr=0x0040 },
    [PWM_SUBMAP_SP0_B] = { .flags=0x0000, .input_ptr=NULL, .count=4, .x=submap_sp0_B_x, .input_addr=0x0044 },
    [PWM_SUBMAP_SP1_B] = { .flags=0x0000, .input_ptr=NULL, .count=4, .x=submap_sp1_B_x, .input_addr=0x0146 },
    [PWM_SUBMAP_SP2_B] = { .flags=0x0000, .input_ptr=NULL, .count=2, .x=submap_sp2_B_x, .input_addr=0x0042 },
    [PWM_SUBMAP_SP2_A] = { .flags=0x0000, .input_ptr=NULL, .count=2, .x=submap_sp2_A_x, .input_addr=0x0040 },
};

/* ── ROM-extracted calibration (TABLE[RWA4]+offset) ─────────────────── */

const pwm_calibration_t pwm_cal_rom = {
    .target_minimum   = 0,        /* CAL+0x011E */
    .y_pair = {
        pwm_y_y_pair_0_data, /* CAL+0x0184 @ 0x9EB4 */
        pwm_y_y_pair_1_data, /* CAL+0x0186 @ 0x9EFC */
        pwm_y_y_pair_2_data, /* CAL+0x0188 @ 0x9F44 */
    },

    /* PI shaping parameters */
    .pi_upper_breakpoint       = 853,        /* CAL+0x00FE */
    .pi_lower_breakpoint       = (int16_t)0xFCAB,  /* CAL+0x0100 */
    .pi_center_slope           = 2560,       /* CAL+0x010C */
    .pi_upper_outer_slope      = 2560,       /* CAL+0x010E */
    .pi_lower_outer_slope      = 2560,       /* CAL+0x0110 */
    .pi_upper_integrator_gain  = 1024,       /* CAL+0x0112 */
    .pi_center_integrator_gain = 1024,       /* CAL+0x0114 */
    .pi_lower_integrator_gain  = 1024,       /* CAL+0x0116 */

    /* compute_closed_loop_correction / fast_recovery tuning */
    .closed_loop_gain_const    = 4,        /* CAL+0x0156 */
    .error_persist_init_count  = 100,        /* CAL+0x0108 */
    .recovery_rpm_threshold    = 4194,        /* CAL+0x011A */

    /* Setpoint offset latched at init by FUN_8643 (0x867d):
     *   CAL[0x52]=2167 - CAL[0x54]=2833 = -666
     * (RAM[0x0430] always 0, so omitted). */
    .setpoint_offset           = (int16_t)0xFD66,        /* CAL+0x0052 - CAL+0x0054 */
};

/* ── ROM-extracted flash tables (rebased from FLASH:xxxx) ───────────── */

const pwm_flash_t pwm_flash_rom = {
    /* Max-error interpolation table (descriptor at CAL+0x0136)
     * Input variable: 0x0040 (rpm)
     * 4 entries, x-array descending */
    .max_error_x     = {10066, 3565, 1678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    .max_error_y     = {1536, 1365, 853, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    .max_error_count = 4,
    .max_error_input_addr = 0x0040,

    /* PI controller thresholds */
    .request_upper_limit    = 0,        /* CAL+0x011C (FLASH:9734) */
    .large_pos_error_thresh = 171,        /* CAL+0x0102 (FLASH:971A) */
    .large_neg_error_thresh = (int16_t)0xFF55,  /* CAL+0x0104 (FLASH:971C) */
    .inj_qty_demand_thresh  = 160,        /* CAL+0x010A (FLASH:9722) */

    /* PWM shaping tables */
    .rpm_breakpoints = {3775, 4614, 7969, 8892, 12163, 13086, 16358, 17281},
    .rpm_values      = {168, 354, 650, 500, 853, 64683, 171, 65365},
    .shape_scale_src = 354,          /* CAL+0x00F8 (FLASH:9710) */
    .period_max_limit = 29851,       /* CAL+0x00E2 (FLASH:96FA) */
    .period_min_limit = 23529,       /* CAL+0x00E4 (FLASH:96FC) */

    /* PWM submap Y-tables (pointers into ROM) */
    .pwm_y_table   = pwm_y_pwm_y_table_data,   /* CAL+0x0150 @ 0x9E60 */
    .shape_y_table = pwm_y_shape_y_table_data, /* CAL+0x015A @ 0x9E58 */
};
