Files
hpsg5-controller_v2-stm32g4/Core/Kline_Libs/psg_prop.c

229 lines
9.5 KiB
C

/*
* 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 <string.h>
// ================================================================
// 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;
}