Project architecture reference
Introduction
The Goal of this document is to provide a high level overview of the project architecture. This document is a work in progress and will be updated as the project evolves.
Files and Directories
The project is organized into the following directories:
cmake
: Contains the cmake files for the project and for each target
components
: Contains the main components of the project
customization
: Contains the customization files for the project to avoid to change in sources
docs
: Contains project documentation
embedded
: Contains the code for embedded maintenance web page of the firmware
hardware
: Contains the hardware specific files like drivers, partitions description, specific sdkconfig, hardware configuration files
resources
: Contains the graphical resources like logo for bootsplash, icons, etc
main
: Contains the main code of the project
scripts
: Contains the scripts used for the project like the fonts builder, the language pack builder, etc
tools
: Contains the tools used for the project to test features
translations
: Contains the language files for the firmware
CMakelists.txt
: The main CMake file for the project
LICENSE
: The license file for the project
README.md
: The main readme file for the project
.gitignore
: The git ignore file for the project
.gitmodules
: The git submodules file for the project
.github
: The github actions directory for the project
cmake directory
The cmake
directory contains the cmake files for the project and for each target. The cmake files are organized into the following files and subdirectories:
dev_tools.cmake
: Contains the cmake file for the development tools (log level, benchmark, log color, etc), this file can be edited but only for debug purpose
features.cmake
: Contains the cmake file for the features of the project (wifi, webserver, etc)
sanity_check.cmake
: Contains the cmake file for the sanity check of the project
targets.cmake
: Complete the cmake file of the project according target board
targets
directory : contains the cmake file for each target board, the file is named as the target board name
Each target file contains the following sections:
# Ensure the board is enabled in CMakeLists.txt
if(<BOARD_NAME>) #<BOARD_NAME> is enabled or not in CMakeLists.txt
# Add board name (Mandatory)
set(TFT_TARGET "<BOARD_NAME>")
# Add the sdkconfig file path (Mandatory), it can be specific or based on one of the common sdkconfig
set(SDKCONFIG ${CMAKE_SOURCE_DIR}/hardware/<BOARD_NAME>/sdkconfig)
# Add Specific Components if any for the board (Mandatory)
list(APPEND EXTRA_COMPONENT_DIRS ${CMAKE_SOURCE_DIR}/hardware/<BOARD_NAME>/components)
# Add specific usb driver for otg (Only if needed)
list(APPEND EXTRA_COMPONENT_DIRS ${CMAKE_SOURCE_DIR}/hardware/drivers_usb_otg)
# Add specific video driver for i80 (Only if needed)
list(APPEND EXTRA_COMPONENT_DIRS ${CMAKE_SOURCE_DIR}/hardware/drivers_video_i80)
# Add specific video driver for rgb (Only if needed)
list(APPEND EXTRA_COMPONENT_DIRS ${CMAKE_SOURCE_DIR}/hardware/rgb)
# Add specific bsp path for board definition (Mandatory)
add_compile_options("-I${CMAKE_SOURCE_DIR}/hardware/<BOARD_NAME>/components/bsp")
# Enable USB-OTG as serial alternative for communications (Only if needed)
add_compile_options(-DESP3D_USB_SERIAL_FEATURE=1)
endif()
components directory
The components
directory contains the main components of the project. The components are organized into the following subdirectories:
esp_litlefs
: Contains the code for the LittleFS file system
esp3d_log
: Contains the code for the logging system
lvgl
: Contains the code for the LittlevGL graphics library
mdns
: Contains the code for the mDNS service
SSDP_IDF
: Contains the code for the SSDP service
Note SSDP_IDF and esp_littlefs are actually defined as git submodules.
customizations directory
The customizations
directory contains the customization files for the project. The customization files are organized into the following subdirectories:
notifications
: Contains the customization strings for the notifications
ssdp
: Contains the customization strings for the SSDP service
docs directory
embedded directory
The embedded
directory contains the code for the embedded maintenance web page of the firmware. The code is organized into the following subdirectories:
-
assets
: Contains the assets for the embedded maintenance web page
favicon.ico
: The favicon for the embedded maintenance web page
header.txt
: The header for the embedded maintenance web page
footer.txt
: The footer for the embedded maintenance web page
-
config
: Contains the configuration files for the test server and production page
buildassets.js
: This script will convert the binaries assets into a C header file
server.js
: The test server for the embedded maintenance web page
webpack.dev.js
: The webpack configuration for the test server and test page
webpack.prod.js
: The webpack configuration for the production page
-
dist
: Contains the binary distribution file for the embedded maintenance web page
-
server
: Is the directory that simulate the local flash system for the upload
-
src
: Contains the source code for the embedded maintenance web page
index.html
: The main html file for the embedded maintenance web page
index.js
: The main javascript file for the embedded maintenance web page
menu.js
: The menu javascript file for the embedded maintenance web page
style.css
: The main css file for the embedded maintenance web page
-
package.json
: The package file for the embedded maintenance web page
-
Notes.txt
: The notes file for the embedded maintenance web page
-
.gitignore
: The git ignore file for the embedded maintenance web page
hardware directory
The hardware
directory contains the hardware specific files like drivers, partitions description, specific sdkconfig, hardware configuration files. The hardware specific files are organized into one common subdirectory and one subdirectory for each supported hardware platform.
common
: Contains the common hardware specific files like partitions description, specific sdkconfig
drivers_common
: Contains the common drivers for all the boards
drivers_video_i80
: Contains the drivers for the i80 video drivers which cannot be in common drivers because of the specific sdkconfig
drivers_video_rgb
: Contains the drivers for the rgb video drivers which cannot be in common drivers because of the specific sdkconfig
drivers_usb_otg
: Contains the drivers for the usb otg which cannot be in common drivers because of the specific sdkconfig and hardware
<BOARD_NAME>
: Contains the hardware drivers, definitions, partitions and sdkconfig specific files for the <BOARD_NAME> board
- …
Drivers |
Type |
Depend |
ESP32_2432S028R |
ESP32_3248S035C |
ESP32_3248S035R |
ESP32_ROTRICS_DEXARM35 |
ESP32_CUSTOM |
disp_backlight |
Display component |
esp3d_log driver |
X |
X |
X |
O |
O |
disp_spi |
|
esp3d_log driver |
O |
O |
O |
X |
O |
ili9341 |
SPI Display |
esp3d_log esp_lcd driver |
X |
O |
O |
O |
O |
ili9488 |
|
esp3d_log lvgl disp_spi |
O |
O |
O |
X |
O |
st7796 |
SPI Display |
esp3d_log esp_lcd driver |
O |
X |
X |
O |
O |
xpt2046 |
SPI Touch |
esp3d_log driver |
X |
O |
X |
X |
O |
gt911 |
|
esp3d_log i2c_bus |
O |
X |
O |
O |
O |
ft5x06 |
|
esp3d_log lvgl i2c_bus |
O |
O |
O |
O |
O |
i2c_bus |
|
esp3d_log driver |
O |
X |
O |
O |
O |
spi_bus |
SPI Bus |
esp3d_log driver |
X |
X |
X |
X |
O |
sw_spi |
Software SPI |
esp3d_log driver |
X |
O |
O |
O |
O |
Drivers |
Type |
Depend |
ESP32S3_4827S043C |
ESP32S3_8048S043C |
ESP32S3_8048S050C |
ESP32S3_8048S070C |
ESP32S3_BZM_TFT35_GT911 |
ESP32S3_HMI43V3 |
ESP32S3_ZX3D50CE02S_USRC_4832 |
ESP32S3_CUSTOM |
disp_backlight |
Display component |
esp3d_log driver |
X |
X |
X |
X |
X |
O |
O |
O |
st7796 |
i80 Display |
esp3d_log esp_lcd driver |
O |
O |
O |
O |
X |
O |
X |
O |
ili9485 |
RGB Display |
esp3d_log esp_lcd driver |
X |
O |
O |
O |
O |
O |
O |
O |
st7262 |
RGB Display |
esp3d_log esp_lcd driver |
O |
X |
X |
O |
O |
O |
O |
O |
ek9716 |
RGB Display |
esp3d_log lvgl esp_lcd driver |
O |
O |
O |
X |
O |
O |
O |
O |
rm68120 |
i80 Display |
esp3d_log lvgl esp_lcd driver |
O |
O |
O |
O |
O |
X |
O |
O |
ft5x06 |
i2c Touch |
esp3d_log lvgl i2c_bus |
O |
O |
O |
O |
O |
X |
X |
O |
gt911 |
i2c Touch |
esp3d_log i2c_bus |
X |
X |
X |
X |
X |
O |
O |
O |
tca9554 |
IO expander |
esp3d_log i2c_bus |
O |
O |
O |
O |
O |
X |
O |
O |
i2c_bus |
i2c Bus |
esp3d_log driver |
X |
X |
X |
X |
X |
X |
X |
O |
usb_serial |
OTG Host |
esp3d_log |
O |
O |
O |
O |
X |
X |
X |
X |
Bus drivers
- spi_bus driver
The
spi_bus
driver is a SPI bus driver that is used to control the SPI bus. The spi_bus
driver configuration is part of display driver configuration.
in disp_def.h:
// SPI (dedicated or shared)
.spi_bus_config =
{
.spi_host_index = SPI2_HOST,
.pin_miso = 12, /**< MISO pin number */
.pin_mosi = 13, /**< MOSI pin number */
.pin_clk = 14, /**< CLK pin number */
.is_master = true, /**< SPI master mode */
.max_transfer_sz = DISP_BUF_SIZE * 2, /**< Maximum transfer size */
.dma_channel = 1, /**< DMA channel */
.quadwp_io_num = -1, /**< QuadWP pin number */
.quadhd_io_num = -1 /**< QuadHD pin number */
},
- sw_spi driver
The
sw_spi
driver is a software SPI driver that is used to control the SPI bus. The sw_spi
driver configuration is part of the driver configuration file which use it.
eg: touch driver use it, so it can be part of the touch driver configuration.
touch_def.h:
// SPI (BitBang)
const sw_spi_config_t touch_spi_cfg = {
.cs_pin = 33, // GPIO 33
.clk_pin = 25, // GPIO 25
.mosi_pin = 32, // GPIO 33
.miso_pin = 39, // GPIO 39
};
- i2c_bus driver
The
i2c_bus
driver is a I2C bus driver that is used to control the I2C bus. The i2c_bus
driver configuration file is i2c_def.h.
bsp.c:
//define the I2C bus
#define I2C_PORT_NUMBER 0
// I2C pins definition
const i2c_config_t i2c_cfg = {
.mode = I2C_MODE_MASTER,
.scl_io_num = 20, // GPIO 20
.sda_io_num = 19, // GPIO 19
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 400*1000
};
- tca9554 driver
The
tca9554
driver is a I2C GPIO expander driver that is used to control the TCA9554 GPIO expander. The tca9554
driver configuration file is tca9554_def.h.
tca9554_def.h:
const tca9554_config_t tca9554_cfg = {.i2c_clk_speed = 400 * 1000,
.i2c_addr = (uint8_t[]){0x3C, 0x24, 0}};
- usb_serial driver
The
usb_serial
driver is a USB serial driver that is used to control the OTG USB serial. The usb_serial
driver configuration usb_serial_def.h.
usb_serial_def.h:
#define ESP3D_USB_SERIAL_BAUDRATE "115200"
#define ESP3D_USB_SERIAL_DATA_BITS (8)
#define ESP3D_USB_SERIAL_PARITY \
(0) // 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits
#define ESP3D_USB_SERIAL_STOP_BITS \
(0) // 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space
SPI Display drivers
- ili9341 driver
The
ili9341
driver is a SPI display driver that is used to control the ILI9341 display. The ili9341
driver configuration is part of display driver configuration.
in disp_def.h:
#define DISP_HOR_RES_MAX 320
#define DISP_VER_RES_MAX 240
#define DISP_USE_DOUBLE_BUFFER (true)
#if WITH_PSRAM
// 1/10 (24-line) buffer (15KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX / 10)
#define DISP_BUF_MALLOC_TYPE MALLOC_CAP_SPIRAM
#else
// 1/20 (12-line) buffer (7.5KB) in internal DRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * 12)
#define DISP_BUF_MALLOC_TYPE MALLOC_CAP_DMA
#endif // WITH_PSRAM
#define DISP_BUF_SIZE_BYTES (DISP_BUF_SIZE * 2)
// Display configuration
esp_spi_ili9341_config_t display_spi_ili9341_cfg = {
.panel_dev_config = {.reset_gpio_num =
4, // GPIO 4
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.data_endian = LCD_RGB_DATA_ENDIAN_BIG,
.bits_per_pixel = 16,
.flags = {.reset_active_high = 0},
.vendor_config = NULL},
.spi_bus_config =
{
.spi_host_index = SPI2_HOST,
.pin_miso = 12, /**< MISO pin number */
.pin_mosi = 13, /**< MOSI pin number */
.pin_clk = 14, /**< CLK pin number */
.is_master = true, /**< SPI master mode */
.max_transfer_sz = DISP_BUF_SIZE * 2, /**< Maximum transfer size */
.dma_channel = 1, /**< DMA channel */
.quadwp_io_num = -1, /**< QuadWP pin number */
.quadhd_io_num = -1 /**< QuadHD pin number */
},
.disp_spi_cfg =
{.dc_gpio_num = 2, /*!< GPIO used to select the D/C line, set this to -1
if the D/C line is not used */
.cs_gpio_num = 15, /*!< GPIO used for CS line */
.spi_mode = 0, /*!< Traditional SPI mode (0~3) */
.pclk_hz = 40 * 1000 * 1000, /*!< Frequency of pixel clock */
.trans_queue_depth = 10, /*!< Size of internal transaction queue */
.on_color_trans_done = NULL, /*!< Callback invoked when color data
transfer has finished */
.user_ctx = NULL, /*!< User private data, passed directly to
on_color_trans_done's user_ctx */
.lcd_cmd_bits = 8, /*!< Bit-width of LCD command */
.lcd_param_bits = 8, /*!< Bit-width of LCD parameter */
.flags =
{
/*!< Extra flags to fine-tune the SPI device */
.dc_low_on_data = 0, /*!< If this flag is enabled, DC line = 0
means transfer data, DC line = 1 means
transfer command; vice versa */
.octal_mode =
0, /*!< transmit with octal mode (8 data lines), this mode
is used to simulate Intel 8080 timing */
.quad_mode =
0, /*!< transmit with quad mode (4 data lines), this mode
is useful when transmitting LCD parameters (Only use
one line for command) */
.sio_mode =
0, /*!< Read and write through a single data line (MOSI) */
.lsb_first = 0, /*!< transmit LSB bit first */
.cs_high_active = 0, /*!< CS line is high active */
}
},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
- st7796 spi driver
The
st7796
driver is a display driver that is used to control the ST7796 display. The st7796
driver configuration is part of display driver configuration.
disp_def.h:
#define DISP_HOR_RES_MAX 480
#define DISP_VER_RES_MAX 320
// Display interface
#define DISP_USE_DOUBLE_BUFFER (true)
#if WITH_PSRAM
// 1/10 (32-line) buffer (30KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX / 10)
#define DISP_BUF_MALLOC_TYPE MALLOC_CAP_SPIRAM
#else
// 1/40 (8-line) buffer (7.5KB) in internal DRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * 8)
#define DISP_BUF_MALLOC_TYPE MALLOC_CAP_DMA
#endif // WITH_PSRAM
#define DISP_BUF_SIZE_BYTES (DISP_BUF_SIZE * 2)
// LCD panel configuration
esp_spi_st7262_config_t display_spi_st7262_cfg = {
.panel_dev_config = {.reset_gpio_num = -1,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.data_endian = LCD_RGB_DATA_ENDIAN_BIG,
.bits_per_pixel = 16,
.flags = {.reset_active_high = 0},
.vendor_config = NULL},
.spi_bus_config = // SPI (shared with Touch)
{
.spi_host_index = SPI2_HOST,
.pin_miso = 12, /**< MISO pin number */
.pin_mosi = 13, /**< MOSI pin number */
.pin_clk = 14, /**< CLK pin number */
.is_master = true, /**< SPI master mode */
.max_transfer_sz = DISP_BUF_SIZE * 2, /**< Maximum transfer size */
.dma_channel = 1, /**< DMA channel */
.quadwp_io_num = -1, /**< QuadWP pin number */
.quadhd_io_num = -1 /**< QuadHD pin number */
},
.disp_spi_cfg =
{.cs_gpio_num = 15, /*!< GPIO used for CS line */
.dc_gpio_num = 2, /*!< GPIO used to select the D/C line, set this to -1
if the D/C line is not used */
.spi_mode = 0, /*!< Traditional SPI mode (0~3) */
.pclk_hz = 40 * 1000 * 1000, /*!< Frequency of pixel clock */
.trans_queue_depth = 10, /*!< Size of internal transaction queue */
.on_color_trans_done = NULL, /*!< Callback invoked when color data
transfer has finished */
.user_ctx = NULL, /*!< User private data, passed directly to
on_color_trans_done's user_ctx */
.lcd_cmd_bits = 8, /*!< Bit-width of LCD command */
.lcd_param_bits = 8, /*!< Bit-width of LCD parameter */
.flags =
{
/*!< Extra flags to fine-tune the SPI device */
.dc_low_on_data = 0, /*!< If this flag is enabled, DC line = 0
means transfer data, DC line = 1 means
transfer command; vice versa */
.octal_mode =
0, /*!< transmit with octal mode (8 data lines), this mode
is used to simulate Intel 8080 timing */
.quad_mode =
0, /*!< transmit with quad mode (4 data lines), this mode
is useful when transmitting LCD parameters (Only use
one line for command) */
.sio_mode =
0, /*!< Read and write through a single data line (MOSI) */
.lsb_first = 0, /*!< transmit LSB bit first */
.cs_high_active = 0, /*!< CS line is high active */
}},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
RGB Display drivers
- st7262 driver
The
st7262
driver is a RGB display driver that is used to control the ST7262 display. The st7262
driver configuration is part of display driver configuration.
in disp_def.h:
#define DISP_HOR_RES_MAX 800
#define DISP_VER_RES_MAX 480
#define DISP_CLK_FREQ (14 * 1000 * 1000)
#define DISP_AVOID_TEAR_EFFECT_WITH_SEM (true)
#define DISP_USE_BOUNCE_BUFFER (false)
#define DISP_USE_DOUBLE_BUFFER (true)
#define DISP_NUM_FB (1)
#define DISP_PATCH_FS_FREQ (6 * 1000 * 1000) // 6MHz
#define DISP_PATCH_FS_DELAY (40)
#if DISP_NUM_FB == 2
// Full frame buffer (255KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX)
#else
// 1/4 (68-line) buffer (63.75KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX / 4)
#endif // WITH_PSRAM
#define DISP_BUF_SIZE_BYTES (DISP_BUF_SIZE * 2)
const esp_rgb_st7262_config_t disp_panel_cfg = {
.panel_config =
{.clk_src = LCD_CLK_SRC_DEFAULT,
.timings =
{
.pclk_hz = DISP_CLK_FREQ,
.h_res = DISP_HOR_RES_MAX,
.v_res = DISP_VER_RES_MAX,
.hsync_pulse_width = 4,
.hsync_back_porch = 8,
.hsync_front_porch = 8,
.vsync_pulse_width = 4,
.vsync_back_porch = 8,
.vsync_front_porch = 8,
.flags =
{
.hsync_idle_low = 0,
.vsync_idle_low = 0,
.de_idle_high = 0,
.pclk_active_neg = true,
.pclk_idle_high = 0,
},
},
.data_width = 16, // RGB565 in parallel mode
.bits_per_pixel = 0,
.num_fbs = DISP_NUM_FB,
#if DISP_USE_BOUNCE_BUFFER
.bounce_buffer_size_px = DISP_BUF_SIZE,
#else
.bounce_buffer_size_px = 0,
#endif
.sram_trans_align = 0,
.psram_trans_align = 64,
.hsync_gpio_num = 39, // GPIO 39
.vsync_gpio_num = 41, // GPIO 41
.de_gpio_num = 40, // GPIO 40
.pclk_gpio_num = 42, // GPIO 42
.disp_gpio_num = -1, // EN pin not connected
.data_gpio_nums =
{
8, // D0 (B0) - GPIO 8
3, // D1 (B1) - GPIO 3
46, // D2 (B2) - GPIO 46
9, // D3 (B3) - GPIO 9
1, // D4 (B4) - GPIO 1
5, // D5 (G0) - GPIO 5
6, // D6 (G1) - GPIO 6
7, // D7 (G2) - GPIO 7
15, // D8 (G3) - GPIO 15
16, // D9 (G4) - GPIO 16
4, // D10 (G5) - GPIO 4
45, // D11 (R0) - GPIO 45
48, // D12 (R1) - GPIO 48
47, // D13 (R2) - GPIO 47
21, // D14 (R3) - GPIO 21
14, // D15 (R4) - GPIO 14
},
.flags =
{
.disp_active_low = (uint32_t)NULL,
.refresh_on_demand = (uint32_t)NULL,
.fb_in_psram =
true, // Do not change this, as it is mandatory for RGB
// parallel interface and octal PSRAM
.double_fb = (uint32_t)NULL,
.no_fb = (uint32_t)NULL,
.bb_invalidate_cache = (uint32_t)NULL,
}},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
- ek9716 driver
The
ek9716
driver is a RGB display driver that is used to control the EK9716 display. The ek9716
driver configuration is part of display driver configuration.
in disp_def.h:
#define DISP_HOR_RES_MAX 800
#define DISP_VER_RES_MAX 480
#define DISP_AVOID_TEAR_EFFECT_WITH_SEM (true)
#define DISP_USE_BOUNCE_BUFFER (false)
#define DISP_USE_DOUBLE_BUFFER (true)
#define DISP_NUM_FB (1)
#define DISP_CLK_FREQ (16 * 1000 * 1000)
#define DISP_PATCH_FS_FREQ (6 * 1000 * 1000) // 6MHz
#define DISP_PATCH_FS_DELAY (40)
#if DISP_NUM_FB == 2
// Full frame buffer (255KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX)
#else
// 1/4 (68-line) buffer (63.75KB) in external PSRAM
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * DISP_VER_RES_MAX / 4)
#endif // WITH_PSRAM
#define DISP_BUF_SIZE_BYTES (DISP_BUF_SIZE * 2)
//Panel configuration
const esp_rgb_ek9716_config_t disp_panel_cfg = {
.panel_config = {
.clk_src = LCD_CLK_SRC_DEFAULT,
.timings = {
.pclk_hz = DISP_CLK_FREQ ,
.h_res = DISP_HOR_RES_MAX,
.v_res = DISP_VER_RES_MAX,
.hsync_pulse_width = 30,
.hsync_back_porch = 16,
.hsync_front_porch = 210,
.vsync_pulse_width = 13,
.vsync_back_porch = 10,
.vsync_front_porch = 22,
.flags = {
.hsync_idle_low = 0,
.vsync_idle_low = 0,
.de_idle_high = 0,
.pclk_active_neg = true,
.pclk_idle_high = 0,
},
},
.data_width = 16, // RGB565 in parallel mode
.bits_per_pixel = 0,
.num_fbs = DISP_NUM_FB,
#if DISP_USE_BOUNCE_BUFFER
.bounce_buffer_size_px = DISP_BUF_SIZE,
#else
.bounce_buffer_size_px = 0,
#endif
.sram_trans_align = 0,
.psram_trans_align = 64,
.hsync_gpio_num = 39, // GPIO 39
.vsync_gpio_num = 40, // GPIO 40
.de_gpio_num = 41, // GPIO 41
.pclk_gpio_num = 42, // GPIO 42
.disp_gpio_num = -1, // EN pin not connected
.data_gpio_nums = {
15, // D0 (B0) - GPIO 15
7, // D1 (B1) - GPIO 7
6, // D2 (B2) - GPIO 6
5, // D3 (B3) - GPIO 5
4, // D4 (B4) - GPIO 4
9, // D5 (G0) - GPIO 9
46, // D6 (G1) - GPIO 46
3, // D7 (G2) - GPIO 3
8, // D8 (G3) - GPIO 8
16, // D9 (G4) - GPIO 16
1, // D10 (G5) - GPIO 1
14, // D11 (R0) - GPIO 14
21, // D12 (R1) - GPIO 21
47, // D13 (R2) - GPIO 47
48, // D14 (R3) - GPIO 48
45, // D15 (R4) - GPIO 45
},
.flags = {
.disp_active_low = (uint32_t)NULL,
.refresh_on_demand = (uint32_t)NULL,
.fb_in_psram = true, // Do not change this, as it is mandatory for RGB parallel interface and octal PSRAM
.double_fb = (uint32_t)NULL,
.no_fb = (uint32_t)NULL,
.bb_invalidate_cache = (uint32_t)NULL,
}
},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
i80 Display drivers
- rm68120 driver
The
rm68120
driver is a display driver that is used to control the RM68120 display. The rm68120
driver configuration is part of display driver configuration.
disp_def.h:
#define DISP_HOR_RES_MAX (800)
#define DISP_VER_RES_MAX (480)
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * (DISP_VER_RES_MAX / 10))
#define DISP_USE_DOUBLE_BUFFER (true)
const esp_i80_rm68120_config_t rm68120_cfg = {
.bus_config =
{
.clk_src = LCD_CLK_SRC_DEFAULT,
.dc_gpio_num = 38, // DISP_RS_PIN=GPIO38
.wr_gpio_num = 17, // DISP_WR_PIN=GPIO17
.data_gpio_nums =
{
1, // DISP_D00_PIN = GPIO1
9, // DISP_D01_PIN = GPIO9
2, // DISP_D02_PIN = GPIO2
10, // DISP_D03_PIN = GPIO10
3, // DISP_D04_PIN = GPIO3
11, // DISP_D05_PIN = GPIO11
4, // DISP_D06_PIN = GPIO4
12, // DISP_D07_PIN = GPIO12
5, // DISP_D08_PIN = GPIO5
13, // DISP_D09_PIN = GPIO13
6, // DISP_D10_PIN = GPIO6
14, // DISP_D11_PIN = GPIO14
7, // DISP_D12_PIN = GPIO7
15, // DISP_D13_PIN = GPIO15
8, // DISP_D14_PIN = GPIO8
16, // DISP_D15_PIN = GPIO16
},
.bus_width = 16, // DISP_BITS_WIDTH
.max_transfer_bytes = DISP_BUF_SIZE * sizeof(uint16_t),
.psram_trans_align = 64,
.sram_trans_align = 4,
},
.io_config =
{
.cs_gpio_num = -1,
.pclk_hz =
(8 * 1000 *
1000), // could be 10 if no PSRAM memory= DISP_CLK_FREQ,
.trans_queue_depth = 10,
.dc_levels =
{
.dc_idle_level = 0,
.dc_cmd_level = 0,
.dc_dummy_level = 0,
.dc_data_level = 1,
},
.on_color_trans_done =
NULL, // Callback invoked when color data
// transfer has finished updated in bdsp.c
.user_ctx =
NULL, // User private data, passed directly to
// on_color_trans_done’s user_ctx updated in bdsp.c
.lcd_cmd_bits = 16, // DISP_CMD_BITS_WIDTH
.lcd_param_bits = 16, // DISP_PARAM_BITS_WIDTH
},
.panel_config =
{
.reset_gpio_num = 21, // DISP_RST_PIN = GPIO21
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.data_endian =
0, /*!< Set the data endian for color data larger than 1 byte */
.bits_per_pixel = 16, /*!< Color depth, in bpp */
.flags =
{
.reset_active_high = 0, /*!< Setting this if the panel reset
is high level active */
},
.vendor_config = NULL, /*!< Vendor specific configuration */
},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
- st7796 i80 driver
The
st7796
driver is a display driver that is used to control the ST7796 display. The st7796
driver configuration is part of display driver configuration.
disp_def.h:
#define DISP_HOR_RES_MAX (480)
#define DISP_VER_RES_MAX (320)
#define DISP_BUF_SIZE (DISP_HOR_RES_MAX * (DISP_VER_RES_MAX / 10))
const esp_i80_st7796_config_t st7796_cfg = {
.bus_config =
{
.clk_src = LCD_CLK_SRC_DEFAULT,
.dc_gpio_num = 0, // DISP_RS_PIN=0
.wr_gpio_num = 47, // DISP_WR_PIN=GPIO47
.data_gpio_nums =
{
9, // DISP_D00_PIN = GPIO9
46, // DISP_D01_PIN = GPIO46
3, // DISP_D02_PIN = GPIO3
8, // DISP_D03_PIN = GPIO8
18, // DISP_D04_PIN = GPIO18
17, // DISP_D05_PIN = GPIO17
16, // DISP_D06_PIN = GPIO16
15, // DISP_D07_PIN = GPIO15
-1, // DISP_D08_PIN = N/C
-1, // DISP_D09_PIN = N/C
-1, // DISP_D10_PIN = N/C
-1, // DISP_D11_PIN = N/C
-1, // DISP_D12_PIN = N/C
-1, // DISP_D13_PIN = N/C
-1, // DISP_D14_PIN = N/C
-1, // DISP_D15_PIN = N/C
},
.bus_width = 8, // DISP_BITS_WIDTH
.max_transfer_bytes = DISP_BUF_SIZE * sizeof(uint16_t),
.psram_trans_align = 64,
.sram_trans_align = 4,
},
.io_config =
{
.cs_gpio_num = 48, //DISP_CS_PIN
.pclk_hz =
(8 * 1000 *
1000), // could be 10 if no PSRAM memory= DISP_CLK_FREQ,
.trans_queue_depth = 10,
.dc_levels =
{
.dc_idle_level = 0,
.dc_cmd_level = 0,
.dc_dummy_level = 0,
.dc_data_level = 1,
},
.on_color_trans_done =
NULL, // Callback invoked when color data
// transfer has finished updated in bdsp.c
.user_ctx =
NULL, // User private data, passed directly to
// on_color_trans_done’s user_ctx updated in bdsp.c
.lcd_cmd_bits = 8, // DISP_CMD_BITS_WIDTH
.lcd_param_bits = 8, // DISP_PARAM_BITS_WIDTH
},
.panel_config =
{
.reset_gpio_num = 4, // DISP_RST_PIN = GPIO4 - Same as touch
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
.data_endian =
0, /*!< Set the data endian for color data larger than 1 byte */
.bits_per_pixel = 16, /*!< Color depth, in bpp */
.flags =
{
.reset_active_high = 0, /*!< Setting this if the panel reset
is high level active */
},
.vendor_config = NULL, /*!< Vendor specific configuration */
},
.orientation = orientation_landscape,
.hor_res = DISP_HOR_RES_MAX,
.ver_res = DISP_VER_RES_MAX,
};
### Backlight drivers
The `disp_backlight` driver is a display component that is used by the display drivers to control the backlight of the display. The `disp_backlight` driver configuration is part of display driver configuration.
in disp_def.h:
```cpp
// Default backlight level value in percentage
#define DISP_BCKL_DEFAULT_DUTY 100 //%
// Backlight configuration
const disp_backlight_config_t disp_bcklt_cfg = {
.pwm_control = false, // true: LEDC is used, false: GPIO is used
.output_invert = false, // true: LEDC output is inverted, false: LEDC output is not inverted
.gpio_num = 21, // GPIO number for backlight control
// Relevant only for PWM controlled backlight
// Ignored for switch (ON/OFF) backlight control
.timer_idx = 0, // LEDC timer index
.channel_idx = 0 // LEDC channel index
};
SPI Touch drivers
- xpt2046 driver
The
xpt2046
driver is a touch driver that is used to control the XPT2046 touch controller. The xpt2046
driver configuration is part of the touch driver configuration.
touch_def.h:
xpt2046_config_t xpt2046_cfg = {
.irq_pin = 36, // GPIO 36
.touch_threshold = 300, // Threshold for touch detection
.swap_xy = true,
.invert_x = false,
.invert_y = false,
.x_max = 480,
.y_max = 320,
.calibration_x_min = 140,
.calibration_y_min = 290,
.calibration_x_max = 3950,
.calibration_y_max = 3890,
};
I2C Touch drivers
- gt911 driver
The
gt911
driver is a touch driver that is used to control the GT911 touch controller. The gt911
driver configuration is part of the touch driver configuration file : touch_def.h.
touch_def.h:
// GT911 touch controller configuration
const gt911_config_t gt911_cfg = {
.i2c_clk_speed = 400*1000,
.i2c_addr = (uint8_t[]){0x5D, 0X14,0}, // Floating or mis-configured INT pin may cause GT911 to come up at address 0x14 instead of 0x5D, so check there as well.
.rst_pin = 38, // GPIO 38
#if WITH_GT911_INT
.int_pin = 18, // GPIO 18
#else
.int_pin = -1, // INT pin not connected (by default)
#endif
.swap_xy = false,
.invert_x = false,
.invert_y = false,
.x_max = 0,//auto detect
.y_max = 0,//auto detect
};
- ft5x06 driver
The
ft5x06
driver is a touch driver that is used to control the FT5x06 touch controller. The ft5x06
driver configuration is part of the touch driver configuration file : touch_def.h.
touch_def.h:
const ft5x06_config_t ft5x06_cfg = {
.i2c_clk_speed = 400*1000,
.i2c_addr =
(uint8_t[]){
0x38,
0},
.rst_pin = -1, // GPIO 38
#if WITH_FT5X06_INT
.int_pin = 18, // GPIO 18
#else
.int_pin = -1, // INT pin not connected (by default)
#endif
.swap_xy = true,
.invert_x = false,
.invert_y = false,
.x_max = 480,
.y_max = 800,
};
Camera
The esp3d_camera
driver is a camera driver that is used to control the camera. The esp3d_camera
driver configuration is part of the camera driver configuration file : camera_def.h.
camera_def.h:
// Camera configuration
const esp32_camera_config_t camera_config = {
.hw_config =
{
.pin_pwdn = -1, /*!< GPIO pin for camera power down line */
.pin_reset = -1, /*!< GPIO pin for camera reset line */
.pin_xclk = 8, /*!< GPIO pin for camera XCLK line */
.pin_sccb_sda = 47, /*!< GPIO pin for camera SDA line */
.pin_sccb_scl = 21, /*!< GPIO pin for camera SCL line */
.pin_d7 = 3, /*!< GPIO pin for camera D7 line */
.pin_d6 = 18, /*!< GPIO pin for camera D6 line */
.pin_d5 = 17, /*!< GPIO pin for camera D5 line */
.pin_d4 = 15, /*!< GPIO pin for camera D4 line */
.pin_d3 = 6, /*!< GPIO pin for camera D3 line */
.pin_d2 = 5, /*!< GPIO pin for camera D2 line */
.pin_d1 = 4, /*!< GPIO pin for camera D1 line */
.pin_d0 = 7, /*!< GPIO pin for camera D0 line */
.pin_vsync = 9, /*!< GPIO pin for camera VSYNC line */
.pin_href = 46, /*!< GPIO pin for camera HREF line */
.pin_pclk = 16, /*!< GPIO pin for camera PCLK line */
.xclk_freq_hz =
20 * 1000 *
1000, /*!< Frequency of XCLK signal, in Hz. EXPERIMENTAL: Set to
16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode */
.ledc_timer =
LEDC_TIMER_0, /*!< LEDC timer to be used for generating XCLK */
.ledc_channel = LEDC_CHANNEL_0, /*!< LEDC channel to be used for
generating XCLK */
.pixel_format =
PIXFORMAT_JPEG, /*!< Format of the pixel data: PIXFORMAT_ +
YUV422|GRAYSCALE|RGB565|JPEG */
.frame_size =
FRAMESIZE_VGA, /*!< Size of the output image: FRAMESIZE_ +
QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */
.jpeg_quality = 12, /*!< Quality of JPEG output. 0-63 lower means
higher quality */
.fb_count =
1, /*!< Number of frame buffers to be allocated. If more than
one, then each frame will be acquired (double speed) */
.fb_location = CAMERA_FB_IN_PSRAM, /*!< The location where the frame
buffer will be allocated */
.grab_mode =
CAMERA_GRAB_WHEN_EMPTY, /*!< When buffers should be filled */
#if CONFIG_CAMERA_CONVERTER_ENABLED
.conv_mode = 0, /*!< RGB<->YUV Conversion mode */
#endif
.sccb_i2c_port = 0, /*!< If pin_sccb_sda is -1, use the already
configured I2C bus by number */
},
.pin_pullup_1 = -1, /* if any need */
.pin_pullup_2 = -1, /* if any need */
.pin_led = -1,
.flip_horizontaly = false, // if horizontal flip is needed
.flip_vertically = false, // if vertical flip is needed
.brightness = 0, // default value is 0
.contrast = 0, // default value is 0
} ;
main directory
The main directory contains the main application code. The main application code is the code that is executed when the application is started. The main application code is responsible for initializing the application and starting the application tasks. The main application code is also responsible for handling the application events and updating the application state.
The main application code is typically organized into the following files:
-
core directory, which contains the main application code, all common functions and ESP3D commands.
the core directory contains the following files:
- commands directory that contains the ESP3D commands.
- includes directory that contains the includes files of the core files
- esp3d_client.cpp file that contains the internal messaging API
- esp3d_commands.cpp file that contains the handle the ESP3D commands and also the API for the commands
- esp3d_hal.cpp file that contains the hardware abstraction layer API for all supported hardware
- esp3d_json_settings.cpp file that contains the API for reading setting from the JSON file like preferences.json
- esp3d_string.h file that contains the helpers to manipulate strings and char arrays
- esp3d_tft.cpp file that contains the core initialization of the main program
- esp3d_values.cpp file that contains the API for storing and dispaching the values used on TFT
-
display directory, which contain the UI code for the TFT display.
the display directory contains the following files:
-
esp3d_tft.ui.cpp file that contains the UI code for the TFT display
-
esp3d_tft.ui.h file that contains the header code for the TFT display
-
components directory that contains the UI common components for the TFT display
-
screens directory that contains the common screens to be displayed on the TFT display
-
3dprinter directory that contains the UI code for the 3D printer TFT display
this directory contaain one directory for each targeted firmware:
- marlin directory that contains the UI code for the Marlin TFT display
- repetier directory that contains the UI code for the Repetier TFT display
- smoothieware directory that contains the UI code for the Smoothieware TFT display
each target directory contain the ui code, the style to be used , the resources for each resolution and the screens to be displayed :
- res_320_240 directory that contains the resources for the 320x240 resolution
Each resolution directory contains the following files:
- esp3d_style.h file that contains the specific style to be used on this resolution
- logo_320_240.h file that contains the logo to be displayed on the TFT display at this resolution
- res_480_272 directory that contains the resources for the 480x272 resolution
- res_480_320 directory that contains the resources for the 480x320 resolution
- res_800_480 directory that contains the resources for the 800x480 resolution
- screens directory that contains the specifics screens to be displayed on the TFT display
- esp3d_style.cpp/.h files that contains the common style to be used on the TFT display
- esp3d_tft_ui.cpp file that contains the main UI code for the TFT display
-
cnc directory that contains the UI code for the CNC TFT display
Same as above but for the CNC firmware
-
embedded directory, which contains the embedded resources for the ESP32.
the embedded directory contains the following files:
- favicon.ico.gz file that contains the favicon for the web interface
- index.html.gz file that contains the index page for the web interface
-
modules directory, which contains the modules code for the TFT display. each subdirectory contains the code for a specific module / feature.
the modules directory contains the following files:
- authentication directory that contains the code for the authentication feature
- camera directory that contains the code for the camera feature
- config_files directory that contains the code for the config files feature, which allow to apply settings using ini file
- filesystem directory that contains the code for the filesystem feature: SD and flash
- gcode_host directory that contains the code for the gcode streaming feature
- http directory that contains the code for the http server feature, the different handlers for the web interface are splited in different subdirectories / files according usage \
- authentication directory that contains the authentication handlers
- camera directory that contains the camera handler
- flash directory that contains the flash files management handler
- sd directory that contains the sd files managment handler
- ssdp directory that contains the ssdp service handler
- update directory that contains the firmware update handler
- webdav directory that contains the webdav protocol handler
- ws directory that contains the websocket handler (data only not webui)
- esp3d_commands.cpp file that handle the web commands handler
- esp3d_config.cpp file that handle the config handler (shortcut to [ESP420])
- esp3d_favicon.cpp file that handle the favicon handler
- esp3d_file_not_found.cpp file that handle the file not found handler (which also handle the download of the files)
- esp3d_root.cpp file that handle the root handler (including the maintenance mode)
- esp3d_websocket_webui.cpp file that handle the websocket handler for the webui
- mdns directory that contains the code for the mdns feature
- network directory that contains the code for the network feature
- notifications directory that contains the code for the notifications feature
- rendering directory that contains the code for the renderer feature (Display)
- serial directory that contains the code for the serial communications feature
- socket_server directory that contains the code for the socket server feature (Telnet)
- ssdp directory that contains the code for the ssdp protocol feature
- time directory that contains the code for the time feature (NTP)
- translation directory that contains the code for the translation feature
- update directory that contains the code for the update feature
- usb_serial directory that contains the code for the usb serial feature (OTG)
- webdav directory that contains the code for the webdav protocol feature
- websocket directory that contains the code for the websocket feature (webui and data)
-
target directory, which contains the target code specific actions. each subdirectory contains the code for a specific target.
the target directory contains the following files:
- 3dprinter directory that contains the code for the 3D printer target:
- marlin directory that contains the code for the Marlin target
- repetier directory that contains the code for the Repetier target
- smoothieware directory that contains the code for the Smoothieware target
-
cnc directory that contains the code for the CNC target:
- grbl directory that contains the code for the Grbl target
scripts directory
The scripts directory contains the scripts used to build the firmware. The scripts directory contains the following files / directories:
- fonts_builder directory that contains the scripts used to build the fonts for the TFT display
the scripts will build the c code for the fonts to be used on the TFT display, the gerenated files will be placed in the fonts directory
The generated sizes are “8”,“10”,“12”,“14”,“16”,“18”,“20”,“22”,“24”,“26”,“28”,“30”,“32”,“34”,“36”,“38”,“40”,“42”,“44”,“46”,“48” pixels.
- It use Montserrat-Medium.ttf as base font:
- Generic chars are from 0x20 to 0x7F and with 0xB0.
- French chars are 0xE0,0xE7,0xE8,0xE9,0xEA,0xF4
- I use also FreeSerifBold.ttf 0x2022 char
- for the symbols I use Font fa-solid-900 and fa-brands-400.ttf:
code |
SYMBOL |
font |
0xe568 |
HEAT_BED |
fa-solid-900.ttf |
0xf2c9 |
EXTRUDER |
fa-solid-900.ttf |
0xf0ca |
LIST |
fa-solid-900.ttf |
0xf715 |
SLASH |
fa-solid-900.ttf |
0xf012 |
STATION_MODE |
fa-solid-900.ttf |
0xf519 |
ACCESS_POINT |
fa-solid-900.ttf |
0xf00c |
OK |
fa-solid-900.ttf |
0xe596 |
PROBE_CHECK |
fa-solid-900.ttf |
0xf00d |
CLOSE |
fa-solid-900.ttf |
0xf011 |
POWER |
fa-solid-900.ttf |
0xf028 |
VOLUME_HIGH |
fa-solid-900.ttf |
0xf027 |
VOLUME_LOW |
fa-solid-900.ttf |
0xf6a9 |
VOLUME_OFF |
fa-solid-900.ttf |
0xf013 |
SETTINGS |
fa-solid-900.ttf |
0xf2d1 |
NO_HEAT_BED |
fa-solid-900.ttf |
0xe040 |
HEAT_EXTRUDER |
fa-solid-900.ttf |
0xf2ed |
TRASH |
fa-solid-900.ttf |
0xe3af |
HOME |
fa-solid-900.ttf |
0xf019 |
DOWNLOAD |
fa-solid-900.ttf |
0xf021 |
REFRESH |
fa-solid-900.ttf |
0xf304 |
EDIT |
fa-solid-900.ttf |
0xf048 |
PREVIOUS |
fa-solid-900.ttf |
0xf051 |
NEXT |
fa-solid-900.ttf |
0xf04b |
PLAY |
fa-solid-900.ttf |
0xf04c |
PAUSE |
fa-solid-900.ttf |
0xf0c7 |
SAVE |
fa-solid-900.ttf |
0xf0e0 |
MESSAGE |
fa-solid-900.ttf |
0xf0e7 |
LASER |
fa-solid-900.ttf |
0xf76f |
VACCUM |
fa-solid-900.ttf |
0xf1f6 |
DISABLE_ALERT |
fa-solid-900.ttf |
0xf023 |
LOCK |
fa-solid-900.ttf |
0xf2dc |
COOLANT |
fa-solid-900.ttf |
0xf04d |
STOP |
fa-solid-900.ttf |
0xf1eb |
WIFI |
fa-solid-900.ttf |
0xf071 |
WARNING |
fa-solid-900.ttf |
0xf07b |
FOLDER |
fa-solid-900.ttf |
0xf15b |
FILE |
fa-solid-900.ttf |
0xf11c |
KEYBOARD |
fa-solid-900.ttf |
0xf55a |
BACKSPACE |
fa-solid-900.ttf |
0xf7c2 |
SD_CARD |
fa-solid-900.ttf |
0xf0b2 |
JOG |
fa-solid-900.ttf |
0xf077 |
UP |
fa-solid-900.ttf |
0xf078 |
DOWN |
fa-solid-900.ttf |
0xf053 |
LEFT |
fa-solid-900.ttf |
0xf054 |
RIGHT |
fa-solid-900.ttf |
0xf120 |
COMMAND |
fa-solid-900.ttf |
0xf624 |
GAUGE |
fa-solid-900.ttf |
0xf1ab |
LANGUAGE |
fa-solid-900.ttf |
0xf863 |
FAN |
fa-solid-900.ttf |
0xf48b |
SPEED |
fa-solid-900.ttf |
0xf72b |
WIZARD |
fa-solid-900.ttf |
0xf185 |
LIGHT |
fa-solid-900.ttf |
0xf5c1 |
ENGINE |
fa-solid-900.ttf |
0xf5fd |
LAYERS |
fa-solid-900.ttf |
0xe4b8 |
LEVELING |
fa-solid-900.ttf |
0xf4db |
FILAMENT |
fa-solid-900.ttf |
0xe4bd |
CENTER |
fa-solid-900.ttf |
0xf002 |
SEARCH |
fa-solid-900.ttf |
0xf4d7 |
FILAMENT_SENSOR |
fa-solid-900.ttf |
0xf2cc |
MIST |
fa-solid-900.ttf |
0xf13e |
UNLOCK |
fa-solid-900.ttf |
0xf192 |
LASER_2 |
fa-solid-900.ttf |
0xe4c3 |
MILLING |
fa-solid-900.ttf |
0xf3e5 |
NEW_LINE |
fa-solid-900.ttf |
0xf293 |
BLUETOOTH |
fa-brands-400.ttf |
0xf287 |
USB |
fa-brands-400.ttf |
0xf0a1 |
MORE_INFO |
fa-solid-900.ttf |
0xf055 |
PLUS |
fa-solid-900.ttf |
0xf056 |
MINUS |
fa-solid-900.ttf |
0xf256 |
MANUAL |
fa-solid-900.ttf |
0xf544 |
AUTOMATIC |
fa-solid-900.ttf |
Web Handlers
/ (GET)
root is the default handler where all files will be served, if no file is defined, it looks for index.html or index.html.gz (compressed)
if you call specific file, it will look for the filename and filename.gz (compressed)
if no file is defined and there is not index.html(.gz) it will display embedded page
another way to show the embedded page is /?forcefallback=yes
/sd/ (GET)
it will serve any file from SD card if there is one, it is only a wrapper to read SD card, no upload
/files (GET/POST)
this handler handle all commands for FS, including upload on FS.
possible options/arguments are:
quiet=yes
can be used when you don’t want list files but just upload them
path=...
define the path to the file
action=...
define the action to execute which can be:
- delete
delete the file defined by filename=...
it will also use path=...
to do full path
- deletedir
delete the directory defined by filename=...
it will also use path=...
to do full path
- createdir
create the directory defined by filename=...
it will also use path=...
to do full path
createPath=yes
when doing upload and the path do not exists, it will create it, POST only
<filename>S=...
give the size of uploaded file with name, need to be set before file is set in upload, POST only
the output is a json file:
```json
{
"files":[ //the files list
{
"name":"index.html.gz", //the name of the file
"size":"83.46 KB", //the formated size of the file
"time":"2022-09-04 11:56:05" //the time when the file was modified last time, this one is optional and depend on (FILESYSTEM_TIMESTAMP_FEATURE)
},
{
"name":"subdir", //the name of the file / directory
"size":"-1", //the size is -1 because it is a directory
"time":"" //no time for directories optional as depend on (FILESYSTEM_TIMESTAMP_FEATURE)
}
],
"path":"/", //current path
"occupation":"52", //% of occupation
"status":"subdir created", //status
"total":"192.00 KB", //Formated total space of Filesystem
"used":"100.00 KB" //Formated used space of Filesystem
}
```
/sdfiles (GET/POST) )
this handler handle all commands for SD, including upload on SD (only shared and direct SD)
this handler handle all commands for FS, including upload on FS.
possible options/arguments are:
quiet=yes
can be used when you don’t want list files but just upload them
path=...
define the path to the file
action=...
define the action to execute which can be:
- list
Will refresh the stats of the files
- delete
delete the file defined by filename=...
it will also use path=...
to do full path
- deletedir
delete the directory defined by filename=...
it will also use path=...
to do full path
- createdir
create the directory defined by filename=...
it will also use path=...
to do full path
createPath=yes
when doing upload and the path do not exists, it will create it, POST only
<filename>S=...
give the size of uploaded file with name, need to be set before file is set in upload, POST only
the output is a json file:
```json
{
"files":[ //the files list
{
"name":"3Oc-pika2.gco",//the name of the file
"shortname":"3Oc-pika2.gco", //the 8.3 shortname if available, if not the name of the file
"size":"83.46 KB", //the formated size of the file
"time":"2022-09-04 11:56:05" //the time when the file was modified last time, this one is optional and depend on (SD_TIMESTAMP_FEATURE)
},
{
"name":"subdir", //the name of the file / directory
"size":"-1", //the size is -1 because it is a directory
"time":"" //no time for directories optional as depend on (SD_TIMESTAMP_FEATURE)
}
],
"path":"/", //current path
"occupation":"52", //% of occupation
"status":"subdir created", //status
"total":"192.00 KB", //Formated total space of Filesystem
"used":"100.00 KB" //Formated used space of Filesystem
}
```
/upload (POST)
this handler is for MKS boards using MKS communication protocol if enabled, it handle only upload on SD
/command (GET)
this handler is for all commands the parameter is cmd=...
if it is an [ESPXXX]
command the answer is the [ESPXXX]
response
if it is not an [ESPXXX]
command the answer is ESP3D says: command forwarded
and can be ignored
/login (GET/POST)
this handler is for authentication function if enabled
possible options/arguments are:
- DISCONNECT=YES
it will clear current session, remove authentication cookie, set status to disconnected
and response code to 401
- SUBMIT=YES
to login it will need also PASSWORD=...
and USER=...
, the answer will be 200 if success and 401 if failed
if user is already authenticated it can use NEWPASSWORD=...
instead of PASSWORD=...
to change his password, if successful answer will be returned with code 200, otherwise code will be 500 if change failed or if password format is invalid
Output:
- if authentified and no submission:
{"status":"Identified","authentication_lvl":"admin"}
and code 200
- if not authenticated and no submission:
{"status":"Wrong authentication!","authentication_lvl":"guest"}
and code 401
/config (GET)
this handler is a shortcut to [ESP420] command in text mode, to get output in json add json=yes
/updatefw (GET/POST)
this handler is for FW upload and update
Answer output is :
{"status":"..."}
if upload is successful the ESP will restart
/snap (GET)
this handler is on esp32cam with camera enabled to capture a Frame
it answer by sending a jpg image
/description.xml (GET)
this handler is for SSDP if enabled to present device informations
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.2.178:80/</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:upnp:rootdevice:1</deviceType>
<friendlyName>esp3d</friendlyName>
<presentationURL>/</presentationURL>
<serialNumber>52332</serialNumber>
<modelName>ESP Board</modelName>
<modelDescription/>
<modelNumber>ESP3D 3.0</modelNumber>
<modelURL>https://www.espressif.com/en/products/devkits</modelURL>
<manufacturer>Espressif Systems</manufacturer>
<manufacturerURL>https://www.espressif.com</manufacturerURL>
<UDN>uuid:38323636-4558-4dda-9188-cda0e600cc6c</UDN>
<serviceList/>
<iconList/>
</device>
</root>
Captive portal bypass handlers
to avoid a redirect to index.html and so a refresh of the page, some classic handler have been added so they all go to / handler actually
- /generate_204
- /gconnectivitycheck.gstatic.com
- /fwlink/
Web Sockets
there are 2
Terminal websocket
use subprotocol webui-v3
and port is same as web port but use address /ws
text mode
Reserved
messages between webui / ESP
Format: <label>:<message>
-
from ESP to WebUI
-
currentID:<id>
Sent when client is connecting, it is the last ID used and become the active ID
-
activeID:<id>
Broadcast current active ID, when new client is connecting, client without this is should close, ESP WS Server close all open WS connections but this one also
-
PING:<time left>:<time out>
It is a response to PING from client to inform the time left if no activity (see below)
-
ERROR:<code>:<message>
If an error raise when doing upload, it informs client it must stop uploading because sometimes the http answer is not possible,
or cannot cancel the upload, this is a workaround as there is no API in current webserver to cancel active upload
-
NOTIFICATION:<message>
Forward the message sent by [ESP600] to webUI toast system
-
SENSOR: <value>[<unit>] <value2>[<unit2>] ...
The sensor connected to ESP like DHT22
-
from WebUI to ESP
PING:<current cookiesessionID / none >
if any, or “none” if none
binary mode
Reserved
Data websocket
use sub protocol arduino
and port same as web port but use address /wsdata
text mode
This mode is used to transfert all GCODE commands and their answers from printer/cnc
binary mode
This mode is used to transfert files to / from esp board
it use frame of 1024 bytes, can be increased after test
the frame format is :
2 bytes: for frame type
2 bytes: for frame size to check some integrity, currently as already part of frame no checksume is used
x bytes : extra data according frame type
Frame types
Query status frame
type: client -> esp
Status Request
with hexadecimal values:
Response frame use inverted header:
Response Status
with hexadecimal values:
the first byte of answer is the state
Code |
Hexa |
Meaning |
B |
0x42 |
busy |
O |
0x4F |
idle/ok |
E |
0x45 |
error |
A |
0x41 |
abort |
D |
0x44 |
download ongoing |
U |
0x55 |
upload ongoing |
extra data may be added :
For Error:
error code and string,
1 byte : error code: 0->255
1 byte : string size 0->255
XX bytes for the string
For Upload:
Upload informations:
1 byte : path size 0->255
XX bytes : the path string
1 byte : the filename size 0->255
xx bytes : filename string
4 bytes : total file size
4 bytes : currently processed bytes
4 bytes : last packet id processed
R |
S |
x |
x |
U |
X |
.. |
.. |
X |
.. |
.. |
S1 |
S1 |
S1 |
S1 |
S2 |
S2 |
S2 |
S2 |
For Download:
Download informations:
1 byte : path size 0->255
XX bytes : the path string
1 byte : the filename size 0->255
xx bytes : filename string
4 bytes : total file size
4 bytes : currently processed bytes
4 bytes : last packet id processed
R |
S |
x |
x |
D |
X |
.. |
.. |
X |
.. |
.. |
S1 |
S1 |
S1 |
S1 |
S2 |
S2 |
S2 |
S2 |
Start upload frame
header is :
the content is:
1 byte : path size 0->255
XX bytes : the path string
1 byte : the filename size 0->255
xx bytes : filename string
4 bytes : total file size
S |
U |
x |
x |
D |
X |
.. |
.. |
X |
.. |
.. |
S1 |
S1 |
S1 |
S1 |
if answer is :
it means transfert can start
Transfert upload frame
header is :
U |
P |
x |
x |
ID |
ID |
ID |
ID |
.. |
.. |
4 bytes is packet id
XXXX bytes is data
if packet is received the answer is
Start dowload frame
header is :
the content is:
1 byte : path size 0->255
XX bytes : the path string
1 byte : the filename size 0->255
xx bytes : filename string
4 bytes : total file size
S |
D |
x |
x |
D |
X |
.. |
.. |
X |
.. |
.. |
S1 |
S1 |
S1 |
S1 |
if answer is :
it means transfert can start
Transfert download frame
header is :
D |
P |
x |
x |
ID |
ID |
ID |
ID |
.. |
.. |
4 bytes is packet id
XXXX bytes is data
if packet is received the answer is
Command frame
header is :
Commands:
Code |
Hexa |
Meaning |
A |
0x41 |
abort |
Abort command frame
Syntax conventions
Info
This document is a receipe of conventions that may not be currently implemented yet, but will be from now, current code will be updated according to it before beta state.
Style should be also applied also
C++
Style
- Use Clang-format
- Download the tool according your system
https://releases.llvm.org/
- Install client extension
CLang-Format from Xaver Hellauer
- Define the style
set Google
as default style
General
- Avoid abreviation as much as possible
- Avoid unnecessary long name
- ESP3D is always uppercase in code, esp3d is valid only for filename, any mixing case is proscribed (e.g.:
Esp3D
/esp3D
/Esp3d
)
- ESP command is always uppercase, so any reference to it (e.g.:
ESP100
) should be uppercase to avoid confusion, only filename can be lowercase, any mixing case is proscribed
File name
- Use lower case for file names
- Use underscores as words separators
e.g: esp3d_settings.cpp
Directory name
- Use lower case for directory names
- Use underscores as words separators
e.g: esp3d_commansds
- Target directories are the only names that use full uppercase unlike others directories
e.g: ESP32S3_ZX3D50CE02S_USRC_4832
Variable
- Any name should begin with an alphabet.
- The first character should be lowercase.
- Use upper case letters as words separators
- Digits may be used in the name but only after the alphabet.
- No special symbols can be used in names.
- No keywords can be used as names.
- Pointer variables should be prepended with ‘p’ and place the asterisk ‘*’ close to the name instead of the pointer type.
- Static variables should be prepended with ‘s’.
- always initialize the variable
e.g:
char adminPassword[20]{0};
char *pAdminLogin = nullptr;
Constant
- Any name should begin with an alphabet.
- The first character should be
k
.
- Use upper case letters as words separators
- Digits may be used in the name but only after the alphabet.
- No special symbols can be used in names.
- No keywords can be used as names.
e.g: const int kTopLimit 100;
Define
Define use uppercase letters only and underscores as words separators, dash is not allowed.
e.g: #define LOWER_LIMIT 10;
Enum
- Enum should use
enum class
not plain enum
neither enum struct
- If enum is used by several file, enum should be defined in separate file to avoid repeated definitions, and add
_type
suffix to file name
- The first character in the enum name must be in upper case.
- Use upper case letters as word separators.
- No underscores (‘_’) are permitted in the enum name.
- Enum values are lower case and use underscores as words separators.
- No need to
typedef
enum
- Use type as much as possible to clarify any casting if necessary
- Define enum values as much as possible to ensure consistency when doing update
- Do not use
#ifdef
in enum unless all enum values are explicitly defined
e.g: esp3d_gcode_host_type.h
enum class Esp3dGcodeHostWait : uint8_t {
no_wait = 0,
wait_ack,
wait_busy,
wait_processing,
wait_heating
};
Usage example: Esp3dGcodeHostWait::no_wait
enum class Status: char
{
high = 'h',
low = 'l'
};
Usage example: Status::low
Struct/Union
- If struct/union is used by several file, struct should be defined in separate file to avoid repeated definitions, and add
_type
suffix to file name
- The first character in the struct name must be in upper case.
- Use upper case letters as word separators
- Struct values are lower case and use underscores as words separators if variables.
- No need to
typedef
for struct
- As we use C++20, initialize struct explicitly
e.g: setting_description_type.h
struct SettingDescription{
uint16_t size = 0;
const char* defaultVal = nullptr;
} ;
usage example: SettingDescription notificationSetting;
Class
- The class name should be a noun.
- Use upper case letters as word separators, and lower case for the rest of the word in the class name.
- The first character in the class name must be in upper case.
- No underscores (‘_’) are permitted in the class name.
- The private and protected attribute name in class should be prepended with the character underscore (‘_’).
- Each method/ function name should begin with a verb.
- The first character of function/ method argument names should be lowercase.
- Use upper case letter as word separator
- Any name should begin with an alphabet.
- Digits may be used in the name but only after the alphabet.
- No special symbols can be used in names except for the underscore(‘_’).
- No keywords can be used as names.
- Pointer variables should be prepended with ‘p’ and place the asterisk ‘*’ close to the name instead of the pointer type.
- Static variables should be prepended with ‘s’.
- Getter should use same name as attribute name.
- Setter should use same name as attribute name with
set
prefix and upper case the first letter of name.
e.g:
class Esp3dAuthenticationService {
public:
bool begin();
bool isAdmin (const char *pwd);
char * getPassword ();
private:
std::string _adminPwd;
char *_pName;
static char _sLogin;
}
Function/Procedure
- Each Function/Procedure name should begin with a verb.
- The first character of argument names should be lowercase.
- Use upper case letter as word separator
- Any name should begin with an alphabet.
- Digits may be used in the name but only after the alphabet.
- No special symbols can be used in names except for the underscore(‘_’).
- No keywords can be used as names.
Namespace
- Namespace names are all lower-case, with words separated by underscores.
- Do not use
using
but full namespace instead for clarity
e.g:
namespace esp3d_hal{
int64_t millis();
}
usage example: esp3d_hal::millis();
typedef
- If variable
- Use lower case for names
- Use underscores as words separators
- Add suffix
_t
e.g: typedef int setting_index_t
- If function
- Follow function naming syntax
- Add suffix
_t
e.g: typedef std::function<bool(const char*, const char*,const char*)> processingFunction_t;
0 and nullptr/NULL
Use nullptr for pointers, and ‘\0’ for chars (and not the 0 literal).
For pointers (address values), use nullptr, as this provides type-safety.
Use ‘\0’ for the null character. Using the correct type makes the code more readable.
sizeof
Prefer sizeof(varname) to sizeof(type). sizeof(varname) will update appropriately if someone changes the variable type either now or later.
auto
type
Only use auto type if no need to to do type deduction, C++ code is usually clearer when types are explicit, especially when type deduction would depend on information from distant parts of the code.
Casting
- Use C++-style casts
e.g: static_cast<float>(double_value)
- Do not use C cast unless the cast is to void
e.g: (int)3.5;
Initialization
- Do not mix brace initialization and
=
for readibility
Lambda Expressions
//TODO
Inspired from :
GCode streaming API
Clients
The Gcode Stream Client is the actual streaming service, it is the only one that send msg to output client. On another way the GcodeStreamClient is only one of the active clients which will get the msg from the output client.
The GcodeStreamClient use the GCodeParser to parse in/out commands and handle messages correctly.
Components
1 - Streaming Types
There are several types of streaming services:
A - Unknown
The type is not yet defined, this type cannot be streamed until it is identified.
B - Single Command
This is for any normal GCODE or ESPXXX command coming from any client, this type cannot be interrupted once started, ESP700 / ESP701 do not support it. This type will be added to the script queue and processed FIFO.
C - Multiple Commands
This is used by scripts stored in EEPROM (resume/pause/abort), this type cannot be interrupted, and all commands will be executed one after another until the end, ESP700 / ESP701 do not support it. This type will be added to the script queue and processed FIFO
D - Flash File Stream
This is the one that will be used to stream a file from flash, this type can be interrupted only between each command execution.
This type will put in hold if any command is present in scripts queue and resumed when the scripts queue is empty.
This type is used with the command [ESP700]stream=/fs/mystream.gco
the file name must have the /fs/ prefix to be sure that the file is handled properly, the [ESP701] commands can handle it but only between commands commands execution, that the purpose of the stream= tag. This type will be added to the stream queue and processed FIFO.
E - Flash File script
This is the one that will be used to stream a file from flash, unlike previous type this type cannot be interrupted and will be excuted until the end. This one is used with the command [ESP700]/fs/myfile.gco
The file name must have the /fs/ prefix to be sure that the file is handled properly. The [ESP701] command do not handle it. The file should only contain few commands and it is used by macros only
This type will be added to the script queue and processed FIFO
F - SD File Stream
This is the one that will be used to stream a file from sd card, this type can be interrupted only between each command execution.
This type will put in hold if any command is present in scripts queue and resumed when the scripts queue is empty.
This type is used with the command [ESP700]stream=/sd/mystream.gco
the file name must have the /sd/ prefix to be sure that the file is handled properly, the [ESP701] commands can handle it but only between commands commands execution, that the purpose of the stream= tag. This type will be added to the stream queue and processed FIFO.
G - SD File script
This is the one that will be used to stream a file from sd card, unlike previous type this type cannot be interrupted and will be excuted until the end. This one is used with the command [ESP700]/sd/myfile.gco
The file name must have the /sd/ prefix to be sure that the file is handled properly. The [ESP701] command do not handle it. The file should only contain few commands and it is used by macros only
This type will be added to the script queue and processed FIFO
E- Invalid
The type is not yet identified, this type cannot be streamed and will raise an error.
2 - Streaming Queues
There are 3 types of queues for streams
A - Stream queue
This queue contain sd streams and fs streams, this queue has lower processing priority than script queue, which mean when the stream reach some state it can be interrupted, put in hold, and resumed.
The active stream of this queue can be monitored and controlled with the command [ESP701]
B - Script queue
This queue contains single commands, multiple commands, sd scripts and fs scripts. The queue has higher priority than script queue and will be processed before the stream queue. There is not control of this queue from user point of view.
C - Emmergency Queue => TBC
This queue contain single commands that will be executed as soon as possible.
3 - Streaming queue states
The stream states only applied streams queue and only to the active stream, not to scripts queue.
A - idle
The streams queue is empty, but the scripts queue may not be empty
B - processing
It means at least one stream in streams queue is being processed, even in hold due to scripts queue not being empty.
C - paused
The current stream in stream queue is paused.
D - error
Currently not implemented because when a stream go to error it is removed from stream queue to process the next one in stream queue if any.
3 - Stream command states
The stream command states cover all states of a processed command.
A - Undefined
The state is undefined and the command will go to error state.
B - Start
This is the state to start a command or resume it. Next state is normally Ready to read cursor.
C - Ready to read cursor
This is the state before really processing command, this is the state used to put a stream in hold to allow scripts queue or to respond to external change of state for stream like pause/abort. If not change state requested then the next state will be read cursor state
D - Read Cursor
This state read coming processing command from file/multiple commands line or single command.
According to the command the next state will be send gcode command state or send esp command state.
E - Send gcode command
Send gcode command to the output client, the command may have been completed with line number and checksum if is requested.
Depending of the command the next state will be wait for ack if an ack is requested or ready to read next command if no ack is requested.
F - Send esp command
The command has been identified as ESP command, so it will be handled internaly and response will be sent to the original client
The next state will be ready to read next command.
G - Wait for ack
If the command has been identified as GCode command and this command will send an ack, this state it to wait for it, if no ack received before a specific timout the next state will be the error state, if the ack is received before timeout then the next state will be ready to read next command.
H - Resend gcode command
In case of GCode command that is completed with line number and checksum and if there a checksum error received, this state will be resend the current gcode command again, ater a specific amount of failure the command will go to the error state.
I - Pause
This state will make the current stream queue on hold and process add a specific script to scripts queue if defined in settings, the next state will be paused.
J - Paused
This state will be waiting for resume or abort request to complete the stream.
K - Resume
If the current stream is paused it will resume it by adding a specific script to scripts queue if .defined in settings, and changing the next state as ready to read next command
L - Abort
This state will abort the current stream by adding a specific script to scripts queue if .defined in settings and changing the next state as end for the next command.
M - End
This state will close the current stream and remove it from the corresponding queue.
N - Error
If there is an error during the stream processing the error state will be raised, this state will notify the user about the error and the next state will be end state to remove failing stream.
Operations
the streaming is a loop of different operations
1 - Check external notifications / requests
This will check if there is an external request for change stream status e.g: pause or resume or abort
2 - Check what is the current active stream
This will check if there is a need of switching between queues and so switch between active streams, emmergency commands queue > scripts queue > streams queue
3 - Check what is the current active stream state
This will check if there is a need of changing the current state of the current active stream and applied it
4 - Check the client rx queue and process it
This will check if there is response / command in the rx queue, parse the response if necessary to search for a command ack, add any external command to the stream queue coming, etc…
WebDAV API
The WebDAV server serve flash and sd at once.
Introduction
The protocol is based on HTTP and is designed to allow clients to perform remote Web content authoring operations.
WebDav protocol provides facilities to copy, move, delete resources, to query and set properties on resources.
This protocol has several features but many are useless for the purpose of this project, so the protocol will be followed but using only the features that are needed.
The authentication is not implemented yet.
If no namespace is supposed ok for xml tags because there is no possible conflict in webdav requests/responses, Windows seems request them so they have been added.
As it is embedded system on local network, the header Date
is not supported, indeed it make no sense to give 1970 based year date, if system date is not initialized.
WebDav version
The version of WebDav that will be used is 1 because we do not need PROPATCH, LOCK and UNLOCK methods.
The DAV header will be set to 1.
The allow header will be set to GET, HEAD, PUT, DELETE, OPTIONS, PROPFIND, MKCOL, COPY, MOVE.
Date format for WebDav like last modified and creation date is the GMT time format with name of day and month in english: Thu, 01 Jan 1970 00:04:34 GMT
, because even if the rfc says if can be in this format :1997-12-01T17:42:21-08:00
, it seems not usable on Filezilla Pro neither Windows, so english date is a must.
GET method
The GET method is used to retrieve information about the resource identified by the Request-URI. And the content of the resource is returned as the response body.
The necessary headers in response are:
- DAV
- Allow
- Last-Modified
- Content-Length (if the resource is a file)
- Content-Type (if the resource is a file)
The content of the reponse is:
- the file if the resource is a file
- empty if the resource is a directory
The response code is:
- 200 if the resource is a file or a directory and the request was successful
- 404 if the resource does not exist
- 500 if any error during the file streaming
- 503 if any error accessing the local file system (e.g. access denied)
HEAD method
The HEAD method is used to retrieve information about the resource identified by the Request-URI.
The necessary headers in response are:
- DAV
- Allow
- Last-Modified
- Content-Length (if the resource is a file)
- Content-Type (if the resource is a file)
Unlike GET method, the HEAD method does not return the content of the resource.
The response code is:
- 200 if the resource is a file or a directory and the request was successful
- 404 if the resource does not exist
- 500 if any error during the file streaming
- 503 if any error accessing the local file system (e.g. access denied)
OPTIONS method
The OPTIONS method is used to retrieve the communication options for WebDav.
The necessary headers in response are:
- DAV
- Allow
No content
The response code is always 200.
DELETE method
The DELETE method is used to delete the resource identified by the Request-URI.
The necessary headers in response are:
- DAV
- Allow
No content
The response code is:
- 204 if success
- 404 if the resource does not exist
- 503 if any error accessing the local file system (e.g. access denied)
- 500 if any error during the file/dir deletion
- 400 if the resource is / or /sd or /fs
MKCOL method
The MKCOL method is used to create a new collection resource at the location specified by the Request-URI.
The request has the following headers:
- Destination is the path of the resource to create. to be used instead of the Request-URI if present.
The necessary headers in response are:
- DAV
- Allow
No content
The response code is:
- 201 if success
- 409 if the resource already exists
- 503 if any error accessing the local file system (e.g. access denied)
- 500 if any error during the dir creation
- 400 if the resource is / or /sd or /fs
PUT method
The PUT method is used to create a new non-collection resource at the location specified by the Request-URI.
The request has the following headers:
- Content-Length is the size of the file.
- Content-Type is the type of the file.
no Overwrite header because we always overwrite the file.
the request content is the content of the resource to create.
The necessary headers in response are:
- DAV
- Allow
- Last-Modified
No content
The response code is:
- 201 if success and file is created
- 204 if success and file is overwritten
- 412 if the resource is a directory
- 503 if any error accessing the local file system (e.g. access denied)
- 500 if any error during the file creation
- 507 if the file is too big for the targeted file system
PROPFIND method
The PROPFIND method retrieves properties defined on the resource identified by the Request-URI, if the Request-URI is a collection it returns the properties of the collection and the properties of the members of the collection.
The request has the following headers:
- Depth can be 0 or 1 or infinity but we do not support infinity so instead we use 1 and that will be returned as the depth in the PROPFIND response
- Content-Type is the type of the request body. It can be text/xml or application/xml or application/x-www-form-urlencoded or multipart/form-data but we only support text/xml.
this content can be ignored because we will always return the same content type.
- Content-Length is the size of the request body.
The request body can be ignored because we will always return the same content
The necessary headers in response are:
- DAV
- Allow
- Content-Type is text/xml
- Connection: close
- Content-Length is the size of the response body but because it is not possible to know the size of the response body before generating it because we do not know the number of resources in the directory, we will use chunked transfer encoding. so this header will not be present in the response.
- depth=1 will only be added in case of a request of depth=infinity
The response body is an xml document containing the properties of the resource.
<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response xmlns:esp3d="DAV:">
<D:href>/webdav</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<esp3d:getlastmodified>Wed, 25 Oct 2023 04:44:55 GMT</esp3d:getlastmodified>
<esp3d:creationdate>Wed, 25 Oct 2023 04:44:55 GMT</esp3d:creationdate>
<D:resourcetype>
<D:collection/>
</D:resourcetype>
<esp3d:displayname>/</esp3d:displayname>
</D:prop>
</D:propstat>
</D:response>
<D:response xmlns:esp3d="DAV:">
<D:href>/webdav/fs</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<esp3d:getlastmodified>Wed, 31 Dec 1969 23:59:59 GMT</esp3d:getlastmodified>
<esp3d:creationdate>Thu, 01 Jan 1970 00:00:00 GMT</esp3d:creationdate>
<D:resourcetype>
<D:collection/>
</D:resourcetype>
<esp3d:displayname>fs</esp3d:displayname>
</D:prop>
</D:propstat>
</D:response>
<D:response xmlns:esp3d="DAV:">
<D:href>/webdav/sd</D:href>
<D:propstat>
<D:status>HTTP/1.1 200 OK</D:status>
<D:prop>
<esp3d:getlastmodified>Thu, 01 Jan 1970 00:00:00 GMT</esp3d:getlastmodified>
<esp3d:creationdate>Thu, 01 Jan 1970 00:00:00 GMT</esp3d:creationdate>
<D:resourcetype>
<D:collection/>
</D:resourcetype>
<esp3d:displayname>sd</esp3d:displayname>
</D:prop>
</D:propstat>
</D:response>
</D:multistatus>
The response code is:
- 207 if success
- 404 if the resource does not exist
- 503 if any error accessing the local file system (e.g. access denied)
COPY method
The COPY method is used to copy the resource identified by the Request-URI to the destination URI.
The copy is allowed only for a file and not for a directory.
Only move /fs to /fs and /sd to /sd
The request has the following headers:
- Destination is the path of the resource to create. to be used instead of the Request-URI if present.
- Overwrite is a boolean that indicates if the destination resource should be overwritten if it already exists. If the header is not present, the default value is false.
- Depth can be 0 or 1 or infinity but we do not support collection copy so this header is ignored
The necessary headers in response are:
No content
The response code is:
- 201 if success and file is created
- 204 if success and file is overwritten
- 404 if the resource does not exist
- 413 if the resource is a directory
- 412 if the destination resource already exists and overwrite is false
- 409 if overwrite is true and the destination and source are different types (file or directory)
- 503 if any error accessing the local file system (e.g. access denied)
- 500 if any error during the file creation
- 507 if the file is too big for the targeted file system
- 400 if source or destination is / or /sd or /fs, or try to /sd to /fs or /fs to /sd
MOVE method
The MOVE method is used to move the resource identified by the Request-URI to the destination URI.
There is no merge of the destination resource and the source resource but the destination resource is overwritten/replaced if it already exists.
Only move /fs to /fs and /sd to /sd
The request has the following headers:
- Destination is the path of the resource to create. to be used instead of the Request-URI if present.
- Overwrite is a boolean that indicates if the destination resource should be overwritten if it already exists. If the header is not present, the default value is false.
The necessary headers in response are:
No content
The response code is:
- 201 if success and file is created
- 204 if success and file is overwritten
- 404 if the resource does not exist
- 412 if the destination resource already exists and overwrite is false
- 409 if overwrite is true and the destination and source are different types (file or directory)
- 503 if any error accessing the local file system (e.g. access denied)
- 500 if any error during the file creation
- 400 if source or destination is / or /sd or /fs, or try to move /sd to /fs or /fs to /sd