TRMNL ePaper device firmware
1,164
stars
1,015
commits
C
primary language
Sep 10, 2026
updated
created for the TRMNL e-ink display.
[!IMPORTANT] the
mainbranch is under constant development and may contain breaking changes. flash at your own risk.to access production-ready firmware, check out the tagged releases or use the Flash Assistant.
graph TB
Start(["Start"])
Init("Init peripherals")
Start --> Init
IsLongRst{"Reset button
pressed > 5000 ms?"}
Init --> IsLongRst
ClearWifi("Wi-Fi credentials clear")
IsLongRst -->|"Yes"| ClearWifi
DisplayInit("Display init")
IsLongRst -->|"No"| DisplayInit
ClearWifi --> DisplayInit
WakeReason{"Wake by
user or timer?"}
DisplayInit --> WakeReason
ClearDisplay("Display clear")
WakeReason -->|"User"| ClearDisplay
IsWiFiSetup{"Wi-Fi saved?"}
WakeReason -->|"Timer"| IsWiFiSetup
ClearDisplay --> IsWiFiSetup
NeedConfig("Show set-up message")
IsWiFiSetup -->|"No"| NeedConfig
%% Config Wifi
RunSetup("Start config portal")
NeedConfig --> RunSetup
IsReset1{"Device
reset?"}
RunSetup -->|"Yes"| IsReset1
WipeConfig1("API key, friendly ID and WiFi clear")
IsReset1 -->|"Yes"| WipeConfig1
Reboot1(["Reboot"])
WipeConfig1 --> Reboot1
IsWifiConnect{"WiFi
connected?"}
IsReset1 -->|"No"| IsWifiConnect
%% Main Body
TryConnect{"WiFi connected
(5tries)?"}
IsWiFiSetup -->|"Yes"| TryConnect
ConnectError("Show connection error")
IsWifiConnect -->|"No"| ConnectError
TryConnect -->|"No"| ConnectError
Sleep1(["Sleep"])
ConnectError --> Sleep1
ClockSync("Check synchronization")
IsWifiConnect -->|"Yes"| ClockSync
TryConnect -->|"Yes"| ClockSync
IsApiSetup{"API key and
friendly ID exist?"}
ClockSync --> IsApiSetup
%% Setup
CallSetup("Ping /api/setup")
IsApiSetup -->|"No"| CallSetup
IsSetupSuccess{"Setup
success?"}
CallSetup --> IsSetupSuccess
SetupError("Show setup error")
IsSetupSuccess --> SetupError
Sleep2(["Sleep"])
SetupError --> Sleep2
%% Check update
PingServer{"Ping server,
success?"}
IsApiSetup -->|"Yes"| PingServer
IsSetupSuccess -->|"Yes"| PingServer
PingError("Show server error")
PingServer -->|"No"| PingError
Sleep3(["Sleep"])
PingError --> Sleep3
%% Act on update
IsNeedReset{"Need to reset
the device?"}
PingServer -->|"Yes"| IsNeedReset
IsNeedReset -->|"Yes"| WipeConfig1
IsNeedUpdate{"Need to update?"}
IsNeedReset -->|"No"| IsNeedUpdate
IsNeedUpdate -->|"No"| Sleep3
Update("Download and update")
IsNeedUpdate -->|"Yes"| Update
Update --> Sleep3
following Wifi connection via the captive portal, device swaps its Mac Address for an API Key and Friendly ID from the server (which get saved on device).
GET /api/setup
headers = {
'ID' => 'XX:XX:XX:XX:XX' # mac address
}
response example (success):
{ "status": 200, "api_key": "2r--SahjsAKCFksVcped2Q", "friendly_id": "917F0B", "image_url": "https://trmnl.com/images/setup/setup-logo.bmp", "filename": "empty_state" }
response example (fail, device with this Mac Address not found)
{ "status" => 404, "api_key" => nil, "friendly_id" => nil, "image_url" => nil, "filename" => nil }
assuming the Setup endpoint responded successfully, future requests are made solely for image / display content:
GET /api/display
headers = {
'ID' => 'XX:XX:XX:XX',
'Access-Token' => '2r--SahjsAKCFksVcped2Q',
'Refresh-Rate' => '1800',
'Battery-Voltage' => '4.1',
'FW-Version' => '2.1.3',
'RSSI' => '-69'
}
response example (success, device found with this access token):
{
"status"=>0, # will be 202 if no user_id is attached to device
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"2024-09-20T00:00:00",
"update_firmware"=>false,
"firmware_url"=>nil,
"refresh_rate"=>"1800",
"reset_firmware"=>false
}
response example (success, device found AND needs soft reset):
{
"status"=>0,
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"name-of-img.bmp",
"update_firmware"=>false,
"firmware_url"=>nil,
"refresh_rate"=>"1800",
"reset_firmware"=>true
}
response example (success, device found AND needs firmware update):
{
"status"=>0,
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"name-of-img.bmp",
"update_firmware"=>true,
"firmware_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-firmware.bin",
"refresh_rate"=>"1800",
"reset_firmware"=>false
}
response example (fail, device not found for this access token):
{"status"=>500, "error"=>"Device not found"}
if 'FW-Version' header != web server `Setting.firmware_download_url`, server will include absolute URL from which to download firmware.
if device detects an issue with response data from the api/display endpoint, logs are sent to server.
POST /api/log
# example request tbd
A bit of background first. The ESP32-C3 inside the TRMNL OG is one of Espressif's newer, more efficient microcontrollers. For battery powered applications, it's designed to be put to sleep to conserve power when your project doesn't need it to be active. There are two sleep modes - light and deep. Deep sleep conserves the most power, but at the cost of losing the contents of the main memory. The lowest possible power consumption is about 4uA @ 3V with a timed wakeup, but TRMNL needs to be able to wake up with a button press. Keeping the GPIO active during deep sleep (to detect the button press) uses about 100uA on average (see power profile below). This means that a 2500mAh battery could theoretically keep the TRMNL powered in this state for approximately 25,000 hours.

Of course its not very useful to have a device that's permanently sleeping, so shown below is the power profile of TRMNL doing a normal display update (timed wake up, send device status, fetch new image, show it on the e-paper display):

The peaks and valleys you see above represent the variation in electrical current (power) drawn by the ESP32-C3 at different points during the ~10.5 second update cycle. The majority of energy is used while WiFi is active (between the 3 and 9 second marks). The last portion of the graph with higher frequency peaks is from the e-paper display cycling through its update (average power is quite low). The total electrical charge needed for the update is shown in the lower right corner (0.67c). This value is in Coulombs and represents the number of electrons that have moved through the circuit.
0.67 C = 0.186111 mAh
If we ignore the ESP32 sleep periods, the energy used in each display update would allow 2500/0.186111 = 13433 updates. If we configure our TRMNL account to update the information every 15 minutes, we'll be requesting 96 updates per day and the battery charge could last for 140 days (13433 / 96). This isn't too far off from real world results. The battery voltage will drop below a safe threshold before it has released its full energy and in the equation above, we haven't counted the energy used during the sleep periods nor the energy lost in the TRMNL's power supply (between the battery and the ESP32). The real world result will be closer to 120 days on a full charge.
We can extend the battery life further by disabling updates during our sleeping hours. In the TRMNL web portal there is a setting for “Sleep Mode” (see screenshot below):

For example - by reducing the total active time each day by 8 hours, the number of updates per day (set to a 15-minute interval like above) changes from 96 to 64. With sleep mode set to 8 hours, our battery life is extended:
13433 / 64 = 210 days (theoretical maximum)
Designed for Efficiency
Lithium batteries deliver between 3.7 and 4.2 volts depending on their charge state. The ESP32 operates between 2.8V and 3.3V. In order to power the ESP32 from the battery, the voltage needs to be reduced.
There are two main types of power regulators - buck converters, and linear regulators. Many ESP32 products use linear regulators since they are less expensive. This savings comes at a cost - they throw away up to 20% of the battery's energy as waste heat. Your TRMNL was designed with a buck converter to safely and efficiently power the ESP32. This ensures the best use of the battery's energy. At TRMNL we are always looking for additional software optimizations that improve battery life.
Lithium ion batteries are ubiquitous in our lives; they're in nearly everyone's pocket/purse and many other devices you use daily. They bring a host of benefits, some risks and require care to keep them working at their best. Your TRMNL protects the battery against overcharging, but your help is needed to prevent problems when the battery is low. There are two main problems that arise with dead Li-Ion batteries:
The conditions above are to be avoided, but #2 can be dangerous as well. If your battery is puffy, dispose of it safely at a local recycling spot and contact TRMNL support to get a new one.
Even when your TRMNL is disconnected (power switch in the off position), its battery will slowly self-discharge. To keep your TRMNL's battery running at peak performance:
See releases. For older versions go here.
There are technical and non-technical options to flashing firmware.
pio run -e TRMNL_X_devpio run -e TRMNL_X_dev -t uploadpio device list # make sure JTAG device is visible
pio run -e TRMNL_X_dev -t upload --upload-port /dev/cu.usbmodem1234
pio device monitor -e TRMNL_X_dev
pio device monitor -e trmnl
When switching between TRMNL X and OG/BWRY, run pio pkg install once for the environment you are about to build (use the same -e value as pio run):
pio pkg install -e TRMNL_X_dev # TRMNL X
pio pkg install -e trmnl # TRMNL OG
pio pkg install -e trmnl_4clr # TRMNL BWRY
If you skip this step, the build may fail with Error: Missing Arduino framework directory 'None'.

Put the TRMNL into flashing mode.
Mac/Windows: Select the proper COM port from drop-down list (or leave on "Auto"). Ubuntu: Look for something like "/dev/ttyACMO USB JTAG/serial debug unit" or "Espressif USB JTAG/serial debug unit" via lsusb.

Tools required:
bootloader.bin, firmware.bin, partitions.bin (see Compilation Guide above)boot_app0.bin, found in ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/)open the Flash Tool (executable file), select these parameters, then click OK:

“0x00000000” in the far right space and check the box.
“0x00008000” in the far right space and check the box.
“0x0000e000” in the far right space and check the box.
“0x00010000” in the far right space and check the box.

finally, set the following parameters at the bottom of the Flash Tool interface:


Next, connect the PCB to the Windows machine with a USB-C cable. make sure the USB port is on the right, and that the PCB’s on/off switch is toggled DOWN for “off.”
While holding the BOOT button (below the on/off toggle), toggle the device ON by flipping the above switch UP. you may hear a sound from your Windows machine Inspect the Device Manager connections at the bottom of the interface, and a new device should appear. it may be “USB Component {{ Num }},” or something like below:


Inside the Flash Tool click the “STOP” button.

Next turn off (toggle DOWN) and unplug the PCB. you are now ready to flash another device - see Step 1.
If you would like to run local tests, you'll need to have g++/gcc installed (f.e., as part of MinGW) in PATH:
bin from installed folder (f.e. c:\mingw64\bin) to your PATHNow you can switch from "env:esp32..." to "esp:native" clicking at the bottom of the studio (point 1):

And then run platformio tests by clicking test button (point 2).
There is a suite of on-device hardware tests written with the Unity test framework, defined in test/integration/test_all. They compile into a single firmware image that is uploaded to the device, runs the tests sequentially in setup(), and prints results over the serial port.
To run the test suite (currently only on OG):
test/integration/test_config.h.example to test/integration/test_config.h and modify the file as needed to set up the WiFi network and other values. This file is ignored by Git and will not be checked in.env:trmnl_test environment.You should see terminal output like:
test/integration/test_all/all.test.cpp:33: connect_to_wifi [PASSED]
test/integration/test_all/all.test.cpp:75: test_setup_succeeds_with_registered_mac [PASSED]
test/integration/test_all/all.test.cpp:76: test_setup_returns_status_error_for_unknown_mac [PASSED]
test/integration/test_all/all.test.cpp:77: test_setup_fails_with_unreachable_host [PASSED]
test/integration/test_all/all.test.cpp:97: test_low_battery_returns_low_battery_image [PASSED]
test/integration/test_all/all.test.cpp:63: test_wifi_connects_with_valid_credentials [PASSED]
test/integration/test_all/all.test.cpp:64: test_wifi_fails_with_wrong_password [PASSED]
test/integration/test_all/all.test.cpp:65: test_wifi_fails_with_wrong_ssid [PASSED]
---------------------------------------------------------------------------- trmnl_test:integration/test_all [PASSED] Took 56.49 seconds ----------------------------------------------------------------------------
====================================================================================================== SUMMARY ======================================================================================================
Environment Test Status Duration
------------- -------------------- -------- ------------
trmnl_test integration/test_all PASSED 00:00:56.488
We use clang-format for formatting C/C++ source files. You can install it via Homebrew or your package manager of choice - it's part of llvm.
Two ways to format files:
./scripts/format.sh to format the entire repository.(top 30 of 42)
C
72.0%
C++
25.5%
HTML
1.1%
TRMNL ePaper device firmware
1,164
stars
1,015
commits
C
primary language
Sep 10, 2026
updated
created for the TRMNL e-ink display.
[!IMPORTANT] the
mainbranch is under constant development and may contain breaking changes. flash at your own risk.to access production-ready firmware, check out the tagged releases or use the Flash Assistant.
graph TB
Start(["Start"])
Init("Init peripherals")
Start --> Init
IsLongRst{"Reset button
pressed > 5000 ms?"}
Init --> IsLongRst
ClearWifi("Wi-Fi credentials clear")
IsLongRst -->|"Yes"| ClearWifi
DisplayInit("Display init")
IsLongRst -->|"No"| DisplayInit
ClearWifi --> DisplayInit
WakeReason{"Wake by
user or timer?"}
DisplayInit --> WakeReason
ClearDisplay("Display clear")
WakeReason -->|"User"| ClearDisplay
IsWiFiSetup{"Wi-Fi saved?"}
WakeReason -->|"Timer"| IsWiFiSetup
ClearDisplay --> IsWiFiSetup
NeedConfig("Show set-up message")
IsWiFiSetup -->|"No"| NeedConfig
%% Config Wifi
RunSetup("Start config portal")
NeedConfig --> RunSetup
IsReset1{"Device
reset?"}
RunSetup -->|"Yes"| IsReset1
WipeConfig1("API key, friendly ID and WiFi clear")
IsReset1 -->|"Yes"| WipeConfig1
Reboot1(["Reboot"])
WipeConfig1 --> Reboot1
IsWifiConnect{"WiFi
connected?"}
IsReset1 -->|"No"| IsWifiConnect
%% Main Body
TryConnect{"WiFi connected
(5tries)?"}
IsWiFiSetup -->|"Yes"| TryConnect
ConnectError("Show connection error")
IsWifiConnect -->|"No"| ConnectError
TryConnect -->|"No"| ConnectError
Sleep1(["Sleep"])
ConnectError --> Sleep1
ClockSync("Check synchronization")
IsWifiConnect -->|"Yes"| ClockSync
TryConnect -->|"Yes"| ClockSync
IsApiSetup{"API key and
friendly ID exist?"}
ClockSync --> IsApiSetup
%% Setup
CallSetup("Ping /api/setup")
IsApiSetup -->|"No"| CallSetup
IsSetupSuccess{"Setup
success?"}
CallSetup --> IsSetupSuccess
SetupError("Show setup error")
IsSetupSuccess --> SetupError
Sleep2(["Sleep"])
SetupError --> Sleep2
%% Check update
PingServer{"Ping server,
success?"}
IsApiSetup -->|"Yes"| PingServer
IsSetupSuccess -->|"Yes"| PingServer
PingError("Show server error")
PingServer -->|"No"| PingError
Sleep3(["Sleep"])
PingError --> Sleep3
%% Act on update
IsNeedReset{"Need to reset
the device?"}
PingServer -->|"Yes"| IsNeedReset
IsNeedReset -->|"Yes"| WipeConfig1
IsNeedUpdate{"Need to update?"}
IsNeedReset -->|"No"| IsNeedUpdate
IsNeedUpdate -->|"No"| Sleep3
Update("Download and update")
IsNeedUpdate -->|"Yes"| Update
Update --> Sleep3
following Wifi connection via the captive portal, device swaps its Mac Address for an API Key and Friendly ID from the server (which get saved on device).
GET /api/setup
headers = {
'ID' => 'XX:XX:XX:XX:XX' # mac address
}
response example (success):
{ "status": 200, "api_key": "2r--SahjsAKCFksVcped2Q", "friendly_id": "917F0B", "image_url": "https://trmnl.com/images/setup/setup-logo.bmp", "filename": "empty_state" }
response example (fail, device with this Mac Address not found)
{ "status" => 404, "api_key" => nil, "friendly_id" => nil, "image_url" => nil, "filename" => nil }
assuming the Setup endpoint responded successfully, future requests are made solely for image / display content:
GET /api/display
headers = {
'ID' => 'XX:XX:XX:XX',
'Access-Token' => '2r--SahjsAKCFksVcped2Q',
'Refresh-Rate' => '1800',
'Battery-Voltage' => '4.1',
'FW-Version' => '2.1.3',
'RSSI' => '-69'
}
response example (success, device found with this access token):
{
"status"=>0, # will be 202 if no user_id is attached to device
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"2024-09-20T00:00:00",
"update_firmware"=>false,
"firmware_url"=>nil,
"refresh_rate"=>"1800",
"reset_firmware"=>false
}
response example (success, device found AND needs soft reset):
{
"status"=>0,
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"name-of-img.bmp",
"update_firmware"=>false,
"firmware_url"=>nil,
"refresh_rate"=>"1800",
"reset_firmware"=>true
}
response example (success, device found AND needs firmware update):
{
"status"=>0,
"image_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-img.bmp",
"filename"=>"name-of-img.bmp",
"update_firmware"=>true,
"firmware_url"=>"https://trmnl.s3.us-east-2.amazonaws.com/path-to-firmware.bin",
"refresh_rate"=>"1800",
"reset_firmware"=>false
}
response example (fail, device not found for this access token):
{"status"=>500, "error"=>"Device not found"}
if 'FW-Version' header != web server `Setting.firmware_download_url`, server will include absolute URL from which to download firmware.
if device detects an issue with response data from the api/display endpoint, logs are sent to server.
POST /api/log
# example request tbd
A bit of background first. The ESP32-C3 inside the TRMNL OG is one of Espressif's newer, more efficient microcontrollers. For battery powered applications, it's designed to be put to sleep to conserve power when your project doesn't need it to be active. There are two sleep modes - light and deep. Deep sleep conserves the most power, but at the cost of losing the contents of the main memory. The lowest possible power consumption is about 4uA @ 3V with a timed wakeup, but TRMNL needs to be able to wake up with a button press. Keeping the GPIO active during deep sleep (to detect the button press) uses about 100uA on average (see power profile below). This means that a 2500mAh battery could theoretically keep the TRMNL powered in this state for approximately 25,000 hours.

Of course its not very useful to have a device that's permanently sleeping, so shown below is the power profile of TRMNL doing a normal display update (timed wake up, send device status, fetch new image, show it on the e-paper display):

The peaks and valleys you see above represent the variation in electrical current (power) drawn by the ESP32-C3 at different points during the ~10.5 second update cycle. The majority of energy is used while WiFi is active (between the 3 and 9 second marks). The last portion of the graph with higher frequency peaks is from the e-paper display cycling through its update (average power is quite low). The total electrical charge needed for the update is shown in the lower right corner (0.67c). This value is in Coulombs and represents the number of electrons that have moved through the circuit.
0.67 C = 0.186111 mAh
If we ignore the ESP32 sleep periods, the energy used in each display update would allow 2500/0.186111 = 13433 updates. If we configure our TRMNL account to update the information every 15 minutes, we'll be requesting 96 updates per day and the battery charge could last for 140 days (13433 / 96). This isn't too far off from real world results. The battery voltage will drop below a safe threshold before it has released its full energy and in the equation above, we haven't counted the energy used during the sleep periods nor the energy lost in the TRMNL's power supply (between the battery and the ESP32). The real world result will be closer to 120 days on a full charge.
We can extend the battery life further by disabling updates during our sleeping hours. In the TRMNL web portal there is a setting for “Sleep Mode” (see screenshot below):

For example - by reducing the total active time each day by 8 hours, the number of updates per day (set to a 15-minute interval like above) changes from 96 to 64. With sleep mode set to 8 hours, our battery life is extended:
13433 / 64 = 210 days (theoretical maximum)
Designed for Efficiency
Lithium batteries deliver between 3.7 and 4.2 volts depending on their charge state. The ESP32 operates between 2.8V and 3.3V. In order to power the ESP32 from the battery, the voltage needs to be reduced.
There are two main types of power regulators - buck converters, and linear regulators. Many ESP32 products use linear regulators since they are less expensive. This savings comes at a cost - they throw away up to 20% of the battery's energy as waste heat. Your TRMNL was designed with a buck converter to safely and efficiently power the ESP32. This ensures the best use of the battery's energy. At TRMNL we are always looking for additional software optimizations that improve battery life.
Lithium ion batteries are ubiquitous in our lives; they're in nearly everyone's pocket/purse and many other devices you use daily. They bring a host of benefits, some risks and require care to keep them working at their best. Your TRMNL protects the battery against overcharging, but your help is needed to prevent problems when the battery is low. There are two main problems that arise with dead Li-Ion batteries:
The conditions above are to be avoided, but #2 can be dangerous as well. If your battery is puffy, dispose of it safely at a local recycling spot and contact TRMNL support to get a new one.
Even when your TRMNL is disconnected (power switch in the off position), its battery will slowly self-discharge. To keep your TRMNL's battery running at peak performance:
See releases. For older versions go here.
There are technical and non-technical options to flashing firmware.
pio run -e TRMNL_X_devpio run -e TRMNL_X_dev -t uploadpio device list # make sure JTAG device is visible
pio run -e TRMNL_X_dev -t upload --upload-port /dev/cu.usbmodem1234
pio device monitor -e TRMNL_X_dev
pio device monitor -e trmnl
When switching between TRMNL X and OG/BWRY, run pio pkg install once for the environment you are about to build (use the same -e value as pio run):
pio pkg install -e TRMNL_X_dev # TRMNL X
pio pkg install -e trmnl # TRMNL OG
pio pkg install -e trmnl_4clr # TRMNL BWRY
If you skip this step, the build may fail with Error: Missing Arduino framework directory 'None'.

Put the TRMNL into flashing mode.
Mac/Windows: Select the proper COM port from drop-down list (or leave on "Auto"). Ubuntu: Look for something like "/dev/ttyACMO USB JTAG/serial debug unit" or "Espressif USB JTAG/serial debug unit" via lsusb.

Tools required:
bootloader.bin, firmware.bin, partitions.bin (see Compilation Guide above)boot_app0.bin, found in ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/)open the Flash Tool (executable file), select these parameters, then click OK:

“0x00000000” in the far right space and check the box.
“0x00008000” in the far right space and check the box.
“0x0000e000” in the far right space and check the box.
“0x00010000” in the far right space and check the box.

finally, set the following parameters at the bottom of the Flash Tool interface:


Next, connect the PCB to the Windows machine with a USB-C cable. make sure the USB port is on the right, and that the PCB’s on/off switch is toggled DOWN for “off.”
While holding the BOOT button (below the on/off toggle), toggle the device ON by flipping the above switch UP. you may hear a sound from your Windows machine Inspect the Device Manager connections at the bottom of the interface, and a new device should appear. it may be “USB Component {{ Num }},” or something like below:


Inside the Flash Tool click the “STOP” button.

Next turn off (toggle DOWN) and unplug the PCB. you are now ready to flash another device - see Step 1.
If you would like to run local tests, you'll need to have g++/gcc installed (f.e., as part of MinGW) in PATH:
bin from installed folder (f.e. c:\mingw64\bin) to your PATHNow you can switch from "env:esp32..." to "esp:native" clicking at the bottom of the studio (point 1):

And then run platformio tests by clicking test button (point 2).
There is a suite of on-device hardware tests written with the Unity test framework, defined in test/integration/test_all. They compile into a single firmware image that is uploaded to the device, runs the tests sequentially in setup(), and prints results over the serial port.
To run the test suite (currently only on OG):
test/integration/test_config.h.example to test/integration/test_config.h and modify the file as needed to set up the WiFi network and other values. This file is ignored by Git and will not be checked in.env:trmnl_test environment.You should see terminal output like:
test/integration/test_all/all.test.cpp:33: connect_to_wifi [PASSED]
test/integration/test_all/all.test.cpp:75: test_setup_succeeds_with_registered_mac [PASSED]
test/integration/test_all/all.test.cpp:76: test_setup_returns_status_error_for_unknown_mac [PASSED]
test/integration/test_all/all.test.cpp:77: test_setup_fails_with_unreachable_host [PASSED]
test/integration/test_all/all.test.cpp:97: test_low_battery_returns_low_battery_image [PASSED]
test/integration/test_all/all.test.cpp:63: test_wifi_connects_with_valid_credentials [PASSED]
test/integration/test_all/all.test.cpp:64: test_wifi_fails_with_wrong_password [PASSED]
test/integration/test_all/all.test.cpp:65: test_wifi_fails_with_wrong_ssid [PASSED]
---------------------------------------------------------------------------- trmnl_test:integration/test_all [PASSED] Took 56.49 seconds ----------------------------------------------------------------------------
====================================================================================================== SUMMARY ======================================================================================================
Environment Test Status Duration
------------- -------------------- -------- ------------
trmnl_test integration/test_all PASSED 00:00:56.488
We use clang-format for formatting C/C++ source files. You can install it via Homebrew or your package manager of choice - it's part of llvm.
Two ways to format files:
./scripts/format.sh to format the entire repository.(top 30 of 42)
C
72.0%
C++
25.5%
HTML
1.1%