diff Calypso-test-reset @ 15:38cc5795d79c

Calypso-test-reset article written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 26 May 2019 10:45:04 +0000
parents
children 396d44c543e3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Calypso-test-reset	Sun May 26 10:45:04 2019 +0000
@@ -0,0 +1,284 @@
+Reset logic and on/off states in the Calypso+Iota chipset
+=========================================================
+
+Our beloved Calypso+Iota chipset provides a special reset signal (called
+nTESTRESET on Leonardo schematics) that is just for testing, development and
+debugging, not used at all in the normal life cycle of a phone handset or
+modem.  This special test reset is triggered when you press the RESET button on
+a TI/FreeCalypso development board (D-Sample or FCDEV3B), and it can also be
+triggered slightly indirectly through the reset pin on the TI-style JTAG
+connector.  The way this reset works is very quirky and requires a lot of
+explanation, but before one can properly understand this test reset, we first
+need to look at the "regular" power-on reset, switch-on and switch-off logic
+that works in the absence of nTESTRESET.
+
+Before looking at resets and switch-on and switch-off sequences, we first need
+to understand the power domains that are involved.  There are two major power
+domains of interest: there is the main power domain that is physically powered
+off when the mobile device is not in the switched-on state, and there is the
+RTC power domain that is powered at all times whenever the battery is physically
+present, or perhaps even from a separate backup battery (a tiny coin cell) that
+provides RTC power when the main battery is removed.  The always-on RTC power
+domain allows the real time clock to maintain the time of day while the mobile
+is otherwise off (hence the name), and it also provides power to the logic that
+allows the rest of the mobile (the main power domain) to be powered on,
+initialized, booted, run and eventually switched off again in an orderly manner.
+
+All reset and on/off logic in our chipset happens in the VRPC (Voltage Reference
+and Power Control) block in the Iota chip; all of Calypso and the rest of Iota
+are fully subservient to this VRPC block.  It is crucial to understand the
+difference between powering on and off vs. switching on and off: in the
+terminology that is established in TI's chip datasheets and application notes,
+powering on means physically providing battery power to the chipset (inserting
+the battery into a phone that had it removed, or connecting a VBAT power supply
+to the orange power input connector on one of our development boards), and
+powering off means physically removing all battery power, i.e., yanking the
+battery out of a phone or disconnecting the power supply from the development
+board.  In board designs with a backup battery or a provision for one, it is
+even more complicated: a power-on happens when either the main battery or a
+backup battery becomes present, and a power-off happens when both batteries are
+removed, leaving the Iota chipset without any energy source whatsoever.  In
+contrast, the actions of a user turning her phone on and off are called
+switch-on and switch-off, respectively.
+
+The RTC power domain is powered on and receives its power-on reset (POR) on a
+power-on event and loses power only on a full power-off (complete loss of all
+battery power), whereas the main power domain is powered on and lifted out of
+reset only on a switch-on, and powered back down and held in reset on a
+switch-off.  The Calypso chip receives two reset signals from the Iota (meaning
+that each signal is an output from the Iota and an input to the Calypso):
+nRESPWON and ON_nOFF.  The nRESPWON signal is asserted (active low) only on a
+hardware power-on (and also on nTESTRESET as will be explained in due course)
+and stays high (inactive) at all other times, whereas ON_nOFF is driven high on
+switch-on and low on switch-off.  When the ON_nOFF signal is driven low by the
+Iota ABB in the switched-off state, all main (non-RTC) logic in the Calypso is
+held in reset, and in any case that logic cannot function as the physical power
+to it (coming from LDO regulators in the Iota) will typically be turned off.
+When the Iota ABB drives ON_nOFF high on switch-on, it does so after the LDO
+regulators for the main power domain have been turned on and have had enough
+time to stabilize; in the Calypso chip the transition of ON_nOFF from low to
+high causes the ARM7 core to boot.
+
+A true power-on reset happens only when all battery power is removed and
+reconnected: in simple designs without a backup battery one would need to
+remove the main battery or the power supply providing VBAT and also disconnect
+anything that may be feeding power into the system through pull-up resistors;
+in more complex designs that feature a backup battery, both the main battery
+and the backup battery would need to be removed and reconnected in order to
+trigger a POR.  Such a complete POR would reset the RTC power domain, and on
+exit from the POR the VRPC block will be in the switched-off state, with
+everything except the RTC powered off and waiting for the user to press the
+PWON button.
+
+The green LED on the FCDEV3B indicates the state of the ON_nOFF signal, and
+thus allows you to see if the VRPC block is switched on (LED on) or switched
+off (LED off).  The actual VRPC state machine in the Iota chip is a little more
+complicated and has 5 states, not just two (the states are NOBAT, BACKUP, OFF,
+ACTIVE and SLEEP), but I am simplifying here - for the complete details, please
+see the VRPC description in Iota datasheet TWL3025_SWRS021.pdf, section 4.10
+starting on page 40.  The transition from OFF to ACTIVE (switch-on event)
+happens whenever the PWON button is pressed or charging voltage is applied (on
+hardware that has charging circuits), whereas commanding a switch-off (going
+back to OFF) requires having Calypso ARM7 firmware establish communication with
+the Iota ABB over SPI and send a DEVOFF command.  If the Calypso firmware
+requests a switch-off when the PWON button is held down (jumper on FCDEV3B) or
+when a charging power source is present, the Iota VRPC goes through a switch-off
+immediately followed by a switch-on, effecting a very deep kind of reboot.
+
+nTESTRESET enters the picture
+=============================
+
+So where does nTESTRESET fit in the just-described architecture of on/off
+switching and resets?  Contrary to what one might naively think, it is NOT an
+externally-triggerable way to simulate a POR, nor is it simply ANDed or ORed
+together with some other internal reset signal.  Instead as you can see in
+Figure 4-8 on page 43 of the TWL3025_SWRS021.pdf datasheet, it is its own
+separate and very special path through the VRPC state machine that is never
+exercised at all in normal product operation.
+
+When you press the RESET button or trigger a reset through JTAG connector pin 2
+(let's call it XDS_RESET), the VRPC state machine will unconditionally leave
+whatever state it was in and will be forced into this special nTESTRESET state
+that does not occur at any other time.  For as long as nTESTRESET is held low,
+both reset signals to the Calypso (nRESPWON and ON_nOFF) will be held low as
+well, putting the Calypso into a POR-like superdeep reset, but meanwhile the
+LDO regulators are fully turned on, not off!  While nTESTRESET is held low, the
+green LED on the FCDEV3B will be off (ON_nOFF is low), but the regulators are
+on, as can be seen on JTAG connector pin 5 where the V-IO rail is brough out.
+This combination of ON_nOFF low (green LED off) but regulators on happens only
+in this special nTESTRESET-held-low state and not at any other time.
+
+When the RESET button and XDS_RESET are both released, causing nTESTRESET to go
+back to high, the VRPC state machine goes from the special nTESTRESET state to
+the ACTIVE (switched-on) state via a special direct transition that bypasses
+the normal checks.  Calypso reset inputs nRESPWON and ON_nOFF go from low to
+high at the same time (this is the only time when they do it like this), and
+the ARM7 core boots.
+
+Thus the test reset triggered via nTESTRESET is not a simple POR-like reset,
+instead it is a very special "deep reset, then unconditional power-on and boot"
+kind of operation.  As a practical matter, it does its intended job of giving
+developers an unconditional and unstoppable way to take control of the chipset
+when the ARM7 processor and its code execution are in a runaway state: in the
+Calypso+Iota on/off architecture, the most "kosher" way to cleanly reset the
+system would be a switch-off followed by a switch-on, but a normal switch-off
+is a quite complex operation that has to be performed by ARM7 firmware, and it
+is thus unavailable when the processor executes something other than perfectly
+good firmware code with clean soft-power-off functionality.  The test reset
+mechanism provides a solution, although it is a solution that may be quite
+difficult to understand at first.
+
+It is also important to note that nTESTRESET acts the same way and puts the
+chipset into the exact same state regardless of *all* prior state, as in not
+only prior sw state, but also prior hw state: in particular, it works exactly
+the same way whether the chipset was switched on or switched off prior to
+nTESTRESET assertion.  If the system was previously switched on, running some
+code that hung or become uncontrollable, nTESTRESET can be thought of as acting
+mostly like a typical processor reset that most software developers are used to,
+but if the system was previously switched off, nTESTRESET acts like a different
+kind of "turn on" command, producing a switch-on that is distinguishable from
+all other switch-on causes like PWON and charger-plug.
+
+Lack of debouncing
+==================
+
+It is important to note that there is no debouncing circuit for nTESTRESET
+inside the Iota chip, like there is for the regular PWON button.  Thus shorting
+nTESTRESET to GND directly with a finger-actuated pushbutton switch is not
+particularly good, although TI's Leonardo schematics depict just such an
+arrangement, and it works OK on the FCDEV3B in practice.
+
+The entity that drives nTESTRESET to the Calypso+Iota system takes full
+responsibility for ensuring proper timing.  The reset which is propagated from
+nTESTRESET to nRESPWON and ON_nOFF needs to have a certain duration in order to
+reset all logic properly, and there is nothing in the chipset itself to assure
+such, unlike what happens on normal switch-on sequences - instead it is the
+responsibility of the nTESTRESET driving source.  The exact timing requirements
+are not stated anywhere (at least none that we could find), but if you are
+driving nTESTRESET from a programmatic source (presumably via the XDS_RESET
+signal path described below), I would give it a 50 ms pulse.
+
+When nTESTRESET is shorted to GND with a finger-actuated pushbutton switch, one
+needs to watch out for contact bounce.  If the dry contact switch does a lot of
+make-break bounce, that make-break noise will translate directly into Calypso
+and Iota resets being asserted and negated just as rapidly, which is certainly
+not clean.  The final release from reset is the most important part though: if
+the system is put through a bunch of erratic resets as a result of contact
+bounce on the initial RESET button press, there should be no problem if there
+is a long solid reset at the end, with a clean release from it.  But if the
+release from reset is also accompanied by contact bounce with make-break events
+on the order of microseconds, then the chipset may enter garbage state by way
+of an improperly timed reset.  The nTESTRESET signal was clearly designed to be
+driven by development systems that can produce controlled timing, not by
+bounce-prone electromechanical switches driven by bounce-prone human fingers.
+
+nTESTRESET vs. XDS_RESET
+========================
+
+In its native form the internal nTESTRESET signal is pulled up to a non-logic
+voltage rail (specifically UPR, which normally follows VBAT in the absence of
+backup batteries), and it can be shorted or pulled to GND either by pushbutton
+switches (aside from the contact bounce problem noted above) or by OC/OD
+drivers.  It cannot, however, be driven by any kind of external push-pull
+driver, and more generally it cannot be connected to any circuit that operates
+on standard logic voltages like 3.3 V - the VBAT rail will typically be in the
+3.6 to 4.2 V range, which is too high for external 3.3 V logic.
+
+But TI Back In The Day had a need to drive this test reset from their XDS510
+and XDS560 "emulator" pods, and the only reset signal those pods put out is the
+one that was originally intended for JTAG TRST (which does not exist in the
+Calypso+Iota chipset), driven with a push-pull driver.  TI's solution was to
+insert a clever transistor circuit between JTAG connector pin 2 (the pin that
+was originally intended to be TRST) and the internal nTESTRESET signal; this
+circuit is depicted on the available Leonardo schematics, it has been replicated
+on our FCDEV3B, and we have every reason to believe that it is the same on TI's
+D-Sample board as well.  The effect of this circuit is that whenever the
+external XDS_RESET signal is driven low and the internal V-IO rail has power
+(see below), the internal nTESTRESET signal is driven low (asserted), and
+whenever the external XDS_RESET signal is either driven high or left alone, the
+internal nTESTRESET signal is left alone, high from the pull-up to UPR - but
+the nTESTRESET and XDS_RESET electrical nets are never exposed directly to each
+other's voltages.
+
+This clever solution does however have one side effect which is visible to
+developers working with these boards: the reset signal isolation circuit can
+only propagate an asserted low from XDS_RESET to nTESTRESET when the V-IO rail
+has power, i.e., when Iota regulators are turned on - and in the normal
+switched-off state these regulators are turned off.  Thus the operator needs to
+first cause a switch-on or at least a regulator turn-on by pressing either the
+PWON button or the RESET button, and once V-IO is on, the external host driving
+the XDS_RESET signal via the JTAG connector can take over.
+
+Another unexpected quirk is that XDS_RESET can still sometimes work even though
+the Iota regulators are off (VRPC in the switched-off state) if some leakage
+power is being fed into the V-IO rail from UART or JTAG lines through pull-up
+resistors - but this behaviour should be considered an unfortunate design
+blemish, not something to be relied on.
+
+Test reset, then switch-off, then switch-on quirk
+=================================================
+
+If you use any version of FreeCalypso host tools earlier than the upcoming
+fc-host-tools-r11 release with an FCDEV3B, you might have noticed a really odd
+quirk: if you make an fc-loadtool entry via the RESET button instead of PWON,
+then exit your loadtool session cleanly, such that the green LED goes out, the
+board ends up in a weird state - if you then do a subsequent switch-on via PWON,
+something goes wrong (fc-loadtool entry doesn't work, regular fw also hangs
+instead of producing rvinterf output) - it seems as though if you have done a
+RESET once, only another RESET works from then on, and PWON stops working
+correctly.  Yet if you press the RESET button without fc-loadtool and let the
+regular firmware boot from this nTESTRESET switch-on, and then execute a
+switch-off through the firmware (AT@POFF, fc-shell poweroff, or press, hold and
+release the PWON button) the board is powered off in a clean state - subsequent
+PWON works just fine.  What in the world is going on?
+
+The secret magic was discovered by carefully studying the TCS211 firmware code
+we've inherited from TI.  It turns out that our Iota chip has at least one
+secret undocumented register (or perhaps many more, who knows) that is not
+documented in the TWL3025_SWRS021.pdf datasheet, and any Calypso programs (full
+firmwares or standalone programs like our loadagent) that execute a Iota
+poweroff (really switch-off) operation need to make a special write to this
+magic register in order to avoid trouble in the test reset, then switch-off,
+then switch-on sequence.
+
+We are calling this undocumented Iota register VRPCAUX (its official name is
+unknown, but there is a seemingly-corresponding register in TI's newer Syren
+ABB chip which the firmware calls VRPCAUX, and the name logically fits in terms
+of the function), and it is accessed via undocumented register page 2.
+Officially both Iota and Syren ABB chips only have register pages 0 and 1, but
+it turns out that both chips also have an undocumented page 2 - and in order to
+access this secret page 2, one first needs to issue a special (also secret)
+unlock command through yet other registers - whew!
+
+So just *why* do we need to mess around with secret undocumented Iota registers
+from our production code?  From what we can tell, this VRPCAUX register lives
+in the VRPC block in the RTC power domain, and it preserves its state when the
+rest of the system is powered down in the switched-off state.  Apparently this
+register controls some aspects of the switch-on process, and when an nTESTRESET
+reset-and-boot sequence is performed, this VRPCAUX register is loaded with a
+different configuration than on normal POR.  It appears that the "normal" value
+of VRPCAUX in the absence of test reset operations is 0x007 (bit meaning unknown
+of course when we are dealing with secret undocumented stuff), and this value
+is needed for switch-on and possibly other things (sleep entry and exit, ABB
+interrupts, who knows) to work correctly.  But if we boot via nTESTRESET and
+read the secret register, we see 0x2E7 instead - and if we do a normal DEVOFF
+command without changing it to 0x007 first, we get into the broken state where
+PWON switch-ons don't work.  (It is very reassuring though that another
+nTESTRESET always works no matter what - so it looks like this debug reset is
+truly irrespective of all prior hw state.)
+
+TI's TCS211 firmware has a bit of magic in its boot code path in the ABB_on()
+function in the chipsetsw/drivers/drv_core/abb/abb.c module, and it has this
+attention-drawing comment:
+
+// Restore the ABB checks and debouncing if start on TESTRESETZ
+
+The code following this comment goes through the gymnastics of enabling access
+to register page 2, then writing 0x007 into the register which we've named
+VRPCAUX.  (That's what it does for Iota; for Syren it also writes a few other
+registers also in that same undocumented page 2.)  Reproducing these steps in
+our target-utils code (loadagent and friends) has resulted in the problem
+behaviour going away: now we can enter fc-loadtool via the RESET button, then
+exit loadtool (loadagent poweroff command executed on the target), and the
+board is powered off cleanly, with both PWON and RESET working for subsequent
+switch-ons.  Whew!