terrano setup, not working

This commit is contained in:
2026-05-05 14:12:07 +02:00
parent ad3a9bb474
commit de8a09361b
18 changed files with 582 additions and 285 deletions

View File

@@ -103,6 +103,13 @@ const pwm_calibration_t pwm_cal_rom = {
.target_5e_min_clamp = (int16_t)0xFE00, /* cal+0x12A */
.can_aux_12e_max = 1451, /* cal+0x002 */
/* CKP-zero acquisition — values re-extracted from this ROM
* (RWA4=0x9BD8); cal slot offsets differ from T06235 (T06215 has
* cal+0x4E/0x50/0xA0 vs T06235 cal+0x50/0x52/0xA2). */
.ckp_zero_anchor = 4147, /* cal+0x04E @ 0x9C26 = 0x1033 */
.can_dckp_offset_bias = -427, /* cal+0x050 @ 0x9C28 = 0xFE55 */
.ckp_modulus = 7680, /* cal+0x0A0 @ 0x9C78 = 0x1E00 (90°) */
/* Recovery / sustained-error machinery */
.pi_state_c2_reload = 100, /* cal+0x114 (ROM 0x9CEC = 0x0064) */
.inj_qty_thresh = 96, /* cal+0x116 (ROM 0x9CEE = 0x0060) */

View File

@@ -14,9 +14,14 @@
* ~cal+0x9E (the new ADR-SV-* / KW_SIM_UMSCHALTUNG diagnostic fields per
* doc.txt 30.08.02). All T06215 cal field roles map to T06235 with the
* +0x14 offset; the actual values were re-extracted from this ROM.
* NOTE: there is also a +0x02 shift in the lower region — at minimum
* cal+0x4c → cal+0x4e and cal+0xa0 → cal+0xa2 (both confirmed in FUN_6a4b
* @ 0x6a4b). Lower-region scalars must be re-checked, not assumed unchanged.
*
* Notable value deltas vs T06215:
* - setpoint_offset = cal+0x4c cal+0x4e = 4399 3499 = +900 (T06215: -648).
* - setpoint_offset = cal+0x4e cal+0x50 = 3499 4228 = -729 (T06215 cal+0x4ccal+0x4e = -648).
* Cal-block +0x02 shift in this lower region; T06215's cal+0xa0 modulo
* also moves to cal+0xa2 in T06235 (verified in FUN_6a4b @ 0x6a4b).
* - init_p_gain_normal = +368 (T06215: +336)
* - init_p_slope_large_pos = +2047 (T06215: +1792)
* - init_integ_step_normal = +320 (T06215: +256)
@@ -112,10 +117,16 @@ const pwm_calibration_t pwm_cal_rom = {
/* CAN-decoded setpoint cal constants (lower region — invariant offsets) */
.b_fb_kw_upper_bound = 7680, /* cal+0x004 */
.b_fb_kw_lower_bound = (int16_t)0xFD00, /* cal+0x006 */
.setpoint_offset = 900, /* cal+0x4c cal+0x4e = 4399 3499 = 900 (T06215: -648) */
.setpoint_offset = -729, /* cal+0x4e cal+0x50 = 3499 4228 = -729 (T06215 cal+0x4ccal+0x4e = -648) */
.target_5e_min_clamp = (int16_t)0xFE00, /* cal+0x13E = -512 (T06215 cal+0x12A +0x14) */
.can_aux_12e_max = 1451, /* cal+0x002 */
/* CKP-zero acquisition (FUN_55e0 + FUN_6a4b chain) — values read from
* rom_eeprom_dump_0000-9FFF_504042.bin at RWA4 + offset. */
.ckp_zero_anchor = 4228, /* cal+0x050 @ 0x9C08 = 0x1084 */
.can_dckp_offset_bias = 0, /* cal+0x052 @ 0x9C0A = 0x0000 */
.ckp_modulus = 7680, /* cal+0x0A2 @ 0x9C5A = 0x1E00 (90° at 256/3°/unit) */
/* Recovery / sustained-error machinery */
.pi_state_c2_reload = 100, /* cal+0x128 (was T06215 cal+0x114) */
.inj_qty_thresh = 96, /* cal+0x12A (was T06215 cal+0x116) */

View File

@@ -192,6 +192,13 @@ struct pwm_calibration {
int16_t target_5e_min_clamp; /* cal+0x12A */
int16_t can_aux_12e_max; /* cal+0x002 */
/* CKP-zero acquisition (FUN_70d8 chain) cal constants — see
* docs/algorithm-ckp-zero-acquisition.md. T06215 cal slot offsets
* differ from T06235 (T06235 has +0x02 lower-region shift). */
int16_t ckp_zero_anchor; /* cal+0x04E — FUN_70d8 additive anchor */
int16_t can_dckp_offset_bias; /* cal+0x050 — Stage-1/Stage-2 bias */
int16_t ckp_modulus; /* cal+0x0A0 — FUN_70d8 modulo wrap */
/* Recovery / sustained-error machinery */
int16_t pi_state_c2_reload; /* cal+0x114 — reload value for pi_state_c2 on latch */
int16_t inj_qty_thresh; /* cal+0x116 — inj-qty threshold for recovery vs reset */

View File

@@ -193,6 +193,11 @@ struct pwm_calibration {
int16_t target_5e_min_clamp; /* cal+0x12A */
int16_t can_aux_12e_max; /* cal+0x002 */
/* CKP-zero acquisition (FUN_55e0 + FUN_6a4b chain) cal constants */
int16_t ckp_zero_anchor; /* cal+0x050 — FUN_6a4b additive anchor */
int16_t can_dckp_offset_bias; /* cal+0x052 — FUN_55e0/FUN_6a4b bias */
int16_t ckp_modulus; /* cal+0x0A2 — FUN_6a4b modulo wrap */
/* Recovery / sustained-error machinery */
int16_t pi_state_c2_reload; /* cal+0x114 — reload value for pi_state_c2 on latch */
int16_t inj_qty_thresh; /* cal+0x116 — inj-qty threshold for recovery vs reset */

View File

@@ -1,46 +1,32 @@
/**
* @file cal_tables_rom.c (variant/T06235/compact_src)
* @brief ROM-decoded T06235 calibration.
* @file cal_tables_rom.c (families/T06215/compact_src)
* @brief ROM-decoded T06215 calibration.
*
* Source ROM: rom_eeprom_dump_0000-9FFF_504042.bin
* Bosch P/N header: '16700 69T63\0' (24-byte ASCII header at flash 0x9BA0)
* Calibration base: RWA4 = 0x9BB8
* Source ROM: 424026.bin (Bosch P/N 167002X9001494060200)
* Calibration base: RWA4 = 0x9BD8
* Flash anchor: 0x9618
* Generated: 2026-05-01 (extracted via tools/extract_calibration.py
* + direct flash readback per Step 7)
* Generated: 2026-04-29 (hand-extracted via Ghidra MCP + ROM readback)
*
* Field-name → ROM-address binding lives in pwm_addr_map.h. T06235 is a
* recompile of T06215 with a uniform +0x14 cal-block insertion above
* ~cal+0x9E (the new ADR-SV-* / KW_SIM_UMSCHALTUNG diagnostic fields per
* doc.txt 30.08.02). All T06215 cal field roles map to T06235 with the
* +0x14 offset; the actual values were re-extracted from this ROM.
* NOTE: there is also a +0x02 shift in the lower region — at minimum
* cal+0x4c → cal+0x4e and cal+0xa0 → cal+0xa2 (both confirmed in FUN_6a4b
* @ 0x6a4b). Lower-region scalars must be re-checked, not assumed unchanged.
* Field name → ROM-address binding lives in pwm_addr_map.h. Boot-derived
* values that previously lived as hard-coded literals in pwm.c's
* runtime_reset are now in `init_*` fields here so each variant carries
* its own values without code edits.
*
* Notable value deltas vs T06215:
* - setpoint_offset = cal+0x4e cal+0x50 = 3499 4228 = -729 (T06215 cal+0x4ccal+0x4e = -648).
* Cal-block +0x02 shift in this lower region; T06215's cal+0xa0 modulo
* also moves to cal+0xa2 in T06235 (verified in FUN_6a4b @ 0x6a4b).
* - init_p_gain_normal = +368 (T06215: +336)
* - init_p_slope_large_pos = +2047 (T06215: +1792)
* - init_integ_step_normal = +320 (T06215: +256)
* - init_integ_step_large_pos= +831 (T06215: +512)
* - init_integ_step_large_neg= +255 (T06215: +256)
* - rpm_threshold_recovery = 2726 (T06215: 2936)
* - pwm_rpm_windows[1] = 6795 (T06215: 6837)
* - setpoint_y[] = [1707,1707,1707,1195,768,427]
* (T06215: [1707,1707,1195,768,427,427])
* - pwm Y-table values mostly re-tuned (90 entries); see arrays below.
*
* All other scalars match T06215 exactly.
* Cal-offset deltas vs t06211:
* - PI body thresholds (0x10E, 0x110, 0x116) — same offsets.
* - target/pi clamps (-512) live at cal+0x128 / cal+0x12A in T06215
* (vs t06211's cal+0x120 / cal+0x122).
* - pwm_y_table_ptr at cal+0x15C; shape_y_table_ptr at cal+0x166.
* - PWM RPM-window block 0xEE..0x104 — UNCHANGED offsets.
* - setpoint_offset = cal+0x4c - cal+0x4e = 3499 - 4147 = -648.
* - s_recovery RPM gate at cal+0x126 (t06211 used cal+0x11E).
*/
#include "pwm.h"
/* ── Submap x/y arrays ──────────────────────────────────────────────── */
static const int16_t setpoint_x[6] = { 8389, 5872, 3775, 2726, 1426, 0 };
static const int16_t setpoint_y[6] = { 1707, 1707, 1707, 1195, 768, 427 };
static const int16_t setpoint_y[6] = { 1707, 1707, 1195, 768, 427, 427 };
static const int16_t pwm_A_x[9] = { 25166, 18455, 13841, 8389, 5872, 3775, 2726, 1426, 0 };
static const int16_t pwm_A_y[9] = { 1707, 1365, 1195, 768, 427, 85, 0, -171, -469 };
@@ -48,8 +34,6 @@ static const int16_t pwm_A_y[9] = { 1707, 1365, 1195, 768, 427, 85, 0,
static const int16_t pwm_B_x[10] = { 1707, 1365, 1195, 768, 427, 85, 0, -171, -469, -512 };
static const int16_t pwm_B_y[10] = { 819, 737, 492, 0, 41, 49, 82, 102, 205, 205 };
/* T06215 inferred shape map kept verbatim — needs Step 7 follow-up to
* re-extract from T06235 for accuracy if shape stage is exercised. */
static const int16_t shape_x[4] = { 819, 737, 492, 0 };
static const int16_t shape_y[4] = { 41, 49, 82, 102 };
@@ -57,18 +41,16 @@ static const int16_t shape_y[4] = { 41, 49, 82, 102 };
static const int16_t shape_y_table_rom[4] = { 41, 49, 82, 102 };
/* PWM bilinear Y-table at flash 0x9E20 (T06235; T06215 was 0x9E30) —
* 10 rows × 9 cols (90 entries). Re-extracted 2026-05-01 from this
* ROM; values differ from T06215 (recalibrated). */
/* PWM bilinear Y-table at flash 0x9E30 — 10 rows × 9 cols (90 entries). */
static const int16_t pwm_y_table_rom[90] = {
/* row 0 */ 205, 205, 205, 205, 205, 205, 205, 205, 0,
/* row 1 */ 1638, 1433, 1229, 1024, 819, 205, 205, 205, 0,
/* row 2 */ 1843, 1658, 1474, 1229, 1024, 205, 205, 205, 0,
/* row 3 */ 2375, 2211, 2068, 1802, 1577, 1167, 205, 205, 0,
/* row 4 */ 2744, 2621, 2580, 2457, 2273, 1904, 1372, 205, 0,
/* row 5 */ 3358, 3276, 3235, 3194, 3092, 2867, 2539, 1351, 205,
/* row 6 */ 3686, 3604, 3522, 3440, 3358, 3215, 2867, 1761, 614,
/* row 7 */ 3890, 3890, 3890, 3890, 3890, 3890, 3890, 2518, 1527,
/* row 1 */ 1568, 1433, 1355, 1065, 799, 205, 205, 205, 0,
/* row 2 */ 1716, 1679, 1556, 1290, 983, 205, 205, 205, 0,
/* row 3 */ 2219, 2129, 2052, 1925, 1679, 880, 205, 205, 0,
/* row 4 */ 2744, 2580, 2518, 2477, 2355, 1740, 1310, 205, 0,
/* row 5 */ 3210, 3071, 3030, 3194, 3194, 3018, 2867, 737, 205,
/* row 6 */ 3702, 3493, 3403, 3583, 3583, 3493, 3071, 1192, 483,
/* row 7 */ 3890, 3890, 3890, 3890, 3890, 3890, 3890, 2076, 1229,
/* row 8 */ 3890, 3890, 3890, 3890, 3890, 3890, 3890, 3890, 3481,
/* row 9 */ 3890, 3890, 3890, 3890, 3890, 3890, 3890, 3890, 4095,
};
@@ -108,24 +90,25 @@ const int16_t *pwm_submap_y_of(uint16_t idx)
/* ── Scalars ────────────────────────────────────────────────────────── */
const pwm_calibration_t pwm_cal_rom = {
/* PI controller error-band thresholds (T06235 cal+0x122/0x124 = T06215 +0x14) */
.large_pos_error_thresh = 128, /* cal+0x122 (was T06215 cal+0x10E) */
.large_neg_error_thresh = (int16_t)0xFF00, /* cal+0x124 = -256 */
.pi_low_clamp = (int16_t)0xFE00, /* cal+0x13C = -512 */
/* PI controller error-band thresholds */
.large_pos_error_thresh = 128, /* cal+0x10E */
.large_neg_error_thresh = (int16_t)0xFF00, /* cal+0x110 = -256 */
.pi_low_clamp = (int16_t)0xFE00, /* cal+0x128 = -512 */
.pi_high_clamp = 1707, /* fallback; runtime uses pi_high_clamp_ceiling */
/* CAN-decoded setpoint cal constants (lower region — invariant offsets) */
/* CAN-decoded setpoint cal constants */
.b_fb_kw_upper_bound = 7680, /* cal+0x004 */
.b_fb_kw_lower_bound = (int16_t)0xFD00, /* cal+0x006 */
.setpoint_offset = -729, /* cal+0x4e cal+0x50 = 3499 4228 = -729 (T06215 cal+0x4ccal+0x4e = -648) */
.target_5e_min_clamp = (int16_t)0xFE00, /* cal+0x13E = -512 (T06215 cal+0x12A +0x14) */
.setpoint_offset = -648, /* cal+0x4c cal+0x4e */
.target_5e_min_clamp = (int16_t)0xFE00, /* cal+0x12A */
.can_aux_12e_max = 1451, /* cal+0x002 */
/* CKP-zero acquisition (FUN_55e0 + FUN_6a4b chain) — values read from
* rom_eeprom_dump_0000-9FFF_504042.bin at RWA4 + offset. */
.ckp_zero_anchor = 4228, /* cal+0x050 @ 0x9C08 = 0x1084 */
.can_dckp_offset_bias = 0, /* cal+0x052 @ 0x9C0A = 0x0000 */
.ckp_modulus = 7680, /* cal+0x0A2 @ 0x9C5A = 0x1E00 (90° at 256/3°/unit) */
/* CKP-zero acquisition — values re-extracted from this ROM
* (RWA4=0x9BD8); cal slot offsets differ from T06235 (T06215 has
* cal+0x4E/0x50/0xA0 vs T06235 cal+0x50/0x52/0xA2). */
.ckp_zero_anchor = 4147, /* cal+0x04E @ 0x9C26 = 0x1033 */
.can_dckp_offset_bias = -427, /* cal+0x050 @ 0x9C28 = 0xFE55 */
.ckp_modulus = 7680, /* cal+0x0A0 @ 0x9C78 = 0x1E00 (90°) */
/* CKP process-tooth derivation (FUN_6c70 — feeds get_ckp_process_tooth()).
* Read direct from rom_eeprom_dump_0000-9FFF_504042.bin at RWA4=0x9BB8
@@ -136,49 +119,57 @@ const pwm_calibration_t pwm_cal_rom = {
.ckp_teeth_per_seg = 26, /* cal+0x0A0 @ 0x9C58 (default cal+0x0A4; same value across all variants) */
/* Recovery / sustained-error machinery */
.pi_state_c2_reload = 100, /* cal+0x128 (was T06215 cal+0x114) */
.inj_qty_thresh = 96, /* cal+0x12A (was T06215 cal+0x116) */
.pi_sat_count_threshold = 800, /* cal+0x126 (was T06215 cal+0x112) */
.rpm_threshold_recovery = 2726, /* cal+0x13A (was T06215 cal+0x126; T06215 = 2936 — value Δ) */
.pi_cl_rpm_floor = 420, /* flash[0x605C] = 0x01A4 — invariant */
.pi_state_c2_reload = 100, /* cal+0x114 (ROM 0x9CEC = 0x0064) */
.inj_qty_thresh = 96, /* cal+0x116 (ROM 0x9CEE = 0x0060) */
.pi_sat_count_threshold = 800, /* cal+0x112 (ROM 0x9CEA = 0x0320) */
.rpm_threshold_recovery = 2936, /* cal+0x126 (ROM 0x9CFE = 0x0B78) — was wrong (256, t06211 holdover) */
.pi_cl_rpm_floor = 420, /* flash[0x605C] = 0x01A4 */
/* PI runtime-reset values (T06235-extracted from cal block at RWA4=0x9BB8 + offset). */
.init_p_shape_bound_pos = +107, /* cal+0x11E (T06215 cal+0x10A) */
.init_p_shape_bound_neg = -107, /* cal+0x120 (T06215 cal+0x10C) */
.init_p_gain_normal = +368, /* cal+0x12C (T06215 cal+0x118; was +336 — value Δ) */
.init_p_slope_large_pos = +2047, /* cal+0x12E (T06215 cal+0x11A; was +1792 — value Δ) */
.init_p_slope_large_neg = +512, /* cal+0x130 (T06215 cal+0x11C) */
.init_integ_step_normal = +320, /* cal+0x132 (T06215 cal+0x11E; was +256 — value Δ) */
.init_integ_step_large_pos = +831, /* cal+0x134 (T06215 cal+0x120; was +512 — value Δ) */
.init_integ_step_large_neg = +255, /* cal+0x136 (T06215 cal+0x122; was +256 — value Δ) */
.init_open_loop_p_gain = +6, /* cal+0x138 byte (T06215 cal+0x124; same value, clamped to 15) */
/* PI runtime-reset values (ROM-extracted from t06215 cal block at
* RWA4=0x9BD8 + offset). Boot multipliers DAT_0410..0416 are
* uninitialized RAM (no writers anywhere in ROM), so they default
* to 0 — the boot equation `(trim_byte << N) + cal_value` resolves
* to cal_value. Earlier defaults of ±853 / 480 / etc. were t06211
* holdovers from the original fork; corrected 2026-04-29 against
* the actual t06215 ROM bytes. */
.init_p_shape_bound_pos = +107, /* cal+0x10A (ROM 0x9CE2 = 0x006B) → DAT_0450 */
.init_p_shape_bound_neg = -107, /* cal+0x10C (ROM 0x9CE4 = 0xFF95) → DAT_0452 */
.init_p_gain_normal = +336, /* cal+0x118 (ROM 0x9CF0 = 0x0150) → DAT_0454 */
.init_p_slope_large_pos = +1792, /* cal+0x11A (ROM 0x9CF2 = 0x0700) → DAT_027e */
.init_p_slope_large_neg = +512, /* cal+0x11C (ROM 0x9CF4 = 0x0200) → DAT_0280 */
.init_integ_step_normal = +256, /* cal+0x11E (ROM 0x9CF6 = 0x0100) → DAT_0456 */
.init_integ_step_large_pos = +512, /* cal+0x120 (ROM 0x9CF8 = 0x0200) → DAT_0282 */
.init_integ_step_large_neg = +256, /* cal+0x122 (ROM 0x9CFA = 0x0100) → DAT_0284 */
.init_open_loop_p_gain = +6, /* cal+0x124 (ROM 0x9CFC = 0x06, byte, clamped to 15) → DAT_033e */
/* CL correction normalizers — boot-cached at DAT_0340/DAT_0342. */
.init_pos_error_normalizer = 350, /* cal+0x11C (T06215 cal+0x108) */
.init_neg_error_normalizer = 350, /* cal+0x11A (T06215 cal+0x106) */
/* CL correction normalizers — boot-cached at DAT_0340/DAT_0342 in
* the ROM (NOT 0x0332/0x0334 — that was a t06211 holdover). Source
* cal offsets are 0x108 (pos) and 0x106 (neg); both equal 350 in
* this ROM. */
.init_pos_error_normalizer = 350, /* cal+0x108 (ROM 0x9CE0 = 0x015E) → DAT_0340 */
.init_neg_error_normalizer = 350, /* cal+0x106 (ROM 0x9CDE = 0x015E) → DAT_0342 */
/* PWM stage scalars — entire block shifted +0x14 in T06235 */
.pwm_detail_x0 = (int16_t)0x9C40, /* cal+0x102 = 40000 unsigned (period_max) */
.pwm_detail_x1 = (int16_t)0x8235, /* cal+0x104 = 33333 unsigned (period_min) */
.pwm_cached_ptr_0F2 = 5662, /* cal+0x106 (T06215 cal+0x0F2) */
.pwm_cached_ptr_102 = 168, /* cal+0x116 = halfwidth (T06215 cal+0x102) */
.pwm_const_104 = 354, /* cal+0x118 = slew_step (T06215 cal+0x104) */
/* PWM stage scalars */
.pwm_detail_x0 = (int16_t)0x9C40,
.pwm_detail_x1 = (int16_t)0x8235,
.pwm_cached_ptr_0F2 = 5662,
.pwm_cached_ptr_102 = 168,
.pwm_const_104 = 354,
/* RPM-window block — index 1 differs (6795 vs T06215 6837) */
.pwm_rpm_windows = { 5662, 6795, 8808, 10486, 11954, 13422, 18036, 19713 },
.pwm_window_halfwidth = 168, /* cal+0x116 */
.pwm_slew_step = 354, /* cal+0x118 */
.pwm_rpm_windows = { 5662, 6837, 8808, 10486, 11954, 13422, 18036, 19713 },
.pwm_window_halfwidth = 168,
.pwm_slew_step = 354,
.pwm_y_table = pwm_y_table_rom,
.shape_y_table = shape_y_table_rom,
.closed_loop_gain_const = 10, /* flash[0x6056] = 0x000A — invariant */
.closed_loop_gain_const = 10,
.pwm_period_min = 33333, /* cal+0x104 = 60.0 Hz */
.pwm_period_max = 40000, /* cal+0x102 = 50.0 Hz */
.pwm_period_min = 33333,
.pwm_period_max = 40000,
.pwm_min = 0x00CD, /* flash[0x6058] = 205 */
.pwm_max = 0x0F32, /* flash[0x605A] = 3890 */
.pwm_min = 0x00CD,
.pwm_max = 0x0F32,
};
const pwm_flash_t pwm_flash_rom = { 0 };

View File

@@ -18,7 +18,6 @@ uint8_t commitCKP_offset = 0;
/* RAM trims (DAT_0430 word, DAT_0404 signed byte) — see header. */
int16_t CKP_RAM_TRIM_0430 = 0;
int8_t CKP_RAM_TRIM_0404 = 0;
/* Outputs */
int16_t dCKP_OFFSET = 0;

View File

@@ -1,16 +1,13 @@
/**
* @file pwm.c (variant/T06235/compact_src)
* @brief Compact single-file implementation of the T06235 PWM control
* pipeline. Body copied verbatim from variant/T06215/compact_src/pwm.c
* per the pillar-port-verbatim rule — T06235's pipeline is a 1:1
* structural mirror of T06215 (only addresses + cal offsets shift;
* the C body is invariant by design of the semantic field names).
* @file pwm.c (families/T06215/compact_src)
* @brief Compact single-file implementation of the T06215 PWM control
* pipeline.
*
* Pipeline (pwm_service @ 0x7a1e in T06235; analog of T06215 @ 0x7772):
* 0. setpoint interp (FUN_732c) — writes pi_high_clamp_ceiling (DAT_0344)
* 1. supervisor (FUN_7f12) — reset + counter + error + clamp
* 2. publish_cl (FUN_7fca) — calls cl_correction, publishes est_angle
* 3. pi_update (FUN_5809) — open/closed-loop PI body
* Pipeline (pwm_service @ 0x7780):
* 0. setpoint interp (FUN_7051) — writes pi_high_clamp_ceiling (DAT_0344)
* 1. supervisor (s_supervisor) — reset + counter + error + clamp
* 2. publish_cl (s_publish_cl) — calls cl_correction, publishes est_angle
* 3. pi_update (s_pi_update @ 0x542f) — open/closed-loop PI body
* 4. pwm_output (s_pwm_output) — eval+eval+combine+saturate+HW shadow
*
* The PI block (s_pi_update + s_recovery) was re-translated 1:1 from the

View File

@@ -1,14 +1,13 @@
/**
* @file pwm.h (variant/T06235/compact_src)
* @brief Compact single-header API for the T06235 PWM controller.
* @file pwm.h (families/T06215/compact_src)
* @brief Compact single-header API for the T06215 PWM controller.
*
* Variant note: this header was copied verbatim from variant/T06215/compact_src
* per the pillar-port-verbatim rule (docs/pillar-functions.md). T06235 is a
* recompile of T06215 with a +0x14 cal-block insertion and one RAM slot move
* (reset_flag 0x002e → 0x002c) — see variant/T06235/docs/algorithm-diff-vs-T06215.md.
* Runtime-struct field names are purely semantic; the address binding for
* any field lives in `pwm_addr_map.h` (documentation-only; not included
* by pwm.c).
* Variant note: this header was originally forked from t06211 and carried
* runtime/cal field names that embedded RAM addresses (e.g. `pi_b4_state`,
* `target_336`). Those addresses were t06211-correct but t06215-wrong.
* Field names here are now purely semantic; the address binding for any
* field lives in `pwm_addr_map.h` (documentation-only; not included by
* pwm.c).
*
* Public API:
* pwm_init() — one-time setup
@@ -193,6 +192,7 @@ struct pwm_calibration {
int16_t target_5e_min_clamp; /* cal+0x12A */
int16_t can_aux_12e_max; /* cal+0x002 */
<<<<<<< HEAD
/* CKP-zero acquisition (FUN_55e0 + FUN_6a4b chain) cal constants */
int16_t ckp_zero_anchor; /* cal+0x050 — FUN_6a4b additive anchor */
int16_t can_dckp_offset_bias; /* cal+0x052 — FUN_55e0/FUN_6a4b bias */
@@ -212,6 +212,14 @@ struct pwm_calibration {
int16_t ckp_teeth_per_seg; /* cal+0x0A0 — per-segment clamp:
* if tooth > teeth_per_seg → tooth = 0
* (T06235: 26 teeth / 90° segment). */
=======
/* CKP-zero acquisition (FUN_70d8 chain) cal constants — see
* docs/algorithm-ckp-zero-acquisition.md. T06215 cal slot offsets
* differ from T06235 (T06235 has +0x02 lower-region shift). */
int16_t ckp_zero_anchor; /* cal+0x04E — FUN_70d8 additive anchor */
int16_t can_dckp_offset_bias; /* cal+0x050 — Stage-1/Stage-2 bias */
int16_t ckp_modulus; /* cal+0x0A0 — FUN_70d8 modulo wrap */
>>>>>>> 0ad144c (terrano setup, not working)
/* Recovery / sustained-error machinery */
int16_t pi_state_c2_reload; /* cal+0x114 — reload value for pi_state_c2 on latch */

View File

@@ -16,9 +16,11 @@
//#define T15021 //audi 506 -> 030 033
//#define T31804 //audi 506 -> 037 038
//#define T06209 //eq: T06216
//#define T06211
#define T06215
#define T06235 //no hace nada pero habria que verificar vcon la t06215
#define _504042
/* FORD */
@@ -38,7 +40,7 @@
/* ALL FBKW */
#define FBKW_FEEDBACK_ZERO 49.571
#define FBKW_FEEDBACK_ZERO 49.571 //49.559
#define FBKW_FEEDBACK_MIN -5.367
#define FBKW_FEEDBACK_MAX 21.27

View File

@@ -12,16 +12,13 @@
/* DEBUG PARAMETERS*/
//#define T06301 //ford 004 -> 002 004 006 || 504 -> 010 018
//#define T06215 //bmw rover 004 -> 005 014 015 016 017 || 504 -> 005 007 017 || 006 -> 001 002 003 004 007 008
#define T06215 //bmw rover 004 -> 005 014 015 016 017 || 504 -> 005 007 017 || 006 -> 001 002 003 004 007 008
//#define T15021 //audi 506 -> 030 033
//#define T31804 //audi 506 -> 037 038
//#define T06209 //eq: T06216
//#define T06211
#define T06215
#define T06235 //no hace nada pero habria que verificar vcon la t06215
#define _504042
#define _424026
/* FORD */
#define FORD_SYNC_PULSE_OUT 0
@@ -32,20 +29,19 @@
#define CYLINDERS 4
/* TIMING COMPENSATIONS */
#define PHI1 41.004
#define PHI1 41.0f
#define TEIN_NOMINAL 1556
//(phiad - injangle with fault tein)*totime = teinnom
#define TEIN_FAULT 950
/* ALL FBKW */
#define FBKW_FEEDBACK_ZERO 49.571 //49.559
//#define FBKW_FEEDBACK_ZERO 45.2
#define FBKW_FEEDBACK_ZERO 53.613
#define FBKW_FEEDBACK_MIN -5.367
#define FBKW_FEEDBACK_MAX 21.27
#define FBKW_FEEDBACK_IC_DT 19
#define FBKW_FEEDBACK_IC_DT 18
/* CAN DEFINITIONS */
#define CAN_BAUDRATE 500

View File

@@ -749,6 +749,116 @@ static void compute_accel_comp_offset(runtime_state_t *rt, const calibration_t *
(void)rw1c; /* rw1c is discarded after MUL; preserved for block-mapping */
}
/* ======================================================================
* tooth_isr / reset_tooth_state — port of FUN_51e1 @ 0x51e1 (producer)
* and FUN_5210 @ 0x5210 (DIVU helper) from the T06215 ROM.
*
* The producer fires once per cylinder when R88 == cal_byte_56 (= 13).
* It computes rpm_baseline = 0x0F000000 / period_ticks where period is
* the elapsed EPA timer ticks between two consecutive phase-13 hits.
* ====================================================================== */
/* 0x0F000000 = 251,658,240 — the fixed dividend (cal+0xA2:cal+0xA4). */
#define RPM_DIVIDEND_HI ((uint16_t)0x0F00u)
#define RPM_DIVIDEND_LO ((uint16_t)0x0000u)
/* Period saturation (cal+0xA6:cal+0xA8) = 0x001B7740 = 1,800,000 ticks. */
#define PERIOD_CLAMP_LO ((uint16_t)0x7740u)
#define PERIOD_CLAMP_HI ((uint16_t)0x001Bu)
/* 0x52100x529c: period_to_rpm_div helper (FUN_5210). */
static int16_t period_to_rpm_div(uint16_t period_lo, uint16_t period_hi)
{
/* 0x52550x526a: period saturation. */
if (period_hi > PERIOD_CLAMP_HI) {
period_lo = PERIOD_CLAMP_LO;
period_hi = PERIOD_CLAMP_HI;
} else if (period_hi == PERIOD_CLAMP_HI) {
if (period_lo > PERIOD_CLAMP_LO) {
period_lo = PERIOD_CLAMP_LO;
period_hi = PERIOD_CLAMP_HI;
}
}
/* 0x526f0x5274: load dividend RL1C = 0x0F000000. */
uint16_t rw1c = RPM_DIVIDEND_LO;
uint16_t rw1e = RPM_DIVIDEND_HI;
/* 0x52790x527c: if high word == 0, simple 32÷16 DIVU. */
if (period_hi == 0u) {
/* 0x527e: DIVU RL1C, RW80. */
if (period_lo == 0u) {
return 0;
}
uint32_t dividend = ((uint32_t)rw1e << 16) | (uint32_t)rw1c;
rw1c = (uint16_t)(dividend / (uint32_t)period_lo);
} else {
/* 0x52830x5295: long-period scaling loop. */
uint8_t shift_count = 0u;
uint32_t divisor = ((uint32_t)period_hi << 16) | (uint32_t)period_lo;
while ((divisor >> 16) != 0u) {
divisor >>= 1;
shift_count++;
}
uint32_t dividend = ((uint32_t)rw1e << 16) | (uint32_t)rw1c;
uint16_t scaled_divisor = (uint16_t)divisor;
if (scaled_divisor == 0u) {
return 0;
}
rw1c = (uint16_t)(dividend / (uint32_t)scaled_divisor);
/* 0x5292: SHR RW1C, R20 — rescale quotient. */
rw1c >>= shift_count;
}
return (int16_t)rw1c;
}
void phi_tooth_isr(phi_state_t *state,
const phi_cal_t *cal,
uint8_t current_tooth,
uint16_t current_capture)
{
runtime_state_t *rt = &state->rt;
/* 0x7aa40x7aa9: gate on phase comparand. */
if (current_tooth != cal->cal_byte_56) {
return;
}
/* First call after reset: seed snapshot, skip divide. */
if (!rt->mt_rpm_seeded) {
rt->mt_rpm_capture_prev = current_capture;
rt->mt_rpm_index_prev = 0u;
rt->rpm_baseline = 0;
rt->mt_rpm_seeded = 1u;
return;
}
/* 0x52470x524b: SUB RW80, RW64, [RW1C]+ / SUBC RW82, [RW1C]. */
uint16_t period_lo = (uint16_t)(current_capture - rt->mt_rpm_capture_prev);
uint16_t borrow = (current_capture < rt->mt_rpm_capture_prev) ? 1u : 0u;
uint16_t period_hi = (uint16_t)(0u - rt->mt_rpm_index_prev - borrow);
/* 0x524e0x5251: persist new snapshot. */
rt->mt_rpm_capture_prev = current_capture;
rt->mt_rpm_index_prev = 0u;
/* 0x52550x5298: helper → quotient. */
int16_t result = period_to_rpm_div(period_lo, period_hi);
/* 0x51ec: ST RW1C, 0x138. */
rt->rpm_baseline = result;
}
void phi_reset_tooth_state(phi_state_t *state)
{
runtime_state_t *rt = &state->rt;
rt->rpm_baseline = 0;
rt->mt_rpm_capture_prev = 0u;
rt->mt_rpm_index_prev = 0u;
rt->mt_rpm_seeded = 0u;
}
/*
* 1:1 translation of the RPM-hysteresis block at 0x78010x7825 inside
* the orphan scheduler at 0x77FF (T06211 variant). Bytes were not
@@ -1052,6 +1162,10 @@ void phi_init(phi_state_t *state, const phi_cal_t *cal,
* already zeroed rt->rw9c / rt->rw9e (mirrors FUN_6ba3 @ 0x6bbf0x6bc1). */
state->rt.temp_phi_comp_r94 = 100u;
/* Tooth-ISR pipeline: memset already zeroed mt_rpm_capture_prev,
* mt_rpm_index_prev, rpm_baseline, and mt_rpm_seeded — matching
* reset_toothed_wheel @ 0x5301 boot behaviour. */
/* Bake scratch_0221 = 1 — FUN_62a2's early-out gate. In the live
* ROM this is written by FUN_5a97 with an RPM-correlated condition
* via RW68 (whose actual writer lives in the unreadable ROM gap
@@ -1078,7 +1192,8 @@ void phi_service(phi_state_t *state, const phi_cal_t *cal, phi_outputs_t *out)
rt->inj_qty_demand = g->get_inj_qty_demand();
rt->angle_dec_cmd = g->get_angle_dec_cmd();
rt->temperature = g->get_temperature();
rt->rpm_baseline = g->get_rpm_baseline();
/* rpm_baseline is now produced internally by tooth_isr (FUN_51e1);
* no longer pulled from a getter. */
rt->rwc2 = g->get_rwc2();
rt->reset_gate_0226 = g->get_reset_gate_0226();
rt->dphi = g->get_dphi();

View File

@@ -102,7 +102,14 @@ typedef struct {
int16_t dphi; /* *(0x014c) — angle delta. */
/* ---- Inputs to FUN_732d (compute_accel_comp_offset) ---- */
int16_t rpm_baseline; /* *(0x0138) — slow RPM baseline. */
int16_t rpm_baseline; /* *(0x0138) — RPM baseline produced internally by tooth_isr
* (FUN_51e1 @ 0x51e1). No longer an external input. */
/* ---- Tooth-ISR pipeline state (FUN_51e1 @ 0x51e1 + FUN_5210 @ 0x5210) ---- */
uint16_t mt_rpm_capture_prev; /* *(0x02A8) — RW64 from previous phase-13 hit */
uint16_t mt_rpm_index_prev; /* *(0x02AA) — RW7E (capture index) at previous hit */
uint8_t mt_rpm_seeded; /* 0 = first phase-13 after reset; skip divide and seed only */
int16_t accel_comp_gain; /* *(0x0164) — Δ-rpm × gain multiplier. */
uint8_t reset_gate_0226; /* *(0x0226) — accel_comp_offset enable gate. */
uint8_t gate_0220; /* *(0x0220) — RPM-hysteresis gate. */
@@ -150,6 +157,7 @@ typedef struct {
int16_t tein_nominal; /* CAL[0x1e] — seed base added to tein_valve_fault_guard at 0x747b. */
int16_t cal_48; /* CAL[0x48] — value loaded into RW7A when FUN_62a2 fires (= 0x04B0). */
int16_t phi0; /* CAL[0x4c] — base/initial angle. */
uint8_t cal_byte_56; /* CAL_byte[0x56] — tooth phase comparand for rpm_baseline producer (= 0x0D = 13). */
uint8_t cal_byte_9c; /* CAL_byte[0x9c] — counter increment in FUN_62a2 (= 0x03). */
int16_t cal_54; /* CAL[0x54] — UPPER clamp on target_inj_angle at 0x7493. */
int16_t cal_74; /* CAL[0x74] — LOWER RPM threshold for gate_0220 hysteresis. */
@@ -216,7 +224,6 @@ typedef struct {
int16_t (*get_angle_dec_cmd)(void); /* RW42 */
uint16_t (*get_rpm)(void); /* RW40 */
int16_t (*get_temperature)(void); /* *(0x0146) */
int16_t (*get_rpm_baseline)(void); /* *(0x0138) */
uint16_t (*get_rwc2)(void); /* RWC2 */
uint8_t (*get_reset_gate_0226)(void); /* *(0x0226) */
int16_t (*get_dphi)(void); /* *(0x014c) */
@@ -251,6 +258,19 @@ void phi_service(phi_state_t *state,
* runtime_state_t. */
void phi_tick_1khz(phi_state_t *state, const phi_cal_t *cal);
/** Per-accepted-tooth ISR entry point. Updates rt->rpm_baseline when
* current_tooth == cal->cal_byte_56 (=13). No-op for other phases.
* The caller invokes this once per accepted tooth event at HSI.0 rate,
* separate from the phi_service scheduler cadence. */
void phi_tooth_isr(phi_state_t *state,
const phi_cal_t *cal,
uint8_t current_tooth,
uint16_t current_capture);
/** Clear the tooth-ISR pipeline (mirrors reset_toothed_wheel @ 0x5301).
* Next phi_tooth_isr call will seed without dividing. */
void phi_reset_tooth_state(phi_state_t *state);
size_t phi_state_size(void);
size_t phi_cal_size(void);

View File

@@ -159,6 +159,7 @@ calibration_t phi_t06215_cal = {
.tein_nominal = (int16_t)0x0C28, /* CAL+0x1E @ 0x9BF6 -- tein_nominal — nominal TE_IN base added to tein_valve_fault_guard / tein_overtemp_guard (T06211 FUN_7453 0x747b; T06215 FUN_74EA -- see README) */
.cal_48 = (int16_t)0x04B0, /* CAL+0x48 @ 0x9C20 -- RW7A latch value when FUN_62a2 fires (0x62d8) */
.phi0 = (int16_t)0x0DAB, /* CAL+0x4C @ 0x9C24 -- phi0: base/initial angle. ROM addend baked into phi1 (= *(0x014e)) by FUN_6aaf (0x6ad2); T06211 FUN_7453 reads phi0 + dphi at 0x74a2 */
.cal_byte_56 = 0x0Du, /* CAL+0x56 @ 0x9C2E -- tooth phase comparand for rpm_baseline producer (FUN_51e1 at Tooth_scheduler? 0x7aa4) */
.cal_byte_9c = 0x03u, /* CAL+0x9C @ 0x9C74 -- FUN_62a2 counter increment (0x62c6) */
.cal_54 = (int16_t)0x0B2B, /* CAL+0x54 @ 0x9C2C -- UPPER clamp on target_inj_angle (T06211 FUN_7453 0x7493) */
.cal_74 = (int16_t)0x20C5, /* CAL+0x74 @ 0x9C4C -- gate_0220 lower RPM threshold */

View File

@@ -1,6 +1,6 @@
/**
* @file phi.c
* @brief T06235 compact-port — monolithic single-translation-unit
* @brief T06215 compact-port — monolithic single-translation-unit
* implementation of the injection-angle producer chain.
*
* All seven producer stages and the shared submap helpers are inlined
@@ -579,7 +579,7 @@ void phi_tick_1khz(phi_state_t *state, const phi_cal_t *cal)
/*
* 1:1 translation of orphan calc_temp_comp_factor @ 0x6AE70x6B29
* (T06235 variant; algorithmically byte-equivalent to T06211 FUN_5DAB
* (T06215 variant; algorithmically byte-equivalent to T06211 FUN_5DAB
* @ 0x5DAB).
*
* Per-tick producer of `rt->temp_comp_factor` (the runtime mirror of
@@ -649,7 +649,7 @@ static void compute_temp_comp_factor(runtime_state_t *rt, const calibration_t *c
/*
* 1:1 translation of orphan compute_angle_kick_2d @ 0x6A940x6AE6
* (T06235 variant; algorithmically byte-equivalent to T06211 FUN_5D58
* (T06215 variant; algorithmically byte-equivalent to T06211 FUN_5D58
* @ 0x5D58).
*
* Per-tick producer of `rt->angle_kick_2d` (RW3E). Reached by
@@ -749,6 +749,116 @@ static void compute_accel_comp_offset(runtime_state_t *rt, const calibration_t *
(void)rw1c; /* rw1c is discarded after MUL; preserved for block-mapping */
}
/* ======================================================================
* tooth_isr / reset_tooth_state — port of FUN_51e1 @ 0x51e1 (producer)
* and FUN_5210 @ 0x5210 (DIVU helper) from the T06215 ROM.
*
* The producer fires once per cylinder when R88 == cal_byte_56 (= 13).
* It computes rpm_baseline = 0x0F000000 / period_ticks where period is
* the elapsed EPA timer ticks between two consecutive phase-13 hits.
* ====================================================================== */
/* 0x0F000000 = 251,658,240 — the fixed dividend (cal+0xA2:cal+0xA4). */
#define RPM_DIVIDEND_HI ((uint16_t)0x0F00u)
#define RPM_DIVIDEND_LO ((uint16_t)0x0000u)
/* Period saturation (cal+0xA6:cal+0xA8) = 0x001B7740 = 1,800,000 ticks. */
#define PERIOD_CLAMP_LO ((uint16_t)0x7740u)
#define PERIOD_CLAMP_HI ((uint16_t)0x001Bu)
/* 0x52100x529c: period_to_rpm_div helper (FUN_5210). */
static int16_t period_to_rpm_div(uint16_t period_lo, uint16_t period_hi)
{
/* 0x52550x526a: period saturation. */
if (period_hi > PERIOD_CLAMP_HI) {
period_lo = PERIOD_CLAMP_LO;
period_hi = PERIOD_CLAMP_HI;
} else if (period_hi == PERIOD_CLAMP_HI) {
if (period_lo > PERIOD_CLAMP_LO) {
period_lo = PERIOD_CLAMP_LO;
period_hi = PERIOD_CLAMP_HI;
}
}
/* 0x526f0x5274: load dividend RL1C = 0x0F000000. */
uint16_t rw1c = RPM_DIVIDEND_LO;
uint16_t rw1e = RPM_DIVIDEND_HI;
/* 0x52790x527c: if high word == 0, simple 32÷16 DIVU. */
if (period_hi == 0u) {
/* 0x527e: DIVU RL1C, RW80. */
if (period_lo == 0u) {
return 0;
}
uint32_t dividend = ((uint32_t)rw1e << 16) | (uint32_t)rw1c;
rw1c = (uint16_t)(dividend / (uint32_t)period_lo);
} else {
/* 0x52830x5295: long-period scaling loop. */
uint8_t shift_count = 0u;
uint32_t divisor = ((uint32_t)period_hi << 16) | (uint32_t)period_lo;
while ((divisor >> 16) != 0u) {
divisor >>= 1;
shift_count++;
}
uint32_t dividend = ((uint32_t)rw1e << 16) | (uint32_t)rw1c;
uint16_t scaled_divisor = (uint16_t)divisor;
if (scaled_divisor == 0u) {
return 0;
}
rw1c = (uint16_t)(dividend / (uint32_t)scaled_divisor);
/* 0x5292: SHR RW1C, R20 — rescale quotient. */
rw1c >>= shift_count;
}
return (int16_t)rw1c;
}
void phi_tooth_isr(phi_state_t *state,
const phi_cal_t *cal,
uint8_t current_tooth,
uint16_t current_capture)
{
runtime_state_t *rt = &state->rt;
/* 0x7aa40x7aa9: gate on phase comparand. */
if (current_tooth != cal->cal_byte_56) {
return;
}
/* First call after reset: seed snapshot, skip divide. */
if (!rt->mt_rpm_seeded) {
rt->mt_rpm_capture_prev = current_capture;
rt->mt_rpm_index_prev = 0u;
rt->rpm_baseline = 0;
rt->mt_rpm_seeded = 1u;
return;
}
/* 0x52470x524b: SUB RW80, RW64, [RW1C]+ / SUBC RW82, [RW1C]. */
uint16_t period_lo = (uint16_t)(current_capture - rt->mt_rpm_capture_prev);
uint16_t borrow = (current_capture < rt->mt_rpm_capture_prev) ? 1u : 0u;
uint16_t period_hi = (uint16_t)(0u - rt->mt_rpm_index_prev - borrow);
/* 0x524e0x5251: persist new snapshot. */
rt->mt_rpm_capture_prev = current_capture;
rt->mt_rpm_index_prev = 0u;
/* 0x52550x5298: helper → quotient. */
int16_t result = period_to_rpm_div(period_lo, period_hi);
/* 0x51ec: ST RW1C, 0x138. */
rt->rpm_baseline = result;
}
void phi_reset_tooth_state(phi_state_t *state)
{
runtime_state_t *rt = &state->rt;
rt->rpm_baseline = 0;
rt->mt_rpm_capture_prev = 0u;
rt->mt_rpm_index_prev = 0u;
rt->mt_rpm_seeded = 0u;
}
/*
* 1:1 translation of the RPM-hysteresis block at 0x78010x7825 inside
* the orphan scheduler at 0x77FF (T06211 variant). Bytes were not
@@ -1035,7 +1145,7 @@ void phi_init(phi_state_t *state, const phi_cal_t *cal,
* input_var field is runtime-bound by design (the C model treats the
* cal as a writable buffer, not flash-resident, since extract_*.py
* emits a non-const initializer for this very reason). */
phi_t06235_bind_inputs(&state->rt, (phi_cal_t *)cal);
phi_t06215_bind_inputs(&state->rt, (phi_cal_t *)cal);
/* Pull boot-only getters — Phase-1 / Phase-2 thresholds for the
* FUN_62a2 state machine. */
@@ -1052,6 +1162,10 @@ void phi_init(phi_state_t *state, const phi_cal_t *cal,
* already zeroed rt->rw9c / rt->rw9e (mirrors FUN_6ba3 @ 0x6bbf0x6bc1). */
state->rt.temp_phi_comp_r94 = 100u;
/* Tooth-ISR pipeline: memset already zeroed mt_rpm_capture_prev,
* mt_rpm_index_prev, rpm_baseline, and mt_rpm_seeded — matching
* reset_toothed_wheel @ 0x5301 boot behaviour. */
/* Bake scratch_0221 = 1 — FUN_62a2's early-out gate. In the live
* ROM this is written by FUN_5a97 with an RPM-correlated condition
* via RW68 (whose actual writer lives in the unreadable ROM gap
@@ -1078,7 +1192,8 @@ void phi_service(phi_state_t *state, const phi_cal_t *cal, phi_outputs_t *out)
rt->inj_qty_demand = g->get_inj_qty_demand();
rt->angle_dec_cmd = g->get_angle_dec_cmd();
rt->temperature = g->get_temperature();
rt->rpm_baseline = g->get_rpm_baseline();
/* rpm_baseline is now produced internally by tooth_isr (FUN_51e1);
* no longer pulled from a getter. */
rt->rwc2 = g->get_rwc2();
rt->reset_gate_0226 = g->get_reset_gate_0226();
rt->dphi = g->get_dphi();

View File

@@ -1,16 +1,6 @@
/**
* @file phi.h
* @brief T06235 injection-angle algorithm — compact public interface.
*
* AUTO-GENERATED by tools/extract_t06235_cal.py
* Source ROM: rom_eeprom_dump_0000-9FFF_504042.bin
* Bases: RWA4 = 0x9BB8, RWC6 = 0x8002
*
* Cal scalars from offset 0x48 onwards are shifted +0x02 vs T06215.
* Field names retain T06215 semantics so forked C bodies reuse unchanged.
*
* DO NOT EDIT -- regenerate with:
* python tools/extract_t06235_cal.py --target compact
* @brief T06215 injection-angle algorithm — compact public interface.
*
* AUTO-GENERATED by tools/extract_t06215_cal.py
* Source ROM: rom_eeprom_dump_0000-9FFF_424026.bin
@@ -20,7 +10,7 @@
* python tools/extract_t06215_cal.py --target compact
*
* Companion to phi.c (single-translation-unit port of the per-function
* verbose tree under variants/T06235/src/) and the auto-generated
* verbose tree under variants/T06215/src/) and the auto-generated
* phi_cal_tables.c. Callers see only this header; embedded
* `runtime_state_t` / `calibration_t` fields are IMPLEMENTATION DETAIL
* — touch only the outputs struct and the getter vtable.
@@ -29,7 +19,7 @@
*
* phi_input_getters_t getters = { .get_rpm = ..., ... };
* phi_state_t state;
* phi_cal_t cal = phi_t06235_cal; // copy from auto-extracted master
* phi_cal_t cal = phi_t06215_cal; // copy from auto-extracted master
* phi_outputs_t out;
*
* phi_init(&state, &cal, &getters); // boot-once
@@ -51,20 +41,20 @@
*
* The orphan temperature-kick chain (compute_temp_comp_factor → orphan
* FUN_5D58 angle_kick + `RW52 += RW3E` fold-in @ 0x7A3E) is ported in
* variants/T06235/src/ and wired into this compact phi_service.
* variants/T06215/src/ and wired into this compact phi_service.
* RW9E (the IIR state high word consumed by compute_temp_comp_factor)
* is produced internally by compute_temp_phi_comp — see
* compute_temp_phi_comp.h for the 1 kHz hook the host must drive.
* See variants/T06211/docs/open-questions.md §9.
*/
#ifndef PHI_T06235_H
#define PHI_T06235_H
#ifndef PHI_T06215_H
#define PHI_T06215_H
#include <stdint.h>
#include <stddef.h>
/* ─── Internal runtime / calibration types ───────────────────────────
* Inlined verbatim from variants/T06235/src/injection_angle_state.h.
* Inlined verbatim from variants/T06215/src/injection_angle_state.h.
* Treat all fields as IMPLEMENTATION DETAIL — see the lifecycle
* comment above; the supported surface is `phi_outputs_t` and the
* getter vtable. */
@@ -112,7 +102,14 @@ typedef struct {
int16_t dphi; /* *(0x014c) — angle delta. */
/* ---- Inputs to FUN_732d (compute_accel_comp_offset) ---- */
int16_t rpm_baseline; /* *(0x0138) — slow RPM baseline. */
int16_t rpm_baseline; /* *(0x0138) — RPM baseline produced internally by tooth_isr
* (FUN_51e1 @ 0x51e1). No longer an external input. */
/* ---- Tooth-ISR pipeline state (FUN_51e1 @ 0x51e1 + FUN_5210 @ 0x5210) ---- */
uint16_t mt_rpm_capture_prev; /* *(0x02A8) — RW64 from previous phase-13 hit */
uint16_t mt_rpm_index_prev; /* *(0x02AA) — RW7E (capture index) at previous hit */
uint8_t mt_rpm_seeded; /* 0 = first phase-13 after reset; skip divide and seed only */
int16_t accel_comp_gain; /* *(0x0164) — Δ-rpm × gain multiplier. */
uint8_t reset_gate_0226; /* *(0x0226) — accel_comp_offset enable gate. */
uint8_t gate_0220; /* *(0x0220) — RPM-hysteresis gate. */
@@ -160,6 +157,7 @@ typedef struct {
int16_t tein_nominal; /* CAL[0x1e] — seed base added to tein_valve_fault_guard at 0x747b. */
int16_t cal_48; /* CAL[0x48] — value loaded into RW7A when FUN_62a2 fires (= 0x04B0). */
int16_t phi0; /* CAL[0x4c] — base/initial angle. */
uint8_t cal_byte_56; /* CAL_byte[0x56] — tooth phase comparand for rpm_baseline producer (= 0x0D = 13). */
uint8_t cal_byte_9c; /* CAL_byte[0x9c] — counter increment in FUN_62a2 (= 0x03). */
int16_t cal_54; /* CAL[0x54] — UPPER clamp on target_inj_angle at 0x7493. */
int16_t cal_74; /* CAL[0x74] — LOWER RPM threshold for gate_0220 hysteresis. */
@@ -226,7 +224,6 @@ typedef struct {
int16_t (*get_angle_dec_cmd)(void); /* RW42 */
uint16_t (*get_rpm)(void); /* RW40 */
int16_t (*get_temperature)(void); /* *(0x0146) */
int16_t (*get_rpm_baseline)(void); /* *(0x0138) */
uint16_t (*get_rwc2)(void); /* RWC2 */
uint8_t (*get_reset_gate_0226)(void); /* *(0x0226) */
int16_t (*get_dphi)(void); /* *(0x014c) */
@@ -261,13 +258,26 @@ void phi_service(phi_state_t *state,
* runtime_state_t. */
void phi_tick_1khz(phi_state_t *state, const phi_cal_t *cal);
/** Per-accepted-tooth ISR entry point. Updates rt->rpm_baseline when
* current_tooth == cal->cal_byte_56 (=13). No-op for other phases.
* The caller invokes this once per accepted tooth event at HSI.0 rate,
* separate from the phi_service scheduler cadence. */
void phi_tooth_isr(phi_state_t *state,
const phi_cal_t *cal,
uint8_t current_tooth,
uint16_t current_capture);
/** Clear the tooth-ISR pipeline (mirrors reset_toothed_wheel @ 0x5301).
* Next phi_tooth_isr call will seed without dividing. */
void phi_reset_tooth_state(phi_state_t *state);
size_t phi_state_size(void);
size_t phi_cal_size(void);
/* ─── Auto-generated cal export (defined in phi_cal_tables.c) ──────── */
extern calibration_t phi_t06235_cal;
extern calibration_t phi_t06215_cal;
void phi_t06235_bind_inputs(runtime_state_t *rt, calibration_t *cal);
void phi_t06215_bind_inputs(runtime_state_t *rt, calibration_t *cal);
#endif /* PHI_T06235_H */
#endif /* PHI_T06215_H */

View File

@@ -1,179 +1,185 @@
/**
* @file phi_cal_tables.c
* @brief T06235 compact-port calibration data (auto-generated).
* @brief T06215 compact-port calibration data (auto-generated).
*
* AUTO-GENERATED by tools/extract_t06235_cal.py
* Source ROM: rom_eeprom_dump_0000-9FFF_504042.bin
* Bases: RWA4 = 0x9BB8, RWC6 = 0x8002
*
* Cal scalars from offset 0x48 onwards are shifted +0x02 vs T06215.
* Field names retain T06215 semantics so forked C bodies reuse unchanged.
* AUTO-GENERATED by tools/extract_t06215_cal.py
* Source ROM: rom_eeprom_dump_0000-9FFF_424026.bin
* Bases: RWA4 = 0x9BD8, RWC6 = 0x7E56
*
* DO NOT EDIT -- regenerate with:
* python tools/extract_t06235_cal.py --target compact
* python tools/extract_t06215_cal.py --target compact
*/
#include <stddef.h>
#include "phi.h"
/* Accel RPM axis -- 7 words @ 0x9D34. */
/* ======================================================================
* Accel axes + data tables (file-local; expose only phi_t06215_cal).
* Angle accumulator axes + 3-D table (FUN_722e producer chain).
* ====================================================================== */
/* Accel RPM axis -- 7 words @ 0x9D40. */
static const int16_t phi_accel_axis_rpm[7] = {
(int16_t)0x4B5E, (int16_t)0x3127, (int16_t)0x16F0, (int16_t)0x1206, (int16_t)0x09D5, (int16_t)0x068E, (int16_t)0x0000
};
/* Accel inj_qty_demand axis -- 6 words @ 0x9D42. */
/* Accel inj_qty_demand axis -- 6 words @ 0x9D4E. */
static const int16_t phi_accel_axis_demand[6] = {
(int16_t)0x08C0, (int16_t)0x0640, (int16_t)0x0460, (int16_t)0x0280, (int16_t)0x01E0, (int16_t)0x0000
};
/* Accel temperature axis -- 5 words @ 0x9D4E. */
/* Accel temperature axis -- 5 words @ 0x9D5A. */
static const int16_t phi_accel_axis_temp[5] = {
(int16_t)0x12F0, (int16_t)0x1250, (int16_t)0x1110, (int16_t)0x0FD0, (int16_t)0x0000
};
/* Accel 2-D combine (RPM x demand) -- 42 words @ 0x9D58. */
/* Accel 2-D combine (RPM x demand) -- 42 words @ 0x9D64. */
static const int16_t phi_accel_combine_table[42] = {
(int16_t)0x0000, (int16_t)0x01F8, (int16_t)0x0500, (int16_t)0x07E4, (int16_t)0x07E4, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x01F8, (int16_t)0x0500,
(int16_t)0x07E4, (int16_t)0x07E4, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x01F8, (int16_t)0x0500, (int16_t)0x07E4, (int16_t)0x07E4, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x01F8, (int16_t)0x0500, (int16_t)0x07E4, (int16_t)0x07E4, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x01F8,
(int16_t)0x0500, (int16_t)0x07E4, (int16_t)0x07E4, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x01F8, (int16_t)0x0500, (int16_t)0x07E4, (int16_t)0x07E4,
(int16_t)0x0000, (int16_t)0x020A, (int16_t)0x052C, (int16_t)0x082A, (int16_t)0x082A, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x020A, (int16_t)0x052C,
(int16_t)0x082A, (int16_t)0x082A, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x020A, (int16_t)0x052C, (int16_t)0x082A, (int16_t)0x082A, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x020A, (int16_t)0x052C, (int16_t)0x082A, (int16_t)0x082A, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x020A,
(int16_t)0x052C, (int16_t)0x082A, (int16_t)0x082A, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x020A, (int16_t)0x052C, (int16_t)0x082A, (int16_t)0x082A,
(int16_t)0x0000, (int16_t)0x0000
};
/* Accel 1-D refine (temperature) -- 5 words @ 0x9DAC. */
/* Accel 1-D refine (temperature) -- 5 words @ 0x9DB8. */
static const int16_t phi_accel_refine_table[5] = {
(int16_t)0x00FF, (int16_t)0x00FF, (int16_t)0x00FF, (int16_t)0x00FF, (int16_t)0x00FF
};
/* Angle RPM axis -- 13 words @ 0x8038. */
/* Angle RPM axis -- 13 words @ 0x7E8C. */
static const int16_t phi_angle_axis_rpm[13] = {
(int16_t)0x4EA5, (int16_t)0x4817, (int16_t)0x4189, (int16_t)0x3AFB, (int16_t)0x346E, (int16_t)0x2DE0, (int16_t)0x240B, (int16_t)0x1A37, (int16_t)0x1206, (int16_t)0x0B78,
(int16_t)0x4B5E, (int16_t)0x4674, (int16_t)0x4189, (int16_t)0x3AFB, (int16_t)0x346E, (int16_t)0x2DE0, (int16_t)0x240B, (int16_t)0x1A37, (int16_t)0x13A9, (int16_t)0x0D1B,
(int16_t)0x068E, (int16_t)0x0347, (int16_t)0x0000
};
/* Angle inj_qty_demand axis -- 15 words @ 0x8052. */
/* Angle inj_qty_demand axis -- 15 words @ 0x7EA6. */
static const int16_t phi_angle_axis_demand[15] = {
(int16_t)0x0F90, (int16_t)0x0C73, (int16_t)0x0A60, (int16_t)0x084D, (int16_t)0x0743, (int16_t)0x063A, (int16_t)0x0530, (int16_t)0x0426, (int16_t)0x031D, (int16_t)0x0213,
(int16_t)0x0F90, (int16_t)0x0C73, (int16_t)0x0A60, (int16_t)0x0956, (int16_t)0x08D2, (int16_t)0x07C8, (int16_t)0x063A, (int16_t)0x04AB, (int16_t)0x031D, (int16_t)0x0213,
(int16_t)0x010A, (int16_t)0x0085, (int16_t)0x0035, (int16_t)0x000D, (int16_t)0x0000
};
/* Angle angle_dec_cmd axis -- 3 words @ 0x8070. */
/* Angle angle_dec_cmd axis -- 3 words @ 0x7EC4. */
static const int16_t phi_angle_axis_dec_cmd[3] = {
(int16_t)0x0300, (int16_t)0x01C4, (int16_t)0x0000
};
/* 3-D angle combine (RPM x demand x angle_dec_cmd) -- 585 words @ 0x8076. */
/* 3-D angle combine (RPM x demand x angle_dec_cmd) -- 585 words @ 0x7ECA. */
static const int16_t phi_angle_3d_table[585] = {
(int16_t)0x05F8, (int16_t)0x0838, (int16_t)0x08EE, (int16_t)0x09B4, (int16_t)0x0A3A, (int16_t)0x0927, (int16_t)0x0781, (int16_t)0x05E0, (int16_t)0x0494, (int16_t)0x03EC,
(int16_t)0x03CD, (int16_t)0x04A2, (int16_t)0x04A2, (int16_t)0x05F8, (int16_t)0x0838, (int16_t)0x08EE, (int16_t)0x09B4, (int16_t)0x0A3A, (int16_t)0x0927, (int16_t)0x0781,
(int16_t)0x05E0, (int16_t)0x0494, (int16_t)0x03EC, (int16_t)0x0331, (int16_t)0x039C, (int16_t)0x039C, (int16_t)0x05F8, (int16_t)0x0838, (int16_t)0x08EE, (int16_t)0x09B4,
(int16_t)0x0A3A, (int16_t)0x0927, (int16_t)0x0781, (int16_t)0x05E0, (int16_t)0x0494, (int16_t)0x037A, (int16_t)0x02C9, (int16_t)0x02ED, (int16_t)0x02ED, (int16_t)0x05F8,
(int16_t)0x0838, (int16_t)0x08EE, (int16_t)0x09B4, (int16_t)0x08D1, (int16_t)0x07F4, (int16_t)0x0692, (int16_t)0x052E, (int16_t)0x0400, (int16_t)0x0314, (int16_t)0x0277,
(int16_t)0x0276, (int16_t)0x0276, (int16_t)0x05F8, (int16_t)0x0838, (int16_t)0x08EE, (int16_t)0x08EE, (int16_t)0x081F, (int16_t)0x0753, (int16_t)0x0615, (int16_t)0x04C6,
(int16_t)0x03BE, (int16_t)0x02D9, (int16_t)0x0252, (int16_t)0x021E, (int16_t)0x021E, (int16_t)0x0601, (int16_t)0x0841, (int16_t)0x08F7, (int16_t)0x0833, (int16_t)0x077B,
(int16_t)0x06C3, (int16_t)0x059A, (int16_t)0x046B, (int16_t)0x0375, (int16_t)0x029E, (int16_t)0x0228, (int16_t)0x0204, (int16_t)0x0204, (int16_t)0x060B, (int16_t)0x084B,
(int16_t)0x082C, (int16_t)0x0783, (int16_t)0x06DC, (int16_t)0x063B, (int16_t)0x0527, (int16_t)0x0406, (int16_t)0x032F, (int16_t)0x026D, (int16_t)0x0204, (int16_t)0x01E8,
(int16_t)0x01E8, (int16_t)0x0614, (int16_t)0x0854, (int16_t)0x07A2, (int16_t)0x0700, (int16_t)0x065D, (int16_t)0x05C2, (int16_t)0x04BD, (int16_t)0x03B4, (int16_t)0x02E6,
(int16_t)0x0242, (int16_t)0x01E9, (int16_t)0x0175, (int16_t)0x0175, (int16_t)0x0624, (int16_t)0x0798, (int16_t)0x06F3, (int16_t)0x0664, (int16_t)0x05DD, (int16_t)0x0554,
(int16_t)0x045A, (int16_t)0x0358, (int16_t)0x02A2, (int16_t)0x0217, (int16_t)0x01D0, (int16_t)0x0160, (int16_t)0x0160, (int16_t)0x0634, (int16_t)0x0725, (int16_t)0x0685,
(int16_t)0x05E7, (int16_t)0x054A, (int16_t)0x04C4, (int16_t)0x03DF, (int16_t)0x030D, (int16_t)0x025A, (int16_t)0x01D7, (int16_t)0x01B0, (int16_t)0x014C, (int16_t)0x014C,
(int16_t)0x0634, (int16_t)0x060F, (int16_t)0x059B, (int16_t)0x0534, (int16_t)0x04A9, (int16_t)0x042E, (int16_t)0x0381, (int16_t)0x02C1, (int16_t)0x021C, (int16_t)0x0198,
(int16_t)0x018C, (int16_t)0x0134, (int16_t)0x0134, (int16_t)0x0634, (int16_t)0x05F0, (int16_t)0x056A, (int16_t)0x0503, (int16_t)0x0476, (int16_t)0x0404, (int16_t)0x034D,
(int16_t)0x02AA, (int16_t)0x01FB, (int16_t)0x0186, (int16_t)0x017B, (int16_t)0x0128, (int16_t)0x0128, (int16_t)0x0634, (int16_t)0x05CE, (int16_t)0x054E, (int16_t)0x04E7,
(int16_t)0x045D, (int16_t)0x03D4, (int16_t)0x0323, (int16_t)0x027D, (int16_t)0x01ED, (int16_t)0x017E, (int16_t)0x016C, (int16_t)0x0121, (int16_t)0x0121, (int16_t)0x0634,
(int16_t)0x05B4, (int16_t)0x0534, (int16_t)0x04CE, (int16_t)0x0443, (int16_t)0x03C8, (int16_t)0x0309, (int16_t)0x0263, (int16_t)0x01D4, (int16_t)0x0168, (int16_t)0x0164,
(int16_t)0x011C, (int16_t)0x011C, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x06AC, (int16_t)0x094A, (int16_t)0x09DC, (int16_t)0x0A89, (int16_t)0x0AF5,
(int16_t)0x09D9, (int16_t)0x083A, (int16_t)0x06A5, (int16_t)0x054E, (int16_t)0x04AE, (int16_t)0x045E, (int16_t)0x046B, (int16_t)0x046B, (int16_t)0x06AC, (int16_t)0x094A,
(int16_t)0x09DC, (int16_t)0x0A89, (int16_t)0x0AF5, (int16_t)0x09D9, (int16_t)0x083A, (int16_t)0x06A5, (int16_t)0x054E, (int16_t)0x04AE, (int16_t)0x03D3, (int16_t)0x03F3,
(int16_t)0x03F3, (int16_t)0x06AC, (int16_t)0x094A, (int16_t)0x09DC, (int16_t)0x0A89, (int16_t)0x0AF5, (int16_t)0x09D9, (int16_t)0x083A, (int16_t)0x06A5, (int16_t)0x054E,
(int16_t)0x044F, (int16_t)0x0376, (int16_t)0x03A2, (int16_t)0x03A2, (int16_t)0x06AC, (int16_t)0x094A, (int16_t)0x09DC, (int16_t)0x0A89, (int16_t)0x09A3, (int16_t)0x08B0,
(int16_t)0x0755, (int16_t)0x05F2, (int16_t)0x04C6, (int16_t)0x03E5, (int16_t)0x0330, (int16_t)0x02F3, (int16_t)0x02F3, (int16_t)0x06AC, (int16_t)0x094A, (int16_t)0x09DC,
(int16_t)0x09D6, (int16_t)0x08F2, (int16_t)0x081C, (int16_t)0x06DB, (int16_t)0x0594, (int16_t)0x047C, (int16_t)0x03B0, (int16_t)0x0314, (int16_t)0x02E3, (int16_t)0x02E3,
(int16_t)0x06B5, (int16_t)0x0953, (int16_t)0x09E5, (int16_t)0x091B, (int16_t)0x0852, (int16_t)0x078D, (int16_t)0x065F, (int16_t)0x053D, (int16_t)0x0436, (int16_t)0x037E,
(int16_t)0x02ED, (int16_t)0x02CF, (int16_t)0x02CF, (int16_t)0x06BF, (int16_t)0x095D, (int16_t)0x0938, (int16_t)0x087C, (int16_t)0x07BE, (int16_t)0x070A, (int16_t)0x05F5,
(int16_t)0x04E2, (int16_t)0x03F9, (int16_t)0x034E, (int16_t)0x02C2, (int16_t)0x02B9, (int16_t)0x02B9, (int16_t)0x06C8, (int16_t)0x0966, (int16_t)0x0895, (int16_t)0x07E0,
(int16_t)0x0735, (int16_t)0x068B, (int16_t)0x058A, (int16_t)0x048B, (int16_t)0x03BC, (int16_t)0x031E, (int16_t)0x029F, (int16_t)0x0238, (int16_t)0x0238, (int16_t)0x06D8,
(int16_t)0x08B9, (int16_t)0x07F6, (int16_t)0x075B, (int16_t)0x06B2, (int16_t)0x060D, (int16_t)0x0518, (int16_t)0x042C, (int16_t)0x0375, (int16_t)0x02ED, (int16_t)0x027D,
(int16_t)0x0221, (int16_t)0x0221, (int16_t)0x06E8, (int16_t)0x07BA, (int16_t)0x0734, (int16_t)0x06B7, (int16_t)0x061E, (int16_t)0x0585, (int16_t)0x04B2, (int16_t)0x03D1,
(int16_t)0x032B, (int16_t)0x02BB, (int16_t)0x025F, (int16_t)0x0210, (int16_t)0x0210, (int16_t)0x06E8, (int16_t)0x071E, (int16_t)0x06A8, (int16_t)0x0623, (int16_t)0x0589,
(int16_t)0x0500, (int16_t)0x043F, (int16_t)0x0372, (int16_t)0x02D9, (int16_t)0x0284, (int16_t)0x023E, (int16_t)0x01F8, (int16_t)0x01F8, (int16_t)0x06E8, (int16_t)0x0707,
(int16_t)0x066E, (int16_t)0x05EB, (int16_t)0x055B, (int16_t)0x04E0, (int16_t)0x0424, (int16_t)0x0357, (int16_t)0x02BD, (int16_t)0x026A, (int16_t)0x022D, (int16_t)0x01EC,
(int16_t)0x01EC, (int16_t)0x06E8, (int16_t)0x06E1, (int16_t)0x064E, (int16_t)0x05C8, (int16_t)0x053F, (int16_t)0x04C3, (int16_t)0x0406, (int16_t)0x0341, (int16_t)0x02AF,
(int16_t)0x025B, (int16_t)0x0225, (int16_t)0x01E4, (int16_t)0x01E4, (int16_t)0x06E8, (int16_t)0x06C5, (int16_t)0x0631, (int16_t)0x05AC, (int16_t)0x052A, (int16_t)0x04A0,
(int16_t)0x03E5, (int16_t)0x032D, (int16_t)0x0297, (int16_t)0x0243, (int16_t)0x0210, (int16_t)0x01CF, (int16_t)0x01CF, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x0508, (int16_t)0x07FB, (int16_t)0x0A1A, (int16_t)0x097B, (int16_t)0x08AD, (int16_t)0x07A5, (int16_t)0x0654, (int16_t)0x04FF, (int16_t)0x046F, (int16_t)0x03A0,
(int16_t)0x034F, (int16_t)0x02A7, (int16_t)0x02A7, (int16_t)0x0508, (int16_t)0x07FB, (int16_t)0x0A1A, (int16_t)0x097B, (int16_t)0x08AD, (int16_t)0x07A5, (int16_t)0x0654,
(int16_t)0x04FF, (int16_t)0x046F, (int16_t)0x03A0, (int16_t)0x034F, (int16_t)0x02A7, (int16_t)0x02A7, (int16_t)0x0508, (int16_t)0x07FB, (int16_t)0x0A1A, (int16_t)0x097B,
(int16_t)0x08AD, (int16_t)0x07A5, (int16_t)0x0654, (int16_t)0x04FF, (int16_t)0x046F, (int16_t)0x03A0, (int16_t)0x02F4, (int16_t)0x0238, (int16_t)0x0238, (int16_t)0x0508,
(int16_t)0x07FB, (int16_t)0x0A1A, (int16_t)0x097B, (int16_t)0x08AD, (int16_t)0x07A5, (int16_t)0x0654, (int16_t)0x04FF, (int16_t)0x042A, (int16_t)0x0367, (int16_t)0x02BB,
(int16_t)0x020C, (int16_t)0x020C, (int16_t)0x0508, (int16_t)0x07FB, (int16_t)0x0A1A, (int16_t)0x0956, (int16_t)0x086A, (int16_t)0x0772, (int16_t)0x0620, (int16_t)0x04D4,
(int16_t)0x0407, (int16_t)0x034F, (int16_t)0x02A4, (int16_t)0x01FA, (int16_t)0x01FA, (int16_t)0x0506, (int16_t)0x07F9, (int16_t)0x0974, (int16_t)0x0892, (int16_t)0x07C3,
(int16_t)0x06F0, (int16_t)0x05BA, (int16_t)0x0490, (int16_t)0x03C7, (int16_t)0x031C, (int16_t)0x0271, (int16_t)0x01D4, (int16_t)0x01D4, (int16_t)0x0504, (int16_t)0x07F7,
(int16_t)0x0838, (int16_t)0x0787, (int16_t)0x06D2, (int16_t)0x0628, (int16_t)0x050A, (int16_t)0x0413, (int16_t)0x036D, (int16_t)0x02DA, (int16_t)0x0229, (int16_t)0x019C,
(int16_t)0x019C, (int16_t)0x0501, (int16_t)0x07F4, (int16_t)0x0766, (int16_t)0x06C4, (int16_t)0x0626, (int16_t)0x0576, (int16_t)0x0487, (int16_t)0x039A, (int16_t)0x030F,
(int16_t)0x0291, (int16_t)0x01DE, (int16_t)0x0167, (int16_t)0x0167, (int16_t)0x04FF, (int16_t)0x06F4, (int16_t)0x068B, (int16_t)0x0600, (int16_t)0x057C, (int16_t)0x04EE,
(int16_t)0x03F4, (int16_t)0x031F, (int16_t)0x02A0, (int16_t)0x0231, (int16_t)0x018C, (int16_t)0x0140, (int16_t)0x0140, (int16_t)0x04FD, (int16_t)0x0661, (int16_t)0x05F9,
(int16_t)0x0582, (int16_t)0x04F9, (int16_t)0x0480, (int16_t)0x03AA, (int16_t)0x02D0, (int16_t)0x0261, (int16_t)0x01E6, (int16_t)0x0164, (int16_t)0x0121, (int16_t)0x0121,
(int16_t)0x04FD, (int16_t)0x05FD, (int16_t)0x059B, (int16_t)0x0524, (int16_t)0x04A7, (int16_t)0x041E, (int16_t)0x0363, (int16_t)0x029E, (int16_t)0x020E, (int16_t)0x0190,
(int16_t)0x0136, (int16_t)0x0103, (int16_t)0x0103, (int16_t)0x04FD, (int16_t)0x0593, (int16_t)0x0530, (int16_t)0x04C0, (int16_t)0x045A, (int16_t)0x03EF, (int16_t)0x0325,
(int16_t)0x0260, (int16_t)0x01E7, (int16_t)0x0158, (int16_t)0x011B, (int16_t)0x00AB, (int16_t)0x00AB, (int16_t)0x04FD, (int16_t)0x0523, (int16_t)0x04CB, (int16_t)0x0461,
(int16_t)0x03F5, (int16_t)0x038F, (int16_t)0x02EB, (int16_t)0x022F, (int16_t)0x01B1, (int16_t)0x0138, (int16_t)0x00BB, (int16_t)0x009B, (int16_t)0x009B, (int16_t)0x04FD,
(int16_t)0x04E5, (int16_t)0x0492, (int16_t)0x041D, (int16_t)0x03B0, (int16_t)0x034F, (int16_t)0x029C, (int16_t)0x01F1, (int16_t)0x0178, (int16_t)0x011B, (int16_t)0x00AE,
(int16_t)0x008B, (int16_t)0x008B, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0648, (int16_t)0x08FE, (int16_t)0x0B09, (int16_t)0x0A71, (int16_t)0x0972,
(int16_t)0x0889, (int16_t)0x0729, (int16_t)0x05D6, (int16_t)0x0552, (int16_t)0x046C, (int16_t)0x0420, (int16_t)0x035C, (int16_t)0x035C, (int16_t)0x0648, (int16_t)0x08FE,
(int16_t)0x0B09, (int16_t)0x0A71, (int16_t)0x0972, (int16_t)0x0889, (int16_t)0x0729, (int16_t)0x05D6, (int16_t)0x0552, (int16_t)0x046C, (int16_t)0x0420, (int16_t)0x035C,
(int16_t)0x035C, (int16_t)0x0648, (int16_t)0x08FE, (int16_t)0x0B09, (int16_t)0x0A71, (int16_t)0x0972, (int16_t)0x0889, (int16_t)0x0729, (int16_t)0x05D6, (int16_t)0x0552,
(int16_t)0x046C, (int16_t)0x03C1, (int16_t)0x0314, (int16_t)0x0314, (int16_t)0x0648, (int16_t)0x08FE, (int16_t)0x0B09, (int16_t)0x0A71, (int16_t)0x0972, (int16_t)0x0889,
(int16_t)0x0729, (int16_t)0x05D6, (int16_t)0x050F, (int16_t)0x043B, (int16_t)0x039A, (int16_t)0x02EE, (int16_t)0x02EE, (int16_t)0x0648, (int16_t)0x08FE, (int16_t)0x0B09,
(int16_t)0x0A19, (int16_t)0x092F, (int16_t)0x084F, (int16_t)0x06F8, (int16_t)0x05AF, (int16_t)0x04ED, (int16_t)0x0425, (int16_t)0x0384, (int16_t)0x02D9, (int16_t)0x02D9,
(int16_t)0x0646, (int16_t)0x08FC, (int16_t)0x0A4D, (int16_t)0x0975, (int16_t)0x089C, (int16_t)0x07D0, (int16_t)0x0697, (int16_t)0x0564, (int16_t)0x04B1, (int16_t)0x03F8,
(int16_t)0x0351, (int16_t)0x02AF, (int16_t)0x02AF, (int16_t)0x0644, (int16_t)0x08FA, (int16_t)0x0939, (int16_t)0x086F, (int16_t)0x07B7, (int16_t)0x0711, (int16_t)0x0602,
(int16_t)0x04FA, (int16_t)0x0458, (int16_t)0x03B0, (int16_t)0x0305, (int16_t)0x0280, (int16_t)0x0280, (int16_t)0x0641, (int16_t)0x08F7, (int16_t)0x0867, (int16_t)0x07B6,
(int16_t)0x0707, (int16_t)0x066B, (int16_t)0x0570, (int16_t)0x0488, (int16_t)0x03FA, (int16_t)0x035E, (int16_t)0x02B1, (int16_t)0x0251, (int16_t)0x0251, (int16_t)0x063F,
(int16_t)0x07FB, (int16_t)0x077B, (int16_t)0x06E4, (int16_t)0x063D, (int16_t)0x05CB, (int16_t)0x04E8, (int16_t)0x040E, (int16_t)0x03A1, (int16_t)0x031B, (int16_t)0x0273,
(int16_t)0x021C, (int16_t)0x021C, (int16_t)0x063D, (int16_t)0x0761, (int16_t)0x06E7, (int16_t)0x064D, (int16_t)0x05BF, (int16_t)0x0552, (int16_t)0x048A, (int16_t)0x03BE,
(int16_t)0x0354, (int16_t)0x02D6, (int16_t)0x0238, (int16_t)0x01F5, (int16_t)0x01F5, (int16_t)0x063D, (int16_t)0x06C1, (int16_t)0x0666, (int16_t)0x05DA, (int16_t)0x0574,
(int16_t)0x04FF, (int16_t)0x0421, (int16_t)0x0361, (int16_t)0x02EA, (int16_t)0x0274, (int16_t)0x0201, (int16_t)0x01D2, (int16_t)0x01D2, (int16_t)0x063D, (int16_t)0x0663,
(int16_t)0x05F9, (int16_t)0x0586, (int16_t)0x0527, (int16_t)0x04B7, (int16_t)0x03E0, (int16_t)0x0316, (int16_t)0x02A2, (int16_t)0x0239, (int16_t)0x01A0, (int16_t)0x016B,
(int16_t)0x016B, (int16_t)0x063D, (int16_t)0x063D, (int16_t)0x05CF, (int16_t)0x0553, (int16_t)0x04FB, (int16_t)0x048E, (int16_t)0x03C6, (int16_t)0x02E9, (int16_t)0x0275,
(int16_t)0x01FB, (int16_t)0x0166, (int16_t)0x012F, (int16_t)0x012F, (int16_t)0x063D, (int16_t)0x0619, (int16_t)0x05B8, (int16_t)0x052C, (int16_t)0x04D3, (int16_t)0x0466,
(int16_t)0x03A0, (int16_t)0x02BC, (int16_t)0x0249, (int16_t)0x01C4, (int16_t)0x013B, (int16_t)0x0104, (int16_t)0x0104, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x07F1, (int16_t)0x0AFA, (int16_t)0x0B98, (int16_t)0x0C54, (int16_t)0x0CB6, (int16_t)0x0B9C, (int16_t)0x0A01, (int16_t)0x0868, (int16_t)0x0715, (int16_t)0x0676,
(int16_t)0x0727, (int16_t)0x06B2, (int16_t)0x06B2, (int16_t)0x07F1, (int16_t)0x0AFA, (int16_t)0x0B98, (int16_t)0x0C54, (int16_t)0x0CB6, (int16_t)0x0B9C, (int16_t)0x0A01,
(int16_t)0x0868, (int16_t)0x0715, (int16_t)0x0676, (int16_t)0x0598, (int16_t)0x05B6, (int16_t)0x05B6, (int16_t)0x07F1, (int16_t)0x0AFA, (int16_t)0x0B98, (int16_t)0x0C54,
(int16_t)0x0CB6, (int16_t)0x0B9C, (int16_t)0x0A01, (int16_t)0x0868, (int16_t)0x0715, (int16_t)0x0616, (int16_t)0x053B, (int16_t)0x0559, (int16_t)0x0559, (int16_t)0x07F1,
(int16_t)0x0AFA, (int16_t)0x0B98, (int16_t)0x0C54, (int16_t)0x0B6B, (int16_t)0x0A78, (int16_t)0x0915, (int16_t)0x07B5, (int16_t)0x068D, (int16_t)0x05A9, (int16_t)0x04F4,
(int16_t)0x04B8, (int16_t)0x04B8, (int16_t)0x07F1, (int16_t)0x0AFA, (int16_t)0x0B98, (int16_t)0x0B99, (int16_t)0x0ABC, (int16_t)0x09E1, (int16_t)0x089D, (int16_t)0x0755,
(int16_t)0x0642, (int16_t)0x0574, (int16_t)0x04D8, (int16_t)0x04A7, (int16_t)0x04A7, (int16_t)0x07FA, (int16_t)0x0B03, (int16_t)0x0BA1, (int16_t)0x0ADB, (int16_t)0x0A17,
(int16_t)0x0951, (int16_t)0x0826, (int16_t)0x06FE, (int16_t)0x05FC, (int16_t)0x0543, (int16_t)0x04B1, (int16_t)0x0495, (int16_t)0x0495, (int16_t)0x0804, (int16_t)0x0B0D,
(int16_t)0x0AF4, (int16_t)0x0A39, (int16_t)0x097D, (int16_t)0x08C8, (int16_t)0x07BA, (int16_t)0x06A5, (int16_t)0x05C0, (int16_t)0x0514, (int16_t)0x0486, (int16_t)0x047E,
(int16_t)0x047E, (int16_t)0x080D, (int16_t)0x0B16, (int16_t)0x0A59, (int16_t)0x09A3, (int16_t)0x08F4, (int16_t)0x084B, (int16_t)0x074E, (int16_t)0x064E, (int16_t)0x0580,
(int16_t)0x04E4, (int16_t)0x0463, (int16_t)0x03FC, (int16_t)0x03FC, (int16_t)0x081D, (int16_t)0x0A3B, (int16_t)0x09AD, (int16_t)0x0908, (int16_t)0x0862, (int16_t)0x07C2,
(int16_t)0x06DB, (int16_t)0x05F1, (int16_t)0x053A, (int16_t)0x04B2, (int16_t)0x0442, (int16_t)0x03E5, (int16_t)0x03E5, (int16_t)0x082D, (int16_t)0x097D, (int16_t)0x08ED,
(int16_t)0x0863, (int16_t)0x07CF, (int16_t)0x0737, (int16_t)0x0662, (int16_t)0x0593, (int16_t)0x04EE, (int16_t)0x047F, (int16_t)0x0424, (int16_t)0x03D2, (int16_t)0x03D2,
(int16_t)0x082D, (int16_t)0x086E, (int16_t)0x07EE, (int16_t)0x077E, (int16_t)0x070C, (int16_t)0x0692, (int16_t)0x05E8, (int16_t)0x053B, (int16_t)0x049E, (int16_t)0x0448,
(int16_t)0x0402, (int16_t)0x03BB, (int16_t)0x03BB, (int16_t)0x082D, (int16_t)0x0824, (int16_t)0x07A6, (int16_t)0x0738, (int16_t)0x06BC, (int16_t)0x0653, (int16_t)0x05B5,
(int16_t)0x0516, (int16_t)0x047F, (int16_t)0x042E, (int16_t)0x03F2, (int16_t)0x03AF, (int16_t)0x03AF, (int16_t)0x082D, (int16_t)0x07FF, (int16_t)0x078A, (int16_t)0x071B,
(int16_t)0x06A4, (int16_t)0x063D, (int16_t)0x05A0, (int16_t)0x0503, (int16_t)0x0470, (int16_t)0x041E, (int16_t)0x03E6, (int16_t)0x03A7, (int16_t)0x03A7, (int16_t)0x082D,
(int16_t)0x07D6, (int16_t)0x0769, (int16_t)0x0705, (int16_t)0x068D, (int16_t)0x0628, (int16_t)0x058C, (int16_t)0x04F3, (int16_t)0x0460, (int16_t)0x040D, (int16_t)0x03D8,
(int16_t)0x039B, (int16_t)0x039B, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x079D, (int16_t)0x0AB3, (int16_t)0x0CC8, (int16_t)0x0C36, (int16_t)0x0B3C, (int16_t)0x0A48, (int16_t)0x09F1, (int16_t)0x0896, (int16_t)0x0796, (int16_t)0x068B,
(int16_t)0x066B, (int16_t)0x067C, (int16_t)0x067C, (int16_t)0x079D, (int16_t)0x0AB3, (int16_t)0x0CC8, (int16_t)0x0C36, (int16_t)0x0B3C, (int16_t)0x0A48, (int16_t)0x09F1,
(int16_t)0x0896, (int16_t)0x0796, (int16_t)0x068B, (int16_t)0x05E8, (int16_t)0x0526, (int16_t)0x0526, (int16_t)0x079D, (int16_t)0x0AB3, (int16_t)0x0CC8, (int16_t)0x0C36,
(int16_t)0x0B3C, (int16_t)0x0A48, (int16_t)0x093E, (int16_t)0x07F0, (int16_t)0x0713, (int16_t)0x062F, (int16_t)0x0586, (int16_t)0x04D3, (int16_t)0x04D3, (int16_t)0x079D,
(int16_t)0x0AB3, (int16_t)0x0CC8, (int16_t)0x0C36, (int16_t)0x0B3C, (int16_t)0x0A48, (int16_t)0x08E5, (int16_t)0x079A, (int16_t)0x06D0, (int16_t)0x0601, (int16_t)0x055B,
(int16_t)0x04B2, (int16_t)0x04B2, (int16_t)0x079D, (int16_t)0x0AB3, (int16_t)0x0CC8, (int16_t)0x0BE0, (int16_t)0x0AF3, (int16_t)0x0A0E, (int16_t)0x08B8, (int16_t)0x0770,
(int16_t)0x06B0, (int16_t)0x05E9, (int16_t)0x0549, (int16_t)0x0499, (int16_t)0x0499, (int16_t)0x079B, (int16_t)0x0AB1, (int16_t)0x0C12, (int16_t)0x0B37, (int16_t)0x0A62,
(int16_t)0x0991, (int16_t)0x0858, (int16_t)0x0728, (int16_t)0x0676, (int16_t)0x05BB, (int16_t)0x0514, (int16_t)0x0476, (int16_t)0x0476, (int16_t)0x0799, (int16_t)0x0AAF,
(int16_t)0x0AFB, (int16_t)0x0A4B, (int16_t)0x0997, (int16_t)0x08E3, (int16_t)0x07C8, (int16_t)0x06BA, (int16_t)0x061E, (int16_t)0x0575, (int16_t)0x04C4, (int16_t)0x0441,
(int16_t)0x0441, (int16_t)0x0796, (int16_t)0x0AAC, (int16_t)0x0A25, (int16_t)0x0977, (int16_t)0x08CF, (int16_t)0x0826, (int16_t)0x072F, (int16_t)0x0647, (int16_t)0x05BE,
(int16_t)0x0522, (int16_t)0x0474, (int16_t)0x0412, (int16_t)0x0412, (int16_t)0x0794, (int16_t)0x09C2, (int16_t)0x0944, (int16_t)0x089A, (int16_t)0x0818, (int16_t)0x078D,
(int16_t)0x06AF, (int16_t)0x05EE, (int16_t)0x0566, (int16_t)0x04E2, (int16_t)0x0434, (int16_t)0x03DA, (int16_t)0x03DA, (int16_t)0x0792, (int16_t)0x08D7, (int16_t)0x0876,
(int16_t)0x07EC, (int16_t)0x076D, (int16_t)0x06FF, (int16_t)0x064A, (int16_t)0x0586, (int16_t)0x0523, (int16_t)0x04A0, (int16_t)0x03FD, (int16_t)0x03B6, (int16_t)0x03B6,
(int16_t)0x0792, (int16_t)0x083A, (int16_t)0x07DB, (int16_t)0x076F, (int16_t)0x070F, (int16_t)0x069B, (int16_t)0x05EA, (int16_t)0x0523, (int16_t)0x04AB, (int16_t)0x043D,
(int16_t)0x03C6, (int16_t)0x0394, (int16_t)0x0394, (int16_t)0x0792, (int16_t)0x07D1, (int16_t)0x077A, (int16_t)0x0712, (int16_t)0x06B5, (int16_t)0x0654, (int16_t)0x0594,
(int16_t)0x04D9, (int16_t)0x0468, (int16_t)0x03FD, (int16_t)0x035F, (int16_t)0x0304, (int16_t)0x0304, (int16_t)0x0792, (int16_t)0x07AB, (int16_t)0x074E, (int16_t)0x06CF,
(int16_t)0x067A, (int16_t)0x061B, (int16_t)0x0568, (int16_t)0x04B1, (int16_t)0x0444, (int16_t)0x03BB, (int16_t)0x0332, (int16_t)0x02D1, (int16_t)0x02D1, (int16_t)0x0792,
(int16_t)0x0773, (int16_t)0x0710, (int16_t)0x069A, (int16_t)0x0640, (int16_t)0x05CE, (int16_t)0x051F, (int16_t)0x0479, (int16_t)0x0418, (int16_t)0x0390, (int16_t)0x0321,
(int16_t)0x02C0, (int16_t)0x02C0, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000,
(int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000, (int16_t)0x0000
};
/* 2-D angle-kick combine (RPM x demand) -- consumed by compute_angle_kick_2d @ T06235 0x6D6B -- 195 words @ 0x8508. */
/* 2-D angle-kick combine (RPM x demand) -- consumed by orphan compute_angle_kick_2d @ 0x6AC9 (T06211 analog FUN_5D58 @ 0x5D8D) -- 195 words @ 0x835C. */
static const int16_t phi_angle_2d_kick_table[195] = {
(int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0B3A, (int16_t)0x0962, (int16_t)0x07B5, (int16_t)0x0607, (int16_t)0x053C, (int16_t)0x0499,
(int16_t)0x0512, (int16_t)0x0A37, (int16_t)0x0949, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0B3A, (int16_t)0x0962, (int16_t)0x07B5,
(int16_t)0x0607, (int16_t)0x053C, (int16_t)0x0499, (int16_t)0x0512, (int16_t)0x0A37, (int16_t)0x0949, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD,
(int16_t)0x0B3A, (int16_t)0x0962, (int16_t)0x07B5, (int16_t)0x0607, (int16_t)0x053C, (int16_t)0x0499, (int16_t)0x0512, (int16_t)0x0A37, (int16_t)0x0949, (int16_t)0x0CCD,
(int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0B3A, (int16_t)0x0962, (int16_t)0x07B5, (int16_t)0x0607, (int16_t)0x053C, (int16_t)0x0499, (int16_t)0x0512,
(int16_t)0x0A37, (int16_t)0x0949, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0CCD, (int16_t)0x0B3A, (int16_t)0x0962, (int16_t)0x07B5, (int16_t)0x0607,
(int16_t)0x053C, (int16_t)0x0499, (int16_t)0x0512, (int16_t)0x0A37, (int16_t)0x0949, (int16_t)0x09FD, (int16_t)0x09FD, (int16_t)0x09FD, (int16_t)0x09FD, (int16_t)0x08B2,
(int16_t)0x073D, (int16_t)0x0603, (int16_t)0x04CA, (int16_t)0x0472, (int16_t)0x042C, (int16_t)0x0504, (int16_t)0x0D6A, (int16_t)0x0748, (int16_t)0x072D, (int16_t)0x072D,
(int16_t)0x072D, (int16_t)0x072D, (int16_t)0x062A, (int16_t)0x0517, (int16_t)0x0452, (int16_t)0x038C, (int16_t)0x03A8, (int16_t)0x03BF, (int16_t)0x04F6, (int16_t)0x109C,
(int16_t)0x0547, (int16_t)0x04FA, (int16_t)0x04FA, (int16_t)0x04FA, (int16_t)0x04FA, (int16_t)0x03EF, (int16_t)0x03C2, (int16_t)0x031A, (int16_t)0x0273, (int16_t)0x030D,
(int16_t)0x0388, (int16_t)0x048D, (int16_t)0x0BCB, (int16_t)0x04F6, (int16_t)0x02C6, (int16_t)0x02C6, (int16_t)0x02C6, (int16_t)0x02C6, (int16_t)0x01B3, (int16_t)0x026D,
(int16_t)0x01E3, (int16_t)0x0159, (int16_t)0x0272, (int16_t)0x0352, (int16_t)0x0424, (int16_t)0x06FA, (int16_t)0x04A6, (int16_t)0x018E, (int16_t)0x018E, (int16_t)0x018E,
(int16_t)0x018E, (int16_t)0x00FA, (int16_t)0x014C, (int16_t)0x0132, (int16_t)0x0118, (int16_t)0x0211, (int16_t)0x02D8, (int16_t)0x03A0, (int16_t)0x0657, (int16_t)0x04CB,
(int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0040, (int16_t)0x002B, (int16_t)0x0081, (int16_t)0x00D7, (int16_t)0x01B0, (int16_t)0x025E,
(int16_t)0x031C, (int16_t)0x05B4, (int16_t)0x04F0, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0040, (int16_t)0x002B, (int16_t)0x0081,
(int16_t)0x00D7, (int16_t)0x01B0, (int16_t)0x025E, (int16_t)0x031C, (int16_t)0x05B4, (int16_t)0x04F0, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055,
(int16_t)0x0040, (int16_t)0x002B, (int16_t)0x0081, (int16_t)0x00D7, (int16_t)0x01B0, (int16_t)0x025E, (int16_t)0x031C, (int16_t)0x05B4, (int16_t)0x04F0, (int16_t)0x0055,
(int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0040, (int16_t)0x002B, (int16_t)0x0081, (int16_t)0x00D7, (int16_t)0x01B0, (int16_t)0x025E, (int16_t)0x031C,
(int16_t)0x05B4, (int16_t)0x04F0, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0055, (int16_t)0x0040, (int16_t)0x002B, (int16_t)0x0081, (int16_t)0x00D7,
(int16_t)0x01B0, (int16_t)0x025E, (int16_t)0x031C, (int16_t)0x05B4, (int16_t)0x04F0
(int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0B8E, (int16_t)0x0C42, (int16_t)0x0957, (int16_t)0x066D, (int16_t)0x074F, (int16_t)0x0831,
(int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0B8E, (int16_t)0x0C42, (int16_t)0x0957,
(int16_t)0x066D, (int16_t)0x074F, (int16_t)0x0831, (int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16,
(int16_t)0x0B8E, (int16_t)0x0C42, (int16_t)0x0957, (int16_t)0x066D, (int16_t)0x074F, (int16_t)0x0831, (int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x0C16,
(int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0C16, (int16_t)0x0B8E, (int16_t)0x0C42, (int16_t)0x0957, (int16_t)0x066D, (int16_t)0x074F, (int16_t)0x0831, (int16_t)0x05F6,
(int16_t)0x05F6, (int16_t)0x05F6, (int16_t)0x0A33, (int16_t)0x0A33, (int16_t)0x0A33, (int16_t)0x0A33, (int16_t)0x09A2, (int16_t)0x0A10, (int16_t)0x07C0, (int16_t)0x0570,
(int16_t)0x0682, (int16_t)0x0795, (int16_t)0x054C, (int16_t)0x054C, (int16_t)0x054C, (int16_t)0x075F, (int16_t)0x075F, (int16_t)0x075F, (int16_t)0x075F, (int16_t)0x06C0,
(int16_t)0x06C6, (int16_t)0x055D, (int16_t)0x03F4, (int16_t)0x054F, (int16_t)0x06AB, (int16_t)0x044D, (int16_t)0x044D, (int16_t)0x044D, (int16_t)0x0481, (int16_t)0x0481,
(int16_t)0x0481, (int16_t)0x0481, (int16_t)0x0542, (int16_t)0x04A0, (int16_t)0x03A9, (int16_t)0x02B3, (int16_t)0x0372, (int16_t)0x0431, (int16_t)0x04AE, (int16_t)0x04AE,
(int16_t)0x04AE, (int16_t)0x01A3, (int16_t)0x01A3, (int16_t)0x01A3, (int16_t)0x01A3, (int16_t)0x03C4, (int16_t)0x027A, (int16_t)0x01F6, (int16_t)0x0172, (int16_t)0x0194,
(int16_t)0x01B7, (int16_t)0x0510, (int16_t)0x0510, (int16_t)0x0510, (int16_t)0x016B, (int16_t)0x016B, (int16_t)0x016B, (int16_t)0x016B, (int16_t)0x02CB, (int16_t)0x013D,
(int16_t)0x0141, (int16_t)0x0146, (int16_t)0x01A2, (int16_t)0x01FF, (int16_t)0x0421, (int16_t)0x0421, (int16_t)0x0421, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133,
(int16_t)0x0133, (int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D, (int16_t)0x011A, (int16_t)0x01B0, (int16_t)0x0247, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0333,
(int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D, (int16_t)0x011A, (int16_t)0x01B0, (int16_t)0x0247,
(int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D,
(int16_t)0x011A, (int16_t)0x01B0, (int16_t)0x0247, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133,
(int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D, (int16_t)0x011A, (int16_t)0x01B0, (int16_t)0x0247, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0133,
(int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D, (int16_t)0x011A, (int16_t)0x01B0, (int16_t)0x0247, (int16_t)0x0333,
(int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x0133, (int16_t)0x01D3, (int16_t)0x0000, (int16_t)0x008D, (int16_t)0x011A,
(int16_t)0x01B0, (int16_t)0x0247, (int16_t)0x0333, (int16_t)0x0333, (int16_t)0x0333
};
/* ======================================================================
* Master calibration literal.
* ====================================================================== */
calibration_t phi_t06235_cal = {
/* RWA4-relative scalars (base 0x9BB8) */
.tein_nominal = (int16_t)0x0C28, /* CAL+0x1E @ 0x9BD6 -- tein_nominal -- nominal TE_IN base (T06215 cal+0x1E unchanged) */
.cal_48 = (int16_t)0x04B0, /* CAL+0x4A @ 0x9C02 -- RW7A latch value when FUN_62a2 fires (T06235 shift +0x02 from T06215 cal+0x48) */
.phi0 = (int16_t)0x0DAB, /* CAL+0x4E @ 0x9C06 -- phi0: base/initial angle (T06215 cal+0x4C, T06235 +0x02) */
.cal_byte_9c = 0x03u, /* CAL+0x9E @ 0x9C56 -- FUN_62a2 counter increment (T06215 cal+0x9C, T06235 +0x02) */
.cal_54 = (int16_t)0x08DE, /* CAL+0x56 @ 0x9C0E -- UPPER clamp on target_inj_angle (T06215 cal+0x54, T06235 +0x02; value differs) */
.cal_74 = (int16_t)0x20C5, /* CAL+0x76 @ 0x9C2E -- gate_0220 lower RPM threshold (T06215 cal+0x74, T06235 +0x02) */
.cal_76 = (int16_t)0x01A3, /* CAL+0x78 @ 0x9C30 -- gate_0220 hysteresis width (T06215 cal+0x76, T06235 +0x02) */
.cal_78 = (int16_t)0x007F, /* CAL+0x7A @ 0x9C32 -- accel_comp_offset upper clamp (T06215 cal+0x78, T06235 +0x02) */
.cal_7a = (int16_t)0xFFCF, /* CAL+0x7C @ 0x9C34 -- accel_comp_offset lower clamp (T06215 cal+0x7A, T06235 +0x02) */
.cal_7e = (int16_t)0x1390, /* CAL+0x80 @ 0x9C38 -- temperature reference subtrahend in compute_temp_comp_factor (read at T06235 0x6DE4; T06215 cal+0x7E) */
.cal_temp_comp_switch_dynamic = (int16_t)0x1702, /* CAL+0x82 @ 0x9C3A -- boot value of temp_comp_dynamic = TK_AT_W switch (T06215 cal+0x80, T06235 +0x02) */
.cal_82 = (int16_t)0x026F, /* CAL+0x84 @ 0x9C3C -- IIR input gain b for iir_step_unsigned (read at T06235 0x6E3D; T06215 cal+0x82) */
.cal_84 = (int16_t)0xFD91, /* CAL+0x86 @ 0x9C3E -- IIR pole coefficient a for iir_step_unsigned (read at T06235 0x6E25/0x6E2E; T06215 cal+0x84) */
.cal_temp_comp_switch_complete = (int16_t)0x0001, /* CAL+0x88 @ 0x9C40 -- boot value of temp_comp_complete = F_TK_TE_W switch (T06215 cal+0x86, T06235 +0x02) */
.cal_92 = (int16_t)0x1750, /* CAL+0x94 @ 0x9C4C -- temperature offset subtracted in tein_overtemp_guard (T06215 cal+0x92, T06235 +0x02) */
.cal_94 = (int16_t)0x0008, /* CAL+0x96 @ 0x9C4E -- tein_overtemp_guard multiplier (T06215 cal+0x94, T06235 +0x02) */
.cal_96 = (int16_t)0x04B0, /* CAL+0x98 @ 0x9C50 -- tein_overtemp_guard RW1C upper clamp (T06215 cal+0x96, T06235 +0x02) */
.cal_98 = (int16_t)0x1D7E, /* CAL+0x9A @ 0x9C52 -- tein_overtemp_guard lower RPM (T06215 cal+0x98, T06235 +0x02) */
.cal_9a = (int16_t)0x3127, /* CAL+0x9C @ 0x9C54 -- tein_overtemp_guard upper RPM (T06215 cal+0x9A, T06235 +0x02) */
/* RWC6-relative scalars (base 0x8002) */
.cal_rwc6_34 = (int16_t)0x0831, /* RWC6+0x34 @ 0x8036 -- demand-weight multiplier in compute_angle_kick_2d (T06235 0x6D9D; same RWC6 offset as T06215) */
calibration_t phi_t06215_cal = {
/* RWA4-relative scalars (base 0x9BD8) */
.tein_nominal = (int16_t)0x0C28, /* CAL+0x1E @ 0x9BF6 -- tein_nominal nominal TE_IN base added to tein_valve_fault_guard / tein_overtemp_guard (T06211 FUN_7453 0x747b; T06215 FUN_74EA -- see README) */
.cal_48 = (int16_t)0x04B0, /* CAL+0x48 @ 0x9C20 -- RW7A latch value when FUN_62a2 fires (0x62d8) */
.phi0 = (int16_t)0x0DAB, /* CAL+0x4C @ 0x9C24 -- phi0: base/initial angle. ROM addend baked into phi1 (= *(0x014e)) by FUN_6aaf (0x6ad2); T06211 FUN_7453 reads phi0 + dphi at 0x74a2 */
.cal_byte_56 = 0x0Du, /* CAL+0x56 @ 0x9C2E -- tooth phase comparand for rpm_baseline producer (FUN_51e1 at Tooth_scheduler? 0x7aa4) */
.cal_byte_9c = 0x03u, /* CAL+0x9C @ 0x9C74 -- FUN_62a2 counter increment (0x62c6) */
.cal_54 = (int16_t)0x0B2B, /* CAL+0x54 @ 0x9C2C -- UPPER clamp on target_inj_angle (T06211 FUN_7453 0x7493) */
.cal_74 = (int16_t)0x20C5, /* CAL+0x74 @ 0x9C4C -- gate_0220 lower RPM threshold */
.cal_76 = (int16_t)0x01A3, /* CAL+0x76 @ 0x9C4E -- gate_0220 hysteresis width (upper = cal_74 + cal_76) */
.cal_78 = (int16_t)0x007F, /* CAL+0x78 @ 0x9C50 -- accel_comp_offset upper clamp (FUN_732d 0x7340) */
.cal_7a = (int16_t)0xFFCF, /* CAL+0x7A @ 0x9C52 -- accel_comp_offset lower clamp (FUN_732d 0x734e) */
.cal_7e = (int16_t)0x13AA, /* CAL+0x7E @ 0x9C56 -- temperature reference subtrahend in compute_temp_comp_factor (calc_temp_comp_factor @ 0x6B0D; T06211 analog FUN_5DAB 0x5DD1) */
.cal_temp_comp_switch_dynamic = (int16_t)0x1702, /* CAL+0x80 @ 0x9C58 -- boot value of temp_comp_dynamic = TK_AT_W switch (compute_temp_comp_factor 0x6AF0; T06211 analog 0x5DB4) */
.cal_82 = (int16_t)0x026F, /* CAL+0x82 @ 0x9C5A -- IIR input gain b for compute_temp_phi_comp (FUN_6b4e MULU at 0x6B66; Q16 unsigned) */
.cal_84 = (int16_t)0xFD91, /* CAL+0x84 @ 0x9C5C -- IIR pole coefficient a for compute_temp_phi_comp (FUN_6b4e MULU at 0x6B4E and 0x6B57; Q16 unsigned) */
.cal_temp_comp_switch_complete = (int16_t)0x0001, /* CAL+0x86 @ 0x9C5E -- boot value of temp_comp_complete = F_TK_TE_W switch (compute_temp_comp_factor 0x6B17; T06211 analog 0x5DDB) */
.cal_92 = (int16_t)0x1750, /* CAL+0x92 @ 0x9C6A -- temperature offset subtracted in FUN_5ca1 (0x5cf7) */
.cal_94 = (int16_t)0x0008, /* CAL+0x94 @ 0x9C6C -- FUN_5ca1 multiplier (0x5d05) */
.cal_96 = (int16_t)0x04B0, /* CAL+0x96 @ 0x9C6E -- FUN_5ca1 RW1C upper clamp (0x5d0b, unsigned) */
.cal_98 = (int16_t)0x1D7E, /* CAL+0x98 @ 0x9C70 -- tein_overtemp_guard lower RPM (FUN_5ca1 0x5d1a, unsigned) */
.cal_9a = (int16_t)0x3127, /* CAL+0x9A @ 0x9C72 -- tein_overtemp_guard upper RPM (FUN_5ca1 0x5d21, unsigned) */
/* RWC6-relative scalars (base 0x7E56) */
.cal_rwc6_34 = (int16_t)0x0831, /* RWC6+0x34 @ 0x7E8A -- demand-weight multiplier in compute_angle_kick_2d (orphan @ 0x6ABD; T06211 analog FUN_5D58 @ 0x5D81) */
/* Accel descriptors (input_var bound at runtime by phi_t06235_bind_inputs). */
/* Accel descriptors (input_var bound at runtime by phi_t06215_bind_inputs). */
.desc_accel_rpm = {
.runtime_slot = 0,
.input_var = NULL,
@@ -198,10 +204,10 @@ calibration_t phi_t06235_cal = {
.accel_refine_table = phi_accel_refine_table,
/* Absolute-address ROM constants. */
.dat_604c = (int16_t)0x0444, /* *(0x604C) -- FUN_62a2 RWC2 timing threshold (T06215 = 0x0444; verify) */
.cal_byte_402 = (int16_t)0xFFF5, /* *(0x0402) -- FUN_6ba3-equivalent sign-extends byte 0x0402 in temp_comp_factor (T06235 0x6DE9 reads abs *(0x0402)) */
.dat_604c = (int16_t)0x0444, /* *(0x604C) -- FUN_62a2 RWC2 timing threshold (T06211 = 0x0444; verify in T06215) */
.cal_byte_402 = (int16_t)0xFFF2, /* *(0x0402) -- FUN_6ba3 sign-extends byte 0x0402 (compute_temp_comp_factor 0x6B12; T06211 analog 0x5DD6) */
/* Angle accumulator descriptors (RWC6-relative; identical to T06215; input_var bound at runtime). */
/* Angle accumulator descriptors (FUN_722e, RWC6-relative; input_var bound at runtime). */
.desc_rpm = {
.runtime_slot = 0,
.input_var = NULL,
@@ -226,7 +232,11 @@ calibration_t phi_t06235_cal = {
.data_table_2d_kick = phi_angle_2d_kick_table,
};
void phi_t06235_bind_inputs(runtime_state_t *rt, calibration_t *cal)
/* ======================================================================
* Runtime input binder.
* ====================================================================== */
void phi_t06215_bind_inputs(runtime_state_t *rt, calibration_t *cal)
{
cal->desc_accel_rpm.input_var = (int16_t *)&rt->rpm;
cal->desc_accel_demand.input_var = &rt->inj_qty_demand;

View File

@@ -77,14 +77,14 @@ void init_FuelMap(float *PHIAD) {
s_phi_getters.get_inj_qty_demand = get_inj_qty_demand;
s_phi_getters.get_temperature = get_temperature;
s_phi_getters.get_angle_dec_cmd = get_angle_dec_cmd;
s_phi_getters.get_rpm_baseline = get_rpm_baseline;
//s_phi_getters.get_rpm_baseline = get_rpm_baseline;
s_phi_getters.get_rwc2 = get_rwc2;
s_phi_getters.get_reset_gate_0226 = get_reset_gate_0226;
s_phi_getters.get_dphi = get_dphi;
s_phi_getters.get_scratch_0103 = get_scratch_0103;
s_phi_getters.get_scratch_0108 = get_scratch_0108;
s_phi_cal = phi_t06235_cal;
s_phi_cal = phi_t06215_cal;
phi_init(&s_phi_state, &s_phi_cal, &s_phi_getters);
/* Pre-latch to skip the cranking-phase ramp (mirrors
@@ -99,7 +99,7 @@ void Timer1_FM_ISR(){
}
void TW_FM_ISR(uint8_t currentTooth, uint32_t ic){
//phi_tick_1khz(&s_phi_state, &s_phi_cal);
phi_tooth_isr(&s_phi_state, &s_phi_cal, currentTooth, (uint16_t)(ic >> 4));
}
extern float forceTemp;
@@ -111,6 +111,8 @@ float FM_GET_PHIAD(float RPM, float ME, float Temp) {
phi_service(&s_phi_state, &s_phi_cal, &s_phi_out);
float Z = (float)s_phi_out.angle_accumulator * ANGLE_DEG_PER_RAW;
Z = s_me ? Z : 0; // el terrano se apagaba
if (s_phiad_out) *s_phiad_out = Z;
return Z;
}

View File

@@ -224,6 +224,7 @@ void TW_TEETH_CAPTURE(){
if(currentTooth == TW_PERCYL_TEETH - 1){
INJ_END();
}
TW_FM_ISR(currentTooth,IC_RPM_Val2 );
hasCapturedTeeth = 1;