%(qi-html-head)s %(qi-html-body-top)s

Anelok: keeping the time during battery swaps

Werner Almesberger werner at almesberger.net
Sun Mar 27 04:55:37 UTC 2016


To be able to support time-based protocols like TOTP [1], Anelok
needs to be able to provide reasonably accurate time. The sMCU
has a real-time clock driven by a 32.768 kHz "watch" crystal.

The problem is that this clock won't run without power, e.g.,
during a battery change. While battery changes should be relatively
infrequent, having to set the clock each time would be at least
inconvenient.

So far, the plan was to add some generously-sized silo capacitors
to keep the sMCU powered and thus the real-time clock running
during battery removal.


When discussing power distribution in Anelok on #qi-hardware, Joerg
suggested a rather different approach: instead of trying to keep
the clock running, why don't we just save the time across battery
swaps ?

The MCU has a low-voltage warning interrupt that can be set to
kick in well before the system voltage would be too low for the
MCU to keep running.


Now, what do we set the time to after coming back up again ? We
could just make an educated guess of how many seconds a typical
battery swap would take, but that may be a bit too inaccurate.

But what if we measure the time during which Anelok was off ?
Joerg suggested to use a capacitor that slowly discharges through
a resistor for this. When the sMCU comes up again, it can measure
the remaining voltage and calculate the downtime.


We then considered a few circuits:

http://downloads.qi-hardware.com/people/werner/anelok/tmp/time-backup-20160327.pdf

The first one uses two GPIOs and has only passive components. The
idea is that the capacitor is charged through ADC-R1 and CHARGE-R2,
then both GPIOs are "turned off" (High-Z) and the capacitor
discharges through R3.

The discharge time is chosen such that the capacitor voltage Vc1
should be around Vmin when we recharge again. During these cycles,
the MCU can also measure the actual performance of the capacitor,
and adjust the timing parameters, e.g., to compensate for
temperature effects.

The circuit is fairly simple, but it's not so nice that we have to
discharge all the time, thus leaking a few uA on average, and that
this needs fairly active charge management. We're also rather short
on GPIOs, so two is a lot.


On to the next page. This one is much simpler: we charge directly
from the 3.3 V rail. When the Vcc collapses and falls below Vc1,
we discharge.

No periodic recharging required, no leakage.

However, this circuit has some drawbacks. The biggest issue is that
its accuracy depends on our ability to correctly predict how Vcc
decays. E.g., if there are very different speeds at which it decays,
especially below 1.7 V, where the MCU no longer runs, then the time
measurement could be quite inaccurate. Likewise, if it doesn't fall
all the way to zero but stays for a long time at a higher voltage.


The next one has a small variation: we add a diode that prevents Vcc
from charging the capacitor, and puts charging exclusively under MCU
control. This way, the MCU could wait until we're sure that the user
has finished inserting the battery, and only then start charging
again.


The last circuit addresses the problem of uncertain Vcc decay
characteristics by always discharging towards ground (instead of the
possibly uncertain Vcc voltage).

The drawback, besides the cost of the FET, is that we can only
discharge until Vc1 reaches Vgs(th) + Vcc(residual), with Vgs(th)
being the voltage at which the FET stops/starts conducting, and
Vcc(residual) being whatever is left on Vcc after battery removal.


Some remarks regarding the component values: the overall idea is
that this RC timer should work for about one minute, with some
margin for error. The resistors on the GPIOs protect the charge in
the capacitor from glitches that may occur while Vcc is too low for
the MCU to operate.

The 680 kOhm resistor on ADC is a compromise between trying to make
it large, to provide better protection against glitches, and trying
to making it small, limit the effect leakage on the IO pin from has
on the measured voltage.

GPIO leakage is highly temperature-dependent, with a maximum of 25 nA
at 25 C but can go all the way up to 1 uA over the full temperature
range.


Opinions ?

- Werner

[1] https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm



More information about the discussion mailing list
%(qi-html-body-bottom)s