docs: Wordsmtithing updates after review
Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
This commit is contained in:
parent
6f0238415f
commit
748e5fe65a
8 changed files with 188 additions and 149 deletions
35
README.rst
35
README.rst
|
@ -4,19 +4,18 @@ Watch Application System in Python
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Although still in its infancy wasp-os provides many example applications
|
Wasp-os is a firmware for smart watches that are based on the nRF52
|
||||||
including a simple digital clock, a stopwatch, a step counter and a heart rate
|
family of microcontrollers, including hacker friendly watches such
|
||||||
monitor. All of these, together with access to the MicroPython REPL for
|
as the Pine64 PineTime. Wasp-os includes a digital clock, a stopwatch,
|
||||||
interactive tweaking and testing, are running on `PineTime
|
a step counter and a heart rate monitor. All of these, together with
|
||||||
<https://www.pine64.org/pinetime/>`_. It keeps time well and has enough power
|
access to the MicroPython REPL for interactive tweaking, development
|
||||||
saving functions implemented that it can survive for well over 72 hours between
|
and testing.
|
||||||
charges so even at this early stage it is functional as a wearable timepiece.
|
|
||||||
|
|
||||||
Wasp-os includes a robust bootloader based on the Adafruit NRF52
|
Wasp-os includes a robust bootloader based on the Adafruit NRF52
|
||||||
Bootloader. It has been extended to make it robust for development on
|
Bootloader. It has been extended to make it robust for development on
|
||||||
form-factor devices without a reset button, power switch, SWD debugger
|
form-factor devices without a reset button, power switch, SWD debugger
|
||||||
or UART. This allows us to confidently develop on sealed devices relying
|
or UART. This allows us to confidently develop on sealed devices relying
|
||||||
only on BLE for updates.
|
on Bluetooth Low Energy for over-the-air updates.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
@ -29,19 +28,19 @@ get started coding for wasp-os as quickly as possible.
|
||||||
Getting Started
|
Getting Started
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Wasp-os can be installed without using any tools onto the following
|
Wasp-os can be installed without using any tools or disassembly onto the
|
||||||
devices:
|
following devices:
|
||||||
|
|
||||||
* Pine64 PineTime (developer edition)
|
* Pine64 PineTime
|
||||||
* Colmi P8
|
* Colmi P8
|
||||||
* Senbono K9
|
* Senbono K9
|
||||||
|
|
||||||
The
|
Use the
|
||||||
`Installation Guide <https://wasp-os.readthedocs.io/en/latest/install.html>`_
|
`Installation Guide <https://wasp-os.readthedocs.io/en/latest/install.html>`_
|
||||||
contains detailed instructions on how to build and install wasp-os.
|
to learn how to build and install wasp-os on these devices.
|
||||||
|
|
||||||
At the end of the install process your watch will show the time (03:00)
|
At the end of the install process your watch will show the time (03:00)
|
||||||
together with a date and battery meter. When the watch goes into power
|
together with a date and a battery meter. When the watch goes into power
|
||||||
saving mode you can use the button to wake it again.
|
saving mode you can use the button to wake it again.
|
||||||
|
|
||||||
At this point you will also be able to use the Nordic UART Service to
|
At this point you will also be able to use the Nordic UART Service to
|
||||||
|
@ -56,7 +55,7 @@ To set the time and restart the main application:
|
||||||
watch.rtc.set_localtime((yyyy, mm, dd, HH, MM, SS))
|
watch.rtc.set_localtime((yyyy, mm, dd, HH, MM, SS))
|
||||||
wasp.system.run()
|
wasp.system.run()
|
||||||
|
|
||||||
Or just use:
|
Or, if you have a suitable GNU/Linux workstation, just use:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
|
@ -103,10 +102,12 @@ Videos
|
||||||
Screenshots
|
Screenshots
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
(An older version of) the digital clock application running on a Pine64 PineTime:
|
(An older version of) the digital clock application running on a Pine64
|
||||||
|
PineTime:
|
||||||
|
|
||||||
.. image:: res/clock_app.jpg
|
.. image:: res/clock_app.jpg
|
||||||
:alt: wasp-os digital clock app running on PineTime
|
:alt: wasp-os digital clock app running on PineTime
|
||||||
|
:width: 233
|
||||||
|
|
||||||
Screenshots of the built in applications running on the wasp-os
|
Screenshots of the built in applications running on the wasp-os
|
||||||
simulator (the "blank" screen is the torch application):
|
simulator (the "blank" screen is the torch application):
|
||||||
|
@ -163,6 +164,6 @@ using one of the techniques is the Application Writer's guide.
|
||||||
:alt: Game of Life running in the wasp-os simulator
|
:alt: Game of Life running in the wasp-os simulator
|
||||||
:width: 179
|
:width: 179
|
||||||
|
|
||||||
.. image:: res/MusicPlayerApp.png
|
.. image:: res/MusicApp.png
|
||||||
:alt: Music Player running in the wasp-os simulator
|
:alt: Music Player running in the wasp-os simulator
|
||||||
:width: 179
|
:width: 179
|
||||||
|
|
4
TODO.rst
4
TODO.rst
|
@ -11,9 +11,7 @@ Roadmap
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
For 0.4 we focus on improving the watch/phone integration whilst also taking steps
|
For 0.4 we focus on improving the watch/phone integration whilst also taking steps
|
||||||
to improve the general fit and finish. In addition the reloader will be extended
|
to improve the general fit and finish.
|
||||||
to ensure we retain the capability to install wasp-os over-the-air on newer
|
|
||||||
PineTime models.
|
|
||||||
|
|
||||||
Bootloader
|
Bootloader
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
|
@ -14,7 +14,7 @@ roadmap: make writing applications easy (and fun).
|
||||||
Applications that can be loaded, changed, adapted and remixed by the user
|
Applications that can be loaded, changed, adapted and remixed by the user
|
||||||
are what **really** distinguishes a smart watch from a "feature watch"[#]_.
|
are what **really** distinguishes a smart watch from a "feature watch"[#]_.
|
||||||
In other words if we want a watch built around a tiny microcontroller to be
|
In other words if we want a watch built around a tiny microcontroller to be
|
||||||
sufficiently "smart" then it has to be all about the applications.
|
"smart" then it has to be all about the applications.
|
||||||
|
|
||||||
This guide will help you get started writing applications for wasp-os. Have fun!
|
This guide will help you get started writing applications for wasp-os. Have fun!
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ This guide will help you get started writing applications for wasp-os. Have fun!
|
||||||
took over the industry were retrospectively renamed "feature phones" to
|
took over the industry were retrospectively renamed "feature phones" to
|
||||||
distinguish them from newer devices. Many of them were superficially similar
|
distinguish them from newer devices. Many of them were superficially similar
|
||||||
to early Android devices but is was the application ecosystem that really
|
to early Android devices but is was the application ecosystem that really
|
||||||
made smart phones smart.
|
made smart phones into what they are today.
|
||||||
|
|
||||||
Hello World for wasp-os
|
Hello World for wasp-os
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -32,16 +32,16 @@ Let's start by examining a simple "Hello, World!" application for wasp-os.
|
||||||
.. literalinclude:: hello.py
|
.. literalinclude:: hello.py
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
There are a couple of points of interest:
|
Some of the key points of interest in this example application are:
|
||||||
|
|
||||||
1. Applications have a :py:attr:`~.TemplateApp.NAME`, which is shown in the
|
1. Applications have a :py:attr:`~.TemplateApp.NAME`, which is shown in the
|
||||||
launcher. Most applications also provide an :py:attr:`~.TemplateApp.ICON`
|
launcher. Most applications also provide an :py:attr:`~.TemplateApp.ICON`
|
||||||
but a default is displayed if this is omitted.
|
but a default will be displayed if this is omitted.
|
||||||
2. This example uses :py:meth:`~.TemplateApp.__init__` to initialize
|
2. This example uses :py:meth:`~.TemplateApp.__init__` to initialize
|
||||||
the state of the application, this ensure the state remains "sticky"
|
the state of the application, these variables are used to remember
|
||||||
when the application is activated and deactivated.
|
the state of the application when when it is deactivated.
|
||||||
3. :py:meth:`~.TemplateApp.foreground` is the only mandatory application entry
|
3. :py:meth:`~.TemplateApp.foreground` is the only mandatory application entry
|
||||||
point and is responsible for redrawing the screen. This application does
|
point and it is responsible for redrawing the screen. This application does
|
||||||
not implement :py:meth:`~.TemplateApp.background` because there is nothing
|
not implement :py:meth:`~.TemplateApp.background` because there is nothing
|
||||||
for us to do!
|
for us to do!
|
||||||
4. The use of :py:meth:`~.TemplateApp._draw` is optional. We could just do
|
4. The use of :py:meth:`~.TemplateApp._draw` is optional. We could just do
|
||||||
|
@ -55,10 +55,11 @@ Application life-cycle
|
||||||
Applications in wasp-os are triggered by and do all their processing
|
Applications in wasp-os are triggered by and do all their processing
|
||||||
from calls their entry points. The entry points can be coarsely categorized
|
from calls their entry points. The entry points can be coarsely categorized
|
||||||
event notifications, timer callbacks (the application tick) and
|
event notifications, timer callbacks (the application tick) and
|
||||||
system notifications.
|
system actions.
|
||||||
|
|
||||||
System notifications control the application life-cycle and the entry point
|
System actions control the application life-cycle and that lifecyle is
|
||||||
calls, together with the implicit application states are shown below.
|
shown below. The system actions are used to tell the application about
|
||||||
|
any change in its lifecycle.
|
||||||
|
|
||||||
.. graphviz::
|
.. graphviz::
|
||||||
|
|
||||||
|
@ -80,56 +81,66 @@ calls, together with the implicit application states are shown below.
|
||||||
}
|
}
|
||||||
|
|
||||||
When an application is initialized is enters the ``BACKGROUND`` state. A
|
When an application is initialized is enters the ``BACKGROUND`` state. A
|
||||||
backgrounded application will not execute but it should nevertheless
|
backgrounded application will not execute but it should nevertheless
|
||||||
maintain its user visible state whilst in the background. To conserve
|
maintain its user visible state whilst deactivated. To conserve
|
||||||
memory wasp-os does not permit two applications to run simultaneously but
|
memory wasp-os does not permit two applications to run simultaneously but
|
||||||
because each application preserves its state when in the background it will
|
because each application remembers its state when it is not running then it
|
||||||
appear to the user as though all applications are running all the time.
|
will appear to the user as though all applications are running all the time.
|
||||||
|
|
||||||
For example, a stopwatch application should record the time that it was started
|
For example, a stopwatch application should record the time that it was started
|
||||||
and remember that start time, regardless of it's state, until either the
|
and remember that start time, regardless of whether it is running or not so
|
||||||
stopwatch is stopped of the application is destroyed.
|
that when it restarted is can continue to run as the user expects.
|
||||||
|
|
||||||
A backgrounded application can enter the ``ACTIVE`` state via a call to
|
A backgrounded application enters the ``ACTIVE`` state via a call to
|
||||||
:py:meth:`~.TemplateApp.foreground`. When it is active the application owns the
|
:py:meth:`~.TemplateApp.foreground`. When it is active the application owns the
|
||||||
screen and should draw and maintain its UI.
|
screen and must draw and maintain its user interface.
|
||||||
|
|
||||||
If the system manager want to put an active application to sleep then it will
|
If the system manager wants to put the watch to sleep then it will tell the
|
||||||
call :py:meth:`~.TemplateApp.sleep`. If the application returns True then the
|
active application to :py:meth:`~.TemplateApp.sleep`.
|
||||||
application will stop running (e.g. receive no events and no application tick)
|
If the application returns True then the application will remain active
|
||||||
but instead must wait to receive a notification via
|
whilst the watch is asleep.
|
||||||
:py:meth:`~.TemplateApp.wake` telling the application that the device
|
It will receive no events nor the application tick whilst the system is
|
||||||
is waking up and that it may update the screen if needed.
|
asleep and, instead, must wait for a :py:meth:`~.TemplateApp.wake` notification
|
||||||
|
telling the application that the device is waking up and that it may
|
||||||
|
update the screen if needed.
|
||||||
|
|
||||||
If an application does not support sleeping then it can simply not implement
|
If an application does not support sleeping then it can simply not implement
|
||||||
:py:meth:`~.TemplateApp.sleep` (or :py:meth:`~.TemplateApp.wake`) although it
|
:py:meth:`~.TemplateApp.sleep` or :py:meth:`~.TemplateApp.wake`.
|
||||||
can also return False from :py:meth:`~.TemplateApp.sleep` if this is preferred.
|
|
||||||
In this case the system manager will automatically return to the default
|
In this case the system manager will automatically return to the default
|
||||||
application, typically the main clock face.
|
application, typically the main clock face.
|
||||||
|
|
||||||
|
Some applications may support sleeping only under certain circumstances. For
|
||||||
|
example a stopwatch may choose to remain active when the watch sleeps only if
|
||||||
|
the stopwatch is running.
|
||||||
|
This type of application must implement :py:meth:`~.TemplateApp.sleep` and
|
||||||
|
return False when it does not want to remain active when the system
|
||||||
|
resumes.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Most applications do not need to support :py:meth:`~.TemplateApp.sleep`
|
Most applications should not implement :py:meth:`~.TemplateApp.sleep`
|
||||||
since it is often a better user experience for the watch to return to the
|
since it is often a better user experience for the watch to return to the
|
||||||
default application when they complete an interaction.
|
default application when they complete an interaction.
|
||||||
|
|
||||||
API primer
|
API primer
|
||||||
----------
|
----------
|
||||||
|
|
||||||
This API primer introduces some of the most important and frequently used
|
This API primer introduces some of the most important and frequently used
|
||||||
interfaces for wasp-os. For more comprehensive coverage see the
|
interfaces in wasp-os. For more comprehensive coverage see the
|
||||||
:ref:`Wasp-os Reference Manual` which contains extensive API documentation
|
:ref:`Wasp-os Reference Manual` which contains extensive API documentation
|
||||||
covering the entire of wasp-os, including its drivers.
|
covering the entire of wasp-os, including its drivers.
|
||||||
|
|
||||||
System management
|
System management
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The system management API does provide a number of low-level calls that
|
The system management API provides a number of low-level calls that
|
||||||
can register new applications and navigate between them. However most
|
can register new applications and navigate between them. However most
|
||||||
applications need not use these. Instead most applications use a small
|
applications do not need to make these low level calls and will use
|
||||||
set of methods. In particular almost all applictions need to call a couple of
|
a much smaller set of methods.
|
||||||
methods from :py:meth:`~.TemplateApp.foreground` in order to register
|
|
||||||
for notifications:
|
Applictions must call a couple of functions from their
|
||||||
|
:py:meth:`~.TemplateApp.foreground` in order to register for
|
||||||
|
event notifications and timer callbacks:
|
||||||
|
|
||||||
* :py:meth:`~.Manager.request_event` - register for UI events such as button
|
* :py:meth:`~.Manager.request_event` - register for UI events such as button
|
||||||
presses and touch screen activity.
|
presses and touch screen activity.
|
||||||
|
@ -137,8 +148,8 @@ for notifications:
|
||||||
and specify the tick frequency.
|
and specify the tick frequency.
|
||||||
|
|
||||||
Additionally if your application is a game or a similar program that should
|
Additionally if your application is a game or a similar program that should
|
||||||
not allow the watch to go to sleep then it should arrange to call
|
not allow the watch to go to sleep when it is running then it should
|
||||||
:py:meth:`~.Manager.keep_awake` from the application's
|
arrange to call :py:meth:`~.Manager.keep_awake` from the application's
|
||||||
:py:meth:`~.TemplateApp.tick` method.
|
:py:meth:`~.TemplateApp.tick` method.
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
|
@ -148,8 +159,8 @@ Most applications using the drawing toolbox, :py:data:`wasp.watch.drawable`,
|
||||||
in order to handle the display. Applications are permitted to directly access
|
in order to handle the display. Applications are permitted to directly access
|
||||||
:py:data:`wasp.watch.display` if they require direct pixel access or want to
|
:py:data:`wasp.watch.display` if they require direct pixel access or want to
|
||||||
exploit specific features of the display hardware (inverse video, partial
|
exploit specific features of the display hardware (inverse video, partial
|
||||||
display, etc) but for simple applications then the following simple drawing
|
display, etc) but for most applications the drawing toolbox provides
|
||||||
functions are sufficient.
|
convenient and optimized drawing functions.
|
||||||
|
|
||||||
* :py:meth:`~.Draw565.blit` - blit an image to the display at specified (x, y)
|
* :py:meth:`~.Draw565.blit` - blit an image to the display at specified (x, y)
|
||||||
coordinates, image type is detected automatically
|
coordinates, image type is detected automatically
|
||||||
|
@ -186,7 +197,7 @@ MicroPython
|
||||||
|
|
||||||
Many of the features of wasp-os are inherited directly from MicroPython_. It is
|
Many of the features of wasp-os are inherited directly from MicroPython_. It is
|
||||||
useful to have a basic understanding of MicroPython and, in particular, put
|
useful to have a basic understanding of MicroPython and, in particular, put
|
||||||
in a little time learning the best ways to copy with running
|
a little time into learning the best practices when running
|
||||||
`MicroPython on microcontrollers`__.
|
`MicroPython on microcontrollers`__.
|
||||||
|
|
||||||
.. _MicroPython: https://micropython.org/
|
.. _MicroPython: https://micropython.org/
|
||||||
|
@ -201,10 +212,10 @@ How to run your application
|
||||||
Testing on the simulator
|
Testing on the simulator
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
wasp-os provides a simulator that can be used to test applications before
|
wasp-os includes a simulator that can be used to test applications before
|
||||||
downloading them to the device. The simulator is useful for ensuring the
|
downloading them to the device. The simulator is useful for ensuring the
|
||||||
code is syntactically correct and that there are not major runtime problems
|
code is syntactically correct and that there are not major runtime problems
|
||||||
(e.g. missing symbols).
|
such as misspelt symbol names.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -212,7 +223,7 @@ code is syntactically correct and that there are not major runtime problems
|
||||||
device. It may still be necessary to tune the application for minimal
|
device. It may still be necessary to tune the application for minimal
|
||||||
footprint after testing on the simulator.
|
footprint after testing on the simulator.
|
||||||
|
|
||||||
Firstly launch the simulator:
|
To launch the simulator:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
|
@ -224,7 +235,7 @@ Firstly launch the simulator:
|
||||||
Watch is running, use Ctrl-C to stop
|
Watch is running, use Ctrl-C to stop
|
||||||
|
|
||||||
From the simulator console we can register the application with the following
|
From the simulator console we can register the application with the following
|
||||||
code:
|
commands:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
@ -240,19 +251,25 @@ code:
|
||||||
|
|
||||||
When an application is registered it does not start automatically but it will
|
When an application is registered it does not start automatically but it will
|
||||||
have been added to the launcher and you will be able to select in the simulator
|
have been added to the launcher and you will be able to select in the simulator
|
||||||
by using the Arrow keys to bring up the launcher and then clicking on your
|
by swiping or using the Arrow keys to bring up the launcher and then clicking
|
||||||
application.
|
on your application.
|
||||||
|
|
||||||
The application can also be registered automatically when you load the
|
The application can also be registered automatically when you load the
|
||||||
simulator if you add it to ``wasp/main.py``. Try adding lines 5 and 6 from
|
simulator if you add it to ``wasp/main.py``. Try adding lines 5 and 6 from
|
||||||
the above example into this file (between ``import wasp`` and
|
the above example into this file (between ``import wasp`` and
|
||||||
``wasp.system.run()``).
|
``wasp.system.run()``).
|
||||||
|
|
||||||
|
The simulator accepts gestures such as up/down and left/right swipes but the
|
||||||
|
simulator also accepts keystrokes for convenience. The arrow keys simulate
|
||||||
|
swipes and the Tab key simulates the physical button, whilst the 's' key
|
||||||
|
can be used to capture screen shots to add to the documentation for your
|
||||||
|
application.
|
||||||
|
|
||||||
Testing on the device
|
Testing on the device
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If we have an application under development when we can launch a quick test
|
When an application is under development it is best to temporarily load
|
||||||
that does not result in the application being permanently stored on the device.
|
your application without permanently stored on the device.
|
||||||
Providing there is enough available RAM then this can lead to a very quick
|
Providing there is enough available RAM then this can lead to a very quick
|
||||||
edit-test cycles.
|
edit-test cycles.
|
||||||
|
|
||||||
|
@ -264,11 +281,10 @@ Try:
|
||||||
--exec myapp.py \\
|
--exec myapp.py \\
|
||||||
--eval "wasp.system.register(MyApp())"
|
--eval "wasp.system.register(MyApp())"
|
||||||
Preparing to run myapp.py:
|
Preparing to run myapp.py:
|
||||||
[##################################################] 100%
|
[##################################################] 100%
|
||||||
|
|
||||||
Like the simulator, when an application is registered it does not start
|
Like the simulator, when an application is registered it is added to the
|
||||||
automatically but it will have been added to the launcher and can be launched
|
launcher and it does not start automatically.
|
||||||
using the normal gestures to control the device.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -276,19 +292,24 @@ using the normal gestures to control the device.
|
||||||
application is too large to be compiled on the target. You may have to
|
application is too large to be compiled on the target. You may have to
|
||||||
adopt the frozen module approach from the next section.
|
adopt the frozen module approach from the next section.
|
||||||
|
|
||||||
|
To remove the application simply reboot the watch by pressing and
|
||||||
|
holding the physical button until the watch enters OTA mode (this
|
||||||
|
takes around five seconds). Once the watch is in OTA mode then
|
||||||
|
press the phyiscal button again to return to normal mode with the
|
||||||
|
application cleared out.
|
||||||
|
|
||||||
Making it permanent
|
Making it permanent
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
To ensure you application survives a system reset (press the hardware
|
To ensure you application survives a reboot then we must copy it to the
|
||||||
button for around five seconds until the splash screen is seen, wait
|
device and ensure it gets launched during system startup.
|
||||||
five seconds and then press again) then we must copy it to the device
|
|
||||||
and ensure it gets launched during system startup.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Applications stored in external FLASH have a greater RAM overhead than
|
Applications stored in external FLASH have a greater RAM overhead than
|
||||||
applications that are frozen into the wasp-os binary. See next section for
|
applications that are frozen into the wasp-os binary. If you app does
|
||||||
additional details.
|
not fix then see next section for additional details on how to embed
|
||||||
|
your app in the wasp-os binary itself..
|
||||||
|
|
||||||
To copy your application to the external FLASH try:
|
To copy your application to the external FLASH try:
|
||||||
|
|
||||||
|
@ -296,7 +317,7 @@ To copy your application to the external FLASH try:
|
||||||
|
|
||||||
sh$ ./tools/wasptool --upload myapp.py
|
sh$ ./tools/wasptool --upload myapp.py
|
||||||
Uploading myapp.py:
|
Uploading myapp.py:
|
||||||
[##################################################] 100%
|
[##################################################] 100%
|
||||||
|
|
||||||
At this point your application is stored on the external FLASH but it will
|
At this point your application is stored on the external FLASH but it will
|
||||||
not automatically be loaded. This requires you to update the ``main.py`` file
|
not automatically be loaded. This requires you to update the ``main.py`` file
|
||||||
|
@ -321,7 +342,7 @@ to the watch:
|
||||||
|
|
||||||
sh$ ./tools/wasptool --upload wasp/main.py
|
sh$ ./tools/wasptool --upload wasp/main.py
|
||||||
Uploading wasp/main.py:
|
Uploading wasp/main.py:
|
||||||
[##################################################] 100%
|
[##################################################] 100%
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -334,16 +355,16 @@ Freezing your application into the wasp-os binary
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Freezing your application causes it to consume dramatically less RAM. That is
|
Freezing your application causes it to consume dramatically less RAM. That is
|
||||||
because the code is both pre-compiled (meaning we don't need any RAM budget to
|
because they can execute directly from the internal FLASH rather than running
|
||||||
run the compiler) **and** it can execute directly from the internal FLASH
|
from RAM. Additionally the code is pre-compiled, which also means we don't
|
||||||
memory.
|
need any RAM budget to run the compiler.
|
||||||
|
|
||||||
Freezing your application simply requires you to modify the ``manifest.py``
|
Freezing your application requires you to modify the ``manifest.py``
|
||||||
file for your board (e.g. ``wasp/boards/pinetime/manifest.py``) to include
|
file for your board (e.g. ``wasp/boards/pinetime/manifest.py``) to include
|
||||||
your application and then the whole binary must be re-compiled as normal.
|
your application and then the whole binary must be re-compiled as normal.
|
||||||
|
|
||||||
After that you an use the same technique described in the previous
|
After that you an use the same technique described in the previous
|
||||||
section to add an import and register for you application to ``main.py``
|
section to add an import and register for you application from ``main.py``
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -352,8 +373,10 @@ section to add an import and register for you application to ``main.py``
|
||||||
external FLASH then the frozen version will be loaded.
|
external FLASH then the frozen version will be loaded.
|
||||||
|
|
||||||
In many cases it is possible to avoid rebuilding the binary in order to
|
In many cases it is possible to avoid rebuilding the binary in order to
|
||||||
test new features by parsing the code in the global namespace and then
|
test new features by directly parsing the code in the global
|
||||||
patching it into the existing code. For example the following can be used
|
namespace (e.g. using ``wasptool --exec`` rather than ``wasptool --upload``
|
||||||
|
combined with ``import``). With the code in the global namespace it can
|
||||||
|
then be patched into the system. For example the following can be used
|
||||||
to adopt a new version of the CST816S driver:
|
to adopt a new version of the CST816S driver:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
@ -361,7 +384,7 @@ section to add an import and register for you application to ``main.py``
|
||||||
./tools/wasptool\
|
./tools/wasptool\
|
||||||
--exec wasp/drivers/cst816s.py\
|
--exec wasp/drivers/cst816s.py\
|
||||||
--eval "watch.touch = CST816S(watch.i2c)"`
|
--eval "watch.touch = CST816S(watch.i2c)"`
|
||||||
|
|
||||||
Application entry points
|
Application entry points
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ Application Library
|
||||||
Built-in
|
Built-in
|
||||||
--------
|
--------
|
||||||
|
|
||||||
The built-in application are summarised below but since these apps are
|
The built-in application are summarised below but because these apps are
|
||||||
considers to be examples they are described in detail as part of the
|
treated as examples they are described in detail as part of the
|
||||||
:ref:`Wasp-os Reference Manual`:
|
:ref:`Wasp-os Reference Manual`:
|
||||||
|
|
||||||
* :py:class:`.ClockApp`
|
* :py:class:`.ClockApp`
|
||||||
|
@ -25,18 +25,20 @@ Watch faces
|
||||||
|
|
||||||
.. automodule:: apps.fibonacci_clock
|
.. automodule:: apps.fibonacci_clock
|
||||||
|
|
||||||
This is enabled by default in the simulator. The app is bundled in the
|
This app is enabled by default in the simulator.
|
||||||
firmware image but it is disabled by default to keep RAM available for
|
The app is also frozen into the firmware image but it is disabled by
|
||||||
user developed applications. It can be enabled by modifying ``main.py``.
|
default in order to keep RAM available for user developed applications.
|
||||||
|
It can be enabled by modifying ``main.py``.
|
||||||
|
|
||||||
Games
|
Games
|
||||||
-----
|
-----
|
||||||
|
|
||||||
.. automodule:: apps.gameoflife
|
.. automodule:: apps.gameoflife
|
||||||
|
|
||||||
This is enabled by default in the simulator. The app is bundled in the
|
This app is enabled by default in the simulator.
|
||||||
firmware image but it is disabled by default to keep RAM available for
|
The app is also frozen into the firmware image but it is disabled by
|
||||||
user developed applications. It can be enabled by modifying ``main.py``.
|
default in order to keep RAM available for user developed applications.
|
||||||
|
It can be enabled by modifying ``main.py``.
|
||||||
|
|
||||||
Integration
|
Integration
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -10,11 +10,12 @@ Introduction
|
||||||
|
|
||||||
Anyone can contribute to the wasp-os project. Contributions are typically made
|
Anyone can contribute to the wasp-os project. Contributions are typically made
|
||||||
via github using the typical fork-and-pull-request approach. Contributors who
|
via github using the typical fork-and-pull-request approach. Contributors who
|
||||||
do not wish to use github are also welcome to share patches using
|
do not wish to use github are welcome to share patches using ``git
|
||||||
``git format-patch --to wasp-os@redfelineninja.org.uk`` and ``git send-email``.
|
format-patch --to wasp-os@redfelineninja.org.uk`` and ``git send-email``. In
|
||||||
In both cases, the code will be reviewed by a project maintainer, so please
|
both cases, the code will be reviewed by a project maintainer, so please
|
||||||
anticipate review comments. Typically pull requests will not be merged if there
|
anticipate review comments and requests for changes. Typically pull
|
||||||
are open questions or requests for changes that have not been acted on.
|
requests will not be merged if there are open questions or requests for
|
||||||
|
changes that have not been acted on.
|
||||||
|
|
||||||
All contributions must include a ``Signed-off-by`` tag added by the contributor
|
All contributions must include a ``Signed-off-by`` tag added by the contributor
|
||||||
who submits the patch or patches. The ``Signed-off-by`` tag is added at the end
|
who submits the patch or patches. The ``Signed-off-by`` tag is added at the end
|
||||||
|
@ -68,7 +69,7 @@ easily:
|
||||||
Additionally, please be aware that github will not send out automatic
|
Additionally, please be aware that github will not send out automatic
|
||||||
notifications to let the maintainer know that you have pushed an update to the
|
notifications to let the maintainer know that you have pushed an update to the
|
||||||
pull-request. Follow up the above with a comment on the pull request thread
|
pull-request. Follow up the above with a comment on the pull request thread
|
||||||
saying that your contribution should be ready to go.
|
saying that your contribution has been updated and is ready for another look.
|
||||||
|
|
||||||
Code of Conduct
|
Code of Conduct
|
||||||
---------------
|
---------------
|
||||||
|
|
101
docs/install.rst
101
docs/install.rst
|
@ -31,9 +31,8 @@ a complete sphinx toolchain:
|
||||||
sudo apt install sphinx graphviz python3-recommonmark
|
sudo apt install sphinx graphviz python3-recommonmark
|
||||||
|
|
||||||
Alternatively, if your operating system does not package some or any of
|
Alternatively, if your operating system does not package some or any of
|
||||||
the aforementioned Python modules that were included in the previous
|
the above mentioned Python modules then you can install all of them
|
||||||
command, you can install all of them with pip instead. Make sure to
|
with pip instead:
|
||||||
adapt the following command appropriately:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
|
@ -48,37 +47,37 @@ tested using the `GNU-RM toolchain
|
||||||
|
|
||||||
There are known problems with toolchains older than gcc-7.3 when
|
There are known problems with toolchains older than gcc-7.3 when
|
||||||
link time optimization is enabled during the MicroPython build
|
link time optimization is enabled during the MicroPython build
|
||||||
(and LTO is enabled by default).
|
(LTO is enabled by default).
|
||||||
|
|
||||||
Fetch the code from
|
Fetch the code from
|
||||||
`https://github.com/daniel-thompson/wasp-os <https://github.com/daniel-thompson/wasp-os>`_ :
|
`https://github.com/daniel-thompson/wasp-os <https://github.com/daniel-thompson/wasp-os>`_ and download the prerequisites:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
git clone https://github.com/daniel-thompson/wasp-os
|
git clone https://github.com/daniel-thompson/wasp-os
|
||||||
cd wasp-os
|
cd wasp-os
|
||||||
make submodules
|
make submodules
|
||||||
make softdevice
|
make softdevice
|
||||||
|
|
||||||
To build the firmware select the command appropriate for your board from the
|
To build the firmware select the command appropriate for your board from the
|
||||||
list below:
|
list below:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
make -j `nproc` BOARD=pinetime all
|
make -j `nproc` BOARD=pinetime all
|
||||||
make -j `nproc` BOARD=k9 all
|
make -j `nproc` BOARD=k9 all
|
||||||
make -j `nproc` BOARD=p8 all
|
make -j `nproc` BOARD=p8 all
|
||||||
|
|
||||||
To rebuild the documentation try:
|
To rebuild the documentation:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
make docs
|
make docs
|
||||||
|
|
||||||
Device Support
|
Device Support
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
wasp-os can run on multiple devices and, in time, will hopefully be ported to
|
Wasp-os can run on multiple devices and, in time, will hopefully be ported to
|
||||||
many more.
|
many more.
|
||||||
|
|
||||||
In terms of deciding which device to buy we can suggest two criteria to help.
|
In terms of deciding which device to buy we can suggest two criteria to help.
|
||||||
|
@ -95,9 +94,9 @@ second criteria is not technical, it is about community. The Pine64 PineTime is
|
||||||
unique among the devices supported by wasp-os because it is intended that the
|
unique among the devices supported by wasp-os because it is intended that the
|
||||||
watch be used to run a variety of different open source or free software
|
watch be used to run a variety of different open source or free software
|
||||||
operating systems. By manufacturing a watch with the intention that it be
|
operating systems. By manufacturing a watch with the intention that it be
|
||||||
hacked every which way from Sunday then we get a bigger stronger community
|
hacked every which way from Sunday then we get a bigger, stronger community
|
||||||
focused on the PineTime. There is a vibrant support forum, multiple different
|
focused on the PineTime. There is a vibrant support forum, multiple different
|
||||||
OS developers (who share ideas and knowledge even if hacking on very different
|
OS developers (who share ideas and knowledge even when hacking on very different
|
||||||
code bases) combined with a `near complete set of hardware documentation
|
code bases) combined with a `near complete set of hardware documentation
|
||||||
<https://wiki.pine64.org/index.php/PineTime>`_.
|
<https://wiki.pine64.org/index.php/PineTime>`_.
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ only sold for short periods and may experience undocumented technical changes
|
||||||
between manufacturing runs that can cause compatibility problems. This makes it
|
between manufacturing runs that can cause compatibility problems. This makes it
|
||||||
hard for a large community to form around these devices.
|
hard for a large community to form around these devices.
|
||||||
|
|
||||||
Thus the second criteria it to think about your own needs and abilities. If
|
Thus the second criteria it to think about your own needs and abilities. If
|
||||||
you want to enjoy the social and community aspects of working together on open
|
you want to enjoy the social and community aspects of working together on open
|
||||||
source watch development then you should look very closely at the PineTime.
|
source watch development then you should look very closely at the PineTime.
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ based on an nRF52832 SoC and includes a 240x240 colour display with touch
|
||||||
screen, a step counter and a heart rate sensor.
|
screen, a step counter and a heart rate sensor.
|
||||||
|
|
||||||
wasp-os can be installed directly from the factory default operating
|
wasp-os can be installed directly from the factory default operating
|
||||||
system using an over-the-air update with no tools or disassembly is
|
system using an over-the-air update with no tools or disassembly
|
||||||
required. nRF Connect for Android can be used to install both the
|
required. nRF Connect for Android can be used to install both the
|
||||||
:ref:`wasp-bootloader<Bootloader nRF Connect>` and the
|
:ref:`wasp-bootloader<Bootloader nRF Connect>` and the
|
||||||
:ref:`main OS image<Main OS nRF Connect>`.
|
:ref:`main OS image<Main OS nRF Connect>`.
|
||||||
|
@ -132,9 +131,9 @@ required. nRF Connect for Android can be used to install both the
|
||||||
The early adopter PineTime Developer Edition came pre-programmed
|
The early adopter PineTime Developer Edition came pre-programmed
|
||||||
with a proprietary test firmware rather than the current factory
|
with a proprietary test firmware rather than the current factory
|
||||||
default OS. If you have an early adopter unit then it will appear
|
default OS. If you have an early adopter unit then it will appear
|
||||||
in the device list as *Y7S* and the tools needed for an OTA update
|
in the device list as *Y7S*. In this case the process needed for an
|
||||||
are differnt. DaFlasher for Android can be used to install both the
|
OTA update is different. Use DaFlasher for Android to install both
|
||||||
:ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
the :ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
||||||
:ref:`main OS image<Main OS DaFlasher>`.
|
:ref:`main OS image<Main OS DaFlasher>`.
|
||||||
|
|
||||||
The `developer edition <https://store.pine64.org/?product=pinetime-dev-kit>`_
|
The `developer edition <https://store.pine64.org/?product=pinetime-dev-kit>`_
|
||||||
|
@ -152,9 +151,10 @@ provides a 240x240 colour display together with a touch screen and a
|
||||||
physical button, all of which appears as a window on your host computer.
|
physical button, all of which appears as a window on your host computer.
|
||||||
|
|
||||||
The simulator has large quantities of memory and, whilst useful for
|
The simulator has large quantities of memory and, whilst useful for
|
||||||
exploring wasp-os and testing your programs are syntactically correct
|
exploring wasp-os and testing your programs are syntactically correct,
|
||||||
it is not a substitute for testing on real hardware. See
|
it is not a substitute for testing on real hardware. See
|
||||||
:ref:`Testing on the simulator` for more details on how to use the simulator.
|
:ref:`Testing on the simulator` for more details on how to use the
|
||||||
|
simulator.
|
||||||
|
|
||||||
To launch the simulator try:
|
To launch the simulator try:
|
||||||
|
|
||||||
|
@ -162,6 +162,26 @@ To launch the simulator try:
|
||||||
|
|
||||||
make sim
|
make sim
|
||||||
|
|
||||||
|
Colmi P8
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
The `Colmi P8 <https://www.colmi.com/products/p8-smartwatch>`_ is an almost
|
||||||
|
square smart watch based on an nRF52832 SoC and includes a 240x240 colour
|
||||||
|
display with touch screen, a step counter and a heart rate sensor.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The P8 has multiple hardware revisions and the newest version (the
|
||||||
|
one that includes a magnetic charger) uses a different and,
|
||||||
|
currently, unsupported step counter module. The new models will
|
||||||
|
boot wasp-os successfully but the step counter application will
|
||||||
|
be disabled and cannot function.
|
||||||
|
|
||||||
|
DaFlasher for Android can be used to install both the
|
||||||
|
:ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
||||||
|
:ref:`main OS image<Main OS DaFlasher>`. No tools or disassembly is
|
||||||
|
required.
|
||||||
|
|
||||||
Senbono K9
|
Senbono K9
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -171,7 +191,7 @@ rate sensor.
|
||||||
|
|
||||||
The wasp-os port for Senbono K9 does not, at this point, include a driver for
|
The wasp-os port for Senbono K9 does not, at this point, include a driver for
|
||||||
the touch screen because the protocol has not yet been reverse engineered. The
|
the touch screen because the protocol has not yet been reverse engineered. The
|
||||||
touch screen enumerates via I2C at address 70d (or 0x46) and the interrupt can
|
touch screen enumerates via I2C at address 70d (0x46) and the interrupt can
|
||||||
be used to detect touch screen activity but the touch coordinates cannot be
|
be used to detect touch screen activity but the touch coordinates cannot be
|
||||||
read from the hardware. Currently the touch screen can only act as a
|
read from the hardware. Currently the touch screen can only act as a
|
||||||
multi-function button and can be used to cycle through the quick ring and
|
multi-function button and can be used to cycle through the quick ring and
|
||||||
|
@ -186,22 +206,6 @@ DaFlasher for Android can be used to install both the
|
||||||
:ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
:ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
||||||
:ref:`main OS image<Main OS DaFlasher>`. No tools or disassembly is required.
|
:ref:`main OS image<Main OS DaFlasher>`. No tools or disassembly is required.
|
||||||
|
|
||||||
Colmi P8
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The `Colmi P8 <https://www.colmi.com/products/p8-smartwatch>`_ is an almost
|
|
||||||
square smart watch based on an nRF52832 SoC and includes a 240x240 colour
|
|
||||||
display with touch screen, a step counter and a heart rate sensor.
|
|
||||||
|
|
||||||
The P8 has multiple hardware revisions and the newest version (the one that
|
|
||||||
includes a magnetic charger) uses a different and, currently, unsupported step
|
|
||||||
counter module. The new models will boot wasp-os successfully but the step
|
|
||||||
counter application will not be included.
|
|
||||||
|
|
||||||
DaFlasher for Android can be used to install both the
|
|
||||||
:ref:`wasp-bootloader<Bootloader DaFlasher>` and the
|
|
||||||
:ref:`main OS image<Main OS DaFlasher>`. No tools or disassembly is required.
|
|
||||||
|
|
||||||
Installing wasp-bootloader
|
Installing wasp-bootloader
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
@ -213,6 +217,9 @@ nRF Connect for Android
|
||||||
For Pine64 PineTime devices running Infinitime then nRF Connect for Android
|
For Pine64 PineTime devices running Infinitime then nRF Connect for Android
|
||||||
can be used to install wasp-bootloader:
|
can be used to install wasp-bootloader:
|
||||||
|
|
||||||
|
* Ensure the watch is fully charged before attempting to install the
|
||||||
|
wasp-bootloader. Running out of power during this process can brick
|
||||||
|
sealed devices.
|
||||||
* Copy ``reloader-mcuboot.zip`` (see :ref:`Building wasp-os from source`) to
|
* Copy ``reloader-mcuboot.zip`` (see :ref:`Building wasp-os from source`) to
|
||||||
your Android device and download
|
your Android device and download
|
||||||
`nRF Connect <https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp>`_
|
`nRF Connect <https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp>`_
|
||||||
|
@ -237,9 +244,10 @@ can be used to install wasp-bootloader:
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
It you want to restore the PineTime factory firmware then you can
|
If you want to restore the PineTime factory firmware then you can
|
||||||
use nRF Connect to do this. Use nRF Connect to send
|
use nRF Connect to do this. Perform a long press reset and then
|
||||||
``reloader-factory.zip`` to the wasp-bootloader (called *PineDFU*).
|
use nRF Connect to send ``reloader-factory.zip`` to the *PineDFU*
|
||||||
|
device.
|
||||||
|
|
||||||
.. _Bootloader DaFlasher:
|
.. _Bootloader DaFlasher:
|
||||||
|
|
||||||
|
@ -248,6 +256,9 @@ DaFlasher for Android
|
||||||
|
|
||||||
To install the bootloader using DaFlasher for Android:
|
To install the bootloader using DaFlasher for Android:
|
||||||
|
|
||||||
|
* Ensure the watch is fully charged before attempting to install the
|
||||||
|
wasp-bootloader. Running out of power during this process can brick
|
||||||
|
sealed devices.
|
||||||
* Download and install
|
* Download and install
|
||||||
`DaFlasher <https://play.google.com/store/apps/details?id=com.atcnetz.paatc.patc>`_
|
`DaFlasher <https://play.google.com/store/apps/details?id=com.atcnetz.paatc.patc>`_
|
||||||
and copy the DaFlasher bootloaders to your Android device. You will need
|
and copy the DaFlasher bootloaders to your Android device. You will need
|
||||||
|
@ -377,6 +388,8 @@ To install the main firmware from a GNU/Linux workstation:
|
||||||
:ref:`Building wasp-os from source`) to the device. For example:
|
:ref:`Building wasp-os from source`) to the device. For example:
|
||||||
``tools/ota-dfu/dfu.py -z micropython.zip -a A0:B1:C2:D3:E3:F5 --legacy``
|
``tools/ota-dfu/dfu.py -z micropython.zip -a A0:B1:C2:D3:E3:F5 --legacy``
|
||||||
|
|
||||||
|
.. _Troubleshooting:
|
||||||
|
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ the MicroPython distribution, are licensed under under different open
|
||||||
source licenses. The licensing for these components is clearly
|
source licenses. The licensing for these components is clearly
|
||||||
indicated and reinforced by the directory and sub-module structure.
|
indicated and reinforced by the directory and sub-module structure.
|
||||||
|
|
||||||
Additionally binary releases of wasp-os include the Nordic Softdevice
|
Additionally binary releases of wasp-os include a binary copy of the
|
||||||
which is licensed under the 5-clause Nordic license.
|
Nordic Softdevice which is licensed under the 5-clause Nordic license.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
gnu-lgpl-v3.0.rst
|
gnu-lgpl-v3.0.rst
|
||||||
|
|
|
@ -5,6 +5,7 @@ battery = 'Default battery icon'
|
||||||
bomb = 'Small bomb icon'
|
bomb = 'Small bomb icon'
|
||||||
app = 'Default application icon'
|
app = 'Default application icon'
|
||||||
clock = 'Default digital clock icon'
|
clock = 'Default digital clock icon'
|
||||||
|
headset = 'Default music player icon'
|
||||||
settings = 'Default settings icon'
|
settings = 'Default settings icon'
|
||||||
torch = 'Default torch or flashlight icon'
|
torch = 'Default torch or flashlight icon'
|
||||||
up_arrow = 'Small (16x9) up arrow'
|
up_arrow = 'Small (16x9) up arrow'
|
||||||
|
|
Loading…
Reference in a new issue