%(qi-html-head)s
%(qi-html-body-top)sTo 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