Commit 17763629 authored by TilCreator's avatar TilCreator

Merge branch 'card10/firmware'

parents a9518740 c3c5a5f8
Pipeline #4137 passed with stages
in 1 minute and 11 seconds
......@@ -4,13 +4,80 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
## [v1.11] - 2019-09-24 - [Karotte]
[Karotte]: https://card10.badge.events.ccc.de/release/card10-v1.11-Karotte.zip
### Added
- `micropython.mem_use()` function.
- **Support for sleep-mode instead of full power-off. This means the RTC now
retains its state!**
- For debugger users: A GDB macro `task_backtrace` which allows to view
backtraces of tasks which are currently swapped out. Use like
```text
(gdb) task_backtrace serial_task_id
...
(gdb) task_backtrace dispatcher_task_id
...
(gdb) task_backtrace ble_task_id
```
- BHI160 magnetometer sensor
- ESB API in Pycardium.
- Monotonic clock API
- New FOSS font ...
### Changed
- `Display.print()` uses a transparent background when printing with `bg == fg`.
- Try different crc16 module during build because different environments might
have different ones installed.
- Improved ECG app, it can now blink on pulse and more!
- Improved BHI160 and BME680 apps.
### Fixed
- Fixed a regression which made it impossible to turn off the flashlight.
- Fixed CRT for l0dables not allowing to overwrite interrupt handlers.
- Fixed ECG App not closing the sensor on `KeyboardInterrupt`.
- Fixed a bug which made the power-button unresponsive when pressed during boot
(Interrupts were getting ignored).
- Fixed `simple_menu.Menu.exit()` not actually working.
- Added a few missing locks in `leds` module.
- Added a workaround for BHI160 axis mapping not being applied in some cases.
- Added a critical-section in BLE stack initialization to prevent weird lock-ups.
- Fixed vibra module crashing when calling `vibra.vibrate()` while already running.
- Fixed sensor-sample overflow leading to I2C bus lockup.
## [v1.10] - 2019-09-05 21:42 - [JerusalemArtichoke]
[JerusalemArtichoke]: https://card10.badge.events.ccc.de/release/card10-v1.10-JerusalemArtichoke.zip
### Added
- **ws2812**: Connect Neopixels to the wristband GPIOs and make your card10
even more colorful!
- DigiClk is now in the default prelude!
- High-pass filter and pulse detection in default ECG app.
- Actually added `uuid` module - it was not built into the firmware before,
by accident.
- `leds.get_rgb()`: Get the current color of an LED.
- `leds.get_rocket()`: Get the current brightness of one of the rockets.
- `micropython.mem_use()` function.
- The analog-clock can now also set the time using the buttons.
### Changed
- **Pycardium**: Switched from `long-long` to `mpz` integer representation.
This should resolve any issues with large numbers which had popped up so far.
- Refactored BME680 sensor interface.
- Made OpenOCD scripts work with more debuggers out of the box.
- Internal changes in preparation for button-interrupts.
### Fixed
- Backlight and Vibration motor were not reset when switching apps.
- Mismatch in default settings of the *Card10 Nickname* app.
- Fixed the PMIC ADC muxer not being properly reset to neutral after a
measurement.
- Fixed wrong timezone offset calculation in `utime.time_ms()`.
- Fixed bug where `\` characters were not parsed as path separators.
- Fixed the alignment request check in our ELF l0der.
- Fixed a buffer-overflow in the config-parser.
## [v1.9] - 2019-08-28 23:23 - [IcebergLettuce]
......@@ -214,7 +281,9 @@ fbf7c8c0 fix(menu.py) Refactored menu.py based on !138
## [v1.0] - 2019-08-21 00:50
Initial release.
[Unreleased]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.9...master
[Unreleased]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.11...master
[v1.11]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.10...v1.11
[v1.10]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.9...v1.10
[v1.9]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.8...v1.9
[v1.8]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.7...v1.8
[v1.7]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.6...v1.7
......
......@@ -28,7 +28,7 @@ The current draft uses following service specification:
- Rockets characteristic:
UUID: ``42230210-2342-2342-2342-234223422342``
write no response
read and write no response
- Background LED Bottom Left characteristic:
......@@ -104,6 +104,9 @@ Rockets characteristic
The Rockets characteristic makes it possible to address every three rockets.
Just write there three byte array, one for evey rocket.
On read you get the current value of all three rockets.
Range is between 0 and 31 (``0x1f``) if send higher value it will set to max of 31.
Dataformat:
......@@ -113,8 +116,8 @@ Dataformat:
Rocket0 Rocket1 Rocket2
======= ======= =======
- Enable only Rocket0: ``0xff0000``
- Enable all rockets with 50% brightness: ``0x7f7f7f``
- Enable only Rocket0: ``0x1f0000``
- Enable all rockets with 50% brightness: ``0x0f0f0f``
Background LED <Position> characteristic
----------------------------------------
......
.. _card10_cfg:
card10.cfg
==========
Certain high-level settings can be configured using a filed named ``card10.cfg``. It is accessed from the :ref:`usb_file_transfer` of the bootloader. Once you are in this mode and have mounted the badge's flash device, you can either create or update a file named ``card10.cfg``.
The file is in the well-known INI-style format, with one setting per line. For instance, if there were an option called ``answer_to_life``, you could set it by writing the following line in the ``card10.cfg`` file:
.. code-block:: text
answer_to_life = 42
Don't forget to unmount the filesystem before rebooting your badge after changing any setting.
Syntax and Types
----------------
Lines that start with a ``#`` character are ignored.
Any other line will have the overall syntax of ``option_name = option_value``, with spaces around the ``=`` character optional.
Option names are internal to card10 and described below. Each option has a defined type.
========= ===========
Type name Description
========= ===========
Boolean A true/false value. ``1`` or ``true`` is true, ``0`` or ``false`` is false. Example: ``foo = true``.
String An unquoted string value of maximum 20 bytes. Values longer than 20 bytes are trimmed. Example: ``foo = bar``.
Integer A signed 32-bit integer in base 10. Example: ``foo = 42`` or ``bar = -1337``.
Float A single-precision (32-bit) floating-point number in base 10. Example: ``foo = 13.37``.
========= ===========
Supported options
-----------------
=============== ========== ===========
Option name Type Description
=============== ========== ===========
``execute_elf`` Boolean Allow running of binary :ref:`l0dables`. These files can be nefarious, so this option is off by default.
=============== ========== ===========
......@@ -90,6 +90,8 @@ html_context = {
autodoc_mock_imports = [
"buttons",
"interrupt",
"sys_bme680",
"sys_bhi160",
"sys_display",
"sys_leds",
"sys_max30001",
......
......@@ -115,6 +115,12 @@ command to soft-reset card10.
...
(gdb)
.. note::
You will also find the following self-describing gdb files in the firmware
root directory, which do not require additional arguments:
``flash-all.gdb, flash-bootloader.gdb,
flash-both.gdb, flash-epicardium.gdb, flash-pycardium.gdb``
.. warning::
If you are used to use ``mon reset halt``, be aware that the card10 prototypes
do not connect the reset line to the debugger. OpenOCD is configured to only do
......
......@@ -107,7 +107,6 @@ firmware features:
info related to BLE.
- ``-Ddebug_core1=true``: Enable the core 1 SWD lines which are exposed on the
SAO connector. Only use this if you have a debugger which is modified for core 1.
- ``-Djailbreak_card10=true``: Enable execution of .elf l0dables on core 1.
.. warning::
......@@ -144,6 +143,15 @@ In order to do a rebuild you can issue a clean command to ninja via
Otherwise, rerunning ``./bootstrap.sh`` will also clean the build-directory.
.. note::
**macOS**: If ``strip`` fails to work on the freshly compiled ``mpy-cross``:
"strip: object: (...)/lib/micropython/micropython/mpy-cross/mpy-cross
malformed object (unknown load command 9)", you a likely not using the
`strip` that matches to your ``clang``. Do ``which strip && which clang``,
and if the paths don't match, clean up your PATHs, or as a quick hack,
create a symlink for strip.
.. note::
If you try to flash pycardium_epicardium.bin (renamed to card10.bin)
......@@ -152,4 +160,4 @@ Otherwise, rerunning ``./bootstrap.sh`` will also clean the build-directory.
was >1MB. This was caused by the ``tr`` tool in the build process
(it's supposed to create a large file with 0xff in it) - this requires the
LC_ALL environment variable to be not set, or set to "C"
(but not UTF8 or similar).
\ No newline at end of file
(but not UTF8 or similar).
......@@ -5,27 +5,14 @@ method of flashing:
Flash Without Debugger
----------------------
If you do not have a debugger, you have to update the firmware using our
bootloader. To do so, you need to reboot card10 while keeping the buttom on
the bottom right pressed. Rebooting is done by either short pressing the power
button (top left) while you have a working firmware, or turning the card10 off
completely (by pressing the power button for 8 seconds) and then starting it again.
.. image:: static/bootloader-buttons.png
If you did everything correctly, the bootloader will display:
.. code-block:: text
Bootloader
Jul 28 2019
USB activated.
Ready.
If you do not have a debugger, you have to update the firmware using our
bootloader by going into :ref:`usb_file_transfer`.
On your host, you should now see an 8MB flash-device appear. You can now drop
the firmware's ``.bin`` (from ``build/pycardium/pycardium_epicardium.bin`` in
most cases) into this flash-storage. You **must** call the file ``card10.bin``
for the bootloader to use it.
After you get your badge into :ref:`usb_file_transfer`, you can drop the firmware's
``.bin`` (from ``build/pycardium/pycardium_epicardium.bin`` in most cases) into
this flash-storage. You **must** call the file ``card10.bin`` for the
bootloader to use it.
The bootloader will then display ``Writing.`` in red while it is actually
writing the file to external flash. Please wait until it displays ``Ready.``
......
......@@ -38,12 +38,15 @@ Last but not least, if you want to start hacking the lower-level firmware, the
pycardium/simple_menu
pycardium/utime
pycardium/vibra
pycardium/ws2812
.. toctree::
:maxdepth: 1
:caption: Firmware
overview
card10-cfg
usb-file-transfer
how-to-build
how-to-flash
debugger
......
......@@ -14,24 +14,38 @@ Epicardium
Epicardium is based on `FreeRTOS <https://www.freertos.org/>`_. There are a
number of tasks that will have been keeping card10 running. These are:
* **Dispatcher**: The dispatcher task handles API calls from core 1.
* **PMIC**: The power manager task checks the battery level and other interesting
statistics that can be gathered from our power manager IC (MAX77650).
* **Serial**: Handles serial communication via *UART*, *CDC ACM* and possibly
Bluetooth.
* **BHI160**: Housekeeping task for interaction with the `BHI160`_.
+-------------------+-------------------------------+----------+-------------------------------------------+
| Name | ID Global | Priority | Description |
+===================+===============================+==========+===========================================+
| `vPmicTask`_ | ``pmic_task_id`` (static) | +4 | Power Management (and Reset Button) |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vLifecycleTask`_ | ``lifecycle_task`` (static) | +3 | Control of the payload running on core 1. |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vBleTask`_ | ``ble_task_id`` (static) | +3 | Bluetooth Low Energy Stack |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vSerialTask`_ | ``serial_task_id`` | +3 | Serial Output via UART/CDC-ACM/BLE |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vApiDispatcher`_ | ``dispatcher_task_id`` | +2 | Epicardium API dispatcher |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vLedTask`_ | -/- | +1 | LED Animations |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vMAX30001Task`_ | ``max30001_task_id`` (static) | +1 | `MAX30001`_ ECG driver |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vBhi160Task`_ | ``bhi160_task_id`` (static) | +1 | `BHI160`_ sensor fusion driver |
+-------------------+-------------------------------+----------+-------------------------------------------+
.. _vPmicTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/pmic.c#L281
.. _vLifecycleTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/lifecycle.c#L361
.. _vBleTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/ble/ble.c#L237
.. _vSerialTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/serial.c#L289
.. _vApiDispatcher: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/dispatcher.c#L25
.. _vLedTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/personal_state.c#L58
.. _vMAX30001Task: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/max30001.c#L378
.. _vBhi160Task: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/bhi.c#L419
.. _MAX30001: https://www.maximintegrated.com/en/products/analog/data-converters/analog-front-end-ics/MAX30001.html
.. _BHI160: https://www.bosch-sensortec.com/bst/products/all_products/bhi160
.. todo::
The following tasks have not yet been implemented/are currently in the works:
- **Bluetooth**: The bluetooth stack (`#23`_)
- **Payload Controller**: Control what is running on core 1
.. _#23: https://git.card10.badge.events.ccc.de/card10/firmware/issues/23
Epicardium API
--------------
Epicardium exposes lots of functionality via the *Epicardium API*. The
......@@ -41,23 +55,28 @@ you should probably read the :ref:`epicardium_api_guide` guide.
Pycardium
---------
Pycardium is our MicroPython fork. Its purpose is to make it as easy as
possible to interact with card10. If you are interested in working on
Pycardium, take a look at the :ref:`pycardium_guide` guide.
L0dables
.. _l0dables:
l0dables
--------
Next to Pycardium, other bare-metal code can also run on core 1. For example,
a Rustcardium or C-cardium. These l0dables must be compiled using our special
a `Rustcardium`_ or C-cardium. These l0dables must be compiled using our special
linker script and should link against the api-caller library so they can
interface with the :ref:`epicardium_api`.
Note: this feature is disabled by default and has to be enabled at build time.
To do this, run ``bootstrap.sh`` with the option ``-Djailbreak_card10=true``
and rebuild the firmware as described in :ref:`how_to_build`.
.. todo::
Note: this feature is disabled by default and has to be enabled in :ref:`card10_cfg`. A :ref:`card10_cfg` file dropped into the :ref:`usb_file_transfer` of the badge containing ``execute_elf = true`` is enough.
l0dables are currently built within the source tree of the main repository. See ``l0dables/blinky`` for an example of a hello-world-like program. Within those programs, you can access the :ref:`epicardium_api` to control the hardware and behaviour of the badge.
Once you have a built ELF file, you can drop it into the FAT filesystem of the flash (eg. via :ref:`usb_file_transfer`) and it will be available from the menu program of the badge.
Provide more details how this works
.. _Rustcardium: https://git.card10.badge.events.ccc.de/astro/rust-card10
Program Flow Diagram
--------------------
......
......@@ -2,9 +2,18 @@
``bhi160`` - Sensor Fusion
==========================
.. versionadded:: 1.4
Supports the BHI160 sensor on the card10 for accelerometer, gyroscope...
Supports the BHI160 sensor on the card10 for accelerometer, gyroscope,
magnetometer and orientation.
The coordinate system of the BHI160 sensor data looks like this:
.. image:: ../static/bhi160-coordinates.png
All angles and angular velocities (like gyroscope, orientation) rotate counter
clockwise around their respective axis.
**Example**:
......@@ -12,91 +21,33 @@ Supports the BHI160 sensor on the card10 for accelerometer, gyroscope...
import bhi160
import utime
bhi = bhi160.BHI160Orientation()
while True:
samples = bhi.read()
print(samples)
utime.sleep(0.5)
.. class:: bhi160.BHI160Orientation(sample_rate,dynamic_range,callback,sample_buffer_len)
Orientation of the BHI160
Parameters:
sample_rate: int, optional
Sample rate (default is 4)
dynamic_range: int, optional
Dynamic range (default is 2)
callback: callable, optional
Call this callback when enough data is collected (default is None)
.. todo:: The callback functionality is untested, so do not be confused if it does not work.
sample_buffer_len: int, optional
Length of sample buffer (default is 200)
.. py:method:: read():
Read sensor values
:returns: Collected sensor values as list
.. py:method:: close():
Close the connection to the sensor
.. class:: bhi160.BHI160Accelerometer
Accelerometer of the BHI160
Parameters:
sample_rate: int, optional
Sample rate (default is 4)
dynamic_range: int, optional
Dynamic range (default is 2)
callback: callable, optional
Call this callback when enough data is collected (default is None)
.. todo:: The callback functionality is untested, so do not be confused if it does not work.
sample_buffer_len: int, optional
Length of sample buffer (default is 200)
.. py:method:: read():
Read sensor values
:returns: Collected sensor values as list
.. py:method:: close():
Close the connection to the sensor
.. class:: bhi160.BHI160Gyroscope
Gyroscope of the BHI160
Parameters:
sample_rate: int, optional
Sample rate (default is 4)
dynamic_range: int, optional
Dynamic range (default is 2)
callback: callable, optional
Call this callback when enough data is collected (default is None)
.. todo:: The callback functionality is untested, so do not be confused if it does not work.
sample_buffer_len: int, optional
Length of sample buffer (default is 200)
if len(samples) == 0:
utime.sleep(0.25)
continue
# print the latest sample
print(samples[-1])
utime.sleep(0.25)
.. py:method:: read():
Read sensor values
.. autoclass:: bhi160.BHI160
:returns: Collected sensor values as list
.. autoclass:: bhi160.BHI160Orientation
:members:
:inherited-members:
.. py:method:: close():
.. autoclass:: bhi160.BHI160Accelerometer
:members:
:inherited-members:
Close the connection to the sensor
.. autoclass:: bhi160.BHI160Gyroscope
:members:
:inherited-members:
.. autoclass:: bhi160.BHI160Magnetometer
:members:
:inherited-members:
......@@ -2,6 +2,7 @@
``bme680`` - Environmental Sensor
=================================
Allows access to environmental data of card10's surroundings.
**Example**:
......@@ -9,17 +10,28 @@
import bme680, utime
bme680.init()
with bme680.Bme680() as environment:
while True:
d = environment.get_data()
while True:
temperature, humidity, pressure, resistance = bme680.get_data()
print("Temperature: {:10.2f} °C".format(d.temperature))
print("Humidity: {:10.2f} % r.h.".format(d.humidity))
print("Pressure: {:10.2f} hPa".format(d.pressure))
print("Gas Resistance: {:10.2f} Ω".format(d.resistance))
print("Temperature: {:10.2f} °C".format(temperature))
print("Humidity: {:10.2f} % r.h.".format(humidity))
print("Pressure: {:10.2f} hPa".format(pressure))
print("Gas Resistance: {:10.2f} Ω".format(resistance))
utime.sleep(1)
utime.sleep(1)
Sensor Class
------------
.. autoclass:: bme680.Bme680
:members:
Deprecated Interface
--------------------
The following functions should no longer be used directly. The only exist for
compatibility as they were the old BME680 interface in previous firmware
versions.
.. py:function:: init()
......@@ -29,6 +41,8 @@
:py:func:`bme680.init`.
.. versionadded:: 1.4
.. deprecated:: 1.10
Use the :py:class:`bme680.Bme680` class instead.
.. py:function:: get_data()
......@@ -38,9 +52,13 @@
``pressure`` (hPa) and ``gas resistance`` (Ohm).
.. versionadded:: 1.4
.. deprecated:: 1.10
Use the :py:class:`bme680.Bme680` class instead.
.. py:function:: deinit()
Deinitialize the sensor.
.. versionadded:: 1.4
.. deprecated:: 1.10
Use the :py:class:`bme680.Bme680` class instead.
``display`` - Display
=====================
The display module let's you draw on the card10's display.
Pixels are addressed from top left to bottom right with a range of x: 0 to 159 and y: 0 to 79.
.. code-block:: text
0,0
+---------------------+
| |
| |
| |
| |
+---------------------+
159,79
Drawing operations are clipped, pixels outside of the screen will be ignored.
.. automodule:: display
:members:
......@@ -72,3 +72,30 @@ Card10-Specific
Please only call this function if absolutely necessary. In most cases
you'll want to just :py:func:`os.exit` instead.
.. py:function:: usbconfig(config_type)
Change active USB configuration. By default, card10 boots with
:py:data:`os.USB_SERIAL` active.
This will deactivate the currently active USB configuration. This means
that, if you activate :py:data:`os.USB_FLASH` while :py:data:`os.USB_SERIAL`
was active, the USB serial will be disconnected.
:param config_type: Selects which config to activate. Possible
values are :py:data:`os.USB_SERIAL`, :py:data:`os.USB_FLASH`,
or :py:data:`os.USB_NONE`.
.. versionadded:: 1.11
.. py:data:: USB_NONE
No USB device active.
.. py:data:: USB_SERIAL
CDC-ACM serial device active.
.. py:data:: USB_FLASH
Mass-Storage device active.
......@@ -49,10 +49,19 @@ and power it on::
leds.set_rocket(0, 31)
.. note::
If you're using iOS/Mac then you can connect to your serial console using:
.. code-block:: shell-session
screen /dev/tty.usbmodem* 115200
You can now see in your console what buttons you have pressed and your
console outputs/logs. With ``CTRL+C`` you exit the console.
REPL modes
^^^^^^^^^^
MicroPython supports a different REPL modes over the serial console. The modes
can be changed on every new line.
......@@ -77,5 +86,3 @@ or give you tracebacks if an error occured.
You can use **pycard10** (tools/pycard10.py) to execute python files from your
PC directly on the card10.
......@@ -201,6 +201,8 @@ Struct module.
UUID(bytes='\x12\x34\x56\x78' * 4)
UUID(int=0x12345678123456781234567812345678)
.. versionadded:: 1.10
.. py:attribute:: bytes
UUID as ``bytes()`` object
......@@ -221,7 +223,4 @@ Struct module.
Generate a new UUID version 4 (random UUID).
.. todo::
This function is not yet usable because we don't have
:py:func:`os.urandom` yet.
.. versionadded:: 1.10
......@@ -33,6 +33,18 @@ alarm.
Return the current timestamp in milliseconds since 2000-01-01 00:00 in
the local timezone.
.. py:function:: monotonic()
Return a monotonically increasing timestamp.
.. versionadded:: 1.11
.. py:function:: monotonic_ms()
Return a monotonically increasing timestamp in milliseconds.
.. versionadded:: 1.11
.. py:function:: set_time(secs)
Sets the time to ``secs`` seconds since 2000-01-01 00:00 in the local
......
.. py:module:: ws2812
``ws2812`` - Neopixel LEDs
==========================
The ``ws2812`` module controls LEDs of the WS2812 type. Just as the ``leds`` module, it exposes a function :py:func:`ws2812.set_all`, which works a similar fashion.
.. versionadded:: 1.10
.. py:function:: set_all(pin, colors)
Set multiple of the LEDs to RGB values.
Filling starts at the LED connected to the specified gpio pin.
:param int pin: ID of the pin to use for sending the data.
:param colors: List of RGB triplets.