diff --git a/Cargo.lock b/Cargo.lock index 8aab69d..69e482e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "bitterly" -version = "0.4.0" +version = "0.5.1" dependencies = [ "paste", ] diff --git a/Cargo.toml b/Cargo.toml index 0dbca7a..02207fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitterly" -version = "0.4.0" +version = "0.5.1" edition = "2021" description = "Non-memory mapped bit manipulation library" repository = "https://github.com/BridgeSource/bitterly" diff --git a/examples/max14748.rs b/examples/max14748.rs index 2b84974..7469850 100644 --- a/examples/max14748.rs +++ b/examples/max14748.rs @@ -13,6 +13,7 @@ pub fn main() { peripheral!( Max14748, + u8, 0x0A, 54, [ diff --git a/examples/max17261.rs b/examples/max17261.rs index 3897f5c..03235ff 100644 --- a/examples/max17261.rs +++ b/examples/max17261.rs @@ -43,7 +43,8 @@ pub fn main() { peripheral!( Max17261, - 0x0A, + u8, + 0x36, 112, [ // 0x00 to 0x10 diff --git a/max17261.txt b/max17261.txt deleted file mode 100644 index 15f69ad..0000000 --- a/max17261.txt +++ /dev/null @@ -1,1545 +0,0 @@ -ModelGauge m5 Registers -Registers that relate to functionality of the ModelGauge m5 fuel gauge are located on pages 0h4h and are continued on pages Bh and Dh. See the ModelGauge m5 Algorithm section for -details of specific register operation. Table 10 shows the ModelGauge m5 memory map. - -Table 10. ModelGauge m5 Register Memory Map -PAGE/ -WORD - -00h - -10h - -20h - -30h - -40h - -B0h - -D0h - -0h - -Status - -FullCapRep - -TTF - -Reserved - -Reserved - -Status2 - -RSense / -UserMem3 - -1h - -VAlrtTh - -TTE - -DevName - -Reserved - -Reserved - -Power - -ScOcvLim - -2h - -TAlrtTh - -QRTable00 - -QRTable10 - -QRTable20 QRTable30 - -ID / -UserMem2 - -VGain - -3h - -SAlrtTh - -FullSocThr - -FullCapNom - -Reserved - -RGain - -AvgPower - -SOCHold - -4h - -AtRate - -RCell - -Reserved - -DieTemp - -Reserved - -IAlrtTh - -MaxPeakPower - -5h - -RepCap - -Reserved - -Reserved - -FullCap - -dQAcc - -TTFCfg - -SusPeakPower - -6h - -RepSOC - -AvgTA - -Reserved - -Reserved - -dPAcc - -CVMixCap - -PackResistance - -7h - -Age - -Cycles - -AIN - -Reserved - -Reserved - -CVHalfTime - -SysResistance - -8h - -Temp - -DesignCap - -LearnCfg - -RComp0 - -Reserved - -CGTempCo - -MinSysVoltage - -9h - -VCell - -AvgVCell - -FilterCfg - -TempCo - -ConvgCfg - -Curve - -MPPCurrent - -Ah - -Current - -MaxMinTemp - -RelaxCfg - -VEmpty - -VFRemCap - -HibCfg - -SPPCurrent - -Bh - -AvgCurrent - -MaxMinVolt - -MiscCfg - -Reserved - -Reserved - -Config2 - -ModelCfg - -Ch - -QResidual - -MaxMinCurr - -TGain - -Reserved - -Reserved - -VRipple - -AtQResidual - -Dh - -MixSOC - -Config - -TOff - -FStat - -QH - -RippleCfg - -AtTTE - -Eh - -AvSOC - -IChgTerm - -CGain - -Timer - -Reserved - -TimerH - -AtAvSOC - -Fh - -MixCap - -AvCap - -COff - -ShdnTimer - -Reserved - -Reserved - -AtAvCap - -Maxim Integrated - -Page 27 of 49 - - Figure 11. ModelGauge m5 algorithm registers. - -ModelGauge m5 Algorithm Battery Parameters -The following registers are inputs to the ModelGauge m5 algorithm and store characterization -information for the application cells as well as important application-specific specifications. They -are described only briefly here. Contact Maxim for information regarding cell characterization. -VEmpty Register (3Ah) -Initial Value: 0xA561 (3.3V / 3.88V) -The VEmpty register sets thresholds related to empty detection during operation. Table 11 -shows the register format. - -Table 11. VEmpty (3Ah) Format -D15 - -D14 - -D13 - -D12 - -D11 -VE - -D10 - -D9 - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -VR - -VE: Empty Voltage Target, during load. The fuel gauge provides capacity and percentage -relative to the empty voltage target, eventually declaring 0% at VE. A 10mV resolution gives a -range of 0 to 5.11V. This value is written to 3.3V after reset. -VR: Recovery Voltage. Sets the voltage level for clearing empty detection. Once the cell voltage -rises above this point, empty voltage detection is re-enabled. A 40mV resolution gives a range -or 0 to 5.08V. This value is written to 3.88V, which is recommended for most applications. - -Maxim Integrated - -Page 28 of 49 - - DesignCap Register (18h) -Register Type: Capacity -The DesignCap register holds the expected capacity of the cell. This value is used to determine -the age and health of the cell by comparing against the measured present cell capacity. -ModelCfg Register (DBh) -Register Type: Special -Initial value: 0x8400 -The ModelCFG register controls basic options of the EZ algorithm. Table 12 shows the register -format. - -Table 12. ModelCFG (DBh) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -Refresh - -0 - -R100 - -0 - -0 - -VChg - -0 - -0 - -D7 - -D6 - -D5 - -ModelID - -D4 - -D3 - -D2 - -D1 - -D0 - -Reserved - -Reserved - -0 - -0 - -Refresh: Set Refresh to 1 to command the model reload. After execution, the MAX1726x clears -Refresh to 0. -R100: If using 100kΩ NTC, set R100 = 1; if using 10kΩ NTC, set R100 = 0. -0: Bit must be written 0. Do not write 1. -ModelID: Choose from one of the following lithium models. For most batteries, use ModelID = 0. - -• - -ModelID = 0: Use for most lithium cobalt oxide variants (a large majority of lithium in the -marketplace). Supported by EZ without characterization. - -• - -ModelID = 2: Use for lithium NCR or NCA cells such as Panasonic®. Supported by EZ -without characterization. - -• - -ModelID = 6: Use for lithium iron phosphate (LiFePO4). For better performance, a -custom characterization is recommended in this case, instead of an EZ configuration. - -VChg: Set VChg to 1 for a charge voltage higher than 4.25V (4.3V–4.4V). Set VChg to 0 for a -4.2V charge voltage. -Reserved: Read-only bit. -IChgTerm Register (1Eh) -Register Type: Current -Initial Value: 0x0640 (250mA on 10mΩ) -The IChgTerm register allows the device to detect when a charge cycle of the cell has -completed. IChgTerm should be programmed to the exact charge termination current used in -the application. The device detects end of charge if all the following conditions are met: - -• -• -• - -VFSOC Register > FullSOCThr Register -AND IChgTerm x 0.125 < Current Register < IChgTerm x 1.25 -AND IChgTerm x 0.125 < AvgCurrent Register < IChgTerm x 1.25 - -See the End-of-Charge Detection section for more details. -Maxim Integrated - -Page 29 of 49 - - FullSOCThr Register (13h) -Register Type: Percentage -Initial Value: 95% -The FullSOCThr register gates detection of end-of-charge. VFSOC must be larger than the -FullSOCThr value before IChgTerm is compared to the AvgCurrent register value. The -recommended FullSOCThr register setting for most custom characterized applications is 95% -(default, 0x5F05). For EZ Performance applications the recommendation is 80% (0x5005). See -the IChgTerm register description and End-of-Charge Detection section for details. Table 13 -shows the register format. - -Table 13. FullSOCThr (13h) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -D7 - -FullSOCThr - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -1 - -0 - -1 - -OCVTable0 (80h) to OCVTable15 (8Fh) Registers -Register Type: Special -Cell characterization information used by the ModelGauge algorithm to determine capacity -versus operating conditions. This table comes from battery characterization data. -XTable0 (90h) to XTable15 (9Fh) Registers -Register Type: Special -Cell characterization information used by the ModelGauge algorithm to determine capacity -versus operating conditions. This table comes from battery characterization data. -QRTable00 (12h) to QRTable30 (42h) Registers -Register Type: Special -The QRTable00 to QRTable30 register locations contain characterization information regarding -cell capacity under different application conditions. -RComp0 Register (38h) -Register Type: Special -The RComp0 register holds characterization information critical to computing the open circuit -voltage of a cell under loaded conditions. -TempCo Register (39h) -Register Type: Special -The TempCo register holds temperature compensation information for the RComp0 register -value. - -Maxim Integrated - -Page 30 of 49 - - ModelGauge m5 Output Registers -The following registers are outputs from the ModelGauge m5 algorithm. -RepCap Register (05h) -Register Type: Capacity -RepCap or reported remaining capacity in mAh. This register is protected from making sudden -jumps during load changes. -AtAvCap Register (DFh) -Register Type: Capacity -The AtAvCap register holds the estimated remaining capacity of the cell based on the -theoretical load current value of the AtRate register. The value is stored in terms of µVh and -must be divided by the application sense-resistor value to determine the remaining capacity in -mAh. -RepSOC Register (06h) -Register Type: Percentage -RepSOC is the reported state-of-charge percentage output for use by the application GUI. -AtAvSOC Register (DEh) -Register Type: Percentage -The AtAvSOC register holds the theoretical SOC of the cell based on the theoretical load of the -AtRate register. The register value is stored as a percentage with a resolution of 1/256 % per -LSB. The high byte indicates 1% resolution. -FullCapRep Register (10h) -Register Type: Capacity -This register reports the full capacity that goes with RepCap, generally used for reporting to the -GUI. Most applications should only monitor FullCapRep, instead of FullCap or FullCapNom. A -new full-capacity value is calculated at the end of every charge cycle in the application. -FullCap Register (35h) -Register Type: Capacity -FullCap is the full discharge capacity compensated according to the present conditions. A new -full-capacity value is calculated continuously as application conditions change (temperature and -load). -FullCapNom Register (23h) -Register Type: Capacity -FullCap is the full discharge capacity compensated according to the present conditions. A new -full-capacity value is calculated continuously as application conditions change (temperature and -load). - -Maxim Integrated - -Page 31 of 49 - - TTE Register (11h) -Register Type: Time -The TTE register holds the estimated time to empty for the application under present -temperature and load conditions. The TTE value is determined by relating AvCap with -AvgCurrent. -The corresponding AvgCurrent filtering gives a delay in TTE, but provides more stable results. -AtTTE Register (DDh) -Register Type: Time -The AtTTE register can be used to estimate time to empty for any theoretical load entered into -the AtRate register. -TTF Register (20h) -Register Type: Time -The TTF register holds the estimated time to full for the application under present conditions. -The TTF value is determined by learning the constant current and constant voltage portions of -the charge cycle based on experience of prior charge cycles. Time to full is then estimated by -comparing present charge current to the charge termination current. Operation of the TTF -register assumes all charge profiles are consistent in the application. -Cycles Register (17h) -Register Type: Special -The Cycles register maintains a total count of the number of charge/discharge cycles of the cell -that have occurred. The result is stored as a percentage of a full cycle. For example, a full -charge/discharge cycle results in the Cycles register incrementing by 100%. -The Cycles register accumulates fractional or whole cycles. For example, if a battery cycles -10% x 10 times, then it tracks 100% of a cycle. -The Cycles register has a full range of 0 to 655.35 cycles with a 1% LSb. -Status Register (00h) -Register Type: Special -Initial Value: 0x0002 (change to 0x8082 immediately after POR) -The Status register maintains all flags related to alert thresholds and battery insertion or -removal. Table 14 shows the Status register format. - -Table 14. Status (00h) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -Br - -Smx - -Tmx - -Vmx - -Bi - -Smn - -Tmn - -Vmn - -dSOCi - -Imx - -X - -X - -Bst - -Imn - -POR - -X - -POR (Power-On Reset): This bit is set to 1 when the device detects that a software or -hardware POR event has occurred. This bit must be cleared by system software to detect the -next POR event. POR is set to 1 at power-up. -Maxim Integrated - -Page 32 of 49 - - Imn and Imx (Minimum/Maximum Current Alert Threshold Exceeded): These bits are set to -a 1 whenever a Current register reading is below (Imn) or above (Imx) the IAlrtTh thresholds. -These bits may or may not need to be cleared by system software to detect the next event. See -the Config.IS bit description. Imn and Imx are cleared to 0 at power-up. -Vmn and Vmx (Minimum/Maximum Voltage Alert Threshold Exceeded): These bits are set -to a 1 whenever a VCell register reading is below (Vmn) or above (Vmx) the VAlrtTh thresholds. -These bits may or may not need to be cleared by system software to detect the next event. See -the Config.VS bit description. Vmn and Vmx are cleared to 0 at power-up. -Tmn and Tmx (Minimum/Maximum Temperature Alert Threshold Exceeded): These bits -are set to a 1 whenever a Temperature register reading is below (Tmn) or above (Tmx) the -TAlrtTh thresholds. These bits may or may not need to be cleared by system software to detect -the next event. See the Config.TS bit description. Tmn and Tmx are cleared to 0 at power-up. -Smn and Smx (Minimum/Maximum SOC Alert Threshold Exceeded): These bits set to 1 -when the SOC is below (Smn) or above (Smx) the SAlrtTh thresholds. These bits might or might -not need to be cleared by system software to detect the next event. See the Config.SS -description. Smn and Smx are cleared to 0 at power-up. -Bst (Battery Status): This bit is useful when the IC is used in a host-side application. This bit is -set to 0 when a battery is present in the system and set to 1 when the battery is absent. Bst is -set to 0 at power-up. -dSOCi (State of Charge 1% Change Alert): This bit is set to 1 when the RepSOC register -crosses an integer percentage boundary such as 50.0%, 51.0%, etc. The bit must be cleared by -host software. dSOCi is set to 1 at power-up. -Bi (Battery Insertion): This bit is useful when the IC is used in a host-side application. This bit -is set to 1 when the device detects that a battery has been inserted into the system by -monitoring the TH pin. This bit must be cleared by system software to detect the next insertion -event. Bi is set to 0 at power-up. -Br (Battery Removal): This bit is useful when the IC is used in a host-side application. Br is set -to 1 when the system detects that a battery has been removed from the system. This bit must -be cleared by system software to detect the next removal event. Br is set to 1 at power-up. -X (Don’t Care): This bit is undefined and can be logic 0 or 1. -Age Register (07h) -Register Type: Percentage -The Age register contains a calculated percentage value of the application’s present cell -capacity compared to its original design capacity. The result can be used by the host to gauge -the battery pack health as compared to a new pack of the same type. The equation for the -register output is: -Age Register (%) = 100% x (FullCapRep Register / DesignCap Register) -For example, if DesignCap = 2000mAh and FullCapRep = 1800mAh, then Age = 90% (or -0x5A00) -TimerH (BEh) and Timer (3Eh) Register -Register Type: Special -Initial Value: 0x0000 - -Maxim Integrated - -Page 33 of 49 - - TimerH and Timer provide a long-duration time count since the last POR. A 3.2-hour LSb gives -a full-scale range for the register of up to 23.94 years. The Timer register LSb is 175.8ms, giving -a full-scale range of 0 to 3.2 hours. TimerH and Timer can be interpreted together as a 32-bit -timer. -RCell Register (14h) -Register Type: Resistance -Initial Value: 0x0290 (160mΩ) -The RCell register provides the calculated internal resistance of the cell. RCell is determined by -comparing open-circuit voltage (VFOCV) against measured voltage (VCell) over a long time -period while under load or charge current. -VRipple Register (BCh) -Register Type: Special -Initial Value: 0x0000 -The VRipple register holds the slow average RMS ripple value of VCell register reading -variation compared to the AvgVCell register. The default filter time is 22.5 seconds. See the -RippleCfg register description. VRipple has an LSb weight of 1.25mV/128. - -ModelGauge m5 Algorithm Configuration Registers -The following registers allow operation of the ModelGauge m5 algorithm to be adjusted for the -application. It is recommended that the default values for these registers be used. -AtRate Register (04h) -Register Type: Current -Host software should write the AtRate register with a negative two’s complement 16-bit value of -a theoretical load current prior to reading any of the at-rate output registers (AtTTE, AtAvSOC, -AtAvCap). -FilterCfg Register (29h) -Register Type: Special -Initial Value: 0xCEA4 -The FilterCfg register sets the average time period for all ADC readings, for mixing OCV results -and coulomb-count results. It is recommended that these values are not changed unless -absolutely required by the application. Table 15 shows the FilterCfg register format. - -Table 15. FilterCfg (29h) Format -D15 - -D14 - -1 - -1 - -D13 - -D12 - -TEMP - -D11 - -D10 - -D9 - -D8 - -MIX - -D7 - -D6 - -D5 -VOLT - -D4 - -D3 - -D2 - -D1 - -D0 - -CURR - -CURR: Sets the time constant for the AvgCurrent register. The default POR value of 0100b -gives a time constant of 5.625s. The equation setting the period is: -AvgCurrent time constant = 45s × 2(CURR-7) - -Maxim Integrated - -Page 34 of 49 - - VOLT: Sets the time constant for the AvgVCell register. The default POR value of 010b gives a -time constant of 45.0s. The equation setting the period is: -AvgVCell time constant = 45s × 2(VOLT-2) -MIX: Sets the time constant for the mixing algorithm. The default POR value of 1101b gives a -time constant of 12.8 hours. The equation setting the period is: -Mixing Period = 45s × 2(MIX-3) -TEMP: Sets the time constant for the AvgTA register. The default POR value of 0001b gives a -time constant of 1.5min. The equation setting the period is: -AvgTA time constant = 45s × 2TEMP -1: Write these bits to 1. Do not write 0. -RelaxCfg Register (2Ah) -Register Type: Special -Initial Value: 0x2039 -The RelaxCfg register defines how the IC detects whether the cell is in a relaxed state with a -low dV/dt. Figure 12 describes relaxation detection. If AvgCurrent remains below the LOAD -threshold while AvgVCell changes less than the dV threshold over two consecutive periods of -dt, the cell is considered relaxed. Table 16 shows the RelaxCfg register format. - -Table 16. RelaxCfg (2Ah) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -LOAD - -D9 - -D8 - -D7 - -D6 -dV - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -dt - -LOAD: Sets the threshold, which the AvgCurrent and Current registers are compared against. -The AvgCurrent and Current registers must remain below this threshold value for the cell to be -considered unloaded. Load is an unsigned 7-bit value, where 1 LSb = 50μV (5mA on 10mΩ). -The default value is 800μV (80mA on 10mΩ). -dV: Sets the change threshold, which AvgVCell is compared against. If the cell voltage changes -by less than dV over two consecutive periods set by dt, the cell is considered relaxed; dV has a -range of 0 to 40mV where 1 LSb = 1.25mV. The default value is 3.75mV. -dt: Sets the time period over which the change in AvgVCell is compared against dV. If the cell -voltage changes by less than dV over two consecutive periods set by dt, the cell is considered -relaxed. The default value is 1.5 minutes. The comparison period is calculated as: -Relaxation Period = 2(dt - 8) × 45s - -Maxim Integrated - -Page 35 of 49 - - Figure 12. Cell relaxation detection. -LearnCfg Register (28h) -Register Type: Special -Initial Value: 0x4486 -The LearnCfg register controls all functions relating to adaptation during operation. Table 17 -shows the register format. - -Table 17. LearnCfg (28h) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -D7 - -0 - -1 - -0 - -0 - -0 - -1 - -0 - -0 - -1 - -D6 - -D5 -LS - -D4 - -D3 - -D2 - -D1 - -D0 - -0 - -1 - -1 - -0 - -0: Bit must be written 0. Do not write 1. -1: Bit must be written 1. Do not write 0. -LS: Learn Stage. The Learn Stage value controls the influence of the voltage fuel gauge on the -mixing algorithm. Learn Stage defaults to 0h, making the voltage fuel gauge dominate. Learn -Stage then advances to 7h over the course of two full cell cycles to make the coulomb counter -dominate. Host software can write the Learn Stage value to 7h to advance to the final stage at -any time. Writing any value between 1h and 6h is ignored. -MiscCfg Register (2Bh) -Register Type: Special -Initial Value: 0x3870 -The MiscCfg control register enables various other functions of the device. The MiscCfg register -default values should not be changed unless specifically required by the application. Table 18 -shows the register format. -Maxim Integrated - -Page 36 of 49 - - Table 18. MiscCfg (2Bh) Format -D15 - -D14 - -D13 - -D12 - -FUS - -D11 - -D10 - -1 - -0 - -D9 - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -1 - -0 - -0 - -SACFG - -MR - -D0 - -0: Bit must be written 0. Do not write 1. -1: Bit must be written 1. Do not write 0. -SACFG: SOC Alert Config. SOC Alerts can be generated by monitoring any of the SOC -registers as follows. SACFG defaults to 0b00 at power-up: - -• -• -• -• - -00: SOC Alerts are generated based on the RepSOC register. -01: SOC Alerts are generated based on the AvSOC register. -10: SOC Alerts are generated based on the MixSOC register. -11: SOC Alerts are generated based on the VFSOC register. - -MR: Mixing Rate. This value sets the strength of the servo mixing rate after the final mixing -state has been reached (> 2.08 complete cycles). The units are MR0 = 6.25μV, giving a range -up to 19.375mA with a standard 10mΩ sense resistor. Setting this value to 00000b disables -servo mixing and the MAX1726x continues with time-constant mixing indefinitely. The default -setting is 18.75μV or 1.875mA with a standard sense resistor. -FUS: Full Update Slope. This value prevents jumps in the RepSOC and FullCapRep registers -by setting the rate of adjustment of FullCapRep near the end of a charge cycle. The update -slope adjustment range is from 2% per 15 minutes (0000b) to a maximum of 32% per 15 -minutes (1111b). -ConvgCfg Register (49h) -Register Type: Special -The ConvgCfg register configures operation of the converge-to-empty feature. The default and -recommended value for ConvgCfg is 0x2241. -RippleCfg Register (BDh) -Register Type: Special -The RippleCfg register configures ripple measurement and ripple compensation. The default -and recommended value for this register is 0x0204. Table 19 shows the register format. - -Table 19. RippleCfg (BDh) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -kDV - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -NR - -NR: Ripple Measurement Filter. Sets the filter magnitude for ripple observation as defined by -the following equation giving a range of 1.4 seconds to 180 seconds. -Ripple Time Range = 1.4 seconds × 2NR -kDV: Ripple Empty Compensation Coefficient. Configures MAX1726x to compensate the fuel -gauge % according to the ripple. - -Maxim Integrated - -Page 37 of 49 - - ModelGauge m5 Algorithm Additional Registers -The following registers contain intermediate ModelGauge m5 data that might be useful for -debugging or performance analysis. The values in these registers initially update within 710ms -after the IC is reset. -dQAcc Register (45h) -Register Type: Capacity -This register tracks change in battery charge between relaxation points. It is available to the -user for debug purposes. -dPAcc Register (46h) -Register Type: Percentage (1/16% per LSB) -Initial Value: 0x0190 (25%) -This register tracks change in battery SOC between relaxation points. It is available to the user -for debug purposes. -QResidual Register (0Ch) -Register Type: Capacity -The QResidual register provides the calculated amount of charge in mAh that is currently inside -of, but cannot be removed from, the cell under present application conditions (load and -temperature). This value is subtracted from the MixCap value to determine capacity available to -the user under present conditions (AvCap). -AtQResidual Register (DCh) -Register Type: Capacity -The AtQResidual register provides the calculated amount of charge in mAh that is currently -inside of, but cannot be removed from, the cell under present temperature and hypothetical load -(AtRate). -This value is subtracted from the MixCap value to determine capacity available to the user -(AtAvCap). -VFSOC Register (FFh) -Register Type: Percentage -The VFSOC register holds the calculated present SOC of the battery according to the voltage -fuel gauge. -VFOCV Register (FBh) -Register Type: Voltage -The VFOCV register contains the calculated open-circuit voltage of the cell as determined by -the voltage fuel gauge. This value is used in other internal calculations. -QH Register (4Dh) -Register Type: Capacity -Initial Value: 0x0000 -Maxim Integrated - -Page 38 of 49 - - The QH register displays the raw coulomb count generated by the device. This register is used -internally as an input to the mixing algorithm. Monitoring changes in QH over time can be useful -for debugging device operation. -AvCap (1Fh) and AvSOC (0Eh) Registers -Register Type: Capacity (AvCap), Percentage (AvSOC) -The AvCap and AvSOC registers hold the calculated available capacity and percentage of the -battery based on all inputs from the ModelGauge m5 algorithm, including empty compensation. -These registers provide unfiltered results. Jumps in the reported values can be caused by -abrupt changes in load current or temperature. See the Empty Compensation section for details. -MixCap (0Fh) and MixSOC (0Dh) Registers -Register Type: Capacity (MixCap) and Percentage (MixSOC) -The MixCap and MixSOC registers hold the calculated remaining capacity and percentage of -the cell before any empty compensation adjustments are performed. -See the Empty Compensation section for details. -VFRemCap Register (4Ah) -Register Type: Capacity -The VFRemCap register holds the remaining capacity of the cell as determined by the voltage -fuel gauge before any empty compensation adjustments are performed. -See the Empty Compensation section for details. -FStat Register (3Dh) -Register Type: Special -The FStat register is a read-only register that monitors the status of the ModelGauge m5 -algorithm. Table 20 is the FStat register format. - -Table 20. FStat (3Dh) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -X - -X - -X - -X - -X - -X - -RelDt - -EDet - -FQ - -RelDt2 - -X - -X - -X - -X - -X - -DNR - -DNR: Data Not Ready. This bit is set to 1 at cell insertion and remains set until the output -registers have been updated. Afterward, the IC clears this bit, indicating the fuel gauge -calculations are up to date. This takes 710ms from power-up. -FQ: Full Qualified. This bit is set when all charge termination conditions have been met. See the -End-of-Charge Detection section for details. -EDet: Empty Detection. This bit is set to 1 when the IC detects that the cell empty point has -been reached. This bit is reset to 0 when the cell voltage rises above the recovery threshold. -See the VEmpty register for details. -RelDt: Relaxed Cell Detection. This bit is set to 1 when the ModelGauge m5 algorithm detects -that the cell is in a fully relaxed state. This bit is cleared to 0 when a current greater than the -Load threshold is detected. See Figure 12. - -Maxim Integrated - -Page 39 of 49 - - RelDt2: Long Relaxation. This bit is set to 1 when the ModelGauge m5 algorithm detects that -the cell has been relaxed for a period of 48 to 96 minutes or longer. This bit is cleared to 0 when -the cell is no longer in a relaxed state. See Figure 12. -X: Don’t Care. This bit is undefined and can be logic 0 or 1. - -Status and Configuration Registers -The following registers control IC operation not related to the fuel gauge such as power-saving -modes and ALRT pin functionality. -Config Register (1Dh) and Config2 Register (BBh) -Register Type: Special -See individual data sheet for details. -DevName Register (21h) -Register Type: Special -The DevName register holds device type and firmware revision information. This allows host -software to easily identify the type of IC being communicated to. - -Table 21. DevName Register Values for Different Variants of the -MAX1726x -PART - -ADDRESS - -FEATURE - -MAX17260 - -0x4031 - -Single-cell optional high-side sensing - -MAX17261 - -0x4033 - -Multi-cell fuel gauge - -MAX17262 - -0x4039 - -Internal current sensing - -MAX17263 - -0x4037 - -Single/multi-cell with integrated LED driver - -ShdnTimer Register (3Fh) -Register Type: Special -Initial Value: 0x0000 -The ShdnTimer register sets the time-out period from when a shutdown event is detected until -the device disables the regulators and enters low-power mode. Table 22 shows the ShdnTimer -register format. - -Table 22. ShdnTimer (3Fh) Format -D15 - -D14 - -D13 - -D12 - -D11 - -D10 - -D9 - -D8 - -D7 - -THR - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -CTR - -CTR: Shutdown Counter. This register counts the total amount of elapsed time since the -shutdown trigger event. This counter value stops and resets to 0 when the shutdown time-out -completes. The counter LSb is 1.4s. -THR: Sets the shutdown time-out period from a minimum of 45s to a maximum of 1.6h. The -default POR value of 0h gives a shutdown delay of 45s. The equation setting the period is: -Shutdown Time-Out Period = 175.8ms × 2(8+THR) -Maxim Integrated - -Page 40 of 49 - - Status2 Register (B0h) -Register Type: Special -Initial Value: 0x0000 -The Status2 register maintains status of various firmware functions. Table 23 shows the Status2 -register format. - -Table 23. Status2 (B0h) Format - -D15 D14 -X - -X - -D13 - -D12 - -AtRateReady - -DPReady - -D11 D10 - -D9 - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -D2 - -D1 - -D0 - -X - -X - -SNReady - -X - -X - -FullDet - -X - -X - -X - -Hib - -X - -X - -Hib: Hibernate Status. This bit is set to a 1 when the device is in hibernate mode or 0 when the -device is in active mode. Hib is set to 0 at power-up. -FullDet: Full Detected. -For the following 3 bits, see also the Serial Number Feature section for more details. -SNReady: If SNReady = 1, the unique serial number is available over the I2C. This bit is set to 1 -by firmware after the serial number is read internally and placed into RAM. Serial number -overwrites Dynamic Power and AtRate output registers as described in the Serial Number -Feature section. -AtRateReady: If AtRateReady = 1, AtRate output registers are filled by the firmware and ready -to be read by the host. -DPReady: If DPReady = 1, Dynamic Power output registers are filled by the firmware and ready -to be read by the host. -X: Don’t Care. This bit is undefined and can be logic 0 or 1. -HibCfg Register (BAh) -Register Type: Special -Initial Value: 0x870C -The HibCfg register controls hibernate mode functionality. The MAX1726x enters and exits -hibernate when the battery current is less than approximately C/100. While in hibernate mode, -the MAX1726x reduces its operating current to 5µA by reducing ADC sampling to once every -5.625s. Table 24 shows the register format. - -Table 24. HibCfg (BAh) Format -D15 -EnHib - -D14 - -D13 - -D12 - -HibEnterTime - -D11 - -D10 - -D9 - -HibThreshold - -D8 - -D7 - -D6 - -D5 - -D4 - -D3 - -0 - -0 - -0 - -HibExitTime - -D2 - -D1 - -D0 - -HibScalar - -0: Bit must be written 0. Do not write 1. -HibScalar: Sets the task period while in hibernate mode based on the following equation: - -Hibernate Mode Task Period -= -( s ) 351ms × 2 (HibScalar) - -Maxim Integrated - -Page 41 of 49 - - HibExitTime: Sets the required time period of consecutive current readings above the -HibThreshold value before the IC exits hibernate and returns to active mode of operation. - -Hibernate Mode Exit= -Time ( s ) - -(HibExitTime + 1) × 702ms × 2 (HibScalar) - -HibThreshold: Sets the threshold level for entering or exiting hibernate mode. The threshold is -calculated as a fraction of the full capacity of the cell using the following equation: - -Hibernate Mode Threshold (mA) = - -Full Cap (mAh)/0.8hrs -2(HibThreshold) - -HibEnterTime: Sets the time period that consecutive current readings must remain below the -HibThreshold value before the IC enters hibernate mode, as defined by the following equation. -The default HibEnterTime value of 000b causes the IC to enter hibernate mode if all current -readings are below the HibThreshold for a period of 5.625 seconds, but the IC could enter -hibernate mode as quickly as 2.812 seconds. - -2.812s × 2(HibEnterTime) < Hibernate Mode Entry Time < 2.812s × 2(HibEnterTime +1) -EnHib: Enable Hibernate Mode. When set to 1, the IC will enter hibernate mode if conditions -are met. When set to 0, the IC always remains in the active mode of operation. -Soft-Wakeup (Command Register 60h) -Register Type: Special -The Command register accepts commands to perform functions listed in the following table. -Command - -Mnemonic - -0000h - -Clear - -Clears all commands. - -Soft -wakeup - -Wakes up the fuel gauge from hibernate mode -to reduce the response time of the IC to -configuration changes. This command must be -manually cleared (0000h) afterward to keep -proper fuel gauge timing. - -0090h - -Description - -To wake and exit hibernate: -1. Write HibCfg = 0x0000. -2. Soft-Wakeup Command. Write Command Register (60h) to 0x0090. -3. Clear Command. Write Command Register (60h) to 0x0000. -4. Eventually restore HibCfg to again allow automatic hibernate decisions. - -Maxim Integrated - -Page 42 of 49 - - \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 4fedb8d..780cc56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,9 +25,9 @@ pub enum Errors { #[macro_export] macro_rules! register_backer { ($reg_name:ident, $reg_type:ty) => { - type RegisterType = $reg_type; + pub type RegisterType = $reg_type; - type RegisterBacker = $reg_name; + pub type RegisterBacker = $reg_name; #[derive(Copy, Clone)] pub struct $reg_name { @@ -142,7 +142,7 @@ macro_rules! register_backer { macro_rules! peripheral { //($enum_name:ident, $enum_type:ty, [$(($name:ident, $value:literal)),+]) => { - ($peripheral_name:ident, $i2c_addr:literal, $count:literal, [$(($register:ident, $addr:literal, $index:literal)),+]) => { + ($peripheral_name:ident, $address_type:ty, $i2c_addr:literal, $count:literal, [$(($register:ident, $addr:literal, $index:literal)),+]) => { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum RegisterAddress { $( @@ -159,24 +159,63 @@ macro_rules! peripheral { pub struct $peripheral_name { registers: [RegisterBacker; $count], + address_index: [$address_type; $count], i2c_addr: u16, } impl $peripheral_name { pub fn new() -> Self { + let mut address_index: [$address_type; $count] = [0; $count]; + + $( + address_index[$index as usize] = $addr as $address_type; + )+ + $peripheral_name { registers: [RegisterBacker { contents: 0 }; $count], + address_index, i2c_addr: $i2c_addr, } } - pub fn direct_update(&mut self, address: usize, val: RegisterType) -> &mut Self { - self.registers[address].update(val); + pub fn find_index_by_address(&self, address: usize) -> Option { + for i in 0..$count { + if self.address_index[i] == address as $address_type { + return Some(i); + } + } + + None + } + + pub fn direct_update_by_address(&mut self, address: usize, val: RegisterType) -> &mut Self { + let index = self.find_index_by_address(address); + match index { + Some(i) => { + self.registers[i].update(val); + }, + None => { + panic!("Address not found"); + } + } self } - pub fn direct_read(&self, address: usize) -> RegisterType { - self.registers[address].contents() + pub fn direct_read_by_address(&self, address: usize) -> RegisterType { + let index = self.find_index_by_address(address); + match index { + Some(i) => { + return self.registers[i].contents(); + }, + None => { + panic!("Address not found"); + } + } + } + + pub fn direct_update_by_index(&mut self, index: usize, val: RegisterType) -> &mut Self { + self.registers[index].update(val); + self } pub fn get_i2c_address(&self) -> u16 { @@ -258,12 +297,12 @@ macro_rules! register { macro_rules! bitfield { ($register:ident, $bitfield_name:ident, $bit:literal) => { paste! { - pub trait $bitfield_name { + pub trait [<$register _ $bitfield_name>]{ fn [](&self) -> bool; fn [](&mut self, value: bool) -> &mut Self; } - impl $bitfield_name for $register { + impl [<$register _ $bitfield_name>] for $register { fn [](&self) -> bool { unsafe { self.register.as_mut().unwrap().is_set($bit) @@ -324,12 +363,12 @@ macro_rules! bitrange_enum_values { macro_rules! bitrange { ($register:ident, $bitrange_name:ident, $msb:literal, $lsb:literal, $val_type:ty) => { paste! { - pub trait $bitrange_name { + pub trait [<$register _ $bitrange_name>] { fn [](&self) -> Option<$val_type>; fn [](&mut self, value: $val_type) -> &mut Self; } - impl $bitrange_name for $register { + impl [<$register _ $bitrange_name>] for $register { fn [](&self) -> Option<$val_type> { unsafe { let val = self.register.as_mut().unwrap().get_range(BitRange {stop_bit: $msb, start_bit: $lsb }); @@ -356,24 +395,22 @@ macro_rules! bitrange { macro_rules! bitrange_raw { ($register:ident, $bitrange_name:ident, $msb:literal, $lsb:literal, $val_type:ty) => { paste! { - pub trait $bitrange_name { + pub trait [<$register _ $bitrange_name>] { fn [](&self) -> $val_type; fn [](&mut self, value: $val_type) -> &mut Self; } - impl $bitrange_name for $register { + impl [<$register _ $bitrange_name>] for $register { fn [](&self) -> $val_type { unsafe { let value = (self.register.as_mut().unwrap().get_range(BitRange {stop_bit: $msb, start_bit: $lsb }) as $val_type); - value.wrapping_neg() + value } } fn [](&mut self, value: $val_type) -> &mut Self { unsafe { - // Wrapping neg is for 2's complement - // thanks: https://www.reddit.com/r/rust/comments/ekucxn/2s_complement/?utm_source=share&utm_medium=web2x&context=3 - let comp = (value as $val_type).wrapping_neg(); + let comp = (value as $val_type); self.register.as_mut().unwrap().set_range(BitRange { stop_bit: $msb, start_bit: $lsb }, comp as RegisterType); } @@ -422,9 +459,7 @@ macro_rules! bitrange_quantized { fn [](&self) -> f32 { unsafe { let value = (self.register.as_mut().unwrap().get_range(BitRange {stop_bit: $msb, start_bit: $lsb }) as $val_type); - // Wrapping neg is for 2's complement - // thanks: https://www.reddit.com/r/rust/comments/ekucxn/2s_complement/?utm_source=share&utm_medium=web2x&context=3 - (value.wrapping_neg() as f32) * $quantization as f32 + (value as f32) * $quantization as f32 } } @@ -432,9 +467,7 @@ macro_rules! bitrange_quantized { if value < $min as f32 || value > $max { None }else{ - // Wrapping neg is for 2's complement - // thanks: https://www.reddit.com/r/rust/comments/ekucxn/2s_complement/?utm_source=share&utm_medium=web2x&context=3 - let quant_val = ((value / $quantization as f32) as $val_type).wrapping_neg(); + let quant_val = ((value / $quantization as f32) as $val_type); unsafe { self.register.as_mut().unwrap().set_range(BitRange { stop_bit: $msb, start_bit: $lsb }, quant_val as RegisterType); } diff --git a/tests/bitterly.rs b/tests/bitterly.rs index 52448c0..1399f32 100644 --- a/tests/bitterly.rs +++ b/tests/bitterly.rs @@ -58,6 +58,7 @@ mod tests { peripheral!( Max14748, + u8, 0x0A, 5, [ @@ -92,6 +93,7 @@ mod tests { peripheral!( Max14748, + u8, 0x0A, 5, [ @@ -144,6 +146,7 @@ mod tests { peripheral!( Max14748, + u8, 0x0A, 5, [ @@ -169,6 +172,7 @@ mod tests { peripheral!( Max14748, + u8, 0x0A, 5, [ @@ -234,6 +238,7 @@ mod tests { peripheral!( Max17261, + u8, 0x36, 4, [ @@ -287,6 +292,16 @@ mod tests { i8_result = max17261.MaxMinTemp().set_MinTemp(128.0); assert!(i8_result.is_none()); + i8_result = max17261.MaxMinTemp().set_MaxTemp(128.0); + assert!(i8_result.is_none()); + + let msb = max17261.MaxMinTemp().set_MaxTemp(127.0).unwrap(); + let lsb = max17261.MaxMinTemp().set_MinTemp(-128.0).unwrap(); + + let reconstructed_value = u16::from_le_bytes([lsb as u8, msb as u8]); + let raw_register = max17261.MaxMinTemp().contents(); + assert_eq!(reconstructed_value, raw_register); + register!(I8TestRegister); bitrange_raw!(I8TestRegister, I8Upper, 15, 8, i8); bitrange_raw!(I8TestRegister, I8Lower, 7, 0, i8); @@ -324,8 +339,9 @@ mod tests { peripheral!( Max14748, + u8, 0x0A, - 8, + 9, [ (ChipId, 0x00, 0), (ChipRev, 0x01, 1),