-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
This example app implements a simple interactive shell that lets you tinker with the display. You can draw simple shapes (i.e. everything the epd driver provides), read system information, etc. I've ported some of my screen test algorithms (i.e. render_stairs and render_grid) as well. This can be helpful when debugging incompatible or broken displays or just experimenting with the draw functions. Also note: the power_on command basically obsoletes the calibration_helper example.
- Loading branch information
Showing
24 changed files
with
7,713 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# For more information about build system see | ||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html | ||
# The following five lines of boilerplate have to be in your project's | ||
# CMakeLists in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.18) | ||
|
||
# dependencies | ||
set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../") | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(screen_diag) | ||
|
||
set(IDF_VER_SANE "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") | ||
if (IDF_VER_SANE VERSION_LESS "5.0.0") | ||
message(FATAL_ERROR "screen_diag requires at least ESP-IDF v5.0.0") | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
# Screen Diagnostics | ||
This example app implements a simple shell to allow you to tinker with the display. You have access to all drawing functions from the _epd driver_, as well as system information, etc. | ||
|
||
There are also pre-programmed algorithms (e.g. `render_stairs`, `render_grid`) which can be used to find pixel errors or display incompatibilities. | ||
|
||
The `screen_diag` examples requires ESP-IDF v5.x or newer. | ||
|
||
## Setup | ||
Don't forget to set your display type in `epd_init` in `epd.c`! | ||
|
||
First you need to flash the firmware: | ||
```sh | ||
idf.py flash | ||
``` | ||
|
||
After that, you can enter the shell environment with: | ||
```sh | ||
idf.py monitor | ||
``` | ||
|
||
Please note the [known issues](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/tools/idf-monitor.html#known-issues-with-idf-monitor) of the IDF Monitor for limitations. | ||
|
||
## Usage | ||
You can get a full list (see below) of all available commands with: `help`. | ||
|
||
``` | ||
system_restart | ||
Restarts the system. | ||
free_heap_size | ||
Returns the free heap size. | ||
dump_heaps_info [<caps>] | ||
Dumps heap information of all heaps matching the capability. | ||
<caps> Heap caps to print. Default: MALLOC_CAP_DEFAULT | ||
dump_tasks | ||
Dumps all tasks with their names, current state and stack usage. | ||
chip_info | ||
Dumps chip information. | ||
firmware_info | ||
Dumps information about the ESP-IDF and the firmware. | ||
get_time | ||
Returns the time in microseconds since boot. | ||
get_mac [<interface>] | ||
Returns the MAC address for the given interface or the pre-programmed base | ||
address. | ||
<interface> Either "wifi_station", "wifi_ap", "bluetooth" or "ethernet" | ||
get_rotation | ||
Get current screen rotation. | ||
set_rotation <rotation> [--inverted] | ||
Changes screen rotation. | ||
<rotation> screen rotation: "horizontal" or "portrait" | ||
--inverted | ||
get_width | ||
Print screen width. | ||
get_height | ||
Print screen height. | ||
get_pixel <posx> <posy> | ||
Get pixel color in front buffer. | ||
<posx> x position | ||
<posy> y position | ||
set_pixel <posx> <posy> [<color>] | ||
Set pixel color in front buffer. | ||
<posx> x position | ||
<posy> y position | ||
<color> color. default value: 0 (0x00) | ||
clear_screen | ||
Clear the entire screen and reset the front buffer to white. | ||
full_clear_screen | ||
Same as clear_screen, but also tries to get rid of any artifacts by cycling | ||
through colors on the screen. | ||
get_temp | ||
Returns the ambient temperature. | ||
power_on | ||
Turns on the power of the display. | ||
power_off | ||
Turns off the power of the display. | ||
draw_hline <x> <y> <len> [<color>] | ||
Draw horizontal line. | ||
<x> start x position | ||
<y> start y position | ||
<len> length of the line | ||
<color> default value: 0x00 | ||
draw_vline <x> <y> <len> [<color>] | ||
Draw vertical line. | ||
<x> start x position | ||
<y> start y position | ||
<len> length of the line | ||
<color> default value: 0x00 | ||
draw_line <start_x> <start_y> <end_x> <end_y> [<color>] | ||
Draw line between two points. | ||
<start_x> start x position | ||
<start_y> start y position | ||
<end_x> end x position | ||
<end_y> end y position | ||
<color> default value: 0x00 | ||
draw_rect <x> <y> <width> <height> [<color>] | ||
Draw a rectangle. | ||
<x> top left x position | ||
<y> top left y position | ||
<width> square width | ||
<height> square height | ||
<color> default value: 0x00 | ||
fill_rect <x> <y> <width> <height> [<color>] | ||
Draw a filled rectangle. | ||
<x> top left x position | ||
<y> top left y position | ||
<width> square width | ||
<height> square height | ||
<color> default value: 0x00 | ||
draw_circle <center_x> <center_y> <radius> [<color>] | ||
Draw a circle. | ||
<center_x> center x position | ||
<center_y> center y position | ||
<radius> circle radius | ||
<color> default value: 0x00 | ||
fill_circle <center_x> <center_y> <radius> [<color>] | ||
Draw a filled circle. | ||
<center_x> center x position | ||
<center_y> center y position | ||
<radius> circle radius | ||
<color> default value: 0x00 | ||
draw_triangle <x0> <y0> <x1> <y1> <x0> <y0> [<color>] | ||
Draw a triangle from three different points. | ||
<x0> first edge x position | ||
<y0> first edge y position | ||
<x1> second edge x position | ||
<y1> second edge y position | ||
<x0> third edge x position | ||
<y0> third edge y position | ||
<color> default value: 0x00 | ||
fill_triangle <x0> <y0> <x1> <y1> <x0> <y0> [<color>] | ||
Draw a filled triangle from three different points. | ||
<x0> first edge x position | ||
<y0> first edge y position | ||
<x1> second edge x position | ||
<y1> second edge y position | ||
<x0> third edge x position | ||
<y0> third edge y position | ||
<color> default value: 0x00 | ||
write_text [-s] <x> <y> [<color>] <msg> | ||
Write text message to the screen using the sans-serif font by default. | ||
<x> x position | ||
<y> y position | ||
<color> default value: 0x00 | ||
-s, --serif Use serif font rather than sans-serif. | ||
<msg> Text to be printed. | ||
render_stairs [<slope>] [<width>] [<color>] | ||
Render multiple diagonal lines across the screen. | ||
<slope> angle by which each diagonal line is drawn. default value: 3 | ||
<width> thickness of each diagonal line. default value: 100 | ||
<color> default value: 0x00 | ||
render_grid [<gutter>] [<color>] | ||
Renders a grid across the whole screen. At a certain gutter size, cell info | ||
will be printed as well. | ||
<gutter> default value: 75 | ||
<color> default value: 0x00 | ||
help | ||
Print the list of registered commands | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
idf_component_register(SRCS "screen_diag.c" "epd.c" "commands.c" "commands/system.c" | ||
"commands/screen.c" "commands/graphics.c" "commands/tests.c" | ||
INCLUDE_DIRS "." "res/fonts" | ||
REQUIRES epdiy console nvs_flash fatfs esp_app_format) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "commands.h" | ||
|
||
bool validate_color(uint8_t* inout_color, struct arg_int* arg) | ||
{ | ||
int user_color = arg->count != 0 ? arg->ival[0] : *inout_color; | ||
if (user_color < 0 || user_color > 0xFF) | ||
{ | ||
printf("Invalid color %d (0x%02x): Must be in range 0x00 to 0xFF.\r\n", user_color, (uint8_t) user_color); | ||
return false; | ||
} | ||
|
||
*inout_color = (uint8_t) user_color; | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#pragma once | ||
/* Helper functions and macros for common use cases, | ||
* when registering or implementing commands. | ||
*/ | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
#include <esp_console.h> | ||
#include <argtable3/argtable3.h> | ||
|
||
#ifndef ARRAY_SIZE | ||
/** | ||
* Returns size of a (static) C array. | ||
*/ | ||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | ||
#endif | ||
|
||
/** | ||
* Checks whether the given color argument is a valid color. | ||
* I.e. when it's color value is possible to represent by an uint8_t (0x00 - 0xFF). | ||
* If no color argument was provided by the user, returns the default color of 0x00. | ||
* | ||
* @param inout_color initial value will be used as default color, | ||
* when the user did not specify a color. | ||
* when successful, will be set to the given color. | ||
* @param arg user-specified color argument | ||
* @return whether the given color is valid | ||
*/ | ||
bool validate_color(uint8_t* inout_color, struct arg_int* arg); | ||
|
||
/** | ||
* Determines the number of arguments stored in a struct (container). | ||
* That is usually the number of arguments for a given command and | ||
* can be used when initializing the arg_end parameter. | ||
* | ||
* This macro assumes, that | ||
* 1. each argument inside the struct is referenced by a pointer, | ||
* 2. each struct ends with an arg_end*, | ||
* 3. there are no other members in the struct, besides different argument types. | ||
*/ | ||
#define NARGS(container) ((sizeof(container) / sizeof(struct arg_end*)) - 1) | ||
|
||
/** | ||
* Handles argument validation for the command. | ||
* Assumes that `argc` and `argv` variables are visible, thus should | ||
* only be used inside the command implementation function. | ||
* | ||
* @param args_struct name of the (static) argument struct. | ||
*/ | ||
#define HANDLE_ARGUMENTS(args_struct) \ | ||
{ \ | ||
int nerrors = arg_parse(argc, argv, (void**) &args_struct); \ | ||
if (nerrors > 0) { \ | ||
arg_print_errors(stdout, args_struct.end, argv[0]); \ | ||
return 1; \ | ||
} \ | ||
} | ||
|
||
/** | ||
* Get optional argument value if provided by the user. Otherwise use the default value. | ||
* | ||
* @param arg pointer to argument struct (e.g. struct arg_int*) | ||
* @param accessor accessor used to retrieve the first value (e.g. ival for struct arg_int) | ||
* @param default_value | ||
*/ | ||
#define GET_ARG(arg, accessor, default_value) (arg)->count == 1 ? (arg)->accessor[0] : (default_value) | ||
|
||
/** | ||
* Alias for GET_ARG, specialized for int arguments. | ||
* | ||
* @param arg pointer to an struct arg_int | ||
* @param default_value | ||
*/ | ||
#define GET_INT_ARG(arg, default_value) GET_ARG(arg, ival, default_value) |
Oops, something went wrong.