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
Select Git revision

Target

Select target project
  • flow3r/flow3r-firmware
  • Vespasian/flow3r-firmware
  • alxndr42/flow3r-firmware
  • pl/flow3r-firmware
  • Kari/flow3r-firmware
  • raimue/flow3r-firmware
  • grandchild/flow3r-firmware
  • mu5tach3/flow3r-firmware
  • Nervengift/flow3r-firmware
  • arachnist/flow3r-firmware
  • TheNewCivilian/flow3r-firmware
  • alibi/flow3r-firmware
  • manuel_v/flow3r-firmware
  • xeniter/flow3r-firmware
  • maxbachmann/flow3r-firmware
  • yGifoom/flow3r-firmware
  • istobic/flow3r-firmware
  • EiNSTeiN_/flow3r-firmware
  • gnudalf/flow3r-firmware
  • 999eagle/flow3r-firmware
  • toerb/flow3r-firmware
  • pandark/flow3r-firmware
  • teal/flow3r-firmware
  • x42/flow3r-firmware
  • alufers/flow3r-firmware
  • dos/flow3r-firmware
  • yrlf/flow3r-firmware
  • LuKaRo/flow3r-firmware
  • ThomasElRubio/flow3r-firmware
  • ai/flow3r-firmware
  • T_X/flow3r-firmware
  • highTower/flow3r-firmware
  • beanieboi/flow3r-firmware
  • Woazboat/flow3r-firmware
  • gooniesbro/flow3r-firmware
  • marvino/flow3r-firmware
  • kressnerd/flow3r-firmware
  • quazgar/flow3r-firmware
  • aoid/flow3r-firmware
  • jkj/flow3r-firmware
  • naomi/flow3r-firmware
