/* * psg_prop.c * PSG K-Line data dictionary implementation. * * Provides lookup functions for all ROM and EEPROM read responses. * Static constant tables are derived from protocol captures. * Dynamic values (DFI, calibration) use runtime storage. * * Created on: 2025 * Author: herli */ #include "psg_prop.h" #include "ee_manager.h" #include // ================================================================ // ROM lookup tables // ================================================================ /* Binary ROM entries: fixed-length raw data blobs */ typedef struct { uint16_t addr; uint8_t len; uint8_t data[10]; } RomEntry_t; static const RomEntry_t s_rom_bin_table[] = { /* addr len data bytes (from protocol capture) description */ { 0x9FCC, 10, { 0xA2,0x93,0x61,0x9F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } }, /* fixed block */ { 0x9FD6, 10, { 0x4B,0x9F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x9C } }, /* fixed block */ { 0x9FE0, 10, { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } }, /* fixed block */ { 0x9FEA, 10, { 0xFF,0xFF,0xFF,0xFF,0xDD,0x95,0xFF,0xFF,0xFF,0xFF } }, /* fixed block */ { 0x9FF4, 10, { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } }, /* fixed block */ { 0x9FB6, 2, { 0x44,0x00 } }, /* ptr -> DFI EEPROM addr */ { 0x9FBE, 2, { 0xC6,0x00 } }, /* unknown ptr */ { 0x9FBC, 2, { 0xA4,0x00 } }, /* unknown ptr */ { 0x9FBA, 2, { 0xED,0x00 } }, /* unknown ptr */ { 0x9FA6, 2, { 0x06,0x04 } }, /* unknown */ { 0x9FA8, 2, { 0x42,0x00 } }, /* dT-Hybrid ref */ { 0x9F74, 2, { 0x70,0x00 } }, /* DeltaBlockierwinkel */ { 0x9F72, 2, { 0x74,0x00 } }, /* DeltaPhi-Offset */ { 0x9F70, 2, { 0x48,0x00 } }, /* DynFDKorrekturt */ { 0x93AD, 3, { 0x30,0x30,0x30 } }, /* Änderungsindex PV "000" */ { 0x9F9E, 3, { 0xFF,0xFF,0xFF } }, /* PSG Fertigungsdatum (unset) */ { 0x9FA1, 3, { 0xFF,0xFF,0xFF } }, /* PSG Chargen-Nr. (unset) */ { 0x9C10, 10, PSG_KUNDENNUMMER1_STR },/* Kundennummer 1 "1234567891" */ { 0x9C1A, 2, PSG_KUNDENNUMMER2_STR }, /* Kundennummer 2 "23" */ { PSG_CUST_CHANGE_ADDR, 3, PSG_FERTIGUNGSWERK_STR }, /* Fertigungswerk */ { PSG_CUST_CHANGE_ADDR + 3, 6, PSG_MOD_INDEX_STR }, /* Mod Index */ }; #define ROM_BIN_COUNT (sizeof(s_rom_bin_table) / sizeof(s_rom_bin_table[0])) /* String ROM entries: 10-byte ASCII identifiers */ typedef struct { uint16_t addr; const char *str; /* exactly 10 ASCII bytes, no NUL */ } RomStrEntry_t; static const RomStrEntry_t s_rom_str_table[] = { { 0x93BA, PSG_IDENT_STR }, /* ident (at PSG_IDENT_ADDR - 10) */ { 0x9F80, PSG_SOFTWARE_VER_STR }, /* software version */ { 0x9F94, PSG_STEUERGERAET_STR }, /* Steuergeraet */ { 0x9F76, PSG_FAHRSOFTWARE_STR }, /* Fahrsoftware */ { 0x9C1C, PSG_DATENSATZ_STR }, /* Datensatz */ { 0x93B0, PSG_REFERENZ_STR }, /* Referenz-Kennfeld */ }; #define ROM_STR_COUNT (sizeof(s_rom_str_table) / sizeof(s_rom_str_table[0])) // ================================================================ // EEPROM static data blocks // ================================================================ /* * DTC storage region (0x0000-0x003F, 64 bytes). * Stored as a flat array so any-length chunk reads reconstruct correctly. * Byte values derived from protocol capture. */ /*static const uint8_t s_dtc_eeprom_block[64] = { 0x50, 0x20, 0xAB, 0x0A, 0x0E, 0x09, 0x01, 0xED, 0x5A, 0x20, 0xDF, 0x2D, 0x05, 0x00, 0x02, 0x33, 0x5B, 0x20, 0xDF, 0x2D, 0x05, 0x00, 0x03, 0x34, 0x52, 0x20, 0xDF, 0x2D, 0x00, 0x00, 0x04, 0x30, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }*/ static const uint8_t s_dtc_eeprom_block[64] = { /* 0x0000-0x000C (13 bytes, DTC MSG 1) */ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x000D-0x0019 (13 bytes, DTC MSG 2) */ 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, /* 0x001A-0x0026 (13 bytes, DTC MSG 3) */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x0027-0x0033 (13 bytes, DTC MSG 4) */ 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, /* 0x0034-0x003F (12 bytes, DTC MSG 5) */ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* * DeltaPhi calibration array (0x009A-0x00BD, 36 bytes = 18 x int16 LE). * 0x8000 entries are "not calibrated" placeholders. */ static const uint8_t s_deltaphi_block[36] = { /* 0x009A-0x00A6 (13 bytes, AD1) */ 0xDE, 0xFF, 0xE8, 0xFF, 0x0C, 0x00, 0x08, 0x00, 0xFE, 0xFF, 0x00, 0x80, 0x00, /* 0x00A7-0x00B3 (13 bytes, AD2) */ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, /* 0x00B4-0x00BD (10 bytes, AD3) */ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80 }; /* ================================================================ * Runtime-writable EEPROM values. * Initialized to sniffed defaults; updated by WriteEeprom handlers. * ================================================================ */ static uint8_t s_dt_hybrid[2] = { 0xDE, 0x22 }; /* 0x0042, dT-Hybrid, default 1958.5 K */ static uint8_t s_dynfd_korr[2] = { 0x00, 0x00 }; /* 0x0048, DynFDKorrekturt */ static uint8_t s_delta_blockierwinkel[4] = { 0x00, 0x00, 0x00, 0x00 }; /* 0x0070 */ static uint8_t s_deltaphi_offset[4] = { 0x00, 0x00, 0x00, 0x00 }; /* 0x0074 */ // ================================================================ // PSG_ROM_GetData // ================================================================ uint8_t PSG_ROM_GetData(uint16_t addr, uint8_t len, uint8_t *out) { /* customerChangeAddress (0x9FFE) — 2 bytes little-endian */ if (addr == 0x9FFE && len == 2) { out[0] = (uint8_t)(PSG_CUST_CHANGE_ADDR & 0xFF); out[1] = (uint8_t)((PSG_CUST_CHANGE_ADDR >> 8) & 0xFF); return 1; } /* Binary data blocks */ for (int i = 0; i < (int)ROM_BIN_COUNT; i++) { if (s_rom_bin_table[i].addr == addr && s_rom_bin_table[i].len == len) { memcpy(out, s_rom_bin_table[i].data, len); return 1; } } /* 10-byte ASCII string entries */ for (int i = 0; i < (int)ROM_STR_COUNT; i++) { if (s_rom_str_table[i].addr == addr && len == 10) { memcpy(out, s_rom_str_table[i].str, 10); return 1; } } return 0; } // ================================================================ // PSG_EEPROM_GetData // ================================================================ uint8_t PSG_EEPROM_GetData(uint16_t addr, uint8_t len, uint8_t *out) { /* DFI angle correction (0x0044, 2 bytes) — dynamic, caller must check lock */ if (addr == 0x0044 && len == 2) { int8_t code = GetDfiValue(); out[0] = (uint8_t)code; out[1] = (uint8_t)(-(int8_t)code); /* two's-complement checksum byte */ return 1; } /* Serial number (0x0080, 6 bytes) */ if (addr == 0x0080 && len == 6) { memcpy(out, PSG_SERIAL_STR, 6); return 1; } /* Fertigungsdatum / manufacturing date (0x0086, 3 bytes) */ if (addr == 0x0086 && len == 3) { memcpy(out, FERTIGUNGSDATUM_STR, 3); //memcpy(out + 3, FERTIGUNGSDATUM_STR, 3); si length = 6 return 1; } /* Unknown/reserved (0x0094, 2 bytes) */ if (addr == 0x0094 && len == 2) { out[0] = 0x00; out[1] = 0x00; return 1; } /* dT-Hybrid (0x0042, 2 bytes) */ if (addr == 0x0042 && len == 2) { memcpy(out, s_dt_hybrid, 2); return 1; } /* DynFDKorrekturt (0x0048, 2 bytes) */ if (addr == 0x0048 && len == 2) { memcpy(out, s_dynfd_korr, 2); return 1; } /* DeltaBlockierwinkel (0x0070, 4 bytes) */ if (addr == 0x0070 && len == 4) { memcpy(out, s_delta_blockierwinkel, 4); return 1; } /* DeltaPhi-Offset (0x0074, 4 bytes) */ if (addr == 0x0074 && len == 4) { memcpy(out, s_deltaphi_offset, 4); return 1; } /* DTC EEPROM block (0x0000-0x003F, 64 bytes total) */ if (addr < 0x0040U) { if ((uint16_t)(addr + len) <= 0x0040U) { memcpy(out, &s_dtc_eeprom_block[addr], len); return 1; } } /* DeltaPhi calibration array (0x009A-0x00BD, 36 bytes) */ if (addr >= 0x009AU && addr < (0x009AU + 36U)) { uint16_t off = addr - 0x009AU; uint16_t avail = (uint16_t)(36U - off); uint8_t n = (len <= (uint8_t)avail) ? len : (uint8_t)avail; memcpy(out, &s_deltaphi_block[off], n); if (n < len) memset(out + n, 0xFF, len - n); return 1; } return 0; }