Representative results only · all C code here is synthetic · no TI code is included or displayed details
Results are representative and informational only. Under Texas Instruments' C2000 software license terms, real TI SDK source code is confidential and licensed for internal use only, so no TI code is included, displayed, processed, or emitted here. All C code on this site is synthetic, written for this demo, with invented names and values that resemble typical power-converter firmware. The generated headers compile against this demo's sample firmware in CI; the "legacy" files used for the audit are illustrative and not guaranteed to compile on any target. Product ratings come from public IntelliPower data sheets; all circuit values and gains are invented. Independent demo, not affiliated with or endorsed by AMETEK, IntelliPower, or Texas Instruments. TI, C2000, and Code Composer Studio are trademarks of Texas Instruments.
Audit: legacy firmware against the spec
The realistic week-one task: before generating anything, read the firmware that exists and compare it to the spec. Read-only; nothing is changed.
Constants found
33
Match the spec
10
Contradict the data sheet
3
Differ from a design value
10
Not covered by a rule
10
Two kinds of disagreement. A value that contradicts the data sheet is wrong for the product (here: a 220 V output on a 120 V unit, a 14 A overload on a 15 A rating). A value that differs from a design value only disagrees with this demo's invented board and design choices (shunt, margins, timing such as dead time, PWM period and overload delay, and the cell cutoff); it needs a conversation, not a fix. The most important one here: the legacy fast trip at 21.2 A peak sits at the peak of the RMS overload level, so a fully loaded unit feeding 3:1 crest-factor loads would trip; the current design puts the hardware limit at 43.75 A and handles overload with a timed RMS check.
The legacy code is synthetic: written for this demo by a separate agent under clean-room rules, with seeded mistakes, traps, and an answer key the classifier never sees. It is also friendlier than real legacy firmware (most constants have comments), which flatters the AI scores below.
protect.c (59 lines)
1 /* SYNTHETIC EXAMPLE — written for the calgen demo. Not from any real product
2 * or vendor SDK. Names and values are invented to resemble typical
3 * power-converter firmware. May not compile on any target. */
4
5 /* protect.c -- fast (per-cycle) and slow (1 ms) protection */
6 #include "ups_config.h"
7 #include "sense_scale.h"
8
9 #define FLT_LOG_LEN 16
10
11 enum { FLT_OC = 1, FLT_OL, FLT_UVB, FLT_OVO, FLT_BRN };
12
13 static const float k_trip_a = 15.0f; /* A rms, overload trip */
14 static const unsigned short ol_hold_ms = 5000; /* overload ride-through */
15
16 static unsigned char flt_log[FLT_LOG_LEN];
17 static unsigned char flt_idx;
18 static unsigned short ol_ms;
19 static unsigned char retry;
20
21 extern void inv_off(void);
22 extern void inv_on(void);
23 extern void delay_ms(unsigned short ms);
24
25 static void log_fault(unsigned char code)
26 {
27 flt_log[flt_idx++ & (FLT_LOG_LEN - 1)] = code;
28 }
29
30 void prot_fast(float i_pk)
31 {
32 float a = (i_pk < 0.0f) ? -i_pk : i_pk;
33
34 if (a > 21.2f) { /* peak of the RMS trip level */
35 inv_off();
36 log_fault(FLT_OC);
37 }
38 }
39
40 void prot_slow(float i_rms, float vbat, float vo_rms)
41 {
42 if (i_rms > k_trip_a) {
43 if (++ol_ms >= ol_hold_ms) { inv_off(); log_fault(FLT_OL); }
44 } else if (ol_ms) {
45 ol_ms--;
46 }
47 if (vbat < VBAT_CUT) { inv_off(); log_fault(FLT_UVB); }
48 if (vo_rms > VO_HI) { inv_off(); log_fault(FLT_OVO); }
49 if (vo_rms < 0.9f * VO_NOM) { log_fault(FLT_BRN); }
50 }
51
52 void prot_restart(void)
53 {
54 if (retry < 3) {
55 delay_ms(500);
56 retry++;
57 inv_on();
58 }
59 }sense_scale.h (27 lines)
1 /* SYNTHETIC EXAMPLE — written for the calgen demo. Not from any real product 2 * or vendor SDK. Names and values are invented to resemble typical 3 * power-converter firmware. May not compile on any target. */ 4 5 /* sense_scale.h -- ADC / comparator scaling for the sense chain */ 6 #ifndef SENSE_SCALE_H 7 #define SENSE_SCALE_H 8 9 #define ADC_FULL 4095.0f /* 12-bit converter */ 10 #define DAC_FULL 4095 /* comparator reference DAC */ 11 12 /* DC bus: 1.5 M / 10 k divider */ 13 #define VBUS_FS 498.3f /* V at ADC full scale */ 14 #define K_VS (VBUS_FS / ADC_FULL) /* V per count */ 15 16 /* battery: 499 k / 10 k divider */ 17 #define VBAT_FS 168.0f /* V at ADC full scale */ 18 19 /* output voltage, mid-rail biased */ 20 #define VO_FS_PK 501.6f /* peak V at +/- half scale */ 21 22 /* output current: 5 mOhm shunt into x10 amp, mid-rail biased */ 23 #define IO_FS_PK 33.0f /* peak A at +/- half scale */ 24 #define CMP_DAC_HI 3364 /* positive overcurrent trip code */ 25 #define CMP_DAC_LO (DAC_FULL - CMP_DAC_HI) 26 27 #endif /* SENSE_SCALE_H */
ups_config.h (51 lines)
1 /* SYNTHETIC EXAMPLE — written for the calgen demo. Not from any real product 2 * or vendor SDK. Names and values are invented to resemble typical 3 * power-converter firmware. May not compile on any target. */ 4 5 /* 6 * ups_config.h -- 1500 VA on-line UPS, main controller settings 7 * 8 * History (hand-maintained): 9 * 2009-03 first cut, carried over from the 1250 VA export board (JR) 10 * 2011-08 domestic 120 V / 60 Hz build (MK) 11 * 2014-02 lithium battery option (MK) 12 * 13 * NOTE: keep in sync with sense_scale.h if the divider changes. 14 */ 15 #ifndef UPS_CONFIG_H 16 #define UPS_CONFIG_H 17 18 /* ---- firmware id ------------------------------------------------------ */ 19 #define FW_VER_MAJ 2 20 21 /* ---- AC input window -------------------------------------------------- */ 22 #define VIN_LO_XFER 85.0f /* go to battery below this, Vrms */ 23 #define VIN_HI_XFER 265.0f /* go to battery above this, Vrms */ 24 25 /* ---- DC bus ----------------------------------------------------------- */ 26 #define VBUS_REF 400.0f /* PFC regulation target, V */ 27 28 /* ---- inverter / output ------------------------------------------------ */ 29 #define VO_NOM 220.0f /* output, Vrms */ 30 #define VO_TOL 0.03f /* +/- regulation band */ 31 #define VO_HI (VO_NOM * (1.0f + VO_TOL)) 32 #define IO_RATED 12.5f /* A rms, 1500 VA / 120 V */ 33 #define I_TRIP_RMS 14.0f /* overload shutdown, A rms */ 34 35 /* ---- PWM -------------------------------------------------------------- */ 36 #define TMR_LD 6000 /* PWM period, 25 kHz carrier */ 37 #define DB_CNT 30 /* 300 us dead time */ 38 39 /* ---- voltage loop (do not touch without power eng sign-off) ----------- */ 40 #define K_P 0.8f 41 #define K_I 0.015f /* per control ISR */ 42 43 /* ---- battery ---------------------------------------------------------- */ 44 #define VBAT_NOM 89.6f /* string nominal, V */ 45 #define VBAT_CUT 78.4f /* end of discharge, 1.75 V/cell */ 46 47 /* ---- comms / IO ------------------------------------------------------- */ 48 #define UART_BAUD 19200 /* front-panel / RS-232 port */ 49 #define PIN_BYP_RELAY 12 /* GPIO, static bypass relay drive */ 50 51 #endif /* UPS_CONFIG_H */
Every constant
Verdicts are deterministic (no AI). The last column is the AI draft: what a model thinks each number is, for a reviewer to accept or correct.
| Where | Symbol | Value | Verdict | AI draft (recorded) |
|---|---|---|---|---|
| protect.c:9 | FLT_LOG_LEN | 16 | not in spec | other · counts · no rule FLT_LOG_LEN (line 9) defines the length of flt_log ring buffer: static unsigned char flt_log[FLT_LOG_LEN]; used with mask (FLT_LOG_LEN - 1) for wraparound. |
| protect.c:13 | k_trip_a | 15.0f | match iout_trip | trip_limit · A · iout_trip k_trip_a (line 13) is 'A rms, overload trip' and is compared in prot_slow: if (i_rms > k_trip_a) with action after ol_hold_ms. This is the software overload trip current (RMS). |
| protect.c:14 | ol_hold_ms | 5000 | differs from design value current design: 30000 ms (overload_delay) | timing · ms · overload_delay ol_hold_ms (line 14) is the overload ride-through time; prot_slow increments ol_ms and trips only when ol_ms >= ol_hold_ms after i_rms exceeds k_trip_a. |
| protect.c:34 | <inline> | 21.2f | differs from design value current design: 43.75 A (iout_pk_limit) | trip_limit · A · iout_pk_limit Inline literal 21.2f in prot_fast (line 34) is commented 'peak of the RMS trip level' and triggers immediate inv_off and log_fault(FLT_OC) when abs(i_pk) exceeds it. This is a fast peak-current hardware-style software protection threshold. |
| protect.c:49 | <inline> | 0.9f | not in spec | protection_threshold · ratio · no rule Inline literal 0.9f in prot_slow (line 49) is used as vo_rms < 0.9f * VO_NOM to log a brownout fault (FLT_BRN). It defines the lower operating edge as a fraction of VO_NOM, not the trip level used for shutdown (no inv_off in this branch). |
| protect.c:54 | <inline> | 3 | not in spec | other · counts · no rule Inline literal 3 in prot_restart (line 54) is the retry limit: if (retry < 3) then delay_ms(500), inv_on(). |
| protect.c:55 | <inline> | 500 | not in spec | timing · ms · no rule Inline literal 500 in prot_restart (line 55) is the delay before retrying: delay_ms(500) prior to inv_on(). This is a restart backoff time, not the specified overload_delay. |
| sense_scale.h:9 | ADC_FULL | 4095.0f | not in spec | sense_scale_factor · counts · no rule ADC_FULL (line 9) is the ADC full-scale count value for the sense chain (12-bit converter), used to derive per-count scaling (see K_VS). |
| sense_scale.h:10 | DAC_FULL | 4095 | not in spec | other · counts · no rule DAC_FULL (line 10) is the comparator reference DAC full-scale code (used with CMP_DAC_HI/L0 to form hardware comparator trip thresholds). |
| sense_scale.h:13 | VBUS_FS | 498.3f | match vbus_fs | sense_full_scale · V · vbus_fs VBUS_FS (line 13) is “V at ADC full scale” for the DC bus divider; it directly corresponds to the bus ADC full-scale voltage rule vbus_fs. |
| sense_scale.h:14 | K_VS | (VBUS_FS / ADC_FULL) | differs from design value current design: 0.121655 V/count (vbus_scale) | sense_scale_factor · V/count · vbus_scale K_VS (line 14) is defined as (VBUS_FS / ADC_FULL) = volts per ADC count; corresponds to vbus_scale. |
| sense_scale.h:17 | VBAT_FS | 168.0f | match vbat_fs | sense_full_scale · V · vbat_fs VBAT_FS (line 17) is “V at ADC full scale” for the battery divider; corresponds to vbat_fs. |
| sense_scale.h:20 | VO_FS_PK | 501.6f | match vout_fs_pk | sense_full_scale · V · vout_fs_pk VO_FS_PK (line 20) is “peak V at +/- half scale” for the output voltage mid-rail biased sense range; matches vout_fs_pk. |
| sense_scale.h:23 | IO_FS_PK | 33.0f | differs from design value current design: 82.5 A (iout_fs_pk) | sense_full_scale · A · iout_fs_pk IO_FS_PK (line 23) is “peak A at +/- half scale” for mid-rail biased output current sensing; matches iout_fs_pk. |
| sense_scale.h:24 | CMP_DAC_HI | 3364 | differs from design value current design: 3134 (iout_pklim_dac_hi) | trip_limit · counts · iout_pklim_dac_hi CMP_DAC_HI (line 24) is the positive overcurrent trip code from the comparator reference DAC; corresponds to iout_pklim_dac_hi. |
| sense_scale.h:25 | CMP_DAC_LO | (DAC_FULL - CMP_DAC_HI) | differs from design value current design: 962 (iout_pklim_dac_lo) | trip_limit · counts · iout_pklim_dac_lo CMP_DAC_LO (line 25) is (DAC_FULL - CMP_DAC_HI), the negative comparator trip code; corresponds to iout_pklim_dac_lo. |
| ups_config.h:19 | FW_VER_MAJ | 2 | not in spec | version_or_id · none · no rule FW_VER_MAJ (line 19) is the firmware major version ID. |
| ups_config.h:22 | VIN_LO_XFER | 85.0f | match vin_min | protection_threshold · V · vin_min VIN_LO_XFER (line 22) is the AC input window lower transfer point: “go to battery below this, Vrms” => lowest input voltage before transfer to battery. |
| ups_config.h:23 | VIN_HI_XFER | 265.0f | match vin_max | protection_threshold · V · vin_max VIN_HI_XFER (line 23) is the AC input window upper transfer point: “go to battery above this, Vrms” => highest input voltage before transfer to battery. |
| ups_config.h:26 | VBUS_REF | 400.0f | differs from design value current design: 410 V (vbus_set) | setpoint · V · vbus_set VBUS_REF (line 26) is labeled PFC regulation target, “V”. It corresponds to the DC bus regulation setpoint, rule vbus_set (though rule definition says bus minimum + margin, rounded up to 10 V). |
| ups_config.h:29 | VO_NOM | 220.0f | contradicts data sheet data sheet gives 120 V (vout_set) | protection_threshold · V · vout_set VO_NOM (line 29) is output nominal voltage, Vrms. This is the intended output regulation setpoint (rule vout_set). |
| ups_config.h:30 | VO_TOL | 0.03f | not in spec | protection_threshold · ratio · no rule VO_TOL (line 30) is the tolerance band width given as ±0.03 around VO_NOM (ratio of nominal). It defines the regulation band edges indirectly, but is not itself a rule quantity. |
| ups_config.h:31 | VO_HI | (VO_NOM * (1.0f + VO_TOL)) | contradicts data sheet data sheet gives 123.6 V (vout_hi) | protection_threshold · V · vout_hi VO_HI (line 31) is computed as VO_NOM * (1.0f + VO_TOL), i.e., upper edge of the output regulation band (+VO_TOL). Maps directly to rule vout_hi. |
| ups_config.h:32 | IO_RATED | 12.5f | match iout_rated | other · A · iout_rated IO_RATED (line 32) is labeled “A rms, 1500 VA / 120 V” => rated output current (rule iout_rated). |
| ups_config.h:33 | I_TRIP_RMS | 14.0f | contradicts data sheet data sheet gives 15 A (iout_trip) | trip_limit · A · iout_trip I_TRIP_RMS (line 33) is labeled “overload shutdown, A rms” => software overload trip level (rule iout_trip). |
| ups_config.h:36 | TMR_LD | 6000 | differs from design value current design: 2500 (pwm_period) | timing · counts · pwm_period TMR_LD (line 36) is labeled “PWM period, 25 kHz carrier” and is used as a PWM period register value. Maps to pwm_period in center-aligned count mode (TBPRD = f_clk/(2 f_sw)). |
| ups_config.h:37 | DB_CNT | 30 | differs from design value current design: 100 (pwm_deadband) | timing · counts · pwm_deadband DB_CNT (line 37) is labeled “300 us dead time” and is the dead-time count register => pwm_deadband. |
| ups_config.h:40 | K_P | 0.8f | match vloop_kp | control_gain · ratio · vloop_kp K_P (line 40) is labeled “voltage loop” proportional gain => vloop_kp. |
| ups_config.h:41 | K_I | 0.015f | match vloop_ki | control_gain · ratio · vloop_ki K_I (line 41) is labeled “voltage loop” integral gain per control ISR => vloop_ki. |
| ups_config.h:44 | VBAT_NOM | 89.6f | match vbat_nom | battery · V · vbat_nom VBAT_NOM (line 44) is labeled “string nominal, V” => battery nominal voltage (vbat_nom). |
| ups_config.h:45 | VBAT_CUT | 78.4f | differs from design value current design: 70 V (vbat_cutoff) | battery · V · vbat_cutoff VBAT_CUT (line 45) is labeled “end of discharge” => low-battery shutdown voltage (vbat_cutoff). |
| ups_config.h:48 | UART_BAUD | 19200 | not in spec | comms_or_buffer · baud · no rule UART_BAUD (line 48) is the UART baud rate for front-panel/RS-232 port => comms_or_buffer. |
| ups_config.h:49 | PIN_BYP_RELAY | 12 | not in spec | pin_map · none · no rule PIN_BYP_RELAY (line 49) is a GPIO pin assignment for the static bypass relay drive => pin_map. |
AI classification results
Scored against the blind answer key; mean (min–max) over recorded runs. Bar set before any model ran: mean ≥ 90% category and ≥ 85% units. Recorded runs are replayed here; no model is called from this page.
| Model | Runs | Category | Units | Typed vs derived | Rule mapping | Cost / run | Verdict |
|---|---|---|---|---|---|---|---|
| gpt-5.4-nano | 3 | 83% (79–85) | 95% (94–97) | 100% | 99% (97–100) | $0.0042 | below bar |
What this means: gpt-5.4-nano maps legacy constants to the right rule almost every time, which is what the audit needs, but its category labels disagree with the key on borderline cases (is a 4095 ADC count "sense full scale" or "other"?) often enough to miss the bar. Under the rule set in advance, no recorded model passes yet; the next step would be a stronger model, not a looser bar. History: an earlier single run scored 91% on category with a different rule set, and the very first run scored 39% because of two harness bugs (fixed and tested). All runs are kept in the repository.
How the AI is used, and where it is not
- The model sees one file at a time and answers in a strict JSON schema; every answer is validated.
- Its output is a draft mapping for review. It never edits firmware or specs.
- The firmware path (spec → constants → gates → C code) never calls a model.
- On controlled data (vendor-confidential, CUI, ITAR), run a local model behind the same interface, or turn the step off.