main
John Lauer R0 engineering checkpoint: checked schematic, sourcing, servo evidence and safety-policy code; PCB and qualification incomplete 10054d3 1h ago
/* Register-level implementation from TI DACx0501 SBAS794E and INA226 SBOS547.
 * Board adapter supplies bounded-time I2C operations and big-endian 16-bit words.
 * Keep MCU_ENABLE low throughout initialization and on ANY returned false.
 */
#include "instruments.h"
#define DAC_ADDR 0x48
#define INA_ADDR 0x40
bool load_dac_write(const load_i2c *b,uint16_t code){
 if(code>4095)return false;
 uint16_t status=0;
 return b->write16(DAC_ADDR,8,(uint16_t)(code<<4)) && b->read16(DAC_ADDR,7,&status) && !(status&1);
}
bool load_instruments_init(const load_i2c *b){
 uint16_t id=0,mfr=0,gain=0,status=0;
 if(!b || !b->write16 || !b->read16 || !b->delay_ms)return false;
 if(!b->write16(DAC_ADDR,8,0))return false;
 if(!b->read16(DAC_ADDR,1,&id)||id!=0x2115)return false; /* DAC60501Z, not M or 16-bit */
 /* At VDD=3.3V the internal 2.5V reference MUST be divided by 2.
    Buffer gain 2 restores a 2.5V output span. GAIN bits 8 and 0 = 1. */
 if(!b->write16(DAC_ADDR,3,0)||!b->write16(DAC_ADDR,4,0x0101)||!b->write16(DAC_ADDR,2,0))return false;
 b->delay_ms(10); /* conservative startup delay; verify on hardware */
 if(!b->read16(DAC_ADDR,4,&gain)||gain!=0x0101||!b->read16(DAC_ADDR,7,&status)||(status&1))return false;
 if(!b->read16(INA_ADDR,0xFE,&mfr)||mfr!=0x5449||!b->read16(INA_ADDR,0xFF,&id)||(id&0xFFF0)!=0x2260)return false;
 /* 16 averages, 1.1ms bus + 1.1ms shunt each, continuous (~35.2ms update). */
 if(!b->write16(INA_ADDR,0,0x4527)||!b->write16(INA_ADDR,5,1024))return false;
 return load_dac_write(b,0);
}
bool load_ina_read(const load_i2c *b,float *v,float *a){
 uint16_t flags=0,shunt=0,bus=0;
 if(!b->read16(INA_ADDR,6,&flags)||!(flags&8)||(flags&4))return false;
 if(!b->read16(INA_ADDR,1,&shunt)||!b->read16(INA_ADDR,2,&bus))return false;
 /* The current conversion below uses shunt volts directly, independent of CAL.
    Bus measurement is AFTER the input protection diode, not the DUT connector. */
 *v=(float)bus*.00125f;*a=(float)(int16_t)shunt*.000125f;
 return true;
}