← Commit history
Modular_BMS.glbadded
⋯ 1 unchanged line ⋯
PlatformIO/MSP430_BQ76952/platformio.iniadded+14
@@ -0,0 +1,14 @@+; PlatformIO Project Configuration File+;+;   Build options: build flags, source filter+;   Upload options: custom upload port, speed and extra flags+;   Library options: dependencies, extra library storages+;   Advanced options: extra scripting+;+; Please visit documentation for the other options and examples+; https://docs.platformio.org/page/projectconf.html++[env:lpmsp430f5529]+platform = timsp430+board = lpmsp430f5529+framework = arduino
PlatformIO/MSP430_BQ76952/src/BQ769x2Header.hadded+409
@@ -0,0 +1,409 @@+//BQ769x2 General Program Header File++//Data	Memory	registers	Name in TRM+#define Cell1Gain 0x9180      //Calibration:Voltage:Cell 1 Gain			+#define Cell2Gain 0x9182      //Calibration:Voltage:Cell 2 Gain			+#define Cell3Gain 0x9184      //Calibration:Voltage:Cell 3 Gain			+#define Cell4Gain 0x9186      //Calibration:Voltage:Cell 4 Gain			+#define Cell5Gain 0x9188      //Calibration:Voltage:Cell 5 Gain			+#define Cell6Gain 0x918A      //Calibration:Voltage:Cell 6 Gain			+#define Cell7Gain 0x918C      //Calibration:Voltage:Cell 7 Gain			+#define Cell8Gain 0x918E      //Calibration:Voltage:Cell 8 Gain			+#define Cell9Gain 0x9190      //Calibration:Voltage:Cell 9 Gain			+#define Cell10Gain 0x9192      //Calibration:Voltage:Cell 10 Gain			+#define Cell11Gain 0x9194      //Calibration:Voltage:Cell 11 Gain			+#define Cell12Gain 0x9196      //Calibration:Voltage:Cell 12 Gain			+#define Cell13Gain 0x9198      //Calibration:Voltage:Cell 13 Gain			+#define Cell14Gain 0x919A      //Calibration:Voltage:Cell 14 Gain			+#define Cell15Gain 0x919C      //Calibration:Voltage:Cell 15 Gain			+#define Cell16Gain 0x919E      //Calibration:Voltage:Cell 16 Gain			+#define PackGain 0x91A0      //Calibration:Voltage:Pack Gain			+#define TOSGain 0x91A2      //Calibration:Voltage:TOS Gain			+#define LDGain 0x91A4      //Calibration:Voltage:LD Gain			+#define ADCGain 0x91A6      //Calibration:Voltage:ADC Gain			+#define CCGain 0x91A8      //Calibration:Current:CC Gain			+#define CapacityGain 0x91AC      //Calibration:Current:Capacity Gain			+#define VcellOffset 0x91B0      //Calibration:Vcell Offset:Vcell Offset			+#define VdivOffset 0x91B2      //Calibration:V Divider Offset:Vdiv Offset			+#define CoulombCounterOffsetSamples 0x91C6      //Calibration:Current Offset:Coulomb Counter Offset Samples			+#define BoardOffset 0x91C8      //Calibration:Current Offset:Board Offset			+#define InternalTempOffset 0x91CA      //Calibration:Temperature:Internal Temp Offset			+#define CFETOFFTempOffset 0x91CB      //Calibration:Temperature:CFETOFF Temp Offset			+#define DFETOFFTempOffset 0x91CC      //Calibration:Temperature:DFETOFF Temp Offset			+#define ALERTTempOffset 0x91CD      //Calibration:Temperature:ALERT Temp Offset			+#define TS1TempOffset 0x91CE      //Calibration:Temperature:TS1 Temp Offset			+#define TS2TempOffset 0x91CF      //Calibration:Temperature:TS2 Temp Offset			+#define TS3TempOffset 0x91D0      //Calibration:Temperature:TS3 Temp Offset			+#define HDQTempOffset 0x91D1      //Calibration:Temperature:HDQ Temp Offset			+#define DCHGTempOffset 0x91D2      //Calibration:Temperature:DCHG Temp Offset			+#define DDSGTempOffset 0x91D3      //Calibration:Temperature:DDSG Temp Offset			+#define IntGain 0x91E2      //Calibration:Internal Temp Model:Int Gain			+#define Intbaseoffset 0x91E4      //Calibration:Internal Temp Model:Int base offset			+#define IntMaximumAD 0x91E6      //Calibration:Internal Temp Model:Int Maximum AD			+#define IntMaximumTemp 0x91E8      //Calibration:Internal Temp Model:Int Maximum Temp			+#define T18kCoeffa1 0x91EA      //Calibration:18K Temperature Model:Coeff a1			+#define T18kCoeffa2 0x91EC      //Calibration:18K Temperature Model:Coeff a2			+#define T18kCoeffa3 0x91EE      //Calibration:18K Temperature Model:Coeff a3			+#define T18kCoeffa4 0x91F0      //Calibration:18K Temperature Model:Coeff a4			+#define T18kCoeffa5 0x91F2      //Calibration:18K Temperature Model:Coeff a5			+#define T18kCoeffb1 0x91F4      //Calibration:18K Temperature Model:Coeff b1			+#define T18kCoeffb2 0x91F6      //Calibration:18K Temperature Model:Coeff b2			+#define T18kCoeffb3 0x91F8      //Calibration:18K Temperature Model:Coeff b3			+#define T18kCoeffb4 0x91FA      //Calibration:18K Temperature Model:Coeff b4			+#define T18kAdc0 0x91FE      //Calibration:18K Temperature Model:Adc0			+#define T180kCoeffa1 0x9200      //Calibration:180K Temperature Model:Coeff a1			+#define T180kCoeffa2 0x9202      //Calibration:180K Temperature Model:Coeff a2			+#define T180kCoeffa3 0x9204      //Calibration:180K Temperature Model:Coeff a3			+#define T180kCoeffa4 0x9206      //Calibration:180K Temperature Model:Coeff a4			+#define T180kCoeffa5 0x9208      //Calibration:180K Temperature Model:Coeff a5			+#define T180kCoeffb1 0x920A      //Calibration:180K Temperature Model:Coeff b1			+#define T180kCoeffb2 0x920C      //Calibration:180K Temperature Model:Coeff b2			+#define T180kCoeffb3 0x920E      //Calibration:180K Temperature Model:Coeff b3			+#define T180kCoeffb4 0x9210      //Calibration:180K Temperature Model:Coeff b4			+#define T180kAdc0 0x9214      //Calibration:180K Temperature Model:Adc0			+#define CustomCoeffa1 0x9216      //Calibration:Custom Temperature Model:Coeff a1			+#define CustomCoeffa2 0x9218      //Calibration:Custom Temperature Model:Coeff a2			+#define CustomCoeffa3 0x921A      //Calibration:Custom Temperature Model:Coeff a3			+#define CustomCoeffa4 0x921C      //Calibration:Custom Temperature Model:Coeff a4			+#define CustomCoeffa5 0x921E      //Calibration:Custom Temperature Model:Coeff a5			+#define CustomCoeffb1 0x9220      //Calibration:Custom Temperature Model:Coeff b1			+#define CustomCoeffb2 0x9222      //Calibration:Custom Temperature Model:Coeff b2			+#define CustomCoeffb3 0x9224      //Calibration:Custom Temperature Model:Coeff b3			+#define CustomCoeffb4 0x9226      //Calibration:Custom Temperature Model:Coeff b4			+#define CustomRc0 0x9228      //Calibration:Custom Temperature Model:Rc0			+#define CustomAdc0 0x922A      //Calibration:Custom Temperature Model:Adc0			+#define CoulombCounterDeadband 0x922D      //Calibration:Current Deadband:Coulomb Counter Deadband			+#define CUVThresholdOverride 0x91D4      //Calibration:CUV:CUV Threshold Override			+#define COVThresholdOverride 0x91D6      //Calibration:COV:COV Threshold Override			+#define MinBlowFuseVoltage 0x9231      //Settings:Fuse:Min Blow Fuse Voltage			+#define FuseBlowTimeout 0x9233      //Settings:Fuse:Fuse Blow Timeout			+#define PowerConfig 0x9234      //Settings:Configuration:Power Config			+#define REG12Config 0x9236      //Settings:Configuration:REG12 Config			+#define REG0Config 0x9237      //Settings:Configuration:REG0 Config			+#define HWDRegulatorOptions 0x9238      //Settings:Configuration:HWD Regulator Options			+#define CommType 0x9239      //Settings:Configuration:Comm Type			+#define I2CAddress 0x923A      //Settings:Configuration:I2C Address			+#define SPIConfiguration 0x923C      //Settings:Configuration:SPI Configuration			+#define CommIdleTime 0x923D      //Settings:Configuration:Comm Idle Time			+#define CFETOFFPinConfig 0x92FA      //Settings:Configuration:CFETOFF Pin Config			+#define DFETOFFPinConfig 0x92FB      //Settings:Configuration:DFETOFF Pin Config			+#define ALERTPinConfig 0x92FC      //Settings:Configuration:ALERT Pin Config			+#define TS1Config 0x92FD      //Settings:Configuration:TS1 Config			+#define TS2Config 0x92FE      //Settings:Configuration:TS2 Config			+#define TS3Config 0x92FF      //Settings:Configuration:TS3 Config			+#define HDQPinConfig 0x9300      //Settings:Configuration:HDQ Pin Config			+#define DCHGPinConfig 0x9301      //Settings:Configuration:DCHG Pin Config			+#define DDSGPinConfig 0x9302      //Settings:Configuration:DDSG Pin Config			+#define DAConfiguration 0x9303      //Settings:Configuration:DA Configuration			+#define VCellMode 0x9304      //Settings:Configuration:Vcell Mode			+#define CC3Samples 0x9307      //Settings:Configuration:CC3 Samples			+#define ProtectionConfiguration 0x925F      //Settings:Protection:Protection Configuration			+#define EnabledProtectionsA 0x9261      //Settings:Protection:Enabled Protections A			+#define EnabledProtectionsB 0x9262      //Settings:Protection:Enabled Protections B			+#define EnabledProtectionsC 0x9263      //Settings:Protection:Enabled Protections C			+#define CHGFETProtectionsA 0x9265      //Settings:Protection:CHG FET Protections A			+#define CHGFETProtectionsB 0x9266      //Settings:Protection:CHG FET Protections B			+#define CHGFETProtectionsC 0x9267      //Settings:Protection:CHG FET Protections C			+#define DSGFETProtectionsA 0x9269      //Settings:Protection:DSG FET Protections A			+#define DSGFETProtectionsB 0x926A      //Settings:Protection:DSG FET Protections B			+#define DSGFETProtectionsC 0x926B      //Settings:Protection:DSG FET Protections C			+#define BodyDiodeThreshold 0x9273      //Settings:Protection:Body Diode Threshold			+#define DefaultAlarmMask 0x926D      //Settings:Alarm:Default Alarm Mask			+#define SFAlertMaskA 0x926F      //Settings:Alarm:SF Alert Mask A			+#define SFAlertMaskB 0x9270      //Settings:Alarm:SF Alert Mask B			+#define SFAlertMaskC 0x9271      //Settings:Alarm:SF Alert Mask C			+#define PFAlertMaskA 0x92C4      //Settings:Alarm:PF Alert Mask A			+#define PFAlertMaskB 0x92C5      //Settings:Alarm:PF Alert Mask B			+#define PFAlertMaskC 0x92C6      //Settings:Alarm:PF Alert Mask C			+#define PFAlertMaskD 0x92C7      //Settings:Alarm:PF Alert Mask D			+#define EnabledPFA 0x92C0      //Settings:Permanent Failure:Enabled PF A			+#define EnabledPFB 0x92C1      //Settings:Permanent Failure:Enabled PF B			+#define EnabledPFC 0x92C2      //Settings:Permanent Failure:Enabled PF C			+#define EnabledPFD 0x92C3      //Settings:Permanent Failure:Enabled PF D			+#define FETOptions 0x9308      //Settings:FET:FET Options			+#define ChgPumpControl 0x9309      //Settings:FET:Chg Pump Control			+#define PrechargeStartVoltage 0x930A      //Settings:FET:Precharge Start Voltage			+#define PrechargeStopVoltage 0x930C      //Settings:FET:Precharge Stop Voltage			+#define PredischargeTimeout 0x930E      //Settings:FET:Predischarge Timeout			+#define PredischargeStopDelta 0x930F      //Settings:FET:Predischarge Stop Delta			+#define DsgCurrentThreshold 0x9310      //Settings:Current Thresholds:Dsg Current Threshold			+#define ChgCurrentThreshold 0x9312      //Settings:Current Thresholds:Chg Current Threshold			+#define CheckTime 0x9314      //Settings:Cell Open-Wire:Check Time			+#define Cell1Interconnect 0x9315      //Settings:Interconnect Resistances:Cell 1 Interconnect			+#define Cell2Interconnect 0x9317      //Settings:Interconnect Resistances:Cell 2 Interconnect			+#define Cell3Interconnect 0x9319      //Settings:Interconnect Resistances:Cell 3 Interconnect			+#define Cell4Interconnect 0x931B      //Settings:Interconnect Resistances:Cell 4 Interconnect			+#define Cell5Interconnect 0x931D      //Settings:Interconnect Resistances:Cell 5 Interconnect			+#define Cell6Interconnect 0x931F      //Settings:Interconnect Resistances:Cell 6 Interconnect			+#define Cell7Interconnect 0x9321      //Settings:Interconnect Resistances:Cell 7 Interconnect			+#define Cell8Interconnect 0x9323      //Settings:Interconnect Resistances:Cell 8 Interconnect			+#define Cell9Interconnect 0x9325      //Settings:Interconnect Resistances:Cell 9 Interconnect			+#define Cell10Interconnect 0x9327      //Settings:Interconnect Resistances:Cell 10 Interconnect			+#define Cell11Interconnect 0x9329      //Settings:Interconnect Resistances:Cell 11 Interconnect			+#define Cell12Interconnect 0x932B      //Settings:Interconnect Resistances:Cell 12 Interconnect			+#define Cell13Interconnect 0x932D      //Settings:Interconnect Resistances:Cell 13 Interconnect			+#define Cell14Interconnect 0x932F      //Settings:Interconnect Resistances:Cell 14 Interconnect			+#define Cell15Interconnect 0x9331      //Settings:Interconnect Resistances:Cell 15 Interconnect			+#define Cell16Interconnect 0x9333      //Settings:Interconnect Resistances:Cell 16 Interconnect			+#define MfgStatusInit 0x9343      //Settings:Manufacturing:Mfg Status Init			+#define BalancingConfiguration 0x9335      //Settings:Cell Balancing Config:Balancing Configuration			+#define MinCellTemp 0x9336      //Settings:Cell Balancing Config:Min Cell Temp			+#define MaxCellTemp 0x9337      //Settings:Cell Balancing Config:Max Cell Temp			+#define MaxInternalTemp 0x9338      //Settings:Cell Balancing Config:Max Internal Temp			+#define CellBalanceInterval 0x9339      //Settings:Cell Balancing Config:Cell Balance Interval			+#define CellBalanceMaxCells 0x933A      //Settings:Cell Balancing Config:Cell Balance Max Cells			+#define CellBalanceMinCellVCharge 0x933B      //Settings:Cell Balancing Config:Cell Balance Min Cell V (Charge)			+#define CellBalanceMinDeltaCharge 0x933D      //Settings:Cell Balancing Config:Cell Balance Min Delta (Charge)			+#define CellBalanceStopDeltaCharge 0x933E      //Settings:Cell Balancing Config:Cell Balance Stop Delta (Charge)			+#define CellBalanceMinCellVRelax 0x933F      //Settings:Cell Balancing Config:Cell Balance Min Cell V (Relax)			+#define CellBalanceMinDeltaRelax 0x9341      //Settings:Cell Balancing Config:Cell Balance Min Delta (Relax)			+#define CellBalanceStopDeltaRelax 0x9342      //Settings:Cell Balancing Config:Cell Balance Stop Delta (Relax)			+#define ShutdownCellVoltage 0x923F      //Power:Shutdown:Shutdown Cell Voltage			+#define ShutdownStackVoltage 0x9241      //Power:Shutdown:Shutdown Stack Voltage			+#define LowVShutdownDelay 0x9243      //Power:Shutdown:Low V Shutdown Delay			+#define ShutdownTemperature 0x9244      //Power:Shutdown:Shutdown Temperature			+#define ShutdownTemperatureDelay 0x9245      //Power:Shutdown:Shutdown Temperature Delay			+#define FETOffDelay 0x9252      //Power:Shutdown:FET Off Delay			+#define ShutdownCommandDelay 0x9253      //Power:Shutdown:Shutdown Command Delay			+#define AutoShutdownTime 0x9254      //Power:Shutdown:Auto Shutdown Time			+#define RAMFailShutdownTime 0x9255      //Power:Shutdown:RAM Fail Shutdown Time			+#define SleepCurrent 0x9248      //Power:Sleep:Sleep Current			+#define VoltageTime 0x924A      //Power:Sleep:Voltage Time			+#define WakeComparatorCurrent 0x924B      //Power:Sleep:Wake Comparator Current			+#define SleepHysteresisTime 0x924D      //Power:Sleep:Sleep Hysteresis Time			+#define SleepChargerVoltageThreshold 0x924E      //Power:Sleep:Sleep Charger Voltage Threshold			+#define SleepChargerPACKTOSDelta 0x9250      //Power:Sleep:Sleep Charger PACK-TOS Delta			+#define ConfigRAMSignature 0x91E0      //System Data:Integrity:Config RAM Signature			+#define CUVThreshold 0x9275      //Protections:CUV:Threshold			+#define CUVDelay 0x9276      //Protections:CUV:Delay			+#define CUVRecoveryHysteresis 0x927B      //Protections:CUV:Recovery Hysteresis			+#define COVThreshold 0x9278      //Protections:COV:Threshold			+#define COVDelay 0x9279      //Protections:COV:Delay			+#define COVRecoveryHysteresis 0x927C      //Protections:COV:Recovery Hysteresis			+#define COVLLatchLimit 0x927D      //Protections:COVL:Latch Limit			+#define COVLCounterDecDelay 0x927E      //Protections:COVL:Counter Dec Delay			+#define COVLRecoveryTime 0x927F      //Protections:COVL:Recovery Time			+#define OCCThreshold 0x9280      //Protections:OCC:Threshold			+#define OCCDelay 0x9281      //Protections:OCC:Delay			+#define OCCRecoveryThreshold 0x9288      //Protections:OCC:Recovery Threshold			+#define OCCPACKTOSDelta 0x92B0      //Protections:OCC:PACK-TOS Delta			+#define OCD1Threshold 0x9282      //Protections:OCD1:Threshold			+#define OCD1Delay 0x9283      //Protections:OCD1:Delay			+#define OCD2Threshold 0x9284      //Protections:OCD2:Threshold			+#define OCD2Delay 0x9285      //Protections:OCD2:Delay			+#define SCDThreshold 0x9286      //Protections:SCD:Threshold			+#define SCDDelay 0x9287      //Protections:SCD:Delay			+#define SCDRecoveryTime 0x9294      //Protections:SCD:Recovery Time			+#define OCD3Threshold 0x928A      //Protections:OCD3:Threshold			+#define OCD3Delay 0x928C      //Protections:OCD3:Delay			+#define OCDRecoveryThreshold 0x928D      //Protections:OCD:Recovery Threshold			+#define OCDLLatchLimit 0x928F      //Protections:OCDL:Latch Limit			+#define OCDLCounterDecDelay 0x9290      //Protections:OCDL:Counter Dec Delay			+#define OCDLRecoveryTime 0x9291      //Protections:OCDL:Recovery Time			+#define OCDLRecoveryThreshold 0x9292      //Protections:OCDL:Recovery Threshold			+#define SCDLLatchLimit 0x9295      //Protections:SCDL:Latch Limit			+#define SCDLCounterDecDelay 0x9296      //Protections:SCDL:Counter Dec Delay			+#define SCDLRecoveryTime 0x9297      //Protections:SCDL:Recovery Time			+#define SCDLRecoveryThreshold 0x9298      //Protections:SCDL:Recovery Threshold			+#define OTCThreshold 0x929A      //Protections:OTC:Threshold			+#define OTCDelay 0x920B      //Protections:OTC:Delay			+#define OTCRecovery 0x929C      //Protections:OTC:Recovery			+#define OTDThreshold 0x929D      //Protections:OTD:Threshold			+#define OTDDelay 0x929E      //Protections:OTD:Delay			+#define OTDRecovery 0x929F      //Protections:OTD:Recovery			+#define OTFThreshold 0x92A0      //Protections:OTF:Threshold			+#define OTFDelay 0x92A1      //Protections:OTF:Delay			+#define OTFRecovery 0x92A2      //Protections:OTF:Recovery			+#define OTINTThreshold 0x92A3      //Protections:OTINT:Threshold			+#define OTINTDelay 0x92A4      //Protections:OTINT:Delay			+#define OTINTRecovery 0x92A5      //Protections:OTINT:Recovery			+#define UTCThreshold 0x92A6      //Protections:UTC:Threshold			+#define UTCDelay 0x92A7      //Protections:UTC:Delay			+#define UTCRecovery 0x92A8      //Protections:UTC:Recovery			+#define UTDThreshold 0x92A9      //Protections:UTD:Threshold			+#define UTDDelay 0x92AA      //Protections:UTD:Delay			+#define UTDRecovery 0x92AB      //Protections:UTD:Recovery			+#define UTINTThreshold 0x92AC      //Protections:UTINT:Threshold			+#define UTINTDelay 0x92AD      //Protections:UTINT:Delay			+#define UTINTRecovery 0x92AE      //Protections:UTINT:Recovery			+#define ProtectionsRecoveryTime 0x92AF      //Protections:Recovery:Time			+#define HWDDelay 0x92B2      //Protections:HWD:Delay			+#define LoadDetectActiveTime 0x92B4      //Protections:Load Detect:Active Time			+#define LoadDetectRetryDelay 0x92B5      //Protections:Load Detect:Retry Delay			+#define LoadDetectTimeout 0x92B6      //Protections:Load Detect:Timeout			+#define PTOChargeThreshold 0x92BA      //Protections:PTO:Charge Threshold			+#define PTODelay 0x92BC      //Protections:PTO:Delay			+#define PTOReset 0x92BE      //Protections:PTO:Reset			+#define CUDEPThreshold 0x92C8      //Permanent Fail:CUDEP:Threshold			+#define CUDEPDelay 0x92CA      //Permanent Fail:CUDEP:Delay			+#define SUVThreshold 0x92CB      //Permanent Fail:SUV:Threshold			+#define SUVDelay 0x92CD      //Permanent Fail:SUV:Delay			+#define SOVThreshold 0x92CE      //Permanent Fail:SOV:Threshold			+#define SOVDelay 0x92D0      //Permanent Fail:SOV:Delay			+#define TOSSThreshold 0x92D1      //Permanent Fail:TOS:Threshold			+#define TOSSDelay 0x92D3      //Permanent Fail:TOS:Delay			+#define SOCCThreshold 0x92D4      //Permanent Fail:SOCC:Threshold			+#define SOCCDelay 0x92D6      //Permanent Fail:SOCC:Delay			+#define SOCDThreshold 0x92D7      //Permanent Fail:SOCD:Threshold			+#define SOCDDelay 0x92D9      //Permanent Fail:SOCD:Delay			+#define SOTThreshold 0x92DA      //Permanent Fail:SOT:Threshold			+#define SOTDelay 0x92DB      //Permanent Fail:SOT:Delay			+#define SOTFThreshold 0x92DC      //Permanent Fail:SOTF:Threshold			+#define SOTFDelay 0x92DD      //Permanent Fail:SOTF:Delay			+#define VIMRCheckVoltage 0x92DE      //Permanent Fail:VIMR:Check Voltage			+#define VIMRMaxRelaxCurrent 0x92E0      //Permanent Fail:VIMR:Max Relax Current			+#define VIMRThreshold 0x92E2      //Permanent Fail:VIMR:Threshold			+#define VIMRDelay 0x92E4      //Permanent Fail:VIMR:Delay			+#define VIMRRelaxMinDuration 0x92E5      //Permanent Fail:VIMR:Relax Min Duration			+#define VIMACheckVoltage 0x92E7      //Permanent Fail:VIMA:Check Voltage			+#define VIMAMinActiveCurrent 0x92E9      //Permanent Fail:VIMA:Min Active Current			+#define VIMAThreshold 0x92EB      //Permanent Fail:VIMA:Threshold			+#define VIMADelay 0x92ED      //Permanent Fail:VIMA:Delay			+#define CFETFOFFThreshold 0x92EE      //Permanent Fail:CFETF:OFF Threshold			+#define CFETFOFFDelay 0x92F0      //Permanent Fail:CFETF:OFF Delay			+#define DFETFOFFThreshold 0x92F1      //Permanent Fail:DFETF:OFF Threshold			+#define DFETFOFFDelay 0x92F3      //Permanent Fail:DFETF:OFF Delay			+#define VSSFFailThreshold 0x92F4      //Permanent Fail:VSSF:Fail Threshold			+#define VSSFDelay 0x92F6      //Permanent Fail:VSSF:Delay			+#define PF2LVLDelay 0x92F7      //Permanent Fail:2LVL:Delay			+#define LFOFDelay 0x92F8      //Permanent Fail:LFOF:Delay			+#define HWMXDelay 0x92F9      //Permanent Fail:HWMX:Delay			+#define SecuritySettings 0x9256      //Security:Settings:Security Settings			+#define UnsealKeyStep1 0x9257      //Security:Keys:Unseal Key Step 1			+#define UnsealKeyStep2 0x9259      //Security:Keys:Unseal Key Step 2			+#define FullAccessKeyStep1 0x925B      //Security:Keys:Full Access Key Step 1			+#define FullAccessKeyStep2 0x925D      //Security:Keys:Full Access Key Step 2			++//Direct Commands +#define ControlStatus 0x00+#define SafetyAlertA 0x02+#define SafetyStatusA 0x03+#define SafetyAlertB 0x04+#define SafetyStatusB 0x05+#define SafetyAlertC 0x06+#define SafetyStatusC 0x07+#define PFAlertA 0x0A+#define PFStatusA 0x0B+#define PFAlertB 0x0C+#define PFStatusB 0x0D+#define PFAlertC 0x0E+#define PFStatusC 0x0F+#define PFAlertD 0x10+#define PFStatusD 0x11+#define BatteryStatus 0x12+#define Cell1Voltage 0x14+#define Cell2Voltage 0x16+#define Cell3Voltage 0x18+#define Cell4Voltage 0x1A+#define Cell5Voltage 0x1C+#define Cell6Voltage 0x1E+#define Cell7Voltage 0x20+#define Cell8Voltage 0x22+#define Cell9Voltage 0x24+#define Cell10Voltage 0x26+#define Cell11Voltage 0x28+#define Cell12Voltage 0x2A+#define Cell13Voltage 0x2C+#define Cell14Voltage 0x2E+#define Cell15Voltage 0x30+#define Cell16Voltage 0x32+#define StackVoltage 0x34+#define PACKPinVoltage 0x36+#define LDPinVoltage 0x38+#define CC2Current 0x3A+#define AlarmStatus 0x62+#define AlarmRawStatus 0x64+#define AlarmEnable 0x66+#define IntTemperature 0x68+#define CFETOFFTemperature 0x6A+#define DFETOFFTemperature 0x6C+#define ALERTTemperature 0x6E+#define TS1Temperature 0x70+#define TS2Temperature 0x72+#define TS3Temperature 0x74+#define HDQTemperature 0x76+#define DCHGTemperature 0x78+#define DDSGTemperature 0x7A+#define FETStatus 0x7F++//Subcommands +#define DEVICE_NUMBER 0x0001+#define FW_VERSION 0x0002+#define HW_VERSION 0x0003+#define IROM_SIG 0x0004+#define STATIC_CFG_SIG 0x0005+#define PREV_MACWRITE 0x0007+#define DROM_SIG 0x0009+#define SECURITY_KEYS 0x0035+#define SAVED_PF_STATUS 0x0053+#define MANUFACTURINGSTATUS 0x0057+#define MANU_DATA 0x0070+#define DASTATUS1 0x0071+#define DASTATUS2 0x0072+#define DASTATUS3 0x0073+#define DASTATUS4 0x0074+#define DASTATUS5 0x0075+#define DASTATUS6 0x0076+#define DASTATUS7 0x0077+#define CUV_SNAPSHOT 0x0080+#define COV_SNAPSHOT 0X0081+#define CB_ACTIVE_CELLS 0x0083+#define CB_SET_LVL 0x0084+#define CBSTATUS1 0x0085+#define CBSTATUS2 0x0086+#define CBSTATUS3 0x0087+#define FET_CONTROL 0x0097+#define REG12_CONTROL 0x0098+#define OTP_WR_CHECK 0x00A0+#define OTP_WRITE 0x00A1+#define READ_CAL1 0xF081+#define CAL_CUV 0xF090+#define CAL_COV 0xF091++// Command Only Subcommands +#define EXIT_DEEPSLEEP 0x000E+#define DEEPSLEEP 0x000F+#define SHUTDOWN 0x0010+#define BQ769x2_RESET 0x0012 //"RESET" in documentation+#define PDSGTEST 0x001C+#define FUSE_TOGGLE 0x001D+#define PCHGTEST 0x001E+#define CHGTEST 0x001F+#define DSGTEST 0x0020+#define FET_ENABLE 0x0022+#define PF_ENABLE 0x0024+#define PF_RESET 0x0029+#define SEAL 0x0030+#define RESET_PASSQ 0x0082+#define PTO_RECOVER 0x008A+#define SET_CFGUPDATE 0x0090+#define EXIT_CFGUPDATE 0x0092+#define DSG_PDSG_OFF 0x0093+#define CHG_PCHG_OFF 0x0094+#define ALL_FETS_OFF 0x0095+#define ALL_FETS_ON 0x0096+#define SLEEP_ENABLE 0x0099+#define SLEEP_DISABLE 0x009A+#define OCDL_RECOVER 0x009B+#define SCDL_RECOVER 0x009C+#define LOAD_DETECT_RESTART 0x009D+#define LOAD_DETECT_ON 0x009E+#define LOAD_DETECT_OFF 0x009F+#define CFETOFF_LO 0x2800+#define DFETOFF_LO 0x2801+#define ALERT_LO 0x2802+#define HDQ_LO 0x2806+#define DCHG_LO 0x2807+#define DDSG_LO 0x2808+#define CFETOFF_HI 0x2810+#define DFETOFF_HI 0x2811+#define ALERT_HI 0x2812+#define HDQ_HI 0x2816+#define DCHG_HI 0x2817+#define DDSG_HI 0x2818+#define PF_FORCE_A 0x2857+#define PF_FORCE_B 0x29A3+#define SWAP_COMM_MODE 0x29BC+#define SWAP_TO_I2C 0x29E7+#define SWAP_TO_SPI 0x7C35+#define SWAP_TO_HDQ 0x7C40
PlatformIO/MSP430_BQ76952/src/README.mdadded+336
@@ -0,0 +1,336 @@+# BQ76952EVM + MSP430F5529 BMS Firmware++Firmware for the **BQ76952EVM** using an **MSP430F5529** as the I²C host. This project is based on TI’s BQ769x2 demo framework and adds higher-level helpers for:++- n-cell configuration using `VCellMode`+- periodic measurement polling and alarm handling+- CHG/DSG FET control from two GPIO inputs (P3.3 and P3.4)+- structured output in **human-readable** or **JSON** notification format in Hydrogen Style++---++## Hardware++- **MSP430F5529LP** eval board (for programming over SBW)+- **MSP430F5529** (host MCU)+- **BQ76952EVM** (battery monitor + protection + balancing)+- I²C: UCB1 mapped to **P4.4=SCL**, **P4.5=SDA**+- UART: UCA1 mapped to **P4.2=RX**, **P4.3=TX**+- FET control inputs:+  - **P3.3** → enable **Discharge** (DSG)+  - **P3.4** → enable **Charge** (CHG)+  - Both are configured as GPIO inputs with pulldown resistors++---++## Build / Run++This code is intended to be built in PIO toolchain using the MSP430F5529 eval board for SBW programming.++At startup, `main()`:+1. Stops the watchdog+2. Initializes GPIO, port mapping, UART, I²C+3. Resets the BQ76952+4. Applies RAM configuration via `BQ769x2_Init()`+5. Enables FET control and disables sleep for full-speed measurement updates+6. Enters the main polling loop++---++## Configuration++### Cell Count++This project is configured for **3 cells** using `VCellMode`:++```c+#define NUM_CELLS 3+#define NUM_CELLS_BITS 0x0007   // enable Cell1..Cell3+```++`NUM_CELLS_BITS` is written to the `VCellMode` register inside `BQ769x2_Init()`.++---++## Output Modes++A global `output_mode` controls whether telemetry is printed as:+- `OUTPUT_HUMAN`: readable console logs via `printf`+- `OUTPUT_JSON`: JSON notification packets (Hydrogen-style wrapper)++Select mode:++```c+set_output_mode(OUTPUT_HUMAN);+// or+set_output_mode(OUTPUT_JSON);+```++### JSON Wrapper++JSON output is wrapped in a common “notification” envelope via:++- `send_json_notification_data(method, id, data_str)`+- `send_json_notification_fmt(method, id, data_fmt, ...)`++All BMS-specific output functions ultimately route through these.++---++## Key High-Level BQ76952 Functions++### `BQ769x2_Init()`++Applies the core BQ76952 RAM configuration:+- enters `CONFIG_UPDATE`+- sets power / regulator / TS pin config+- sets `VCellMode` for your pack (3S by default)+- enables protections (SCD/OCD/OV/UV/etc.)+- sets alarm mask, balancing config, thresholds+- exits `CONFIG_UPDATE`++**Used in `main()` once after reset**, before enabling FETs.++---++### `BQ769x2_ReadAlarmStatus()`++Reads `AlarmStatus` (direct command) and returns a 16-bit bitmask.++In `main()` this is used as the “scheduler”:+- if FULLSCAN bit is set → new measurements are ready+- if SafetyStatus alarm bits set → fetch safety status++---++### `BQ769x2_ReadAllVoltages()`++Updates:+- `CellVoltage[0..15]` from `Cell1Voltage..Cell16Voltage`+- `Stack_Voltage` from `StackVoltage`+- `Pack_Voltage` from `PACKPinVoltage`+- `LD_Voltage` from `LDPinVoltage`++**Important note:** on the EVM, `Pack_Voltage` is the PACK pin *after* the FETs, so it may read ~0V when DSG/CHG FETs are open.+**Important note:** on the EVM, `Stack_Voltage` is what we would usually call the "Battery Pack" voltage. Basically the voltage from top cell to GND. ++---++### `BQ769x2_ReadVoltage(command)`++Generic “direct command” voltage read:+- Cell voltages are returned in **mV**+- Stack/Pack/LD voltages are treated as **0.01V units** and converted to mV++---++### `BQ769x2_ReadCurrent()`++Reads `CC2Current` (direct command) and returns the raw 16-bit value.++**Current direction:** CC2 current is signed (two’s complement).++Recommended usage in this codebase:++```c+int16_t current_mA = (int16_t)BQ769x2_ReadCurrent();+// positive = charging, negative = discharging+```++---++### `BQ769x2_ReadTemperature(command)`++Reads a temperature direct command (e.g., `TS1Temperature`) and converts to °C:++```c+Temperature_C = 0.1 * raw_K - 273.15+```++---++## Protection / Fault Monitoring++### `BQ769x2_ReadSafetyStatus()`++Reads:+- `SafetyStatusA`+- `SafetyStatusB`+- `SafetyStatusC`++And derives high-level flags:+- `UV_Fault`, `OV_Fault`, `SCD_Fault`, `OCD_Fault`+- `ProtectionsTriggered`++In `main()`, safety status is checked whenever AlarmStatus indicates safety-related bits or when a protection was previously active.++---++### `BQ769x2_ReadPFStatus()`++Reads Permanent Failure status registers A/B/C. Useful when diagnosing “fuse LED” or persistent shutdown behavior.++---++## FET Control (CHG/DSG)++### `BQ769x2_ReadFETStatus()`++Reads `FETStatus` and updates globals:+- `CHG`, `DSG`, `PCHG`, `PDSG`++Use this to confirm the actual driver states.++---++### `BQ769x2_WriteFETStatus(bool DSG, bool CHG)`++Controls CHG/DSG using the **FET_CONTROL** subcommand.++This function uses the BQ76952 convention:+- writing `DSG_OFF=1` forces DSG OFF+- writing `CHG_OFF=1` forces CHG OFF++So the function takes **enable booleans** and internally writes the “OFF” bits as needed.++Example:++```c+BQ769x2_WriteFETStatus(true, false);  // DSG enabled, CHG forced off+```++> Note: this is host control. The BQ76952 may still keep FETs open if protections are active (UV/OV/OCD/SCD/PF).++---++### `update_fets_from_buttons()`++Reads the two GPIO inputs and applies FET control:+- `P3.3 high` → enable discharge (DSG)+- `P3.4 high` → enable charge (CHG)++Then:++```c+BQ769x2_WriteFETStatus(dsg_enable, chg_enable);+```++This is called periodically from `main()` (currently every 20 cycles).++---++## Output Helpers (Human + JSON)++These functions produce either console output or JSON notifications depending on `output_mode`.++### `output_bms_config(battery_type, cell_count)`++Emits a config packet at startup and periodically.++### `output_bms_voltages(pack_mV, CellVoltage[], cell_count)`++Emits pack + per-cell voltages.++### `output_fet_status(chg, dsg)`++Emits CHG/DSG states as booleans/ints.++### `output_current_value(current_mA)`++Emits signed current in mA.++---++## Main Loop Behavior (Current Program)++The `while(1)` loop does:++1. Read `AlarmStatus`+2. If FULLSCAN complete → read voltages/current/temps → clear FULLSCAN bit+3. If safety alarm bits present → read safety status → clear alarm bits+4. Every ~20 cycles:+   - output voltages+   - update FETs from button inputs+   - read and output FET states+   - read and output current+5. Every ~100 cycles:+   - re-emit config and print faults if present+6. Delay ~20 ms++---++## How to Write Your Own `main()`++A minimal, clean template:++```c+int main(void)+{+    WDTCTL = WDTPW | WDTHOLD;++    GPIO_initPins();+    map_I2C_and_UART();+    UART_Init();+    I2C_initModule();++    set_output_mode(OUTPUT_JSON);++    CommandSubcommands(BQ769x2_RESET);+    delayUS(60000);++    BQ769x2_Init();+    delayUS(10000);++    CommandSubcommands(FET_ENABLE);+    CommandSubcommands(SLEEP_DISABLE);++    while (1)+    {+        uint16_t alarms = BQ769x2_ReadAlarmStatus();++        if (alarms & 0x80) {+            BQ769x2_ReadAllVoltages();+            int16_t current_mA = (int16_t)BQ769x2_ReadCurrent();++            // clear FULLSCAN complete bit+            DirectCommands(AlarmStatus, 0x0080, W);++            output_bms_voltages(Stack_Voltage, CellVoltage, NUM_CELLS);+            output_current_value(current_mA);+        }++        update_fets_from_buttons();++        if (alarms & 0xC000) {+            BQ769x2_ReadSafetyStatus();+            // clear safety alarm bits+            DirectCommands(AlarmStatus, 0xF800, W);+        }++        delayUS(20000);+    }+}+```++Recommended approach:+- Drive logic from `AlarmStatus` FULLSCAN rather than reading constantly.+- Keep FET control separate (e.g., button read each loop).+- Treat CC2 current as **signed** (cast to `int16_t`).++---++## Common Gotchas++- **PACK pin voltage reading 0V** is normal if the PACK node is not being driven and/or FETs are open.+- **Current is signed**; treat `CC2Current` as two’s-complement.+- Protections (UV/OV/OCD/SCD/PF) can override host FET commands.+- If the EVM “FUSE” LED is on, check PF status and PF-related configuration.++---++## Module Notes++- `BQ769x2Header.h`: contains direct command IDs, subcommands, and RAM register addresses+- Low-level comms:+  - `I2C_ReadReg()`, `I2C_WriteReg()`, ISR state machine+  - `DirectCommands()`, `Subcommands()`, `CommandSubcommands()`
PlatformIO/MSP430_BQ76952/src/main_MSP430FR2355_I2C.cppadded+1216
@@ -0,0 +1,1216 @@+#include "msp430f5529.h"+#define ACTIVE+#ifdef ACTIVE++/* --COPYRIGHT--,BSD_EX+ * Copyright (c) 2021, Texas Instruments Incorporated+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * *  Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ *+ * *  Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * *  Neither the name of Texas Instruments Incorporated nor the names of+ *    its contributors may be used to endorse or promote products derived+ *    from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * --/COPYRIGHT--*/++//******************************************************************************+//   BQ76952EVM demo code for MSP430FR2x55 + BQ769x2+//+//   Description: MSP430FR2x55 functions as the I2C host that communicates+//   with the BQ769x2 sending and receiving different types of commands.+//   ACLK = 32.768kHz REFO or external XT1, MCLK = SMCLK = 1MHz DCO+//+//                                     /|\ /|\+//                    MSP430FR2x55     10k  |+//                 -----------------    |  10k+//            /|\ |             P4.5|---+---|-- I2C Data (UCB1SDA)+//             |  |                 |       |+//             ---|RST          P4.4|-------+-- I2C Clock (UCB1SCL)+//                |                 |+//                |             P2.3|---> SHUT+//                |                 |+//                |             P4.2|---> UART RX+//                |                 |+//       LEDs <---|P8.0 -8.2       P4.3|<--- UART TX+//                |                 |+//+//+//   Andrew Han and Matt Sunna+//   Texas Instruments Inc.+//   August 2021+//   Built with Code Composer Studio (CCS) v10.1.1+//******************************************************************************++//------------------------------------------------------------------------------+// Includes+//------------------------------------------------------------------------------+#include <assert.h>+#include <msp430.h>+#include <stdbool.h>+#include <stdint.h>+#include <stdio.h>++#include "BQ769x2Header.h"++//------------------------------------------------------------------------------+// Defines / macros+//------------------------------------------------------------------------------++// USER CONFIG HERE+#define NUM_CELLS 3+#define NUM_CELLS_BITS 0x0007 // bit 0 for cell 0, bit 3 for cell 3, etc. Write 1 to enable, write 0 to disable+++// other +#define DEV_ADDR 0x08 // BQ769x2 7-bit I2C address+#define CRC_Mode 0    // 0 = disabled, 1 = enabled++#define MAX_BUFFER_SIZE 10+#define R 0  // Read+#define W 1  // Write+#define W2 2 // Write data with two bytes++// Porting macros for F5529: match FR-style USCI flags+#define USCI_I2C_UCRXIFG0 USCI_I2C_UCRXIFG+#define USCI_I2C_UCTXIFG0 USCI_I2C_UCTXIFG++// These extra FIFO levels don't exist on F5529; they will never be hit+#define USCI_I2C_UCRXIFG1 0x12+#define USCI_I2C_UCRXIFG2 0x14+#define USCI_I2C_UCRXIFG3 0x16+#define USCI_I2C_UCTXIFG1 0x18+#define USCI_I2C_UCTXIFG2 0x1A+#define USCI_I2C_UCTXIFG3 0x1C++// Upper bound for __even_in_range+#define USCI_I2C_UCBIT9IFG USCI_I2C_UCTXIFG++//------------------------------------------------------------------------------+// Types+//------------------------------------------------------------------------------+typedef enum I2C_ModeEnum+{+    IDLE_MODE,+    NACK_MODE,+    TX_REG_ADDRESS_MODE,+    RX_REG_ADDRESS_MODE,+    TX_DATA_MODE,+    RX_DATA_MODE,+    SWITCH_TO_RX_MODE,+    SWITHC_TO_TX_MODE,+    TIMEOUT_MODE+} I2C_Mode;++typedef enum+{+    OUTPUT_HUMAN = 0,+    OUTPUT_JSON = 1+} OutputMode;++//------------------------------------------------------------------------------+// Globals+//------------------------------------------------------------------------------++// UART output mode++static OutputMode output_mode = OUTPUT_HUMAN; // default to human-readable output++// I2C state machine+I2C_Mode MasterMode = IDLE_MODE;+uint8_t TransmitRegAddr = 0;+uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};+uint8_t RXByteCtr = 0;+uint8_t ReceiveIndex = 0;+uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};+uint8_t TXByteCtr = 0;+uint8_t TransmitIndex = 0;++// RX / measurement buffers+uint8_t RX_data[2] = {0x00, 0x00};+uint8_t RX_32Byte[32] = {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};++uint16_t CellVoltage[16] = {+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};++float Temperature[3] = {0, 0, 0};+uint16_t Stack_Voltage = 0x00;+uint16_t Pack_Voltage = 0x00;+uint16_t LD_Voltage = 0x00;+uint16_t Pack_Current = 0x00;+uint16_t AlarmBits = 0x00;++uint8_t value_SafetyStatusA;+uint8_t value_SafetyStatusB;+uint8_t value_SafetyStatusC;+uint8_t value_PFStatusA;+uint8_t value_PFStatusB;+uint8_t value_PFStatusC;+uint8_t FET_Status;+uint16_t CB_ActiveCells;++uint8_t UV_Fault = 0;+uint8_t OV_Fault = 0;+uint8_t SCD_Fault = 0;+uint8_t OCD_Fault = 0;+uint8_t ProtectionsTriggered = 0;++uint8_t LD_ON = 0;+uint8_t DSG = 0;+uint8_t CHG = 0;+uint8_t PCHG = 0;+uint8_t PDSG = 0;++//------------------------------------------------------------------------------+// Function prototypes+//------------------------------------------------------------------------------++// Board / low-level+void GPIO_initPins(void);+void GPIO_configPins(void);+void LED_On(int32_t ledPin);+void LED_Off(int32_t ledPin);+void UART_Init(void);+void I2C_initModule(void);+void map_I2C_and_UART(void);++// Utility+void delayUS(uint16_t us);+int putchar(int c);+void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);+unsigned char Checksum(unsigned char *ptr, unsigned char len);++// I2C access+I2C_Mode I2C_ReadReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);+I2C_Mode I2C_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);++// BQ769x2 API+void BQ769x2_SetRegister(uint16_t reg_addr, uint32_t reg_data, uint8_t datalen);+void CommandSubcommands(uint16_t command);+void Subcommands(uint16_t command, uint16_t data, uint8_t type);+void DirectCommands(uint8_t command, uint16_t data, uint8_t type);+void BQ769x2_Init(void);++void BQ769x2_ReadFETStatus(void);+void BQ769x2_WriteFETStatus(bool DSG, bool CHG);+void update_fets_from_buttons(void);+void BQ769x2_ShutdownPin(void);+void BQ769x2_ReleaseShutdownPin(void);++uint16_t BQ769x2_ReadAlarmStatus(void);+void BQ769x2_ReadSafetyStatus(void);+void BQ769x2_ReadPFStatus(void);++uint16_t BQ769x2_ReadVoltage(uint8_t command);+void BQ769x2_ReadAllVoltages(void);+uint16_t BQ769x2_ReadCurrent(void);+float BQ769x2_ReadTemperature(uint8_t command);++// JSON/Hydrogen packets++void send_json_notification(const char *method,+                            const char *id,+                            const char *data_fmt, ...);++// --- 1. BMS output messages ---------------------------------------------------++void output_bms_config(const char *battery_type, int cell_count);+void output_bms_voltages(uint32_t v_mV, const uint16_t *CellVoltage, int cell_count);+void output_fet_status(bool chg, bool dsg);+void output_current_value(int16_t current_mA);++// --- output mode selection --------------------------------------------------++void set_output_mode(OutputMode mode)+{+    output_mode = mode; // set global output mode+}++//------------------------------------------------------------------------------+// main+//------------------------------------------------------------------------------+int main(void)+{+    // Stop watchdog timer+    WDTCTL = WDTPW | WDTHOLD;++    GPIO_initPins();+    map_I2C_and_UART();+    UART_Init();+    I2C_initModule();++    LED_On(0); // Popwer LED++    set_output_mode(OUTPUT_JSON);  // or OUTPUT_JSON++    CommandSubcommands(BQ769x2_RESET); // Reset the BQ769x2 registers+    delayUS(60000);++    BQ769x2_Init(); // Configure all BQ769x2 RAM settings+    delayUS(10000);++    BQ769x2_WriteFETStatus(0,1);+    CommandSubcommands(FET_ENABLE); // Enable CHG and DSG FETs+    delayUS(10000);++    CommandSubcommands(SLEEP_DISABLE); // Disable Sleep for full-speed measurements++    // Wait for FETs to close and measurements to settle+    delayUS(60000);+    delayUS(60000);+    delayUS(60000);+    delayUS(60000);++    delayUS(20000);+    delayUS(20000);+    delayUS(20000);++    LED_On(1);+    printf("hello world\n\r");+    output_bms_config("Li-ion", 3);+++    while (1)+    {+        static int i = 0; // Loop counter for periodic output ++        // Read alarm status and check for new measurements+        AlarmBits = BQ769x2_ReadAlarmStatus();++        if (AlarmBits & 0x80)+        {+            // FULLSCAN complete: new measurements available+            BQ769x2_ReadAllVoltages();+            Pack_Current = BQ769x2_ReadCurrent();+            Temperature[0] = BQ769x2_ReadTemperature(TS1Temperature);+            Temperature[1] = BQ769x2_ReadTemperature(TS3Temperature);++            // Clear the FULLSCAN bit+            DirectCommands(AlarmStatus, 0x0080, W);+        }++        if (AlarmBits & 0xC000)+        {+            // Safety Status bits present in AlarmStatus+            BQ769x2_ReadSafetyStatus();++            if (ProtectionsTriggered & 1)+            {+                P1OUT |= BIT0; // Turn on LED to indicate protection+            }++            // Clear Safety Status Alarm bits+            DirectCommands(AlarmStatus, 0xF800, W);+        }+        else+        {+            if (ProtectionsTriggered & 1)+            {+                BQ769x2_ReadSafetyStatus();+                if (!(ProtectionsTriggered & 1))+                {+                    P1OUT &= ~BIT0; // Turn off LED when protection clears+                    printf("PROTECT");+                }+            }+        }++        // Output for every 20 cycles+        if (i % 20 == 0){+            printf("Running\n\r");+            output_bms_voltages(Stack_Voltage, CellVoltage, NUM_CELLS);+            update_fets_from_buttons();+            BQ769x2_ReadFETStatus();+            output_fet_status(CHG, DSG);+            output_current_value((int16_t)BQ769x2_ReadCurrent());+        }++        // Output for every 100 cycles+        if (i > 100){+            output_bms_config("Li-ion", 3);+            BQ769x2_ReadSafetyStatus();+            if (UV_Fault || OV_Fault || SCD_Fault || OCD_Fault){+                printf("Fault detected\n\r");+                printf("UV: %d", UV_Fault);+                printf("OV: %d", OV_Fault);+                printf("SCD: %d", SCD_Fault);+                printf("OCD: %d", OCD_Fault);+            }       +            i = 0;     +        }++        i++;+        delayUS(20000); // repeat loop every ~20 ms+    }+}++//------------------------------------------------------------------------------+// UART Output helper functions+//------------------------------------------------------------------------------++// Low level formatting function+static void send_json_notification_data(const char *method, const char *id, const char *data_str)+{+    uint32_t timestamp = 5005;++    printf("{\"method\":\"%s\","+           "\"data\":{%s},"+           "\"timestamp\":%lu,"+           "\"source\":\"robot\","+           "\"type\":\"notification\","+           "\"id\":\"%s\","+           "\"agent\":\"robot\"}\n",+           method, data_str, (unsigned long)timestamp, id);+}++// For simple, fixed data payloads+static void send_json_notification_fmt(const char *method,+                                       const char *id,+                                       const char *data_fmt, ...)+{+    char data_buf[256];+    va_list args;+    va_start(args, data_fmt);+    vsnprintf(data_buf, sizeof(data_buf), data_fmt, args); // format into data_buf+    va_end(args);++    send_json_notification_data(method, id, data_buf);+}++// -----------------------------------------------------------------------------+// Public “user” functions (no JSON/quote escaping here)+// -----------------------------------------------------------------------------++// 1. BMS/config  --------------------------------------------------------------++void output_bms_config(const char *battery_type, int cell_count)+{+    const char* type = "battery_type";+    const char* count = "cell_count";+    if (output_mode == OUTPUT_HUMAN)+    {+        printf("BMS config:\n\r");+        printf("  %s: %s\n\r", type, battery_type);+        printf("  %s: %d\n\r", count, cell_count);+    }+    else+    {+        // all escaping handled inside send_json_notification_fmt()+        send_json_notification_fmt(+            "/BMS/config",+            "001",+            "\"%s\":\"%s\",\"%s\":%d",+            type, battery_type, count, cell_count);+    }+}++// 2. Pack + cell voltages  ----------------------------------------------------+// v_mV: pack voltage in millivolts+// CellVoltage[i]: per-cell voltage in millivolts++void output_bms_voltages(uint32_t v_mV, const uint16_t *CellVoltage, int cell_count)+{+    if (output_mode == OUTPUT_HUMAN)+    {+        printf("Pack voltage: %u.%03u V\n\r",+               v_mV / 1000, v_mV % 1000);++        for (int i = 0; i < cell_count; i++)+        {+            printf("    Battery %d voltage: %u.%03u V\n\r",+                   i + 1,+                   CellVoltage[i] / 1000,+                   CellVoltage[i] % 1000);+        }+    }+    else+    {+        // build dynamic JSON data body, then wrap with send_json_notification_data()+        char data_buf[256];+        int len = 0;++        // pack voltage+        len += snprintf(data_buf + len, sizeof(data_buf) - len,+                        "\"pack_voltage_V\":%u.%03u",+                        v_mV / 1000, v_mV % 1000);++        // cell voltages+        for (int i = 0; i < cell_count && len < (int)sizeof(data_buf); i++)+        {+            len += snprintf(data_buf + len, sizeof(data_buf) - len,+                            ",\"cell%d_voltage_V\":%u.%03u",+                            i + 1,+                            CellVoltage[i] / 1000,+                            CellVoltage[i] % 1000);+        }++        send_json_notification_data("/BMS/voltages",+                                    "002",+                                    data_buf);+    }+}++// Example function here+void output_fet_status(bool chg, bool dsg)+{+    const char* chgStatus = "CHG_Status";+    const char* dsgStatus = "DSG_Status";+    if (output_mode == OUTPUT_HUMAN)+    {+        printf("%s: %d  %s: %d \n\r", chgStatus, chg, dsgStatus, dsg);+    }+    else+    {+        // all escaping handled inside send_json_notification_fmt()+        send_json_notification_fmt(+            "/BMS/fet_status",+            "003",+            "\"%s\":%d,\"%s\":%d",+            chgStatus, chg, dsgStatus, dsg);+    }+}++void output_error_notifications(bool UV, bool OV, bool SCD, bool OCD)+{+    const char* UV_s = "Under_Voltage_Status";+    const char* OV_s = "Over_Voltage_Status";+    const char* SCD_s = "SCD_Status";+    const char* OCD_s = "OCD_Status";+    if (output_mode == OUTPUT_HUMAN)+    {+        printf("%s: %d  %s: %d  %s: %d  %s: %d \n\r", UV_s, UV, OV_s, OV, SCD_s, SCD, OCD_s, OCD);+    }+    else+    {+        // all escaping handled inside send_json_notification_fmt()+        send_json_notification_fmt(+            "/BMS/error_notifications",+            "004",+            "\"%s\":%d,\"%s\":%d,\"%s\":%d,\"%s\":%d",+            UV_s, UV, OV_s, OV, SCD_s, SCD, OCD_s, OCD);+    }+}++void output_current_value(int16_t current_mA)+{+    const char* current_s = "Current_mA";+    if (output_mode == OUTPUT_HUMAN)+    {+        printf("%s: %d \n\r", current_s, current_mA);+    }+    else+    {+        // all escaping handled inside send_json_notification_fmt()+        send_json_notification_fmt(+            "/BMS/current_measurement",+            "005",+            "\"%s\":%d",+            current_s, current_mA);+    }+}++++//------------------------------------------------------------------------------+// High-level BQ769x2 helpers+//------------------------------------------------------------------------------++void BQ769x2_Init(void)+{+    // Enter CONFIGUPDATE mode (Subcommand 0x0090)+    CommandSubcommands(SET_CFGUPDATE);++    // Power configuration+    BQ769x2_SetRegister(PowerConfig, 0x2D80, 2);++    // Enable REG0 pre-regulator+    BQ769x2_SetRegister(REG0Config, 0x01, 1);++    // Enable REG1 with 3.3 V output+    BQ769x2_SetRegister(REG12Config, 0x0D, 1);++    // DFETOFF pin controls both CHG and DSG FET+    BQ769x2_SetRegister(DFETOFFPinConfig, 0x42, 1);++    // ALERT pin configuration+    BQ769x2_SetRegister(ALERTPinConfig, 0x2A, 1);++    // TS1 measures cell temperature+    BQ769x2_SetRegister(TS1Config, 0x07, 1);++    // TS3 measures FET temperature+    BQ769x2_SetRegister(TS3Config, 0x0F, 1);++    // HDQ pin: no thermistor on EVM; set to 0+    BQ769x2_SetRegister(HDQPinConfig, 0x00, 1);++    // VCell Mode: enable 16 cells+    BQ769x2_SetRegister(VCellMode, NUM_CELLS_BITS, 2);++    // Enabled Protections A: SCD, OCD1, OCC, COV, CUV+    BQ769x2_SetRegister(EnabledProtectionsA, 0xBC, 1);++    // Enabled Protections B: all enabled+    BQ769x2_SetRegister(EnabledProtectionsB, 0xF7, 1);++    // Default Alarm Mask+    BQ769x2_SetRegister(DefaultAlarmMask, 0xF882, 2);++    // Cell balancing configuration+    BQ769x2_SetRegister(BalancingConfiguration, 0x03, 1);++    // CUV Threshold+    BQ769x2_SetRegister(CUVThreshold, 0x31, 1);++    // COV Threshold+    BQ769x2_SetRegister(COVThreshold, 0x55, 1);++    // OCC Threshold+    BQ769x2_SetRegister(OCCThreshold, 0x05, 1);++    // OCD1 Threshold+    BQ769x2_SetRegister(OCD1Threshold, 0x0A, 1);++    // SCD Threshold+    BQ769x2_SetRegister(SCDThreshold, 0x05, 1);++    // SCD Delay+    BQ769x2_SetRegister(SCDDelay, 0x03, 1);++    // SCDL latch limit+    BQ769x2_SetRegister(SCDLLatchLimit, 0x01, 1);++    // Exit CONFIGUPDATE mode+    CommandSubcommands(EXIT_CFGUPDATE);+}++uint16_t BQ769x2_ReadAlarmStatus(void)+{+    DirectCommands(AlarmStatus, 0x00, R);+    return (RX_data[1] * 256 + RX_data[0]);+}++void BQ769x2_ReadSafetyStatus(void)+{+    // Safety Status A+    DirectCommands(SafetyStatusA, 0x00, R);+    value_SafetyStatusA = (RX_data[1] * 256 + RX_data[0]);++    UV_Fault = ((0x4 & RX_data[0]) >> 2);+    OV_Fault = ((0x8 & RX_data[0]) >> 3);+    SCD_Fault = ((0x8 & RX_data[1]) >> 3);+    OCD_Fault = ((0x2 & RX_data[1]) >> 1);++    // Safety Status B+    DirectCommands(SafetyStatusB, 0x00, R);+    value_SafetyStatusB = (RX_data[1] * 256 + RX_data[0]);++    // Safety Status C+    DirectCommands(SafetyStatusC, 0x00, R);+    value_SafetyStatusC = (RX_data[1] * 256 + RX_data[0]);++    if ((value_SafetyStatusA + value_SafetyStatusB + value_SafetyStatusC) > 1)+    {+        ProtectionsTriggered = 1;+    }+    else+    {+        ProtectionsTriggered = 0;+    }+}++void BQ769x2_ReadPFStatus(void)+{+    DirectCommands(PFStatusA, 0x00, R);+    value_PFStatusA = (RX_data[1] * 256 + RX_data[0]);++    DirectCommands(PFStatusB, 0x00, R);+    value_PFStatusB = (RX_data[1] * 256 + RX_data[0]);++    DirectCommands(PFStatusC, 0x00, R);+    value_PFStatusC = (RX_data[1] * 256 + RX_data[0]);+}++void BQ769x2_ReadFETStatus(void)+{+    DirectCommands(FETStatus, 0x00, R);+    FET_Status = (RX_data[1] * 256 + RX_data[0]);++    DSG = ((0x4 & RX_data[0]) >> 2);+    CHG = (0x1 & RX_data[0]);+    PCHG = ((0x2 & RX_data[0]) >> 1);+    PDSG = ((0x8 & RX_data[0]) >> 3);+}++void BQ769x2_WriteFETStatus(bool DSG, bool CHG){+    uint8_t State = 0;++    // DSG control+    if (!DSG){+        State |= (1 << 0);  // set DSG_OFF bit = force off+    }++    // CHG control+    if (!CHG){+        State |= (1 << 2);  // set CHG_OFF bit = force off+    }++    Subcommands(FET_CONTROL, State, 1);   // or whatever your write call requires+}++void update_fets_from_buttons(void)+{+    bool dsg_enable = false;+    bool chg_enable = false;++    if (P3IN & BIT3) {+        dsg_enable = true;        // p3.3 high -> enable discharge+    }++    if (P3IN & BIT4) {+        chg_enable = true;        // p3.4 high -> enable charge+    }++    BQ769x2_WriteFETStatus(dsg_enable, chg_enable);   // apply fet control+}+++++void BQ769x2_ShutdownPin(void)+{+    P2OUT |= BIT3;+}++void BQ769x2_ReleaseShutdownPin(void)+{+    P2OUT &= ~BIT3;+}++uint16_t BQ769x2_ReadVoltage(uint8_t command)+{+    DirectCommands(command, 0x00, R);++    if (command >= Cell1Voltage && command <= Cell16Voltage)+    {+        // Cell 1–16: mV+        return (RX_data[1] * 256 + RX_data[0]);+    }+    else+    {+        // Stack / Pack / LD: 0.01 V units+        return 10 * (RX_data[1] * 256 + RX_data[0]);+    }+}++void BQ769x2_ReadAllVoltages(void)+{+    unsigned char x;+    int cellvoltageholder = Cell1Voltage;++    for (x = 0; x < 16; x++)+    {+        CellVoltage[x] = BQ769x2_ReadVoltage(cellvoltageholder);+        cellvoltageholder += 2;+    }++    Stack_Voltage = BQ769x2_ReadVoltage(StackVoltage);+    Pack_Voltage = BQ769x2_ReadVoltage(PACKPinVoltage);+    LD_Voltage = BQ769x2_ReadVoltage(LDPinVoltage);+}++uint16_t BQ769x2_ReadCurrent(void)+{+    DirectCommands(CC2Current, 0x00, R);+    return (RX_data[1] * 256 + RX_data[0]); // mA+}++float BQ769x2_ReadTemperature(uint8_t command)+{+    DirectCommands(command, 0x00, R);+    return (0.1f * (float)(RX_data[1] * 256 + RX_data[0])) - 273.15f;+}++//------------------------------------------------------------------------------+// Low-level BQ769x2 register / command helpers+//------------------------------------------------------------------------------++void BQ769x2_SetRegister(uint16_t reg_addr, uint32_t reg_data, uint8_t datalen)+{+    uint8_t TX_Buffer[2] = {0x00, 0x00};+    uint8_t TX_RegData[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};++    //TX_RegData in little endian format+    TX_RegData[0] = reg_addr & 0xff;+    TX_RegData[1] = (reg_addr >> 8) & 0xff;+    TX_RegData[2] = reg_data & 0xff; //1st byte of data++    switch(datalen)+    {+        case 1: //1 byte datalength+            I2C_WriteReg(0x3E, TX_RegData, 3);+            delayUS(2000);+            TX_Buffer[0] = Checksum(TX_RegData, 3);+            TX_Buffer[1] = 0x05; //combined length of register address and data+            I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length+            delayUS(2000);+            break;+        case 2: //2 byte datalength+            TX_RegData[3] = (reg_data >> 8) & 0xff;+            I2C_WriteReg(0x3E, TX_RegData, 4);+            delayUS(2000);+            TX_Buffer[0] = Checksum(TX_RegData, 4);+            TX_Buffer[1] = 0x06; //combined length of register address and data+            I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length+            delayUS(2000);+            break;+        case 4: //4 byte datalength, Only used for CCGain and Capacity Gain+            TX_RegData[3] = (reg_data >> 8) & 0xff;+            TX_RegData[4] = (reg_data >> 16) & 0xff;+            TX_RegData[5] = (reg_data >> 24) & 0xff;+            I2C_WriteReg(0x3E, TX_RegData, 6);+            delayUS(2000);+            TX_Buffer[0] = Checksum(TX_RegData, 6);+            TX_Buffer[1] = 0x08; //combined length of register address and data+            I2C_WriteReg(0x60, TX_Buffer, 2); // Write the checksum and length+            delayUS(2000);+            break;+    }+}++void CommandSubcommands(uint16_t command) //For Command only Subcommands+// See the TRM or the BQ76952 header file for a full list of Command-only subcommands+{   //For DEEPSLEEP/SHUTDOWN subcommand you will need to call this function twice consecutively++    uint8_t TX_Reg[2] = {0x00, 0x00};++    //TX_Reg in little endian format+    TX_Reg[0] = command & 0xff;+    TX_Reg[1] = (command >> 8) & 0xff;++    I2C_WriteReg(0x3E,TX_Reg,2);+    delayUS(2000);+}++void Subcommands(uint16_t command, uint16_t data, uint8_t type)+// See the TRM or the BQ76952 header file for a full list of Subcommands+{+    //security keys and Manu_data writes dont work with this function (reading these commands works)+    //max readback size is 32 bytes i.e. DASTATUS, CUV/COV snapshot+    uint8_t TX_Reg[4] = {0x00, 0x00, 0x00, 0x00};+    uint8_t TX_Buffer[2] = {0x00, 0x00};++    //TX_Reg in little endian format+    TX_Reg[0] = command & 0xff;+    TX_Reg[1] = (command >> 8) & 0xff;++    if (type == R) {//read+        I2C_WriteReg(0x3E,TX_Reg,2);+        delayUS(2000);+        I2C_ReadReg(0x40, RX_32Byte, 32); //RX_32Byte is a global variable+    }+    else if (type == W) {+        //FET_Control, REG12_Control+        TX_Reg[2] = data & 0xff;+        I2C_WriteReg(0x3E,TX_Reg,3);+        delayUS(1000);+        TX_Buffer[0] = Checksum(TX_Reg, 3);+        TX_Buffer[1] = 0x05; //combined length of registers address and data+        I2C_WriteReg(0x60, TX_Buffer, 2);+        delayUS(1000);+    }+    else if (type == W2){ //write data with 2 bytes+        //CB_Active_Cells, CB_SET_LVL+        TX_Reg[2] = data & 0xff;+        TX_Reg[3] = (data >> 8) & 0xff;+        I2C_WriteReg(0x3E,TX_Reg,4);+        delayUS(1000);+        TX_Buffer[0] = Checksum(TX_Reg, 4);+        TX_Buffer[1] = 0x06; //combined length of registers address and data+        I2C_WriteReg(0x60, TX_Buffer, 2);+        delayUS(1000);+    }+}++void DirectCommands(uint8_t command, uint16_t data, uint8_t type)+// See the TRM or the BQ76952 header file for a full list of Direct Commands+{   //type: R = read, W = write+    uint8_t TX_data[2] = {0x00, 0x00};++    //little endian format+    TX_data[0] = data & 0xff;+    TX_data[1] = (data >> 8) & 0xff;++    if (type == R) {//Read+        I2C_ReadReg(command, RX_data, 2); //RX_data is a global variable+        delayUS(2000);+    }+    if (type == W) {//write+    //Control_status, alarm_status, alarm_enable all 2 bytes long+        I2C_WriteReg(command,TX_data,2);+        delayUS(2000);+    }+}++//------------------------------------------------------------------------------+// Utility functions+//------------------------------------------------------------------------------++void delayUS(uint16_t us)+{+    uint16_t ms = us / 1000;+    for (uint16_t i = 0; i < ms; i++)+    {+        __delay_cycles(1000);+    }+}++int putchar(int c)+{+    while (!(UCA1IFG & UCTXIFG))+        ;+    UCA1TXBUF = (unsigned char)c;+    return c;+}++void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)+{+    for (uint8_t i = 0; i < count; i++)+    {+        dest[i] = source[i];+    }+}++unsigned char Checksum(unsigned char *ptr, unsigned char len)+{+    unsigned char checksum = 0;++    for (unsigned char i = 0; i < len; i++)+    {+        checksum += ptr[i];+    }++    checksum = 0xff & ~checksum;+    return checksum;+}++//------------------------------------------------------------------------------+// I2C register access+//------------------------------------------------------------------------------++I2C_Mode I2C_ReadReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)+{+    /* Initialize state machine */+    MasterMode = TX_REG_ADDRESS_MODE;+    TransmitRegAddr = reg_addr;+    RXByteCtr = count;+    TXByteCtr = 0;+    ReceiveIndex = 0;+    TransmitIndex = 0;++    /* Initialize device address and interrupts */+    UCB1I2CSA = DEV_ADDR;+    UCB1IFG &= ~(UCTXIFG + UCRXIFG);        // Clear any pending interrupts+    UCB1IE &= ~UCRXIE;                      // Disable RX interrupt+    UCB1IE |= UCTXIE;                       // Enable TX interrupt+    UCB1CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition+    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0 w/ interrupts+    //For debugger+    __no_operation();++    /* Copy over received data */+    CopyArray(ReceiveBuffer, reg_data, count);++    return MasterMode;+}++I2C_Mode I2C_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)+{+    /* Initialize state machine */+    MasterMode = TX_REG_ADDRESS_MODE;+    TransmitRegAddr = reg_addr;++    /* Copy register data to TransmitBuffer */+    CopyArray(reg_data, TransmitBuffer, count);++    TXByteCtr = count;+    RXByteCtr = 0;+    ReceiveIndex = 0;+    TransmitIndex = 0;++    /* Initialize device address and interrupts */+    UCB1I2CSA = DEV_ADDR;+    UCB1IFG &= ~(UCTXIFG + UCRXIFG);        // Clear any pending interrupts+    UCB1IE &= ~UCRXIE;                      // Disable RX interrupt+    UCB1IE |= UCTXIE;                       // Enable TX interrupt+    UCB1CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition+    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0 w/ interrupts+    //For debugger+    __no_operation();++    return MasterMode;+}++//------------------------------------------------------------------------------+// Board support: GPIO, I2C, UART, port mapping+//------------------------------------------------------------------------------++void LED_On(int32_t ledPin)+{+    assert(ledPin >= 0 && ledPin <= 2);+    P8OUT &= ~(1 << ledPin);+}++void LED_Off(int32_t ledPin)+{+    assert(ledPin >= 0 && ledPin <= 2);+    P8OUT |= (1 << ledPin);+}++void GPIO_initPins(void)+{+    P1OUT = 0x00;+    P2OUT = 0x00;+    P3OUT = 0x00;+    P4OUT = 0x0F;+    P5OUT = 0x00;+    P6OUT = 0x00;+    P8OUT = 0x00;++    P1DIR = 0xFF;+    P2DIR = 0xFF;+    P3DIR = 0xFF;+    P4DIR = 0x00;+    P5DIR = 0xFF;+    P6DIR = 0xFF;+    P8DIR = 0xFF;++    GPIO_configPins();+}++void GPIO_configPins(void)+{+    // P8.0 (LED1)+    P8OUT &= ~BIT0;                 // Set P8.0 to low+    P8DIR |= BIT0;                  // Set P8.0 to output direction++    // P8.1 (LED2)+    P8OUT |= BIT1;                  // Set P8.1 to high+    P8DIR |= BIT1;                  // Set P8.1 to output direction++    // P8.2 (LED3)+    P8OUT |= BIT2;                  // Set P8.2 to high+    P8DIR |= BIT2;                  // Set P8.2 to output direction++    P3DIR &= ~(BIT3 | BIT4);        // Set P4.3 and P4.4 to input+    P3REN |= (BIT3 | BIT4);         // Enable pull up/down resistor+    P3OUT &= ~(BIT3 | BIT4);        // Output low (pull down)+}++void map_I2C_and_UART(void)+{+    PMAPKEYID = PMAPKEY; // Unlock port mapping +    PMAPCTL |= PMAPRECFG;++    P4MAP4 = PM_UCB1SCL; // Set P4.4 as SCL+    P4MAP5 = PM_UCB1SDA; // Set P4.5 as SCL++    P4MAP2 = PM_UCA1RXD; // Set 4.2 as RXD+    P4MAP3 = PM_UCA1TXD; // Set 4.3 as TXD++    PMAPKEYID = 0;+}++void I2C_initModule(void)+{+    // --- Configure I2C pins for UCB1 on MSP430F5529 ---+    // P4.4 = UCB1SDA, P4.5 = UCB1SCL+    P4SEL |= BIT4 | BIT5;      // select peripheral function for P4.4/P4.5+    //P4SEL |= BIT6 | BIT7;      // select peripheral function for P4.6/P4.7++    // --- Configure USCI_B1 in I2C master mode ---+    UCB1CTL1 |= UCSWRST;       // hold USCI in reset++    // CTL0: sync, I2C, master+    UCB1CTL0 = UCMST       |   // master mode+               UCMODE_3    |   // I2C mode+               UCSYNC;         // synchronous mode++    // CTL1: SMCLK as source while still in reset+    UCB1CTL1 = UCSWRST | UCSSEL_2;   // UCSSEL_2 = SMCLK++    // Baud rate: BRCLK / (UCB1BR0+256*BR1)+    // For example: SMCLK = 16 MHz, BR=40 -> 400 kHz I2C+    // We are running now without FLL (1Mhz)+    UCB1BR0 = 10;+    UCB1BR1 = 0;++    // 7-bit slave address of BQ769x2 (0x08) – goes into UCB1I2CSA+    UCB1I2CSA = DEV_ADDR;++    // Release from reset and start operation+    UCB1CTL1 &= ~UCSWRST;++    // Enable NACK interrupt (optional – your ISR already handles NACK)+    UCB1IE |= UCNACKIE;+}++void UART_Init(void)+{+    P4SEL |= BIT2 | BIT3;+    P4DIR |= BIT3;+    P4DIR &= ~BIT2;++    UCA1CTL1 |= UCSWRST;+    UCA1CTL1 &= ~(UCSSEL_3);+    UCA1CTL0 = UCMODE_0;++    UCA1CTL1 |= UCSSEL_1; // ACLK+    UCA1BR0 = 0x03;+    UCA1BR1 = 0x00;+    UCA1MCTL = UCBRS_3 + UCBRF_0;++    UCA1CTL1 &= ~UCSWRST;+}++//------------------------------------------------------------------------------+// I2C ISR+//------------------------------------------------------------------------------+#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)+#pragma vector = USCI_B1_VECTOR+__interrupt void USCI_B1_ISR(void)+#elif defined(__GNUC__)+void __attribute__((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR(void)+#else+#error Compiler not supported!+#endif+{+    uint8_t rx_val = 0;++    switch (UCB1IV)+    {+    case USCI_NONE:+        break;++    case USCI_I2C_UCALIFG:+        break;++    case USCI_I2C_UCNACKIFG:+        break;++    case USCI_I2C_UCSTTIFG:+        break;++    case USCI_I2C_UCSTPIFG:+        break;++    case USCI_I2C_UCRXIFG3:+    case USCI_I2C_UCTXIFG3:+    case USCI_I2C_UCRXIFG2:+    case USCI_I2C_UCTXIFG2:+    case USCI_I2C_UCRXIFG1:+    case USCI_I2C_UCTXIFG1:+        break;++    case USCI_I2C_UCRXIFG0:+        rx_val = UCB1RXBUF;+        if (RXByteCtr)+        {+            ReceiveBuffer[ReceiveIndex++] = rx_val;+            RXByteCtr--;+        }++        if (RXByteCtr == 1)+        {+            UCB1CTLW0 |= UCTXSTP;+        }+        else if (RXByteCtr == 0)+        {+            UCB1IE &= ~UCRXIE;+            MasterMode = IDLE_MODE;+            __bic_SR_register_on_exit(CPUOFF);+        }+        break;++    case USCI_I2C_UCTXIFG0:+        switch (MasterMode)+        {+        case TX_REG_ADDRESS_MODE:+            UCB1TXBUF = TransmitRegAddr;+            if (RXByteCtr)+            {+                MasterMode = SWITCH_TO_RX_MODE;+            }+            else+            {+                MasterMode = TX_DATA_MODE;+            }+            break;++        case SWITCH_TO_RX_MODE:+            UCB1IE |= UCRXIE;+            UCB1IE &= ~UCTXIE;+            UCB1CTLW0 &= ~UCTR;+            MasterMode = RX_DATA_MODE;+            UCB1CTLW0 |= UCTXSTT;++            if (RXByteCtr == 1)+            {+                while (UCB1CTLW0 & UCTXSTT)+                    ;+                UCB1CTLW0 |= UCTXSTP;+            }+            break;++        case TX_DATA_MODE:+            if (TXByteCtr)+            {+                UCB1TXBUF = TransmitBuffer[TransmitIndex++];+                TXByteCtr--;+            }+            else+            {+                UCB1CTLW0 |= UCTXSTP;+                MasterMode = IDLE_MODE;+                UCB1IE &= ~UCTXIE;+                __bic_SR_register_on_exit(CPUOFF);+            }+            break;++        default:+            __no_operation();+            break;+        }+        break;++    default:+        break;+    }+}++#endif
SKILL.mdadded+8
@@ -0,0 +1,8 @@+---+name: modular-bms+description: When to invoke this skill (Claude reads this to decide). Replace me.+---++# Modular BMS++What this skill does and how to use it.
docs/HERO.mdadded+1
@@ -0,0 +1 @@+Put a 1200x630 `hero.png` in this folder. It is the billboard reused on the page header, the homepage, and the screensaver. Until it exists, `adom-wiki pkg lint` reports the hero as the one outstanding item.
docs/hero.pngadded
⋯ 1 unchanged line ⋯
install.shadded+7
@@ -0,0 +1,7 @@+#!/bin/sh+set -e++# Symlink your install targets back into the module dir so edits+# propagate and reinstalls do not clobber, e.g.:+#   ln -sfn "$PWD/bin/run" "$HOME/.local/bin/run"+echo "installed"
package.jsonadded+53
@@ -0,0 +1,53 @@+{+  "slug": "modular-bms",+  "title": "Modular BMS",+  "type": "component",+  "version": "1.0.0",+  "description": "Modular Battery Management System — a composable BMS built from Adom molecules. TI BQ76952 monitor/protector with MSP430 host firmware, supporting 18650 cylindrical and EVE LF105 prismatic cell carriers.",+  "tags": [+    "hardware",+    "bms",+    "battery",+    "bq76952",+    "msp430",+    "platformio",+    "18650",+    "lifepo4",+    "modular"+  ],+  "dependencies": {+    "adom/molecule-18650-battery": "^1.0.0",+    "adom/molecule-18650-jumper": "^1.0.0",+    "adom/molecule-eve-lf105-prismatic": "^1.0.0",+    "adom/molecule-bq76952-v2": "^1.0.0"+  },+  "discovery_triggers": [+    "modular bms",+    "battery management system",+    "bq76952",+    "18650 bms",+    "battery pack monitoring",+    "cell balancing",+    "charge discharge protection"+  ],+  "discovery_pitch": "A complete modular battery management system built from Adom molecules — BQ76952 monitor, MSP430 firmware, and swappable cell carriers for 18650 or prismatic cells.",+  "sample_prompts": [+    {+      "label": "Overview",+      "prompt": "Show me the Modular BMS project and its molecules"+    },+    {+      "label": "Firmware",+      "prompt": "How do I build and flash the Modular BMS firmware?"+    },+    {+      "label": "Configure",+      "prompt": "How do I configure the BQ76952 for a different cell count?"+    }+  ],+"hero": {+    "headline": "Modular BMS",+    "subhead": "Composable battery management system — BQ76952 + MSP430 with swappable 18650 and prismatic cell carriers.",+    "screenshot": "docs/hero.png"+  }+}
uninstall.shadded+5
@@ -0,0 +1,5 @@+#!/bin/sh+set -e++# Undo what install.sh did (remove the symlinks you created).+echo "uninstalled"