#ifndef PCA9956B_FAULT_MONITOR_H
#define PCA9956B_FAULT_MONITOR_H
#include <stdint.h>
#include <stdbool.h>
/* One callback = pointer-write/register repeated-START read1byte/NACK/STOP.
 * Unshifted7bit unicast address; no register data writes/CLRERR permitted.
 * Must return only after STOP, bounded within the scheduler budget. */
typedef bool (*pca_fault_read_fn)(void *ctx,uint8_t addr,uint8_t reg,uint8_t *out);
typedef struct {
    uint32_t short_mask,open_mask,invalid_code_mask;
    uint32_t requested_mask,eligible_mask;
    uint32_t first_read_ms,completed_ms,sequence;
    uint8_t mode2_before,mode2_after;
    bool overtemperature,global_error,summary_mismatch,coverage_complete;
} pca_fault_snapshot;
typedef struct {
    void *ctx;pca_fault_read_fn read;
    uint8_t address,step,mode2_before,eflag[6];
    uint32_t requested_mask,eligible_mask,last_poll,first_read,sequence;
    bool bound,failed,valid;
    pca_fault_snapshot snapshot;
} pca_fault_monitor;
/* requested selects populated channels; eligible MUST be independently derived
 * from actual LEDOUT/IREF/PWM>=8, enabled powered load and qualified REXT<=3k.
 * It cannot be inferred from all-zero flags or from commanded PWM alone.
 * This monitor never grants led_driver_ok/output permission. Main-loop owner. */
bool pca_fault_init(pca_fault_monitor *m,void *ctx,pca_fault_read_fn read,
                    uint8_t address,uint32_t requested,uint32_t eligible,uint32_t now);
void pca_fault_poll(pca_fault_monitor *m,uint32_t now);
bool pca_fault_get(const pca_fault_monitor *m,uint32_t now,pca_fault_snapshot *out);
#endif