41 results
Select Git revision
Show changes
Showing
with 861 additions and 304 deletions
License
=======
The Flow3r badge firmware is Copyright (c) 2023 to the Flow3r Badge Authors. For
the purposes of copyright, the Authors are assumed to be the people who have
directly contributed to the git repository of the Flow3r badge firmware.
The Flow3r badge firmware is licensed under the GNU Lesser General Public
License 3.0.
The firmware also incorporates numerous third-party work. A list of incorporated
work and license terms under which the work has been incorporated into the
Flow3r badge firmware follow.
Firmware
--------
* `GC9A01 Library <https://github.com/liyanboy74/gc9a01-esp-idf>`_ library, Copyright (c) 2021, liyanboy74 and licensed under 3-clause BSD license.
* `stb_image <https://github.com/nothings/stb>`_ library, Copyright (c) 2017 Sean Barrett, and licensed under the MIT License.
* `ctx <https://ctx.graphics/>`_ library, Copyright (c) 2002, 2012, 2015, 2019, 2020 Øyvind Kolås <pippin@gimp.org>, and licensed under the LGPL 3.0 License.
* Roboto font, Copyright (c) 2014 Christian Robertson, and licensed under the Apache License 2.0.
* Cousine Regular font, Copyright (c) 2013 Steve Matteson, and licensed under the Apache License 2.0.
* TinyUSB library, Copyright (c) 2018, hathach (tinyusb.org), and licensed under the MIT License.
* BMI270 Library, Copyright (c) 2023 Bosch Sensortec GmbH., and licensed under the 3-clause BSD license.
* BMP581 Library, Copyright (c) 2022 Bosch Sensortec GmbH., and licensed under the 3-clause BSD license.
* Micropython, Copyright (c) 2014-2023 Damien P. George, and licensed under the MIT License.
* `ESP-IDF <https://github.com/espressif/esp-idf/tree/3befd5fff72aa6980514454a50233037718b611f>`_ library, Copyright (C) Copyright (C) 2015-2022 Espressif Systems, is licensed under `Apache License 2.0 <https://www.apache.org/licenses/LICENSE-2.0>`_.
* `Newlib`_ is licensed under the BSD License and is Copyright of various parties, as described in `COPYING.NEWLIB <https://github.com/bminor/newlib/blob/master/COPYING.NEWLIB>`_.
* `Xtensa header files` are Copyright (C) 2013 Tensilica Inc and are licensed under the MIT License as reproduced in the individual header files.
* Original parts of FreeRTOS_ (components/freertos) are Copyright (C) 2017 Amazon.com, Inc. or its affiliates are licensed under the MIT License, as described in `LICENSE.md <https://github.com/espressif/esp-idf/blob/master/components/freertos/FreeRTOS-Kernel/LICENSE.md>`_.
* Original parts of LWIP_ (components/lwip) are Copyright (C) 2001, 2002 Swedish Institute of Computer Science and are licensed under the BSD License as described in `COPYING <https://github.com/espressif/esp-idf/blob/master/components/freertos/FreeRTOS-Kernel/LICENSE.md>`_.
* `wpa_supplicant`_ Copyright (c) 2003-2005 Jouni Malinen and licensed under the BSD license.
* `FreeBSD net80211`_ Copyright (c) 2004-2008 Sam Leffler, Errno Consulting and licensed under the BSD license.
* `argtable3`_ argument parsing library Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann and licensed under 3-clause BSD license. argtable3 also includes the following software components. For details, please see argtable3 `LICENSE <https://github.com/espressif/esp-idf/blob/3befd5fff7/components/console/argtable3/LICENSE>`.
* C Hash Table library, Copyright (c) 2002, Christopher Clark and licensed under 3-clause BSD license.
* The Better String library, Copyright (c) 2014, Paul Hsieh and licensed under 3-clause BSD license.
* TCL library, Copyright the Regents of the University of California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState Corporation and other parties, and licensed under TCL/TK License.
* `linenoise`_ line editing library Copyright (c) 2010-2014 Salvatore Sanfilippo, Copyright (c) 2010-2013 Pieter Noordhuis, licensed under 2-clause BSD license.
* `FatFS`_ library, Copyright (C) 2017 ChaN, is licensed under `a BSD-style license <https://github.com/espressif/esp-idf/blob/3befd5fff7/components/console/argtable3/LICENSE>`_.
* `cJSON`_ library, Copyright (c) 2009-2017 Dave Gamble and cJSON contributors, is licensed under MIT license as described in `LICENSE <https://github.com/espressif/esp-idf/blob/3befd5fff7/components/console/argtable3/LICENSE>`_.
* `micro-ecc`_ library, Copyright (c) 2014 Kenneth MacKay, is licensed under 2-clause BSD license.
* `Mbed TLS`_ library, Copyright (C) 2006-2018 ARM Limited, is licensed under Apache License 2.0 as described in `Mbed TLS LICENSE file <https://github.com/espressif/mbedtls/blob/65b3c08/LICENSE>`_.
* `SPIFFS`_ library, Copyright (c) 2013-2017 Peter Andersson, is licensed under MIT license as described in `SPIFFS LICENSE file <https://github.com/pellepl/spiffs/blob/0dbb3f7/LICENSE>`_.
* `SD/MMC driver` is derived from `OpenBSD SD/MMC driver`_, Copyright (c) 2006 Uwe Stuehler, and is licensed under BSD license.
* `ESP-MQTT <mqtt>` MQTT Package (contiki-mqtt) - Copyright (c) 2014, Stephen Robinson, MQTT-ESP - Tuan PM <tuanpm at live dot com> is licensed under Apache License 2.0 as described in `ESP-MQTT LICENSE file <https://github.com/espressif/esp-mqtt/blob/dffabb0/LICENSE>`_.
* `BLE Mesh <bt/esp_ble_mesh>` is adapted from Zephyr Project, Copyright (c) 2017-2018 Intel Corporation and licensed under Apache License 2.0
* `mynewt-nimble`_ Apache Mynewt NimBLE, Copyright 2015-2018, The Apache Software Foundation, is licensed under Apache License 2.0 as described in `mynewt-nimble LICENSE file <https://github.com/espressif/esp-mqtt/blob/dffabb0/LICENSE>`_.
* `TLSF allocator <https://github.com/espressif/tlsf>`_ Two Level Segregated Fit memory allocator, Copyright (c) 2006-2016, Matthew Conte, and licensed under the BSD 3-clause license.
* `openthread`, Copyright (c) The OpenThread Authors, is licensed under BSD License as described in `openthread LICENSE file <https://github.com/espressif/openthread/blob/5beae14/LICENSE>`_.
* `UBSAN runtime` — Copyright (c) 2016, Linaro Limited and Jiří Zárevúcky, licensed under the BSD 2-clause license.
* `HTTP Parser <http_parser>`_ Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev. Additional changes are licensed under the same terms as NGINX and Joyent, Inc. and other Node contributors. For details please check `http_parser LICENSE file <https://github.com/espressif/esp-idf/blob/3befd5fff7/components/http_parser/LICENSE.txt>`_.
* `SEGGER SystemView`_ target-side library, Copyright (c) 1995-2021 SEGGER Microcontroller GmbH, is licensed under BSD 1-clause license.
Xtensa libhal MIT License
^^^^^^^^^^^^^^^^^^^^^^^^^
Copyright (c) 2003, 2006, 2010 Tensilica Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
TinyBasic Plus MIT License
^^^^^^^^^^^^^^^^^^^^^^^^^^
Copyright (c) 2012-2013
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
TJpgDec License
^^^^^^^^^^^^^^^
TJpgDec - Tiny JPEG Decompressor R0.01 (C)ChaN, 2011
The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.
This is a free software that opened for education, research and commercial
developments under license policy of following terms.
Copyright (C) 2011, ChaN, all right reserved.
* The TJpgDec module is a free software and there is NO WARRANTY.
* No restriction on use. You can use, modify and redistribute it for personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
* Redistributions of source code must retain the above copyright notice.
.. _Newlib: https://sourceware.org/newlib/
.. _FreeRTOS: https://freertos.org/
.. _esptool.py: https://github.com/espressif/esptool
.. _LWIP: https://savannah.nongnu.org/projects/lwip/
.. _TinyBasic: https://github.com/BleuLlama/TinyBasicPlus
.. _miniz: https://code.google.com/archive/p/miniz/
.. _wpa_supplicant: https://w1.fi/wpa_supplicant/
.. _FreeBSD net80211: https://github.com/freebsd/freebsd-src/tree/master/sys/net80211
.. _TJpgDec: http://elm-chan.org/fsw/tjpgd/00index.html
.. _argtable3: https://github.com/argtable/argtable3
.. _linenoise: https://github.com/antirez/linenoise
.. _fatfs: http://elm-chan.org/fsw/ff/00index_e.html
.. _cJSON: https://github.com/DaveGamble/cJSON
.. _micro-ecc: https://github.com/kmackay/micro-ecc
.. _OpenBSD SD/MMC driver: https://github.com/openbsd/src/blob/f303646/sys/dev/sdmmc/sdmmc.c
.. _Mbed TLS: https://github.com/Mbed-TLS/mbedtls
.. _spiffs: https://github.com/pellepl/spiffs
.. _asio: https://github.com/chriskohlhoff/asio
.. _mqtt: https://github.com/espressif/esp-mqtt
.. _zephyr: https://github.com/zephyrproject-rtos/zephyr
.. _mynewt-nimble: https://github.com/apache/mynewt-nimble
.. _ESP-IDF Programming Guide: https://docs.espressif.com/projects/esp-idf/en/latest/
.. _sphinx_idf_theme: https://github.com/espressif/sphinx_idf_theme
.. _sphinx_rtd_theme: https://github.com/readthedocs/sphinx_rtd_theme
.. _SEGGER SystemView: https://www.segger.com/downloads/systemview/
.. include:: <isonum.txt>
Modifications
=============
Documentation of some hardware modifications and addons for the badge.
Improved Power Switch
---------------------
With a few simple steps the Flow3rs power switch can be improved to protect it
from damage and make it easier operate.
.. image:: assets/pwr_swtch_mod.png
1. Print switch cap
^^^^^^^^^^^^^^^^^^^
Download the `power_switch.stl <https://git.flow3r.garden/flow3r/flow3r-
hardware/-/raw/main/mechanical/STLs/power_switch.stl>`_ from the flow3r
hardware repo and print it on a 3d printer. The part is simple and does not
require special printer settings. On a regular FDM printer it should only take
a couple of minutes.
2a. Modify spacer
^^^^^^^^^^^^^^^^^
To make space for the printed switch the original spacer needs to modified.
Increase the height of the switch gap in the spacer by shaving of about 0.5mm
with an exacto knife or sand it of with the included piece of sand paper.
Remove the material marked red in the image:
.. image:: assets/pwr_swtch_mod_grind.png
2b. Alternative: Print New Spacer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There is also a new model of the spacer with a large enough gap for the switch
cap. The latest version can be downloaded from the project repository:
`spacer.stl <https://git.flow3r.garden/flow3r/flow3r-hardware/-/raw/main/
mechanical/STLs/spacer.stl>`_
When printing on FDM best results can be archived by orienting the side with
the LED pockets towards the print bed and adding a cylindrical support enforcer
(d=55mm) for the central bracing with no other autogenerated support like this:
.. image:: assets/fdm_print_prep.png
3. Assembly
^^^^^^^^^^^
Simply snap the printed switch cap onto the Flow3rs power switch and reassemble
the badge.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="64.55027mm"
height="36.421959mm"
viewBox="0 0 64.55027 36.421959"
version="1.1"
id="svg720"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="overview.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview722"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.2753006"
inkscape:cx="105.92007"
inkscape:cy="122.84091"
inkscape:window-width="1918"
inkscape:window-height="1058"
inkscape:window-x="0"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs717">
<marker
style="overflow:visible"
id="TriangleStart"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="TriangleStart"
markerWidth="5.3244081"
markerHeight="6.155385"
viewBox="0 0 5.3244081 6.1553851"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-59.920887,-54.501301)">
<g
id="g616"
transform="translate(26.129445,-9.0815132)"
style="display:inline">
<g
id="g606"
transform="translate(-0.38132449,0.72602215)">
<g
id="g500"
transform="translate(0.02990985)">
<circle
style="fill:#000000;stroke:none;stroke-width:11.9081;stroke-linecap:round;stroke-linejoin:round;paint-order:fill markers stroke"
id="path482"
cx="67.483925"
cy="78.054527"
r="1.0715659" />
<circle
style="fill:#000000;stroke:none;stroke-width:11.9081;stroke-linecap:round;stroke-linejoin:round;paint-order:fill markers stroke"
id="circle484"
cx="42.890316"
cy="78.054527"
r="1.0715659" />
</g>
<path
id="path418"
style="fill:#ffffff;stroke:#000000;stroke-width:0.531681;stroke-linecap:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="m 55.199604,70.203727 v 0.0198 c -1.236491,0.67721 -1.868042,1.51366 -2.22056,2.42387 -1.684113,-0.74442 -3.754653,-0.90875 -5.935231,-0.9075 -0.816715,2.06807 -1.267884,4.05285 -1.019886,5.87807 l -4.050146,1.12649 2.446957,3.30529 c -1.160632,1.67076 -1.916976,3.38436 -2.344748,5.1324 1.680993,1.9774 3.338659,2.40161 4.999419,3.03988 l 0.05138,3.93969 3.878425,-1.3625 c 1.07327,1.65112 2.353337,3.10897 4.211425,4.02678 l 0.01151,0.19914 -0.01044,-0.19914 c 1.858087,-0.91781 3.13788,-2.37566 4.21115,-4.02678 l 3.878699,1.3625 0.05138,-3.93969 c 1.660759,-0.63827 3.318426,-1.06248 4.999418,-3.03988 -0.427771,-1.74804 -1.184389,-3.46164 -2.345022,-5.1324 l 2.446956,-3.30529 -4.04987,-1.12649 c 0.247998,-1.82522 -0.203446,-3.81 -1.020161,-5.87807 -2.180578,-7.9e-4 -4.250843,0.16308 -5.934956,0.9075 -0.352515,-0.9102 -0.984092,-1.74667 -2.22056,-2.42387 v -0.0198 c -0.006,0.003 -0.01157,0.006 -0.01758,0.01 -0.006,-0.003 -0.01153,-0.006 -0.01758,-0.01 z"
sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
<path
id="path420"
style="fill:#ff00e6;fill-opacity:1;stroke:#000000;stroke-width:0.531681;stroke-linecap:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="m 55.168083,68.658287 -0.04103,0.0415 c -2.189027,2.45158 -3.357679,5.37999 -4.068689,8.54874 -3.550635,-0.36029 -6.76352,0.0178 -9.575447,1.27266 1.693712,2.71028 3.87271,5.04078 6.959512,6.66059 -1.386735,3.06764 -1.815303,6.19395 -1.655118,9.35646 3.1461,-0.71873 6.045833,-2.21138 8.447582,-4.43975 v 0.0341 c 2.41314,2.25872 5.239788,3.68108 8.411591,4.40569 0.16018,-3.16252 -0.268386,-6.28882 -1.655125,-9.35647 3.086815,-1.61981 5.266085,-3.95031 6.959782,-6.66058 -2.811917,-1.25483 -6.024805,-1.63295 -9.575439,-1.27266 -0.710943,-3.16848 -1.928538,-6.10641 -4.117217,-8.55786 l 0.216804,0.26864 c -0.01431,0.0157 -0.244005,-0.31747 -0.258235,-0.30177 -0.01423,-0.0158 -0.415883,0.49361 -0.430183,0.47791 z m 0.0059,10.16625 c 2.326545,0 4.212568,1.88775 4.212518,4.21637 5.5e-5,2.32863 -1.885969,4.21638 -4.212518,4.21638 -2.326552,0 -4.212582,-1.88775 -4.212527,-4.21638 -5e-5,-2.32862 1.885978,-4.21637 4.212527,-4.21637 z"
sodipodi:nodetypes="cccccccccccccccccscscs" />
</g>
<circle
style="fill:#000000;stroke:none;stroke-width:2.432;stroke-linecap:round;stroke-linejoin:round;paint-order:fill markers stroke"
id="path502"
cx="54.835705"
cy="83.910004"
r="4.3151007" />
</g>
<path
d="m 89.119148,58.972994 -0.600756,-0.346933 v 0.247485 h -3.070636 l 0.597888,-0.631672 c 0.05088,-0.04078 0.117457,-0.06939 0.185941,-0.07098 0.277044,0 0.441566,-7.3e-5 0.502126,-1.91e-4 0.04106,0.116952 0.151314,0.201369 0.282398,0.201369 0.165831,0 0.300409,-0.134567 0.300409,-0.300457 0,-0.165962 -0.134566,-0.30048 -0.300409,-0.30048 -0.131084,0 -0.241349,0.08437 -0.282398,0.201225 l -0.496242,-8.7e-5 c -0.134496,0 -0.275424,0.07379 -0.365123,0.160296 0.0024,-0.0026 0.005,-0.0053 -1.45e-4,5e-5 -0.0019,0.0022 -0.634339,0.670116 -0.634339,0.670116 -0.05077,0.04073 -0.117313,0.06916 -0.185749,0.07079 h -0.347364 c -0.04604,-0.22948 -0.248685,-0.40237 -0.491764,-0.40237 -0.27714,0 -0.501789,0.22465 -0.501789,0.501706 0,0.27714 0.224649,0.501801 0.501789,0.501801 0.243127,0 0.445768,-0.173034 0.491813,-0.402702 h 0.341278 c 9.33e-4,0 0.0018,5e-5 0.0026,0 h 0.754845 c 0.0683,0.0018 0.134758,0.03021 0.185485,0.07098 0,0 0.632297,0.667932 0.634255,0.670093 0.005,0.0053 0.0025,0.0026 4.9e-5,4.9e-5 0.0897,0.08649 0.230689,0.160236 0.365206,0.160236 l 0.478234,-1.09e-4 v 0.201428 h 0.600911 v -0.60085 h -0.600919 v 0.201165 c 0,0 -0.125957,-2.27e-4 -0.484092,-2.27e-4 -0.06849,-0.0016 -0.135142,-0.03015 -0.186001,-0.07093 L 86.198629,59.072 h 2.319717 v 0.247881 z"
id="path1334"
style="display:inline;stroke-width:0.0120063" />
<g
id="g1783"
transform="matrix(-1.3247758,0,0,1.3859201,146.89863,-29.594124)"
style="display:inline">
<path
style="fill:none;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 60.645092,68.93931 c 0.606809,0.341612 0.879433,0.826722 1.069303,1.347362"
id="path1777"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 59.342533,68.471927 c -0.676405,-0.165504 -1.207007,0.0022 -1.7015,0.252365"
id="path1779"
sodipodi:nodetypes="cc" />
<path
style="fill:#000000;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 60.29165,67.877846 -0.559934,1.626428"
id="path1781"
sodipodi:nodetypes="cc" />
</g>
<g
id="g1839"
transform="matrix(0.01636068,0,0,0.01636068,102.04507,68.911599)"
style="display:inline">
<path
d="M 0,87.7 C 0,39.2 39.2,0 87.7,0 v 0 15 15 c -16,0 -30.3,6.4 -40.8,16.9 v 0 C 36.4,57.4 30,71.7 30,87.7 v 0 c 0,16 6.4,30.3 16.9,40.8 v 0 c 10.5,10.5 24.8,16.9 40.8,16.9 v 0 c 16,0 30.3,-6.4 40.8,-16.9 v 0 C 139,118 145.4,103.7 145.4,87.7 v 0 c 0,-16 -6.4,-30.3 -16.9,-40.8 v 0 C 118,36.4 103.6,30 87.7,30 V 30 15 0 c 48.4,0 87.7,39.2 87.7,87.7 v 0 c 0,48.4 -39.2,87.7 -87.7,87.7 v 0 C 39.2,175.3 0,136.1 0,87.7 Z"
id="path1829" />
<path
d="m 72.7,115.4 v -55 c 0,-8.3 6.7,-15 15,-15 v 0 c 8.3,0 15,6.7 15,15 v 0 55 c 0,8.3 -6.7,15 -15,15 v 0 c -8.3,0 -15,-6.8 -15,-15 z"
id="path1831" />
</g>
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="m 101.17441,70.982205 -8.155099,2.921322"
id="path1841"
sodipodi:nodetypes="cc" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:0.143579;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="m 81.074142,59.61063 0.603905,-0.747465 1.60339,-0.02544"
id="path2442"
sodipodi:nodetypes="ccc" />
<g
id="g2604"
transform="matrix(1.3247758,0,0,1.3859201,15.099532,-29.594124)"
style="display:inline">
<path
style="fill:none;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 60.645092,68.93931 c 0.606809,0.341612 0.879433,0.826722 1.069303,1.347362"
id="path2598"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 59.342533,68.471927 c -0.676405,-0.165504 -1.207007,0.0022 -1.7015,0.252365"
id="path2600"
sodipodi:nodetypes="cc" />
<path
style="fill:#000000;stroke:#000000;stroke-width:0.160515;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#TriangleStart);paint-order:fill markers stroke"
d="m 60.29165,67.877846 -0.559934,1.626428"
id="path2602"
sodipodi:nodetypes="cc" />
</g>
<text
xml:space="preserve"
style="font-size:2.84336px;line-height:1.25;font-family:Questrial;-inkscape-font-specification:Questrial;letter-spacing:0px;word-spacing:0px;display:inline;stroke-width:0.0710842"
x="89.972633"
y="60.106968"
id="text2662"><tspan
sodipodi:role="line"
id="tspan2660"
style="stroke-width:0.0710842"
x="89.972633"
y="60.106968">USB-C</tspan></text>
<text
xml:space="preserve"
style="font-size:2.94636px;line-height:1.25;font-family:Questrial;-inkscape-font-specification:Questrial;letter-spacing:0px;word-spacing:0px;display:inline;stroke-width:0.0736593"
x="105.82865"
y="71.32"
id="text2666"><tspan
sodipodi:role="line"
id="tspan2664"
style="stroke-width:0.0736593"
x="105.82865"
y="71.32">ON/OFF</tspan></text>
<g
id="g3507"
style="display:inline;fill:#73ff00;fill-opacity:1"
transform="translate(33.017306,-1.2411252)">
<g
id="g3012"
style="fill:#ff00e6;fill-opacity:1" />
</g>
</g>
</svg>
.. _programming:
Programming
===========
*NOTE: this is about programming your own apps/instruments/toys while keeping the badge firmware stock. If you want to port Doom or work on the firmware, see the Firmware Development section.*
The main programming interface and language for the flow3rbadge is Python. More
exactly, it's `Micropython <https://micropython.org/>`_, which is a fairly
sizeable subset of Python that can run on microcontrollers.
Good news: if you've ever used Micropython on an ESP32, then you probably
already have all the tools required to get started. However, while the tools to
program the badge might be the same as for stock Micropython on ESP32, our APIs
are quite different.
If you haven't used Micrpython, don't worry. It's not that difficult other than
wrapping your head around file access.
The :ref:`st3m` framework is the main Python codebase you'll be writing against.
Instead of using standard Micropython libraries like ``machine`` or low level
display drivers, you'll be writing applications that implement st3m classes like
:py:class:`Responder` or :py:class:`Application`.
But, enough intro for now, let's get started.
Accessing the badge
-------------------
When the badge runs (for example, when you see the main menu), you can connect
it to a PC and it should appear as a serial device. On Linux systems, this
device will be usually called ``/dev/ttyACM0`` (sometimes ``/dev/ttyACM1``).
You can then use any terminal emulator program (like picocom, GNU screen, etc)
to access the badge's runtime logs. Even better, use a dedicated
micropython-specific program, as that will actually let you transfer files.
These are the tools we've tested and are known to work:
+---------------+-----------------------+
| Tool | Platforms |
+===============+=======================+
| mpremote_ | Linux, macOS, Windows |
+---------------+-----------------------+
| `Micro REPL`_ | Android |
+---------------+-----------------------+
.. _mpremote: https://docs.micropython.org/en/latest/reference/mpremote.html
.. _`Micro REPL`: https://github.com/Ma7moud3ly/micro-repl
In the rest of these docs we'll use mpremote. But you should be able to follow
along with any of the aforementioned tools. If you are on Linux and your flow3r
came up as ``/dev/ttyACM1``, add an ``a1`` after ``mprempote``.
After connecting your badge and making sure it runs:
::
$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell
[... logs here... ]
The badge will continue to run. Now, if you press Ctrl-C, you will interrupt the
firmware and break into a Python REPL (read-eval-print-loop) prompt:
::
Traceback (most recent call last):
File "/flash/sys/main.py", line 254, in <module>
[... snip ...]
KeyboardInterrupt:
MicroPython c48f94151-dirty on 1980-01-01; badge23 with ESP32S3
Type "help()" for more information.
>>>
The badge's display will now switch to 'In REPL' to indicate that software
execution has been interrupted and that the badge is waiting for a command over
REPL.
Congratulations! You can now use your badge as a calculator:
::
>>> 5 + 5
10
But that's not super interesting. Let's try to turn on some LEDs:
::
>>> import leds
>>> leds.set_rgb(0, 255, 0, 0)
>>> leds.update()
The LED right next to the USB connector should light up red. You can continue
experimenting with different APIs (like :py:mod:`leds`, :py:mod:`audio`, etc).
Transferring files over REPL
----------------------------
You can also access the filesystem over the same Micropython serial port:
::
$ mpremote
MicroPython c48f94151-dirty on 1980-01-01; flow3r with ESP32S3
Type "help()" for more information.
>>> import os
>>> os.listdir('/')
['flash']
>>> os.listdir('/flash/sys')
['main.py', 'st3m', '.sys-installed']
>>>
$ mpremote ls :flash/sys
ls :flash/sys
0 main.py
0 st3m
0 .sys-installed
.. _disk mode:
Disk Mode
---------
For larger file transfers (eg. images, sound samples, etc.) you can put the
badge into Disk Mode by selecting ``Settings -> Disk Mode`` in the badge's menu.
You can then select whether to mount the 10MiB internal flash or SD card (if
present) as a pendrive. The selected device will then appear as a pendrive on
your system, and will stay until it is ejected. The serial connection will
disconnect for the duration of the badge being in disk mode.
Disk Mode can also be enabled when the badge is in :ref:`Recovery mode`.
Writing Applications
--------------------
Once you feel some familiary with the REPL, you're ready to advance to the next
chapter: writing full-fledged applications that can draw graphics on the screen,
respond to input and play sound!
For that, continue with :ref:`application_programming`.
\ No newline at end of file
Troubleshooting
---------------
*This page assumes that you're running the latest stable firmware. As such, we
suggest ensuring that you're on latest firmware before proceeding with
troubleshooting.*
Captouch doesn't work properly
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If petal presses are not registered or fake inputs occur randomly, recalibrate
the captouch driver in `System -> Settings -> Captouch Calibrator`. You can
visualize with `captouch demo` how your current calibration performs. Having a
USB cable or audio cables connected has slight influence on calibration, this
is usually negligible but if you don't reach satisfactory results it might be
worthwhile to try remove all connections (except for USB, if you don't have a
battery installed) before calibration.
If you have issues with positional captouch, be aware that the top petals have
large deadzones. If you struggle with *sometimes* unresponsive scrolling behavior,
it is likely that you go too far away from the center of the petal. You can use
`captouch demo` or the testing screen of `Captouch Calibrator` to familiarize
yourself with the responsive range. This issue sadly cannot be fixed in software.
If this doesn't solve your problems, please open an issue in our `Issue Tracker
<https://git.flow3r.garden/flow3r/flow3r-firmware/-/issues>`_ so that we can have
a look and account for whatever we may find in a future release.
*Note that the system menu doesn't use captouch by default and that the screen
doesn't have captouch functionality. You can activate experimental hybrid
trackpad/button system menu captouch control with System -> Settings -> Touch OS.
Consult the help text of any system menu after activating it if its behavior
confuses you.*
updat3r fails
^^^^^^^^^^^^^
updat3r relies on a functional SD card, see SD card issues below for details.
Many old apps are tagged as "new"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is typically a bad stock SD card, see SD card issues below for details.
Copy all your files to a replacement except for `/user_data/app_settings.json`,
if this file does not exists all apps are registered as known. You can delete
it in the `fil3s` app too, but bad SD cards may result in the bug reoccuring.
SD card issues
^^^^^^^^^^^^^^
Sadly, some SD cards that flow3r shipped with do not work well with the driver.
Since many applications store their data on SD card this also means they might
run into issues (it's a random issue that occurs more with larger files so they
may appear to work just fine most of the time), it's best in this case to swap
to a different SD card.
*Note: We have found a potential pattern in the unreliable SD cards. You can check
the SD card status on the second page of System -> About. If our suspected pattern
matches, there will be a (Unreliable model) warning displayed above the storage
indicator.*
You can do so by carefully opening your badge and replacing the stock microSD
card with a new one, formatted as FAT32. We have used microSD cards of various
sizes without issues (16-256GB). Be careful not to overtighten the screws when
reassembling as this can rip the screw holders out of the PCB fairly easily!
You might want to prefill the `/music/` folder with your favorite .mp3 tunes
to use with the mp3 player app as file transfers via flow3r USB to the SD card
are much slower than card readers.
If you accidentially ripped off a screw holder it's possible to fix it with
some careful and patient soldering, we'll try to add a video guide soon!
*(If you do wanna try it beforehand: Be careful, it needs a lot of heat which
makes it easy to "swipe off" other tiny components that are harder to repair.
This is not a safe first soldering experience.)*
Volume control doesn't work
^^^^^^^^^^^^^^^^^^^^^^^^^^^
You probably have the `Show FPS` option enabled in the settings. This is primarily
a debug feature and blocks every other overlay since drawing them affects frame
rate negatively (including the FPS monitor). This behavior will probably be
improved in a future firmware release.
.. include:: <isonum.txt>
.. _updating_firmware:
Updating firmware
=================
Update via webflash
-------------------
If you have a web browser which supports WebSerial, you can connect your badge
to your computer then navigate to:
https://flow3r.garden/flasher/
Update via updat3r
------------------
Since firmware v1.3.0, there is a built-in wifi updater.
Ensure wifi is connected, and then go to Settings |rarr| Check For Updates and
follow the instructions.
Update via USB mass storage
---------------------------
Put your badge into SD Card Disk Mode: either by selecting 'Disk Mode (SD)'
from the badge's System menu, or by rebooting into Recovery Mode (by holding
down the right trigger) and selecting 'Disk Mode (SD)' from there.
Now, with the badge connected to a computer, you should see a USB Mass Storage
('pendrive') appear. Copy flow3r.bin from the release there.
Then, stop disk mode, and from the Recovery Mode (boot the badge with the right
trigger pushed down), select 'Flash Firmware Image', then flow3r.bin.
Update using esptool.py
-----------------------
You can also fully flash the badge from the commandline. To do that, start the
badge in bootloader mode (this is different from recovery mode!) by holding
down the left trigger while powering it up.
Extract the .bin files from a release tarball, and run esptool.py with the
following arguments:
::
esptool.py -p /dev/ttyACM0 -b 460800 \
--before default_reset --after no_reset --chip esp32s3 \
write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m \
0x0 bootloader.bin \
0x8000 partition-table.bin \
0x10000 recovery.bin \
0x90000 flow3r.bin \
-e
Usage
=====
TODO
\ No newline at end of file
import os import os
import sys import sys
import shutil import shutil
import subprocess
import time
# Configuration file for the Sphinx documentation builder. # Configuration file for the Sphinx documentation builder.
# #
...@@ -14,12 +16,21 @@ project = 'flow3r' ...@@ -14,12 +16,21 @@ project = 'flow3r'
copyright = '2023' copyright = '2023'
author = 'ccc' author = 'ccc'
# The full version, including alpha/beta/rc tags
release = (
subprocess.check_output(["git", "describe", "--tags", "--long", "--always"]).decode().strip()
)
release += "\n"
release += time.strftime("%F %R")
version = release
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [ extensions = [
'sphinx_rtd_theme', 'sphinx_rtd_theme',
'sphinx.ext.autodoc', 'sphinx.ext.autodoc',
'sphinx_multiversion',
] ]
templates_path = ['_templates'] templates_path = ['_templates']
...@@ -27,6 +38,8 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] ...@@ -27,6 +38,8 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
pygments_style = 'sphinx' pygments_style = 'sphinx'
maximum_signature_line_length = 120
# -- Options for HTML output ------------------------------------------------- # -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
...@@ -40,8 +53,29 @@ html_css_files = [ ...@@ -40,8 +53,29 @@ html_css_files = [
html_theme_options = { html_theme_options = {
'logo_only': True, 'logo_only': True,
'style_nav_header_background': "#000", 'style_nav_header_background': "#000",
'style_external_links': True,
}
# Show "Edit on GitLab" links
html_show_sourcelink = False
html_context = {
'display_gitlab': True,
'gitlab_host': "git.flow3r.garden",
'gitlab_user': "flow3r",
'gitlab_repo': "flow3r-firmware",
'gitlab_version': "main/",
'conf_py_path': "docs/",
'theme_vcs_pageview_mode': "edit",
} }
smv_tag_whitelist = r'$^'
smv_branch_whitelist = r'^v\d+\.\d+\.\d+$|^dev$'
if False:
# for local testing
smv_remote_whitelist = r'^origin$'
smv_branch_whitelist = r'^release/\d+\.\d+\.\d+$|^main$'
def setup(app): def setup(app):
tmpdir = "_build/mypystubs" tmpdir = "_build/mypystubs"
shutil.rmtree(tmpdir, ignore_errors=True) shutil.rmtree(tmpdir, ignore_errors=True)
......
...@@ -8,35 +8,71 @@ Welcome to flow3r's documentation! ...@@ -8,35 +8,71 @@ Welcome to flow3r's documentation!
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
:caption: The badge: :caption: User manual
badge/assembly.rst
badge/getting_started.rst
badge/config.rst
badge/updating_firmware.rst
badge/troubleshooting.rst
badge/mods.rst
badge/hardware_specs.rst badge/hardware_specs.rst
badge/usage.rst
badge/programming.rst
badge/application-programming.rst
badge/firmware.rst
badge/firmware-development.rst
badge/badge_link.rst
badge/badge_net.rst
badge/bl00mbox.rst
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
:caption: API: :caption: App programming
api/audio.rst app/guide/blinky.rst
api/badgelink.rst app/guide/environment.rst
api/badgenet.rst app/guide/basics.rst
api/captouch.rst app/guide/savefiles.rst
api/ctx.rst app/guide/bl00mbox.rst
api/leds.rst app/guide/fonts.rst
api/uos.rst app/guide/badge_link.rst
api/sys_buttons.rst app/guide/badge_net.rst
api/sys_display.rst app/guide/qwiic.rst
api/sys_kernel.rst
.. toctree::
:maxdepth: 1
:caption: App API
app/api/application.rst
app/api/input.rst
app/api/captouch.rst
app/api/widgets.rst
app/api/ctx.rst
app/api/colours.rst
app/api/leds.rst
app/api/led_patterns.rst
app/api/view.rst
app/api/audio.rst
app/api/badgelink.rst
app/api/badgenet.rst
app/api/uos.rst
.. toctree::
:maxdepth: 1
:caption: OS programming
os/guide/structure.rst
os/guide/development.rst
.. toctree::
:maxdepth: 1
:caption: OS API
os/api/sys_audio.rst
os/api/sys_display.rst
os/api/sys_kernel.rst
.. toctree::
:maxdepth: 1
:caption: About
badge/license.rst
Indices and tables Indices and tables
================== ------------------
* :ref:`genindex` * :ref:`genindex`
* :ref:`modindex` * :ref:`modindex`
......
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
.. py:module:: audio .. py:module:: sys_audio
``audio`` module ``sys_audio`` module
================ ====================
This module also includes members of the ``audio`` module for convenience.
.. warning::
These functions are not to be used in applications, but only by OS settings.
Many of these functions are available in three variants: headphone volume, Many of these functions are available in three variants: headphone volume,
speaker volume, and volume. If :code:`headphones_are_connected()` returns 1 speaker volume, and volume. If :code:`headphones_are_connected()` returns 1
the "headphone" variant is chosen, else the "speaker" variant is chosen. the "headphone" variant is chosen, else the "speaker" variant is chosen.
.. py:function:: headset_is_connected() -> bool .. py:function:: headphones_detection_override(enable : bool, override_state : bool)
Returns 1 if headphones with microphone were connected to the headphone
jack at the last call of audio_update_jacksense.
.. py:function:: headphones_are_connected() -> bool Set to 'enable = True' if the system should ignore jacksense and use
override_state to determine whether headphones are connected (True) or not
(False).
Returns 1 if headphones with or without microphone were connected to the Use cases:
headphone jack at the last call of audio_update_jacksense.
.. py:function:: headphones_detection_override(enable : bool) - If a sleeve contact mic doesn't pull the detection pin low enough the
codec's built in headphone detection might fail.
- If the headset only has a mic connected but we wish to use the internal
speaker anyway
If a sleeve contact mic doesn't pull the detection pin low enough the Call with 'enable = 0' to revert to automatic detection.
codec's built in headphone detection might fail. Calling this function
with 'enable = 1' overrides the detection and assumes there's headphones
plugged in. Call with 'enable = 0' to revert to automatic detection.
.. py:function:: headphones_set_volume_dB(vol_dB : float) -> float .. py:function:: headphones_set_volume_dB(vol_dB : float) -> float
.. py:function:: speaker_set_volume_dB(vol_dB : float) -> float .. py:function:: speaker_set_volume_dB(vol_dB : float) -> float
...@@ -97,49 +101,42 @@ the "headphone" variant is chosen, else the "speaker" variant is chosen. ...@@ -97,49 +101,42 @@ the "headphone" variant is chosen, else the "speaker" variant is chosen.
:code:`audio_{headphones_/speaker_/}set_{maximum/minimum}_volume_` and 0 if :code:`audio_{headphones_/speaker_/}set_{maximum/minimum}_volume_` and 0 if
in a fake mute condition. in a fake mute condition.
.. py:function:: headphones_line_in_set_hardware_thru(enable : bool) .. py:function:: headset_mic_set_gain_dB(gain_dB : float)
.. py:function:: speaker_line_in_set_hardware_thru(enable : bool) .. py:function:: headset_mic_get_gain_dB() -> float
.. py:function:: line_in_set_hardware_thru(enable : bool) .. py:function:: onboard_mic_set_gain_dB(gain_dB : float)
.. py:function:: onboard_mic_get_gain_dB() -> float
.. py:function:: line_in_set_gain_dB(gain_dB : float)
.. py:function:: line_in_get_gain_dB() -> float
These route whatever is on the line in port directly to the headphones or Set and get gain for the respective input channels.
speaker respectively (enable = 1), or don't (enable = 0). Is affected by mute
and coarse hardware volume settings, however software fine volume is not
applied.
Good for testing, might deprecate later, idk~ .. py:function:: codec_i2c_write(reg : int, data : int)
.. py:function:: input_set_source(source : int) Write audio codec register. Obviously very unsafe. Do not use in applications that you
.. py:function:: input_get_source() -> int distribute to users. This can fry your speakers with DC
The codec can transmit audio data from different sources. This function .. py:function:: _codec_configure_dynamic_range_control(enable : bool, attack : int, release : int, make_up_gain_dB : int, comp_ratio : int, comp_threshold_dB : int, exp_ratio : int, exp_threshold_dB : int)
enables one or no source as provided by the ``INPUT_SOURCE_*`` constants.
Note: The onboard digital mic turns on an LED on the top board if it receives Configures dynamic range control (compressor/expander) in the max98091 codec.
a clock signal which is considered a good proxy for its capability of reading
data.
.. py:data:: INPUT_SOURCE_NONE Temporary API for compressor experimentation, to be replaced later.
.. py:data:: INPUT_SOURCE_LINE_IN
.. py:data:: INPUT_SOURCE_HEADSET_MIC
.. py:data:: INPUT_SOURCE_ONBOARD_MIC
.. py:function:: headset_set_gain_dB(gain_dB : int) See page 134 of the datasheet for values:
.. py:function:: headset_get_gain_dB() -> int
Hardware preamp gain, 0dB-50dB. TODO: figure out if int/float inconsistency https://www.analog.com/media/en/technical-documentation/data-sheets/MAX98091.pdf
is a good thing here compared to all other _dB functions.
.. py:function:: input_thru_set_volume_dB(vol_dB : float) ``exp_threshold_dB`` is expressed in dB from 35 to 66, not in raw values
.. py:function:: input_thru_get_volume_dB() -> float from 0 to 31.
.. py:function:: input_thru_set_mute(mute : bool)
.. py:function:: input_thru_get_mute() -> bool
You can route whatever source is selected with input_set_source() to Example:
the audio output. Use these to control volume and mute.
.. py:function:: codec_i2c_write(reg : int, data : int) .. code-block:: python
audio._codec_configure_dynamic_range_control(True, 2, 3, 0, 4, 10, 0, 0)
Write audio codec register. Obviously very unsafe. Have fun. Will result in enabling the compressor with attack 2 (1.25ms), release 3
(1s), no make up gain, compression ratio 4 (INF:1), compression threshold
10dB, and expander disabled (ratio 1:1)
Headphone port policy Headphone port policy
......
File moved
File moved
Firmware Development Development
==================== ===========
*Note: if you just want to make apps/instruments, see the Programming section.*
*Note: we assume you've read the Firmware section before, as that contains general information about the firmware structure.*
Source Code Source Code
----------- -----------
...@@ -42,6 +38,7 @@ On other Linux-based distributions, you will have to manually install ESP-IDF al ...@@ -42,6 +38,7 @@ On other Linux-based distributions, you will have to manually install ESP-IDF al
$ git clone --recursive https://git.flow3r.garden/flow3r/esp-idf $ git clone --recursive https://git.flow3r.garden/flow3r/esp-idf
$ cd esp-idf $ cd esp-idf
$ git checkout 5.1-flow3r
$ ./install.sh $ ./install.sh
$ source export.sh $ source export.sh
...@@ -52,12 +49,22 @@ For running the simulator, you'll need Python 3 with pygame and wasmer: ...@@ -52,12 +49,22 @@ For running the simulator, you'll need Python 3 with pygame and wasmer:
:: ::
$ python3 -m venv venv $ python3 -m venv venv
$ . venv/bin/activate $ venv/bin/pip install pygame requests pymad
$ pip install pygame wasmer wasmer-compiler-cranelift $ venv/bin/pip install wasmer wasmer-compiler-cranelift
If using python 3.11, for some reason the wasmer developers haven't published working wheels. We have `unofficial builds here <https://flow3r.garden/tmp/wasmer-py311/>`_. .. warning::
For Python development, you're also encouraged to use mypy for typechecks. It should be available in your distribution repositories. The wasmer python module from PyPI `doesn't work with Python versions 3.10 or 3.11
<https://github.com/wasmerio/wasmer-python/issues/539>`_. You will get
``ImportError: Wasmer is not available on this system`` when trying to run
the simulator.
Instead, install our `rebuilt wasmer wheels <https://flow3r.garden/tmp/wasmer-py311/>`_ using
::
venv/bin/pip install https://flow3r.garden/tmp/wasmer-py311/wasmer_compiler_cranelift-1.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
venv/bin/pip install https://flow3r.garden/tmp/wasmer-py311/wasmer-1.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
On macOS: the above might work. On macOS: the above might work.
...@@ -80,12 +87,6 @@ As with application development, you can first check your changes using the simu ...@@ -80,12 +87,6 @@ As with application development, you can first check your changes using the simu
$ python3 sim/run.py $ python3 sim/run.py
You should also run typechecks:
::
$ MYPYPATH=python_payload/mypystubs mypy python_payload/main.py
Working on C st3m code Working on C st3m code
---------------------- ----------------------
...@@ -170,13 +171,35 @@ All printf() (and other stdio) calls will be piped to the default Micropython RE ...@@ -170,13 +171,35 @@ All printf() (and other stdio) calls will be piped to the default Micropython RE
If you're debugging the USB stack, or want to see Guru Meditation crashes, connect to UART0 over the USB-C connector's sideband pins (**TODO**: link to flow3rpot). If you're debugging the USB stack, or want to see Guru Meditation crashes, connect to UART0 over the USB-C connector's sideband pins (**TODO**: link to flow3rpot).
You can also disable the USB stack and make the badge stay in UART/JTAG mode: **TODO: issue 23**. Then, you can use openocd/gdb: gdb Debugging
-------------
You can also disable the TinyUSB stack and make the badge stay in UART/JTAG mode:
``idf.py menuconfig`` -> Component config -> debug config -> usb gdb mode
Console output (including REPL) is not currently implemented in this mode.
Do a clean build with ``rm -r build; idf.py app-flash``
In one terminal:
:: ::
$ OPENOCD_COMMANDS="-f board/esp32s3-builtin.cfg" idf.py opencod $ OPENOCD_COMMANDS="-f board/esp32s3-builtin.cfg" idf.py openocd
In another terminal:
::
$ idf.py gdb
If experiencing issues with ctrl-c, try calling gdb directly (reusing the ``build/gdbinit/gdbinit`` created by the above command)
::
$ xtensa-esp32s3-elf-gdb -x build/gdbinit/gdbinit build/flow3r.elf
*TODO: document how to start gdb*
Porting Doom (or other alternate firmware) Porting Doom (or other alternate firmware)
------------------------------------------ ------------------------------------------
...@@ -189,6 +212,13 @@ Then, you can run your firmware by distributing the resulting ``.bin`` file and ...@@ -189,6 +212,13 @@ Then, you can run your firmware by distributing the resulting ``.bin`` file and
For an example, see our doom port at **TODO**. For an example, see our doom port at **TODO**.
Alternative Firmware Projects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you fancy playing with Rust on the flow3r, check out the `flow3-rs <https://git.flow3r.garden/flow3r/flow3-rs>`_ project.
A port of Open-Smartwatch is also `in the works <https://github.com/Open-Smartwatch/open-smartwatch-os/pull/368>`_.
Hardware Generations Hardware Generations
-------------------- --------------------
...@@ -217,6 +247,14 @@ Writing Docs ...@@ -217,6 +247,14 @@ Writing Docs
Automatically updated on CI runs of the main branch and lives under https://docs.flow3r.garden. Automatically updated on CI runs of the main branch and lives under https://docs.flow3r.garden.
You will need ``sphinx`` and ``sphinx_rtd_theme`` installed. If you're not usinx Nix, install these via venv:
::
$ python3 -m venv venv
$ venv/bin/pip install sphinx sphinx_rtd_theme
$ . venv/bin/activate
To build the docs locally: To build the docs locally:
:: ::
......
Firmware Structure
======== =========
Introduction Introduction
------------ ------------
...@@ -75,6 +75,8 @@ This is the SPI flash partition layout we use: ...@@ -75,6 +75,8 @@ This is the SPI flash partition layout we use:
| ``vfs`` | 12MiB | FAT32 filesystem (with [#WL]_ layer). | | ``vfs`` | 12MiB | FAT32 filesystem (with [#WL]_ layer). |
+--------------+--------+---------------------------------------+ +--------------+--------+---------------------------------------+
.. [#WL] Wear leveling, to protect internal flash from death by repeat sector write.
Accessing files from a PC Accessing files from a PC
------------------------- -------------------------
...@@ -98,6 +100,18 @@ If the badge is running correctly, you can access the filesystem over the microp ...@@ -98,6 +100,18 @@ If the badge is running correctly, you can access the filesystem over the microp
0 st3m 0 st3m
0 .sys-installed 0 .sys-installed
.. warning::
**Your flow3r is not showing up using Linux?**
To let ``mpremote`` to work properly your user needs to have access rights to ttyACM.
Quick fix: ``sudo chmod a+rw /dev/ttyACM[Your Device Id here]```
More sustainable fix: Setup an udev rule to automatically allow the logged in user to access ttyUSB
1. To use this, add the following to /etc/udev/rules.d/60-extra-acl.rules: ``KERNEL=="ttyACM[0-9]*", TAG+="udev-acl", TAG+="uaccess"``
2. Reload ``udevadm control --reload-rules && udevadm trigger``
You can also put the badge into :ref:`Disk Mode` to make it appear as a USB pendrive You can also put the badge into :ref:`Disk Mode` to make it appear as a USB pendrive
on your PC. However, only one of the two FAT32 block devices (internal flash on your PC. However, only one of the two FAT32 block devices (internal flash
...@@ -168,7 +182,7 @@ You should be greeted with a purple screen from which multiple actions can be se ...@@ -168,7 +182,7 @@ You should be greeted with a purple screen from which multiple actions can be se
1. **Reboot**: reboots the badge back into the current (non-recovery) firmware. 1. **Reboot**: reboots the badge back into the current (non-recovery) firmware.
2. **Disk Mode**: mounts the internal SPI flash FAT partition as a USB mass storage. This is effectively a copy of the :ref:`Disk Mode` from the main firmware. 2. **Disk Mode**: mounts the internal SPI flash FAT partition as a USB mass storage. This is effectively a copy of the :ref:`Disk Mode` from the main firmware.
3. **Format FAT partition**: fully wipes the internal SPI flash, which should let you recover from most cases of bricking. On next reboot, the badge will re-populate the FAT partition with :ref:`st3m` files and should start up normally. 3. **Format FAT partition**: fully wipes the internal SPI flash, which should let you recover from most cases of bricking. On next reboot, the badge will re-populate the FAT partition with :ref:`st3m` files and should start up normally.
4. **Update firmware**: flashes a file from the FAT partition onto the main firmware partition_. This can be used to update your badge to the newest firmware (**TODO**) or to an alternative firmware. 4. **Update firmware**: flashes a file from the FAT partition onto the main firmware partition_. This can be used to update your badge to the `newest firmware <https://git.flow3r.garden/flow3r/flow3r-firmware/-/releases>`_ or to an alternative firmware.
.. _flash: .. _flash:
...@@ -189,11 +203,7 @@ Instructions on how to run ``esptool.py`` are given with every firmware update r ...@@ -189,11 +203,7 @@ Instructions on how to run ``esptool.py`` are given with every firmware update r
Updating Firmware Updating Firmware
----------------- -----------------
Download a release from **TODO**, extract the tarball and follow instructions in the README. There will be notes on how to perform updates through either :ref:`Disk Mode`, `Recovery Mode`_ or through a low-level flash_. (Moved to :ref:`its own section <updating_firmware>`)
Or, if you're at CCCamp2023, visit one of our firmware update stations.
.. [#WL] Wear leveling, to protect internal flash from death by repeat sector write.
Versioning Versioning
---------- ----------
......
import os
DRY_RUN = False
DOMAIN = "https://docs.flow3r.garden"
BUILD_DIR = "_build"
FILE_TEMPLATE = '<meta http-equiv="refresh" content="0; url={url}" />\n<p><a href="{url}">Redirect</a></p>'
redirects = [
# (obsolete, target)
("badge/firmware.html", "os/guide/structure.html"),
("badge/fonts.html", "app/guide/fonts.html"),
("badge/usage.html", "badge/getting_started.html"),
("badge/programming.html", "app/guide/basics.html"),
("badge/badge_link.html", "app/guide/badge_link.html"),
("badge/badge_net.html", "app/guide/badge_net.html"),
("badge/bl00mbox.html", "app/guide/bl00mbox.html"),
("badge/firmware-development.html", "os/guide/development.html"),
("api/badgenet.html","app/api/badgenet.html"),
("api/sys_display.html", "os/api/sys_display.html"),
("api/ctx.html", "app/api/ctx.html"),
("api/badgelink.html", "app/api/badgelink.html"),
("api/audio.html", "app/api/audio.html"),
("api/colours.html", "app/api/colours.html"),
("api/leds.html", "app/api/leds.html"),
("api/led_patterns.html", "app/api/led_patterns.html"),
("api/uos.html", "app/api/uos.html"),
("api/sys_kernel.html", "os/api/sys_kernel.html"),
("api/sys_buttons.html", "app/api/input.html"),
("api/captouch.html", "app/api/captouch.html"),
]
for obsolete, target in redirects:
redirect_file_content = FILE_TEMPLATE.format(url = "/".join([DOMAIN, target]))
redirect_file_path = os.path.join(BUILD_DIR, obsolete)
if not DRY_RUN:
redirect_dir_path, _ = os.path.split(redirect_file_path)
os.makedirs(redirect_dir_path, exist_ok = True)
if not os.path.isfile(redirect_file_path):
print(f"writing to {redirect_file_path}")
if not DRY_RUN:
with open(redirect_file_path, "w") as f:
f.write(redirect_file_content)
else:
print(f"{redirect_file_content}\n")
else:
print(f"file {redirect_file_path} already exists")
sphinx==5.3.0
sphinx_rtd_theme==1.2.0
sphinx-multiversion @ git+https://github.com/dequis/sphinx-multiversion@fd3f0a0a1ef90781deac2de72c5d5c102c7f66da
--- a/git.py 2024-04-30 17:43:17.242346208 +0200
+++ b/git.py 2024-04-30 17:46:54.348580864 +0200
@@ -147,17 +147,17 @@
def copy_tree(gitroot, src, dst, reference, sourcepath="."):
- with tempfile.SpooledTemporaryFile() as fp:
- cmd = (
- "git",
- "archive",
- "--format",
- "tar",
- reference.commit,
- "--",
- sourcepath,
- )
- subprocess.check_call(cmd, cwd=gitroot, stdout=fp)
- fp.seek(0)
- with tarfile.TarFile(fileobj=fp) as tarfp:
- tarfp.extractall(dst)
+ os.makedirs(dst, exist_ok=True)
+ cmd = (
+ "git",
+ "clone",
+ sourcepath,
+ dst,
+ )
+ subprocess.run(cmd, cwd=gitroot, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ cmd = (
+ "git",
+ "checkout",
+ reference.commit,
+ )
+ subprocess.run(cmd, cwd=dst, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
set(SYS_C_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/sys_data.c") set(SYS_C_PATH "${CMAKE_CURRENT_BINARY_DIR}/include/sys_data.c")
if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/include/")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/")
endif()
idf_component_register( idf_component_register(
SRCS SRCS
main.c main.c
......
#include "bl00mbox.h"
#include "flow3r_bsp.h" #include "flow3r_bsp.h"
#include "st3m_audio.h" #include "st3m_audio.h"
#include "st3m_badgenet.h" #include "st3m_badgenet.h"
...@@ -57,21 +56,7 @@ static QueueHandle_t _core1_init_done_q; ...@@ -57,21 +56,7 @@ static QueueHandle_t _core1_init_done_q;
void _init_core1(void *unused) { void _init_core1(void *unused) {
st3m_usb_init(); st3m_usb_init();
st3m_console_init(); st3m_console_init();
st3m_usb_app_conf_t app = { st3m_usb_startup();
.fn_rx = st3m_console_cdc_on_rx,
.fn_txpoll = st3m_console_cdc_on_txpoll,
.fn_detach = st3m_console_cdc_on_detach,
};
st3m_usb_mode_t usb_mode = {
.kind = st3m_usb_mode_kind_app,
.app = &app,
};
st3m_usb_mode_switch(&usb_mode);
puts(" ___ _ ___ _ _");
puts("| _| |___ _ _ _|_ |___| |_ ___ _| |___ ___");
puts("| _| | . | | | |_ | _| . | .'| . | . | -_|");
puts("|_| |_|___|_____|___|_| |___|__,|___|_ |___|");
puts(" |___|");
// Load bearing delay. USB crashes otherwise? // Load bearing delay. USB crashes otherwise?
// TODO(q3k): debug this // TODO(q3k): debug this
...@@ -91,13 +76,10 @@ void _init_core1(void *unused) { ...@@ -91,13 +76,10 @@ void _init_core1(void *unused) {
nvs_flash_init(); nvs_flash_init();
} }
// Let the main startup code know that core1 init is done. Then sleep // Let the main startup code know that core1 init is done.
// forever. What a waste of stack space.
bool done = true; bool done = true;
xQueueSend(_core1_init_done_q, &done, portMAX_DELAY); xQueueSend(_core1_init_done_q, &done, portMAX_DELAY);
for (;;) { vTaskDelete(NULL);
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
} }
// Called by micropython via MICROPY_BOARD_STARTUP. // Called by micropython via MICROPY_BOARD_STARTUP.
...@@ -109,7 +91,7 @@ void flow3r_startup(void) { ...@@ -109,7 +91,7 @@ void flow3r_startup(void) {
// Submit splash a couple of times to make sure we've fully flushed out the // Submit splash a couple of times to make sure we've fully flushed out the
// initial framebuffer (both on-ESP and in-screen) noise before we turn on // initial framebuffer (both on-ESP and in-screen) noise before we turn on
// the backlight. // the backlight.
for (int i = 0; i < 4; i++) { for (int i = 0; i < 5; i++) {
st3m_gfx_splash(""); st3m_gfx_splash("");
} }
// Display should've flushed by now. Turn on backlight. // Display should've flushed by now. Turn on backlight.
...@@ -130,7 +112,6 @@ void flow3r_startup(void) { ...@@ -130,7 +112,6 @@ void flow3r_startup(void) {
st3m_scope_init(); st3m_scope_init();
st3m_audio_init(); st3m_audio_init();
bl00mbox_init();
st3m_badgenet_init(); st3m_badgenet_init();
st3m_mode_set(st3m_mode_kind_starting, "micropython"); st3m_mode_set(st3m_mode_kind_starting, "micropython");
......