Tanmatsu: software
Work in progress
The software for Tanmatsu is currently under active development. On this page we will regulary post updates on our progress. Don’t want to miss out on any updates? Join our Discord or Telegram groups.
Device drivers
The invisible though crucial part of all software running on Tanmatsu. These ESP-IDF components provide the building blocks for interfacing with the hardware on the Tanmatsu mainboard.
MIPI DSI display
The Tanmatsu has a MIPI DSI display with a ST7701 controller. Espressif provides a driver for this controller, we added the correct initialization commands and configuration for the display on the Tanmatsu and packaged these in a component. In addition to the configuration of the Tanmatsu display the display included with the Espressif ESP32-P4 devkit is also supported by this component, allowing for easy switching between Tanmatsu hardware and the ESP32-P4 devkit.
Coprocessor
This driver component manages communication with the coprocessor firmware via I2C and exposes functions for accessing all coprocessor functionality.
ES8156 audio DAC
This driver component allows for configuring the ES8156 audio DAC via I2C.
BMI270 IMU
This driver component wraps the Bosch SDK for the BMI270 IMU, implementing communication via I2C for the ESP32-P4.
In circuit programming
These components are as invisible during normal use as they are useful when you need them. To do initial hardware bringup and to update the firmware of the coprocessor and the radio Tanmatsu needs a way to reprogram these chips from the ESP32-P4 application processor.
Component | Status | Repository |
---|
RVSWD for CH32V203 | Published | esp32-component-rvswd |
ESPTOOL² for ESP32-C6 | Proof of concept | |
The BSP (Board Support Package) wraps the driver components to provide an easy way to integrate board support for Tanmatsu (and other devices) into ESP-IDF projects.
AppFS allows for dynamically installing and running ESP32 firmware from a special flash partition. This mechanism allows for installing and running apps directly from the Tanmatsu launcher.
The LVGL BSP interface is a component providing the glue needed to use the LVGL graphics stack component provided by Espressif with the BSP component, mapping the keyboard buttons and correctly configuring the display and display rotation.
1 - AppFS
AppFS is an ESP-IDF component that implements a method for dynamically installing and loading firmware binaries. It implements a pseudo filesystem interface for storing firmwares and a bootloader modification which allows for starting firmwares from the AppFS partition.
Originally AppFS was created by Jeroen Domburg (sprite_tm) for the PocketSprite keychain gameconsole. Since it’s creation Badge.Team has succesfully deployed, updated and extended AppFS to make it the ready to use component it is today.
The current version of AppFS supports ESP-IDF 5.3 and later and has bootloader modifications for the ESP32, ESP32-C6 and ESP32-P4 included. Other ESP32 variants are not supported yet.
Using the AppFS component in your projects
Apps do not require any changes to be started using AppFS, you only need the AppFS component to build a launcher menu.
To include the AppFS component in your launcher menu project first add the component as a requirement using idf.py:
idf.py add-dependency "badgeteam/appfs^1.0.0"
This makes the AppFS APIs available, but does not apply the required bootloader changes.
To apply the bootloader changes either create two symlinks or copy the contents of the folders.
mkdir bootloader_components
ln -s managed_components/badgeteam__appfs bootloader_components/appfs
ln -s managed_components/badgeteam__appfs/bootloader_main bootloader_components/main
The component is now ready for use.
#include "esp_err.h"
#include "esp_log.h"
#include "appfs.h"
void initialize_appfs(void) {
esp_err_t res = appfsInit(APPFS_PART_TYPE, APPFS_PART_SUBTYPE);
if (res != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize AppFS: %s", esp_err_to_name(res));
return;
}
}
See the functions defined in appfs.h for more information on how to use the library.
Partition table
The appfs.h
header defines a type and subtype for the AppFS partition:
#define APPFS_PART_TYPE 0x43 /*<! Default partition type of an appfs partition */
#define APPFS_PART_SUBTYPE 0x3 /*<! Default partition subtype of an appfs partition */
To create an AppFS partition add an entry to the partitions CSV file for your project:
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size,
appfs, 0x43, 3, 0x330000, 8000K,
After ESP-IDF has downloaded the component a tools
folder can be found at managed_components/badgeteam__appfs/tools
. In this folder a set of Python scripts can be found for creating and managing AppFS partition data.
Creating an AppFS partition image
In the partition table above the partition is 8000 KB in size. Converted to bytes 8000 KB becomes 8000 x 1024 = 8192000
bytes.
A partition can be created using the following command:
python appfs_generate.py 8192000 example.bin
To add firmware binaries to the AppFS partition file the appfs_add_file.py
tool can be used:
python appfs_add_file.py example.bin myapp.bin "myapp" "My app" 1
The name and title fields are strings. The filename (name
field) of the file can be a maximum of 48 bytes long and the title
of the file can be 64 bytes long. The version
field is an 16 bits unsigned integer with a range of 0 - 65535.
The filename (name
field) of the file is used in the AppFS API to identify files in the filesystem, filenames have to be unique. The title
field is optional and may be used to include a human readable alternative to the filename. If unused the title
field can be set to a blank string ""
. The version
field is also optional and may be used to identify the installed version of an application, allowing for easier implementation of update mechanisms. If unused the version
field can be set to 0
.
2 - BadgeLink
BadgeLink is a protocol for communicating with Tanmatsu over USB. It allows you to manage apps, settings and files on the device via WebUSB applications in Chromium based browsers or a Python script.
You can find the Python script on the releases page of the BadgeLink repository. Download the tools.zip
artifact and unzip it into a folder.
Make sure Python is installed on your computer.
A bash shell script has been provided to automatically create a Python virtual environment and install the required libraries into the environment. On Linux and Mac machines you can run this script to automate the process.
On Windows you can manually create the virtual environment by running the following commands in a command window:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Permissions for accessing the USB device on Linux
Copy the 60-badgelink.rules
file to /etc/udev/rules.d
on your system. Then reload the udev rules and trigger re-detection of hardware.
sudo cp 60-badgelink.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
On Linux and Mac the badgelink.sh
script automatically starts the badgelink.py
script in the virtual environment. On Windows you have to manually enable the virtual environment as follows:
source .venv/bin/activate
python badgelink.py
Make sure your Tanmatsu is set to USB device mode
, by default the USB interface is set to debugging mode and you can change the mode easily by pressing the purple diamond key (second button from the top right of the keyboard). It might take a second before the icon changes but the icon on the top right of the screen will change from the bug to an USB icon to indicate that the USB port mode has been switched.
In the next sections we assume you are using the badgelink.sh
script. If you are using Windows replace badgelink.sh
in the commands below with python badgelink.py
and make sure the virtual envirotnment is active in the command window you are using.
AppFS
Listing installed applications
./badgelink.sh appfs list
This command will list all the application binaries currently installed into the AppFS partition of the flash chip.
Example output:
slug | title | version | size
------------+-------------+---------+------
konsool64 | Konsool 64 | 1 | 833K
synthwave | Synthwave | 1 | 438K
coprocessor | Coprocessor | 1 | 1063K
In this context slug
is a lowercase ascii string without spaces, formatted in such a way to ensure the name can be used as filename. The slug
is used for coupling the binary in AppFS with its related files on the FAT partition of flash or the SD card in the /apps/<slug>/
folder. The slug
filename needs to be unique for every file in the AppFS.
The title
field is a human readable name for the application, this string is visible in the menu and you can safely use uppercase letters and spaces in this string.
The version
field contains an integer number used to couple the version of the installed binary in AppFS to the version of its related files on the FAT partition.
The size
field contains the size of the application binary in kilobyte.
View partition size and usage
./badgelink.sh appfs usage
This command gives you information on the size of the AppFS partition and the amount of space in use by the installed applications.
Example output:
Usage: 2432K / 8128K (29.9%)
Deleting an application
./badgelink.sh appfs delete synthwave
The last argument in this command is the slug
filename of the app you want to remove from AppFS, you can find the slug
filename using the list command.
Copying an app from the device to your computer
./badgelink.sh appfs download konsool64 konsool64.bin
This command transfers a file on the AppFS partition to your computer. The last two arguments are the slug
filename of the app and the filename of the output file on your computer.
Copying an app from your computer to the device
./badgelink.sh appfs upload test "An example app" 123 firmware.bin
This command transfers a file on your computer to the AppFS partition. The argumens are the slug
filename you want the application to have, this name has to be unique, followed by the title
of the app, in the example above quotes were added around the string to allow the use of spaces. After that comes the version
argument, an integer number, when testing you can use any number you want, for example 0
. And the last argument is the filename of the firmware binary you want to upload to the device.
If you have just compiled the example app, take a look in the build folder to find the firmware.bin
file. This file is the only file you need for installing your app.
Starting an app
To start an app on the AppFS partition you can use the start
command:
./badgelink.sh start synthwave
In which the synthwave
argument is the slug name of the app to start.
NVS (Non-volitile storage)
NVS is a partition on the flash which contains a key-value store for settings. Using BadgeLink you can list which keys are in use and read, write and delete the entries.
Listing keys in use
./badgelink.sh nvs list
This command lists all the keys in use. To limit the results to a specific namespace the name of the namespace can be added as an extra argument.
Example output:
namespace | key | type
----------+--------------+-------
wifi | s00.ssid | string
wifi | s00.password | string
wifi | s00.identity | string
wifi | s00.username | string
wifi | s00.authmode | u32
wifi | s00.phase2 | u32
system | ntp | u8
system | timezone | string
system | tz | string
wifi | s01.ssid | string
wifi | s01.password | string
wifi | s01.identity | string
wifi | s01.username | string
wifi | s01.authmode | u32
wifi | s01.phase2 | u32
Reading an entry
./badgelink.sh nvs read system timezone string
To read an entry you specify the namespace, key and type of the entry you want to read. The tool then returns you the value.
type: NvsValueString
stringval: "Europe/Amsterdam"
'Europe/Amsterdam'
Writing an entry
./badgelink.sh nvs write test example string "Hello world"
The example command above creates or overwrites an entry in the namespace test
, with key example
and type string
. The value Hello world
gets written into the entry.
Deleting an entry
./badgelink.sh nvs delete test example
The example command above deletes the entry example
in the namespace test
.
FAT filesystem
The internal FAT filesystem partition and the SD card contents can also be manipulated using the BadgeLink tool.
The internal FAT partition on the flash chip is mounted at /int
and the SD card is mounted at the path /sd
.
Listing the contents of a directory
To list the contents of the root of the internal flash chip filesystem you can run
./badgelink.sh fs list /int
This results in for example the following output:
type | path
-----+------
dir | icons
Type can be dir
for a directory and file
for a file.
File statistics
To query statistics for a specific file you can use the stat
command:
./badgelink.sh fs stat /int/icons/menu/wifi_0.png
This gives you information about the size of the file and the timestamps for creation, modification and last access. Note that the timestamps have a high chance of not being accurate. If the timestamp is unavailable you will most likely see 1970-01-01 as the date.
Type: file
Size: 539
Created: 1970-01-01 01:00:00
Modified: 1980-01-01 00:00:00
Accessed: 1970-01-01 01:00:00
Creating a directory
./badgelink.sh fs mkdir /int/example
Creates a directory called example
in the root of the internal flash FAT filesystem.
Removing a directory
./badgelink.sh fs rmdir /int/example
Removes a directory called example
from the root of the internal flash FAT filesystem.
Uploading a file from your computer to the device
To send a file to the device you can use the upload
command.
echo "Hello world" > example.txt
./badgelink.sh fs upload /int/example.txt example.txt
Downloading a file from the device to your computer
To retrieve a file from the device you can use the download
command.
./badgelink.sh fs download /int/example.txt downloaded_file.txt
3 - Meshtastic
This document describes how to install Meshtastic compatible firmware onto your Tanmatsu. The Meshtastic firmware for Tanmatsu is in active development and not yet fully stable. You might experience crashes and bugs.
Tanmatsu uses two ESP32 chips, one as application processor and one as radio. The GUI app for Meshtastic, running on the application processor can be installed as an app using BadgeLink. Support for installing applications in a similar fashion on the radio is still being worked on. Because of this it is currently required to replace the radio firmware which provides the launcher and apps on the application processor with WiFi and BLE access when installing Meshtastic onto the radio.
A tool for flashing Meshtastic or the default “ESP-HOSTED” firmware to the radio will soon be provided as a web application making use of Webserial to connect to your Tanmatsu. It is also possible to flash firmware to the radio using esptool.py, the flashing script provided by Espressif. This guide explains how to flash Meshtastic using esptool.py, which is assumed to be installed and available on your system.
Stability
This software is not stable yet, you will experience crashes, mostly of the GUI software. We hope to resolve these issues soon but keep this in mind when you install the app.BLE
BLE does not work properly due to a bug in the Meshtastic radio firmware. You can connect to the radio using the official Meshtastic frontend apps in the webbrowser and on your phone over USB and WiFi without issues. This is a software bug in the Meshtastic firmware on all ESP32-C6 targets which we hope gets resolved soon.Requirements
Download the two archives linked to above and extract them to a folder. Then open a command prompt in that same folder.
Installing the radio firmware
The first step is to replace the ESP-HOSTED radio firmware normally running on the ESP32-C6 with the Meshtastic firmware.
Controlling the state of the radio using the launcher firmware
If the launcher is unable to communicate with the radio via the protocol implemented by ESP-HOSTED the launcher will automatically power off the radio. You can see the state of the radio by looking at the color of the radio LED, which is the middle LED on the left side of the front of Tanmatsu. If the LED is green the radio is powered on and working, if the LED is blue the radio is in bootloader mode and if the LED is off then the radio is powered off.
While on the homescreen of the launcher firmware you can press a key combination to force the radio into either of the three states (off, bootloader and on).
Key combination | Radio state | LED color |
---|
Fn + red X | Off | Off |
Fn + orange triangle | Bootloader | Blue |
Fn + yellow square | On | Green |
The radio can be flashed using the online recovery tool or using esptool.py via the USB interface exposed by the radio when the radio is in either bootloader or on state. Sometimes the firmware on the radio can cause issues when trying to flash, in such a situation it is useful to try flashing while in bootloader mode. The bootloader is located in read-only memory and will always work, regardless of the state of the installed firmware.
Both the application processor and the radio expose a serial port for debugging and flashing when enabled. The first serial port to appear is the ESP32-P4 application processor and the second serial port is the ESP32-C6 radio.
You can install the Meshtastic firmware by first erasing and then overwriting the firmware on the ESP32-C6 radio using the following commands:
esptool.py --chip esp32c6 erase_flash
esptool.py --chip esp32c6 write_flash 0x0 radio/bootloader.bin 0x10000 radio/firmware.bin 0x8000 radio/partitions.bin
Installing the GUI app
Now that the radio is running Meshtastic the GUI app can be used to interact with the Meshtastic firmware running on the radio.
Switching the USB mode of the ESP32-P4 to BadgeLink mode
Press the purple diamond button while on the homescreen of the launcher firmware. The bug icon in the top right corner of the screen should now be replaced with an USB icon. In BadgeLink mode the application processor exposes an interface which allows for installing applications. You can use this interface using the BadgeLink tools.
Installing the Meshtastic app
Installing the Meshtastic GUI is done using BadgeLink.
Run the following command to install the Meshtastic GUI application:
./badgelink.sh appfs upload meshtastic "Meshtastic" 0 meshtastic-gui.bin