Mer/Documentation/BME Protocol
(Add some information about retu registers) |
(→Some BULK0 message (0x42, 0x00): Add information on "instantaneous battery voltage" field.) |
||
Line 92: | Line 92: | ||
}; | }; | ||
</pre> | </pre> | ||
+ | |||
+ | The “Instantaneous battery voltage (mV)” field’s observed values have a certain regular spacing indicating a linear function of some integer value with a smaller range, presumably retu adc register #8. If it is indeed from that register, then note there is a non-zero offset involved: from memory, one function that gives values consistent with the set of values observed and that somewhat matches observations of both fields (unfortunately with non-negligible delay between sampling the two so far) is mV = 2252.361 + 2.81361 * adc#8 (where the multiplier is fairly accurate if I've correctly remembered it, but the constant could be out by some multiple of 2.81361). -- pjrm. | ||
+ | |||
+ | The “Battery monitor check voltage (mV)” field has similar values to the “Instantaneous battery voltage (mV)” field, but without obvious regular spacing. I don't know how it's calculated. -- pjrm. | ||
== Some BULK1 message (0x43, 0x00) == | == Some BULK1 message (0x43, 0x00) == |
Revision as of 04:51, 12 June 2009
This documentation is entirely for the purpose of implementing software gathering battery information on Nokia Internet Tablets, not alteration of battery management state.
Existing code:
- Dummy server: https://garage.maemo.org/plugins/scmsvn/viewcvs.php/dsme/trunk/adhoc/dummy_bme.c?revision=155&root=dsm&view=markup , released as LGPL 2.1. (Bug: The server shouldn't send a status word before sending the response struct.)
- Simple command-line client written based on this web page: http://bowman.infotech.monash.edu.au/~pmoulder/bme-client.c . (GPLv2+, assuming that the text on this web page is compatible with that license.)
General protocol:
- UNIX socket connection to /tmp/.bmesrv
- Client: send('BMentity')
- Server: send('\n')
After handshake:
typedef struct { uint16 type, subtype; } BMEHeader;
types so far (NAME, (type, subtype)):
Contents |
EM_BATTERY_INFO_REQ (0x06, 0x00)
typedef struct { BMEHeader header; u_int32_t flags; // Set to 0xFFFFFFFF to get all data } BME_EM_BATTERY_INFO_Req; struct emsg_battery_info_reply { uint32 a; uint32 flags; uint16 c; uint16 d; uint16 temp; // Battery temperature measured in Kelvin uint16 f; uint16 g; uint16 h; uint16 i; uint16 j; uint16 k; uint16 l; };
Some BULK0 message (0x42, 0x00)
typedef struct { BMEHeader header; u_int32_t flags; // Set to 0xFFFFFFFF to get all data } BME_EM_BULK_Req; struct emsg_bme_bulk_reply { uint32 unknown1; uint32 unknown2; uint32 unknown3; uint16 sw_status; // Battery monitor SW status uint16 instaneous_battery_voltage; // Instantaneous battery voltage (mV) uint16 // Remaining standby time to battery low (mins) uint16 unknown4; uint16 unknown5; uint16 unknown6; uint16 // Battery monitor check voltage (mV) uint16 // Battery low warning interval counter uint16 // Double median filtered battery voltage uint16 // Initial battery monitor voltage (mV) uint16 // Time per battery bar (mins) uint16 // DMF voltage sampled at first battery low (mV) uint32 // Average phone current (uA) uint16 // Most recent battery charge condition (mAh) uint16 // Lowest TX-Off voltage (mV) uint16 // Lowest TX-On voltage (mV) uint16 // Largest TX-Off/On voltage difference (mV) uint8 // Battery bar level log mask uint8 // Previous battery bar level uint8 // Battery low reason uint8 // CS state information uint16 // Number of battery bars uint16 // Battery type uint16 // Temperature, in kelvin uint16 // Battery capacity uint16 // Battery impedance (mOhm) uint16 // Present value of v_bat_full_level uint16 // Present value of v_bat_low_ths_mv uint16 unknown7; uint16 unknown8; uint16 unknown9; uint16 // Load current estimated by Batmon4 (uA) uint16 unknown10; };
The “Instantaneous battery voltage (mV)” field’s observed values have a certain regular spacing indicating a linear function of some integer value with a smaller range, presumably retu adc register #8. If it is indeed from that register, then note there is a non-zero offset involved: from memory, one function that gives values consistent with the set of values observed and that somewhat matches observations of both fields (unfortunately with non-negligible delay between sampling the two so far) is mV = 2252.361 + 2.81361 * adc#8 (where the multiplier is fairly accurate if I've correctly remembered it, but the constant could be out by some multiple of 2.81361). -- pjrm.
The “Battery monitor check voltage (mV)” field has similar values to the “Instantaneous battery voltage (mV)” field, but without obvious regular spacing. I don't know how it's calculated. -- pjrm.
Some BULK1 message (0x43, 0x00)
typedef struct { BMEHeader header; u_int32_t flags; // Set to 0xFFFFFFFF to get all data } BME_EM_BULK1_Req; struct emsg_bme_bulk1_reply { uint32 unknown1; uint32 unknown2; uint32 unknown3; uint16 // Elapsed model time (min) uint16 // Tx-Off battery voltage (mV) uint16 // Tx-On battery voltage (mV) uint8 // Battery power state uint8 // Batmon4 internal flags2 uint8 // Batmon4 internal flags3 uint8 // Charging method uint16 // Present Phi value (mV) uint16 // Present Delta Phi value (mV) uint8 // Charging mode uint8 // Previous charging mode uint8 // Charger type uint8 // Previous charger type uint16 // Instantaneous battery voltage (mV) uint8 // Number of charger checks (0-9) ? uint8 // Charger recognition state uint16 unknown4; uint16 // Instantaneous charger current (mA) uint16 unknown5; uint16 // Charging time (min) uint16 // Average Vchar (mV) uint16 // Equivalent DC charger current (mA) uint8 // Battery full flag (0 or 1) uint8 // HW Cha PWM value L ?? uint8 // Cha PWM value L ?? uint8 unknown6; uint16 // Open switch battery voltage (mV) uint16 // Closed switch battery voltage (mV) uint16 unknown7; };
Some BULK2 message (0x44, 0x00)
typedef struct { BMEHeader header; u_int32_t flags; // Set to 0xFFFFFFFF to get all data } BME_EM_BULK2_Req; struct emsg_bme_bulk2_reply { uint32 unknown1; uint32 unknown2; uint32 unknown3; uint16 // Conf. battery footprint uint16 // Conf. minimum standby current (mA) uint16 // Conf. Batmon battery low voltage (Safety level) uint16 // Conf. Batmon battery low voltage (Empty) uint16 // Configured number of battery bars uint16 unknown4; };
Other information about battery life
Some battery-related information is also available from retu adc registers (which in turn are available via ioctl's on /dev/rutu: see retu-adc source).
It's said that register 3 shows whether charging is occurring: with value 0 meaning "not being charged", while "values 0xff and above" are an indication of the voltage being applied for charging.
Register 8 apparently indicates battery voltage. Note that this value can fluctuate a lot when the device is in use, but when idle it gets a good fit to the curve adc#8 = 438.3 + exp(p0 + p1*t) - exp(n0 + n1*t) where t is time, and p0,p1,n0,n1 are constants. (I forget the values I found for them, but in any case it would be good to fit for them again once more data is on hand.)
To invert this function to find idle time remaining (on assumption that the device was idle when the register was read), first see whether the adc#8 value is above or below 438.3, which tells you which exponential is dominant, and approximate the other exponential with a constant 3 (or a straight line if you like); can iterate and update this approximation for the neighbourhood of the solution found by the previous iteration.