94 lines
3.1 KiB
C
94 lines
3.1 KiB
C
/*
|
||
* ckp_acquisition.c
|
||
*
|
||
* Created on: May 5, 2026
|
||
* Author: herli
|
||
*
|
||
* Mirrors ROM FUN_55e0 @ 0x55e0 → FUN_6a4b @ 0x6a4b for the CKP-zero
|
||
* acquisition path. See ckp_acquisition.h for the data-flow summary.
|
||
*/
|
||
|
||
#include "ckp_acquisition.h"
|
||
#include "pwm.h" /* pwm_cal_rom + shra16 */
|
||
#include "ee_manager.h"
|
||
|
||
/* Inputs */
|
||
int16_t B_CKP_OFFSET = 0;
|
||
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;
|
||
int16_t CKP_ZERO_OFFSET = 0;
|
||
|
||
/* FUN_6a4b @ 0x6a4b core — DAT_0152 derivation only.
|
||
*
|
||
* ROM body (fulldissasembly.txt:20025–20061):
|
||
* RW1E = cal[+0x50] + DAT_0430
|
||
* RW1C = RW1E - DAT_0434 - cal[+0x52] + (int8_t)DAT_0404
|
||
* while RW1C < 0 : RW1C += cal[+0xa2] ; JGE LAB_6a7e (signed)
|
||
* while RW1C > cal[+0xa2] : RW1C -= cal[+0xa2] ; JLE LAB_6a8c (signed)
|
||
* DAT_0152 = RW1C
|
||
*
|
||
* Side-effects (FUN_6c70 R8F/R90 derivation, DAT_02cb/R2C/R2D clears,
|
||
* DAT_017a=5, DAT_0278 reload) belong to the CKP-decode synchronization
|
||
* stage and are intentionally not ported here — see the plan's
|
||
* "Out of scope" section.
|
||
*/
|
||
static void ckp_recompute_zero_offset(void)
|
||
{
|
||
int16_t anchor = (int16_t)((int16_t)pwm_cal_rom.ckp_zero_anchor
|
||
+ CKP_RAM_TRIM_0430);
|
||
|
||
/* LDBSE at fulldissasembly.txt:20038 sign-extends the byte to a
|
||
* word before the ADD. */
|
||
int16_t v = (int16_t)(anchor
|
||
- dCKP_OFFSET
|
||
- pwm_cal_rom.can_dckp_offset_bias
|
||
+ (int16_t)s_dfi_code);
|
||
|
||
int16_t mod = pwm_cal_rom.ckp_modulus;
|
||
|
||
/* Verbatim ROM modulo. JGE/JLE in the ROM are signed compares, so
|
||
* the loops bracket v into [0, mod] inclusive. Replacing with `%`
|
||
* would diverge for negative v under C90/C99 implementation-defined
|
||
* sign-of-remainder rules. */
|
||
while (v < 0) v = (int16_t)(v + mod);
|
||
while (v > mod) v = (int16_t)(v - mod);
|
||
|
||
CKP_ZERO_OFFSET = v;
|
||
}
|
||
|
||
/* FUN_55e0 @ 0x55e0 entry — detect change in (B_CKP_OFFSET >> 1) and
|
||
* update dCKP_OFFSET; on change, FUN_6a4b is invoked. We always re-run
|
||
* FUN_6a4b on the first call so consumers see a coherent
|
||
* CKP_ZERO_OFFSET even before B_CKP_OFFSET first moves.
|
||
*/
|
||
int16_t get_ckp_zero(void)
|
||
{
|
||
static uint8_t initialized = 0;
|
||
|
||
int16_t halved = shra16(B_CKP_OFFSET, 1);
|
||
int16_t biased_now = (int16_t)(dCKP_OFFSET
|
||
+ pwm_cal_rom.can_dckp_offset_bias);
|
||
|
||
if (halved != biased_now) {
|
||
dCKP_OFFSET = (int16_t)(halved
|
||
- pwm_cal_rom.can_dckp_offset_bias);
|
||
/* commitCKP_offset stays unused per user direction; future hook
|
||
* for the FUN_56d8 flash-write sequence and the DAT_01e7 bit-7
|
||
* persist-pending flag. */
|
||
(void)commitCKP_offset;
|
||
ckp_recompute_zero_offset();
|
||
initialized = 1;
|
||
} else if (!initialized) {
|
||
ckp_recompute_zero_offset();
|
||
initialized = 1;
|
||
}
|
||
|
||
return CKP_ZERO_OFFSET;
|
||
}
|