"""Helios status-register bit definitions (Tables 8-1, 8-2, 8-3). Kept out of the driver and out of the Qt apps so that a command-line diagnostic can decode a register without importing either. Each entry: bit_number -> (severity, description, comment) severity: 'C' = critical error, 'S' = status, 'I' = input error, '' = none """ LER_FLAGS = { 0: ('C', 'Controller temperature failure (resonator/SHG/q-switch)', 'Check CCE register for details'), 1: ('S', 'Trigger input active', 'High when trigger signal applied or laser in continuous pulsing'), 2: ('I', 'Command error', 'Unknown command sent to controller'), 3: ('C', 'Laser disable pin open (utility connector)', 'Shuts down pump diodes; reset LER 0 required to restart'), 4: ('C', 'Internal hardware failure', 'Contact Coherent'), 5: ('C', 'Over voltage laser diode', 'Check for open circuit or voltage spikes'), 6: ('C', 'Internal hardware failure', 'Contact Coherent'), 7: ('C', 'Controller temperature failure at pump diodes', 'Check LCE register for details'), 8: ('S', 'Laser start delay (60 s warmup)', 'Laser cannot be started yet; status error LED flashing'), 9: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 10: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 11: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 12: ('S', 'Slave controller error (remote input)', 'Valid only for master controller coupled with a slave'), 13: ('', 'Laserhead not found', 'Head not connected / not found; check EMI; ignore for double-electronic slave'), 14: ('', 'Laserhead I\u00b2C acknowledge error', 'Check environment for strong EMI; ignore for double-electronic slave'), 15: ('S', 'Range-Error (not critical)', 'Input value out of range'), } LCE_FLAGS = { 0: ('C', 'Pump diode over/under temperature', 'Limit exceeded (<10\u00b0C or >60\u00b0C); check head cooling'), 1: ('C', 'Internal hardware failure', 'Contact Coherent'), 2: ('C', 'Pump diode temperature out of range', 'Actual temp >2\u00b0C off setpoint for >1 min'), 3: ('C', 'Pump diode current critical', 'Current set too close to current limit'), 4: ('C', 'Pump diode temperature out of limit', 'Pump diode temperature is out of limit'), 5: ('S', 'Door switch open', 'Close utility connector pin 2 permanently to pin 9 (GND)'), 7: ('C', 'Pump diode NTC error', 'Invalid temperature measured or NTC broken'), 8: ('C', 'Laser diode power stage over temperature', 'Temp <10\u00b0C or >65\u00b0C at controller; check controller cooling'), 9: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 10: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 11: ('C', 'Internal hardware failure', 'Check environment for strong EMI; contact Coherent'), 15: ('S', 'Range-Error (not critical)', 'Input value out of range'), } CCE_FLAGS = { 0: ('C', 'Resonator/SHG under/over temperature', 'Limit exceeded (<10\u00b0C or >60\u00b0C); temperature controller deactivated'), 1: ('C', 'Resonator/SHG NTC failure', 'Temperature sensor broken or disconnected'), 2: ('C', 'Resonator/SHG temperature out of range', 'Actual temp >2\u00b0C off setpoint for >1 min'), 3: ('C', 'Q-switch ADC / temperature readout failure', 'Internal hardware error or no NTC connected'), 4: ('C', 'Q-switch temperature out of range', 'Actual temp >2\u00b0C off setpoint for >1 min'), 5: ('C', 'Q-switch under/over temperature', 'Limit exceeded (<10\u00b0C or >60\u00b0C); temperature controller deactivated'), 7: ('C', 'Q-switch NTC failure', 'Internal hardware error or no NTC connected'), 8: ('C', 'Internal hardware failure', 'Contact Coherent'), 15: ('S', 'Range-Error (not critical)', 'Input value out of range'), } SEVERITY_LABEL = {'C': '[CRIT]', 'S': '[STAT]', 'I': '[INPT]', '': '[INFO]'} def decode_register(flags_dict: dict, value: int) -> list: """Return list of (bit, severity, description, comment) for each set bit.""" active = [] for bit, (sev, desc, comment) in flags_dict.items(): if value & (1 << bit): active.append((bit, sev, desc, comment)) return active