Merge remote-tracking branch 'ofw/dev' into mntm-dev

This commit is contained in:
Willy-JL
2024-10-14 23:44:44 +01:00
167 changed files with 6280 additions and 2155 deletions
+63 -67
View File
@@ -3,18 +3,15 @@
## Basic info
On system startup, most of the peripheral devices are under reset and not clocked by default. This is done to reduce power consumption and to guarantee that the device will always be in the same state before use.
Some crucial peripherals are enabled right away by the system, others must be explicitly enabled by the user code.
**NOTE:** Here and afterwards, the word *"system"* refers to any code belonging to the operating system, hardware drivers or built-in apps.
To **ENABLE** a peripheral, call `furi_hal_bus_enable()`. At the time of the call, the peripheral in question **MUST** be disabled;
otherwise a crash will occur to indicate improper use. This means that any given peripheral cannot be enabled twice or more without disabling it first.
To **ENABLE** a peripheral, call `furi_hal_bus_enable()`. At the time of the call, the peripheral in question MUST be disabled, otherwise a crash will occur to indicate improper use. This means that any given peripheral cannot be enabled twice or more without disabling it first.
To **DISABLE** a peripheral, call `furi_hal_bus_disable()`. Likewise, the peripheral in question **MUST** be enabled, otherwise a crash will occur.
To **DISABLE** a peripheral, call `furi_hal_bus_disable()`. Likewise, the peripheral in question MUST be enabled, otherwise a crash will occur.
To **RESET** a peripheral, call `furi_hal_bus_reset()`. The peripheral in question MUST be enabled, otherwise a crash will occur.
This method is used whenever it is necessary to reset all the peripheral's registers to their initial states without disabling it.
To **RESET** a peripheral, call `furi_hal_bus_reset()`. The peripheral in question MUST be enabled, otherwise a crash will occur. This method is used whenever it is necessary to reset all the peripheral's registers to their initial states without disabling it.
## Peripherals
@@ -25,26 +22,26 @@ Built-in peripherals are divided into three categories:
### Always-on peripherals
Below is the list of peripherals that are enabled by the system. The user code must **NEVER** attempt to disable them.
Below is the list of peripherals that are enabled by the system. The user code must NEVER attempt to disable them. If a corresponding API is provided, the user code must employ it in order to access the peripheral.
*Table 1* — Peripherals enabled by the system
| Peripheral | Enabled at |
|:-------------:|:---------------------------:|
| DMA1 | `furi_hal_dma.c` |
| DMA2 | -- |
| DMAMUX | -- |
| GPIOA | `furi_hal_resources.c` |
| GPIOB | -- |
| GPIOC | -- |
| GPIOD | -- |
| GPIOE | -- |
| GPIOH | -- |
| PKA | `furi_hal_bt.c` |
| AES2 | -- |
| HSEM | -- |
| IPCC | -- |
| FLASH | enabled by hardware |
| Peripheral | Enabled at |
| :-----------: | :-----------------------: |
| DMA1 | `furi_hal_dma.c` |
| DMA2 | -- |
| DMAMUX | -- |
| GPIOA | `furi_hal_resources.c` |
| GPIOB | -- |
| GPIOC | -- |
| GPIOD | -- |
| GPIOE | -- |
| GPIOH | -- |
| PKA | `furi_hal_bt.c` |
| AES2 | -- |
| HSEM | -- |
| IPCC | -- |
| FLASH | enabled by hardware |
### On-demand system peripherals
@@ -54,64 +51,63 @@ When not using the API, these peripherals MUST be enabled by the user code and t
*Table 2* — Peripherals enabled and disabled by the system
| Peripheral | API header file |
|:--------------:|:------------------------:|
| RNG | `furi_hal_random.h` |
| SPI1 | `furi_hal_spi.h` |
| SPI2 | -- |
| I2C1 | `furi_hal_i2c.h` |
| I2C3 | -- |
| USART1 | `furi_hal_serial.h` |
| LPUART1 | -- |
| USB | `furi_hal_usb.h` |
| Peripheral | API header file |
| :-----------: | :-------------------: |
| RNG | `furi_hal_random.h` |
| SPI1 | `furi_hal_spi.h` |
| SPI2 | -- |
| I2C1 | `furi_hal_i2c.h` |
| I2C3 | -- |
| USART1 | `furi_hal_serial.h` |
| LPUART1 | -- |
| USB | `furi_hal_usb.h` |
### On-demand shared peripherals
Below is the list of peripherals that are not enabled by default and **MUST** be enabled by the user code each time it accesses them.
Below is the list of peripherals that are not enabled by default and MUST be enabled by the user code each time it accesses them.
Note that some of these peripherals may also be used by the system to implement its certain features.
The system will take over any given peripheral only when the respective feature is in use.
*Table 3* — Peripherals enabled and disabled by user
| Peripheral | System | Purpose |
|:----------:|:------:|:----------------------------------------|
| CRC | | |
| TSC | | |
| ADC | | |
| QUADSPI | | |
| TIM1 | yes | subghz, lfrfid, nfc, infrared, etc... |
| TIM2 | yes | subghz, infrared, etc... |
| TIM16 | yes | speaker |
| TIM17 | yes | cc1101_ext |
| LPTIM1 | yes | tickless idle timer |
| LPTIM2 | yes | pwm |
| SAI1 | | |
| LCD | | |
| Peripheral | System | Purpose |
| :-----------: | :-------: | ------------------------------------- |
| CRC | | |
| TSC | | |
| ADC | | |
| QUADSPI | | |
| TIM1 | yes | subghz, lfrfid, nfc, infrared, etc... |
| TIM2 | yes | subghz, infrared, etc... |
| TIM16 | yes | speaker |
| TIM17 | yes | cc1101_ext |
| LPTIM1 | yes | tickless idle timer |
| LPTIM2 | yes | pwm |
| SAI1 | | |
| LCD | | |
## DMA
The `DMA1`, `DMA2` peripherals are a special case in that they have multiple independent channels.
Some channels may be in use by the system.
The DMA1,2 peripherals are a special case in that they have multiple independent channels. Some of the channels may be in use by the system.
Below is the list of DMA channels and their usage by the system.
*Table 4* — DMA channels
| DMA | Channel | System | Purpose |
|:------:|:-------:|:------:|:-----------------------------|
| DMA1 | 1 | yes | digital signal |
| -- | 2 | yes | -- |
| -- | 3 | | |
| -- | 4 | yes | pulse reader |
| -- | 5 | | |
| -- | 6 | yes | USART_Rx |
| -- | 7 | yes | LPUART_Rx |
| DMA2 | 1 | yes | infrared, lfrfid, subghz, |
| -- | 2 | yes | -- |
| -- | 3 | yes | cc1101_ext |
| -- | 4 | yes | cc1101_ext |
| -- | 5 | yes | cc1101_ext |
| -- | 6 | yes | SPI |
| -- | 7 | yes | SPI |
| DMA | Channel | System | Purpose |
| :---: | :-------: | :-------: | ------------------------- |
| DMA1 | 1 | yes | digital signal |
| -- | 2 | yes | -- |
| -- | 3 | | |
| -- | 4 | yes | pulse reader |
| -- | 5 | | |
| -- | 6 | yes | USART_Rx |
| -- | 7 | yes | LPUART_Rx |
| DMA2 | 1 | yes | infrared, lfrfid, subghz, |
| -- | 2 | yes | -- |
| -- | 3 | yes | cc1101_ext |
| -- | 4 | yes | cc1101_ext |
| -- | 5 | yes | cc1101_ext |
| -- | 6 | yes | SPI |
| -- | 7 | yes | SPI |
@@ -0,0 +1,88 @@
# Debugging via the Devboard {#dev_board_debugging_guide}
On this page, you'll learn about how debugging via the Wi-Fi Developer Board works. To illustrate this process, we'll start a debug session for Flipper Zero's firmware in VS Code using the native Flipper Build Tool.
***
## Overview
The Developer Board acts as the debug probe, which provides a bridge between the IDE (integrated development environment) with a debugger running on a host computer and the target microcontroller (in your Flipper Zero). The user controls the debugging process on the computer connected to the Developer Board via [Wi-Fi](#dev_board_wifi_connection) or [USB cable](#dev_board_usb_connection).
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_hardware_CDN.jpg width=700
Data exchange between the Wi-Fi Developer Board and your Flipper Zero is conducted via the Serial Wire Debug interface. The following GPIO pins serve this purpose:
- **Pin 10:** Serial Wire Clock (SWCLK)
- **Pin 12:** Serial Wire Debug Data I/O (SWDIO)
To learn more about Flipper Zero pinout, visit [GPIO & modules in Flipper Docs](https://docs.flipper.net/gpio-and-modules).
***
## Prerequisites
### Step 1. Installing Git
You'll need Git installed on your computer to clone the firmware repository. If you don't have Git, install it following the [official installation guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
### Step 2. Building the firmware
Before starting debugging, you need to clone and build Flipper Zero firmware:
1. Open the **Terminal** (on Linux & macOS) or **PowerShell** (on Windows) in the directory where you want to store the firmware source code.
2. Clone the firmware repository:
```
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
cd flipperzero-firmware
```
3. Run the **Flipper Build Tool (FBT)** to build the firmware:
```
./fbt
```
***
## Debugging the firmware
From the **flipperzero-firmware** directory that you cloned earlier, run the following command:
```
./fbt flash
```
This will upload the firmware you've just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware. We recommend using **VS Code** with the recommended extensions (as described below), and we have pre-made configurations for it.
To debug in **VS Code**, do the following:
1. In VS Code, open the **flipperzero-firmware** directory.
2. You should see a notification about recommended extensions. Install them.
If there were no notifications, open the **Extensions** tab, enter `@recommended` in the search bar, and install the workspace recommendations.
3. Run the `./fbt vscode_dist` command. This will generate the VS Code configuration files needed for debugging.
4. In VS Code, open the **Run and Debug** tab and select a debugger from the dropdown menu:
- **Attach FW (blackmagic):** Can be used via **Wi-Fi** or **USB**
- **Attach FW (DAP):** Can be used via **USB** only
Note that when debugging via USB, you need to make sure the selected debugger matches the debug mode on your Devboard. To check the debug mode on your Devboard, access the Devboard's web interface as described [here](#dev_board_wifi_connection) and check the **USB mode** field. If you want to use a different debug mode, enable this mode by following the steps in [Devboard debug modes](#dev_board_debug_modes).
5. If needed, flash your Flipper Zero with the `./fbt flash` command, then click the ▷ **Start Debugging** button in the debug sidebar to start the debugging session.
6. Note that starting a debug session halts the execution of the firmware, so you'll need to click the I▷ **Continue** button on the toolbar at the top of your VS Code window to continue execution.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_VS_Code.jpg width=900
> [!note]
> If you want to use a different debug mode on your Developer Board, visit [Devboard debug modes](#dev_board_debug_modes).
>
> If you want to read logs via the Developer Board, see [Reading logs via the Devboard](#dev_board_reading_logs).
>
> To learn about debugging in VS Code, see [VS Code official guide](https://code.visualstudio.com/docs/editor/debugging).
@@ -0,0 +1,33 @@
# Devboard debug modes {#dev_board_debug_modes}
The Wi-Fi Devboard for Flipper Zero supports **Black Magic** and **DAPLink** debug modes, and you can switch between them depending on your needs. Note that available modes depend on connection:
- **Wi-Fi:** Only **Black Magic** mode is available.
- **USB:** Switch between **Black Magic** (default) and **DAPLink**. Learn more about switching debug modes for USB connection below.
> [!note]
> Black Magic mode doesn't support RTOS threads, but you can still perform other debugging operations.
***
## Switching debug modes for USB connection
Switching debug modes for working via USB has to be done wirelessly (yes, you read that correctly). Additionally, depending on how the Devboard wireless connection is configured, you may need to follow different steps for **Wi-Fi access point mode** or **Wi-Fi client mode**:
1. If the Devboard isn't connected to your Flipper Zero, turn off your Flipper Zero and connect the Developer Board, then turn the device back on.
2. Access the Devboard's web interface:
- [Wi-Fi access point mode](#wifi-access-point)
- [Wi-Fi client mode](#wifi-client-mode)
3. In the **WiFi** tab, click the **USB mode** option and select **BlackMagicProbe** or **DapLink**.
4. Click **SAVE**, then click **REBOOT** to apply the changes.
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_switching_modes_CDN.jpg width=700
> [!note]
> After switching debug modes on your Devboard, remember to select the same debugger in **VS Code** in the **Run and Debug** tab, and click the ▷ **Start Debugging** button.
@@ -1,104 +1,112 @@
# Firmware update on Developer Board {#dev_board_fw_update}
> [!IMPORTANT]
>
> It's important to regularly update your Developer Board to ensure that you have access to the latest features and bug fixes.
> This tutorial will guide you through the necessary steps to update the firmware of your Developer Board.
It's important to regularly update your Developer Board to ensure that you have access to the latest features and bug fixes. This page will guide you through the necessary steps to update the firmware of your Developer Board.
This tutorial assumes that you're familiar with the basics of the command line.
> [!note]
> This guide assumes that you're familiar with the basics of the command line. If you're new to it, we recommend checking out these [Windows](https://learn.microsoft.com/en-us/powershell/scripting/learn/ps101/01-getting-started?view=powershell-7.4) or [macOS/Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
If youre not, please refer to the [Windows](https://www.digitalcitizen.life/command-prompt-how-use-basic-commands/) or [MacOS / Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
***
## Installing the micro Flipper Build Tool
## Step 1. Install the micro Flipper Build Tool
Micro Flipper Build Tool (uFBT) is a cross-platform tool that enables basic development tasks for Flipper Zero, such as building and debugging applications, flashing firmware, and creating VS Code development configurations.
is a cross-platform tool developed and supported by our team that enables basic development tasks for Flipper Zero, such as building and debugging applications, flashing firmware, creating VS Code development configurations, and flashing firmware to the Wi-Fi Developer Board.
Install uFBT on your computer by running the following command in the Terminal:
**On Linux & macOS:**
**For Linux & macOS:**
Run the following command in the Terminal:
```bash
```
python3 -m pip install --upgrade ufbt
```
**For Windows:**
**On Windows:**
```powershell
python -m pip install --upgrade ufbt
```
1. Download the latest version of Python on
2. Run the following command in the PowerShell
If you want to learn more about uFBT, visit [the project's page](https://pypi.org/project/ufbt/).
```
py -m pip install --upgrade ufbt
```
## Connecting the Developer Board to your computer
***
## Step 2. Connect the Devboard to PC
To update the firmware, you need to switch your Developer Board to Bootloader mode, connect to a PC via a USB cable, and make sure that the PC detects the Developer Board:
1. List all of the serial devices on your computer.
**Windows**
- **macOS:** Run the `ls /dev/cu.*` command in the Terminal.
On Windows, go to Device Manager and expand the Ports (COM & LPT) section.
- **Linux:** Run the `ls /dev/tty*` command in the Terminal.
**macOS**
- **Windows:** Go to **Device Manager** and expand the **Ports (COM & LPT)** section.
On macOS, you can run the following command in the Terminal:
```bash
ls /dev/cu.*
```
**Linux**
On Linux, you can run the following command in the Terminal:
```text
ls /dev/tty*
```
View the devices in the list.
2. Connect the Developer Board to your computer using a USB-C cable.
![The Developer Board in Wired mode](https://github.com/user-attachments/assets/d13e4e90-d83d-45bf-8787-6eadba590795)
4. Switch your Developer Board to Bootloader mode:
3.1. Press and hold the **BOOT** button.
3.2. Press the **RESET** button while holding the **BOOT** button.
3.3. Release the **BOOT** button.
![You can easily switch the Dev Board to Bootloader mode](https://github.com/user-attachments/assets/aecc957f-f37b-4bec-af9f-9efd4837152e)
6. Repeat Step 1 and view the name of your Developer Board that appeared in the list.
For example, on macOS:
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_update_wired_connection.jpg width=700
```shell
/dev/cu.usbmodem01
```
3. Switch your Developer Board to Bootloader mode:
## Flashing the firmware
1. Press and hold the **BOOT** button.
2. Press the **RESET** button while holding the **BOOT** button.
3. Release the **BOOT** button.
To flash the firmware onto your Developer Board, run the following command in the terminal:
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot_to_bootloader.png width=700
```shell
4. Repeat **Step 1** and view the name of your Developer Board that appeared in the list.
***
## Step 3. Flash the firmware
**On Linux & macOS:**
```
python3 -m ufbt devboard_flash
```
**On Windows:** Run the following command in the PowerShell:
```
py -m ufbt devboard_flash
```
You should see the following message: `WiFi board flashed successfully`.
## If flashing failed
### If flashing failed
If you get an error message during the flashing process, such as this:
Occasionally, you might get an error message during the flashing process, such as:
```shell
```
A fatal error occurred: Serial data stream stopped: Possible serial noise or corruption.
```
Or this:
*or*
```shell
```
FileNotFoundError: [Errno 2] No such file or directory: '/dev/cu.usbmodem01'
```
Try doing the following:
* Disconnect the Developer Board from your computer, then reconnect it.
* Use a different USB port on your computer.
* Use a different USB-C cable.
To fix it, try doing the following:
## Finishing the installation
- Disconnect the Developer Board from your computer, then reconnect it. After that, switch your Developer Board to Bootloader mode once again, as described in
After flashing the firmware:
1. Reboot the Developer Board by pressing the **RESET** button. ![Reset the Developer Board](https://github.com/user-attachments/assets/7527dd7b-eaa5-4fac-8d67-7ba52e552756)
3. Disconnect and reconnect the USB-C cable.
- Use a different USB port on your computer.
- Use a different USB-C cable.
***
## Step 4. Finish the installation
1. Reboot the Developer Board by pressing the **RESET** button.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot_after_flashing.jpg width=700
2. Disconnect and reconnect the USB-C cable.
You've successfully updated the firmware of your Developer Board!
If you followed the **Get started with the Devboard** guide, you're ready for the next step: [Step 3. Plug the Devboard into Flipper Zero](#dev_board_get_started_step-3).
The Developer Board should appear as a serial device on your computer. Now, you can use it with the Black Magic Debug client of your choice.
@@ -1,175 +1,80 @@
# Get started with the Dev Board {#dev_board_get_started}
The Wi-Fi Developer Board serves as a tool to debug the Flipper Zero firmware. To debug the firmware, the initial step involves compiling the firmware from its source code. This process enables the debugging functionality within the firmware and generates all the necessary files required for debugging purposes.
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_developer_board_box_CDN.jpg width=700
> [!IMPORTANT]
>
> Building and debugging the Flipper Zero firmware is fully supported on MacOS and Linux.
> Support for Windows is in beta test.
## Updating the firmware of your Developer Board
Update the firmware of your Developer Board before using it. For more information, visit [Firmware update on Developer Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/update).
## Installing Git
You'll need Git installed on your computer to clone the firmware repository. If you don't have Git, install it by doing the following:
### MacOS
On MacOS, install the **Xcode Command Line Tools** package, which includes Git as one of the pre-installed command-line utilities, by running in the Terminal the following command:
```bash
xcode-select --install
```
### Linux
On Linux, you can install Git using your package manager. For example, on Ubuntu, run in the Terminal the following command:
```bash
sudo apt install git
```
For other distributions, refer to your package manager documentation.
Before you start using your Devboard, you need to prepare your Flipper Zero and Devboard for debugging. In this guide, we'll walk you through all the necessary steps and provide links to explore the Devboard's capabilities further.
***
## Building the firmware
## Step 1. Enable Debug Mode on your Flipper Zero
First, clone the firmware repository:
Since the main purpose of the Developer board is to debug applications on Flipper Zero, you first need to enable Debug Mode. To do so, go to **Settings → System** and set **Debug** to **ON**.
```bash
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
cd flipperzero-firmware
```
\image html https://cdn.flipperzero.one/Flipper_Zero_enamble_debug_CDN.jpg width=700
Then, run the **Flipper Build Tool** (FBT) to build the firmware:
> [!note]
> Debug Mode needs to be re-enabled after each update of Flipper Zero's firmware.
```bash
./fbt
```
Debug Mode allows you to debug your apps for Flipper Zero, as well as access debugging options in apps via the user interface and CLI. To learn more about Flipper Zero CLI, visit [Command-line interface in Flipper Docs](https://docs.flipper.net/development/cli).
\image html https://cdn.flipperzero.one/Flipper_Zero_Command_Line_Interface_CDN.jpg width=700
***
## Connecting the Developer Board
## Step 2. Update firmware on the Developer Board
The Developer Board can work in the **Wired** mode and two **Wireless** modes: **Wi-Fi access point (AP)** mode and **Wi-Fi client (STA)** mode. The Wired mode is the simplest to set up, but requires a USB Type-C cable. The Wireless modes are more complex to set up, but they allow you to debug your Flipper Zero wirelessly.
The Developer Board comes with stock firmware that may not include all the latest features and bug fixes. To ensure optimal performance, please update your board's firmware using the instructions in [Firmware update on Devboard](#dev_board_fw_update).
> [!TIP]
>
> Use the following credentials when connecting to the Developer Board in **Wi-Fi access point** mode:
> Name: **blackmagic**
> Password: **iamwitcher**
***
## Wired
## Step 3. Plug the Devboard into Flipper Zero {#dev_board_get_started_step-3}
![The Developer Board in Wired mode](https://github.com/user-attachments/assets/32938d4a-20b7-4a53-8b36-608cf0112c9a)
Once your Developer Board firmware is up to date, you can proceed to plug it into your Flipper Zero. Two important things to keep in mind:
To connect the Developer Board in **Wired** mode, do the following:
1. **Power off your Flipper Zero before plugging in the Developer Board.**
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
If you skip this step, you may corrupt the data stored on the microSD card. Connecting external modules with a large capacitive load may affect the microSD card's power supply since both the microSD card and external module are powered from the same 3.3 V power source inside Flipper Zero.
2. On your computer, open the **Terminal** and run the following:
2. **Make sure the Developer Board is inserted all the way in.**
### MacOS
```shell
ls /dev/cu.*
```
### Linux
```bash
ls /dev/tty*
```
Note the list of devices.
If your Flipper Zero isn't in a silicone case, insert the module all the way in so there is no gap between your Flipper Zero and the Devboard. You may need to apply more force to insert it completely. After that, press and hold the **BACK** button to power on your Flipper Zero.
3. Connect the Developer Board to your computer via a USB-C cable.
\image html https://cdn.flipperzero.one/Flipper_Zero_external_module_without_case_CDN.jpg width=700
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
If your Flipper Zero is in a silicone case, insert the module all the way in so there is no gap in the middle between the silicone case and the module. After that, press and hold the **BACK** button to power on your Flipper Zero.
> [!NOTE]
>
> If the Developer Board doesn't appear in the list of devices, try using a different cable, USB port, or computer.
\image html https://cdn.flipperzero.one/Flipper_Zero_external_module_with_case_CDN.jpg width=700
<br />
***
> [!IMPORTANT]
>
> Flipper Zero logs can only be viewed when the Developer Board is connected via USB.
> The option to view logs over Wi-Fi will be added in future updates.
> For more information, visit [Reading logs via the Dev Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/reading-logs).
## Step 4. Connect to a computer
## Wireless
Now, you can connect the Developer Board to your computer via USB or Wi-Fi, depending on your needs. We described both methods in separate documents:
### Wi-Fi access point (AP) mode
- **[Via USB cable](#dev_board_usb_connection)** for debugging in DAP Link or Black Magic mode, and reading logs.
- [Via Wi-Fi](#dev_board_wifi_connection) for debugging in Black Magic mode.
![The Developer Board in Wi-Fi access point mode](https://github.com/user-attachments/assets/1f210e91-3ac8-4f4c-a910-cc7c52b94346)
***
Out of the box, the Developer Board is configured to work as a **Wi-Fi access point**. This means it'll create its own Wi-Fi network to which you can connect. If your Developer Board doesn't create a Wi-Fi network, it is probably configured to work in **Wi-Fi client** mode. To reset your Developer Board back to **Wi-Fi access point** mode, press and hold the **BOOT** button for 10 seconds, then wait for the module to reboot.
## Next steps
![You can reconfigure the Developer Board mode by pressing and holding the BOOT button](https://github.com/user-attachments/assets/8fee05de-fb1e-475a-b23a-d1ddca9cd701)
You are ready to debug now! To further explore what you can do with the Devboard, check out these pages:
To connect the Developer Board in **Wi-Fi access point** mode, do the following:
- [Debugging via the Devboard](#dev_board_debugging_guide)
- [Devboard debug modes](#dev_board_debug_modes)
- [Reading logs via the Devboard](#dev_board_reading_logs)
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
2. Open Wi-Fi settings on your client device (phone, laptop, or other).
3. Connect to the network:
* Name: `blackmagic`
* Password: `iamwitcher`
4. To configure the Developer Board, open a browser and go to `http://192.168.4.1`.
These guides should help you get started with your Devboard. If you have any questions or you want to share your experience, don't hesitate to join our community on [Reddit](https://www.reddit.com/r/flipperzero/) and [Discord](https://discord.com/invite/flipper), where we have a dedicated #wifi-devboard channel.
### Wi-Fi client (STA) mode
![The Developer Board in Wi-Fi client mode](https://github.com/user-attachments/assets/42e7e69e-51b0-4914-b082-431c68bc75d3)
To connect the Developer Board in **Wi-Fi client** mode, you need to configure it to connect to your Wi-Fi network by doing the following:
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
2. Connect to the Developer Board in **Wi-Fi access point** mode.
3. In a browser, go to the configuration page on `http://192.168.4.1`.
4. Select the **STA** mode and enter your network's **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby networks.
5. Save the configuration and reboot the Developer Board.
6. In the Wi-Fi tab, you can set the Developer Board mode
![Developer Board mode](https://github.com/user-attachments/assets/fbeea000-1117-4297-8a0d-5d580123e938)
After rebooting, the Developer Board connects to your Wi-Fi network. You can connect to the device using the mDNS name `blackmagic.local` or the IP address it got from your router (you'll have to figure this out yourself, every router is different).
After connecting to your debugger via [http://blackmagic.local](http://blackmagic.local), you can find its IP address in the **SYS** tab. You can also change the debugger's mode to **AP** or **STA** there.
![In the SYS tab, you can view the IP address of your Developer Board](https://github.com/user-attachments/assets/aa3afc64-a2ec-46a6-a827-eea187a97c04)
## Debugging the firmware
Open the **Terminal** in the `flipperzero-firmware` directory that you cloned earlier and run the following command:
```bash
./fbt flash
```
This will upload the firmware you've just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware using the [GDB](https://www.gnu.org/software/gdb/) debugger. We recommend using **VSCode** with the recommended extensions, and we have pre-made configurations for it.
To debug in **VSCode**, do the following:
1. In VSCode, open the `flipperzero-firmware` directory.
2. You should see a notification about recommended extensions. Install them.
> [!TIP]
>
> If there were no notifications, open the `Extensions` tab,
> enter `@recommended` in the search bar,
> and install the workspace recommendations.
>
3. In the **Terminal**, run the `./fbt vscode_dist` command. This will generate the VSCode configuration files needed for debugging.
4. In VSCode, open the **Run and Debug** tab and select **Attach FW (blackmagic)** from the dropdown menu.
5. If needed, flash your Flipper Zero with the `./fbt flash` command, then click the **Play** button in the debug sidebar to start the debugging session.
6. Note that starting a debug session halts the execution of the firmware, so you'll need to click the **Continue** button on the toolbar at the top of your VSCode window to continue execution.
![Click Continue in the toolbar to continue execution of the firmware](https://github.com/user-attachments/assets/74f26bdb-8511-4e5a-8aa8-c44212aa6228)
To learn about debugging, visit the following pages:
* [Debugging with GDB](https://sourceware.org/gdb/current/onlinedocs/gdb.pdf)
* [Debugging in VSCode](https://code.visualstudio.com/docs/editor/debugging)
@@ -9,17 +9,19 @@ The Developer Board allows you to read Flipper Zero logs via UART. Unlike readin
## Setting the log level
Depending on your needs, you can set the log level by going to **Main Menu → Settings → Log Level**. To learn more about logging levels, visit [Settings](https://docs.flipperzero.one/basics/settings#d5TAt).
Depending on your needs, you can set the log level by going to **Main Menu → Settings → Log Level**. To learn more about logging levels, visit [Settings](https://docs.flipper.net/basics/settings#d5TAt).
![You can manually set the preferred log level](https://github.com/user-attachments/assets/b1317d01-8b9b-4544-8720-303c87b85324)
\image html https://cdn.flipperzero.one/Flipper_Zero_log_level.jpg "You can manually set the preferred log level" width=700
***
## Viewing Flipper Zero logs
Depending on your operating system, you need to install an additional application on your computer to read logs via the Developer Board:
### MacOS
### macOS
On MacOS, you need to install the `minicom` communication program by doing the following:
On macOS, you need to install the **minicom** communication program by doing the following:
1. [Install Homebrew](https://brew.sh/) by running the following command in the Terminal:
```bash
@@ -41,9 +43,11 @@ After installation of `minicom` on your macOS computer, you can connect to the D
>
> The list of devices.
3. Connect the developer board to your computer using a USB Type-C cable.
![Connect the developer board with a USB-C cable](https://github.com/user-attachments/assets/0f469a31-2dd1-4559-918a-ff3ca3309531)
5. Rerun the command. Two new devices have to appear: this is the Developer Board.
```bash
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
```text
/dev/cu.usbmodemblackmagic1
```
```bash
@@ -81,7 +85,8 @@ After installation of `minicom` on your Linux computer, you can connect to the D
```
Note the list of devices.
3. Connect the developer board to your computer using a USB Type-C cable.
![Connect the developer board with a USB-C cable](https://github.com/user-attachments/assets/0f469a31-2dd1-4559-918a-ff3ca3309531)
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
```bash
/dev/ttyACM0
@@ -116,12 +121,18 @@ On Windows, do the following:
1. On your computer, [install the PuTTY application](https://www.chiark.greenend.org.uk/\~sgtatham/putty/latest.html).
2. Cold-plug the Developer Board into your Flipper Zero by turning off the Flipper Zero, connecting the developer board, and then turning it back on.
3. Connect the developer board to your computer using a USB Type-C cable.
![Connect the developer board with a USB-C cable](https://github.com/user-attachments/assets/0f469a31-2dd1-4559-918a-ff3ca3309531)
4. Find the serial port that the developer board is connected to by going to `Device Manager → Ports (COM & LPT)` and looking for a new port that appears when you connect the Wi-Fi developer board.
![Find the serial port in your Device Manager](https://github.com/user-attachments/assets/aa542fe6-4781-45dc-86f6-e98ab34952b0)
6. Run the `PuTTY` application and select `Serial` as the connection type.
7. Enter the port number you found in the previous step into the `Serial line` field.
8. Set the `Speed` parameter to `230400` and click `Open`.
![Set speed to 230400](https://github.com/user-attachments/assets/93463c78-9776-479b-a6cc-d68ed712d0c4)
10. View logs of your Flipper Zero in the PuTTY terminal window.
11. To quit, close the PuTTY window.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
4. Find the serial port that the developer board is connected to by going to **Device Manager → Ports (COM & LPT)** and looking for a new port that appears when you connect the Wi-Fi developer board.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_Device_Manager.png width=700
5. Run the PuTTY application and select **Serial** as the connection type.
6. Enter the port number you found in the previous step into the **Serial line** field.
7. Set the **Speed** parameter to **230400** and click **Open**.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_PuTTy.jpg width=700
8. View logs of your Flipper Zero in the PuTTY terminal window.
9. To quit, close the PuTTY window.
@@ -0,0 +1,22 @@
# USB connection to the Devboard {#dev_board_usb_connection}
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_USB_connection_CDN.jpg width=700
To connect to the Developer Board via USB, do the following:
1. If the Devboard isn't connected to your Flipper Zero, turn off your Flipper Zero and connect the Developer Board to it. Then, turn your Flipper Zero back on.
2. On your computer, check the list of serial devices.
- **macOS:** On your computer, run `ls /dev/cu.*` in the Terminal.
- **Linux:** On your computer, run `ls /dev/tty*` in the Terminal.
- **Windows:** Go to **Device Manager** and expand the **Ports (COM & LPT)** section.
3. Connect the Devboard to your computer via a USB-C cable.
4. Repeat **Step 2**. Two new devices will appear — this is the Developer Board.
> [!warning]
> If the Developer Board doesn't appear in the list of devices, try using a different cable, USB port, or computer.
@@ -0,0 +1,60 @@
# Wi-Fi connection to the Devboard {#dev_board_wifi_connection}
You can connect to the Developer Board wirelessly in two ways:
- **Wi-Fi access point mode (default):** The Devboard creates its own Wi-Fi network, which you can connect to in order to access its web interface and debug via Wi-Fi. The downside is that you will need to disconnect from your current Wi-Fi network, resulting in a loss of internet connection.
- **Wi-Fi client mode:** You can connect to the Devboard through an existing Wi-Fi network, allowing you to access the Devboard web interface and debug via Wi-Fi without losing your internet connection.
Let's go over both of these modes below.
***
## Wi-Fi access point (AP) mode {#wifi-access-point}
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_Access_Point_CDN.jpg width=700
Out of the box, the Developer Board is configured to work as a Wi-Fi access point. To connect the Developer Board in this mode, do the following:
1. Plug the Wi-Fi Devboard into your Flipper Zero by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
2. Open Wi-Fi settings on your client device (phone, laptop, or other).
3. Connect to the network:
Name: `blackmagic`
Password: `iamwitcher`
If your computer fails to find the **blackmagic** network, read the [troubleshooting section](#wifi-access-point_troubleshooting) below.
4. To access the Devboard's web interface, open a browser and go to <http://192.168.4.1> or <http://blackmagic.local>.
### If your computer fails to find the black magic network {#wifi-access-point_troubleshooting}
- Reset Wi-Fi connection on your computer.
- The Developer Board is probably configured to work in Wi-Fi client mode. → Reset your Developer Board settings to default by pressing and holding the **BOOT** button for **10 seconds**, then wait for the Devboard to reboot. After the reset, the Devboard will work in Wi-Fi access point mode.
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot.jpg width=700
***
## Wi-Fi client (STA) mode {#wifi-client-mode}
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_STA_CDN.jpg width=700
To connect the Developer Board in **Wi-Fi client** mode, you need to configure it to connect to your Wi-Fi network by doing the following:
1. Plug the Wi-Fi Devboard into your Flipper Zero by turning off your Flipper Zero and connecting the Developer Board, and then turning the device back on.
2. Connect to the Developer Board in [Wi-Fi access point](#wifi-access-point) mode.
3. In a browser, go to the Devboard's web interface at <http://192.168.4.1> or <http://blackmagic.local>.
4. Select the **STA** mode and enter your network's **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby 2.4 GHz networks (5 GHz networks aren't supported).
5. Save the configuration and reboot the Developer Board.
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_connect_to_WiFi_CDN.jpg width=700
6. Now, you can access the Devboard's web interface at [http://blackmagic.local](https://blackmagic.local) via the existing Wi-Fi network without losing connection to the internet.
+1 -1
View File
@@ -1108,7 +1108,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = $(DOXY_SRC_ROOT)/documentation/images
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
+30 -3
View File
@@ -1,10 +1,37 @@
/**
@page dev_board Developer Board
@page dev_board Wi-Fi Developer Board
[ESP32-based development board](https://shop.flipperzero.one/collections/flipper-zero-accessories/products/wifi-devboard).
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_laptop_CDN.jpg width=700
Wi-Fi-enabled Developer Board brings debugging and firmware update capabilities to your Flipper Zero. The Developer Board is based on the ESP32-S2 MCU with custom firmware incorporating Black Magic Debug and CMSIS-DAP, and is built with ESP-IDF. It can flash and debug various microprocessors and microcontrollers (including the one used in your Flipper Zero) via Wi-Fi or USB cable.
The Developer Board provides a debug interface, allowing developers to halt program execution, set breakpoints, inspect variables and memory, and step through code execution.
<div align="center">
<a href="https://shop.flipperzero.one/products/wifi-devboard"><img src="https://cdn.flipperzero.one/Get_developer_board_button_green_600.png" width="350" align="center" alt="Get your Wi-Fi Developer Board"/></a>
</div>
<br>
Check out these guides to get started with the Devboard:
- @subpage dev_board_get_started — Quick start for new users
- @subpage dev_board_fw_update — Keep the Developer Board up to date
- @subpage dev_board_usb_connection — Instructions for Windows, macOS and Linux
- @subpage dev_board_wifi_connection — Instructions for Windows, macOS and Linux
- @subpage dev_board_debugging_guide — Learn how it works
- @subpage dev_board_debug_modes — Available modes and how to switch between them
- @subpage dev_board_reading_logs — Find out what is currently happening on the system
- @subpage dev_board_fw_update — Keep the developer board up to date
## Hardware
The Developer Board is equipped with an [ESP32-S2-WROVER](https://www.espressif.com/en/products/socs/esp32-s2) module, which includes built-in Wi-Fi capabilities. It also offers GPIO pins for easy connectivity to various targets. Additionally, the Developer Board features a USB Type-C connector for data transfer and power supply. For user interaction, the Developer Board has tactile switches.
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_developer_board_hardware_CDN.jpg width=700
## Additional resources
To learn more about the Wi-Fi Developer Board hardware, visit [Schematics in Flipper Docs](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/schematics).
For additional information about Flipper Zero GPIO pins, visit [GPIO & modules in Flipper Docs](https://docs.flipperzero.one/gpio-and-modules).
*/
+1 -1
View File
@@ -52,7 +52,7 @@ $extrastylesheet
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign">
<div id="projectname"><a href="index.html">$projectname</a><!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
<div id="projectname"><a href="index.html" style="background: none; color: var(--foreground_color) !important;">$projectname</a><!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
+15 -7
View File
@@ -11,12 +11,20 @@ This page contains some information on the Flipper Zero scripting engine, which
JS modules use the Flipper app plugin system. Each module is compiled into a `.fal` library file and is located on a microSD card. Here is a list of implemented modules:
- @subpage js_badusb BadUSB module
- @subpage js_serial Serial module
- @subpage js_math Math module
- @subpage js_dialog — Dialog module
- @subpage js_submenu — Submenu module
- @subpage js_textbox — Textbox module
- @subpage js_notification — Notifications module
- @subpage js_badusb - BadUSB module
- @subpage js_serial - Serial module
- @subpage js_math - Math module
- @subpage js_notification - Notifications module
- @subpage js_event_loop - Event Loop module
- @subpage js_gpio - GPIO module
- @subpage js_gui - GUI module and its submodules:
- @subpage js_gui__submenu - Submenu view
- @subpage js_gui__loading - Hourglass (Loading) view
- @subpage js_gui__empty_screen - Empty view
- @subpage js_gui__text_input - Keyboard-like text input
- @subpage js_gui__text_box - Simple multiline text box
- @subpage js_gui__dialog - Dialog with up to 3 options
All modules have corresponding TypeScript declaration files, so you can set up your IDE to show suggestions when writing JS scripts.
*/
+1 -7
View File
@@ -57,15 +57,9 @@ Additionally, `compile_commands.json` is generated in that folder (it is used fo
`build/latest` symlink & compilation database are only updated upon *firmware build targets* — that is, when you're re-building the firmware itself. Running other tasks, like firmware flashing or building update bundles *for a different debug/release configuration or hardware target*, does not update `built/latest` dir to point to that configuration.
Running other tasks, like firmware flashing or building update bundles *for a different debug/release configuration or hardware target*, does not update `built/latest` dir to point to that configuration.
## VSCode integration
`fbt` includes basic development environment configuration for VSCode. Run `./fbt vscode_dist` to deploy it.
That will copy the initial environment configuration to the `.vscode` folder.
After that, you can use that configuration by starting VSCode and choosing the firmware root folder in the <kbd>File > Open Folder</kbd> menu.
`fbt` includes basic development environment configuration for VS Code. Run `./fbt vscode_dist` to deploy it. That will copy the initial environment configuration to the `.vscode` folder. After that, you can use that configuration by starting VS Code and choosing the firmware root folder in the "File > Open Folder" menu.
To use language servers other than the default VS Code C/C++ language server, use `./fbt vscode_dist LANG_SERVER=<language-server>` instead.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

+3 -9
View File
@@ -41,16 +41,10 @@ print("string1", "string2", 123);
Same as `print`, but output to serial console only, with corresponding log level.
## to_string
Convert a number to string.
Convert a number to string with an optional base.
### Examples:
```js
to_string(123)
```
## to_hex_string
Convert a number to string(hex format).
### Examples:
```js
to_hex_string(0xFF)
to_string(123) // "123"
to_string(123, 16) // "0x7b"
```
-49
View File
@@ -1,49 +0,0 @@
# js_dialog {#js_dialog}
# Dialog module
```js
let dialog = require("dialog");
```
# Methods
## message
Show a simple message dialog with header, text and "OK" button.
### Parameters
- Dialog header text
- Dialog text
### Returns
true if central button was pressed, false if the dialog was closed by back key press
### Examples:
```js
dialog.message("Dialog demo", "Press OK to start");
```
## custom
More complex dialog with configurable buttons
### Parameters
Configuration object with the following fields:
- header: Dialog header text
- text: Dialog text
- button_left: (optional) left button name
- button_right: (optional) right button name
- button_center: (optional) central button name
### Returns
Name of pressed button or empty string if the dialog was closed by back key press
### Examples:
```js
let dialog_params = ({
header: "Dialog header",
text: "Dialog text",
button_left: "Left",
button_right: "Right",
button_center: "OK"
});
dialog.custom(dialog_params);
```
+144
View File
@@ -0,0 +1,144 @@
# js_event_loop {#js_event_loop}
# Event Loop module
```js
let eventLoop = require("event_loop");
```
The event loop is central to event-based programming in many frameworks, and our
JS subsystem is no exception. It is a good idea to familiarize yourself with the
event loop first before using any of the advanced modules (e.g. GPIO and GUI).
## Conceptualizing the event loop
If you ever wrote JavaScript before, you have definitely seen callbacks. It's
when a function accepts another function (usually an anonymous one) as one of
the arguments, which it will call later on, e.g. when an event happens or when
data becomes ready:
```js
setTimeout(function() { console.log("Hello, World!") }, 1000);
```
Many JavaScript engines employ a queue that the runtime fetches events from as
they occur, subsequently calling the corresponding callbacks. This is done in a
long-running loop, hence the name "event loop". Here's the pseudocode for a
typical event loop:
```js
while(loop_is_running()) {
if(event_available_in_queue()) {
let event = fetch_event_from_queue();
let callback = get_callback_associated_with(event);
if(callback)
callback(get_extra_data_for(event));
} else {
// avoid wasting CPU time
sleep_until_any_event_becomes_available();
}
}
```
Most JS runtimes enclose the event loop within themselves, so that most JS
programmers does not even need to be aware of its existence. This is not the
case with our JS subsystem.
# Example
This is how one would write something similar to the `setTimeout` example above:
```js
// import module
let eventLoop = require("event_loop");
// create an event source that will fire once 1 second after it has been created
let timer = eventLoop.timer("oneshot", 1000);
// subscribe a callback to the event source
eventLoop.subscribe(timer, function(_subscription, _item, eventLoop) {
print("Hello, World!");
eventLoop.stop();
}, eventLoop); // notice this extra argument. we'll come back to this later
// run the loop until it is stopped
eventLoop.run();
// the previous line will only finish executing once `.stop()` is called, hence
// the following line will execute only after "Hello, World!" is printed
print("Stopped");
```
I promised you that we'll come back to the extra argument after the callback
function. Our JavaScript engine does not support closures (anonymous functions
that access values outside of their arguments), so we ask `subscribe` to pass an
outside value (namely, `eventLoop`) as an argument to the callback so that we
can access it. We can modify this extra state:
```js
// this timer will fire every second
let timer = eventLoop.timer("periodic", 1000);
eventLoop.subscribe(timer, function(_subscription, _item, counter, eventLoop) {
print("Counter is at:", counter);
if(counter === 10)
eventLoop.stop();
// modify the extra arguments that will be passed to us the next time
return [counter + 1, eventLoop];
}, 0, eventLoop);
```
Because we have two extra arguments, if we return anything other than an array
of length 2, the arguments will be kept as-is for the next call.
The first two arguments that get passed to our callback are:
- The subscription manager that lets us `.cancel()` our subscription
- The event item, used for events that have extra data. Timer events do not,
they just produce `undefined`.
# API reference
## `run`
Runs the event loop until it is stopped with `stop`.
## `subscribe`
Subscribes a function to an event.
### Parameters
- `contract`: an event source identifier
- `callback`: the function to call when the event happens
- extra arguments: will be passed as extra arguments to the callback
The callback will be called with at least two arguments, plus however many were
passed as extra arguments to `subscribe`. The first argument is the subscription
manager (the same one that `subscribe` itself returns). The second argument is
the event item for events that produce extra data; the ones that don't set this
to `undefined`. The callback may return an array of the same length as the count
of the extra arguments to modify them for the next time that the event handler
is called. Any other returns values are discarded.
### Returns
A `SubscriptionManager` object:
- `SubscriptionManager.cancel()`: unsubscribes the callback from the event
### Warning
Each event source may only have one callback associated with it.
## `stop`
Stops the event loop.
## `timer`
Produces an event source that fires with a constant interval either once or
indefinitely.
### Parameters
- `mode`: either `"oneshot"` or `"periodic"`
- `interval`: the timeout (for `"oneshot"`) timers or the period (for
`"periodic"` timers)
### Returns
A `Contract` object, as expected by `subscribe`'s first parameter.
## `queue`
Produces a queue that can be used to exchange messages.
### Parameters
- `length`: the maximum number of items that the queue may contain
### Returns
A `Queue` object:
- `Queue.send(message)`:
- `message`: a value of any type that will be placed at the end of the queue
- `input`: a `Contract` (event source) that pops items from the front of the
queue
+77
View File
@@ -0,0 +1,77 @@
# js_gpio {#js_gpio}
# GPIO module
```js
let eventLoop = require("event_loop");
let gpio = require("gpio");
```
This module depends on the `event_loop` module, so it _must_ only be imported
after `event_loop` is imported.
# Example
```js
let eventLoop = require("event_loop");
let gpio = require("gpio");
let led = gpio.get("pc3");
led.init({ direction: "out", outMode: "push_pull" });
led.write(true);
delay(1000);
led.write(false);
delay(1000);
```
# API reference
## `get`
Gets a `Pin` object that can be used to manage a pin.
### Parameters
- `pin`: pin identifier (examples: `"pc3"`, `7`, `"pa6"`, `3`)
### Returns
A `Pin` object
## `Pin` object
### `Pin.init()`
Configures a pin
#### Parameters
- `mode`: `Mode` object:
- `direction` (required): either `"in"` or `"out"`
- `outMode` (required for `direction: "out"`): either `"open_drain"` or
`"push_pull"`
- `inMode` (required for `direction: "in"`): either `"analog"`,
`"plain_digital"`, `"interrupt"` or `"event"`
- `edge` (required for `inMode: "interrupt"` or `"event"`): either
`"rising"`, `"falling"` or `"both"`
- `pull` (optional): either `"up"`, `"down"` or unset
### `Pin.write()`
Writes a digital value to a pin configured with `direction: "out"`
#### Parameters
- `value`: boolean logic level to write
### `Pin.read()`
Reads a digital value from a pin configured with `direction: "in"` and any
`inMode` except `"analog"`
#### Returns
Boolean logic level
### `Pin.read_analog()`
Reads an analog voltage level in millivolts from a pin configured with
`direction: "in"` and `inMode: "analog"`
#### Returns
Voltage on pin in millivolts
### `Pin.interrupt()`
Attaches an interrupt to a pin configured with `direction: "in"` and
`inMode: "interrupt"` or `"event"`
#### Returns
An event loop `Contract` object that identifies the interrupt event source. The
event does not produce any extra data.
+161
View File
@@ -0,0 +1,161 @@
# js_gui {#js_gui}
# GUI module
```js
let eventLoop = require("event_loop");
let gui = require("gui");
```
This module depends on the `event_loop` module, so it _must_ only be imported
after `event_loop` is imported.
## Conceptualizing GUI
### Event loop
It is highly recommended to familiarize yourself with the event loop first
before doing GUI-related things.
### Canvas
The canvas is just a drawing area with no abstractions over it. Drawing on the
canvas directly (i.e. not through a viewport) is useful in case you want to
implement a custom design element, but this is rather uncommon.
### Viewport
A viewport is a window into a rectangular portion of the canvas. Applications
always access the canvas through a viewport.
### View
In Flipper's terminology, a "View" is a fullscreen design element that assumes
control over the entire viewport and all input events. Different types of views
are available (not all of which are unfortunately currently implemented in JS):
| View | Has JS adapter? |
|----------------------|------------------|
| `button_menu` | ❌ |
| `button_panel` | ❌ |
| `byte_input` | ❌ |
| `dialog_ex` | ✅ (as `dialog`) |
| `empty_screen` | ✅ |
| `file_browser` | ❌ |
| `loading` | ✅ |
| `menu` | ❌ |
| `number_input` | ❌ |
| `popup` | ❌ |
| `submenu` | ✅ |
| `text_box` | ✅ |
| `text_input` | ✅ |
| `variable_item_list` | ❌ |
| `widget` | ❌ |
In JS, each view has its own set of properties (or just "props"). The programmer
can manipulate these properties in two ways:
- Instantiate a `View` using the `makeWith(props)` method, passing an object
with the initial properties
- Call `set(name, value)` to modify a property of an existing `View`
### View Dispatcher
The view dispatcher holds references to all the views that an application needs
and switches between them as the application makes requests to do so.
### Scene Manager
The scene manager is an optional add-on to the view dispatcher that makes
managing applications with complex navigation flows easier. It is currently
inaccessible from JS.
### Approaches
In total, there are three different approaches that you may take when writing
a GUI application:
| Approach | Use cases | Available from JS |
|----------------|------------------------------------------------------------------------------|-------------------|
| ViewPort only | Accessing the graphics API directly, without any of the nice UI abstractions | ❌ |
| ViewDispatcher | Common UI elements that fit with the overall look of the system | ✅ |
| SceneManager | Additional navigation flow management for complex applications | ❌ |
# Example
An example with three different views using the ViewDispatcher approach:
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let loadingView = require("gui/loading");
let submenuView = require("gui/submenu");
let emptyView = require("gui/empty_screen");
// Common pattern: declare all the views in an object. This is absolutely not
// required, but adds clarity to the script.
let views = {
// the view dispatcher auto-✨magically✨ remembers views as they are created
loading: loadingView.make(),
empty: emptyView.make(),
demos: submenuView.makeWith({
items: [
"Hourglass screen",
"Empty screen",
"Exit app",
],
}),
};
// go to different screens depending on what was selected
eventLoop.subscribe(views.demos.chosen, function (_sub, index, gui, eventLoop, views) {
if (index === 0) {
gui.viewDispatcher.switchTo(views.loading);
} else if (index === 1) {
gui.viewDispatcher.switchTo(views.empty);
} else if (index === 2) {
eventLoop.stop();
}
}, gui, eventLoop, views);
// go to the demo chooser screen when the back key is pressed
eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, gui, views) {
gui.viewDispatcher.switchTo(views.demos);
}, gui, views);
// run UI
gui.viewDispatcher.switchTo(views.demos);
eventLoop.run();
```
# API reference
## `viewDispatcher`
The `viewDispatcher` constant holds the `ViewDispatcher` singleton.
### `viewDispatcher.switchTo(view)`
Switches to a view, giving it control over the display and input
#### Parameters
- `view`: the `View` to switch to
### `viewDispatcher.sendTo(direction)`
Sends the viewport that the dispatcher manages to the front of the stackup
(effectively making it visible), or to the back (effectively making it
invisible)
#### Parameters
- `direction`: either `"front"` or `"back"`
### `viewDispatcher.sendCustom(event)`
Sends a custom number to the `custom` event handler
#### Parameters
- `event`: number to send
### `viewDispatcher.custom`
An event loop `Contract` object that identifies the custom event source,
triggered by `ViewDispatcher.sendCustom(event)`
### `viewDispatcher.navigation`
An event loop `Contract` object that identifies the navigation event source,
triggered when the back key is pressed
## `ViewFactory`
When you import a module implementing a view, a `ViewFactory` is instantiated.
For example, in the example above, `loadingView`, `submenuView` and `emptyView`
are view factories.
### `ViewFactory.make()`
Creates an instance of a `View`
### `ViewFactory.make(props)`
Creates an instance of a `View` and assigns initial properties from `props`
#### Parameters
- `props`: simple key-value object, e.g. `{ header: "Header" }`
+53
View File
@@ -0,0 +1,53 @@
# js_gui__dialog {#js_gui__dialog}
# Dialog GUI view
Displays a dialog with up to three options.
<img src="dialog.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let dialogView = require("gui/dialog");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the `gui.js` example script.
# View props
## `header`
Text that appears in bold at the top of the screen
Type: `string`
## `text`
Text that appears in the middle of the screen
Type: `string`
## `left`
Text for the left button. If unset, the left button does not show up.
Type: `string`
## `center`
Text for the center button. If unset, the center button does not show up.
Type: `string`
## `right`
Text for the right button. If unset, the right button does not show up.
Type: `string`
# View events
## `input`
Fires when the user presses on either of the three possible buttons. The item
contains one of the strings `"left"`, `"center"` or `"right"` depending on the
button.
Item type: `string`
+22
View File
@@ -0,0 +1,22 @@
# js_gui__empty_screen {#js_gui__empty_screen}
# Empty Screen GUI View
Displays nothing.
<img src="empty.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let emptyView = require("gui/empty_screen");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the GUI example.
# View props
This view does not have any props.
+23
View File
@@ -0,0 +1,23 @@
# js_gui__loading {#js_gui__loading}
# Loading GUI View
Displays an animated hourglass icon. Suppresses all `navigation` events, making
it impossible for the user to exit the view by pressing the back key.
<img src="loading.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let loadingView = require("gui/loading");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the GUI example.
# View props
This view does not have any props.
+37
View File
@@ -0,0 +1,37 @@
# js_gui__submenu {#js_gui__submenu}
# Submenu GUI view
Displays a scrollable list of clickable textual entries.
<img src="submenu.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let submenuView = require("gui/submenu");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the GUI example.
# View props
## `header`
Single line of text that appears above the list
Type: `string`
## `items`
The list of options
Type: `string[]`
# View events
## `chosen`
Fires when an entry has been chosen by the user. The item contains the index of
the entry.
Item type: `number`
+25
View File
@@ -0,0 +1,25 @@
# js_gui__text_box {#js_gui__text_box}
# Text box GUI view
Displays a scrollable read-only text field.
<img src="text_box.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let textBoxView = require("gui/text_box");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the `gui.js` example script.
# View props
## `text`
Text to show in the text box.
Type: `string`
+44
View File
@@ -0,0 +1,44 @@
# js_gui__text_input {#js_gui__text_input}
# Text input GUI view
Displays a keyboard.
<img src="text_input.png" width="200" alt="Sample screenshot of the view" />
```js
let eventLoop = require("event_loop");
let gui = require("gui");
let textInputView = require("gui/text_input");
```
This module depends on the `gui` module, which in turn depends on the
`event_loop` module, so they _must_ be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example refer to the `gui.js` example script.
# View props
## `minLength`
Smallest allowed text length
Type: `number`
## `maxLength`
Biggest allowed text length
Type: `number`
Default: `32`
## `header`
Single line of text that appears above the keyboard
Type: `string`
# View events
## `input`
Fires when the user selects the "save" button and the text matches the length
constrained by `minLength` and `maxLength`.
Item type: `string`
-48
View File
@@ -1,48 +0,0 @@
# js_submenu {#js_submenu}
# Submenu module
```js
let submenu = require("submenu");
```
# Methods
## setHeader
Set the submenu header text.
### Parameters
- header (string): The submenu header text
### Example
```js
submenu.setHeader("Select an option:");
```
## addItem
Add a new submenu item.
### Parameters
- label (string): The submenu item label text
- id (number): The submenu item ID, must be a Uint32 number
### Example
```js
submenu.addItem("Option 1", 1);
submenu.addItem("Option 2", 2);
submenu.addItem("Option 3", 3);
```
## show
Show a submenu that was previously configured using `setHeader()` and `addItem()` methods.
### Returns
The ID of the submenu item that was selected, or `undefined` if the BACK button was pressed.
### Example
```js
let selected = submenu.show();
if (selected === undefined) {
// if BACK button was pressed
} else if (selected === 1) {
// if item with ID 1 was selected
}
```
-69
View File
@@ -1,69 +0,0 @@
# js_textbox {#js_textbox}
# Textbox module
```js
let textbox = require("textbox");
```
# Methods
## setConfig
Set focus and font for the textbox.
### Parameters
- focus: "start" to focus on the beginning of the text, or "end" to focus on the end of the text
- font: "text" to use the default proportional font, or "hex" to use a monospaced font, which is convenient for aligned array output in HEX
### Example
```js
textbox.setConfig("start", "text");
textbox.addText("Hello world");
textbox.show();
```
## addText
Add text to the end of the textbox.
### Parameters
- text (string): The text to add to the end of the textbox
### Example
```js
textbox.addText("New text 1\nNew text 2");
```
## clearText
Clear the textbox.
### Example
```js
textbox.clearText();
```
## isOpen
Return true if the textbox is open.
### Returns
True if the textbox is open, false otherwise.
### Example
```js
let isOpen = textbox.isOpen();
```
## show
Show the textbox. You can add text to it using the `addText()` method before or after calling the `show()` method.
### Example
```js
textbox.show();
```
## close
Close the textbox.
### Example
```js
if (textbox.isOpen()) {
textbox.close();
}
```