FreeCalypso > hg > freecalypso-tools
view doc/Deep-sleep-support @ 1008:2b4c3e0f73fc
doc/High-speed-serial: update for current situation
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 10 Dec 2023 23:42:12 +0000 |
parents | 19cabe7c8e08 |
children |
line wrap: on
line source
All standard phones and modems based on the Calypso chipset from TI implement several different power saving modes, called sleep modes, and one of these sleep modes has a profound impact on the operation of the externally visible UART interfaces provided by the device. The power saving mode in question is called deep sleep, and the phone or modem can only enter this deep sleep mode when it is in the so-called idle state, meaning that it is camped on a cell and is ready to receive incoming calls, messages or GPRS packets - deep sleep cannot be entered while in an active call or in the middle of packet data transfer. When a Calypso GSM device is idle with deep sleep enabled, it will only wake up at preprogrammed intervals to listen on the paging channel, and will stay in deep sleep in between these paging windows. Calypso GSM devices also enter deep sleep when they are completely idle with no radio network connection. When a Calypso GSM device enters deep sleep, the main VCXO or VCTCXO that runs at 13 or 26 MHz and provides all other clocks in normal operation is completely stopped (powered off), and the only clock that remains running is the 32.768 kHz watch crystal oscillator. The preprogrammed wakeup timing (waking up to listen on the paging channel at the right time) is driven by this 32.768 kHz clock, but the Calypso can also be woken up ahead of the programmed time by an external interrupt such as a button press on the phone keypad. This deep sleep mode provides a very important power saving measure (the extremely low current draw that is achieved during deep sleep is not possible without stopping the fast clock), but it presents a real challenge for the external UART interfaces. Consider what happens when an external host sends some characters to one of Calypso's UARTs (either the AT command interface or RVTMUX) while the GSM device is in deep sleep. In normal operation a UART requires a clock of 16x the baud rate (some vendors' UARTs can make do with only 8x the baud rate) in order to receive asynchronous incoming characters, and in the Calypso these UART clocks come from the 13 MHz master clock - but that master clock is stopped during deep sleep! Calypso UARTs have some special asynchronous (non-clock-dependent) logic that causes a wakeup signal to be generated if some incoming traffic is detected at a UART while in deep sleep, but the first character that triggers this wakeup will be lost: the asynchronous logic can detect that there is "something happening" on the UART RxD line, but it cannot catch the actual byte content without a clock: the *only* clock available during deep sleep is 32.768 kHz, and even at 9600 baud one would need a clock several times faster than this rate in order to receive and register an incoming byte. Furthermore, wakeup from deep sleep takes a non-trivial length of time, thus if someone tries to send lots of data to a Calypso UART while in deep sleep, quite a bit more than just the first character will be lost: I did some experiments to characterize the delay which needs to be inserted between the first "sacrificial" wakeup character and the subsequent character which is expected to be received correctly, and 40 ms wasn't enough, whereas 60 ms did the trick. So how can one have reliable communication with a Calypso GSM device over a UART if the GSM device goes into and out of deep sleep at times which are unpredictable to the external host and if sending characters to the Calypso during deep sleep causes those characters to be lost? The solution involves a special protocol: 1) On the Calypso side, TI's reference firmware implements a UART activity timer: every time some characters are received at a UART, the timer is reset to 10 s, and until that timer expires, the GSM device is not allowed to go into deep sleep. 2) Host systems sending command traffic to Calypso modems need to keep track of how much time has elapsed since the last time they sent something to the modem, and if enough time has elapsed that the modem is now allowed to enter deep sleep, the host needs to perform a precautionary wakeup transmission before the actual desired one. What is a precautionary wakeup transmission? The idea is to send something to the modem can be either accepted or lost by the latter: if the modem happens to be awake at the time, the transmission will be received normally, and if the modem is in deep sleep, the transmission will be lost but will cause the modem to wake up and start the 10 s UART activity timer. Our FC host tools currently use the following wakeup transmissions: * On the AT command channel we send A-delay-T-delay-CR, i.e., AT and a carriage return (3 characters total) with delays inserted in between; each of the two delays is currently set to 30 ms based on empirical testing. We expect the response to be either AT<newline>OK<newline> (echo of command followed by OK response) if the modem was awake or just <newline>OK<newline> if we woke it up: if we are waking the modem from deep sleep, our initial characters will trigger the wakeup sequence but will themselves be lost, and the modem is expected to be awake with UARTs working by the time the CR comes in; we make use of a quirk of TI's AT command interpreter implementation in that sending a CR by itself produces a <newline>OK<newline> response. * On the RVTMUX interface we send a string of 64 zero bytes followed by 100 ms of delay; it is certainly overkill, but this approach was implemented back in 2013 (near the very beginning of FreeCalypso) and has worked without any problems ever since, hence we are not changing it. In the case of RVTMUX, our serial communication engine through which everything funnels is rvinterf. Rvinterf will do the "wakeup shot" the first time it sends anything to the target, and for all subsequent transmissions it will consider the time since the last transmission: if it is greater than a set threshold (7 s by default), the wakeup shot is sent again. Thus there will be no extraneous wakeup shots and associated delays during reasonably continuous back to back communication, but the wakeup shot delay will be incurred if rvinterf is killed and restarted or if a non-trivial pause occurs in the communication flow. In the case of AT commands, our fcup-* tools described in the User-phone-tools article go through a back-end program called fcup-atinterf which does the serial talking, and the latter helper program is responsible for the wakeup logic. However, fcup-atinterf is not a daemon like rvinterf, it is run anew for every fcup-* user command, hence every fcup-* command currently involves the wakeup delay step. It is certainly inefficient, but the underlying philosophy values reliability over efficiency. The one remaining use case which has not been addressed at all yet is the GSM 07.10 MUX; the current plan is to investigate it after the fc-host-tools-r9 release and after we get FCDEV3B V2 boards which will hopefully be free from the sleep mode bug that afflicts FCDEV3B V1.