Acer N30 battery controller emulation

Introduction

The Acer N30 PDA, displaying the battery percentage screen
Acer N30

Recently, I obtained three Acer N30 PDAs from Germany. The first attempt to mail them failed due to the inclusion of lithium batteries, so the seller kindly offered to take them out and resend, to which I agreed.

Little did I know that the batteries in this particular series contain an integrated controller...

Cable and flashing

Together with the PDAs, I ordered a pair of car charging adapters specifically for the proprietary 26-pin connector, since this seemed like the cheapest way to obtain it.

Nicely, the connectors contained all the pins and not just the power ones, so I was also able to prepare a USB cable and flash an English-language firmware instead of the original German one.

This very old flashing tool is suitable for the purpose and has been tested to run on a modern system: https://github.com/pinkavaj/romtools.

The UBI image extractable from the Windows Mobile update package is usable with the "dnw" utility from there.

The connector's pinout can be found here: https://allpinouts.org/pinouts/connectors/pda/acer-n30-n35-n310-n311-n50.

I attached a regular USB plug to the charging power, ground, and client D+/D- pins.

Note:

Inside of the particular connectors that I received was a weird arrangement with four overlapping rows of solder terminals, so double-checking and very careful inspection of where each pin actually goes has been essential.

Powering up

Even without a battery, the PDA starts up as soon as power is applied to the connector. However, the troubles began while I was attempting to apply a typical Li-Ion voltage to the battery terminals inside of the device in preparation for sticking a real battery there.

It booted, sure, but immediately reported that the main battery was supposedly very low and kept going to the sleep mode in an effort to save power (on WinCE devices of the era, the user data and configuration is stored in a RAM disk and is lost if the battery is fully discharged).

After some searching, I realized that this issue has been encountered by other owners attempting to replace the original battery, and the proposed solution was just to remove the controller board from a donor and attach a new cell to it.

I didn't give up and sought the service manual (for which I ended up paying a symbolic amount). It did contain a useful description of the system, yet the most important part of the diagram - discussing the battery controller - was blurry.

Inspecting the motherboard, I found a chip marked "AZX", which turned out to be the bq24025 charger from Texas Instruments. The diagram listed a MSP430F1111 microcontroller communicating with something vaguely discernible as bq**00 and appearing related to the battery.

An excerpt of the service manual
A part of the system diagram from the service manual, showing the battery controller.

I realized that said chip has no means of measuring the battery voltage, so something else had to be involved. I kept looking for other chips of the BQ series until I discovered the bq26500.

It is a small "gas gauge" chip for Li-Ion batteries, communicating via the HDQ protocol.

I was aware that the original battery uses a 4-pin connector, with three of those being power, ground, and the NTC thermistor connection for the charging chip, but there was a mysterious extra wire.

Could that wire be used for this? Indeed, it was.

After hooking up a logic analyzer to the extra wire, I immediately noticed constant activity.

This prompted me to start the effort described henceforth.

Emulating the battery controller

An excerpt from the TI document on the HDQ protocol of their battery controller chips
A basic description of the HDQ protocol from TI - SLUA408A

Guided by the datasheet of the bq26500, I quickly prepared a STM32F401RE Nucleo board as the prototype.

After powering up, the PDA constantly tries reading the register 0x7f, which can be used either as a configuration value or an arbitrary programmable ID byte.

If a response to this is seen, several interesting things are performed:

A logic analyzer trace of the HDQ communications
HDQ transfer: A read of register 0x0b, with the response 0x64 (100 decimal)

Setting a response to 0x0b reads, I was able to control the displayed battery percentage almost exactly, and the device no longer complained!

It also turned out that the software runs the returned percentage value through some sort of a non-linear function or a lookup table, possibly for better precision.

With that out of the way, the next question was charging, and the charger chip refused to produce an output voltage.

It actively measures the resistance at the NTC terminal by applying a specific current and comparing the resulting voltage against two thresholds.

Since this was not critical for charging and omitted by many devices nowadays, I simply soldered a 10k SMD resistor between the NTC pin and ground, keeping it satisfied.

CH32V003 implementation

I had plenty of the CH32V003, the famous 3-cent RISC-V microcontroller, and it seemed to be usable for the job.

Importantly, it features a deep sleep ("standby") mode, which would prevent excessive battery drain when idle, and the datasheet promises a full wakeup in about ~250μS.

This allows waking up on the start bit (the "Break signal" of the HDQ transmission) in time to receive the data word and respond.

For the actual battery gauging, I chose to measure the voltage, which is less accurate than the original sophisticated coulomb counting approach yet still very much usable.

The CH32V003 has an internal reference ADC channel fixed to 1.2V, so it is possible to measure Vcc (which is the full-scale voltage of the ADC) against that; I was inspired by a writeup that I saw much earlier: Hackaday.

I prepared another prototype (with the same functionality as the STM32 arrangement described above) on an evaluation board and finally flashed the MCU in a SOIC-8 package, soldering it down onto the motherboard and connecting its pins to the proper locations with enameled wire. A Nokia BL-5CT cell fit nicely into the case.

It let me charge the battery once and discharged correctly, however charging again was completely futile.

Now, upon applying external power, the charging got briefly activated and promptly shut down - what gives? I disassembled the PDA again.

It turned out that the charging process is being disabled by the software (by driving the CE pin of the charger high) after a series of HDQ accesses - but why? What didn't the driver like?

With trial and error, I realized that the zero values returned in 0x7e/0x7f were the culprit.

Returning another byte (I tried 0x55 and other values) immediately changed the access pattern, and now the PDA wanted to see register 0x0a as well. Somehow, I've seen this happen before but didn't realize that specific conditions were required…

A section of the bq26500 datasheet discussing register 0x0a
Register 0x0a, from the bq26500 datasheet

Bit 7 of 0x0a is the charging status, so returning 0x80 there should suffice. This has finally let me charge the device. Success!

Project details

The firmware, based on the ch32v003fun library, can be found in this repo.

Limitations

While charging, the battery voltage is higher, making the indication inaccurate. This is where the original coulomb counter shines; however, the PDA appears to rely on the charging chip to determine when the cycle really stops, so that at least should be indicated properly.

The voltage also fluctuates somewhat under load. There is no current measurement implemented to compensate for this, although this is possible in theory by using a shunt resistor in tandem with the MCU's built-in opamp and ADC.

Hardware

A connection diagram for the N30's motherboard
The relevant pins on the motherboard of the PDA
A CH32V003 microcontroller installed on the PDA's motherboard
CH32V003 mounted on the motherboard

I chose to locate the microcontroller directly on the motherboard of the PDA due to space constraints and not having the original proprietary thin 1.25mm battery connector. It was done rather crudely, but works. A decoupling capacitor across the power pins of the MCU certainly wouldn't hurt.

Home