.. _backup_ram:

Safety Backup RAM
=================

Overview
--------

The STM controller's backup RAM is used to store different kinds of information that shall be preserved if the controller resets.
The hardware setup is missing a separate powersupply for the controller's backup domain. Therefore, the backup RAM is cleared, when the power is cut.

The backup RAM is used to store permanent error flags (See :ref:`safety_flags`). This ensures the flags that trigger hard faults / the panic mode, can be identified, although the wathcoog resets the controller. The only way to clear them is by cutting the power.
Because cutting the power is a way to clear the backup RAM, no separate method for clearing the error entries in the backup RAM is defined.

The backup RAM contents are protected by a `CRC Checksum`_. 

The backup RAM is initialized and checked after boot. If the controller starts from a powered down state,
the backup RAM is empty. This is detected by an invalid `Header`_ at the beginning of the backup RAM. If this is the case, the safety ocntoller
will create a valid backup RAM image with a `Header`_, empty `Boot Status Flag Entries`_, empty `Config Overrides`_, an empty `Error Memory`_, and a valid `CRC Checksum`_.

If the Header is valid during boot (verified by plausible values and correct magic numbers), the backup RAM is CRC checked and the error memory is
checked for valid entries.
In case of a CRC error or invalid entries in the error memory, the Backup RAM is wiped and reinitialized. On top of that, the error flag :ref:`safety_flags_safety_mem_corrupt` is set.

.. note:: It may be possible that future versions of the hardware include a backup RAM battery / Goldcap. In this case, a way to clear the error memory will be implemented,
    because it will no longer be possible to clear the error memory by cutting the power.
    On top of that, the backup memory will also contain the calibration data.

.. note:: The firmware will not use the ``NOP`` entries of the error memory by default, but they will be respected by the validity checker.

Partitioning and Entries
------------------------

The backup RAM consists of multiple sections. The memory section are listed below. 

Header
~~~~~~

The backup memory header is located at offset address:

.. doxygendefine:: SAFETY_MEMORY_HEADER_ADDRESS

The header is defined by the following structure:

.. doxygenstruct:: safety_memory_header

The validity of the header is checked, if the magic and inverse amgic fields contain the correct values, and if the offset address pointers
have values that are located inside the error memory and are not ``0`` or the same value.

The safety memory header magic is:

.. doxygendefine:: SAFETY_MEMORY_MAGIC


.. _backup_ram_boot_flags:

Boot Status Flag Entries
~~~~~~~~~~~~~~~~~~~~~~~~

The boot status flag entries are use to store system states over resets.
The flags are stored in memory using the follwoing structure:

.. doxygenstruct:: safety_memory_boot_status

Flags are evaluated active, if the corresponding word is unequal to ``0``.

Config Overrides
~~~~~~~~~~~~~~~~

Config overrides are used to override persistance and flag weights dynamically. The safety controller will parse the entries on 
startup.

======================= ============ ================= ===================== =====================================
Entry                   Byte 1 (LSB) Byte 2            Byte 3                Byte 4 (MSB)
======================= ============ ================= ===================== =====================================
Weight override         ``0xA2``      ``Weight``       ``Flag Number``       reserved don't care (written as 0xAA)
Persistance override    ``0x8E``      ``Persistance``  ``Flag Number``       reserved don't care (written as 0xBB) 
======================= ============ ================= ===================== =====================================

All words, not matching the table above are ignored and do not cause an error. By default the firmware fills this memory area with zeroes.

Error Memory
~~~~~~~~~~~~

The error memory contains error entries in form of 32 bit words. The entries are coded as stated below.

``Error Flag`` entries are used to restore error flags after boot. In theory, all flags can be set using this entry type.
However, only persistent flags are stored in the error memory by the firmware.

``NOP`` entries have no meaning. They are used as a filler. When adding a new error memory entry, the error memory is scanned until the first ``NOP`` entry is found.
It is replaced with a valid entry. If the error memory contains a word, that is not defined below, it is considered invalid and will trigger the RAM checker on boot.
``NOP`` entries can be used to preallocate the error memory in advance. if the end of the error memory is reached, it is expanded by 1 word to first
the new error entry, until the backup RAM is full. After this, no further errors are stored.

If the same persistent error is triggered mutliple times, the ``COUNTER`` in the error entry is incremented.

======================= ============ ================= ===================== =====================================
Entry                   Byte 1 (LSB) Byte 2            Byte 3                Byte 4 (MSB)
======================= ============ ================= ===================== =====================================
Error Flag              ``0x51``     ``Flag Number``   ``COUNTER 7:0``       ``COUNTER 15:8``
NOP Entry               ``0x22``     ``0x12``          ``0xAA``              ``0xC1``
======================= ============ ================= ===================== =====================================

CRC Checksum
~~~~~~~~~~~~

The CRC checksum is located after the error memory. The checksum is calculated by the internal peripheral module of the STM32F4 controller.
Therefore, the CRC calculation is fixed.

The polynomial is ``0x4C11DB7`` (Ethernet CRC32):

.. math:: P_{CRC}(x) = x^{32}+x^{26}+x^{23}+x^{22}+x^{16}+x^{12}+x^{11}+x^{10}+x^{8}+x^{7}+x^{5}+x^{4}+x^{2}+x+1
