diff --git a/Core/Advance_Control/Unused_advance/cal_tables_rom_424026.c b/Core/Advance_Control/Unused_advance/cal_tables_rom_424026.c index 59758d4..41d743c 100644 --- a/Core/Advance_Control/Unused_advance/cal_tables_rom_424026.c +++ b/Core/Advance_Control/Unused_advance/cal_tables_rom_424026.c @@ -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) */ diff --git a/Core/Advance_Control/Unused_advance/cal_tables_rom_504042.c b/Core/Advance_Control/Unused_advance/cal_tables_rom_504042.c index a01165a..f20ef8e 100644 --- a/Core/Advance_Control/Unused_advance/cal_tables_rom_504042.c +++ b/Core/Advance_Control/Unused_advance/cal_tables_rom_504042.c @@ -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+0x4c−cal+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+0x4c−cal+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) */ diff --git a/Core/Advance_Control/Unused_advance/pwm_424026.h b/Core/Advance_Control/Unused_advance/pwm_424026.h index d5b1c3b..eeca2fa 100644 --- a/Core/Advance_Control/Unused_advance/pwm_424026.h +++ b/Core/Advance_Control/Unused_advance/pwm_424026.h @@ -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 */ diff --git a/Core/Advance_Control/Unused_advance/pwm_504042.h b/Core/Advance_Control/Unused_advance/pwm_504042.h index 420581d..4cd527a 100644 --- a/Core/Advance_Control/Unused_advance/pwm_504042.h +++ b/Core/Advance_Control/Unused_advance/pwm_504042.h @@ -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 */ diff --git a/Core/Advance_Control/cal_tables_rom.c b/Core/Advance_Control/cal_tables_rom.c index 8d6d325..cddd060 100644 --- a/Core/Advance_Control/cal_tables_rom.c +++ b/Core/Advance_Control/cal_tables_rom.c @@ -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+0x4c−cal+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+0x4c−cal+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 }; diff --git a/Core/Advance_Control/ckp_acquisition.c b/Core/Advance_Control/ckp_acquisition.c index 283861e..6d8173d 100644 --- a/Core/Advance_Control/ckp_acquisition.c +++ b/Core/Advance_Control/ckp_acquisition.c @@ -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; diff --git a/Core/Advance_Control/pwm.c b/Core/Advance_Control/pwm.c index f62b4b5..24bf85b 100644 --- a/Core/Advance_Control/pwm.c +++ b/Core/Advance_Control/pwm.c @@ -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 diff --git a/Core/Advance_Control/pwm.h b/Core/Advance_Control/pwm.h index a76230b..6069360 100644 --- a/Core/Advance_Control/pwm.h +++ b/Core/Advance_Control/pwm.h @@ -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 */ diff --git a/Core/Inc/Ids/id_504042.h b/Core/Inc/Ids/id_504042.h index 5288203..54ec1de 100644 --- a/Core/Inc/Ids/id_504042.h +++ b/Core/Inc/Ids/id_504042.h @@ -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 diff --git a/Core/Inc/id.h b/Core/Inc/id.h index 54ec1de..c9cf6ff 100644 --- a/Core/Inc/id.h +++ b/Core/Inc/id.h @@ -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 diff --git a/Core/Phi/Variants/phi_424026.c b/Core/Phi/Variants/phi_424026.c index 9533a3e..d9db0fe 100644 --- a/Core/Phi/Variants/phi_424026.c +++ b/Core/Phi/Variants/phi_424026.c @@ -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) + +/* 0x5210–0x529c: period_to_rpm_div helper (FUN_5210). */ +static int16_t period_to_rpm_div(uint16_t period_lo, uint16_t period_hi) +{ + /* 0x5255–0x526a: 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; + } + } + + /* 0x526f–0x5274: load dividend RL1C = 0x0F000000. */ + uint16_t rw1c = RPM_DIVIDEND_LO; + uint16_t rw1e = RPM_DIVIDEND_HI; + + /* 0x5279–0x527c: 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 { + /* 0x5283–0x5295: 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; + + /* 0x7aa4–0x7aa9: 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; + } + + /* 0x5247–0x524b: 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); + + /* 0x524e–0x5251: persist new snapshot. */ + rt->mt_rpm_capture_prev = current_capture; + rt->mt_rpm_index_prev = 0u; + + /* 0x5255–0x5298: 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 0x7801–0x7825 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 @ 0x6bbf–0x6bc1). */ 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(); diff --git a/Core/Phi/Variants/phi_424026.h b/Core/Phi/Variants/phi_424026.h index 828fecc..752bdf2 100644 --- a/Core/Phi/Variants/phi_424026.h +++ b/Core/Phi/Variants/phi_424026.h @@ -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); diff --git a/Core/Phi/Variants/phi_cal_tables_424026.c b/Core/Phi/Variants/phi_cal_tables_424026.c index 03c6ebf..899ebc1 100644 --- a/Core/Phi/Variants/phi_cal_tables_424026.c +++ b/Core/Phi/Variants/phi_cal_tables_424026.c @@ -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 */ diff --git a/Core/Phi/phi.c b/Core/Phi/phi.c index eba84aa..d9db0fe 100644 --- a/Core/Phi/phi.c +++ b/Core/Phi/phi.c @@ -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 @ 0x6AE7–0x6B29 - * (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 @ 0x6A94–0x6AE6 - * (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) + +/* 0x5210–0x529c: period_to_rpm_div helper (FUN_5210). */ +static int16_t period_to_rpm_div(uint16_t period_lo, uint16_t period_hi) +{ + /* 0x5255–0x526a: 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; + } + } + + /* 0x526f–0x5274: load dividend RL1C = 0x0F000000. */ + uint16_t rw1c = RPM_DIVIDEND_LO; + uint16_t rw1e = RPM_DIVIDEND_HI; + + /* 0x5279–0x527c: 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 { + /* 0x5283–0x5295: 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; + + /* 0x7aa4–0x7aa9: 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; + } + + /* 0x5247–0x524b: 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); + + /* 0x524e–0x5251: persist new snapshot. */ + rt->mt_rpm_capture_prev = current_capture; + rt->mt_rpm_index_prev = 0u; + + /* 0x5255–0x5298: 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 0x7801–0x7825 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 @ 0x6bbf–0x6bc1). */ 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(); diff --git a/Core/Phi/phi.h b/Core/Phi/phi.h index aa1c9de..752bdf2 100644 --- a/Core/Phi/phi.h +++ b/Core/Phi/phi.h @@ -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 #include /* ─── 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 */ diff --git a/Core/Phi/phi_cal_tables.c b/Core/Phi/phi_cal_tables.c index 87af25d..899ebc1 100644 --- a/Core/Phi/phi_cal_tables.c +++ b/Core/Phi/phi_cal_tables.c @@ -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 #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; diff --git a/Core/Src/fuel_map.c b/Core/Src/fuel_map.c index 7f28987..e1896c5 100644 --- a/Core/Src/fuel_map.c +++ b/Core/Src/fuel_map.c @@ -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; } diff --git a/Core/Src/toothed_wheel.c b/Core/Src/toothed_wheel.c index ae2f5f6..17d7a28 100644 --- a/Core/Src/toothed_wheel.c +++ b/Core/Src/toothed_wheel.c @@ -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;