<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://wiki.maemo.org/skins/common/feed.css?207"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.maemo.org/index.php?feed=atom&amp;target=121.44.222.14&amp;title=Special%3AContributions</id>
		<title>maemo.org wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.maemo.org/index.php?feed=atom&amp;target=121.44.222.14&amp;title=Special%3AContributions"/>
		<link rel="alternate" type="text/html" href="https://wiki.maemo.org/Special:Contributions/121.44.222.14"/>
		<updated>2026-04-14T05:29:52Z</updated>
		<subtitle>From maemo.org wiki</subtitle>
		<generator>MediaWiki 1.15.5-7</generator>

	<entry>
		<id>https://wiki.maemo.org/Mer/Documentation/BME_Protocol</id>
		<title>Mer/Documentation/BME Protocol</title>
		<link rel="alternate" type="text/html" href="https://wiki.maemo.org/Mer/Documentation/BME_Protocol"/>
				<updated>2009-06-12T09:13:54Z</updated>
		
		<summary type="html">&lt;p&gt;121.44.222.14:&amp;#32;/* Some BULK0 message (0x42, 0x00) */ tweak description of a field&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This documentation is entirely for the purpose of implementing software gathering battery information on Nokia Internet Tablets, not alteration of battery management state. &lt;br /&gt;
