Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Show changes
Showing
with 464 additions and 61 deletions
......@@ -33,11 +33,56 @@ systems this device will be called ``/dev/ttyACM0`` or ``/dev/ttyACM1``.
Choose a terminal-emulator of your liking and open the above mentioned device.
Baud-rate is 115200. Some options are:
* **screen**: ``screen /dev/ttyACM0 115200``
* **picocom**: ``picocom -b 115200 /dev/ttyACM0``
* **screen**: ``sudo screen /dev/ttyACM0 115200``
* **picocom**: ``sudo picocom -b 115200 /dev/ttyACM0``
After connecting, reboot card10 and you should see the MicroPython REPL pop up.
After connecting, reboot reset the card10 via the power button (left upper
corner) and you should see the output of **menu.py** script (it's located in
*preload/menu.py*). You can press CTRL-C to interrupt the script and jump into
the MicroPython prompt.
.. todo::
To switch on the blue fairy dust you must import the led python module::
Getting Started Guide for people interested in writing Python code.
import leds
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.
Normal mode
"""""""""""
This is the mode you will first see. You can switch to it by pressing CTRL-B.
If you are in a other mode you can return to this mode by pressing CTRL-B too.
Paste mode
""""""""""
You can enter the paste mode by pressing CTRL-E and you can simple copy 'n'
paste your source code into the console and it will be interpreted and executed
line by line. Every new line will be reply by the prompt with **===**.
RAW mode
""""""""
The RAW mode to be intendend for the usage with tools. By pressing CTRL-A you
will enter the RAW REPL mode. The type in code will not printed. By pressing
CTRL-D the whole entered code will be evaluated and executed. The board will
reply with **OK** and print after that the output (print commands) of the code
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.
......@@ -2,7 +2,12 @@
``personal_state`` - Personal State
===================================
The :py:mod:`personal_state` module allows you to set and get the card10 users personal state from your script. The personal state is displayed on the top-left LED on the bottom of the harmonics board. While the personal state is set the LED can't be controlled by the :py:mod:`leds` module.
The :py:mod:`personal_state` module allows you to set and get the card10 users
`personal state`_ from your script. The personal state is displayed on the
top-left LED on the bottom of the harmonics board. While the personal state is
set the LED can't be controlled by the :py:mod:`leds` module.
.. _personal state: https://card10.badge.events.ccc.de/ps/
**Example**:
......@@ -26,8 +31,13 @@ The :py:mod:`personal_state` module allows you to set and get the card10 users p
Set the users personal state.
:param int state: ID of the personal state to set. Must be one of :py:data:`personal_state.NO_CONTACT`, :py:data:`personal_state.CHAOS`, :py:data:`personal_state.COMMUNICATION`, :py:data:`personal_state.CAMP`.
:param int persistent: Controls whether the personal state is persistent. A persistent state is not reset when the pycardium application is changed or restarted. In persistent mode the personal state LED is not controllable by the pycardium application.
:param int state: ID of the personal state to set. Must be one of
:py:data:`personal_state.NO_CONTACT`, :py:data:`personal_state.CHAOS`,
:py:data:`personal_state.COMMUNICATION`, :py:data:`personal_state.CAMP`.
:param int persistent: Controls whether the personal state is persistent. A
persistent state is not reset when the pycardium application is changed
or restarted. In persistent mode the personal state LED is not
controllable by the pycardium application.
.. py:function:: clear()
......@@ -40,7 +50,8 @@ The :py:mod:`personal_state` module allows you to set and get the card10 users p
Get the users personal state.
:returns: A tuple containing the currently set state and a boolean indicating if it's persistent or not.
:returns: A tuple containing the currently set state and a boolean
indicating if it's persistent or not.
.. py:data:: NO_STATE
......
``png`` - PNG Decoder
=====================
The ``png`` module provides functions to decode PNG files into raw pixel data
which can be displayed using the card10's display or its LEDs.
.. automodule:: png
:members:
.. py:module:: power
``power`` - PMIC power module handling
======================================
.. versionadded:: 1.4
The :py:mod:`power` module allows you to read the card10's power status
in your scripts.
**Example**:
.. code-block:: python
import power
print(power.read_battery_voltage())
.. py:function:: read_battery_voltage()
Read the battery voltage in V. Please keep in mind that battery
voltage behaves exponentially when interpreting this value.
.. warning::
Card10 will hard-shutdown once the voltage drops below 3.4 V
.. versionadded:: 1.4
.. py:function:: read_battery_current()
Read the battery-side current flow in A.
.. versionadded:: 1.4
.. py:function:: read_chargein_voltage()
Read the charge voltage in V.
.. versionadded:: 1.4
.. py:function:: read_chargein_current()
Read the charge current in A.
.. versionadded:: 1.4
.. py:function:: read_system_voltage()
Read the system-side voltate in V.
.. versionadded:: 1.4
.. py:function:: read_thermistor_voltage()
Read the thermistor voltage in V.
There is a resistor network from GND over a thermistor
(10K at room temperature) over 10K to the Thermistor Bias voltage.
This reads the voltage between thermistor and resistor.
.. versionadded:: 1.4
``simple_menu`` - Draw a Menu
=============================
.. versionadded:: 1.4
To allow quickly hacking some scripts, Pycardium has a small library for
displaying menus. You can use it like this:
.. code-block:: python
import color
import simple_menu
class MyMenu(simple_menu.Menu):
color_1 = color.CAMPGREEN
color_2 = color.CAMPGREEN_DARK
def on_select(self, name, index):
print("{!r} was selected!".format(name))
if __name__ == "__main__":
MyMenu(["foo", "bar", "baz"]).run()
.. autoclass:: simple_menu.Menu
:members:
.. autodata:: simple_menu.TIMEOUT
.. autofunction:: simple_menu.button_events
MicroPython Standard Library
============================
Pycardium contains some modules from the MicroPython standard library. These
are:
Pycardium contains some modules from the MicroPython standard library.
Some modules below use a standard Python name, but prefixed with “u”,
e.g. ujson instead of json. This is to signify that such a module is a
micro-library, i.e. implements only a subset of CPython module
functionality. Please refer to the official `MicroPython docs`_ for an
explanation why.
All u-name modules can also be imported using their non-u-name. E.g.
``import utime`` and import ``import time`` will both work.
.. _MicroPython docs: http://docs.micropython.org/en/latest/library/index.html#python-standard-libraries-and-micro-libraries
.. py:module:: framebuf
``framebuf``
------------
Refer to the official `MicroPython docs for framebuf`_.
.. _MicroPython docs for framebuf: https://docs.micropython.org/en/latest/library/framebuf.html
.. py:module:: ubinascii
......@@ -201,6 +219,8 @@ Struct module.
UUID(bytes='\x12\x34\x56\x78' * 4)
UUID(int=0x12345678123456781234567812345678)
.. versionadded:: 1.10
.. py:attribute:: bytes
UUID as ``bytes()`` object
......@@ -217,11 +237,8 @@ Struct module.
UUID version accordiung to RFC 4122
.. py:function:: uuid4():
.. py:function:: uuid4()
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
......@@ -8,6 +8,9 @@ CPython but wouldn't fit anywhere else in our implementation. Most
prominently, this is the :py:func:`utime.alarm` function for setting an RTC
alarm.
Like all other u-name modules, ``utime`` can also imported using the standard
``import time`` statement.
.. |time| replace:: ``time``
.. _time: https://docs.python.org/3/library/time.html
......@@ -28,11 +31,69 @@ alarm.
Return the current timestamp in seconds since 2000-01-01 00:00 in
the local timezone.
.. py:function:: time_ms()
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:: ticks_ms()
Return processor ticks (converted to milliseconds) since Pycardium startup.
This function should be the preferred method for timing and profiling
because it does not need an API call and thus is very fast.
.. versionadded:: 1.13
.. py:function:: ticks_us()
Return processor ticks (converted to microseconds) since Pycardium startup.
This function should be the preferred method for timing and profiling
because it does not need an API call and thus is very fast.
.. versionadded:: 1.13
.. py:function:: unix_time()
Return the current unix time as seconds since the epoch.
.. versionadded:: 1.12
.. py:function:: unix_time_ms()
Return the current unix time as milliseconds since the epoch.
.. versionadded:: 1.12
.. py:function:: set_time(secs)
Sets the time to ``secs`` seconds since 2000-01-01 00:00 in the local
timezone.
.. versionchanged:: 1.4
:py:func:`utime.set_time` previously applied a wrong timezone offset,
thus leading to wrong results.
.. py:function:: set_time_ms(msecs)
Set the time to ``msecs`` seconds since 2000-01-01 00:00 in the local
timezone.
.. versionadded:: 1.12
.. py:function:: set_unix_time(secs)
Sets the time to ``secs`` seconds since 1970-01-01 00:00 UTC.
......@@ -40,6 +101,12 @@ alarm.
by running ``date +%s`` in a command line or ``int(time.time())``
in Python.
.. py:function:: set_unix_time_ms(msecs)
Set the time to ``msecs`` milliseconds since the unix epoch.
.. versionadded:: 1.12
.. py:function:: localtime([secs])
Return the current time as a timestruct tuple. If ``secs`` is given, return
......@@ -71,13 +138,13 @@ alarm.
.. code-block:: python
import utime
import time
def minute_timer(x):
current = utime.time()
current = time.time()
print("Current: " + str(current))
alarm = (current // 60 + 1) * 60
utime.alarm(alarm, minute_timer)
time.alarm(alarm, minute_timer)
minute_timer(None)
......@@ -86,13 +153,13 @@ alarm.
.. code-block:: python
import interrupt, utime
import interrupt, time
def 5_second_timer(x):
current = utime.time()
current = time.time()
print("Current: " + str(current))
alarm = (current // 10) * 10 + 5
utime.alarm(alarm)
time.alarm(alarm)
# This time, we need to register and enable the callback manually
interrupt.set_callback(interrupt.RTC_ALARM, 5_second_timer)
......
.. 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.
**Example**
.. code-block:: python
import color, time, ws2812, gpio
gpio.set_mode(gpio.WRISTBAND_2, gpio.mode.OUTPUT)
i = 0
while True:
col1 = color.from_hsv(i % 360, 1.0, 0.1)
col2 = color.from_hsv((i + 20) % 360, 1.0, 0.1)
col3 = color.from_hsv((i + 40) % 360, 1.0, 0.1)
ws2812.set_all(gpio.WRISTBAND_2, [col1, col2, col3])
i += 1
time.sleep_ms(10)
.. versionadded:: 1.10
Documentation/static/bhi160-coordinates.png

324 KiB

.. _usb_file_transfer:
USB File Transfer
=================
The card10 badge bootloader offers a USB Mass Storage mode to access its 8MB external flash.
This flash contains a FAT32 filesystem and files on it will be visible to software running on the badge.
Getting to the USB mode
-----------------------
To get to the USB mode, you will need to boot the badge while keeping the bottom-right button pressed.
.. image:: static/bootloader-buttons.png
1. If the badge is on, hold the top-left (power) button until the sleep screen appears, then release.
2. Start holding the bottom-right button.
3. Quickly press and release the top-left (power) button to turn the badge on.
4. Your badge should now be in file transfer mode, and you can then release the bottom-right button.
If you succesfully got into USB File Transfer mode, the screen will display its version and notify about the USB mode by displaying ``USB activated. Ready.``. If you connect the badge via USB to your computer, it should now detect 8MB of flash storage that you can mount in the same way as a pendrive.
This pendrive can contain multiple files with different functions, some of them outlined here:
============== ========
File name Function
============== ========
``card10.bin`` Firmware update file for the badge. If this file is present, the bootloader will perform an internal update to boot from this firmware file, then it will be deleted.
``main.py`` This file contains the default `application` to be run on power on.
``menu.py`` This file contains the default `menu` to be run when the power button is short-pressed.
``*.py`` These are application files written in (Micro)Python that can be run from the menu.
``*.elf`` These are :ref:`l0dables` that can be run from the menu.
============== ========
Updating files and rebooting
----------------------------
No matter which file you are writing, the bootloader will display a red ``Writing`` status message while write operations are pending. Please wait until it displays ``Ready`` again before resetting the badge by pressing the power button again.
......@@ -6,31 +6,17 @@
#include "gfx.h"
#include "display.h"
/*
* "Decompress" splash-screen image. The algorithm works as follows:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
static void bootloader_display_splash(void)
{
int idx = 0;
Color white = gfx_color(&display_screen, WHITE);
Color black = gfx_color(&display_screen, BLACK);
for (int i = 0; i < sizeof(splash); i++) {
Color color = (splash[i] & 0x80) ? white : black;
uint8_t length = splash[i] & 0x7f;
for (int j = 0; j < length; j++) {
uint16_t x = idx % 160;
uint16_t y = idx / 160;
gfx_setpixel(&display_screen, x, y, color);
idx++;
}
}
gfx_copy_region_rle_mono(
&display_screen,
0,
0,
160,
80,
sizeof(splash),
(const void *)(splash)
);
gfx_update(&display_screen);
}
......@@ -55,6 +41,21 @@ void bootloader_display_header(void)
bootloader_display_line(2, CARD10_VERSION, white);
}
void bootloader_display_error(char *errtype, char *line1, char *line2)
{
gfx_clear(&display_screen);
Color red = gfx_color(&display_screen, RED);
Color yellow = gfx_color(&display_screen, YELLOW);
Color white = gfx_color(&display_screen, WHITE);
bootloader_display_line(0, "[FATAL ERROR]", red);
bootloader_display_line(1, errtype, yellow);
bootloader_display_line(2, CARD10_VERSION, white);
bootloader_display_line(3, line1, white);
bootloader_display_line(4, line2, white);
}
/*
* Display a line of text on the display.
*/
......
......@@ -5,6 +5,7 @@
/* Display */
void bootloader_display_init(void);
void bootloader_display_header(void);
void bootloader_display_error(char *errtype, char *line1, char *line2);
void bootloader_display_line(int line, char *string, uint16_t color);
/* USB */
......
......@@ -6,8 +6,12 @@ BIN1="$2"
BIN2="$3"
BINOUT="$4"
dd if=/dev/zero ibs=1k count=448 2>/dev/null | LANG=C LC_CTYPE=C tr "\000" "\377" > "$BINOUT"
dd if="$BIN1" of="$BINOUT" conv=notrunc 2>/dev/null
dd if="$BIN2" >> "$BINOUT" 2>/dev/null
if [ "$(stat -c "%s" "${BIN1}")" -gt 589824 ]; then
echo "$0: ${BIN1} is too big to fit!" >&2
exit 1
fi
objcopy -I binary -O binary --pad-to=589824 --gap-fill=255 "${BIN1}" "$BINOUT"
cat "$BIN2" >>"$BINOUT"
"$PYTHON" "$(dirname "$0")/crc_patch.py" "$BINOUT"
#!/usr/bin/env python3
import sys
import crc16
import warnings
warnings.simplefilter("ignore")
try:
import crc16
crcfun = crc16.crc16xmodem
except ImportError:
try:
import crcmod
crcfun = crcmod.predefined.mkCrcFun("xmodem")
except ImportError:
try:
import crcelk
crcfun = crcelk.CRC_XMODEM.calc_bytes
except ImportError:
raise Exception(
"Could not find a CRC implementation. Tried: crc16, crcmod, crcelk."
)
def main():
data = open(sys.argv[1], 'rb').read()
crc = crc16.crc16xmodem(data)
data = open(sys.argv[1], "rb").read()
crc = crcfun(data)
# print(crc)
padded = data + bytes([crc >> 8, crc & 0xFF])
crc = crc16.crc16xmodem(padded)
crc = crcfun(padded)
# print(crc)
open(sys.argv[1], 'wb').write(padded)
open(sys.argv[1], "wb").write(padded)
if __name__ == "__main__":
......
......@@ -179,6 +179,9 @@ void flash_partition(void)
data); /* wild cast. not sure if this works */
if (ret != E_NO_ERROR) {
printf("FLC_Write failed with %d\n", ret);
bootloader_display_error(
"Firmware Write", "Firmware not", "updated."
);
while (1)
;
}
......
......@@ -4,7 +4,9 @@ set -xe
cd "$(dirname "$0")"
test -d build/ && rm -r build/
git submodule update --init ./lib/micropython
# Get external libs (MicroPython, tiny-AES-c, SHA256)
git submodule deinit --all
git submodule update --init ./lib
meson --cross-file card10-cross.ini build/ "$@"
set +x
......
......@@ -6,7 +6,7 @@ strip = 'arm-none-eabi-strip'
[properties]
c_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference']
c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs']
c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs', '-Wl,-wrap,BbBleDrvRand']
target_defs = ['-DTARGET=32665', '-DTARGET_REV=0x4131', '-DBOARD_CARD10=1']
......
......@@ -18,6 +18,7 @@ in stdenv.mkDerivation rec {
bash
crc16
gcc-arm-embedded
git
meson
ninja
py
......@@ -42,10 +43,13 @@ in stdenv.mkDerivation rec {
meson --cross-file card10-cross.ini "$build"
ninja -C "$build" -j $NIX_BUILD_CORES
# Copy artifacts to derivation outputs.
install -D -m 444 "$build/bootloader/bootloader.elf" -t "$out/bootloader"
install -D -m 444 "$build/pycardium/pycardium_epicardium.bin" -t "$out/pycardium"
install -D -m 444 "$build/epicardium/epicardium.elf" -t "$out/epicardium"
install -D -m 444 "$build/pycardium/pycardium.elf" -t "$out/pycardium"
# Copy ELFs for debugging
install -D -m 444 "$build/bootloader/bootloader.elf" -t "$out/lib/bootloader.elf"
install -D -m 444 "$build/epicardium/epicardium.elf" -t "$out/lib/epicardium.elf"
install -D -m 444 "$build/pycardium/pycardium.elf" -t "$out/lib/pycardium.elf"
# Create new flash contents
install -D -m 444 "$build/pycardium/pycardium_epicardium.bin" "$out/card10/card10.bin"
install -m 444 preload/*.py -t $out/card10/
cp -ar preload/apps $out/card10/
'';
}
import ws2812, gpio, bluetooth, time, display
from micropython import const
_IRQ_GATTS_WRITE = const(3)
WS2812_SERVICE_UUID = \
bluetooth.UUID("23238000-2342-2342-2342-234223422342")
SET_ALL = (
bluetooth.UUID("23238001-2342-2342-2342-234223422342"),
bluetooth.FLAG_WRITE
)
WS2812_SERVICE = (
WS2812_SERVICE_UUID,
(SET_ALL,)
)
def irq(event, data):
if event == _IRQ_GATTS_WRITE:
conn_handle, value_handle = data
value = ble.gatts_read(value_handle)
ws2812.set_all(gpio.WRISTBAND_3, [value] * 3)
if __name__ == "__main__":
display.open().backlight(0)
gpio.set_mode(gpio.WRISTBAND_3, gpio.mode.OUTPUT)
ble = bluetooth.BLE()
ble.active(True)
ble.irq(irq)
ble.gatts_register_services((WS2812_SERVICE,))
print("Waiting for connection!")
while True:
time.sleep(1)
#!/usr/bin/env python3
import bluepy
import time
import colorsys
# Change this to the MAC of your card10
p = bluepy.btle.Peripheral("CA:4D:10:01:ff:64")
c = p.getCharacteristics(
uuid='23238001-2342-2342-2342-234223422342')[0]
hue = 0
while 1:
r,g,b = colorsys.hsv_to_rgb(hue, 1, 0.1)
c.write(b"%c%c%c" %
(int(r*255), int(g*255), int(b*255)), True)
time.sleep(.1)
hue += 0.1