&lt;br /&gt;
Existing code:&lt;br /&gt;
* Dummy server: https://garage.maemo.org/plugins/scmsvn/viewcvs.php/dsme/trunk/adhoc/dummy_bme.c?revision=155&amp;amp;root=dsm&amp;amp;view=markup , released as LGPL 2.1.  (Bug: The server shouldn't send a status word before sending the response struct.)&lt;br /&gt;
* 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.)&lt;br /&gt;
&lt;br /&gt;
General protocol:&lt;br /&gt;
&lt;br /&gt;
* UNIX socket connection to /tmp/.bmesrv&lt;br /&gt;
* Client: send('BMentity')&lt;br /&gt;
* Server: send('\n')&lt;br /&gt;
&lt;br /&gt;
After handshake:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct {&lt;br /&gt;
    uint16      type, subtype;&lt;br /&gt;
} BMEHeader;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
types so far (NAME, (type, subtype)):&lt;br /&gt;
&lt;br /&gt;
== EM_BATTERY_INFO_REQ (0x06, 0x00) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct {&lt;br /&gt;
    BMEHeader header;&lt;br /&gt;
    u_int32_t flags;   // Set to 0xFFFFFFFF to get all data&lt;br /&gt;
} BME_EM_BATTERY_INFO_Req;&lt;br /&gt;
&lt;br /&gt;
struct emsg_battery_info_reply {&lt;br /&gt;
    uint32      a;&lt;br /&gt;
    uint32      flags;&lt;br /&gt;
    uint16      c;&lt;br /&gt;
    uint16      d;&lt;br /&gt;
    uint16      temp;   // Battery temperature measured in Kelvin &lt;br /&gt;
    uint16      f;&lt;br /&gt;
    uint16      g;&lt;br /&gt;
    uint16      h;&lt;br /&gt;
    uint16      i;&lt;br /&gt;
    uint16      j;&lt;br /&gt;
    uint16      k;&lt;br /&gt;
    uint16      l;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Some BULK0 message (0x42, 0x00) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct {&lt;br /&gt;
    BMEHeader header;&lt;br /&gt;
    u_int32_t flags;   // Set to 0xFFFFFFFF to get all data&lt;br /&gt;
} BME_EM_BULK_Req;&lt;br /&gt;
&lt;br /&gt;
struct emsg_bme_bulk_reply {&lt;br /&gt;
   uint32     unknown1;&lt;br /&gt;
   uint32     unknown2;&lt;br /&gt;
   uint32     unknown3;&lt;br /&gt;
   uint16     sw_status; // Battery monitor SW status&lt;br /&gt;
   uint16     instaneous_battery_voltage; // Instantaneous battery voltage (mV)&lt;br /&gt;
   uint16      // Remaining standby time to battery low (mins)&lt;br /&gt;
   uint16     unknown4;&lt;br /&gt;
   uint16     unknown5;&lt;br /&gt;
   uint16     unknown6;&lt;br /&gt;
   uint16     // Battery monitor check voltage (mV)&lt;br /&gt;
   uint16     // Battery low warning interval counter&lt;br /&gt;
   uint16     // Double median filtered battery voltage&lt;br /&gt;
   uint16     // Initial battery monitor voltage (mV)&lt;br /&gt;
   uint16     // Time per battery bar (mins)&lt;br /&gt;
   uint16     // DMF voltage sampled at first battery low (mV)&lt;br /&gt;
   uint32     // Average phone current (uA)&lt;br /&gt;
   uint16     // Most recent battery charge condition (mAh)&lt;br /&gt;
   uint16     // Lowest TX-Off voltage (mV)&lt;br /&gt;
   uint16     // Lowest TX-On voltage (mV)&lt;br /&gt;
   uint16     // Largest TX-Off/On voltage difference (mV)&lt;br /&gt;
   uint8      // Battery bar level log mask&lt;br /&gt;
   uint8      // Previous battery bar level&lt;br /&gt;
   uint8      // Battery low reason&lt;br /&gt;
   uint8      // CS state information &lt;br /&gt;
   uint16     // Number of battery bars&lt;br /&gt;
   uint16     // Battery type&lt;br /&gt;
   uint16     // Temperature, in kelvin&lt;br /&gt;
   uint16     // Battery capacity &lt;br /&gt;
   uint16     // Battery impedance (mOhm)&lt;br /&gt;
   uint16     // Present value of v_bat_full_level&lt;br /&gt;
   uint16     // Present value of v_bat_low_ths_mv&lt;br /&gt;
   uint16     unknown7;&lt;br /&gt;
   uint16     unknown8;&lt;br /&gt;
   uint16     unknown9;&lt;br /&gt;
   uint16     // Load current estimated by Batmon4 (uA)&lt;br /&gt;
   uint16     unknown10;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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: one function that gives values consistent with the set of values observed and that somewhat matches one set of observations of both fields (which unfortunately had a non-negligible delay between sampling the two) is mV = 2252.362 + 2.81361 * adc#8 (where the multiplier is fairly accurate, but the constant could be out by some multiple of 2.81361).  -- pjrm.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
== Some BULK1 message (0x43, 0x00) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct {&lt;br /&gt;
    BMEHeader header;&lt;br /&gt;
    u_int32_t flags;   // Set to 0xFFFFFFFF to get all data&lt;br /&gt;
} BME_EM_BULK1_Req;&lt;br /&gt;
&lt;br /&gt;
struct emsg_bme_bulk1_reply {&lt;br /&gt;
   uint32     unknown1;&lt;br /&gt;
   uint32     unknown2;&lt;br /&gt;
   uint32     unknown3;&lt;br /&gt;
   uint16     // Elapsed model time (min)&lt;br /&gt;
   uint16     // Tx-Off battery voltage (mV)&lt;br /&gt;
   uint16     // Tx-On battery voltage (mV)&lt;br /&gt;
   uint8      // Battery power state&lt;br /&gt;
   uint8      //  Batmon4 internal flags2&lt;br /&gt;
   uint8      // Batmon4 internal flags3&lt;br /&gt;
   uint8      // Charging method&lt;br /&gt;
   uint16     // Present Phi value (mV)&lt;br /&gt;
   uint16     // Present Delta Phi value (mV)&lt;br /&gt;
   uint8      // Charging mode &lt;br /&gt;
   uint8      // Previous charging mode &lt;br /&gt;
   uint8      // Charger type&lt;br /&gt;
   uint8      // Previous charger type&lt;br /&gt;
   uint16     // Instantaneous battery voltage (mV)&lt;br /&gt;
   uint8      // Number of charger checks (0-9) ?&lt;br /&gt;
   uint8      // Charger recognition state&lt;br /&gt;
   uint16     unknown4;&lt;br /&gt;
   uint16     // Instantaneous charger current (mA)&lt;br /&gt;
   uint16     unknown5;&lt;br /&gt;
   uint16     // Charging time (min)&lt;br /&gt;
   uint16     // Average Vchar (mV)&lt;br /&gt;
   uint16     // Equivalent DC charger current (mA) &lt;br /&gt;
   uint8      // Battery full flag (0 or 1)&lt;br /&gt;
   uint8      // HW Cha PWM value L ??&lt;br /&gt;
   uint8      // Cha PWM value L ??&lt;br /&gt;
   uint8      unknown6;&lt;br /&gt;
   uint16     // Open switch battery voltage (mV)&lt;br /&gt;
   uint16     // Closed switch battery voltage (mV)&lt;br /&gt;
   uint16     unknown7;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Some BULK2 message (0x44, 0x00) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
typedef struct {&lt;br /&gt;
    BMEHeader header;&lt;br /&gt;
    u_int32_t flags;   // Set to 0xFFFFFFFF to get all data&lt;br /&gt;
} BME_EM_BULK2_Req;&lt;br /&gt;
&lt;br /&gt;
struct emsg_bme_bulk2_reply {&lt;br /&gt;
   uint32     unknown1;&lt;br /&gt;
   uint32     unknown2;&lt;br /&gt;
   uint32     unknown3;&lt;br /&gt;
   uint16     // Conf. battery footprint&lt;br /&gt;
   uint16     // Conf. minimum standby current (mA)&lt;br /&gt;
   uint16     // Conf. Batmon battery low voltage (Safety level) &lt;br /&gt;
   uint16     // Conf. Batmon battery low voltage (Empty)&lt;br /&gt;
   uint16     // Configured number of battery bars&lt;br /&gt;
   uint16     unknown4;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Other information about battery life =&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
It's said that register 3 shows whether charging is occurring: with value 0 meaning &amp;quot;not being charged&amp;quot;, while &amp;quot;values 0xff and above&amp;quot; are an indication of the voltage being applied for charging.  Matan adds (http://talk.maemo.org/showpost.php?p=259465&amp;amp;postcount=43) that values around 0x100 indicate charging, while values around 0x170 indicate that the power source is connected but we aren't charging.&lt;br /&gt;
&lt;br /&gt;
Register 8 apparently indicates battery voltage.  See the note above about “instantaneous battery voltage (mV)” for how it might correspond to one measure of voltage.&lt;br /&gt;
&lt;br /&gt;
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 (or more generally charge used or remaining), 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.)&lt;br /&gt;
&lt;br /&gt;
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.  -- pjrm&lt;/div&gt;</summary>
		<author><name>121.44.222.14</name></author>	</entry>

	</feed>