mirror of
https://github.com/suchmememanyskill/CYD-Klipper.git
synced 2026-03-21 13:43:25 +00:00
Compare commits
304 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c564e8ab8 | ||
|
|
5c0ee08135 | ||
|
|
e6b5d17f6a | ||
|
|
d8a9b13fe1 | ||
|
|
fbc2964ad8 | ||
|
|
d616ef5a6d | ||
|
|
9bfbb1cb0e | ||
|
|
8d8e36fde9 | ||
|
|
4e3cd69b63 | ||
|
|
3aeb67cfdd | ||
|
|
8f46b9972d | ||
|
|
0992f466cf | ||
|
|
f8ed3afd06 | ||
|
|
fdfa2d014f | ||
|
|
1efaa616e1 | ||
|
|
5756b31744 | ||
|
|
99b70622fe | ||
|
|
b3d405b355 | ||
|
|
1cd6c8fd92 | ||
|
|
7b0497c75b | ||
|
|
df610168c0 | ||
|
|
d0f90a56d0 | ||
|
|
b67f091c46 | ||
|
|
71119e1648 | ||
|
|
660723d596 | ||
|
|
5ec2ba66e4 | ||
|
|
4fc16ecc92 | ||
|
|
161c10a43b | ||
|
|
093dd5efff | ||
|
|
4dd70aa3ea | ||
|
|
f4498e95cd | ||
|
|
b342e58cfc | ||
|
|
211fe15aee | ||
|
|
abbb0b2f7e | ||
|
|
6aa74633a8 | ||
|
|
2f1b0095b0 | ||
|
|
68b68af715 | ||
|
|
96f8695b0e | ||
|
|
2fce5a9e30 | ||
|
|
1578b4129d | ||
|
|
fcd133eb32 | ||
|
|
15dedb7255 | ||
|
|
0c364ec597 | ||
|
|
8521664a69 | ||
|
|
1b0ca807e4 | ||
|
|
12781051ca | ||
|
|
e5390e731f | ||
|
|
17143d2878 | ||
|
|
bf90803107 | ||
|
|
f9444829ee | ||
|
|
92b7b68dc5 | ||
|
|
747ff4c79c | ||
|
|
d4ce7a71ba | ||
|
|
0e57aed87c | ||
|
|
66e3a6765c | ||
|
|
f21b480611 | ||
|
|
49a1bd6e57 | ||
|
|
1483345e67 | ||
|
|
205926364c | ||
|
|
9a915bedda | ||
|
|
650b055fcd | ||
|
|
4207d82a7e | ||
|
|
b1138d9510 | ||
|
|
572d27dc8a | ||
|
|
ccc5817799 | ||
|
|
b99e00d79c | ||
|
|
d6e788f0c8 | ||
|
|
5bb4fd2b3c | ||
|
|
69d98a9e19 | ||
|
|
1516b785f5 | ||
|
|
fcdce6c5bf | ||
|
|
c0e329c57d | ||
|
|
6273e10e5a | ||
|
|
75bb334b09 | ||
|
|
be0bf0fc71 | ||
|
|
c35b146762 | ||
|
|
e55c2871d9 | ||
|
|
309a6865a5 | ||
|
|
ec7e6f180d | ||
|
|
337a26be3d | ||
|
|
6a9023eb8d | ||
|
|
2078a1541d | ||
|
|
eed4b3efef | ||
|
|
22fc25ccc7 | ||
|
|
9a6fce854c | ||
|
|
9a96f9336f | ||
|
|
0b1db1d834 | ||
|
|
db019939a6 | ||
|
|
5c46764c7c | ||
|
|
6ebaf68cf1 | ||
|
|
41aa073ae0 | ||
|
|
19cfaefd36 | ||
|
|
04d890227e | ||
|
|
e2c2a38b20 | ||
|
|
5d2571ef83 | ||
|
|
d4645f4fa1 | ||
|
|
4ac87c8ffc | ||
|
|
d780c8d55e | ||
|
|
d69446a11b | ||
|
|
90fd1b0ab2 | ||
|
|
4a96f7db0b | ||
|
|
c640d7fade | ||
|
|
d22a9e1ee4 | ||
|
|
98c7364ce7 | ||
|
|
7815a0fbf4 | ||
|
|
bd32fcb81e | ||
|
|
bc0502745d | ||
|
|
d75cbb65dc | ||
|
|
e004456ee9 | ||
|
|
ae34e91530 | ||
|
|
cbd40414c8 | ||
|
|
06691df094 | ||
|
|
9b551915d7 | ||
|
|
73be7c6c9f | ||
|
|
e06ea214c4 | ||
|
|
9e739de731 | ||
|
|
29dcb4717a | ||
|
|
356c78ee5f | ||
|
|
dce6f70ef9 | ||
|
|
2e3ac7b02c | ||
|
|
2e5a2dfbeb | ||
|
|
4a4fdb77d6 | ||
|
|
db448ae401 | ||
|
|
9a9134da4a | ||
|
|
86a999253f | ||
|
|
1238b7ee37 | ||
|
|
f110feee1e | ||
|
|
41d0b77d17 | ||
|
|
364f1ee49c | ||
|
|
ad68095124 | ||
|
|
38a1acb7b1 | ||
|
|
f5f970afce | ||
|
|
e4dd146a96 | ||
|
|
ea8a6b561f | ||
|
|
a9a732daa6 | ||
|
|
713e04bfa5 | ||
|
|
0f472ae78b | ||
|
|
400e2ae266 | ||
|
|
315e066e27 | ||
|
|
c7c6b26730 | ||
|
|
6cde9cb887 | ||
|
|
44e57995fb | ||
|
|
56301d3d72 | ||
|
|
ae3348d61e | ||
|
|
4bfe149244 | ||
|
|
7aceb85621 | ||
|
|
9c958b42b3 | ||
|
|
92d47d8c07 | ||
|
|
1a31ef0758 | ||
|
|
a7bde99442 | ||
|
|
be3b2ddb24 | ||
|
|
36b37176d6 | ||
|
|
d0d80e8980 | ||
|
|
65abe295c9 | ||
|
|
a8c94fe207 | ||
|
|
a265301d97 | ||
|
|
90dcf95cf6 | ||
|
|
8d6d22c38a | ||
|
|
fb1e264df7 | ||
|
|
e457114402 | ||
|
|
61f15ff6f3 | ||
|
|
451304b5df | ||
|
|
68ff78eb49 | ||
|
|
215439df2f | ||
|
|
397c835129 | ||
|
|
870d109c92 | ||
|
|
f98c2eff78 | ||
|
|
67b5ce1948 | ||
|
|
e9b58e0a6f | ||
|
|
3b7b49c62b | ||
|
|
f0cc211e30 | ||
|
|
9427381e05 | ||
|
|
02e27e6d83 | ||
|
|
b65003e40b | ||
|
|
cb242240d3 | ||
|
|
c061164edf | ||
|
|
ea42bf775d | ||
|
|
4e6457c729 | ||
|
|
bc3ca3892f | ||
|
|
639eb50371 | ||
|
|
1adb966ee1 | ||
|
|
64290afd89 | ||
|
|
3fbd14f154 | ||
|
|
ef3676faef | ||
|
|
fc7cfbd85b | ||
|
|
49c27f2b01 | ||
|
|
801432c3a6 | ||
|
|
55e9ce3d81 | ||
|
|
f467e8a604 | ||
|
|
45779b5a13 | ||
|
|
1c7d5ffacd | ||
|
|
1bc770a1cf | ||
|
|
b5ac6d045a | ||
|
|
c9f8935310 | ||
|
|
ff1c13602c | ||
|
|
5d3d32b116 | ||
|
|
edec1724e6 | ||
|
|
dd5e82d637 | ||
|
|
e5edabffa4 | ||
|
|
a1bb6a750f | ||
|
|
43cefaafd2 | ||
|
|
dcf32d6685 | ||
|
|
12c4319173 | ||
|
|
86be30034d | ||
|
|
4fc2316970 | ||
|
|
3dc241dbec | ||
|
|
cd58fcae4f | ||
|
|
87a9257e19 | ||
|
|
a436c6b5c7 | ||
|
|
2b92b8daee | ||
|
|
c443bb74d7 | ||
|
|
2fb83df0cf | ||
|
|
1c10d46a5e | ||
|
|
d3e7eec47a | ||
|
|
64266b1ff8 | ||
|
|
254d8453ad | ||
|
|
f05246f8c7 | ||
|
|
5bbdc9e509 | ||
|
|
4302c4492c | ||
|
|
8ff2be168e | ||
|
|
4fe6f3e975 | ||
|
|
b8cb7f7ad9 | ||
|
|
15209544d0 | ||
|
|
452dbefbdb | ||
|
|
adea917a5d | ||
|
|
e5efe08fc3 | ||
|
|
2c7aab7607 | ||
|
|
4daa0aa549 | ||
|
|
134e7ad48d | ||
|
|
2d6c2e8d10 | ||
|
|
725d76d9c5 | ||
|
|
e669017949 | ||
|
|
82b1d515d1 | ||
|
|
f985813960 | ||
|
|
81aa08b732 | ||
|
|
fb928d28db | ||
|
|
716f934b6c | ||
|
|
26a0f35dd2 | ||
|
|
ab4688c6dd | ||
|
|
c18cd10c69 | ||
|
|
1f76012423 | ||
|
|
a07d28293c | ||
|
|
e152868e0f | ||
|
|
77db3652f2 | ||
|
|
41be4b1a31 | ||
|
|
ba015bb2e8 | ||
|
|
1ff75d2aa5 | ||
|
|
4e7bff92c9 | ||
|
|
9c12588187 | ||
|
|
a84c695a9f | ||
|
|
c077b6e617 | ||
|
|
899f89b57d | ||
|
|
982c03b0f6 | ||
|
|
0ba2abd6b1 | ||
|
|
de1833e219 | ||
|
|
c5b6401c60 | ||
|
|
292f879780 | ||
|
|
c65cc08eb3 | ||
|
|
8f29978082 | ||
|
|
6750c8f572 | ||
|
|
b3c60e4442 | ||
|
|
4ff96e0278 | ||
|
|
2d6fdb8e84 | ||
|
|
66bb1137aa | ||
|
|
db0c335049 | ||
|
|
8198729ad3 | ||
|
|
939a9f6547 | ||
|
|
1c50efa500 | ||
|
|
ec75a3e289 | ||
|
|
2e252c1d18 | ||
|
|
dd20c11d8b | ||
|
|
2a2fff27d6 | ||
|
|
082d66ca10 | ||
|
|
41b4bff940 | ||
|
|
9136f4c94b | ||
|
|
50f4984231 | ||
|
|
48466cfb44 | ||
|
|
a7acd49d60 | ||
|
|
91920a679a | ||
|
|
53441c86c4 | ||
|
|
ffdc8ae87e | ||
|
|
7c786d1e6b | ||
|
|
34c6a5e031 | ||
|
|
7a430f81c5 | ||
|
|
230884c2cc | ||
|
|
f2d232d9eb | ||
|
|
1e3f0ab637 | ||
|
|
e15c7e37ff | ||
|
|
e15ba8d852 | ||
|
|
a759ccbbf7 | ||
|
|
84662a8fab | ||
|
|
cb47286784 | ||
|
|
6717e53fc9 | ||
|
|
dc5a3b5efd | ||
|
|
48520f652a | ||
|
|
dccb10cc6f | ||
|
|
c5d08253a7 | ||
|
|
5224e34f8c | ||
|
|
fb65bc8068 | ||
|
|
c0651a50a7 | ||
|
|
e04e3204eb | ||
|
|
ecc9e5ea99 | ||
|
|
ed024077ee | ||
|
|
91db5036c0 |
74
.github/workflows/compile.yaml
vendored
74
.github/workflows/compile.yaml
vendored
@@ -1,21 +1,37 @@
|
||||
name: PlatformIO CI
|
||||
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags-ignore:
|
||||
- '*'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pip
|
||||
~/.platformio/.cache
|
||||
key: ${{ runner.os }}-pio
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
#- uses: actions/cache@v3
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.cache/pip
|
||||
# ~/.platformio/.cache
|
||||
# key: ${{ runner.os }}-pio-cyd-klipper
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
@@ -24,22 +40,30 @@ jobs:
|
||||
|
||||
- name: Build PlatformIO Project
|
||||
run: |
|
||||
cd CYD-Klipper-Display
|
||||
pio run
|
||||
python3 ci.py
|
||||
|
||||
- name: Make output dir
|
||||
run: mkdir -p output
|
||||
|
||||
- name: Build Binary
|
||||
run: |
|
||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/bootloader.bin output
|
||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/partitions.bin output
|
||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/firmware.bin output
|
||||
cp ~/platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin output
|
||||
esptool --chip esp32 merge_bin -o ./output/merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 ./output/bootloader.bin 0x8000 ./output/partitions.bin 0xe000 ./output/boot_app0.bin 0x10000 ./output/firmware.bin
|
||||
|
||||
- name: Upload artefact
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware
|
||||
path: ./output
|
||||
path: ./out
|
||||
|
||||
- name: Upload GitHub Page Artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: github.event_name == 'release' && github.event.action == 'created'
|
||||
steps:
|
||||
- name: Print GitHub event name
|
||||
run: |
|
||||
echo "${{ github.event_name }}"
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
_site/out/
|
||||
_site/OTA.json
|
||||
_site/esp32-*.json
|
||||
|
||||
pyvenv.cfg
|
||||
bin/
|
||||
out/
|
||||
lib
|
||||
lib64
|
||||
|
||||
__pycache__/
|
||||
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
13
CYD-Klipper-Display/.vscode/settings.json
vendored
13
CYD-Klipper-Display/.vscode/settings.json
vendored
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"string_view": "cpp",
|
||||
"initializer_list": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
lib_deps =
|
||||
SPI
|
||||
lvgl/lvgl@^8.3.9
|
||||
https://github.com/Bodmer/TFT_eSPI.git
|
||||
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
|
||||
bblanchon/ArduinoJson@^6.21.3
|
||||
build_flags =
|
||||
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9341_2_DRIVER=1
|
||||
-DTFT_WIDTH=240
|
||||
-DTFT_HEIGHT=320
|
||||
-DTFT_BL=21
|
||||
-DTFT_BACKLIGHT_ON=HIGH
|
||||
-DTFT_MISO=12
|
||||
-DTFT_MOSI=13
|
||||
-DTFT_SCLK=14
|
||||
-DTFT_CS=15
|
||||
-DTFT_DC=2
|
||||
-DTFT_RST=-1
|
||||
-DLOAD_GCLD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_GFXFF=1
|
||||
-DSMOOTH_FONT=1
|
||||
-DSPI_FREQUENCY=55000000
|
||||
-DSPI_READ_FREQUENCY=20000000
|
||||
-DSPI_TOUCH_FREQUENCY=2500000
|
||||
@@ -1,49 +0,0 @@
|
||||
#include <Preferences.h>
|
||||
#include "global_config.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
GLOBAL_CONFIG global_config = {0};
|
||||
|
||||
COLOR_DEF color_defs[] = {
|
||||
{LV_PALETTE_BLUE, LV_PALETTE_RED},
|
||||
{LV_PALETTE_GREEN, LV_PALETTE_PURPLE},
|
||||
{LV_PALETTE_GREY, LV_PALETTE_CYAN},
|
||||
{LV_PALETTE_YELLOW, LV_PALETTE_PINK},
|
||||
{LV_PALETTE_ORANGE, LV_PALETTE_BLUE},
|
||||
{LV_PALETTE_RED, LV_PALETTE_GREEN},
|
||||
{LV_PALETTE_PURPLE, LV_PALETTE_GREY},
|
||||
};
|
||||
|
||||
void WriteGlobalConfig() {
|
||||
Preferences preferences;
|
||||
preferences.begin("global_config", false);
|
||||
preferences.putBytes("global_config", &global_config, sizeof(global_config));
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
void VerifyVersion(){
|
||||
Preferences preferences;
|
||||
if (!preferences.begin("global_config", false))
|
||||
return;
|
||||
|
||||
GLOBAL_CONFIG config = {0};
|
||||
preferences.getBytes("global_config", &config, sizeof(config));
|
||||
Serial.printf("Config version: %d\n", config.version);
|
||||
if (config.version != CONFIG_VERSION) {
|
||||
Serial.println("Clearing Global Config");
|
||||
preferences.clear();
|
||||
}
|
||||
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
void LoadGlobalConfig() {
|
||||
global_config.version = CONFIG_VERSION;
|
||||
global_config.brightness = 255;
|
||||
global_config.screenTimeout = 5;
|
||||
VerifyVersion();
|
||||
Preferences preferences;
|
||||
preferences.begin("global_config", true);
|
||||
preferences.getBytes("global_config", &global_config, sizeof(global_config));
|
||||
preferences.end();
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef _GLOBAL_CONFIG_INIT
|
||||
#define _GLOBAL_CONFIG_INIT
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#define CONFIG_VERSION 2
|
||||
|
||||
typedef struct _GLOBAL_CONFIG {
|
||||
unsigned char version;
|
||||
union {
|
||||
unsigned char raw;
|
||||
struct {
|
||||
bool screenCalibrated : 1;
|
||||
bool wifiConfigured : 1;
|
||||
bool ipConfigured : 1;
|
||||
bool lightMode : 1;
|
||||
bool invertColors : 1;
|
||||
bool rotateScreen : 1;
|
||||
bool onDuringPrint : 1;
|
||||
};
|
||||
};
|
||||
float screenCalXOffset;
|
||||
float screenCalXMult;
|
||||
float screenCalYOffset;
|
||||
float screenCalYMult;
|
||||
|
||||
char wifiSSID[32];
|
||||
char wifiPassword[64];
|
||||
|
||||
char klipperHost[64];
|
||||
unsigned short klipperPort;
|
||||
|
||||
unsigned char color_scheme;
|
||||
unsigned char brightness;
|
||||
unsigned char screenTimeout;
|
||||
} GLOBAL_CONFIG;
|
||||
|
||||
typedef struct _COLOR_DEF {
|
||||
lv_palette_t primary_color;
|
||||
lv_palette_t secondary_color;
|
||||
} COLOR_DEF;
|
||||
|
||||
extern GLOBAL_CONFIG global_config;
|
||||
extern COLOR_DEF color_defs[];
|
||||
|
||||
void WriteGlobalConfig();
|
||||
void VerifyVersion();
|
||||
void LoadGlobalConfig();
|
||||
|
||||
#endif // !_GLOBAL_CONFIG_INIT
|
||||
@@ -1,182 +0,0 @@
|
||||
|
||||
#include "data_setup.h"
|
||||
#include "lvgl.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
const char *printer_state_messages[] = {
|
||||
"Error",
|
||||
"Idle",
|
||||
"Printing"};
|
||||
|
||||
Printer printer = {0};
|
||||
|
||||
void send_gcode(bool wait, const char *gcode)
|
||||
{
|
||||
char buff[256] = {};
|
||||
sprintf(buff, "http://%s:%d/printer/gcode/script?script=%s", global_config.klipperHost, global_config.klipperPort, gcode);
|
||||
HTTPClient client;
|
||||
client.begin(buff);
|
||||
|
||||
if (!wait)
|
||||
{
|
||||
client.setTimeout(1000);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
client.GET();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Serial.println("Failed to send gcode");
|
||||
}
|
||||
}
|
||||
|
||||
char filename_buff[512] = {0};
|
||||
|
||||
void fetch_printer_data()
|
||||
{
|
||||
char buff[256] = {};
|
||||
sprintf(buff, "http://%s:%d/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks", global_config.klipperHost, global_config.klipperPort);
|
||||
HTTPClient client;
|
||||
client.begin(buff);
|
||||
int httpCode = client.GET();
|
||||
if (httpCode == 200)
|
||||
{
|
||||
String payload = client.getString();
|
||||
DynamicJsonDocument doc(4096);
|
||||
deserializeJson(doc, payload);
|
||||
auto status = doc["result"]["status"];
|
||||
bool emit_state_update = false;
|
||||
int printer_state = printer.state;
|
||||
|
||||
if (status.containsKey("webhooks"))
|
||||
{
|
||||
const char *state = status["webhooks"]["state"];
|
||||
const char *message = status["webhooks"]["state_message"];
|
||||
|
||||
if (strcmp(state, "ready") == 0 && printer.state == PRINTER_STATE_ERROR)
|
||||
{
|
||||
printer_state = PRINTER_STATE_IDLE;
|
||||
}
|
||||
else if (strcmp(state, "shutdown") == 0 && printer.state != PRINTER_STATE_ERROR)
|
||||
{
|
||||
printer_state = PRINTER_STATE_ERROR;
|
||||
}
|
||||
|
||||
if (printer.state_message == NULL || strcmp(printer.state_message, message))
|
||||
{
|
||||
if (printer.state_message != NULL)
|
||||
{
|
||||
free(printer.state_message);
|
||||
}
|
||||
|
||||
printer.state_message = (char *)malloc(strlen(message) + 1);
|
||||
strcpy(printer.state_message, message);
|
||||
emit_state_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (printer_state != PRINTER_STATE_ERROR)
|
||||
{
|
||||
if (status.containsKey("extruder"))
|
||||
{
|
||||
printer.extruder_temp = status["extruder"]["temperature"];
|
||||
printer.extruder_target_temp = status["extruder"]["target"];
|
||||
bool can_extrude = status["extruder"]["can_extrude"];
|
||||
printer.can_extrude = can_extrude == true;
|
||||
}
|
||||
|
||||
if (status.containsKey("heater_bed"))
|
||||
{
|
||||
printer.bed_temp = status["heater_bed"]["temperature"];
|
||||
printer.bed_target_temp = status["heater_bed"]["target"];
|
||||
}
|
||||
|
||||
if (status.containsKey("toolhead"))
|
||||
{
|
||||
printer.position[0] = status["toolhead"]["position"][0];
|
||||
printer.position[1] = status["toolhead"]["position"][1];
|
||||
printer.position[2] = status["toolhead"]["position"][2];
|
||||
const char *homed_axis = status["toolhead"]["homed_axes"];
|
||||
printer.homed_axis = strcmp(homed_axis, "xyz") == 0;
|
||||
}
|
||||
|
||||
if (status.containsKey("gcode_move"))
|
||||
{
|
||||
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
|
||||
printer.absolute_coords = absolute_coords == true;
|
||||
}
|
||||
|
||||
if (status.containsKey("virtual_sdcard"))
|
||||
{
|
||||
printer.print_progress = status["virtual_sdcard"]["progress"];
|
||||
}
|
||||
|
||||
if (status.containsKey("print_stats"))
|
||||
{
|
||||
const char *filename = status["print_stats"]["filename"];
|
||||
strcpy(filename_buff, filename);
|
||||
printer.print_filename = filename_buff;
|
||||
printer.elapsed_time_s = status["print_stats"]["print_duration"];
|
||||
printer.filament_used_mm = status["print_stats"]["filament_used"];
|
||||
|
||||
const char *state = status["print_stats"]["state"];
|
||||
|
||||
if (strcmp(state, "printing") == 0)
|
||||
{
|
||||
printer_state = PRINTER_STATE_PRINTING;
|
||||
}
|
||||
else if (strcmp(state, "paused") == 0)
|
||||
{
|
||||
printer_state = PRINTER_STATE_PAUSED;
|
||||
}
|
||||
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
|
||||
{
|
||||
printer_state = PRINTER_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make a call to /server/files/metadata to get more accurate time estimates
|
||||
// https://moonraker.readthedocs.io/en/latest/web_api/#server-administration
|
||||
|
||||
if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0)
|
||||
{
|
||||
printer.remaining_time_s = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s;
|
||||
}
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
||||
}
|
||||
|
||||
if (printer.state != printer_state || emit_state_update)
|
||||
{
|
||||
printer.state = printer_state;
|
||||
lv_msg_send(DATA_PRINTER_STATE, &printer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("Failed to fetch printer data: %d\n", httpCode);
|
||||
}
|
||||
}
|
||||
|
||||
long last_data_update = 0;
|
||||
const long data_update_interval = 1500;
|
||||
|
||||
void data_loop()
|
||||
{
|
||||
if (millis() - last_data_update < data_update_interval)
|
||||
return;
|
||||
|
||||
last_data_update = millis();
|
||||
|
||||
fetch_printer_data();
|
||||
}
|
||||
|
||||
void data_setup()
|
||||
{
|
||||
printer.print_filename = filename_buff;
|
||||
fetch_printer_data();
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum {
|
||||
PRINTER_STATE_ERROR = 0,
|
||||
PRINTER_STATE_IDLE = 1,
|
||||
PRINTER_STATE_PRINTING = 2,
|
||||
PRINTER_STATE_PAUSED = 3,
|
||||
};
|
||||
|
||||
extern const char* printer_state_messages[];
|
||||
|
||||
typedef struct _Printer {
|
||||
unsigned char state;
|
||||
char* state_message;
|
||||
float extruder_temp;
|
||||
float extruder_target_temp;
|
||||
float bed_temp;
|
||||
float bed_target_temp;
|
||||
float position[3];
|
||||
unsigned char can_extrude;
|
||||
unsigned char homed_axis;
|
||||
unsigned char absolute_coords;
|
||||
float elapsed_time_s;
|
||||
float remaining_time_s;
|
||||
float filament_used_mm;
|
||||
char* print_filename; // 0 -> 1
|
||||
float print_progress;
|
||||
} Printer;
|
||||
|
||||
extern Printer printer;
|
||||
|
||||
#define DATA_PRINTER_STATE 1
|
||||
#define DATA_PRINTER_DATA 2
|
||||
|
||||
void data_loop();
|
||||
void data_setup();
|
||||
void send_gcode(bool wait, const char* gcode);
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <list>
|
||||
#include "files_query.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
// Always has +1 entry with a null'd name
|
||||
FILESYSTEM_FILE* last_query = NULL;
|
||||
|
||||
FILESYSTEM_FILE* get_files(){
|
||||
if (last_query != NULL){
|
||||
FILESYSTEM_FILE* current = last_query;
|
||||
|
||||
while (current->name != NULL){
|
||||
free(current->name);
|
||||
current += 1;
|
||||
}
|
||||
|
||||
free(last_query);
|
||||
}
|
||||
|
||||
std::list<FILESYSTEM_FILE> files;
|
||||
char buff[256] = {};
|
||||
sprintf(buff, "http://%s:%d/server/files/list", global_config.klipperHost, global_config.klipperPort);
|
||||
HTTPClient client;
|
||||
client.begin(buff);
|
||||
int httpCode = client.GET();
|
||||
int count = 0;
|
||||
if (httpCode == 200){
|
||||
String payload = client.getString();
|
||||
DynamicJsonDocument doc(60000);
|
||||
auto a = deserializeJson(doc, payload);
|
||||
Serial.printf("JSON PARSE: %s\n", a.c_str());
|
||||
auto result = doc["result"].as<JsonArray>();
|
||||
for (auto file : result){
|
||||
FILESYSTEM_FILE f = {0};
|
||||
const char* path = file["path"];
|
||||
f.name = (char*)malloc(strlen(path) + 1);
|
||||
strcpy(f.name, path);
|
||||
f.modified = file["modified"];
|
||||
files.push_back(f);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
//Serial.printf("Found %d files\n", count);
|
||||
files.sort([](FILESYSTEM_FILE a, FILESYSTEM_FILE b){return a.modified < b.modified;});
|
||||
files.reverse(); // TODO: Reverse is unneeded here, we can iterate backwards
|
||||
|
||||
size_t size = sizeof(FILESYSTEM_FILE) * (files.size() + 1);
|
||||
FILESYSTEM_FILE* result = (FILESYSTEM_FILE*)malloc(size);
|
||||
//Serial.printf("Allocated %d bytes\n", size);
|
||||
last_query = result;
|
||||
result[files.size()].name = NULL;
|
||||
|
||||
for (auto file : files){
|
||||
*result = file;
|
||||
result += 1;
|
||||
}
|
||||
|
||||
return last_query;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
At some point it may be a fun challenge to try to implement a virtual folder structure, but not today.
|
||||
|
||||
typedef struct _FILESYSTEM_FILE {
|
||||
char* name;
|
||||
char* parent_folder_name;
|
||||
long level;
|
||||
} FILESYSTEM_FILE;
|
||||
|
||||
typedef struct _FILESYSTEM_FOLDER {
|
||||
char** files;
|
||||
char* folder_path;
|
||||
FILESYSTEM_FOLDER* folders;
|
||||
} FILESYSTEM_FOLDER;
|
||||
*/
|
||||
|
||||
typedef struct _FILESYSTEM_FILE {
|
||||
char* name;
|
||||
float modified;
|
||||
} FILESYSTEM_FILE;
|
||||
|
||||
FILESYSTEM_FILE* get_files();
|
||||
@@ -1,230 +0,0 @@
|
||||
#include "screen_driver.h"
|
||||
#include <SPI.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
SPIClass touchscreen_spi = SPIClass(HSPI);
|
||||
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
|
||||
|
||||
uint32_t LV_EVENT_GET_COMP_CHILD;
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[TFT_WIDTH * TFT_HEIGHT / 10];
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
bool isScreenInSleep = false;
|
||||
lv_timer_t *screenSleepTimer;
|
||||
|
||||
TS_Point touchscreen_point()
|
||||
{
|
||||
TS_Point p = touchscreen.getPoint();
|
||||
p.x = round((p.x * global_config.screenCalXMult) + global_config.screenCalXOffset);
|
||||
p.y = round((p.y * global_config.screenCalYMult) + global_config.screenCalYOffset);
|
||||
return p;
|
||||
}
|
||||
|
||||
void touchscreen_calibrate(bool force)
|
||||
{
|
||||
if (global_config.screenCalibrated && !force)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setCursor(20, 140);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
tft.setTextSize(2);
|
||||
tft.println("Calibrate Screen");
|
||||
|
||||
TS_Point p;
|
||||
int16_t x1, y1, x2, y2;
|
||||
|
||||
while (touchscreen.touched())
|
||||
;
|
||||
tft.drawFastHLine(0, 10, 20, ILI9341_WHITE);
|
||||
tft.drawFastVLine(10, 0, 20, ILI9341_WHITE);
|
||||
while (!touchscreen.touched())
|
||||
;
|
||||
delay(50);
|
||||
p = touchscreen.getPoint();
|
||||
x1 = p.x;
|
||||
y1 = p.y;
|
||||
tft.drawFastHLine(0, 10, 20, ILI9341_BLACK);
|
||||
tft.drawFastVLine(10, 0, 20, ILI9341_BLACK);
|
||||
delay(500);
|
||||
|
||||
while (touchscreen.touched())
|
||||
;
|
||||
tft.drawFastHLine(300, 230, 20, ILI9341_WHITE);
|
||||
tft.drawFastVLine(310, 220, 20, ILI9341_WHITE);
|
||||
|
||||
while (!touchscreen.touched())
|
||||
;
|
||||
delay(50);
|
||||
p = touchscreen.getPoint();
|
||||
x2 = p.x;
|
||||
y2 = p.y;
|
||||
tft.drawFastHLine(300, 230, 20, ILI9341_BLACK);
|
||||
tft.drawFastVLine(310, 220, 20, ILI9341_BLACK);
|
||||
|
||||
int16_t xDist = 320 - 40;
|
||||
int16_t yDist = 240 - 40;
|
||||
|
||||
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1);
|
||||
global_config.screenCalXOffset = 20.0 - ((float)x1 * global_config.screenCalXMult);
|
||||
|
||||
global_config.screenCalYMult = (float)yDist / (float)(y2 - y1);
|
||||
global_config.screenCalYOffset = 20.0 - ((float)y1 * global_config.screenCalYMult);
|
||||
|
||||
global_config.screenCalibrated = true;
|
||||
WriteGlobalConfig();
|
||||
}
|
||||
|
||||
void screen_setBrightness(byte brightness)
|
||||
{
|
||||
analogWrite(TFT_BL, brightness);
|
||||
}
|
||||
|
||||
void set_screen_brightness()
|
||||
{
|
||||
if (global_config.brightness < 32)
|
||||
screen_setBrightness(255);
|
||||
else
|
||||
screen_setBrightness(global_config.brightness);
|
||||
}
|
||||
|
||||
void screen_timer_wake()
|
||||
{
|
||||
lv_timer_reset(screenSleepTimer);
|
||||
isScreenInSleep = false;
|
||||
set_screen_brightness();
|
||||
}
|
||||
|
||||
void screen_timer_sleep(lv_timer_t *timer)
|
||||
{
|
||||
screen_setBrightness(0);
|
||||
isScreenInSleep = true;
|
||||
}
|
||||
|
||||
void screen_timer_setup()
|
||||
{
|
||||
screenSleepTimer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL);
|
||||
lv_timer_pause(screenSleepTimer);
|
||||
}
|
||||
|
||||
void screen_timer_start()
|
||||
{
|
||||
lv_timer_resume(screenSleepTimer);
|
||||
}
|
||||
|
||||
void screen_timer_stop()
|
||||
{
|
||||
lv_timer_pause(screenSleepTimer);
|
||||
}
|
||||
|
||||
void screen_timer_period(uint32_t period)
|
||||
{
|
||||
lv_timer_set_period(screenSleepTimer, period);
|
||||
}
|
||||
|
||||
void set_screen_timer_period()
|
||||
{
|
||||
screen_timer_period(global_config.screenTimeout * 1000 * 60);
|
||||
}
|
||||
|
||||
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
|
||||
if (touchscreen.tirqTouched() && touchscreen.touched())
|
||||
{
|
||||
lv_timer_reset(screenSleepTimer);
|
||||
// dont pass first touch after power on
|
||||
if (isScreenInSleep)
|
||||
{
|
||||
screen_timer_wake();
|
||||
while (touchscreen.touched())
|
||||
;
|
||||
return;
|
||||
}
|
||||
|
||||
TS_Point p = touchscreen_point();
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
data->point.x = p.x;
|
||||
data->point.y = p.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_color_scheme(){
|
||||
lv_disp_t *dispp = lv_disp_get_default();
|
||||
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(color_defs[global_config.color_scheme].primary_color), lv_palette_main(color_defs[global_config.color_scheme].secondary_color), !global_config.lightMode, LV_FONT_DEFAULT);
|
||||
lv_disp_set_theme(dispp, theme);
|
||||
}
|
||||
|
||||
void set_invert_display(){
|
||||
tft.invertDisplay(global_config.invertColors);
|
||||
}
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
|
||||
touchscreen.begin(touchscreen_spi);
|
||||
touchscreen.setRotation(global_config.rotateScreen ? 3 : 1);
|
||||
|
||||
lv_init();
|
||||
|
||||
tft.init();
|
||||
tft.setRotation(global_config.rotateScreen ? 3 : 1);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
set_screen_brightness();
|
||||
set_invert_display();
|
||||
|
||||
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
|
||||
touchscreen.begin(touchscreen_spi);
|
||||
|
||||
touchscreen_calibrate();
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = TFT_HEIGHT;
|
||||
disp_drv.ver_res = TFT_WIDTH;
|
||||
disp_drv.flush_cb = screen_lv_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = screen_lv_touchRead;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
screen_timer_setup();
|
||||
screen_timer_start();
|
||||
|
||||
/*Initialize the graphics library */
|
||||
LV_EVENT_GET_COMP_CHILD = lv_event_register_id();
|
||||
set_color_scheme();
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
// Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h
|
||||
|
||||
#ifndef _SCREEN_DRIVER_INIT
|
||||
#define _SCREEN_DRIVER_INIT
|
||||
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
#define XPT2046_IRQ 36
|
||||
#define XPT2046_MOSI 32
|
||||
#define XPT2046_MISO 39
|
||||
#define XPT2046_CLK 25
|
||||
#define XPT2046_CS 33
|
||||
|
||||
TS_Point touchscreen_point();
|
||||
void touchscreen_calibrate(bool force = false);
|
||||
void screen_setBrightness(byte brightness);
|
||||
void screen_timer_setup();
|
||||
void screen_timer_start();
|
||||
void screen_timer_stop();
|
||||
void screen_timer_period(uint32_t period);
|
||||
void set_color_scheme();
|
||||
void screen_setup();
|
||||
void set_invert_display();
|
||||
void screen_timer_wake();
|
||||
void set_screen_timer_period();
|
||||
void set_screen_brightness();
|
||||
|
||||
extern TFT_eSPI tft;
|
||||
|
||||
#endif // _SCREEN_DRIVER_INIT
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "conf/global_config.h"
|
||||
#include "core/screen_driver.h"
|
||||
#include "ui/wifi_setup.h"
|
||||
#include "ui/ip_setup.h"
|
||||
#include "lvgl.h"
|
||||
#include "core/data_setup.h"
|
||||
#include "ui/main_ui.h"
|
||||
#include "ui/nav_buttons.h"
|
||||
|
||||
static void event_handler(lv_event_t * e){
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
global_config.version = 0;
|
||||
WriteGlobalConfig();
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("Hello World");
|
||||
LoadGlobalConfig();
|
||||
screen_setup();
|
||||
Serial.println("Screen init done");
|
||||
|
||||
wifi_init();
|
||||
ip_setup();
|
||||
data_setup();
|
||||
|
||||
nav_style_setup();
|
||||
main_ui_setup();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * label;
|
||||
|
||||
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
label = lv_label_create(btn1);
|
||||
lv_label_set_text(label, "Reset Configuration");
|
||||
lv_obj_center(label);
|
||||
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act());
|
||||
lv_obj_set_width(slider, 200);
|
||||
lv_obj_align(slider, LV_ALIGN_CENTER, 0, 40);
|
||||
lv_slider_set_range(slider, 0, 100);
|
||||
lv_slider_set_value(slider, 50, LV_ANIM_OFF);
|
||||
*/
|
||||
}
|
||||
|
||||
void loop(){
|
||||
wifi_ok();
|
||||
data_loop();
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
#include "ip_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include <TFT_eSPI.h>
|
||||
#include <HTTPClient.h>
|
||||
|
||||
bool connect_ok = false;
|
||||
lv_obj_t * ipEntry;
|
||||
lv_obj_t * portEntry;
|
||||
lv_obj_t * label = NULL;
|
||||
|
||||
bool verify_ip(){
|
||||
HTTPClient client;
|
||||
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
|
||||
int httpCode;
|
||||
try {
|
||||
Serial.println(url);
|
||||
client.begin(url.c_str());
|
||||
httpCode = client.GET();
|
||||
return httpCode == 200;
|
||||
}
|
||||
catch (...) {
|
||||
Serial.println("Failed to connect");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void ta_event_cb(lv_event_t * e) {
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
|
||||
if(code == LV_EVENT_FOCUSED) {
|
||||
lv_keyboard_set_textarea(kb, ta);
|
||||
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else if(code == LV_EVENT_DEFOCUSED) {
|
||||
lv_keyboard_set_textarea(kb, NULL);
|
||||
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else if (code == LV_EVENT_READY)
|
||||
{
|
||||
strcpy(global_config.klipperHost, lv_textarea_get_text(ipEntry));
|
||||
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
|
||||
bool result = verify_ip();
|
||||
if (result)
|
||||
{
|
||||
global_config.ipConfigured = true;
|
||||
WriteGlobalConfig();
|
||||
connect_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_label_set_text(label, "Failed to connect");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ip_setup_inner(){
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
|
||||
label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Enter Klipper IP and Port");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
|
||||
|
||||
ipEntry = lv_textarea_create(lv_scr_act());
|
||||
lv_textarea_set_one_line(ipEntry, true);
|
||||
lv_textarea_set_max_length(ipEntry, 63);
|
||||
lv_textarea_set_text(ipEntry, "");
|
||||
lv_obj_align(ipEntry, LV_ALIGN_TOP_LEFT, 10, 40);
|
||||
lv_obj_add_event_cb(ipEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
|
||||
lv_obj_set_size(ipEntry, TFT_HEIGHT - 20 - 100, 60);
|
||||
|
||||
portEntry = lv_textarea_create(lv_scr_act());
|
||||
lv_textarea_set_one_line(portEntry, true);
|
||||
lv_textarea_set_max_length(portEntry, 5);
|
||||
lv_textarea_set_text(portEntry, "80");
|
||||
lv_obj_align(portEntry, LV_ALIGN_TOP_LEFT, TFT_HEIGHT - 20 - 80, 40);
|
||||
lv_obj_add_event_cb(portEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
|
||||
lv_obj_set_size(portEntry, 90, 60);
|
||||
|
||||
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
|
||||
lv_keyboard_set_textarea(keyboard, ipEntry);
|
||||
}
|
||||
|
||||
void ip_setup(){
|
||||
connect_ok = false;
|
||||
|
||||
if (global_config.ipConfigured && verify_ip()){
|
||||
return;
|
||||
}
|
||||
|
||||
ip_setup_inner();
|
||||
|
||||
while (!connect_ok)
|
||||
{
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
void ip_setup();
|
||||
@@ -1,79 +0,0 @@
|
||||
#include "main_ui.h"
|
||||
#include "../core/data_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "../core/screen_driver.h"
|
||||
#include "lvgl.h"
|
||||
#include "nav_buttons.h"
|
||||
|
||||
char extruder_temp_buff[20];
|
||||
char bed_temp_buff[20];
|
||||
char position_buff[20];
|
||||
|
||||
static void btn_click_restart(lv_event_t * e){
|
||||
send_gcode(false, "RESTART");
|
||||
}
|
||||
|
||||
static void btn_click_firmware_restart(lv_event_t * e){
|
||||
send_gcode(false, "FIRMWARE_RESTART");
|
||||
}
|
||||
|
||||
void error_ui(){
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * label;
|
||||
label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, LV_SYMBOL_WARNING " Printer is not ready");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||
|
||||
label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, printer.state_message);
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 30);
|
||||
lv_obj_set_size(label, TFT_HEIGHT - 20, TFT_WIDTH - 30);
|
||||
lv_obj_clear_flag(label, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -10);
|
||||
lv_obj_set_size(btn, TFT_HEIGHT / 2 - 15, 30);
|
||||
lv_obj_add_event_cb(btn, btn_click_restart, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Restart");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
|
||||
lv_obj_set_size(btn, TFT_HEIGHT / 2 - 15, 30);
|
||||
lv_obj_add_event_cb(btn, btn_click_firmware_restart, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Firmware Restart");
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
void check_if_screen_needs_to_be_disabled(){
|
||||
if (global_config.onDuringPrint && printer.state == PRINTER_STATE_PRINTING){
|
||||
screen_timer_wake();
|
||||
screen_timer_stop();
|
||||
}
|
||||
else {
|
||||
screen_timer_start();
|
||||
}
|
||||
}
|
||||
|
||||
static void on_state_change(void * s, lv_msg_t * m){
|
||||
check_if_screen_needs_to_be_disabled();
|
||||
|
||||
if (printer.state == PRINTER_STATE_ERROR){
|
||||
error_ui();
|
||||
}
|
||||
else {
|
||||
nav_buttons_setup(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main_ui_setup(){
|
||||
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
|
||||
on_state_change(NULL, NULL);
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "panels/panel.h"
|
||||
#include "../core/data_setup.h"
|
||||
#include "nav_buttons.h"
|
||||
#include <HTTPClient.h>
|
||||
|
||||
static lv_style_t nav_button_style;
|
||||
|
||||
static char temp_buffer[10];
|
||||
static char z_pos_buffer[10];
|
||||
static char time_buffer[10];
|
||||
|
||||
static lv_style_t nav_button_text_style;
|
||||
|
||||
static void update_printer_data_z_pos(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
|
||||
sprintf(z_pos_buffer, "Z%.2f", printer.position[2]);
|
||||
lv_label_set_text(label, z_pos_buffer);
|
||||
}
|
||||
|
||||
static void update_printer_data_temp(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
|
||||
sprintf(temp_buffer, "%.0f/%.0f", printer.extruder_temp, printer.bed_temp);
|
||||
lv_label_set_text(label, temp_buffer);
|
||||
}
|
||||
|
||||
static void update_printer_data_time(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
|
||||
if (printer.state == PRINTER_STATE_IDLE){
|
||||
lv_label_set_text(label, "Idle");
|
||||
return;
|
||||
}
|
||||
|
||||
if (printer.state == PRINTER_STATE_PAUSED){
|
||||
lv_label_set_text(label, "Paused");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long time = printer.remaining_time_s;
|
||||
unsigned long hours = time / 3600;
|
||||
unsigned long minutes = (time % 3600) / 60;
|
||||
unsigned long seconds = (time % 3600) % 60;
|
||||
|
||||
if (hours >= 10){
|
||||
sprintf(time_buffer, "%luh", hours);
|
||||
} else if (hours >= 1){
|
||||
sprintf(time_buffer, "%luh%02lum", hours, minutes);
|
||||
} else {
|
||||
sprintf(time_buffer, "%lum", minutes);
|
||||
}
|
||||
|
||||
lv_label_set_text(label, time_buffer);
|
||||
}
|
||||
|
||||
static void btn_click_files(lv_event_t * e){
|
||||
nav_buttons_setup(0);
|
||||
}
|
||||
|
||||
static void btn_click_move(lv_event_t * e){
|
||||
nav_buttons_setup(1);
|
||||
}
|
||||
|
||||
static void btn_click_extrude(lv_event_t * e){
|
||||
nav_buttons_setup(2);
|
||||
}
|
||||
|
||||
static void btn_click_settings(lv_event_t * e){
|
||||
nav_buttons_setup(3);
|
||||
}
|
||||
|
||||
void nav_buttons_setup(unsigned char active_panel){
|
||||
lv_obj_clean(lv_scr_act());
|
||||
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
|
||||
sprintf(temp_buffer, "%.0f/%.0f", printer.extruder_temp, printer.bed_temp);
|
||||
sprintf(z_pos_buffer, "Z%.2f", printer.position[2]);
|
||||
|
||||
const int button_width = 40;
|
||||
const int button_height = 60;
|
||||
const int icon_text_spacing = 10;
|
||||
|
||||
// Files/Print
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_set_size(btn, button_width, button_height);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||
lv_obj_add_event_cb(btn, btn_click_files, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_COPY);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Idle");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||
lv_obj_add_event_cb(label, update_printer_data_time, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
// Move
|
||||
btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_set_size(btn, button_width, button_height);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height);
|
||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||
lv_obj_add_event_cb(btn, btn_click_move, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_CHARGE);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, z_pos_buffer);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
||||
lv_obj_add_event_cb(label, update_printer_data_z_pos, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||
|
||||
// Extrude/Temp
|
||||
btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_set_size(btn, button_width, button_height);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 2);
|
||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||
lv_obj_add_event_cb(btn, btn_click_extrude, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_WARNING);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, temp_buffer);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
||||
lv_obj_add_event_cb(label, update_printer_data_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||
|
||||
// Settings
|
||||
btn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_set_size(btn, button_width, button_height);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 3);
|
||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||
lv_obj_add_event_cb(btn, btn_click_settings, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_SETTINGS);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Screen");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||
|
||||
lv_obj_t * panel = lv_obj_create(lv_scr_act());
|
||||
lv_obj_set_size(panel, TFT_HEIGHT - button_width, TFT_WIDTH);
|
||||
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
lv_obj_set_style_border_width(panel, 0, 0);
|
||||
lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_pad_all(panel, 0, 0);
|
||||
|
||||
switch (active_panel){
|
||||
case 0:
|
||||
print_panel_init(panel);
|
||||
break;
|
||||
case 1:
|
||||
move_panel_init(panel);
|
||||
break;
|
||||
case 2:
|
||||
temp_panel_init(panel);
|
||||
break;
|
||||
case 3:
|
||||
settings_panel_init(panel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nav_style_setup(){
|
||||
lv_style_init(&nav_button_style);
|
||||
lv_style_set_radius(&nav_button_style, 0);
|
||||
|
||||
lv_style_init(&nav_button_text_style);
|
||||
lv_style_set_text_font(&nav_button_text_style, &lv_font_montserrat_10);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
void nav_buttons_setup(unsigned char active_panel);
|
||||
void nav_style_setup();
|
||||
@@ -1,209 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "panel.h"
|
||||
#include "../../core/data_setup.h"
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
static void move_printer(const char* axis, float amount) {
|
||||
if (!printer.homed_axis || printer.state == PRINTER_STATE_PRINTING)
|
||||
return;
|
||||
|
||||
char gcode[64];
|
||||
const char* extra = (amount > 0) ? "+" : "";
|
||||
|
||||
bool absolute_coords = printer.absolute_coords;
|
||||
|
||||
if (absolute_coords) {
|
||||
send_gcode(true, "G91");
|
||||
}
|
||||
|
||||
const char * space = "%20";
|
||||
|
||||
sprintf(gcode, "G1%s%s%s%.1f%sF6000", space, axis, extra, amount, space);
|
||||
send_gcode(true, gcode);
|
||||
|
||||
if (absolute_coords) {
|
||||
send_gcode(true, "G90");
|
||||
}
|
||||
}
|
||||
|
||||
static void x_line_button_press(lv_event_t * e) {
|
||||
float* data_pointer = (float*)lv_event_get_user_data(e);
|
||||
float data = *data_pointer;
|
||||
move_printer("X", data);
|
||||
}
|
||||
|
||||
static void y_line_button_press(lv_event_t * e) {
|
||||
float* data_pointer = (float*)lv_event_get_user_data(e);
|
||||
float data = *data_pointer;
|
||||
move_printer("Y", data);
|
||||
}
|
||||
|
||||
static void z_line_button_press(lv_event_t * e) {
|
||||
float* data_pointer = (float*)lv_event_get_user_data(e);
|
||||
float data = *data_pointer;
|
||||
move_printer("Z", data);
|
||||
}
|
||||
|
||||
char x_pos_buff[12];
|
||||
|
||||
static void x_pos_update(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
sprintf(x_pos_buff, "X: %.1f", printer.position[0]);
|
||||
lv_label_set_text(label, x_pos_buff);
|
||||
}
|
||||
|
||||
char y_pos_buff[12];
|
||||
|
||||
static void y_pos_update(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
sprintf(y_pos_buff, "Y: %.1f", printer.position[1]);
|
||||
lv_label_set_text(label, y_pos_buff);
|
||||
}
|
||||
|
||||
char z_pos_buff[12];
|
||||
|
||||
static void z_pos_update(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
sprintf(z_pos_buff, "Z: %.2f", printer.position[2]);
|
||||
lv_label_set_text(label, z_pos_buff);
|
||||
}
|
||||
|
||||
lv_event_cb_t button_callbacks[] = {x_line_button_press, y_line_button_press, z_line_button_press};
|
||||
lv_event_cb_t position_callbacks[] = {x_pos_update, y_pos_update, z_pos_update};
|
||||
|
||||
const float xy_offsets[] = {-100, -10, -1, 1, 10, 100};
|
||||
const float z_offsets[] = {-25, -1, -0.1, 0.1, 1, 25};
|
||||
const float* offsets[] = {
|
||||
xy_offsets,
|
||||
xy_offsets,
|
||||
z_offsets
|
||||
};
|
||||
|
||||
const char* xy_offset_labels[] = {"-100", "-10", "-1", "+1", "+10", "+100"};
|
||||
const char* z_offset_labels[] = {"-25", "-1", "-0.1", "+0.1", "+1", "+25"};
|
||||
|
||||
const char** offset_labels[] = {
|
||||
xy_offset_labels,
|
||||
xy_offset_labels,
|
||||
z_offset_labels
|
||||
};
|
||||
|
||||
static void home_button_click(lv_event_t * e) {
|
||||
if (printer.state == PRINTER_STATE_PRINTING)
|
||||
return;
|
||||
|
||||
send_gcode(false, "G28");
|
||||
}
|
||||
|
||||
static void disable_steppers_click(lv_event_t * e) {
|
||||
if (printer.state == PRINTER_STATE_PRINTING)
|
||||
return;
|
||||
|
||||
send_gcode(true, "M18");
|
||||
}
|
||||
|
||||
static void stepper_state_update(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, printer.homed_axis ? LV_SYMBOL_HOME " Steppers locked" : LV_SYMBOL_EYE_CLOSE " Steppers unlocked");
|
||||
}
|
||||
|
||||
void move_panel_init(lv_obj_t* panel){
|
||||
lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE);
|
||||
const int button_size = 40;
|
||||
const int button_size_vertical = 40;
|
||||
const int button_padding = 2;
|
||||
const int x_offset = 15;
|
||||
int y_pos = 75;
|
||||
|
||||
auto panel_width = TFT_HEIGHT - 40;
|
||||
|
||||
lv_obj_t * home_button = lv_btn_create(panel);
|
||||
lv_obj_align(home_button, LV_ALIGN_TOP_LEFT, 10, 5);
|
||||
lv_obj_add_event_cb(home_button, home_button_click, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_set_size(home_button, panel_width / 2 - 15, 30);
|
||||
|
||||
lv_obj_t * home_label = lv_label_create(home_button);
|
||||
lv_label_set_text(home_label, LV_SYMBOL_HOME "Home Axis");
|
||||
lv_obj_center(home_label);
|
||||
|
||||
lv_obj_t * disable_steppers_button = lv_btn_create(panel);
|
||||
lv_obj_align(disable_steppers_button, LV_ALIGN_TOP_RIGHT, -10, 5);
|
||||
lv_obj_add_event_cb(disable_steppers_button, disable_steppers_click, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_set_size(disable_steppers_button, panel_width / 2 - 15, 30);
|
||||
|
||||
lv_obj_t * disable_steppers_label = lv_label_create(disable_steppers_button);
|
||||
lv_label_set_text(disable_steppers_label, LV_SYMBOL_EYE_CLOSE "Disable Step");
|
||||
lv_obj_center(disable_steppers_label);
|
||||
|
||||
lv_obj_t * label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "???");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 40);
|
||||
lv_obj_add_event_cb(label, stepper_state_update, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
lv_obj_t * btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i]));
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][0]);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 1, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 1));
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][1]);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 2, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 2));
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][2]);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 3, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 3));
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][3]);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 4, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 4));
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][4]);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_set_size(btn, button_size, button_size_vertical);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 5, y_pos);
|
||||
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 5));
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, offset_labels[i][5]);
|
||||
lv_obj_center(label);
|
||||
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "???");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, x_offset, y_pos - 15);\
|
||||
lv_obj_add_event_cb(label, position_callbacks[i], LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
y_pos += 60;
|
||||
}
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
|
||||
#define SIZEOF(arr) (sizeof(arr) / sizeof(*arr))
|
||||
|
||||
void settings_panel_init(lv_obj_t* panel);
|
||||
void temp_panel_init(lv_obj_t* panel);
|
||||
void print_panel_init(lv_obj_t* panel);
|
||||
void move_panel_init(lv_obj_t* panel);
|
||||
void progress_panel_init(lv_obj_t* panel);
|
||||
@@ -1,88 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "panel.h"
|
||||
#include "../../core/data_setup.h"
|
||||
#include "../../core/files_query.h"
|
||||
#include "../../conf/global_config.h"
|
||||
#include <HardwareSerial.h>
|
||||
#include <HTTPClient.h>
|
||||
|
||||
FILESYSTEM_FILE* selected_file = NULL;
|
||||
|
||||
static void btn_print_file(lv_event_t * e){
|
||||
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
|
||||
lv_obj_del(panel);
|
||||
|
||||
char* buff = (char*)malloc(128 + strlen(selected_file->name));
|
||||
sprintf(buff, "http://%s:%d/printer/print/start?filename=%s", global_config.klipperHost, global_config.klipperPort, selected_file->name);
|
||||
HTTPClient client;
|
||||
client.begin(buff);
|
||||
int httpCode = client.POST("");
|
||||
Serial.printf("Print start: HTTP %d\n", httpCode);
|
||||
}
|
||||
|
||||
static void btn_print_back(lv_event_t * e){
|
||||
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
|
||||
lv_obj_del(panel);
|
||||
}
|
||||
|
||||
static void btn_print_file_verify(lv_event_t * e){
|
||||
lv_obj_t * btn = lv_event_get_target(e);
|
||||
selected_file = (FILESYSTEM_FILE*)lv_event_get_user_data(e);
|
||||
|
||||
lv_obj_t * panel = lv_obj_create(lv_scr_act());
|
||||
lv_obj_set_size(panel, TFT_HEIGHT - 40, TFT_WIDTH - 30);
|
||||
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lv_obj_t * label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "Print File");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, selected_file->name);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
|
||||
lv_obj_set_width(label, TFT_HEIGHT - 90);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -10);
|
||||
lv_obj_set_size(btn, 40, 40);
|
||||
lv_obj_add_event_cb(btn, btn_print_back, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_CLOSE);
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
|
||||
lv_obj_set_size(btn, 40, 40);
|
||||
lv_obj_add_event_cb(btn, btn_print_file, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_OK);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
void print_panel_init(lv_obj_t* panel){
|
||||
if (printer.state == PRINTER_STATE_PRINTING || printer.state == PRINTER_STATE_PAUSED){
|
||||
progress_panel_init(panel);
|
||||
return;
|
||||
}
|
||||
|
||||
auto panel_width = TFT_HEIGHT - 40;
|
||||
auto panel_height_margin = TFT_WIDTH - 10;
|
||||
auto panel_width_margin = panel_width - 10;
|
||||
|
||||
lv_obj_t * list = lv_list_create(panel);
|
||||
lv_obj_set_size(list, panel_width_margin, panel_height_margin);
|
||||
lv_obj_align(list, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
FILESYSTEM_FILE* files = get_files();
|
||||
int count = 0;
|
||||
while (files->name != NULL && count <= 20){
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, files->name);
|
||||
lv_obj_add_event_cb(btn, btn_print_file_verify, LV_EVENT_CLICKED, (void*)files);
|
||||
|
||||
files += 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
#include "panel.h"
|
||||
#include "../../core/data_setup.h"
|
||||
#include <stdio.h>
|
||||
|
||||
char time_buffer[12];
|
||||
|
||||
char* time_display(unsigned long time){
|
||||
unsigned long hours = time / 3600;
|
||||
unsigned long minutes = (time % 3600) / 60;
|
||||
unsigned long seconds = (time % 3600) % 60;
|
||||
sprintf(time_buffer, "%02lu:%02lu:%02lu", hours, minutes, seconds);
|
||||
return time_buffer;
|
||||
}
|
||||
|
||||
static void progress_bar_update(lv_event_t* e){
|
||||
lv_obj_t * bar = lv_event_get_target(e);
|
||||
lv_bar_set_value(bar, printer.print_progress * 100, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
static void update_printer_data_elapsed_time(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, time_display(printer.elapsed_time_s));
|
||||
}
|
||||
|
||||
static void update_printer_data_remaining_time(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, time_display(printer.remaining_time_s));
|
||||
}
|
||||
|
||||
static void update_printer_data_percentage(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char percentage_buffer[12];
|
||||
sprintf(percentage_buffer, "%.2f%%", printer.print_progress * 100);
|
||||
lv_label_set_text(label, percentage_buffer);
|
||||
}
|
||||
|
||||
static void btn_click_stop(lv_event_t * e){
|
||||
send_gcode(true, "CANCEL_PRINT");
|
||||
}
|
||||
|
||||
static void btn_click_pause(lv_event_t * e){
|
||||
send_gcode(true, "PAUSE");
|
||||
}
|
||||
|
||||
static void btn_click_resume(lv_event_t * e){
|
||||
send_gcode(true, "RESUME");
|
||||
}
|
||||
|
||||
void progress_panel_init(lv_obj_t* panel){
|
||||
auto panel_width = TFT_HEIGHT - 40;
|
||||
auto panel_width_margin = panel_width - 30;
|
||||
|
||||
// Filename
|
||||
lv_obj_t * label = lv_label_create(panel);
|
||||
lv_label_set_text(label, printer.print_filename);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||
lv_obj_set_width(label, panel_width_margin);
|
||||
|
||||
// Progress Bar
|
||||
lv_obj_t * bar = lv_bar_create(panel);
|
||||
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_size(bar, panel_width_margin, 20);
|
||||
lv_obj_add_event_cb(bar, progress_bar_update, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, bar, NULL);
|
||||
|
||||
// Elapsed Time
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "???");
|
||||
lv_obj_align(label, LV_ALIGN_LEFT_MID, 10, 20);
|
||||
lv_obj_add_event_cb(label, update_printer_data_elapsed_time, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
// Remaining Time
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "???");
|
||||
lv_obj_align(label, LV_ALIGN_RIGHT_MID, -10, 20);
|
||||
lv_obj_add_event_cb(label, update_printer_data_remaining_time, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
// Percentage
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "???");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
|
||||
lv_obj_add_event_cb(label, update_printer_data_percentage, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
// Stop Button
|
||||
lv_obj_t * btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
|
||||
lv_obj_set_size(btn, 40, 40);
|
||||
lv_obj_add_event_cb(btn, btn_click_stop, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_STOP);
|
||||
lv_obj_center(label);
|
||||
|
||||
// Resume Button
|
||||
if (printer.state == PRINTER_STATE_PAUSED){
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -60, -10);
|
||||
lv_obj_set_size(btn, 40, 40);
|
||||
lv_obj_add_event_cb(btn, btn_click_resume, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_PLAY);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
// Pause Button
|
||||
else {
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -60, -10);
|
||||
lv_obj_set_size(btn, 40, 40);
|
||||
lv_obj_add_event_cb(btn, btn_click_pause, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_PAUSE);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "panel.h"
|
||||
#include "../../core/screen_driver.h"
|
||||
#include "../../conf/global_config.h"
|
||||
#include "../main_ui.h"
|
||||
|
||||
static void invert_color_switch(lv_event_t * e){
|
||||
auto state = lv_obj_get_state(lv_event_get_target(e));
|
||||
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||
global_config.invertColors = checked;
|
||||
WriteGlobalConfig();
|
||||
set_invert_display();
|
||||
}
|
||||
|
||||
static void reset_calibration_click(lv_event_t * e){
|
||||
global_config.screenCalibrated = false;
|
||||
WriteGlobalConfig();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
static void reset_wifi_click(lv_event_t * e){
|
||||
global_config.wifiConfigured = false;
|
||||
global_config.ipConfigured = false;
|
||||
WriteGlobalConfig();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
static void light_mode_switch(lv_event_t * e){
|
||||
auto state = lv_obj_get_state(lv_event_get_target(e));
|
||||
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||
global_config.lightMode = checked;
|
||||
WriteGlobalConfig();
|
||||
set_color_scheme();
|
||||
}
|
||||
|
||||
static void theme_dropdown(lv_event_t * e){
|
||||
lv_obj_t * dropdown = lv_event_get_target(e);
|
||||
auto selected = lv_dropdown_get_selected(dropdown);
|
||||
global_config.color_scheme = selected;
|
||||
set_color_scheme();
|
||||
WriteGlobalConfig();
|
||||
}
|
||||
|
||||
const char* brightness_options = "100%\n75%\n50%\n25%";
|
||||
const char brightness_options_values[] = { 255, 192, 128, 64 };
|
||||
|
||||
static void brightness_dropdown(lv_event_t * e){
|
||||
lv_obj_t * dropdown = lv_event_get_target(e);
|
||||
auto selected = lv_dropdown_get_selected(dropdown);
|
||||
global_config.brightness = brightness_options_values[selected];
|
||||
set_screen_brightness();
|
||||
WriteGlobalConfig();
|
||||
}
|
||||
|
||||
const char* wake_timeout_options = "1m\n2m\n5m\n10m\n15m\n30m\n1h\n2h\n4h";
|
||||
const char wake_timeout_options_values[] = { 1, 2, 5, 10, 15, 30, 60, 120, 240 };
|
||||
|
||||
static void wake_timeout_dropdown(lv_event_t * e){
|
||||
lv_obj_t * dropdown = lv_event_get_target(e);
|
||||
auto selected = lv_dropdown_get_selected(dropdown);
|
||||
global_config.screenTimeout = wake_timeout_options_values[selected];
|
||||
set_screen_timer_period();
|
||||
WriteGlobalConfig();
|
||||
}
|
||||
|
||||
static void rotate_screen_switch(lv_event_t* e){
|
||||
auto state = lv_obj_get_state(lv_event_get_target(e));
|
||||
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||
global_config.rotateScreen = checked;
|
||||
global_config.screenCalibrated = false;
|
||||
WriteGlobalConfig();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
static void on_during_print_switch(lv_event_t* e){
|
||||
auto state = lv_obj_get_state(lv_event_get_target(e));
|
||||
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||
global_config.onDuringPrint = checked;
|
||||
check_if_screen_needs_to_be_disabled();
|
||||
WriteGlobalConfig();
|
||||
}
|
||||
|
||||
int y_offset = 0;
|
||||
const int y_element_size = 50;
|
||||
const int y_seperator_size = 1;
|
||||
const int y_seperator_x_padding = 50;
|
||||
const int panel_width = TFT_HEIGHT - 40;
|
||||
const int y_element_x_padding = 30;
|
||||
const static lv_point_t line_points[] = { {0, 0}, {panel_width - y_seperator_x_padding, 0} };
|
||||
|
||||
void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel){
|
||||
lv_obj_t * panel = lv_obj_create(root_panel);
|
||||
lv_obj_set_style_border_width(panel, 0, 0);
|
||||
lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_pad_all(panel, 0, 0);
|
||||
lv_obj_align(panel, LV_ALIGN_TOP_MID, 0, y_offset);
|
||||
lv_obj_set_size(panel, panel_width - y_element_x_padding, y_element_size);
|
||||
|
||||
lv_obj_t * line = lv_line_create(panel);
|
||||
lv_line_set_points(line, line_points, 2);
|
||||
lv_obj_set_style_line_width(line, y_seperator_size, 0);
|
||||
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
|
||||
lv_obj_align(line, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
|
||||
lv_obj_t * label = lv_label_create(panel);
|
||||
lv_label_set_text(label, label_text);
|
||||
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
lv_obj_set_parent(object, panel);
|
||||
lv_obj_align(object, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
y_offset += y_element_size;
|
||||
}
|
||||
|
||||
void settings_panel_init(lv_obj_t* panel){
|
||||
y_offset = 0;
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(panel);
|
||||
lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Restart");
|
||||
lv_obj_center(label);
|
||||
|
||||
create_settings_widget("Configure WiFi", btn, panel);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_add_event_cb(btn, reset_calibration_click, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Restart");
|
||||
lv_obj_center(label);
|
||||
|
||||
create_settings_widget("Calibrate Touch", btn, panel);
|
||||
|
||||
lv_obj_t * toggle = lv_switch_create(panel);
|
||||
lv_obj_add_event_cb(toggle, invert_color_switch, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
if (global_config.invertColors)
|
||||
lv_obj_add_state(toggle, LV_STATE_CHECKED);
|
||||
|
||||
create_settings_widget("Invert Colors", toggle, panel);
|
||||
|
||||
|
||||
toggle = lv_switch_create(panel);
|
||||
lv_obj_add_event_cb(toggle, light_mode_switch, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
if (global_config.lightMode)
|
||||
lv_obj_add_state(toggle, LV_STATE_CHECKED);
|
||||
|
||||
create_settings_widget("Light Mode", toggle, panel);
|
||||
|
||||
lv_obj_t * dropdown = lv_dropdown_create(panel);
|
||||
lv_dropdown_set_options(dropdown, "Blue\nGreen\nGrey\nYellow\nOrange\nRed\nPurple");
|
||||
lv_dropdown_set_selected(dropdown, global_config.color_scheme);
|
||||
lv_obj_add_event_cb(dropdown, theme_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
create_settings_widget("Theme", dropdown, panel);
|
||||
|
||||
dropdown = lv_dropdown_create(panel);
|
||||
lv_dropdown_set_options(dropdown, brightness_options);
|
||||
lv_obj_add_event_cb(dropdown, brightness_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
for (int i = 0; i < SIZEOF(brightness_options_values); i++){
|
||||
if (brightness_options_values[i] == global_config.brightness){
|
||||
lv_dropdown_set_selected(dropdown, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_settings_widget("Brightness", dropdown, panel);
|
||||
|
||||
dropdown = lv_dropdown_create(panel);
|
||||
lv_dropdown_set_options(dropdown, wake_timeout_options);
|
||||
lv_obj_add_event_cb(dropdown, wake_timeout_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){
|
||||
if (wake_timeout_options_values[i] == global_config.screenTimeout){
|
||||
lv_dropdown_set_selected(dropdown, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_settings_widget("Wake Timeout", dropdown, panel);
|
||||
|
||||
toggle = lv_switch_create(panel);
|
||||
lv_obj_add_event_cb(toggle, rotate_screen_switch, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
if (global_config.rotateScreen)
|
||||
lv_obj_add_state(toggle, LV_STATE_CHECKED);
|
||||
|
||||
create_settings_widget("Rotate Screen", toggle, panel);
|
||||
|
||||
toggle = lv_switch_create(panel);
|
||||
lv_obj_add_event_cb(toggle, on_during_print_switch, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
if (global_config.onDuringPrint)
|
||||
lv_obj_add_state(toggle, LV_STATE_CHECKED);
|
||||
|
||||
create_settings_widget("Screen On During Print", toggle, panel);
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "panel.h"
|
||||
#include "../../core/data_setup.h"
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
// False: Hotend, True: Bed
|
||||
static bool hotend_or_bed = true;
|
||||
static char hotend_buff[40];
|
||||
static char bed_buff[40];
|
||||
|
||||
static void update_printer_data_hotend_temp(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
sprintf(hotend_buff, "Hotend: %.0f C\nTarget: %.0f C", printer.extruder_temp, printer.extruder_target_temp);
|
||||
lv_label_set_text(label, hotend_buff);
|
||||
}
|
||||
|
||||
static void update_printer_data_bed_temp(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
sprintf(bed_buff, "Bed: %.0f C\nTarget: %.0f C", printer.bed_temp, printer.bed_target_temp);
|
||||
lv_label_set_text(label, bed_buff);
|
||||
}
|
||||
|
||||
static void keyboard_callback(lv_event_t * e){
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
|
||||
if (code == LV_EVENT_READY) {
|
||||
const char * text = lv_textarea_get_text(ta);
|
||||
|
||||
int temp = atoi(text);
|
||||
if (temp < 0 || temp > 500){
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("%d %s %d\n", hotend_or_bed, text, temp);
|
||||
char gcode[64];
|
||||
const char* space = "%20";
|
||||
|
||||
if (hotend_or_bed){
|
||||
sprintf(gcode, "M140%sS%d", space, temp);
|
||||
} else {
|
||||
sprintf(gcode, "M104%sS%d", space, temp);
|
||||
}
|
||||
|
||||
send_gcode(true, gcode);
|
||||
}
|
||||
|
||||
if(code == LV_EVENT_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY) {
|
||||
lv_keyboard_set_textarea(kb, NULL);
|
||||
lv_obj_del(kb);
|
||||
lv_obj_del(ta);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_keyboard(lv_event_t * e){
|
||||
lv_obj_t * panel = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
lv_obj_t * keyboard = lv_keyboard_create(panel);
|
||||
lv_obj_t * ta = lv_textarea_create(panel);
|
||||
lv_obj_set_size(ta, 100, 30);
|
||||
lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 40);
|
||||
lv_textarea_set_max_length(ta, 3);
|
||||
lv_textarea_set_one_line(ta, true);
|
||||
lv_textarea_set_text(ta, "");
|
||||
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_ALL, keyboard);
|
||||
|
||||
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
|
||||
lv_keyboard_set_textarea(keyboard, ta);
|
||||
}
|
||||
|
||||
static void show_keyboard_with_hotend(lv_event_t * e){
|
||||
hotend_or_bed = false;
|
||||
show_keyboard(e);
|
||||
}
|
||||
|
||||
static void show_keyboard_with_bed(lv_event_t * e){
|
||||
hotend_or_bed = true;
|
||||
show_keyboard(e);
|
||||
}
|
||||
|
||||
static void cooldown_temp(lv_event_t * e){
|
||||
if (printer.state == PRINTER_STATE_PRINTING){
|
||||
return;
|
||||
}
|
||||
|
||||
send_gcode(true, "M104%20S0");
|
||||
send_gcode(true, "M140%20S0");
|
||||
}
|
||||
|
||||
static void btn_extrude(lv_event_t * e){
|
||||
if (printer.state == PRINTER_STATE_PRINTING){
|
||||
return;
|
||||
}
|
||||
|
||||
send_gcode(true, "M83");
|
||||
send_gcode(true, "G1%20E25%20F300");
|
||||
}
|
||||
|
||||
static void btn_retract(lv_event_t * e){
|
||||
if (printer.state == PRINTER_STATE_PRINTING){
|
||||
return;
|
||||
}
|
||||
|
||||
send_gcode(true, "M83");
|
||||
send_gcode(true, "G1%20E-25%20F300");
|
||||
}
|
||||
|
||||
void temp_panel_init(lv_obj_t* panel){
|
||||
auto panel_width = TFT_HEIGHT - 40;
|
||||
lv_obj_t * label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "Hotend");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||
lv_obj_add_event_cb(label, update_printer_data_hotend_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "Bed");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 50);
|
||||
lv_obj_add_event_cb(label, update_printer_data_bed_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 10);
|
||||
lv_obj_add_event_cb(btn, show_keyboard_with_hotend, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Set");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 50);
|
||||
lv_obj_add_event_cb(btn, show_keyboard_with_bed, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Set");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 90);
|
||||
lv_obj_add_event_cb(btn, cooldown_temp, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Cooldown");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -5);
|
||||
lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_set_size(btn, panel_width / 2 - 15, 30);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_DOWN " Extrude");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(panel);
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -5);
|
||||
lv_obj_add_event_cb(btn, btn_retract, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_set_size(btn, panel_width / 2 - 15, 30);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_UP " Retract");
|
||||
lv_obj_center(label);
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "wifi_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
|
||||
#include "WiFi.h"
|
||||
void wifi_init_inner();
|
||||
|
||||
static void reset_btn_event_handler(lv_event_t * e) {
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
global_config.wifiConfigured = false;
|
||||
wifi_init_inner();
|
||||
}
|
||||
}
|
||||
|
||||
static void refresh_btn_event_handler(lv_event_t * e){
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
wifi_init_inner();
|
||||
}
|
||||
}
|
||||
|
||||
static void ta_event_cb(lv_event_t * e) {
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
|
||||
if (code == LV_EVENT_READY)
|
||||
{
|
||||
const char * txt = lv_textarea_get_text(ta);
|
||||
int len = strlen(txt);
|
||||
if (len > 0)
|
||||
{
|
||||
global_config.wifiConfigured = true;
|
||||
strcpy(global_config.wifiPassword, txt);
|
||||
WriteGlobalConfig();
|
||||
wifi_init_inner();
|
||||
}
|
||||
}
|
||||
else if (code == LV_EVENT_CANCEL)
|
||||
{
|
||||
wifi_init_inner();
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_pass_entry(const char* ssid){
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Enter WiFi Password");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
|
||||
|
||||
lv_obj_t * passEntry = lv_textarea_create(lv_scr_act());
|
||||
lv_textarea_set_one_line(passEntry, true);
|
||||
lv_textarea_set_text(passEntry, "");
|
||||
lv_obj_align(passEntry, LV_ALIGN_TOP_LEFT, 10, 40);
|
||||
lv_obj_add_event_cb(passEntry, ta_event_cb, LV_EVENT_ALL, NULL);
|
||||
lv_obj_set_size(passEntry, TFT_HEIGHT - 20, 60);
|
||||
|
||||
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
|
||||
lv_keyboard_set_textarea(keyboard, passEntry);
|
||||
}
|
||||
|
||||
static void wifi_btn_event_handler(lv_event_t * e){
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
delay(100);
|
||||
char* ssid = (char*)e->user_data;
|
||||
strcpy(global_config.wifiSSID, ssid);
|
||||
Serial.println(ssid);
|
||||
wifi_pass_entry(ssid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wifi_init_inner(){
|
||||
WiFi.disconnect();
|
||||
|
||||
if (global_config.wifiConfigured){
|
||||
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword);
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Connecting to WiFi");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lv_obj_t * resetBtn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_event_cb(resetBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL);
|
||||
lv_obj_align(resetBtn, LV_ALIGN_CENTER, 0, 40);
|
||||
|
||||
label = lv_label_create(resetBtn);
|
||||
lv_label_set_text(label, "Reset");
|
||||
lv_obj_center(label);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Scanning for networks...");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
lv_refr_now(NULL);
|
||||
|
||||
int n = WiFi.scanNetworks();
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * refreshBtn = lv_btn_create(lv_scr_act());
|
||||
lv_obj_add_event_cb(refreshBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL);
|
||||
lv_obj_align(refreshBtn, LV_ALIGN_TOP_RIGHT, -5, 5 - 1);
|
||||
|
||||
label = lv_label_create(refreshBtn);
|
||||
lv_label_set_text(label, LV_SYMBOL_REFRESH);
|
||||
lv_obj_center(label);
|
||||
|
||||
label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Select a network");
|
||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
|
||||
|
||||
lv_obj_t * list = lv_list_create(lv_scr_act());
|
||||
lv_obj_align(list, LV_ALIGN_TOP_LEFT, 10, 40);
|
||||
lv_obj_set_size(list, TFT_HEIGHT - 20, TFT_WIDTH - 40 - 5);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const char* ssid = WiFi.SSID(i).c_str();
|
||||
int len = strlen(ssid);
|
||||
|
||||
if (len == 0)
|
||||
continue;
|
||||
|
||||
const char* ssid_copy = (const char*)malloc(len + 1);
|
||||
strcpy((char*)ssid_copy, ssid);
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy);
|
||||
lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_ALL, (void*)ssid_copy);
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_init(){
|
||||
WiFi.mode(WIFI_STA);
|
||||
wifi_init_inner();
|
||||
|
||||
while (!global_config.wifiConfigured || WiFi.status() != WL_CONNECTED){
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_ok(){
|
||||
if (WiFi.status() != WL_CONNECTED){
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
54
CYD-Klipper/.vscode/settings.json
vendored
Normal file
54
CYD-Klipper/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"string_view": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"functional": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cmath": "cpp",
|
||||
"system_error": "cpp",
|
||||
"random": "cpp",
|
||||
"optional": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"atomic": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"exception": "cpp",
|
||||
"iterator": "cpp",
|
||||
"map": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"tuple": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
},
|
||||
"cmake.configureOnOpen": false
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(CYD-Klipper-Display)
|
||||
project(CYD-Klipper)
|
||||
3
CYD-Klipper/boards/README.md
Normal file
3
CYD-Klipper/boards/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Boards
|
||||
|
||||
Contains specialised CYD definitions from [platformio-espressif32-sunton](https://github.com/rzeldent/platformio-espressif32-sunton)
|
||||
126
CYD-Klipper/boards/esp32-2432S022C-smartdisplay.json
Normal file
126
CYD-Klipper/boards/esp32-2432S022C-smartdisplay.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S022C'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=0'",
|
||||
"'-D LCD_ST7789_I80'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DC=16'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_WR=4'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D8=15'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D9=13'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D10=12'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D11=14'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D12=27'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D13=25'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D14=33'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D15=32'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_BUS_WIDTH=8'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_MAX_TRANSFER_BYTES=(LVGL_BUFFER_PIXELS * sizeof(lv_color_t))'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
|
||||
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=12000000'",
|
||||
"'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_IDLE_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_CMD_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DUMMY_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DATA_LEVEL=1'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_CS_ACTIVE_HIGH=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_REVERSE_COLOR_BITS=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_SWAP_COLOR_BYTES=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'",
|
||||
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
|
||||
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D ST7789_RD_GPIO=2'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=false'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_CST816S_I2C'",
|
||||
"'-D CST816S_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
|
||||
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S022C",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005006284154750.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
127
CYD-Klipper/boards/esp32-2432S022C-vertical.json
Normal file
127
CYD-Klipper/boards/esp32-2432S022C-vertical.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S022C'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=0'",
|
||||
"'-D LCD_ST7789_I80'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DC=16'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_WR=4'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D8=15'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D9=13'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D10=12'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D11=14'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D12=27'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D13=25'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D14=33'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D15=32'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_BUS_WIDTH=8'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_MAX_TRANSFER_BYTES=(LVGL_BUFFER_PIXELS * sizeof(lv_color_t))'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
|
||||
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=12000000'",
|
||||
"'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_IDLE_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_CMD_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DUMMY_LEVEL=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DATA_LEVEL=1'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_CS_ACTIVE_HIGH=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_REVERSE_COLOR_BITS=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_SWAP_COLOR_BYTES=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
|
||||
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'",
|
||||
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
|
||||
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D ST7789_RD_GPIO=2'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=false'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_CST816S_I2C'",
|
||||
"'-D CST816S_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=false'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_VERTICAL=1",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
|
||||
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S022C-V",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005006284154750.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
122
CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json
Normal file
122
CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S024C'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=27'",
|
||||
"'-D LCD_ILI9341_SPI'",
|
||||
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
|
||||
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ILI9341_SPI_BUS_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
|
||||
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=true'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_CST816S_I2C'",
|
||||
"'-D CST816S_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=33'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=32'",
|
||||
"'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
|
||||
"'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=25'",
|
||||
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=21'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S024C-SD",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005005865107357.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
63
CYD-Klipper/boards/esp32-2432S028R.json
Normal file
63
CYD-Klipper/boards/esp32-2432S028R.json
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DUSER_SETUP_LOADED=1",
|
||||
"-DILI9341_2_DRIVER=1",
|
||||
"-DTFT_BACKLIGHT_ON=HIGH",
|
||||
"-DTFT_BL=21",
|
||||
"-DTFT_MISO=12",
|
||||
"-DTFT_MOSI=13",
|
||||
"-DTFT_SCLK=14",
|
||||
"-DTFT_CS=15",
|
||||
"-DTFT_DC=2",
|
||||
"-DTFT_RST=-1",
|
||||
"-DLOAD_GCLD=1",
|
||||
"-DSPI_FREQUENCY=55000000",
|
||||
"-DSPI_READ_FREQUENCY=20000000",
|
||||
"-DSPI_TOUCH_FREQUENCY=2500000",
|
||||
"-DTOUCH_CS=-1",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=240",
|
||||
"-DCYD_SCREEN_WIDTH_PX=320",
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_2432S028R=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S028R",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004502250619.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
125
CYD-Klipper/boards/esp32-2432S028RV1-smartdisplay.json
Normal file
125
CYD-Klipper/boards/esp32-2432S028RV1-smartdisplay.json
Normal file
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S028R'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=21'",
|
||||
"'-D LCD_ILI9341_SPI'",
|
||||
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
|
||||
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ILI9341_SPI_BUS_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
|
||||
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=true'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_XPT2046_SPI'",
|
||||
"'-D XPT2046_SPI_HOST=SPI3_HOST'",
|
||||
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'",
|
||||
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'",
|
||||
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'",
|
||||
"'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'",
|
||||
"'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
|
||||
"'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=true'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S028Rv1-SD",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004502250619.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
125
CYD-Klipper/boards/esp32-2432S028RV2-smartdisplay.json
Normal file
125
CYD-Klipper/boards/esp32-2432S028RV2-smartdisplay.json
Normal file
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S028Rv2'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=21'",
|
||||
"'-D LCD_ILI9341_SPI'",
|
||||
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
|
||||
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ILI9341_SPI_BUS_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
|
||||
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=true'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_XPT2046_SPI'",
|
||||
"'-D XPT2046_SPI_HOST=SPI3_HOST'",
|
||||
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'",
|
||||
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'",
|
||||
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'",
|
||||
"'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'",
|
||||
"'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
|
||||
"'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=true'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S028Rv2-SD",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004502250619.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
125
CYD-Klipper/boards/esp32-2432S028RV3-smartdisplay.json
Normal file
125
CYD-Klipper/boards/esp32-2432S028RV3-smartdisplay.json
Normal file
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S028Rv3'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=21'",
|
||||
"'-D LCD_ST7789_SPI'",
|
||||
"'-D ST7789_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ST7789_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ST7789_SPI_BUS_MISO_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ST7789_SPI_BUS_FLAGS=0'",
|
||||
"'-D ST7789_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'",
|
||||
"'-D ST7789_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
|
||||
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=false'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_XPT2046_SPI'",
|
||||
"'-D XPT2046_SPI_HOST=SPI3_HOST'",
|
||||
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'",
|
||||
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'",
|
||||
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'",
|
||||
"'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'",
|
||||
"'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
|
||||
"'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=true'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S028Rv3-SD",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004502250619.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
125
CYD-Klipper/boards/esp32-2432S032C-smartdisplay.json
Normal file
125
CYD-Klipper/boards/esp32-2432S032C-smartdisplay.json
Normal file
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_2432S032C'",
|
||||
"'-D LCD_WIDTH=240'",
|
||||
"'-D LCD_HEIGHT=320'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=27'",
|
||||
"'-D LCD_IPS'",
|
||||
"'-D LCD_ST7789_SPI'",
|
||||
"'-D ST7789_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ST7789_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ST7789_SPI_BUS_MISO_IO_NUM=12'",
|
||||
"'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ST7789_SPI_BUS_FLAGS=0'",
|
||||
"'-D ST7789_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'",
|
||||
"'-D ST7789_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ST7789_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
|
||||
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=false'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_GT911_I2C'",
|
||||
"'-D GT911_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
|
||||
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=25'",
|
||||
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=21'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=240",
|
||||
"-DCYD_SCREEN_WIDTH_PX=320",
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-2432S032C-SD",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005006224494145.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
122
CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json
Normal file
122
CYD-Klipper/boards/esp32-3248S035C-smartdisplay.json
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32_DEV'",
|
||||
"'-D ESP32_3248S035C'",
|
||||
"'-D LCD_WIDTH=320'",
|
||||
"'-D LCD_HEIGHT=480'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=27'",
|
||||
"'-D LCD_ST7796_SPI'",
|
||||
"'-D ST7796_SPI_HOST=SPI2_HOST'",
|
||||
"'-D ST7796_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D ST7796_SPI_BUS_MOSI_IO_NUM=13'",
|
||||
"'-D ST7796_SPI_BUS_MISO_IO_NUM=12'",
|
||||
"'-D ST7796_SPI_BUS_SCLK_IO_NUM=14'",
|
||||
"'-D ST7796_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7796_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7796_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
|
||||
"'-D ST7796_SPI_BUS_FLAGS=0'",
|
||||
"'-D ST7796_SPI_BUS_INTR_FLAGS=0'",
|
||||
"'-D ST7796_SPI_CONFIG_CS_GPIO_NUM=15'",
|
||||
"'-D ST7796_SPI_CONFIG_DC_GPIO_NUM=2'",
|
||||
"'-D ST7796_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D ST7796_SPI_CONFIG_PCLK_HZ=24000000'",
|
||||
"'-D ST7796_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
|
||||
"'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D ST7796_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D ST7796_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D ST7796_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D ST7796_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D ST7796_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7796_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
|
||||
"'-D ST7796_DEV_CONFIG_BITS_PER_PIXEL=16'",
|
||||
"'-D ST7796_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
|
||||
"'-D ST7796_DEV_CONFIG_VENDOR_CONFIG=NULL'",
|
||||
"'-D LCD_SWAP_XY=false'",
|
||||
"'-D LCD_MIRROR_X=true'",
|
||||
"'-D LCD_MIRROR_Y=false'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_GT911_I2C'",
|
||||
"'-D GT911_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
|
||||
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=25'",
|
||||
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=21'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=true'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=5'",
|
||||
"'-D TF_SPI_MOSI=23'",
|
||||
"'-D TF_SPI_SCLK=18'",
|
||||
"'-D TF_SPI_MISO=19'",
|
||||
"'-D BOARD_HAS_RGB_LED'",
|
||||
"'-D RGB_LED_R=4'",
|
||||
"'-D RGB_LED_G=16'",
|
||||
"'-D RGB_LED_B=17'",
|
||||
"'-D BOARD_HAS_CDS'",
|
||||
"'-D CDS=34'",
|
||||
"'-D BOARD_HAS_SPEAK'",
|
||||
"'-D SPEAK=26'",
|
||||
|
||||
"-DCYD_SCREEN_GAP_PX=10",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-3248S035C",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004632953455.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
66
CYD-Klipper/boards/esp32-3248S035C-vertical.json
Normal file
66
CYD-Klipper/boards/esp32-3248S035C-vertical.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DUSER_SETUP_LOADED=1",
|
||||
"-DST7796_DRIVER=1",
|
||||
"-DTFT_BL=27",
|
||||
"-DTFT_BACKLIGHT_ON=HIGH",
|
||||
"-DTFT_MISO=12",
|
||||
"-DTFT_MOSI=13",
|
||||
"-DTFT_SCLK=14",
|
||||
"-DTFT_CS=15",
|
||||
"-DTFT_DC=2",
|
||||
"-DTFT_RST=-1",
|
||||
"-DLOAD_GCLD=1",
|
||||
"-DSPI_FREQUENCY=80000000",
|
||||
"-DSPI_READ_FREQUENCY=20000000",
|
||||
"-DSPI_TOUCH_FREQUENCY=2500000",
|
||||
"-DTOUCH_CS=-1",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=480",
|
||||
"-DCYD_SCREEN_WIDTH_PX=320",
|
||||
"-DCYD_SCREEN_GAP_PX=10",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_3248S035C=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
|
||||
"-DCYD_SCREEN_VERTICAL=1",
|
||||
"-DCYD_SCREEN_NO_TEMP_SCROLL=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-3248S035C-V",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004632953455.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
64
CYD-Klipper/boards/esp32-3248S035C.json
Normal file
64
CYD-Klipper/boards/esp32-3248S035C.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DUSER_SETUP_LOADED=1",
|
||||
"-DST7796_DRIVER=1",
|
||||
"-DTFT_BL=27",
|
||||
"-DTFT_BACKLIGHT_ON=HIGH",
|
||||
"-DTFT_MISO=12",
|
||||
"-DTFT_MOSI=13",
|
||||
"-DTFT_SCLK=14",
|
||||
"-DTFT_CS=15",
|
||||
"-DTFT_DC=2",
|
||||
"-DTFT_RST=-1",
|
||||
"-DLOAD_GCLD=1",
|
||||
"-DSPI_FREQUENCY=80000000",
|
||||
"-DSPI_READ_FREQUENCY=20000000",
|
||||
"-DSPI_TOUCH_FREQUENCY=2500000",
|
||||
"-DTOUCH_CS=-1",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=320",
|
||||
"-DCYD_SCREEN_WIDTH_PX=480",
|
||||
"-DCYD_SCREEN_GAP_PX=10",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_3248S035C=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-3248S035C",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004632953455.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
143
CYD-Klipper/boards/esp32-4827S043C-smartdisplay.json
Normal file
143
CYD-Klipper/boards/esp32-4827S043C-smartdisplay.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32S3_DEV'",
|
||||
"'-D BOARD_HAS_PSRAM'",
|
||||
"'-D ARDUINO_USB_MODE=1'",
|
||||
"'-D ARDUINO_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
|
||||
"'-D ESP32_4827S043C'",
|
||||
"'-D LCD_WIDTH=480'",
|
||||
"'-D LCD_HEIGHT=272'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=2'",
|
||||
"'-D LCD_ST7262_PAR'",
|
||||
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(8*1000000)'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=43'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=12'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
|
||||
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
|
||||
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
|
||||
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
|
||||
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_GT911_I2C'",
|
||||
"'-D GT911_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
|
||||
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
|
||||
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=false'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=10'",
|
||||
"'-D TF_SPI_MOSI=11'",
|
||||
"'-D TF_SPI_SCLK=12'",
|
||||
"'-D TF_SPI_MISO=13'",
|
||||
|
||||
"'-DCYD_SCREEN_HEIGHT_PX=272'",
|
||||
"'-DCYD_SCREEN_WIDTH_PX=480'",
|
||||
"-DROTATION_INVERTED=LV_DISP_ROT_180",
|
||||
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
|
||||
"'-DCYD_SCREEN_GAP_PX=10'",
|
||||
"'-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35'",
|
||||
"'-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40'",
|
||||
"'-DCYD_SCREEN_FONT=lv_font_montserrat_16'",
|
||||
"'-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12'",
|
||||
"'-DCYD_SCREEN_SIDEBAR_SIZE_PX=50'",
|
||||
"'-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1'",
|
||||
"'-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1'"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-4827S043C-SD",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004788147691.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
146
CYD-Klipper/boards/esp32-4827S043R-smartdisplay.json
Normal file
146
CYD-Klipper/boards/esp32-4827S043R-smartdisplay.json
Normal file
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32S3_DEV'",
|
||||
"'-D BOARD_HAS_PSRAM'",
|
||||
"'-D ARDUINO_USB_MODE=1'",
|
||||
"'-D ARDUINO_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
|
||||
"'-D ESP32_4827S043R'",
|
||||
"'-D LCD_WIDTH=480'",
|
||||
"'-D LCD_HEIGHT=272'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=2'",
|
||||
"'-D LCD_ST7262_PAR'",
|
||||
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(8*1000000)'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=43'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=12'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
|
||||
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
|
||||
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
|
||||
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
|
||||
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_XPT2046_SPI'",
|
||||
"'-D XPT2046_SPI_HOST=SPI2_HOST'",
|
||||
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
|
||||
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=11'",
|
||||
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=13'",
|
||||
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=12'",
|
||||
"'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=38'",
|
||||
"'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
|
||||
"'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
|
||||
"'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
|
||||
"'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=18'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=false'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=10'",
|
||||
"'-D TF_SPI_MOSI=11'",
|
||||
"'-D TF_SPI_SCLK=12'",
|
||||
"'-D TF_SPI_MISO=13'",
|
||||
|
||||
"'-DCYD_SCREEN_HEIGHT_PX=272'",
|
||||
"'-DCYD_SCREEN_WIDTH_PX=480'",
|
||||
"-DROTATION_INVERTED=LV_DISP_ROT_180",
|
||||
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
|
||||
"'-DCYD_SCREEN_GAP_PX=10'",
|
||||
"'-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35'",
|
||||
"'-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40'",
|
||||
"'-DCYD_SCREEN_FONT=lv_font_montserrat_16'",
|
||||
"'-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12'",
|
||||
"'-DCYD_SCREEN_SIDEBAR_SIZE_PX=50'",
|
||||
"'-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1'"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-4827S043R-SD",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004788147691.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
143
CYD-Klipper/boards/esp32-8048S043C-smartdisplay-alt.json
Normal file
143
CYD-Klipper/boards/esp32-8048S043C-smartdisplay-alt.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32S3_DEV'",
|
||||
"'-D BOARD_HAS_PSRAM'",
|
||||
"'-D ARDUINO_USB_MODE=1'",
|
||||
"'-D ARDUINO_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
|
||||
"'-D ESP32_8048S043C'",
|
||||
"'-D LCD_WIDTH=800'",
|
||||
"'-D LCD_HEIGHT=480'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=2'",
|
||||
"'-D LCD_ST7262_PAR'",
|
||||
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=14000000'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
|
||||
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
|
||||
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
|
||||
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
|
||||
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_GT911_I2C'",
|
||||
"'-D GT911_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
|
||||
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
|
||||
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=false'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=10'",
|
||||
"'-D TF_SPI_MOSI=11'",
|
||||
"'-D TF_SPI_SCLK=12'",
|
||||
"'-D TF_SPI_MISO=13'",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=480",
|
||||
"-DCYD_SCREEN_WIDTH_PX=800",
|
||||
"-DROTATION_INVERTED=LV_DISP_ROT_180",
|
||||
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
|
||||
"-DCYD_SCREEN_GAP_PX=15",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=60",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=60",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_22",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=70",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-8048S043C-SD-alt",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005006110360174.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
143
CYD-Klipper/boards/esp32-8048S043C-smartdisplay.json
Normal file
143
CYD-Klipper/boards/esp32-8048S043C-smartdisplay.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"'-D ARDUINO_ESP32S3_DEV'",
|
||||
"'-D BOARD_HAS_PSRAM'",
|
||||
"'-D ARDUINO_USB_MODE=1'",
|
||||
"'-D ARDUINO_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
|
||||
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
|
||||
"'-D ESP32_8048S043C'",
|
||||
"'-D LCD_WIDTH=800'",
|
||||
"'-D LCD_HEIGHT=480'",
|
||||
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
|
||||
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
|
||||
"'-D GPIO_BCKL=2'",
|
||||
"'-D LCD_ST7262_PAR'",
|
||||
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(12.5*1000000)'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
|
||||
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
|
||||
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
|
||||
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
|
||||
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
|
||||
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
|
||||
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
|
||||
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
|
||||
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
|
||||
"'-D BOARD_HAS_TOUCH'",
|
||||
"'-D TOUCH_GT911_I2C'",
|
||||
"'-D GT911_I2C_HOST=I2C_NUM_0'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
|
||||
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
|
||||
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
|
||||
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
|
||||
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
|
||||
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
|
||||
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
|
||||
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
|
||||
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
|
||||
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
|
||||
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
|
||||
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
|
||||
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
|
||||
"'-D TOUCH_SWAP_XY=false'",
|
||||
"'-D TOUCH_SWAP_X=false'",
|
||||
"'-D TOUCH_SWAP_Y=false'",
|
||||
"'-D BOARD_HAS_TF'",
|
||||
"'-D TF_CS=10'",
|
||||
"'-D TF_SPI_MOSI=11'",
|
||||
"'-D TF_SPI_SCLK=12'",
|
||||
"'-D TF_SPI_MISO=13'",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=480",
|
||||
"-DCYD_SCREEN_WIDTH_PX=800",
|
||||
"-DROTATION_INVERTED=LV_DISP_ROT_180",
|
||||
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
|
||||
"-DCYD_SCREEN_GAP_PX=15",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=60",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=60",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_22",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=70",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-8048S043C-SD",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005006110360174.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
63
CYD-Klipper/boards/esp32-CROWPANEL-28R.json
Normal file
63
CYD-Klipper/boards/esp32-CROWPANEL-28R.json
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DUSER_SETUP_LOADED=1",
|
||||
"-DILI9341_2_DRIVER=1",
|
||||
"-DTFT_BACKLIGHT_ON=HIGH",
|
||||
"-DTFT_BL=27",
|
||||
"-DTFT_MISO=12",
|
||||
"-DTFT_MOSI=13",
|
||||
"-DTFT_SCLK=14",
|
||||
"-DTFT_CS=15",
|
||||
"-DTFT_DC=2",
|
||||
"-DTFT_RST=-1",
|
||||
"-DLOAD_GCLD=1",
|
||||
"-DSPI_FREQUENCY=15999999",
|
||||
"-DSPI_READ_FREQUENCY=20000000",
|
||||
"-DSPI_TOUCH_FREQUENCY=600000",
|
||||
"-DTOUCH_CS=33",
|
||||
|
||||
"-DCYD_SCREEN_HEIGHT_PX=240",
|
||||
"-DCYD_SCREEN_WIDTH_PX=320",
|
||||
"-DCYD_SCREEN_GAP_PX=8",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_CROWPANEL_28R=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "esp32"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_board": "esp-wroom-32.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-crowpanel-28R",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.aliexpress.com/item/1005004502250619.html",
|
||||
"vendor": "Sunton"
|
||||
}
|
||||
55
CYD-Klipper/boards/esp32-CROWPANEL-35C.json
Normal file
55
CYD-Klipper/boards/esp32-CROWPANEL-35C.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DCYD_SCREEN_HEIGHT_PX=320",
|
||||
"-DCYD_SCREEN_WIDTH_PX=480",
|
||||
"-DCYD_SCREEN_GAP_PX=10",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
|
||||
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
|
||||
"-DCYD_SCREEN_FONT=lv_font_montserrat_16",
|
||||
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
|
||||
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
|
||||
"-DCYD_SCREEN_DRIVER_ESP32_CROWPANEL_35C=1",
|
||||
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
[
|
||||
"0x303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "esp32-8048S043C-SD",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.elecrow.com/esp-terminal-with-esp32-3-5-inch-parallel-480x320-tft-capacitive-touch-display-rgb-by-chip-ili9488.html",
|
||||
"vendor": "CROWPANEL"
|
||||
}
|
||||
31
CYD-Klipper/extract_commit.py
Normal file
31
CYD-Klipper/extract_commit.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import subprocess
|
||||
|
||||
def extract_commit() -> str:
|
||||
git_describe_output = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True, check=True).stdout.strip()
|
||||
split_output = git_describe_output.split("-")
|
||||
|
||||
if (len(split_output) >= 3):
|
||||
return f"{split_output[0]}\\ ({split_output[2][1:]})"
|
||||
else:
|
||||
return split_output[0]
|
||||
|
||||
try:
|
||||
version = extract_commit()
|
||||
except:
|
||||
version = "Unknown"
|
||||
|
||||
flag = "-D REPO_VERSION=\\\"" + version + "\\\""
|
||||
dev_flag = "-DREPO_DEVELOPMENT=1"
|
||||
print(f"Version: {version}")
|
||||
print(f"Flag: {flag}")
|
||||
|
||||
flags = [flag]
|
||||
|
||||
if ('(' in version):
|
||||
flags.append(dev_flag)
|
||||
|
||||
Import("env")
|
||||
|
||||
env.Append(
|
||||
BUILD_FLAGS=flags
|
||||
)
|
||||
119
CYD-Klipper/platformio.ini
Normal file
119
CYD-Klipper/platformio.ini
Normal file
@@ -0,0 +1,119 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env]
|
||||
platform = espressif32@6.4.0
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
debug_build_flags = -Os
|
||||
lib_deps =
|
||||
https://github.com/suchmememanyskill/esp32-smartdisplay#9c1d737
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
monitor_filters = esp32_exception_decoder
|
||||
build_flags =
|
||||
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
|
||||
extra_scripts =
|
||||
pre:extract_commit.py
|
||||
|
||||
[env:esp32-2432S028R]
|
||||
board = esp32-2432S028R
|
||||
lib_deps =
|
||||
SPI
|
||||
https://github.com/suchmememanyskill/lvgl
|
||||
https://github.com/Bodmer/TFT_eSPI.git
|
||||
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
|
||||
[env:esp32-3248S035C]
|
||||
board = esp32-3248S035C
|
||||
lib_deps =
|
||||
SPI
|
||||
https://github.com/suchmememanyskill/lvgl
|
||||
https://github.com/Bodmer/TFT_eSPI.git
|
||||
https://github.com/OperatorB/gt911-arduino-fixed-reset.git
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
|
||||
[env:esp32-3248S035C-V]
|
||||
board = esp32-3248S035C-vertical
|
||||
lib_deps =
|
||||
SPI
|
||||
https://github.com/suchmememanyskill/lvgl
|
||||
https://github.com/Bodmer/TFT_eSPI.git
|
||||
https://github.com/OperatorB/gt911-arduino-fixed-reset.git
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
|
||||
[env:esp32-2432S024C-SD]
|
||||
board = esp32-2432S024C-smartdisplay
|
||||
|
||||
[env:esp32-2432S028Rv1-SD]
|
||||
board = esp32-2432S028RV1-smartdisplay
|
||||
|
||||
[env:esp32-2432S028Rv2-SD]
|
||||
board = esp32-2432S028RV2-smartdisplay
|
||||
|
||||
[env:esp32-2432S028Rv3-SD]
|
||||
board = esp32-2432S028RV3-smartdisplay
|
||||
|
||||
[env:esp32-2432S032C-SD]
|
||||
board = esp32-2432S032C-smartdisplay
|
||||
|
||||
[env:esp32-3248S035C-SD]
|
||||
board = esp32-3248S035C-smartdisplay
|
||||
|
||||
[env:esp32-4827S043C-SD]
|
||||
board = esp32-4827S043C-smartdisplay
|
||||
|
||||
[env:esp32-4827S043R-SD]
|
||||
board = esp32-4827S043R-smartdisplay
|
||||
|
||||
[env:esp32-8048S043C-SD]
|
||||
board = esp32-8048S043C-smartdisplay
|
||||
|
||||
[env:esp32-8048S043C-SD-alt]
|
||||
board = esp32-8048S043C-smartdisplay-alt
|
||||
|
||||
[env:esp32-2432S022C-SD-V]
|
||||
board = esp32-2432S022C-vertical
|
||||
|
||||
[env:esp32-CROWPANEL-28R]
|
||||
board = esp32-CROWPANEL-28R
|
||||
lib_deps =
|
||||
SPI
|
||||
https://github.com/suchmememanyskill/lvgl
|
||||
https://github.com/Bodmer/TFT_eSPI.git
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
|
||||
[env:esp32-CROWPANEL-35C]
|
||||
board = esp32-CROWPANEL-35C
|
||||
lib_deps =
|
||||
SPI
|
||||
https://github.com/suchmememanyskill/lvgl
|
||||
https://github.com/lovyan03/LovyanGFX@1.2.0
|
||||
bblanchon/ArduinoJson@^7.0.0
|
||||
plageoj/UrlEncode@^1.0.1
|
||||
knolleary/PubSubClient@^2.8
|
||||
WiFiClientSecure
|
||||
|
||||
205
CYD-Klipper/src/conf/global_config.cpp
Normal file
205
CYD-Klipper/src/conf/global_config.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <Preferences.h>
|
||||
#include "global_config.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
GlobalConfig global_config = {0};
|
||||
TemporaryConfig temporary_config = {0};
|
||||
|
||||
ColorDefinition color_defs[] = {
|
||||
{LV_PALETTE_BLUE, 0, LV_PALETTE_RED},
|
||||
{LV_PALETTE_GREEN, 0, LV_PALETTE_PURPLE},
|
||||
{LV_PALETTE_LIME, -2, LV_PALETTE_PURPLE},
|
||||
{LV_PALETTE_GREY, 0, LV_PALETTE_CYAN},
|
||||
{LV_PALETTE_YELLOW, -2, LV_PALETTE_PINK},
|
||||
{LV_PALETTE_ORANGE, -2, LV_PALETTE_BLUE},
|
||||
{LV_PALETTE_RED, 0, LV_PALETTE_BLUE},
|
||||
{LV_PALETTE_PURPLE, 0, LV_PALETTE_CYAN},
|
||||
};
|
||||
|
||||
void write_global_config()
|
||||
{
|
||||
Preferences preferences;
|
||||
preferences.begin("global_config", false);
|
||||
preferences.putBytes("global_config", &global_config, sizeof(global_config));
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
void verify_version()
|
||||
{
|
||||
Preferences preferences;
|
||||
if (!preferences.begin("global_config", false))
|
||||
return;
|
||||
|
||||
GlobalConfig config = {0};
|
||||
preferences.getBytes("global_config", &config, sizeof(config));
|
||||
LOG_F(("Config version: %d\n", config.version))
|
||||
if (config.version != CONFIG_VERSION) {
|
||||
LOG_LN("Clearing Global Config");
|
||||
preferences.clear();
|
||||
}
|
||||
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
PrinterConfiguration* get_current_printer_config()
|
||||
{
|
||||
return &global_config.printer_config[global_config.printer_index];
|
||||
}
|
||||
|
||||
int global_config_get_printer_config_count()
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
|
||||
if (global_config.printer_config[i].setup_complete)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int get_printer_config_free_index()
|
||||
{
|
||||
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
|
||||
if (!global_config.printer_config[i].setup_complete)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void global_config_add_new_printer()
|
||||
{
|
||||
int free_index = get_printer_config_free_index();
|
||||
if (free_index <= -1)
|
||||
{
|
||||
LOG_LN("No available slot for new printer");
|
||||
return;
|
||||
}
|
||||
|
||||
PrinterConfiguration* old_config = &global_config.printer_config[global_config.printer_index];
|
||||
PrinterConfiguration* new_config = &global_config.printer_config[free_index];
|
||||
|
||||
new_config->raw = old_config->raw;
|
||||
new_config->setup_complete = false;
|
||||
new_config->ip_configured = false;
|
||||
new_config->auth_configured = false;
|
||||
new_config->printer_type = PrinterType::PrinterTypeNone;
|
||||
|
||||
new_config->printer_name[0] = 0;
|
||||
new_config->printer_host[0] = 0;
|
||||
new_config->printer_auth[0] = 0;
|
||||
new_config->klipper_port = 0;
|
||||
|
||||
new_config->color_scheme = old_config->color_scheme;
|
||||
|
||||
// TODO: Replace with memcpy
|
||||
for (int i = 0; i < 3; i++){
|
||||
new_config->hotend_presets[i] = old_config->hotend_presets[i];
|
||||
new_config->bed_presets[i] = old_config->bed_presets[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
new_config->printer_move_x_steps[i] = old_config->printer_move_x_steps[i];
|
||||
new_config->printer_move_y_steps[i] = old_config->printer_move_y_steps[i];
|
||||
new_config->printer_move_z_steps[i] = old_config->printer_move_z_steps[i];
|
||||
}
|
||||
|
||||
global_config_set_printer(free_index);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void global_config_set_printer(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= PRINTER_CONFIG_COUNT || global_config.printer_index == idx)
|
||||
return;
|
||||
|
||||
global_config.printer_index = idx;
|
||||
write_global_config();
|
||||
}
|
||||
|
||||
void global_config_delete_printer(int idx)
|
||||
{
|
||||
if (global_config.printer_index == idx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PrinterConfiguration* config = &global_config.printer_config[idx];
|
||||
config->setup_complete = false;
|
||||
write_global_config();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void set_printer_config_index(int index)
|
||||
{
|
||||
if (index < 0 || index >= PRINTER_CONFIG_COUNT)
|
||||
return;
|
||||
|
||||
PrinterConfiguration* old_config = &global_config.printer_config[global_config.printer_index];
|
||||
PrinterConfiguration* new_config = &global_config.printer_config[index];
|
||||
|
||||
global_config.printer_index = index;
|
||||
|
||||
if (!new_config->ip_configured){
|
||||
new_config->raw = old_config->raw;
|
||||
new_config->ip_configured = false;
|
||||
new_config->auth_configured = false;
|
||||
|
||||
new_config->printer_name[0] = 0;
|
||||
new_config->printer_host[0] = 0;
|
||||
new_config->printer_auth[0] = 0;
|
||||
new_config->klipper_port = 0;
|
||||
|
||||
new_config->color_scheme = old_config->color_scheme;
|
||||
|
||||
// TODO: Replace with memcpy
|
||||
for (int i = 0; i < 3; i++){
|
||||
new_config->hotend_presets[i] = old_config->hotend_presets[i];
|
||||
new_config->bed_presets[i] = old_config->bed_presets[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
new_config->printer_move_x_steps[i] = old_config->printer_move_x_steps[i];
|
||||
new_config->printer_move_y_steps[i] = old_config->printer_move_y_steps[i];
|
||||
new_config->printer_move_z_steps[i] = old_config->printer_move_z_steps[i];
|
||||
}
|
||||
|
||||
write_global_config();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
write_global_config();
|
||||
}
|
||||
|
||||
void load_global_config()
|
||||
{
|
||||
global_config.version = CONFIG_VERSION;
|
||||
global_config.brightness = 255;
|
||||
global_config.screen_timeout = 5;
|
||||
global_config.printer_config[0].hotend_presets[0] = 0;
|
||||
global_config.printer_config[0].hotend_presets[1] = 200;
|
||||
global_config.printer_config[0].hotend_presets[2] = 240;
|
||||
global_config.printer_config[0].bed_presets[0] = 0;
|
||||
global_config.printer_config[0].bed_presets[1] = 60;
|
||||
global_config.printer_config[0].bed_presets[2] = 70;
|
||||
global_config.printer_config[0].printer_move_x_steps[0] = 10;
|
||||
global_config.printer_config[0].printer_move_x_steps[1] = 100;
|
||||
global_config.printer_config[0].printer_move_x_steps[2] = 1000;
|
||||
global_config.printer_config[0].printer_move_y_steps[0] = 10;
|
||||
global_config.printer_config[0].printer_move_y_steps[1] = 100;
|
||||
global_config.printer_config[0].printer_move_y_steps[2] = 1000;
|
||||
global_config.printer_config[0].printer_move_z_steps[0] = 1;
|
||||
global_config.printer_config[0].printer_move_z_steps[1] = 10;
|
||||
global_config.printer_config[0].printer_move_z_steps[2] = 100;
|
||||
|
||||
verify_version();
|
||||
Preferences preferences;
|
||||
preferences.begin("global_config", true);
|
||||
preferences.getBytes("global_config", &global_config, sizeof(global_config));
|
||||
preferences.end();
|
||||
|
||||
#if defined REPO_DEVELOPMENT && REPO_DEVELOPMENT == 1
|
||||
temporary_config.debug = true;
|
||||
#else
|
||||
temporary_config.debug = false;
|
||||
#endif
|
||||
temporary_config.remote_echo = true;
|
||||
}
|
||||
138
CYD-Klipper/src/conf/global_config.h
Normal file
138
CYD-Klipper/src/conf/global_config.h
Normal file
@@ -0,0 +1,138 @@
|
||||
#ifndef _GLOBAL_CONFIG_INIT
|
||||
#define _GLOBAL_CONFIG_INIT
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#define CONFIG_VERSION 7
|
||||
#define PRINTER_CONFIG_COUNT 6
|
||||
#define DISPLAY_SECRETS 0
|
||||
|
||||
enum {
|
||||
REMAINING_TIME_CALC_PERCENTAGE = 0,
|
||||
REMAINING_TIME_CALC_INTERPOLATED = 1,
|
||||
REMAINING_TIME_CALC_SLICER = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
SHOW_STATS_ON_PROGRESS_PANEL_NONE = 0,
|
||||
SHOW_STATS_ON_PROGRESS_PANEL_LAYER = 1,
|
||||
SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL = 2,
|
||||
SHOW_STATS_ON_PROGRESS_PANEL_ALL = 3,
|
||||
};
|
||||
|
||||
enum PrinterType {
|
||||
PrinterTypeNone = 0,
|
||||
PrinterTypeKlipper = 1,
|
||||
PrinterTypeKlipperSerial = 2,
|
||||
PrinterTypeBambuLocal = 3,
|
||||
PrinterTypeBambuCloud = 3,
|
||||
PrinterTypeOctoprint = 4,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
unsigned int raw;
|
||||
struct {
|
||||
// Internal
|
||||
bool setup_complete : 1;
|
||||
bool ip_configured : 1;
|
||||
bool auth_configured : 1;
|
||||
bool custom_filament_move_macros : 1;
|
||||
PrinterType printer_type : 3;
|
||||
|
||||
// External
|
||||
bool light_mode : 1;
|
||||
bool invert_colors : 1;
|
||||
unsigned char remaining_time_calc_mode : 2;
|
||||
unsigned char show_stats_on_progress_panel : 2;
|
||||
};
|
||||
};
|
||||
|
||||
char printer_name[25];
|
||||
char printer_host[65];
|
||||
char printer_auth[65];
|
||||
unsigned int klipper_port;
|
||||
|
||||
unsigned char color_scheme;
|
||||
|
||||
unsigned short hotend_presets[3];
|
||||
unsigned short bed_presets[3];
|
||||
|
||||
unsigned short printer_move_x_steps[3];
|
||||
unsigned short printer_move_y_steps[3];
|
||||
unsigned short printer_move_z_steps[3];
|
||||
} PrinterConfiguration;
|
||||
|
||||
typedef struct {
|
||||
unsigned char version;
|
||||
union {
|
||||
unsigned int raw;
|
||||
struct {
|
||||
// Internal
|
||||
bool screen_calibrated : 1;
|
||||
bool wifi_configured : 1;
|
||||
bool wifi_configuration_skipped : 1;
|
||||
|
||||
// External
|
||||
bool rotate_screen : 1;
|
||||
bool auto_ota_update : 1;
|
||||
bool multi_printer_mode : 1;
|
||||
bool on_during_print : 1;
|
||||
bool display_mode : 1; // Driver specifc usage. Currently only used on ESP32-2432S028R to fix the screen on the usb-c model
|
||||
bool disable_m117_messaging : 1;
|
||||
bool sort_macros : 1;
|
||||
bool show_estop : 1;
|
||||
bool full_filenames : 1;
|
||||
bool double_size_gcode_img : 1;
|
||||
};
|
||||
};
|
||||
|
||||
PrinterConfiguration printer_config[PRINTER_CONFIG_COUNT];
|
||||
|
||||
float screen_cal_x_offset;
|
||||
float screen_cal_x_mult;
|
||||
float screen_cal_y_offset;
|
||||
float screen_cal_y_mult;
|
||||
|
||||
char wifi_SSID[33];
|
||||
char wifi_password[65];
|
||||
|
||||
unsigned char brightness;
|
||||
unsigned char screen_timeout;
|
||||
unsigned char printer_index;
|
||||
} GlobalConfig;
|
||||
|
||||
// Volatile/temporary config that doesn't survive a reset
|
||||
typedef struct {
|
||||
bool debug : 1;
|
||||
bool remote_echo : 1;
|
||||
} TemporaryConfig;
|
||||
|
||||
typedef struct {
|
||||
lv_palette_t primary_color;
|
||||
short primary_color_light;
|
||||
lv_palette_t secondary_color;
|
||||
} ColorDefinition;
|
||||
|
||||
extern GlobalConfig global_config;
|
||||
extern TemporaryConfig temporary_config;
|
||||
extern ColorDefinition color_defs[];
|
||||
|
||||
#define LOG(x) if(temporary_config.debug){ Serial.print(x);}
|
||||
#define LOG_LN(x) if(temporary_config.debug){ Serial.println(x);}
|
||||
#define LOG_F(x) if(temporary_config.debug){ Serial.printf x ;} // use with double braces, LOF_F(("x=%d\n",x));
|
||||
|
||||
void write_global_config();
|
||||
void verify_version();
|
||||
void load_global_config();
|
||||
|
||||
void global_config_add_new_printer();
|
||||
void global_config_set_printer(int idx);
|
||||
void global_config_delete_printer(int idx);
|
||||
|
||||
//PRINTER_CONFIG* get_current_printer_config();
|
||||
int global_config_get_printer_config_count();
|
||||
//void set_printer_config_index(int index);
|
||||
//int get_printer_config_free_index();
|
||||
|
||||
#endif // !_GLOBAL_CONFIG_INIT
|
||||
@@ -49,7 +49,7 @@
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
|
||||
#define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/
|
||||
#define LV_MEM_SIZE (40U * 1024U) /*[bytes]*/
|
||||
|
||||
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
|
||||
#define LV_MEM_ADR 0 /*0: unused*/
|
||||
@@ -194,7 +194,7 @@
|
||||
*-----------*/
|
||||
|
||||
/*Enable the log module*/
|
||||
#define LV_USE_LOG 1
|
||||
#define LV_USE_LOG 0
|
||||
#if LV_USE_LOG
|
||||
|
||||
/*How important log should be added:
|
||||
@@ -204,7 +204,7 @@
|
||||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_USER
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_NONE
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
@@ -242,8 +242,12 @@
|
||||
* Others
|
||||
*-----------*/
|
||||
|
||||
#ifndef REPO_DEVELOPMENT
|
||||
#define REPO_DEVELOPMENT 0
|
||||
#endif
|
||||
|
||||
/*1: Show CPU usage and FPS count*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#define LV_USE_PERF_MONITOR REPO_DEVELOPMENT
|
||||
#if LV_USE_PERF_MONITOR
|
||||
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
|
||||
#endif
|
||||
@@ -327,12 +331,12 @@
|
||||
*https://fonts.google.com/specimen/Montserrat*/
|
||||
#define LV_FONT_MONTSERRAT_8 0
|
||||
#define LV_FONT_MONTSERRAT_10 1
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_12 1
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_16 1
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
#define LV_FONT_MONTSERRAT_22 1
|
||||
#define LV_FONT_MONTSERRAT_24 0
|
||||
#define LV_FONT_MONTSERRAT_26 0
|
||||
#define LV_FONT_MONTSERRAT_28 1
|
||||
@@ -363,7 +367,7 @@
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
#define LV_FONT_DEFAULT &CYD_SCREEN_FONT
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
@@ -497,7 +501,7 @@
|
||||
|
||||
#define LV_USE_MSG 1
|
||||
|
||||
#define LV_USE_CHART 0
|
||||
#define LV_USE_CHART 1
|
||||
|
||||
#define LV_USE_COLORWHEEL 0
|
||||
|
||||
@@ -603,7 +607,7 @@
|
||||
#endif
|
||||
|
||||
/*PNG decoder library*/
|
||||
#define LV_USE_PNG 0
|
||||
#define LV_USE_PNG 1
|
||||
|
||||
/*BMP decoder library*/
|
||||
#define LV_USE_BMP 0
|
||||
@@ -674,16 +678,16 @@
|
||||
====================*/
|
||||
|
||||
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
|
||||
#define LV_USE_DEMO_WIDGETS 1
|
||||
#define LV_USE_DEMO_WIDGETS 0
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
#define LV_DEMO_WIDGETS_SLIDESHOW 1
|
||||
#endif
|
||||
|
||||
/*Demonstrate the usage of encoder and keyboard*/
|
||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 1
|
||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
||||
|
||||
/*Benchmark your system*/
|
||||
#define LV_USE_DEMO_BENCHMARK 1
|
||||
#define LV_USE_DEMO_BENCHMARK 0
|
||||
|
||||
/*Stress test for LVGL*/
|
||||
#define LV_USE_DEMO_STRESS 0
|
||||
371
CYD-Klipper/src/core/bambu/bambu_printer_integration.cpp
Normal file
371
CYD-Klipper/src/core/bambu/bambu_printer_integration.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
#include "bambu_printer_integration.hpp"
|
||||
#include <PubSubClient.h>
|
||||
|
||||
WiFiClientSecure wifi_client;
|
||||
PubSubClient client(wifi_client);
|
||||
BambuPrinter* current_printer = NULL;
|
||||
|
||||
const char* COMMAND_FETCH_ALL = "{\"pushing\":{\"sequence_id\":\"0\",\"command\":\"pushall\",\"version\":1,\"push_target\":1}}";
|
||||
const char* COMMAND_LIGHTCTL = "{\"system\":{\"sequence_id\":\"0\",\"command\":\"ledctrl\",\"led_node\":\"%s\",\"led_mode\":\"%s\"}}";
|
||||
const char* COMMAND_SEND_GCODE = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"gcode_line\",\"param\":\"%s\"}}";
|
||||
const char* COMMAND_PRINT_STOP = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"stop\",\"param\":\"\"}}";
|
||||
const char* COMMAND_PRINT_PAUSE = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"pause\",\"param\":\"\"}}";
|
||||
const char* COMMAND_PRINT_RESUME = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"resume\",\"param\":\"\"}}";
|
||||
const char* COMMAND_FILAMENT_UNLOAD = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"unload_filament\"}}";
|
||||
const char* COMMAND_FILAMENT_LOAD_EXTERNAL = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"ams_change_filament\",\"target\":254,\"curr_temp\":215,\"tar_temp\":250}}";
|
||||
const char* COMMAND_AMS_CONTOL_DONE = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"ams_control\",\"param\":\"done\"}}";
|
||||
const char* COMMAND_AMS_CONTOL_RETRY = "{\"print\":{\"sequence_id\":\"0\",\"command\":\"ams_control\",\"param\":\"resume\"}}";
|
||||
|
||||
static void callback(char* topic, byte* payload, unsigned int length)
|
||||
{
|
||||
if (current_printer != NULL)
|
||||
{
|
||||
current_printer->receive_data(payload, length);
|
||||
}
|
||||
}
|
||||
|
||||
void BambuPrinter::receive_data(unsigned char* data, unsigned int length)
|
||||
{
|
||||
data[length] = 0;
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, data);
|
||||
parse_state(doc);
|
||||
}
|
||||
|
||||
bool BambuPrinter::publish_mqtt_command(const char* command)
|
||||
{
|
||||
if (!client.connected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char auth[48] = {0};
|
||||
sprintf(auth, "device/%s/request", printer_config->printer_auth);
|
||||
|
||||
LOG_F(("Publishing MQTT Command: %s\n", command));
|
||||
return client.publish(auth, command);
|
||||
}
|
||||
|
||||
bool BambuPrinter::move_printer(const char* axis, float amount, bool relative)
|
||||
{
|
||||
if (!printer_data.homed_axis || printer_data.state == PrinterStatePrinting)
|
||||
return false;
|
||||
|
||||
char gcode[64];
|
||||
const char* extra = (amount > 0) ? "+" : "";
|
||||
const char* start = "";
|
||||
const char* end = "";
|
||||
|
||||
if (relative) {
|
||||
start = "G91\n";
|
||||
}
|
||||
else {
|
||||
start = "G90\n";
|
||||
}
|
||||
|
||||
sprintf(gcode, "%sG1 %s%s%.3f F6000", start, axis, extra, amount);
|
||||
send_gcode(gcode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BambuPrinter::execute_feature(PrinterFeatures feature)
|
||||
{
|
||||
switch (feature)
|
||||
{
|
||||
case PrinterFeatureHome:
|
||||
return send_gcode("G28");
|
||||
case PrinterFeatureDisableSteppers:
|
||||
return send_gcode("M18 X Y Z");
|
||||
case PrinterFeaturePause:
|
||||
return publish_mqtt_command(COMMAND_PRINT_PAUSE);
|
||||
case PrinterFeatureResume:
|
||||
return publish_mqtt_command(COMMAND_PRINT_RESUME);
|
||||
case PrinterFeatureStop:
|
||||
return publish_mqtt_command(COMMAND_PRINT_STOP);
|
||||
case PrinterFeatureExtrude:
|
||||
if (printer_data.state == PrinterStatePrinting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return send_gcode("M83\nG1 E25 F300");
|
||||
case PrinterFeatureRetract:
|
||||
if (printer_data.state == PrinterStatePrinting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return send_gcode("M83\nG1 E-25 F300");
|
||||
case PrinterFeatureCooldown:
|
||||
return send_gcode("M104 S0\nM140 S0");
|
||||
case PrinterFeatureContinueError:
|
||||
return publish_mqtt_command(COMMAND_AMS_CONTOL_DONE);
|
||||
case PrinterFeatureRetryError:
|
||||
return publish_mqtt_command(COMMAND_AMS_CONTOL_RETRY);
|
||||
case PrinterFeatureIgnoreError:
|
||||
ignore_error = last_error;
|
||||
publish_mqtt_command(COMMAND_FETCH_ALL);
|
||||
return true;
|
||||
default:
|
||||
LOG_F(("Unsupported printer feature %d", feature));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BambuPrinter::connect()
|
||||
{
|
||||
wifi_client.setInsecure();
|
||||
wifi_client.setTimeout(3);
|
||||
client.setBufferSize(4096);
|
||||
client.setServer(printer_config->printer_host, 8883);
|
||||
current_printer = this;
|
||||
client.setCallback(NULL);
|
||||
char buff[10] = {0};
|
||||
sprintf(buff, "%d", printer_config->klipper_port);
|
||||
if (!client.connect("id", "bblp", buff))
|
||||
{
|
||||
LOG_LN("Bambu: Wrong IP or LAN code.");
|
||||
return false;
|
||||
}
|
||||
|
||||
char auth[48] = {0};
|
||||
sprintf(auth, "device/%s/report", printer_config->printer_auth);
|
||||
|
||||
if (!client.subscribe(auth))
|
||||
{
|
||||
LOG_LN("Bambu: Wrong serial number.");
|
||||
return false;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
client.loop();
|
||||
|
||||
if (!client.connected())
|
||||
{
|
||||
LOG_LN("Bambu: Connection lost. Likely wrong serial number.");
|
||||
return false;
|
||||
}
|
||||
|
||||
client.setCallback(callback);
|
||||
printer_data.state = PrinterState::PrinterStateIdle;
|
||||
return publish_mqtt_command(COMMAND_FETCH_ALL);
|
||||
}
|
||||
|
||||
void BambuPrinter::disconnect()
|
||||
{
|
||||
current_printer = NULL;
|
||||
printer_data.state = PrinterState::PrinterStateOffline;
|
||||
client.disconnect();
|
||||
client.setCallback(NULL);
|
||||
client.setBufferSize(16);
|
||||
}
|
||||
|
||||
bool BambuPrinter::fetch()
|
||||
{
|
||||
if (!client.connected())
|
||||
{
|
||||
LOG_LN("Failed to fetch printer data: Not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!client.loop())
|
||||
{
|
||||
LOG_LN("Failed to fetch printer data: Fetching data failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PrinterDataMinimal BambuPrinter::fetch_min()
|
||||
{
|
||||
PrinterDataMinimal min = {};
|
||||
min.success = true;
|
||||
min.state = PrinterState::PrinterStateIdle;
|
||||
min.print_progress = 0;
|
||||
min.power_devices = 0;
|
||||
return min;
|
||||
}
|
||||
|
||||
const char * MACRO_UNLOAD = "Unload filament";
|
||||
const char * MACRO_LOAD = "Load filament (External)";
|
||||
|
||||
Macros BambuPrinter::get_macros()
|
||||
{
|
||||
Macros macros = {0};
|
||||
macros.success = true;
|
||||
macros.count = get_macros_count();
|
||||
macros.macros = (char **)malloc(sizeof(char *) * macros.count);
|
||||
|
||||
macros.macros[0] = (char *)malloc(25);
|
||||
strcpy(macros.macros[0], MACRO_LOAD);
|
||||
|
||||
macros.macros[1] = (char *)malloc(16);
|
||||
strcpy(macros.macros[1], MACRO_UNLOAD);
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
int BambuPrinter::get_macros_count()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool BambuPrinter::execute_macro(const char* macro)
|
||||
{
|
||||
if (strcmp(macro, MACRO_LOAD) == 0)
|
||||
{
|
||||
return publish_mqtt_command(COMMAND_FILAMENT_LOAD_EXTERNAL);
|
||||
}
|
||||
else if (strcmp(macro, MACRO_UNLOAD) == 0)
|
||||
{
|
||||
return publish_mqtt_command(COMMAND_FILAMENT_UNLOAD);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* WORK_LIGHT = "Work Light";
|
||||
const char* CHAMBER_LIGHT = "Chamber Light";
|
||||
|
||||
PowerDevices BambuPrinter::get_power_devices()
|
||||
{
|
||||
PowerDevices power_devices = {0};
|
||||
power_devices.success = true;
|
||||
int count = get_power_devices_count();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
power_devices.power_devices = (char **)malloc(sizeof(char *) * count);
|
||||
power_devices.power_states = (bool *)malloc(sizeof(bool) * count);
|
||||
|
||||
if (work_light_available)
|
||||
{
|
||||
power_devices.power_devices[power_devices.count] = (char *)malloc(10 + 1);
|
||||
strcpy(power_devices.power_devices[power_devices.count], WORK_LIGHT);
|
||||
power_devices.power_states[power_devices.count] = work_light_on;
|
||||
power_devices.count++;
|
||||
}
|
||||
|
||||
if (chamber_light_available)
|
||||
{
|
||||
power_devices.power_devices[power_devices.count] = (char *)malloc(13 + 1);
|
||||
strcpy(power_devices.power_devices[power_devices.count], CHAMBER_LIGHT);
|
||||
power_devices.power_states[power_devices.count] = chamber_light_on;
|
||||
power_devices.count++;
|
||||
}
|
||||
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
int BambuPrinter::get_power_devices_count()
|
||||
{
|
||||
return (work_light_available ? 1 : 0) + (chamber_light_available ? 1 : 0);
|
||||
}
|
||||
|
||||
bool BambuPrinter::set_power_device_state(const char* device_name, bool state)
|
||||
{
|
||||
char buff[128] = {0};
|
||||
const char* device;
|
||||
|
||||
if (strcmp(device_name, WORK_LIGHT) == 0)
|
||||
{
|
||||
device = "work_light";
|
||||
}
|
||||
else if (strcmp(device_name, CHAMBER_LIGHT) == 0)
|
||||
{
|
||||
device = "chamber_light";
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sprintf(buff, COMMAND_LIGHTCTL, device, state ? "on" : "off");
|
||||
return publish_mqtt_command(buff);
|
||||
}
|
||||
|
||||
Files BambuPrinter::get_files()
|
||||
{
|
||||
PrinterState state = printer_data.state;
|
||||
disconnect();
|
||||
Files files = parse_files(wifi_client, 20);
|
||||
connect();
|
||||
printer_data.state = state;
|
||||
return files;
|
||||
}
|
||||
|
||||
Thumbnail BambuPrinter::get_32_32_png_image_thumbnail(const char* gcode_filename)
|
||||
{
|
||||
Thumbnail thumbnail = {0};
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
bool BambuPrinter::set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature)
|
||||
{
|
||||
char gcode[64] = {0};
|
||||
|
||||
switch (device)
|
||||
{
|
||||
case PrinterTemperatureDeviceBed:
|
||||
sprintf(gcode, "M140 S%d", temperature);
|
||||
break;
|
||||
case PrinterTemperatureDeviceNozzle1:
|
||||
sprintf(gcode, "M104 S%d", temperature);
|
||||
break;
|
||||
default:
|
||||
LOG_F(("Unknown temperature device %d was requested to heat to %.2f", device, temperature));
|
||||
return false;
|
||||
}
|
||||
|
||||
return send_gcode(gcode);
|
||||
}
|
||||
|
||||
bool BambuPrinter::send_gcode(const char* gcode, bool wait)
|
||||
{
|
||||
char* buff = (char *)malloc(strlen(gcode) + 70);
|
||||
sprintf(buff, COMMAND_SEND_GCODE, gcode);
|
||||
return publish_mqtt_command(buff);
|
||||
}
|
||||
|
||||
BambuConnectionStatus connection_test_bambu(PrinterConfiguration* config)
|
||||
{
|
||||
WiFiClientSecure connection_test_wifi_client;
|
||||
PubSubClient connection_test_client(connection_test_wifi_client);
|
||||
connection_test_wifi_client.setInsecure();
|
||||
connection_test_client.setServer(config->printer_host, 8883);
|
||||
char buff[10] = {0};
|
||||
sprintf(buff, "%d", config->klipper_port);
|
||||
if (!connection_test_client.connect("id", "bblp", buff))
|
||||
{
|
||||
LOG_LN("Bambu: Wrong IP or LAN code.");
|
||||
return BambuConnectionStatus::BambuConnectFail;
|
||||
}
|
||||
|
||||
char auth[48] = {0};
|
||||
sprintf(auth, "device/%s/report", config->printer_auth);
|
||||
|
||||
if (!connection_test_client.subscribe(auth))
|
||||
{
|
||||
LOG_LN("Bambu: Wrong serial number.");
|
||||
return BambuConnectionStatus::BambuConnectSNFail;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
connection_test_client.loop();
|
||||
|
||||
if (!connection_test_client.connected())
|
||||
{
|
||||
LOG_LN("Bambu: Connection lost. Likely wrong serial number.");
|
||||
return BambuConnectionStatus::BambuConnectSNFail;
|
||||
}
|
||||
|
||||
connection_test_client.disconnect();
|
||||
LOG_LN("Bambu: Connection test successful!");
|
||||
return BambuConnectionStatus::BambuConnectOk;
|
||||
}
|
||||
97
CYD-Klipper/src/core/bambu/bambu_printer_integration.hpp
Normal file
97
CYD-Klipper/src/core/bambu/bambu_printer_integration.hpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include "../printer_integration.hpp"
|
||||
#include <ArduinoJson.h>
|
||||
#include <WifiClientSecure.h>
|
||||
|
||||
enum BambuSpeedProfile
|
||||
{
|
||||
BambuSpeedProfileSilent = 1,
|
||||
BambuSpeedProfileNormal = 2,
|
||||
BambuSpeedProfileSport = 3,
|
||||
BambuSpeedProfileLudicrous = 4,
|
||||
};
|
||||
|
||||
class BambuPrinter : public BasePrinter
|
||||
{
|
||||
private:
|
||||
unsigned int last_error = 0;
|
||||
unsigned int ignore_error = 0;
|
||||
unsigned long print_start;
|
||||
|
||||
protected:
|
||||
void parse_state(JsonDocument& in);
|
||||
void init_ui_panels();
|
||||
Files parse_files(WiFiClientSecure& client, int max_files);
|
||||
|
||||
public:
|
||||
float aux_fan_speed;
|
||||
float chamber_fan_speed;
|
||||
BambuSpeedProfile speed_profile = BambuSpeedProfileNormal;
|
||||
|
||||
union {
|
||||
struct {
|
||||
bool chamber_light_available : 1;
|
||||
bool chamber_light_on : 1;
|
||||
bool work_light_available : 1;
|
||||
bool work_light_on : 1;
|
||||
bool has_ams : 1;
|
||||
};
|
||||
unsigned char bambu_misc;
|
||||
};
|
||||
|
||||
BambuPrinter(int index) : BasePrinter(index)
|
||||
{
|
||||
supported_features = PrinterFeatureHome
|
||||
| PrinterFeatureDisableSteppers
|
||||
| PrinterFeaturePause
|
||||
| PrinterFeatureResume
|
||||
| PrinterFeatureStop
|
||||
| PrinterFeatureEmergencyStop
|
||||
| PrinterFeatureCooldown
|
||||
| PrinterFeatureContinueError
|
||||
| PrinterFeatureExtrude
|
||||
| PrinterFeatureRetract
|
||||
| PrinterFeatureIgnoreError
|
||||
| PrinterFeatureRetryError;
|
||||
|
||||
supported_temperature_devices = PrinterTemperatureDeviceBed
|
||||
| PrinterTemperatureDeviceNozzle1;
|
||||
|
||||
popup_message_timeout_s = -1;
|
||||
bambu_misc = 0;
|
||||
printer_data.error_screen_features = PrinterFeatureRetryError | PrinterFeatureIgnoreError | PrinterFeatureContinueError;
|
||||
print_start = millis();
|
||||
|
||||
init_ui_panels();
|
||||
no_confirm_print_file = true;
|
||||
}
|
||||
|
||||
bool move_printer(const char* axis, float amount, bool relative);
|
||||
bool execute_feature(PrinterFeatures feature);
|
||||
bool connect();
|
||||
bool fetch();
|
||||
PrinterDataMinimal fetch_min();
|
||||
void disconnect();
|
||||
Macros get_macros();
|
||||
int get_macros_count();
|
||||
bool execute_macro(const char* macro);
|
||||
PowerDevices get_power_devices();
|
||||
int get_power_devices_count();
|
||||
bool set_power_device_state(const char* device_name, bool state);
|
||||
Files get_files();
|
||||
bool start_file(const char* filename);
|
||||
Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename);
|
||||
bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature);
|
||||
bool send_gcode(const char* gcode, bool wait = true);
|
||||
void receive_data(unsigned char* data, unsigned int length);
|
||||
bool publish_mqtt_command(const char* command);
|
||||
};
|
||||
|
||||
enum BambuConnectionStatus {
|
||||
BambuConnectFail = 0,
|
||||
BambuConnectOk = 1,
|
||||
BambuConnectSNFail = 2,
|
||||
};
|
||||
|
||||
BambuConnectionStatus connection_test_bambu(PrinterConfiguration* config);
|
||||
257
CYD-Klipper/src/core/bambu/bambu_printer_panels.cpp
Normal file
257
CYD-Klipper/src/core/bambu/bambu_printer_panels.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
#include "bambu_printer_integration.hpp"
|
||||
#include "lvgl.h"
|
||||
#include "../../ui/ui_utils.h"
|
||||
#include <stdio.h>
|
||||
#include "../common/constants.h"
|
||||
|
||||
const char* speed_profiles[] = { "Silent (50%)", "Normal (100%)", "Sport (124%)", "Ludicrous (166%)" };
|
||||
const BambuSpeedProfile speed_profile_values[] = { BambuSpeedProfileSilent, BambuSpeedProfileNormal, BambuSpeedProfileSport, BambuSpeedProfileLudicrous };
|
||||
const char* COMMAND_SET_PRINT_SPEED = "{\"print\":{\"command\":\"print_speed\",\"param\":\"%d\"}}";
|
||||
const char* COMMAND_START_PRINT_3MF = "{\"print\":{\"command\":\"project_file\",\"param\":\"Metadata/plate_1.gcode\",\"project_id\":\"0\",\"profile_id\":\"0\",\"task_id\":\"0\",\"subtask_id\":\"0\",\"subtask_name\":\"CYD-Klipper Print Job\",\"url\":\"file:///sdcard/%s\",\"timelapse\":%s,\"bed_type\":\"auto\",\"bed_leveling\":%s,\"flow_cali\":%s,\"vibration_cali\":%s,\"layer_inspect\":%s,\"ams_mapping\":[],\"use_ams\":%s}}";
|
||||
|
||||
enum FanIndex
|
||||
{
|
||||
PartFan = 1,
|
||||
AuxFan = 2,
|
||||
ChamberFan = 3,
|
||||
};
|
||||
|
||||
static void set_fan_speed_text(lv_event_t* e, FanIndex index)
|
||||
{
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char data[16];
|
||||
|
||||
float fan_speed = 0;
|
||||
const char* fan_type = "";
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case PartFan:
|
||||
fan_speed = get_current_printer_data()->fan_speed;
|
||||
fan_type = "P.Fan";
|
||||
break;
|
||||
case AuxFan:
|
||||
fan_speed = ((BambuPrinter*)get_current_printer)->aux_fan_speed;
|
||||
fan_type = "A.Fan";
|
||||
break;
|
||||
case ChamberFan:
|
||||
fan_speed = ((BambuPrinter*)get_current_printer)->chamber_fan_speed;
|
||||
fan_type = "C.Fan";
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(data, "%s: %.0f%%", fan_type, get_current_printer_data()->fan_speed * 100);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_fan_speed(lv_event_t* e, FanIndex index)
|
||||
{
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
int actual_speed = fan_percent_to_byte(speed);
|
||||
BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
char buff[20];
|
||||
sprintf(buff, "M106 P%d S%d", index, actual_speed);
|
||||
printer->send_gcode(buff);
|
||||
}
|
||||
|
||||
static void set_part_fan_speed_text(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed_text(e, FanIndex::PartFan);
|
||||
}
|
||||
|
||||
static void set_part_fan_speed(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed(e, FanIndex::PartFan);
|
||||
}
|
||||
|
||||
FAN_SPEED_COLUMN(set_part_fan_speed, part_fan_speed_columns)
|
||||
|
||||
static void set_aux_fan_speed_text(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed_text(e, FanIndex::AuxFan);
|
||||
}
|
||||
|
||||
static void set_aux_fan_speed(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed(e, FanIndex::AuxFan);
|
||||
}
|
||||
|
||||
FAN_SPEED_COLUMN(set_aux_fan_speed, aux_fan_speed_columns)
|
||||
|
||||
static void set_chamber_fan_speed_text(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed_text(e, FanIndex::ChamberFan);
|
||||
}
|
||||
|
||||
static void set_chamber_fan_speed(lv_event_t * e)
|
||||
{
|
||||
set_fan_speed(e, FanIndex::ChamberFan);
|
||||
}
|
||||
|
||||
FAN_SPEED_COLUMN(set_chamber_fan_speed, chamber_fan_speed_columns)
|
||||
|
||||
// TODO: move to common
|
||||
static void set_speed_mult_text(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char buff[16];
|
||||
sprintf(buff, "Speed: %.0f%%", get_current_printer_data()->speed_mult * 100);
|
||||
lv_label_set_text(label, buff);
|
||||
}
|
||||
|
||||
static void set_speed_mult(lv_event_t * e)
|
||||
{
|
||||
BambuSpeedProfile speed = (BambuSpeedProfile)((int)lv_event_get_user_data(e));
|
||||
BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
char buff[128];
|
||||
|
||||
sprintf(buff, COMMAND_SET_PRINT_SPEED, speed);
|
||||
printer->publish_mqtt_command(buff);
|
||||
}
|
||||
|
||||
lv_button_column_t speed_profile_columns[] = {
|
||||
{ set_speed_mult, speed_profiles, (const void**)speed_profile_values, 4},
|
||||
};
|
||||
|
||||
static void open_part_fan_speed_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_part_fan_speed_text, part_fan_speed_columns, 3);
|
||||
}
|
||||
|
||||
static void open_aux_fan_speed_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_aux_fan_speed_text, aux_fan_speed_columns, 3);
|
||||
}
|
||||
|
||||
static void open_chamber_fan_speed_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_chamber_fan_speed_text, chamber_fan_speed_columns, 3);
|
||||
}
|
||||
|
||||
|
||||
static void open_speed_mult_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_speed_mult_text, speed_profile_columns, 1);
|
||||
}
|
||||
|
||||
static PrinterUiPanel bambu_ui_panels[4] {
|
||||
{ .set_label = (void*)set_speed_mult_text, .open_panel = (void*)open_speed_mult_panel },
|
||||
{ .set_label = (void*)set_part_fan_speed_text, .open_panel = (void*)open_part_fan_speed_panel },
|
||||
{ .set_label = (void*)set_chamber_fan_speed_text, .open_panel = (void*)open_chamber_fan_speed_panel },
|
||||
{ .set_label = (void*)set_aux_fan_speed_text, .open_panel = (void*)open_aux_fan_speed_panel },
|
||||
};
|
||||
|
||||
void BambuPrinter::init_ui_panels()
|
||||
{
|
||||
custom_menus_count = 4;
|
||||
custom_menus = bambu_ui_panels;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
const char* bambu_current_file;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool bambu_option_use_ams : 1;
|
||||
bool bambu_option_timelapse : 1;
|
||||
bool bambu_option_bed_leveling : 1;
|
||||
bool bambu_option_flow_calibration : 1;
|
||||
bool bambu_option_vibration_compensation : 1;
|
||||
bool bambu_option_layer_inspect : 1;
|
||||
};
|
||||
unsigned char bambu_options_raw;
|
||||
};
|
||||
} __internal_bambu_file_state = {};
|
||||
|
||||
#define SET_BOOL_STATE(bool_name, func_name) static void func_name (lv_event_t * e) { auto state = lv_obj_get_state(lv_event_get_target(e)); bool_name = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); }
|
||||
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_use_ams, set_bambu_option_use_ams)
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_timelapse, set_bambu_option_timelapse)
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_bed_leveling, set_bambu_option_bed_leveling)
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_flow_calibration, set_bambu_option_flow_calibration)
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_vibration_compensation, set_bambu_option_vibration_compensation)
|
||||
SET_BOOL_STATE(__internal_bambu_file_state.bambu_option_layer_inspect, set_bambu_option_layer_inspect)
|
||||
|
||||
#define BOOLEAN_TO_STRING(b) b ? "true" : "false"
|
||||
|
||||
static void print_file_start(lv_event_t * e)
|
||||
{
|
||||
BambuPrinter* printer = (BambuPrinter*)get_current_printer();
|
||||
char buff[713];
|
||||
|
||||
if (snprintf(buff, 713, COMMAND_START_PRINT_3MF,
|
||||
__internal_bambu_file_state.bambu_current_file,
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_timelapse),
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_bed_leveling),
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_flow_calibration),
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_vibration_compensation),
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_layer_inspect),
|
||||
BOOLEAN_TO_STRING(__internal_bambu_file_state.bambu_option_use_ams)) >= 712)
|
||||
{
|
||||
LOG_LN("Failed to prepare message to start print");
|
||||
return;
|
||||
}
|
||||
|
||||
printer->publish_mqtt_command(buff);
|
||||
}
|
||||
|
||||
bool BambuPrinter::start_file(const char* filename){
|
||||
if (get_current_printer_data()->state != PrinterState::PrinterStateIdle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__internal_bambu_file_state.bambu_current_file = filename;
|
||||
|
||||
lv_obj_t * panel = lv_obj_create(lv_scr_act());
|
||||
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX * 2, 0);
|
||||
lv_layout_flex_column(panel);
|
||||
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
|
||||
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lv_obj_t * label_print_file = lv_label_create(panel);
|
||||
lv_obj_set_width(label_print_file, LV_PCT(100));
|
||||
lv_label_set_long_mode(label_print_file, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||
lv_label_set_text_fmt(label_print_file, "Settings for %s", __internal_bambu_file_state.bambu_current_file);
|
||||
|
||||
__internal_bambu_file_state.bambu_option_use_ams = ((BambuPrinter*)get_current_printer())->has_ams;
|
||||
__internal_bambu_file_state.bambu_option_timelapse = false;
|
||||
__internal_bambu_file_state.bambu_option_bed_leveling = true;
|
||||
__internal_bambu_file_state.bambu_option_flow_calibration = true;
|
||||
__internal_bambu_file_state.bambu_option_vibration_compensation = true;
|
||||
__internal_bambu_file_state.bambu_option_layer_inspect = true;
|
||||
|
||||
if (__internal_bambu_file_state.bambu_option_use_ams)
|
||||
{
|
||||
lv_create_custom_menu_switch("Use AMS", panel, set_bambu_option_use_ams, __internal_bambu_file_state.bambu_option_use_ams);
|
||||
}
|
||||
|
||||
lv_create_custom_menu_switch("Timelapse", panel, set_bambu_option_timelapse, __internal_bambu_file_state.bambu_option_timelapse);
|
||||
lv_create_custom_menu_switch("Bed Leveling", panel, set_bambu_option_bed_leveling, __internal_bambu_file_state.bambu_option_bed_leveling);
|
||||
lv_create_custom_menu_switch("Flow Calibration", panel, set_bambu_option_flow_calibration, __internal_bambu_file_state.bambu_option_flow_calibration);
|
||||
lv_create_custom_menu_switch("Vibration Compensation", panel, set_bambu_option_vibration_compensation, __internal_bambu_file_state.bambu_option_vibration_compensation);
|
||||
lv_create_custom_menu_switch("Inspect First Layer", panel, set_bambu_option_layer_inspect, __internal_bambu_file_state.bambu_option_layer_inspect);
|
||||
|
||||
lv_obj_t* buttons_panel = lv_create_empty_panel(panel);
|
||||
lv_layout_flex_row(buttons_panel);
|
||||
lv_obj_set_size(buttons_panel, LV_PCT(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
|
||||
lv_obj_t* btn = lv_btn_create(buttons_panel);
|
||||
lv_obj_set_flex_grow(btn, 1);
|
||||
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, panel);
|
||||
|
||||
lv_obj_t* label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_CLOSE " Cancel");
|
||||
lv_obj_center(label);
|
||||
|
||||
btn = lv_btn_create(buttons_panel);
|
||||
lv_obj_set_flex_grow(btn, 1);
|
||||
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
lv_obj_add_event_cb(btn, print_file_start, LV_EVENT_CLICKED, panel);
|
||||
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, panel);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_OK " Print");
|
||||
lv_obj_center(label);
|
||||
|
||||
return true;
|
||||
}
|
||||
398
CYD-Klipper/src/core/bambu/bambu_printer_parsers.cpp
Normal file
398
CYD-Klipper/src/core/bambu/bambu_printer_parsers.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
#include "bambu_printer_integration.hpp"
|
||||
#include <HTTPClient.h>
|
||||
#include <list>
|
||||
|
||||
#define BIT_X_AXIS_HOMED BIT(0)
|
||||
#define BIT_Y_AXIS_HOMED BIT(1)
|
||||
#define BIT_Z_AXIS_HOMED BIT(2)
|
||||
|
||||
float convert_fan_speed(const char* in)
|
||||
{
|
||||
if (in == NULL || strlen(in) <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int part_value = atoi(in);
|
||||
float percentage = (part_value / 15.0f) * 100;
|
||||
return round(percentage / 10) / 10;
|
||||
}
|
||||
|
||||
void BambuPrinter::parse_state(JsonDocument& in)
|
||||
{
|
||||
if (!in.containsKey("print"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject print = in["print"];
|
||||
|
||||
if (print.containsKey("print_error"))
|
||||
{
|
||||
unsigned int error = print["print_error"].as<unsigned int>();
|
||||
if (error != last_error)
|
||||
{
|
||||
last_error = error;
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
HTTPClient client;
|
||||
client.setTimeout(1000);
|
||||
client.setConnectTimeout(1000);
|
||||
|
||||
LOG_F(("Free heap: %d bytes\n", esp_get_free_heap_size()))
|
||||
|
||||
char buff[10] = {0};
|
||||
sprintf(buff, "%X_%X", error >> 16, error & 0xFFFF);
|
||||
int http_status_code = 0;
|
||||
|
||||
try
|
||||
{
|
||||
client.begin("http://bambu.suchmeme.nl/" + String(buff));
|
||||
LOG_F(("Sending request to http://bambu.suchmeme.nl/%s", buff));
|
||||
http_status_code = client.GET();
|
||||
LOG_F(("Response: %d", http_status_code));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_LN("Error downloading error code page");
|
||||
}
|
||||
|
||||
if (http_status_code == 200)
|
||||
{
|
||||
printer_data.state_message = (char *)malloc(client.getSize() + 20);
|
||||
sprintf(printer_data.state_message, "%s: %s", buff, client.getString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_data.state_message = (char *)malloc(20);
|
||||
sprintf(printer_data.state_message, "Error: %s", buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("nozzle_temper"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexNozzle1] = print["nozzle_temper"];
|
||||
printer_data.can_extrude = printer_data.temperatures[PrinterTemperatureDeviceIndexNozzle1] >= MIN_EXTRUDER_EXTRUDE_TEMP;
|
||||
}
|
||||
|
||||
if (print.containsKey("nozzle_target_temper"))
|
||||
{
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexNozzle1] = print["nozzle_target_temper"];
|
||||
}
|
||||
|
||||
if (print.containsKey("bed_temper"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexBed] = print["bed_temper"];
|
||||
}
|
||||
|
||||
if (print.containsKey("bed_target_temper"))
|
||||
{
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexBed] = print["bed_target_temper"];
|
||||
}
|
||||
|
||||
if (print.containsKey("spd_lvl"))
|
||||
{
|
||||
int speed_profile_int = print["spd_lvl"];
|
||||
speed_profile = (BambuSpeedProfile)speed_profile_int;
|
||||
|
||||
switch (speed_profile)
|
||||
{
|
||||
case BambuSpeedProfileSilent:
|
||||
printer_data.speed_mult = 0.5f;
|
||||
break;
|
||||
case BambuSpeedProfileNormal:
|
||||
printer_data.speed_mult = 1.0f;
|
||||
break;
|
||||
case BambuSpeedProfileSport:
|
||||
printer_data.speed_mult = 1.24f;
|
||||
break;
|
||||
case BambuSpeedProfileLudicrous:
|
||||
printer_data.speed_mult = 1.66f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("home_flag"))
|
||||
{
|
||||
unsigned int home_flag = print["home_flag"].as<unsigned int>();
|
||||
printer_data.homed_axis = (home_flag & (BIT_X_AXIS_HOMED | BIT_Y_AXIS_HOMED | BIT_Z_AXIS_HOMED)) == (BIT_X_AXIS_HOMED | BIT_Y_AXIS_HOMED | BIT_Z_AXIS_HOMED);
|
||||
}
|
||||
|
||||
if (last_error > 0 && last_error != ignore_error)
|
||||
{
|
||||
printer_data.state = PrinterState::PrinterStateError;
|
||||
}
|
||||
else if (print.containsKey("gcode_state"))
|
||||
{
|
||||
const char* state = print["gcode_state"];
|
||||
|
||||
if (strcasecmp(state, "pause") == 0)
|
||||
{
|
||||
printer_data.state = PrinterState::PrinterStatePaused;
|
||||
}
|
||||
else if (strcasecmp(state, "running") == 0 || strcasecmp(state, "prepare") == 0)
|
||||
{
|
||||
printer_data.state = PrinterState::PrinterStatePrinting;
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_data.state = PrinterState::PrinterStateIdle;
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("mc_remaining_time"))
|
||||
{
|
||||
printer_data.remaining_time_s = print["mc_remaining_time"];
|
||||
printer_data.remaining_time_s *= 60;
|
||||
if (printer_data.remaining_time_s > 300)
|
||||
{
|
||||
print_start = millis() - (printer_data.remaining_time_s / (1 - printer_data.print_progress) * printer_data.print_progress * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("mc_percent"))
|
||||
{
|
||||
printer_data.print_progress = print["mc_percent"];
|
||||
printer_data.print_progress /= 100;
|
||||
}
|
||||
|
||||
if (printer_data.state == PrinterState::PrinterStatePrinting)
|
||||
{
|
||||
printer_data.elapsed_time_s = (millis() - print_start) / 1000;
|
||||
}
|
||||
|
||||
if (print.containsKey("layer_num"))
|
||||
{
|
||||
printer_data.current_layer = print["layer_num"];
|
||||
}
|
||||
|
||||
if (print.containsKey("total_layer_num"))
|
||||
{
|
||||
printer_data.total_layers = print["total_layer_num"];
|
||||
}
|
||||
|
||||
if (print.containsKey("lights_report"))
|
||||
{
|
||||
for (JsonObject lights : print["lights_report"].as<JsonArray>())
|
||||
{
|
||||
if (lights.containsKey("node") && lights.containsKey("mode"))
|
||||
{
|
||||
bool mode = !(lights["mode"] == "off");
|
||||
const char* node = lights["node"];
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(node, "chamber_light") == 0)
|
||||
{
|
||||
chamber_light_available = true;
|
||||
chamber_light_on = mode;
|
||||
}
|
||||
else if (strcmp(node, "work_light") == 0)
|
||||
{
|
||||
work_light_available = true;
|
||||
work_light_on = mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("gcode_file"))
|
||||
{
|
||||
const char* filename = print["gcode_file"];
|
||||
|
||||
if (filename != NULL && (printer_data.print_filename == NULL || strcmp(printer_data.print_filename, filename)))
|
||||
{
|
||||
printer_data.print_filename = (char *)malloc(strlen(filename) + 1);
|
||||
strcpy(printer_data.print_filename, filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (print.containsKey("cooling_fan_speed"))
|
||||
{
|
||||
printer_data.fan_speed = convert_fan_speed(print["cooling_fan_speed"]);
|
||||
}
|
||||
|
||||
if (print.containsKey("big_fan1_speed"))
|
||||
{
|
||||
aux_fan_speed = convert_fan_speed(print["big_fan1_speed"]);
|
||||
}
|
||||
|
||||
if (print.containsKey("big_fan2_speed"))
|
||||
{
|
||||
chamber_fan_speed = convert_fan_speed(print["big_fan2_speed"]);
|
||||
}
|
||||
|
||||
if (print.containsKey("ams_exist_bits"))
|
||||
{
|
||||
const char* ams_exists = print["ams_exist_bits"];
|
||||
if (!strcmp(ams_exists, "0"))
|
||||
{
|
||||
has_ams = true;
|
||||
}
|
||||
}
|
||||
|
||||
printer_data.extrude_mult = 1;
|
||||
}
|
||||
|
||||
// Derived from https://github.com/ldab/ESP32_FTPClient/blob/master/src/ESP32_FTPClient.cpp
|
||||
bool wifi_client_response_pass(WiFiClientSecure& client)
|
||||
{
|
||||
unsigned long _m = millis();
|
||||
bool first_char = true;
|
||||
while (!client.available() && millis() < _m + 500) delay(1);
|
||||
|
||||
if(!client.available())
|
||||
{
|
||||
LOG_LN("FTPS: No response from server");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_LN("[FTPS response]");
|
||||
bool response = true;
|
||||
while (client.available())
|
||||
{
|
||||
char byte = client.read();
|
||||
|
||||
if (first_char && (byte == '4' || byte == '5'))
|
||||
{
|
||||
LOG_LN("FTPS: Server returned an error");
|
||||
response = false;
|
||||
}
|
||||
|
||||
first_char = false;
|
||||
|
||||
LOG_F(("%c", byte));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
bool wifi_client_response_parse(WiFiClientSecure& client, std::list<char*> &files, int max_files)
|
||||
{
|
||||
unsigned long _m = millis();
|
||||
while (!client.available() && millis() < _m + 500) delay(1);
|
||||
|
||||
if(!client.available())
|
||||
{
|
||||
LOG_LN("FTPS: No response from server");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_LN("[FTPS response]");
|
||||
char buff[128] = {0};
|
||||
int index = 0;
|
||||
while (client.available()) {
|
||||
int byte = client.read();
|
||||
LOG_F(("%c", byte));
|
||||
buff[index] = byte;
|
||||
|
||||
if (byte == '\n' || byte == '\r' || byte <= 0)
|
||||
{
|
||||
buff[index] = 0;
|
||||
if (index > 10)
|
||||
{
|
||||
char* file = (char*)malloc(index + 1);
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
strcpy(file, buff);
|
||||
files.push_front(file);
|
||||
|
||||
if (files.size() > max_files)
|
||||
{
|
||||
auto last_entry = files.back();
|
||||
|
||||
if (last_entry != NULL)
|
||||
free(last_entry);
|
||||
|
||||
files.pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_LN("Failed to allocate memory");
|
||||
}
|
||||
}
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool send_command_without_response(WiFiClientSecure& client, const char* command)
|
||||
{
|
||||
client.println(command);
|
||||
LOG_F(("[FTPS Command] %s\n", command));
|
||||
return wifi_client_response_pass(client);
|
||||
}
|
||||
|
||||
// TODO: This isn't a 'pure' parser implementation. Remove network calls, only do parsing
|
||||
Files BambuPrinter::parse_files(WiFiClientSecure& wifi_client, int max_files)
|
||||
{
|
||||
LOG_F(("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()));
|
||||
|
||||
unsigned long timer_request = millis();
|
||||
Files result = {0};
|
||||
|
||||
if (!wifi_client.connect(printer_config->printer_host, 990))
|
||||
{
|
||||
LOG_LN("Failed to fetch files: connection failed");
|
||||
}
|
||||
|
||||
wifi_client_response_pass(wifi_client);
|
||||
|
||||
char auth_code_buff[16] = {0};
|
||||
sprintf(auth_code_buff, "PASS %d", printer_config->klipper_port);
|
||||
send_command_without_response(wifi_client, "USER bblp");
|
||||
wifi_client_response_pass(wifi_client);
|
||||
send_command_without_response(wifi_client, auth_code_buff);
|
||||
send_command_without_response(wifi_client, "PASV");
|
||||
send_command_without_response(wifi_client, "NLST");
|
||||
wifi_client.stop();
|
||||
|
||||
if (wifi_client.connect(printer_config->printer_host, 2024))
|
||||
{
|
||||
unsigned long timer_parse = millis();
|
||||
std::list<char*> files;
|
||||
wifi_client_response_parse(wifi_client, files, max_files);
|
||||
result.available_files = (char**)malloc(sizeof(char*) * files.size());
|
||||
if (result.available_files == NULL)
|
||||
{
|
||||
LOG_LN("Failed to allocate memory");
|
||||
|
||||
for (auto file : files){
|
||||
free(file);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto file : files){
|
||||
result.available_files[result.count++] = file;
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
LOG_F(("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()))
|
||||
LOG_F(("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse))
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_LN("Failed to fetch files: data connection failed");
|
||||
}
|
||||
|
||||
wifi_client.stop();
|
||||
return result;
|
||||
}
|
||||
15
CYD-Klipper/src/core/common/constants.cpp
Normal file
15
CYD-Klipper/src/core/common/constants.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "constants.h"
|
||||
|
||||
const char* fan_speeds_col_1[] = { "On\n100%", "Off\n0%" };
|
||||
const int fan_speeds_col_1_values[] = { 100, 0 };
|
||||
|
||||
const char* fan_speeds_col_2[] = { "10%", "20%", "30%", "40%", "50%"};
|
||||
const int fan_speeds_col_2_values[] = { 10, 20, 30, 40, 50 };
|
||||
|
||||
const char* fan_speeds_col_3[] = { "60%", "70%", "80%", "90%"};
|
||||
const int fan_speeds_col_3_values[] = { 60, 70, 80, 90 };
|
||||
|
||||
unsigned char fan_percent_to_byte(int percent)
|
||||
{
|
||||
return percent * 255 / 100;
|
||||
}
|
||||
14
CYD-Klipper/src/core/common/constants.h
Normal file
14
CYD-Klipper/src/core/common/constants.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
extern const char* fan_speeds_col_1[];
|
||||
extern const int fan_speeds_col_1_values[];
|
||||
|
||||
extern const char* fan_speeds_col_2[];
|
||||
extern const int fan_speeds_col_2_values[];
|
||||
|
||||
extern const char* fan_speeds_col_3[];
|
||||
extern const int fan_speeds_col_3_values[];
|
||||
|
||||
unsigned char fan_percent_to_byte(int percent);
|
||||
|
||||
#define FAN_SPEED_COLUMN(set_fan_speed, column_name) lv_button_column_t column_name[] = {{ set_fan_speed, fan_speeds_col_2, (const void**)fan_speeds_col_2_values, 5},{ set_fan_speed, fan_speeds_col_3, (const void**)fan_speeds_col_3_values, 4}, { set_fan_speed, fan_speeds_col_1, (const void**)fan_speeds_col_1_values, 2}};
|
||||
99
CYD-Klipper/src/core/current_printer.cpp
Normal file
99
CYD-Klipper/src/core/current_printer.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "current_printer.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
bool current_printer_move_printer(const char* axis, float amount, bool relative)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->move_printer(axis, amount, relative);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool current_printer_execute_feature(PrinterFeatures feature)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->execute_feature(feature);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
Macros current_printer_get_macros()
|
||||
{
|
||||
freeze_request_thread();
|
||||
Macros macros = get_current_printer()->get_macros();
|
||||
unfreeze_request_thread();
|
||||
return macros;
|
||||
}
|
||||
|
||||
int current_printer_get_macros_count()
|
||||
{
|
||||
freeze_request_thread();
|
||||
int count = get_current_printer()->get_macros_count();
|
||||
unfreeze_request_thread();
|
||||
return count;
|
||||
}
|
||||
|
||||
bool current_printer_execute_macro(const char* macro)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->execute_macro(macro);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
PowerDevices current_printer_get_power_devices()
|
||||
{
|
||||
freeze_request_thread();
|
||||
PowerDevices power_devices = get_current_printer()->get_power_devices();
|
||||
unfreeze_request_thread();
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
int current_printer_get_power_devices_count()
|
||||
{
|
||||
freeze_request_thread();
|
||||
int count = get_current_printer()->get_power_devices_count();
|
||||
unfreeze_request_thread();
|
||||
return count;
|
||||
}
|
||||
|
||||
bool current_printer_set_power_device_state(const char* device_name, bool state)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->set_power_device_state(device_name, state);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
Files current_printer_get_files()
|
||||
{
|
||||
freeze_request_thread();
|
||||
Files files = get_current_printer()->get_files();
|
||||
unfreeze_request_thread();
|
||||
return files;
|
||||
}
|
||||
|
||||
bool current_printer_start_file(const char* filename)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->start_file(filename);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
Thumbnail current_printer_get_32_32_png_image_thumbnail(const char* gcode_filename)
|
||||
{
|
||||
freeze_request_thread();
|
||||
Thumbnail thumbnail = get_current_printer()->get_32_32_png_image_thumbnail(gcode_filename);
|
||||
unfreeze_request_thread();
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
bool current_printer_set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature)
|
||||
{
|
||||
freeze_request_thread();
|
||||
bool result = get_current_printer()->set_target_temperature(device, temperature);
|
||||
unfreeze_request_thread();
|
||||
return result;
|
||||
}
|
||||
|
||||
15
CYD-Klipper/src/core/current_printer.h
Normal file
15
CYD-Klipper/src/core/current_printer.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "printer_integration.hpp"
|
||||
|
||||
bool current_printer_move_printer(const char* axis, float amount, bool relative);
|
||||
bool current_printer_execute_feature(PrinterFeatures feature);
|
||||
Macros current_printer_get_macros();
|
||||
int current_printer_get_macros_count();
|
||||
bool current_printer_execute_macro(const char* macro);
|
||||
PowerDevices current_printer_get_power_devices();
|
||||
int current_printer_get_power_devices_count();
|
||||
bool current_printer_set_power_device_state(const char* device_name, bool state);
|
||||
Files current_printer_get_files();
|
||||
bool current_printer_start_file(const char* filename);
|
||||
Thumbnail current_printer_get_32_32_png_image_thumbnail(const char* gcode_filename);
|
||||
bool current_printer_set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature);
|
||||
121
CYD-Klipper/src/core/data_setup.cpp
Normal file
121
CYD-Klipper/src/core/data_setup.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
#include "data_setup.h"
|
||||
#include "semaphore.h"
|
||||
#include <esp_task_wdt.h>
|
||||
#include <UrlEncode.h>
|
||||
#include "printer_integration.hpp"
|
||||
#include "klipper/klipper_printer_integration.hpp"
|
||||
#include "klipper-serial/serial_klipper_printer_integration.hpp"
|
||||
#include "bambu/bambu_printer_integration.hpp"
|
||||
#include "octoprint/octoprint_printer_integration.hpp"
|
||||
|
||||
const long data_update_interval = 780;
|
||||
|
||||
void fetch_printer_data()
|
||||
{
|
||||
freeze_request_thread();
|
||||
|
||||
if (get_current_printer_data()->state == PrinterStateOffline)
|
||||
{
|
||||
if (!get_current_printer()->connect())
|
||||
{
|
||||
LOG_LN("Failed to connect to printer");
|
||||
unfreeze_request_thread();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool fetch_result = get_current_printer()->fetch();
|
||||
unfreeze_request_thread();
|
||||
|
||||
freeze_render_thread();
|
||||
if (!fetch_result)
|
||||
{
|
||||
LOG_LN("Failed to fetch printer data")
|
||||
get_current_printer()->disconnect();
|
||||
}
|
||||
|
||||
get_current_printer()->AnnouncePrinterData();
|
||||
unfreeze_render_thread();
|
||||
}
|
||||
|
||||
void fetch_printer_data_minimal()
|
||||
{
|
||||
PrinterDataMinimal data[PRINTER_CONFIG_COUNT] = {{}};
|
||||
for (int i = 0; i < get_printer_count(); i++)
|
||||
{
|
||||
freeze_request_thread();
|
||||
BasePrinter* printer = get_printer(i);
|
||||
unfreeze_request_thread();
|
||||
data[i] = printer->fetch_min();
|
||||
}
|
||||
freeze_render_thread();
|
||||
announce_printer_data_minimal(data);
|
||||
unfreeze_render_thread();
|
||||
}
|
||||
|
||||
void data_loop()
|
||||
{
|
||||
// Causes other threads that are trying to lock the thread to actually lock it
|
||||
unfreeze_render_thread();
|
||||
delay(1);
|
||||
freeze_render_thread();
|
||||
}
|
||||
|
||||
void data_loop_background(void * param){
|
||||
esp_task_wdt_init(10, true);
|
||||
int loop_iter = 20;
|
||||
while (true){
|
||||
delay(data_update_interval);
|
||||
fetch_printer_data();
|
||||
if (global_config.multi_printer_mode) {
|
||||
if (loop_iter++ > 20){
|
||||
fetch_printer_data_minimal();
|
||||
loop_iter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TaskHandle_t background_loop;
|
||||
|
||||
void data_setup()
|
||||
{
|
||||
BasePrinter** available_printers = (BasePrinter**)malloc(sizeof(BasePrinter*) * PRINTER_CONFIG_COUNT);
|
||||
int count = 0;
|
||||
int true_current_printer_index = 0;
|
||||
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++)
|
||||
{
|
||||
if (global_config.printer_config[i].setup_complete)
|
||||
{
|
||||
if (global_config.printer_index == i)
|
||||
{
|
||||
true_current_printer_index = count;;
|
||||
}
|
||||
|
||||
switch (global_config.printer_config[i].printer_type)
|
||||
{
|
||||
case PrinterType::PrinterTypeKlipper:
|
||||
available_printers[count++] = new KlipperPrinter(i);
|
||||
break;
|
||||
case PrinterType::PrinterTypeBambuLocal:
|
||||
available_printers[count++] = new BambuPrinter(i);
|
||||
break;
|
||||
case PrinterType::PrinterTypeKlipperSerial:
|
||||
available_printers[count++] = new SerialKlipperPrinter(i);
|
||||
break;
|
||||
case PrinterType::PrinterTypeOctoprint:
|
||||
available_printers[count++] = new OctoPrinter(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialize_printers(available_printers, count);
|
||||
set_current_printer(true_current_printer_index);
|
||||
LOG_F(("Free heap after printer creation: %d bytes\n", esp_get_free_heap_size()));
|
||||
semaphore_init();
|
||||
fetch_printer_data();
|
||||
freeze_render_thread();
|
||||
xTaskCreatePinnedToCore(data_loop_background, "data_loop_background", 5000, NULL, 2, &background_loop, 0);
|
||||
}
|
||||
4
CYD-Klipper/src/core/data_setup.h
Normal file
4
CYD-Klipper/src/core/data_setup.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void data_loop();
|
||||
void data_setup();
|
||||
120
CYD-Klipper/src/core/device/ESP32-2432S028R.cpp
Normal file
120
CYD-Klipper/src/core/device/ESP32-2432S028R.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
|
||||
#include "../screen_driver.h"
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
#error "Vertical screen not supported with the ESP32_2432S028R driver"
|
||||
#endif
|
||||
|
||||
#include <SPI.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../lv_setup.h"
|
||||
|
||||
#define XPT2046_IRQ 36
|
||||
#define XPT2046_MOSI 32
|
||||
#define XPT2046_MISO 39
|
||||
#define XPT2046_CLK 25
|
||||
#define XPT2046_CS 33
|
||||
#define CPU_FREQ_HIGH 240
|
||||
#define CPU_FREQ_LOW 80
|
||||
|
||||
SPIClass touchscreen_spi = SPIClass(HSPI);
|
||||
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
void screen_setBrightness(byte brightness)
|
||||
{
|
||||
// calculate duty, 4095 from 2 ^ 12 - 1
|
||||
uint32_t duty = (4095 / 255) * brightness;
|
||||
|
||||
// write duty to LEDC
|
||||
ledcWrite(0, duty);
|
||||
}
|
||||
|
||||
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
if (touchscreen.tirqTouched() && touchscreen.touched())
|
||||
{
|
||||
TS_Point p = touchscreen.getPoint();
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
data->point.x = p.x;
|
||||
data->point.y = p.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_invert_display(){
|
||||
tft.invertDisplay(global_config.printer_config[global_config.printer_index].invert_colors);
|
||||
}
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
|
||||
touchscreen.begin(touchscreen_spi);
|
||||
touchscreen.setRotation(global_config.rotate_screen ? 3 : 1);
|
||||
|
||||
lv_init();
|
||||
|
||||
tft.init();
|
||||
|
||||
if (global_config.display_mode) {
|
||||
// <3 https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/cyd.md#the-display-doesnt-look-as-good
|
||||
tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected
|
||||
tft.writedata(2);
|
||||
delay(120);
|
||||
tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected
|
||||
tft.writedata(1);
|
||||
}
|
||||
|
||||
ledcSetup(0, 5000, 12);
|
||||
ledcAttachPin(21, 0);
|
||||
|
||||
tft.setRotation(global_config.rotate_screen ? 3 : 1);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
set_invert_display();
|
||||
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
|
||||
touchscreen.begin(touchscreen_spi);
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
|
||||
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
|
||||
disp_drv.flush_cb = screen_lv_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = screen_lv_touchRead;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
#endif // CYD_SCREEN_DRIVER_ESP32_2432S028R
|
||||
154
CYD-Klipper/src/core/device/ESP32-3248S035C.cpp
Normal file
154
CYD-Klipper/src/core/device/ESP32-3248S035C.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_3248S035C
|
||||
#include "../screen_driver.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
#include <TAMC_GT911.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../../conf/global_config.h"
|
||||
#include "../lv_setup.h"
|
||||
|
||||
#define TOUCH_SDA 33
|
||||
#define TOUCH_SCL 32
|
||||
#define TOUCH_INT 21
|
||||
#define TOUCH_RST 25
|
||||
#define TOUCH_WIDTH 320
|
||||
#define TOUCH_HEIGHT 480
|
||||
|
||||
#define LED_PIN_R 4
|
||||
#define LED_PIN_G 16
|
||||
#define LED_PIN_B 17
|
||||
|
||||
TAMC_GT911 tp = TAMC_GT911(TOUCH_SDA, TOUCH_SCL, TOUCH_INT, TOUCH_RST, TOUCH_WIDTH, TOUCH_HEIGHT);
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
void screen_setBrightness(byte brightness)
|
||||
{
|
||||
// calculate duty, 4095 from 2 ^ 12 - 1
|
||||
uint32_t duty = (4095 / 255) * brightness;
|
||||
|
||||
// write duty to LEDC
|
||||
ledcWrite(0, duty);
|
||||
}
|
||||
|
||||
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
tp.read();
|
||||
if (!tp.isTouched)
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
for (int i = 0; i < tp.touches; i++)
|
||||
{
|
||||
uint16_t magicX; // fix GT911 driver - orientation and handle rotation
|
||||
uint16_t magicY;
|
||||
if (!global_config.rotate_screen)
|
||||
{
|
||||
magicY = tp.points[i].x;
|
||||
magicX = TOUCH_HEIGHT - tp.points[i].y;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
// I don't even want to know why this works...
|
||||
magicY = TOUCH_HEIGHT - tp.points[i].x;
|
||||
magicX = tp.points[i].y - 160;
|
||||
#else
|
||||
magicY = TOUCH_WIDTH - tp.points[i].x;
|
||||
magicX = tp.points[i].y;
|
||||
#endif
|
||||
}
|
||||
|
||||
data->point.x = magicX;
|
||||
data->point.y = magicY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_invert_display()
|
||||
{
|
||||
tft.invertDisplay(global_config.printer_config[global_config.printer_index].invert_colors);
|
||||
}
|
||||
|
||||
void set_LED_color(uint8_t rgbVal[3])
|
||||
{
|
||||
analogWrite(LED_PIN_R, 255 - rgbVal[0]);
|
||||
analogWrite(LED_PIN_G, 255 - rgbVal[1]);
|
||||
analogWrite(LED_PIN_B, 255 - rgbVal[2]);
|
||||
}
|
||||
|
||||
void LED_init()
|
||||
{
|
||||
pinMode(LED_PIN_R, OUTPUT);
|
||||
pinMode(LED_PIN_G, OUTPUT);
|
||||
pinMode(LED_PIN_B, OUTPUT);
|
||||
uint8_t rgbVal[3] = {0, 0, 0};
|
||||
set_LED_color(rgbVal);
|
||||
}
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
// Initialize the touchscreen
|
||||
tp.begin();
|
||||
|
||||
// Initialize LVGL
|
||||
lv_init();
|
||||
// Initialize the display
|
||||
tft.init();
|
||||
ledcSetup(0, 5000, 12);
|
||||
ledcAttachPin(TFT_BL, 0);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
set_invert_display();
|
||||
LED_init();
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
disp_drv.hor_res = TFT_WIDTH;
|
||||
disp_drv.ver_res = TFT_HEIGHT;
|
||||
tp.setRotation(2);
|
||||
tft.setRotation(global_config.rotate_screen ? 2 : 0);
|
||||
#else
|
||||
disp_drv.hor_res = TFT_HEIGHT;
|
||||
disp_drv.ver_res = TFT_WIDTH;
|
||||
|
||||
tft.setRotation(global_config.rotate_screen ? 3 : 1);
|
||||
tp.setRotation(ROTATION_NORMAL);
|
||||
#endif
|
||||
|
||||
|
||||
disp_drv.flush_cb = screen_lv_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
// Initialize the (dummy) input device driver
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = screen_lv_touchRead;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
#endif // CYD_SCREEN_DRIVER_ESP32_3248S035C
|
||||
183
CYD-Klipper/src/core/device/ESP32-CROWPANEL-35C.cpp
Normal file
183
CYD-Klipper/src/core/device/ESP32-CROWPANEL-35C.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
// Adapted from https://github.com/OzInFl/Elecrow-3.5-RGB-TFT-SQUARELINE-EXAMPLE
|
||||
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_CROWPANEL_35C
|
||||
#include "../screen_driver.h"
|
||||
#include "lvgl.h"
|
||||
#include "../../conf/global_config.h"
|
||||
#include <LovyanGFX.hpp>
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
#error "Vertical screen not supported with the ESP32_CROWPANEL_28R driver"
|
||||
#endif
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
|
||||
|
||||
#define BUZZER_PIN 20
|
||||
#define LCD_BL 46
|
||||
#define SDA_FT6236 38
|
||||
#define SCL_FT6236 39
|
||||
#define I2C_TOUCH_ADDR 0x38
|
||||
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ILI9488 _panel_instance;
|
||||
lgfx::Bus_Parallel16 _bus_instance;
|
||||
lgfx::Touch_FT5x06 _touch_instance;
|
||||
|
||||
public:
|
||||
LGFX()
|
||||
{
|
||||
auto bus_cfg = _bus_instance.config();
|
||||
bus_cfg.port = 0;
|
||||
bus_cfg.freq_write = 80000000;
|
||||
bus_cfg.pin_wr = 18;
|
||||
bus_cfg.pin_rd = 48;
|
||||
bus_cfg.pin_rs = 45;
|
||||
bus_cfg.pin_d0 = 47;
|
||||
bus_cfg.pin_d1 = 21;
|
||||
bus_cfg.pin_d2 = 14;
|
||||
bus_cfg.pin_d3 = 13;
|
||||
bus_cfg.pin_d4 = 12;
|
||||
bus_cfg.pin_d5 = 11;
|
||||
bus_cfg.pin_d6 = 10;
|
||||
bus_cfg.pin_d7 = 9;
|
||||
bus_cfg.pin_d8 = 3;
|
||||
bus_cfg.pin_d9 = 8;
|
||||
bus_cfg.pin_d10 = 16;
|
||||
bus_cfg.pin_d11 = 15;
|
||||
bus_cfg.pin_d12 = 7;
|
||||
bus_cfg.pin_d13 = 6;
|
||||
bus_cfg.pin_d14 = 5;
|
||||
bus_cfg.pin_d15 = 4;
|
||||
_bus_instance.config(bus_cfg);
|
||||
_panel_instance.setBus(&_bus_instance);
|
||||
|
||||
auto panel_cfg = _panel_instance.config();
|
||||
panel_cfg.pin_cs = -1;
|
||||
panel_cfg.pin_rst = -1;
|
||||
panel_cfg.pin_busy = -1;
|
||||
panel_cfg.memory_width = 320;
|
||||
panel_cfg.memory_height = 480;
|
||||
panel_cfg.panel_width = 320;
|
||||
panel_cfg.panel_height = 480;
|
||||
panel_cfg.offset_x = 0;
|
||||
panel_cfg.offset_y = 0;
|
||||
panel_cfg.offset_rotation = 0;
|
||||
panel_cfg.dummy_read_pixel = 8;
|
||||
panel_cfg.dummy_read_bits = 1;
|
||||
panel_cfg.readable = true;
|
||||
panel_cfg.invert = global_config.printer_config[global_config.printer_index].invert_colors ? true : false;
|
||||
panel_cfg.rgb_order = false;
|
||||
panel_cfg.dlen_16bit = true;
|
||||
panel_cfg.bus_shared = true;
|
||||
|
||||
_panel_instance.config(panel_cfg);
|
||||
|
||||
auto touch_cfg = _touch_instance.config();
|
||||
touch_cfg.x_min = 0;
|
||||
touch_cfg.x_max = 319;
|
||||
touch_cfg.y_min = 0;
|
||||
touch_cfg.y_max = 479;
|
||||
touch_cfg.pin_int = -1;
|
||||
touch_cfg.bus_shared = false;
|
||||
touch_cfg.offset_rotation = 0;
|
||||
|
||||
touch_cfg.i2c_port = 1;
|
||||
touch_cfg.i2c_addr = 0x38;
|
||||
touch_cfg.pin_sda = 38;
|
||||
touch_cfg.pin_scl = 39;
|
||||
touch_cfg.freq = 400000;
|
||||
|
||||
_touch_instance.config(touch_cfg);
|
||||
_panel_instance.setTouch(&_touch_instance);
|
||||
|
||||
setPanel(&_panel_instance);
|
||||
}
|
||||
};
|
||||
|
||||
LGFX tft;
|
||||
|
||||
void screen_setBrightness(unsigned char brightness)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void set_invert_display()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
bool touched = tft.getTouch(&touchX, &touchY);
|
||||
|
||||
if (touchX > CYD_SCREEN_WIDTH_PX || touchY > CYD_SCREEN_HEIGHT_PX)
|
||||
{
|
||||
LOG_LN("Y or y outside of expected parameters..");
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
data->point.x = touchX;
|
||||
data->point.y = touchY;
|
||||
}
|
||||
}
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
pinMode(BUZZER_PIN, OUTPUT);
|
||||
ledcSetup(4, 5000, 8);
|
||||
ledcAttachPin(BUZZER_PIN, 4);
|
||||
|
||||
tft.begin();
|
||||
tft.setRotation(global_config.rotate_screen ? 3 : 1);
|
||||
|
||||
delay(500);
|
||||
|
||||
pinMode(LCD_BL, OUTPUT);
|
||||
digitalWrite(LCD_BL, HIGH);
|
||||
|
||||
/*
|
||||
ledcSetup(0, 5000, 12);
|
||||
ledcAttachPin(LCD_BL, 0);
|
||||
*/
|
||||
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_WIDTH_PX * CYD_SCREEN_HEIGHT_PX / 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
|
||||
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
|
||||
disp_drv.flush_cb = screen_lv_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = screen_lv_touchRead;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
#endif
|
||||
100
CYD-Klipper/src/core/device/ESP32-CROWPANEL_28R.cpp
Normal file
100
CYD-Klipper/src/core/device/ESP32-CROWPANEL_28R.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_CROWPANEL_28R
|
||||
#include "../screen_driver.h"
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
#error "Vertical screen not supported with the ESP32_CROWPANEL_28R driver"
|
||||
#endif
|
||||
|
||||
#include <SPI.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include <TFT_eSPI.h>
|
||||
#include "../lv_setup.h"
|
||||
|
||||
#define TOUCH_THRESHOLD 600
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
void screen_setBrightness(byte brightness)
|
||||
{
|
||||
// calculate duty, 4095 from 2 ^ 12 - 1
|
||||
uint32_t duty = (4095 / 255) * brightness;
|
||||
|
||||
// write duty to LEDC
|
||||
ledcWrite(0, duty);
|
||||
}
|
||||
|
||||
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
if (tft.getTouch( &touchX, &touchY, TOUCH_THRESHOLD))
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
data->point.x = touchX;
|
||||
data->point.y = touchY;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_invert_display(){
|
||||
tft.invertDisplay(global_config.printer_config[global_config.printer_index].invert_colors);
|
||||
}
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
uint16_t calData[5] = { 189, 3416, 359, 3439, 1};
|
||||
|
||||
lv_init();
|
||||
|
||||
tft.init();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.invertDisplay(false);
|
||||
delay(300);
|
||||
|
||||
tft.setRotation(1);
|
||||
tft.setTouch( calData );
|
||||
|
||||
ledcSetup(0, 5000, 12);
|
||||
ledcAttachPin(TFT_BL, 0);
|
||||
|
||||
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
|
||||
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
|
||||
disp_drv.flush_cb = screen_lv_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = screen_lv_touchRead;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
#endif // CYD_SCREEN_DRIVER_ESP32_CROWPANEL_28R
|
||||
67
CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp
Normal file
67
CYD-Klipper/src/core/device/ESP32-smartdisplay.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
|
||||
|
||||
#include "../screen_driver.h"
|
||||
#include <esp32_smartdisplay.h>
|
||||
#include "../../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include "../lv_setup.h"
|
||||
|
||||
typedef void (*lv_disp_drv_t_flush_cb)(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
||||
static lv_disp_drv_t_flush_cb original_screen_driver;
|
||||
|
||||
void screen_setBrightness(byte brightness)
|
||||
{
|
||||
smartdisplay_lcd_set_backlight(brightness / 255.0f);
|
||||
}
|
||||
|
||||
void set_invert_display()
|
||||
{
|
||||
lv_obj_invalidate(lv_scr_act());
|
||||
}
|
||||
|
||||
void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
if (global_config.printer_config[global_config.printer_index].invert_colors) {
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
for (int i = 0 ; i < w * h; i++){
|
||||
color_p[i].full ^= 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
original_screen_driver(disp_drv, area, color_p);
|
||||
}
|
||||
|
||||
|
||||
#ifndef ROTATION_INVERTED
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
#define ROTATION_INVERTED LV_DISP_ROT_180
|
||||
#else
|
||||
#define ROTATION_INVERTED LV_DISP_ROT_270
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ROTATION_NORMAL
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
#define ROTATION_NORMAL LV_DISP_ROT_NONE
|
||||
#else
|
||||
#define ROTATION_NORMAL LV_DISP_ROT_90
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void screen_setup()
|
||||
{
|
||||
smartdisplay_init();
|
||||
|
||||
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
|
||||
if (original_screen_driver == NULL){
|
||||
original_screen_driver = lv_disp_get_default()->driver->flush_cb;
|
||||
lv_disp_get_default()->driver->flush_cb = lv_screen_intercept;
|
||||
}
|
||||
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS
|
||||
|
||||
lv_disp_set_rotation(lv_disp_get_default(), (global_config.rotate_screen) ? ROTATION_INVERTED : ROTATION_NORMAL);
|
||||
}
|
||||
|
||||
#endif // CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
|
||||
@@ -0,0 +1,399 @@
|
||||
#include "serial_klipper_printer_integration.hpp"
|
||||
#include <HardwareSerial.h>
|
||||
#include <UrlEncode.h>
|
||||
#include "../../ui/serial/serial_console.h"
|
||||
|
||||
void clear_serial_buffer(bool can_rely_on_newline_terminator = true)
|
||||
{
|
||||
if (can_rely_on_newline_terminator)
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
while (Serial.read() != '\n')
|
||||
;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Serial.available())
|
||||
{
|
||||
Serial.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request: {timeout} {method} {endpoint}
|
||||
// Response: {status code} {body}
|
||||
bool make_serial_request(JsonDocument &out, int timeout_ms, HttpRequestType requestType, const char* endpoint)
|
||||
{
|
||||
serial_console::global_disable_serial_console = true;
|
||||
temporary_config.debug = false;
|
||||
char buff[10];
|
||||
clear_serial_buffer();
|
||||
|
||||
// TODO: Add semaphore here
|
||||
if (!Serial.availableForWrite())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.printf("HTTP_REQUEST %d %s %s\n", timeout_ms, requestType == HttpGet ? "GET" : "POST", endpoint);
|
||||
|
||||
if (timeout_ms <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
unsigned long _m = millis();
|
||||
while (!Serial.available() && millis() < _m + timeout_ms + 10) delay(1);
|
||||
|
||||
if (!Serial.available())
|
||||
{
|
||||
Serial.println("Timeout...");
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.readBytes(buff, 4);
|
||||
buff[3] = 0;
|
||||
|
||||
if (buff[0] < '0' || buff[0] > '9')
|
||||
{
|
||||
Serial.printf("Invalid error code, got char '%c'\n", buff[0]);
|
||||
clear_serial_buffer();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int status_code = atoi(buff);
|
||||
|
||||
if (status_code < 200 || status_code >= 300)
|
||||
{
|
||||
Serial.println("Non-200 error code");
|
||||
clear_serial_buffer();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = deserializeJson(out, Serial);
|
||||
Serial.printf("Deserialization result: %s\n", result.c_str());
|
||||
bool success = result == DeserializationError::Ok;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int len;
|
||||
unsigned char* data;
|
||||
} BinaryResponse;
|
||||
|
||||
// Request: {timeout} {method} {endpoint}
|
||||
// Response: {8 char 0's padded body length}{body}
|
||||
bool make_binary_request(BinaryResponse* data, int timeout_ms, HttpRequestType requestType, const char* endpoint)
|
||||
{
|
||||
serial_console::global_disable_serial_console = true;
|
||||
temporary_config.debug = false;
|
||||
char buff[10];
|
||||
clear_serial_buffer();
|
||||
|
||||
// TODO: Add semaphore here
|
||||
if (!Serial.availableForWrite() || timeout_ms <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.printf("HTTP_BINARY %d %s %s\n", timeout_ms, requestType == HttpGet ? "GET" : "POST", endpoint);
|
||||
|
||||
unsigned long _m = millis();
|
||||
while (!Serial.available() && millis() < _m + timeout_ms + 10) delay(1);
|
||||
|
||||
if (!Serial.available())
|
||||
{
|
||||
Serial.println("Timeout...");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.readBytes(buff, 8);
|
||||
buff[9] = 0;
|
||||
|
||||
if (buff[0] < '0' || buff[0] > '9')
|
||||
{
|
||||
Serial.println("Invalid length");
|
||||
clear_serial_buffer(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int data_length = atoi(buff);
|
||||
|
||||
if (data_length <= 0)
|
||||
{
|
||||
Serial.println("0 Length");
|
||||
clear_serial_buffer(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
data->len = data_length;
|
||||
data->data = (unsigned char*)malloc(data_length);
|
||||
|
||||
if (data->data == NULL)
|
||||
{
|
||||
Serial.println("Failed to allocate memory");
|
||||
clear_serial_buffer(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = Serial.readBytes((char*)data->data, data_length) == data_length;
|
||||
if (!result)
|
||||
{
|
||||
free(data->data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool make_serial_request_nocontent(HttpRequestType requestType, const char* endpoint)
|
||||
{
|
||||
JsonDocument doc;
|
||||
make_serial_request(doc, 0, requestType, endpoint);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::connect()
|
||||
{
|
||||
return connection_test_serial_klipper(printer_config) == KlipperConnectionStatus::ConnectOk;
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::fetch()
|
||||
{
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status"))
|
||||
{
|
||||
if (printer_data.state == PrinterStateOffline)
|
||||
{
|
||||
printer_data.state = PrinterStateError;
|
||||
}
|
||||
|
||||
klipper_request_consecutive_fail_count = 0;
|
||||
parse_state(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
klipper_request_consecutive_fail_count++;
|
||||
if (klipper_request_consecutive_fail_count >= 5)
|
||||
{
|
||||
printer_data.state = PrinterStateOffline;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PrinterDataMinimal SerialKlipperPrinter::fetch_min()
|
||||
{
|
||||
JsonDocument doc;
|
||||
PrinterDataMinimal data = {};
|
||||
data.success = false;
|
||||
|
||||
if (!printer_config->setup_complete)
|
||||
{
|
||||
data.state = PrinterStateOffline;
|
||||
return data;
|
||||
}
|
||||
|
||||
data.success = true;
|
||||
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?webhooks&print_stats&virtual_sdcard"))
|
||||
{
|
||||
data.state = PrinterState::PrinterStateIdle;
|
||||
parse_state_min(doc, &data);
|
||||
data.power_devices = get_power_devices_count();
|
||||
}
|
||||
else
|
||||
{
|
||||
data.state = PrinterState::PrinterStateOffline;
|
||||
data.power_devices = get_power_devices_count();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
Macros SerialKlipperPrinter::get_macros()
|
||||
{
|
||||
Macros macros = {0};
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help"))
|
||||
{
|
||||
macros = parse_macros(doc);
|
||||
}
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
int SerialKlipperPrinter::get_macros_count()
|
||||
{
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help"))
|
||||
{
|
||||
return parse_macros_count(doc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PowerDevices SerialKlipperPrinter::get_power_devices()
|
||||
{
|
||||
PowerDevices power_devices = {0};
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices"))
|
||||
{
|
||||
power_devices = parse_power_devices(doc);
|
||||
}
|
||||
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
int SerialKlipperPrinter::get_power_devices_count()
|
||||
{
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices"))
|
||||
{
|
||||
return parse_power_devices_count(doc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::set_power_device_state(const char* device_name, bool state)
|
||||
{
|
||||
String request = "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off");
|
||||
return make_serial_request_nocontent(HttpGet, request.c_str());
|
||||
}
|
||||
|
||||
Files SerialKlipperPrinter::get_files()
|
||||
{
|
||||
Files files_result = {0};
|
||||
files_result.success = false;
|
||||
JsonDocument doc;
|
||||
LOG_F(("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()));
|
||||
std::list<KlipperFileSystemFile> files;
|
||||
|
||||
auto timer_request = millis();
|
||||
bool result = make_serial_request(doc, 5000, HttpGet, "/server/files/list");
|
||||
auto timer_parse = millis();
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return files_result;
|
||||
}
|
||||
|
||||
parse_file_list(doc, files, 20);
|
||||
|
||||
files_result.available_files = (char**)malloc(sizeof(char*) * files.size());
|
||||
|
||||
if (files_result.available_files == NULL){
|
||||
LOG_LN("Failed to allocate memory");
|
||||
|
||||
for (auto file : files){
|
||||
free(file.name);
|
||||
}
|
||||
|
||||
return files_result;
|
||||
}
|
||||
|
||||
for (auto file : files){
|
||||
files_result.available_files[files_result.count++] = file.name;
|
||||
}
|
||||
|
||||
files_result.success = true;
|
||||
|
||||
LOG_F(("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()))
|
||||
LOG_F(("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse))
|
||||
return files_result;
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::start_file(const char* filename)
|
||||
{
|
||||
JsonDocument doc;
|
||||
String request = "/printer/print/start?filename=" + urlEncode(filename);
|
||||
return make_serial_request_nocontent(HttpPost, request.c_str());;
|
||||
}
|
||||
|
||||
Thumbnail SerialKlipperPrinter::get_32_32_png_image_thumbnail(const char* gcode_filename)
|
||||
{
|
||||
Thumbnail thumbnail = {0};
|
||||
JsonDocument doc;
|
||||
char* img_filename_path = NULL;
|
||||
|
||||
String request = "/server/files/thumbnails?filename=" + urlEncode(gcode_filename);
|
||||
if (make_serial_request(doc, 1000, HttpGet, request.c_str()))
|
||||
{
|
||||
img_filename_path = parse_thumbnails(doc);
|
||||
doc.clear();
|
||||
}
|
||||
|
||||
if (img_filename_path == NULL)
|
||||
{
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
request = "/server/files/gcodes/" + urlEncode(img_filename_path);
|
||||
BinaryResponse data = {0};
|
||||
if (make_binary_request(&data, 2000, HttpGet, request.c_str()))
|
||||
{
|
||||
thumbnail.png = data.data;
|
||||
thumbnail.size = data.len;
|
||||
thumbnail.success = true;
|
||||
}
|
||||
|
||||
free(img_filename_path);
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::send_gcode(const char* gcode, bool wait)
|
||||
{
|
||||
JsonDocument doc;
|
||||
String request = "/printer/gcode/script?script=" + urlEncode(gcode);
|
||||
|
||||
return wait
|
||||
? make_serial_request(doc, 5000, HttpGet, request.c_str())
|
||||
: make_serial_request_nocontent(HttpGet, request.c_str());
|
||||
}
|
||||
|
||||
bool SerialKlipperPrinter::send_emergency_stop()
|
||||
{
|
||||
return make_serial_request_nocontent(HttpGet, "/printer/emergency_stop");
|
||||
}
|
||||
|
||||
int SerialKlipperPrinter::get_slicer_time_estimate_s()
|
||||
{
|
||||
if (printer_data.state != PrinterStatePrinting && printer_data.state != PrinterStatePaused)
|
||||
return 0;
|
||||
|
||||
String request = "/server/files/metadata?filename=" + urlEncode(printer_data.print_filename);
|
||||
JsonDocument doc;
|
||||
|
||||
if (!make_serial_request(doc, 2000, HttpGet, request.c_str()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parse_slicer_time_estimate(doc);
|
||||
}
|
||||
|
||||
KlipperConnectionStatus connection_test_serial_klipper(PrinterConfiguration* config)
|
||||
{
|
||||
serial_console::global_disable_serial_console = true;
|
||||
temporary_config.debug = false;
|
||||
JsonDocument doc;
|
||||
if (make_serial_request(doc, 1000, HttpGet, "/printer/info"))
|
||||
{
|
||||
return KlipperConnectionStatus::ConnectOk;
|
||||
}
|
||||
|
||||
return KlipperConnectionStatus::ConnectFail;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "../klipper/klipper_printer_integration.hpp"
|
||||
|
||||
class SerialKlipperPrinter : public KlipperPrinter
|
||||
{
|
||||
protected:
|
||||
bool send_emergency_stop();
|
||||
int get_slicer_time_estimate_s();
|
||||
public:
|
||||
SerialKlipperPrinter(int index) : KlipperPrinter(index)
|
||||
{}
|
||||
|
||||
bool connect();
|
||||
bool fetch();
|
||||
PrinterDataMinimal fetch_min();
|
||||
Macros get_macros();
|
||||
int get_macros_count();
|
||||
PowerDevices get_power_devices();
|
||||
int get_power_devices_count();
|
||||
bool set_power_device_state(const char* device_name, bool state);
|
||||
Files get_files();
|
||||
bool start_file(const char* filename);
|
||||
Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename);
|
||||
bool send_gcode(const char* gcode, bool wait = true);
|
||||
};
|
||||
|
||||
KlipperConnectionStatus connection_test_serial_klipper(PrinterConfiguration* config);
|
||||
519
CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp
Normal file
519
CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
#include "klipper_printer_integration.hpp"
|
||||
#include "../../conf/global_config.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <UrlEncode.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <list>
|
||||
|
||||
void KlipperPrinter::configure_http_client(HTTPClient &client, String url_part, bool stream, int timeout)
|
||||
{
|
||||
client.useHTTP10(stream);
|
||||
|
||||
if (timeout > 0){
|
||||
client.setTimeout(timeout);
|
||||
client.setConnectTimeout(timeout);
|
||||
}
|
||||
|
||||
client.begin("http://" + String(printer_config->printer_host) + ":" + String(printer_config->klipper_port) + url_part);
|
||||
|
||||
if (printer_config->auth_configured) {
|
||||
client.addHeader("X-Api-Key", printer_config->printer_auth);
|
||||
}
|
||||
}
|
||||
|
||||
int KlipperPrinter::get_slicer_time_estimate_s()
|
||||
{
|
||||
if (printer_data.state != PrinterStatePrinting && printer_data.state != PrinterStatePaused)
|
||||
return 0;
|
||||
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/server/files/metadata?filename=" + urlEncode(printer_data.print_filename), true, 5000);
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code != 200)
|
||||
return 0;
|
||||
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
return parse_slicer_time_estimate(doc);
|
||||
}
|
||||
|
||||
bool KlipperPrinter::send_gcode(const char *gcode, bool wait)
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/gcode/script?script=" + urlEncode(gcode), false, wait ? 5000 : 750);
|
||||
LOG_F(("Sending gcode: %s\n", gcode))
|
||||
|
||||
try
|
||||
{
|
||||
client.GET();
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_LN("Failed to send gcode");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool KlipperPrinter::move_printer(const char* axis, float amount, bool relative)
|
||||
{
|
||||
if (!printer_data.homed_axis || printer_data.state == PrinterStatePrinting)
|
||||
return false;
|
||||
|
||||
char gcode[64];
|
||||
const char* extra = (amount > 0) ? "+" : "";
|
||||
const char* start = "";
|
||||
const char* end = "";
|
||||
|
||||
if (printer_data.absolute_coords && relative) {
|
||||
start = "G91\n";
|
||||
}
|
||||
else if (!printer_data.absolute_coords && !relative) {
|
||||
start = "G90\n";
|
||||
}
|
||||
|
||||
if (printer_data.absolute_coords && relative) {
|
||||
end = "\nG90";
|
||||
}
|
||||
else if (!printer_data.absolute_coords && !relative) {
|
||||
end = "\nG91";
|
||||
}
|
||||
|
||||
sprintf(gcode, "%sG1 %s%s%.3f F6000%s", start, axis, extra, amount, end);
|
||||
send_gcode(gcode);
|
||||
|
||||
lock_absolute_relative_mode_swap = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KlipperPrinter::send_emergency_stop()
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/emergency_stop", false, 5000);
|
||||
|
||||
try
|
||||
{
|
||||
return client.GET() == 200;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_LN("Failed to send estop");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool KlipperPrinter::execute_feature(PrinterFeatures feature)
|
||||
{
|
||||
switch (feature)
|
||||
{
|
||||
case PrinterFeatureRestart:
|
||||
return send_gcode("RESTART", false);
|
||||
case PrinterFeatureFirmwareRestart:
|
||||
return send_gcode("FIRMWARE_RESTART", false);
|
||||
case PrinterFeatureHome:
|
||||
return send_gcode("G28");
|
||||
case PrinterFeatureDisableSteppers:
|
||||
return send_gcode("M18");
|
||||
case PrinterFeaturePause:
|
||||
return send_gcode("PAUSE");
|
||||
case PrinterFeatureResume:
|
||||
return send_gcode("RESUME");
|
||||
case PrinterFeatureStop:
|
||||
return send_gcode("CANCEL_PRINT");
|
||||
case PrinterFeatureEmergencyStop:
|
||||
LOG_LN("Sending estop");
|
||||
send_gcode("M112", false);
|
||||
send_emergency_stop();
|
||||
|
||||
return true;
|
||||
case PrinterFeatureExtrude:
|
||||
if (printer_data.state == PrinterStatePrinting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (printer_config->custom_filament_move_macros)
|
||||
{
|
||||
return send_gcode("FILAMENT_EXTRUDE");
|
||||
}
|
||||
else
|
||||
{
|
||||
return send_gcode("M83\nG1 E25 F300");
|
||||
}
|
||||
case PrinterFeatureRetract:
|
||||
if (printer_data.state == PrinterStatePrinting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (printer_config->custom_filament_move_macros)
|
||||
{
|
||||
return send_gcode("FILAMENT_RETRACT");
|
||||
}
|
||||
else
|
||||
{
|
||||
return send_gcode("M83\nG1 E-25 F300");
|
||||
}
|
||||
case PrinterFeatureCooldown:
|
||||
return send_gcode("M104 S0\nM140 S0");
|
||||
default:
|
||||
LOG_F(("Unsupported printer feature %d", feature));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KlipperPrinter::connect()
|
||||
{
|
||||
return connection_test_klipper(printer_config) == KlipperConnectionStatus::ConnectOk;
|
||||
}
|
||||
|
||||
bool KlipperPrinter::fetch()
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status", true, 1000);
|
||||
|
||||
int http_code = client.GET();
|
||||
if (http_code == 200)
|
||||
{
|
||||
if (printer_data.state == PrinterStateOffline)
|
||||
{
|
||||
printer_data.state = PrinterStateError;
|
||||
}
|
||||
|
||||
klipper_request_consecutive_fail_count = 0;
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
parse_state(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
klipper_request_consecutive_fail_count++;
|
||||
LOG_F(("Failed to fetch printer data: %d\n", http_code));
|
||||
|
||||
if (klipper_request_consecutive_fail_count >= 5)
|
||||
{
|
||||
printer_data.state = PrinterStateOffline;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PrinterDataMinimal KlipperPrinter::fetch_min()
|
||||
{
|
||||
PrinterDataMinimal data = {};
|
||||
data.success = false;
|
||||
|
||||
if (!printer_config->setup_complete)
|
||||
{
|
||||
data.state = PrinterStateOffline;
|
||||
return data;
|
||||
}
|
||||
|
||||
data.success = true;
|
||||
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/objects/query?webhooks&print_stats&virtual_sdcard", true, 1000);
|
||||
|
||||
int http_code = client.GET();
|
||||
if (http_code == 200)
|
||||
{
|
||||
data.state = PrinterState::PrinterStateIdle;
|
||||
data.power_devices = get_power_devices_count();
|
||||
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
parse_state_min(doc, &data);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.state = PrinterState::PrinterStateOffline;
|
||||
data.power_devices = get_power_devices_count();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void KlipperPrinter::disconnect()
|
||||
{
|
||||
// Nothing to disconnect, everything is http request based
|
||||
printer_data.state = PrinterStateOffline;
|
||||
}
|
||||
|
||||
Macros KlipperPrinter::get_macros()
|
||||
{
|
||||
HTTPClient client;
|
||||
Macros macros = {0};
|
||||
|
||||
configure_http_client(client, "/printer/gcode/help", true, 1000);
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200){
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
return parse_macros(doc);
|
||||
}
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
int KlipperPrinter::get_macros_count()
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/gcode/help", true, 1000);
|
||||
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200){
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
return parse_macros_count(doc);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool KlipperPrinter::execute_macro(const char* macro)
|
||||
{
|
||||
return send_gcode(macro);
|
||||
}
|
||||
|
||||
PowerDevices KlipperPrinter::get_power_devices()
|
||||
{
|
||||
HTTPClient client;
|
||||
PowerDevices power_devices = {0};
|
||||
configure_http_client(client, "/machine/device_power/devices", true, 1000);
|
||||
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200){
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
return parse_power_devices(doc);
|
||||
}
|
||||
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
int KlipperPrinter::get_power_devices_count()
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/machine/device_power/devices", true, 1000);
|
||||
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200){
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
return parse_power_devices_count(doc);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool KlipperPrinter::set_power_device_state(const char* device_name, bool state)
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off"), true, 1000);
|
||||
return client.POST("") == 200;
|
||||
}
|
||||
|
||||
#define KLIPPER_FILE_FETCH_LIMIT 20
|
||||
|
||||
Files KlipperPrinter::get_files()
|
||||
{
|
||||
Files files_result = {0};
|
||||
HTTPClient client;
|
||||
LOG_F(("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()));
|
||||
std::list<KlipperFileSystemFile> files;
|
||||
|
||||
auto timer_request = millis();
|
||||
configure_http_client(client, "/server/files/list", true, 5000);
|
||||
|
||||
int http_code = client.GET();
|
||||
auto timer_parse = millis();
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
JsonDocument doc;
|
||||
auto parseResult = deserializeJson(doc, client.getStream());
|
||||
LOG_F(("Json parse: %s\n", parseResult.c_str()))
|
||||
parse_file_list(doc, files, KLIPPER_FILE_FETCH_LIMIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return files_result;
|
||||
}
|
||||
|
||||
files_result.available_files = (char**)malloc(sizeof(char*) * files.size());
|
||||
|
||||
if (files_result.available_files == NULL){
|
||||
LOG_LN("Failed to allocate memory");
|
||||
|
||||
for (auto file : files){
|
||||
free(file.name);
|
||||
}
|
||||
|
||||
return files_result;
|
||||
}
|
||||
|
||||
for (auto file : files){
|
||||
files_result.available_files[files_result.count++] = file.name;
|
||||
}
|
||||
|
||||
files_result.success = true;
|
||||
|
||||
LOG_F(("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()))
|
||||
LOG_F(("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse))
|
||||
return files_result;
|
||||
}
|
||||
|
||||
bool KlipperPrinter::start_file(const char *filename)
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/printer/print/start?filename=" + urlEncode(filename), false, 1000);
|
||||
|
||||
int http_code = client.POST("");
|
||||
LOG_F(("Print start: HTTP %d\n", http_code))
|
||||
return http_code == 200;
|
||||
}
|
||||
|
||||
bool KlipperPrinter::set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature)
|
||||
{
|
||||
char gcode[64] = {0};
|
||||
|
||||
switch (device)
|
||||
{
|
||||
case PrinterTemperatureDeviceBed:
|
||||
sprintf(gcode, "M140 S%d", temperature);
|
||||
break;
|
||||
case PrinterTemperatureDeviceNozzle1:
|
||||
sprintf(gcode, "M104 S%d", temperature);
|
||||
break;
|
||||
default:
|
||||
LOG_F(("Unknown temperature device %d was requested to heat to %.2f", device, temperature));
|
||||
return false;
|
||||
}
|
||||
|
||||
return send_gcode(gcode);
|
||||
}
|
||||
|
||||
Thumbnail KlipperPrinter::get_32_32_png_image_thumbnail(const char* gcode_filename)
|
||||
{
|
||||
Thumbnail thumbnail = {0};
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/server/files/thumbnails?filename=" + urlEncode(gcode_filename), true, 1000);
|
||||
char* img_filename_path = NULL;
|
||||
unsigned char* data_png = NULL;
|
||||
|
||||
int http_code = 0;
|
||||
try
|
||||
{
|
||||
http_code = client.GET();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_LN("Exception while fetching gcode img location");
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
img_filename_path = parse_thumbnails(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_F(("Failed to fetch gcode image data: %d\n", http_code))
|
||||
}
|
||||
|
||||
if (img_filename_path == NULL)
|
||||
{
|
||||
LOG_LN("No compatible thumbnail found");
|
||||
return thumbnail;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_F(("Found 32x32 PNG gcode img at %s\n", gcode_filename));
|
||||
}
|
||||
|
||||
client.end();
|
||||
|
||||
configure_http_client(client, "/server/files/gcodes/" + urlEncode(img_filename_path), false, 2000);
|
||||
|
||||
http_code = 0;
|
||||
try
|
||||
{
|
||||
http_code = client.GET();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_LN("Exception while fetching gcode img");
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
size_t len = client.getSize();
|
||||
if (len <= 0)
|
||||
{
|
||||
LOG_LN("No gcode img data");
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
data_png = (unsigned char*)malloc(len + 1);
|
||||
|
||||
if (data_png != NULL)
|
||||
{
|
||||
if (len != client.getStream().readBytes(data_png, len))
|
||||
{
|
||||
LOG_LN("Failed to read gcode img data");
|
||||
free(data_png);
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnail.png = data_png;
|
||||
thumbnail.size = len;
|
||||
thumbnail.success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(img_filename_path);
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
KlipperConnectionStatus connection_test_klipper(PrinterConfiguration* config)
|
||||
{
|
||||
HTTPClient client;
|
||||
|
||||
client.setTimeout(1000);
|
||||
client.setConnectTimeout(1000);
|
||||
client.begin("http://" + String(config->printer_host) + ":" + String(config->klipper_port) + "/printer/info");
|
||||
|
||||
if (config->auth_configured) {
|
||||
client.addHeader("X-Api-Key", config->printer_auth);
|
||||
}
|
||||
|
||||
int http_code;
|
||||
try {
|
||||
http_code = client.GET();
|
||||
|
||||
if (http_code == 403)
|
||||
{
|
||||
return KlipperConnectionStatus::ConnectAuthRequired;
|
||||
}
|
||||
|
||||
return http_code == 200 ? KlipperConnectionStatus::ConnectOk : KlipperConnectionStatus::ConnectFail;
|
||||
}
|
||||
catch (...) {
|
||||
LOG_LN("Failed to connect");
|
||||
return KlipperConnectionStatus::ConnectFail;
|
||||
}
|
||||
}
|
||||
87
CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp
Normal file
87
CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include "../printer_integration.hpp"
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <list>
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
float modified;
|
||||
} KlipperFileSystemFile;
|
||||
|
||||
class KlipperPrinter : public BasePrinter
|
||||
{
|
||||
private:
|
||||
unsigned int slicer_estimated_print_time_s{};
|
||||
unsigned int last_slicer_time_query{};
|
||||
void configure_http_client(HTTPClient &client, String url_part, bool stream, int timeout);
|
||||
|
||||
protected:
|
||||
unsigned char lock_absolute_relative_mode_swap{};
|
||||
unsigned char klipper_request_consecutive_fail_count{};
|
||||
|
||||
virtual bool send_emergency_stop();
|
||||
virtual int get_slicer_time_estimate_s();
|
||||
void init_ui_panels();
|
||||
|
||||
int parse_slicer_time_estimate(JsonDocument& in);
|
||||
void parse_state(JsonDocument& in);
|
||||
void parse_state_min(JsonDocument &in, PrinterDataMinimal* data);
|
||||
Macros parse_macros(JsonDocument &in);
|
||||
int parse_macros_count(JsonDocument &in);
|
||||
PowerDevices parse_power_devices(JsonDocument &in);
|
||||
int parse_power_devices_count(JsonDocument &in);
|
||||
void parse_file_list(JsonDocument &in, std::list<KlipperFileSystemFile> &files, int fetch_limit);
|
||||
char *parse_thumbnails(JsonDocument &in);
|
||||
|
||||
public:
|
||||
float gcode_offset[3]{};
|
||||
|
||||
KlipperPrinter(int index) : BasePrinter(index)
|
||||
{
|
||||
supported_features = PrinterFeatureRestart
|
||||
| PrinterFeatureFirmwareRestart
|
||||
| PrinterFeatureHome
|
||||
| PrinterFeatureDisableSteppers
|
||||
| PrinterFeaturePause
|
||||
| PrinterFeatureResume
|
||||
| PrinterFeatureStop
|
||||
| PrinterFeatureEmergencyStop
|
||||
| PrinterFeatureExtrude
|
||||
| PrinterFeatureRetract
|
||||
| PrinterFeatureCooldown;
|
||||
|
||||
supported_temperature_devices = PrinterTemperatureDeviceBed
|
||||
| PrinterTemperatureDeviceNozzle1;
|
||||
|
||||
init_ui_panels();
|
||||
printer_data.error_screen_features = PrinterFeatureRestart | PrinterFeatureFirmwareRestart;
|
||||
}
|
||||
|
||||
bool move_printer(const char* axis, float amount, bool relative);
|
||||
bool execute_feature(PrinterFeatures feature);
|
||||
virtual bool connect();
|
||||
virtual bool fetch();
|
||||
virtual PrinterDataMinimal fetch_min();
|
||||
void disconnect();
|
||||
virtual Macros get_macros();
|
||||
virtual int get_macros_count();
|
||||
bool execute_macro(const char* macro);
|
||||
virtual PowerDevices get_power_devices();
|
||||
virtual int get_power_devices_count();
|
||||
virtual bool set_power_device_state(const char* device_name, bool state);
|
||||
virtual Files get_files();
|
||||
virtual bool start_file(const char* filename);
|
||||
virtual Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename);
|
||||
bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature);
|
||||
virtual bool send_gcode(const char* gcode, bool wait = true);
|
||||
};
|
||||
|
||||
enum KlipperConnectionStatus {
|
||||
ConnectFail = 0,
|
||||
ConnectOk = 1,
|
||||
ConnectAuthRequired = 2,
|
||||
};
|
||||
|
||||
KlipperConnectionStatus connection_test_klipper(PrinterConfiguration* config);
|
||||
188
CYD-Klipper/src/core/klipper/klipper_printer_panels.cpp
Normal file
188
CYD-Klipper/src/core/klipper/klipper_printer_panels.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
#include "klipper_printer_integration.hpp"
|
||||
#include "lvgl.h"
|
||||
#include "../../ui/ui_utils.h"
|
||||
#include "../common/constants.h"
|
||||
#include <stdio.h>
|
||||
#include "../semaphore.h"
|
||||
|
||||
bool send_gcode_blocking(const char *gcode, bool wait = true)
|
||||
{
|
||||
freeze_request_thread();
|
||||
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
bool result = printer->send_gcode(gcode);
|
||||
unfreeze_request_thread();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool move_printer_blocking(const char* axis, float amount, bool relative)
|
||||
{
|
||||
freeze_request_thread();
|
||||
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
bool result = printer->move_printer(axis, amount, relative);
|
||||
unfreeze_request_thread();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void set_fan_speed_text(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char data[16];
|
||||
sprintf(data, "Fan: %.0f%%", get_current_printer_data()->fan_speed * 100);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_fan_speed(lv_event_t * e){
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
int actual_speed = fan_percent_to_byte(speed);
|
||||
char gcode[16];
|
||||
sprintf(gcode, "M106 S%d", actual_speed);
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
FAN_SPEED_COLUMN(set_fan_speed, klipper_fan_speed_columns)
|
||||
|
||||
static void set_zoffset_text(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
char data[24];
|
||||
sprintf(data, "Z Offset: %.03f", printer->gcode_offset[2]);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_zoffset_text_ex(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
|
||||
char data[32];
|
||||
sprintf(data, "Z Offset: %.03f, Z: %.03f", printer->gcode_offset[2], get_current_printer_data()->position[2]);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_zoffset(lv_event_t * e){
|
||||
char* offset = (char*)lv_event_get_user_data(e);
|
||||
char gcode[48];
|
||||
sprintf(gcode, "SET_GCODE_OFFSET Z_ADJUST=%s MOVE=1", offset);
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
static void set_z(lv_event_t * e){
|
||||
void* ptr = lv_event_get_user_data(e);
|
||||
float value = *(float *)(&ptr);
|
||||
|
||||
if (value < 0) {
|
||||
send_gcode_blocking("SET_GCODE_OFFSET Z=0 MOVE=1");
|
||||
return;
|
||||
}
|
||||
|
||||
move_printer_blocking("Z", value, false);
|
||||
}
|
||||
|
||||
const char* zoffsets[] = { "-0.01", "-0.025", "-0.05", "-0.2" };
|
||||
const char* zoffsets_2[] = { "+0.01", "+0.025", "+0.05", "+0.2" };
|
||||
const char* zabs[] = { "Z=0", "Z=0.1", "Z=1", "Clear" };
|
||||
const float zabsvalues[] = { 0, 0.1f, 1.0f, -1.0f };
|
||||
|
||||
lv_button_column_t zoffset_columns[] = {
|
||||
{ set_zoffset, zoffsets, (const void**)zoffsets, 4},
|
||||
{ set_zoffset, zoffsets_2, (const void**)zoffsets_2, 4},
|
||||
{ set_z, zabs, (const void**)zabsvalues, 4}
|
||||
};
|
||||
|
||||
static void set_speed_mult_text(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char data[16];
|
||||
sprintf(data, "Speed: %.0f%%", get_current_printer_data()->speed_mult * 100);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_speed_mult(lv_event_t * e){
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
char gcode[16];
|
||||
sprintf(gcode, "M220 S%d", speed);
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
static void set_speed_mult_offset(lv_event_t * e){
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
float result = get_current_printer_data()->speed_mult * 100 + speed;
|
||||
get_current_printer_data()->speed_mult = result / 100;
|
||||
char gcode[16];
|
||||
sprintf(gcode, "M220 S%.0f", result);
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
const char* speed_presets[] = { "50%", "100%", "150%", "200%" };
|
||||
const int speed_presets_values[] = { 50, 100, 150, 200 };
|
||||
const char* speed_presets_minus[] = { "-1%", "-5%", "-10%", "-25%" };
|
||||
const int speed_presets_minus_values[] = { -1, -5, -10, -25 };
|
||||
const char* speed_presets_plus[] = { "+1%", "+5%", "+10%", "+25%" };
|
||||
const int speed_presets_plus_values[] = { 1, 5, 10, 25 };
|
||||
|
||||
lv_button_column_t speed_mult_columns[] = {
|
||||
{ set_speed_mult, speed_presets, (const void**)speed_presets_values, 4},
|
||||
{ set_speed_mult_offset, speed_presets_minus, (const void**)speed_presets_minus_values, 4},
|
||||
{ set_speed_mult_offset, speed_presets_plus, (const void**)speed_presets_plus_values, 4}
|
||||
};
|
||||
|
||||
static void set_extrude_mult_text(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char data[16];
|
||||
sprintf(data, "Flow: %.0f%%", get_current_printer_data()->extrude_mult * 100);
|
||||
lv_label_set_text(label, data);
|
||||
}
|
||||
|
||||
static void set_extrude_mult(lv_event_t * e){
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
char gcode[16];
|
||||
sprintf(gcode, "M221 S%d", speed);
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
static void set_extrude_mult_offset(lv_event_t * e){
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
float result = get_current_printer_data()->extrude_mult * 100 + speed;
|
||||
get_current_printer_data()->extrude_mult = result / 100;
|
||||
char gcode[16];
|
||||
sprintf(gcode, "M221 S%.0f", result);
|
||||
|
||||
send_gcode_blocking(gcode);
|
||||
}
|
||||
|
||||
const char* extrude_presets[] = { "95%", "100%", "105%", "110%" };
|
||||
const int extrude_presets_values[] = { 95, 100, 105, 110 };
|
||||
const char* extrude_offset[] = { "+5%", "+1%", "-1%", "-5%" };
|
||||
const int extrude_offset_values[] = { 5, 1, -1, -5 };
|
||||
|
||||
lv_button_column_t extrude_mult_columns[] = {
|
||||
{ set_extrude_mult, extrude_presets, (const void**)extrude_presets_values, 4},
|
||||
{ set_extrude_mult_offset, extrude_offset, (const void**)extrude_offset_values, 4}
|
||||
};
|
||||
|
||||
static void open_fan_speed_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, klipper_fan_speed_columns, 3);
|
||||
}
|
||||
|
||||
static void open_zoffset_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text_ex, zoffset_columns, get_current_printer_data()->state == PrinterStateIdle ? 3 : 2);
|
||||
}
|
||||
|
||||
static void open_speed_mult_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_speed_mult_text, speed_mult_columns, 3);
|
||||
}
|
||||
|
||||
static void open_extrude_mult_panel(lv_event_t * e){
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_extrude_mult_text, extrude_mult_columns, 2);
|
||||
}
|
||||
|
||||
static PrinterUiPanel klipper_ui_panels[4] {
|
||||
{ .set_label = (void*)set_fan_speed_text, .open_panel = (void*)open_fan_speed_panel },
|
||||
{ .set_label = (void*)set_zoffset_text, .open_panel = (void*)open_zoffset_panel },
|
||||
{ .set_label = (void*)set_speed_mult_text, .open_panel = (void*)open_speed_mult_panel },
|
||||
{ .set_label = (void*)set_extrude_mult_text, .open_panel = (void*)open_extrude_mult_panel }
|
||||
};
|
||||
|
||||
void KlipperPrinter::init_ui_panels()
|
||||
{
|
||||
custom_menus_count = 4;
|
||||
custom_menus = klipper_ui_panels;
|
||||
}
|
||||
384
CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp
Normal file
384
CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
#include "../printer_integration.hpp"
|
||||
#include "klipper_printer_integration.hpp"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
int KlipperPrinter::parse_slicer_time_estimate(JsonDocument &in)
|
||||
{
|
||||
int time_estimate_s = in["result"]["estimated_time"];
|
||||
LOG_F(("Got slicer time estimate: %ds\n", time_estimate_s))
|
||||
return time_estimate_s;
|
||||
}
|
||||
|
||||
void KlipperPrinter::parse_state(JsonDocument &in)
|
||||
{
|
||||
JsonObject status = in["result"]["status"];
|
||||
|
||||
if (status.containsKey("webhooks"))
|
||||
{
|
||||
const char *state = status["webhooks"]["state"];
|
||||
const char *message = status["webhooks"]["state_message"];
|
||||
|
||||
if (strcmp(state, "ready") == 0 && printer_data.state == PrinterStateError)
|
||||
{
|
||||
printer_data.state = PrinterStateIdle;
|
||||
}
|
||||
else if ((strcmp(state, "shutdown") == 0 || strcmp(state, "error") == 0) && printer_data.state != PrinterStateError)
|
||||
{
|
||||
printer_data.state = PrinterStateError;
|
||||
}
|
||||
|
||||
if (message != NULL && (printer_data.state_message == NULL || strcmp(printer_data.state_message, message)))
|
||||
{
|
||||
printer_data.state_message = (char *)malloc(strlen(message) + 1);
|
||||
strcpy(printer_data.state_message, message);
|
||||
}
|
||||
}
|
||||
|
||||
if (printer_data.state != PrinterStateError)
|
||||
{
|
||||
if (status.containsKey("extruder"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexNozzle1] = status["extruder"]["temperature"];
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexNozzle1] = status["extruder"]["target"];
|
||||
bool can_extrude = status["extruder"]["can_extrude"];
|
||||
printer_data.pressure_advance = status["extruder"]["pressure_advance"];
|
||||
printer_data.smooth_time = status["extruder"]["smooth_time"];
|
||||
printer_data.can_extrude = can_extrude == true;
|
||||
}
|
||||
|
||||
if (status.containsKey("heater_bed"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexBed] = status["heater_bed"]["temperature"];
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexBed] = status["heater_bed"]["target"];
|
||||
}
|
||||
|
||||
if (status.containsKey("toolhead"))
|
||||
{
|
||||
const char *homed_axis = status["toolhead"]["homed_axes"];
|
||||
printer_data.homed_axis = strcmp(homed_axis, "xyz") == 0;
|
||||
}
|
||||
|
||||
if (status.containsKey("gcode_move"))
|
||||
{
|
||||
printer_data.position[0] = status["gcode_move"]["gcode_position"][0];
|
||||
printer_data.position[1] = status["gcode_move"]["gcode_position"][1];
|
||||
printer_data.position[2] = status["gcode_move"]["gcode_position"][2];
|
||||
gcode_offset[0] = status["gcode_move"]["homing_origin"][0];
|
||||
gcode_offset[1] = status["gcode_move"]["homing_origin"][1];
|
||||
gcode_offset[2] = status["gcode_move"]["homing_origin"][2];
|
||||
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
|
||||
|
||||
if (lock_absolute_relative_mode_swap > 0)
|
||||
{
|
||||
lock_absolute_relative_mode_swap--;
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_data.absolute_coords = absolute_coords == true;
|
||||
}
|
||||
|
||||
printer_data.speed_mult = status["gcode_move"]["speed_factor"];
|
||||
printer_data.extrude_mult = status["gcode_move"]["extrude_factor"];
|
||||
printer_data.feedrate_mm_per_s = status["gcode_move"]["speed"];
|
||||
printer_data.feedrate_mm_per_s /= 60; // convert mm/m to mm/s
|
||||
}
|
||||
|
||||
if (status.containsKey("fan"))
|
||||
{
|
||||
printer_data.fan_speed = status["fan"]["speed"];
|
||||
}
|
||||
|
||||
if (status.containsKey("virtual_sdcard"))
|
||||
{
|
||||
printer_data.print_progress = status["virtual_sdcard"]["progress"];
|
||||
}
|
||||
|
||||
if (status.containsKey("print_stats"))
|
||||
{
|
||||
const char *filename = status["print_stats"]["filename"];
|
||||
|
||||
if (filename != NULL && (printer_data.print_filename == NULL || strcmp(printer_data.print_filename, filename)))
|
||||
{
|
||||
printer_data.print_filename = (char *)malloc(strlen(filename) + 1);
|
||||
strcpy(printer_data.print_filename, filename);
|
||||
}
|
||||
|
||||
printer_data.elapsed_time_s = status["print_stats"]["total_duration"];
|
||||
printer_data.printed_time_s = status["print_stats"]["print_duration"];
|
||||
printer_data.filament_used_mm = status["print_stats"]["filament_used"];
|
||||
printer_data.total_layers = status["print_stats"]["info"]["total_layer"];
|
||||
printer_data.current_layer = status["print_stats"]["info"]["current_layer"];
|
||||
|
||||
const char *state = status["print_stats"]["state"];
|
||||
|
||||
if (state == nullptr)
|
||||
{
|
||||
// Continue
|
||||
}
|
||||
else if (strcmp(state, "printing") == 0)
|
||||
{
|
||||
printer_data.state = PrinterStatePrinting;
|
||||
}
|
||||
else if (strcmp(state, "paused") == 0)
|
||||
{
|
||||
printer_data.state = PrinterStatePaused;
|
||||
}
|
||||
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
|
||||
{
|
||||
printer_data.state = PrinterStateIdle;
|
||||
}
|
||||
}
|
||||
|
||||
if (status.containsKey("display_status"))
|
||||
{
|
||||
printer_data.print_progress = status["display_status"]["progress"];
|
||||
const char *message = status["display_status"]["message"];
|
||||
|
||||
if (!global_config.disable_m117_messaging && message != NULL && (printer_data.popup_message == NULL || strcmp(printer_data.popup_message, message)))
|
||||
{
|
||||
printer_data.popup_message = (char *)malloc(strlen(message) + 1);
|
||||
strcpy(printer_data.popup_message, message);
|
||||
}
|
||||
}
|
||||
|
||||
if (printer_data.state == PrinterStatePrinting && printer_data.print_progress > 0)
|
||||
{
|
||||
float remaining_time_s_percentage = (printer_data.printed_time_s / printer_data.print_progress) - printer_data.printed_time_s;
|
||||
float remaining_time_s_slicer = 0;
|
||||
|
||||
if (slicer_estimated_print_time_s > 0)
|
||||
{
|
||||
remaining_time_s_slicer = slicer_estimated_print_time_s - printer_data.printed_time_s;
|
||||
}
|
||||
|
||||
if (remaining_time_s_slicer <= 0 || printer_config->remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE)
|
||||
{
|
||||
printer_data.remaining_time_s = remaining_time_s_percentage;
|
||||
}
|
||||
else if (printer_config->remaining_time_calc_mode == REMAINING_TIME_CALC_INTERPOLATED)
|
||||
{
|
||||
printer_data.remaining_time_s = remaining_time_s_percentage * printer_data.print_progress + remaining_time_s_slicer * (1 - printer_data.print_progress);
|
||||
}
|
||||
else if (printer_config->remaining_time_calc_mode == REMAINING_TIME_CALC_SLICER)
|
||||
{
|
||||
printer_data.remaining_time_s = remaining_time_s_slicer;
|
||||
}
|
||||
}
|
||||
|
||||
if (printer_data.remaining_time_s < 0)
|
||||
{
|
||||
printer_data.remaining_time_s = 0;
|
||||
}
|
||||
|
||||
if (printer_data.state == PrinterStateIdle)
|
||||
{
|
||||
slicer_estimated_print_time_s = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (printer_data.state == PrinterStatePrinting && millis() - last_slicer_time_query > 30000 && slicer_estimated_print_time_s <= 0)
|
||||
{
|
||||
last_slicer_time_query = millis();
|
||||
slicer_estimated_print_time_s = get_slicer_time_estimate_s();
|
||||
}
|
||||
}
|
||||
|
||||
void KlipperPrinter::parse_state_min(JsonDocument &in, PrinterDataMinimal* data)
|
||||
{
|
||||
JsonObject status = in["result"]["status"];
|
||||
|
||||
if (status.containsKey("webhooks"))
|
||||
{
|
||||
const char *state = status["webhooks"]["state"];
|
||||
|
||||
if (strcmp(state, "shutdown") == 0)
|
||||
{
|
||||
data->state = PrinterState::PrinterStateError;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->state != PrinterStateError)
|
||||
{
|
||||
if (status.containsKey("virtual_sdcard"))
|
||||
{
|
||||
data->print_progress = status["virtual_sdcard"]["progress"];
|
||||
}
|
||||
|
||||
if (status.containsKey("print_stats"))
|
||||
{
|
||||
const char *state = status["print_stats"]["state"];
|
||||
|
||||
if (state == nullptr)
|
||||
{
|
||||
data->state = PrinterState::PrinterStateError;
|
||||
}
|
||||
else if (strcmp(state, "printing") == 0)
|
||||
{
|
||||
data->state = PrinterState::PrinterStatePrinting;
|
||||
}
|
||||
else if (strcmp(state, "paused") == 0)
|
||||
{
|
||||
data->state = PrinterState::PrinterStatePaused;
|
||||
}
|
||||
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
|
||||
{
|
||||
data->state = PrinterState::PrinterStateIdle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Macros KlipperPrinter::parse_macros(JsonDocument &in)
|
||||
{
|
||||
JsonObject result = in["result"];
|
||||
Macros macros = {0};
|
||||
macros.macros = (char **)malloc(sizeof(char *) * 32);
|
||||
macros.count = 0;
|
||||
macros.success = true;
|
||||
|
||||
for (JsonPair i : result)
|
||||
{
|
||||
const char *key = i.key().c_str();
|
||||
const char *value = i.value().as<String>().c_str();
|
||||
if (strcmp(value, "CYD_SCREEN_MACRO") == 0)
|
||||
{
|
||||
char *macro = (char *)malloc(strlen(key) + 1);
|
||||
strcpy(macro, key);
|
||||
macros.macros[macros.count++] = macro;
|
||||
}
|
||||
}
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
int KlipperPrinter::parse_macros_count(JsonDocument &in)
|
||||
{
|
||||
JsonObject result = in["result"];
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (JsonPair i : result)
|
||||
{
|
||||
const char *value = i.value().as<String>().c_str();
|
||||
if (strcmp(value, "CYD_SCREEN_MACRO") == 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
PowerDevices KlipperPrinter::parse_power_devices(JsonDocument &in)
|
||||
{
|
||||
PowerDevices power_devices = {0};
|
||||
JsonArray result = in["result"]["devices"];
|
||||
power_devices.power_devices = (char **)malloc(sizeof(char *) * 16);
|
||||
power_devices.power_states = (bool *)malloc(sizeof(bool) * 16);
|
||||
power_devices.count = 0;
|
||||
power_devices.success = true;
|
||||
|
||||
for (JsonObject i : result)
|
||||
{
|
||||
const char *device_name = i["device"];
|
||||
const char *device_state = i["status"];
|
||||
power_devices.power_devices[power_devices.count] = (char *)malloc(strlen(device_name) + 1);
|
||||
strcpy(power_devices.power_devices[power_devices.count], device_name);
|
||||
power_devices.power_states[power_devices.count] = strcmp(device_state, "on") == 0;
|
||||
power_devices.count++;
|
||||
}
|
||||
|
||||
return power_devices;
|
||||
}
|
||||
|
||||
int KlipperPrinter::parse_power_devices_count(JsonDocument &in)
|
||||
{
|
||||
JsonArray result = in["result"]["devices"];
|
||||
int count = 0;
|
||||
|
||||
for (JsonObject i : result)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void KlipperPrinter::parse_file_list(JsonDocument &in, std::list<KlipperFileSystemFile> &files, int fetch_limit)
|
||||
{
|
||||
JsonArray result = in["result"];
|
||||
|
||||
for (JsonObject file : result)
|
||||
{
|
||||
KlipperFileSystemFile f = {0};
|
||||
const char *path = file["path"];
|
||||
float modified = file["modified"];
|
||||
auto file_iter = files.begin();
|
||||
|
||||
while (file_iter != files.end())
|
||||
{
|
||||
if ((*file_iter).modified < modified)
|
||||
break;
|
||||
|
||||
file_iter++;
|
||||
}
|
||||
|
||||
if (file_iter == files.end() && files.size() >= fetch_limit)
|
||||
continue;
|
||||
|
||||
f.name = (char *)malloc(strlen(path) + 1);
|
||||
if (f.name == NULL)
|
||||
{
|
||||
LOG_LN("Failed to allocate memory");
|
||||
continue;
|
||||
}
|
||||
strcpy(f.name, path);
|
||||
f.modified = modified;
|
||||
|
||||
if (file_iter != files.end())
|
||||
files.insert(file_iter, f);
|
||||
else
|
||||
files.push_back(f);
|
||||
|
||||
if (files.size() > fetch_limit)
|
||||
{
|
||||
auto last_entry = files.back();
|
||||
|
||||
if (last_entry.name != NULL)
|
||||
free(last_entry.name);
|
||||
|
||||
files.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *KlipperPrinter::parse_thumbnails(JsonDocument &in)
|
||||
{
|
||||
JsonArray result = in["result"];
|
||||
const char *chosen_thumb = NULL;
|
||||
for (JsonObject file : result)
|
||||
{
|
||||
int width = file["width"];
|
||||
int height = file["height"];
|
||||
int size = file["size"];
|
||||
const char *thumbnail = file["thumbnail_path"];
|
||||
|
||||
if (width != height || width != 32)
|
||||
continue;
|
||||
|
||||
if (strcmp(thumbnail + strlen(thumbnail) - 4, ".png"))
|
||||
continue;
|
||||
|
||||
chosen_thumb = thumbnail;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chosen_thumb != NULL)
|
||||
{
|
||||
char* img_filename_path = (char *)malloc(strlen(chosen_thumb) + 1);
|
||||
strcpy(img_filename_path, chosen_thumb);
|
||||
return img_filename_path;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
304
CYD-Klipper/src/core/lv_setup.cpp
Normal file
304
CYD-Klipper/src/core/lv_setup.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
#include "lv_setup.h"
|
||||
#include "screen_driver.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include "../ui/ui_utils.h"
|
||||
#include <Esp.h>
|
||||
#include "../ui/serial/serial_console.h"
|
||||
|
||||
#ifndef CPU_FREQ_HIGH
|
||||
#define CPU_FREQ_HIGH 240
|
||||
#endif
|
||||
#ifndef CPU_FREQ_LOW
|
||||
#define CPU_FREQ_LOW 80
|
||||
#endif
|
||||
|
||||
unsigned long last_milis = 0;
|
||||
|
||||
void lv_handler()
|
||||
{
|
||||
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
|
||||
if (digitalRead(0) == HIGH)
|
||||
{
|
||||
last_milis = millis();
|
||||
}
|
||||
else if (millis() - last_milis > 8000)
|
||||
{
|
||||
global_config.screen_calibrated = false;
|
||||
write_global_config();
|
||||
ESP.restart();
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
}
|
||||
|
||||
typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
bool is_screen_in_sleep = false;
|
||||
lv_timer_t *screen_sleep_timer;
|
||||
lv_coord_t point[2] = {0};
|
||||
|
||||
static lv_indev_drv_read_cb_t original_touch_driver = NULL;
|
||||
|
||||
void lv_touch_intercept_calibration(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
original_touch_driver(indev_driver, data);
|
||||
|
||||
if (data->state == LV_INDEV_STATE_PR){
|
||||
lv_coord_t local_point[] = {data->point.x, data->point.y};
|
||||
while (data->state == LV_INDEV_STATE_PR){
|
||||
original_touch_driver(indev_driver, data);
|
||||
delay(20);
|
||||
}
|
||||
|
||||
point[0] = local_point[0];
|
||||
point[1] = local_point[1];
|
||||
}
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
original_touch_driver(indev_driver, data);
|
||||
|
||||
if (data->state == LV_INDEV_STATE_PR) {
|
||||
if (is_screen_asleep()) {
|
||||
while (data->state == LV_INDEV_STATE_PR) {
|
||||
original_touch_driver(indev_driver, data);
|
||||
delay(20);
|
||||
}
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
delay(300); // Some screens don't debounce their signal properly
|
||||
}
|
||||
|
||||
screen_timer_wake();
|
||||
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
|
||||
data->point.x = round((data->point.x * global_config.screen_cal_x_mult) + global_config.screen_cal_x_offset);
|
||||
data->point.y = round((data->point.y * global_config.screen_cal_y_mult) + global_config.screen_cal_y_offset);
|
||||
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
|
||||
}
|
||||
}
|
||||
|
||||
void lv_do_calibration(){
|
||||
if (global_config.screen_calibrated){
|
||||
return;
|
||||
}
|
||||
|
||||
lv_indev_t * display_driver = lv_indev_get_next(NULL);
|
||||
display_driver->driver->read_cb = lv_touch_intercept_calibration;
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Calibrate Screen");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lv_obj_t * line_x = lv_line_create(lv_scr_act());
|
||||
lv_obj_t * line_y = lv_line_create(lv_scr_act());
|
||||
|
||||
static lv_point_t line_points_x[] = { {0, 10}, {21, 10} };
|
||||
static lv_point_t line_points_y[] = { {10, 0}, {10, 21} };
|
||||
|
||||
lv_line_set_points(line_x, line_points_x, 2);
|
||||
lv_obj_set_style_line_width(line_x, 1, 0);
|
||||
lv_line_set_points(line_y, line_points_y, 2);
|
||||
lv_obj_set_style_line_width(line_y, 1, 0);
|
||||
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
|
||||
lv_obj_align(line_x, LV_ALIGN_TOP_RIGHT, 1, 0);
|
||||
lv_obj_align(line_y, LV_ALIGN_TOP_RIGHT, -10, 0);
|
||||
#else
|
||||
lv_obj_align(line_x, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
lv_obj_align(line_y, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
#endif
|
||||
|
||||
while (true){
|
||||
lv_handler();
|
||||
serial_console::run();
|
||||
|
||||
if (point[0] != 0 && point[1] != 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delay(300);
|
||||
|
||||
lv_coord_t x1 = point[0];
|
||||
lv_coord_t y1 = point[1];
|
||||
point[0] = 0;
|
||||
point[1] = 0;
|
||||
|
||||
lv_obj_del(line_x);
|
||||
lv_obj_del(line_y);
|
||||
|
||||
line_x = lv_line_create(lv_scr_act());
|
||||
line_y = lv_line_create(lv_scr_act());
|
||||
lv_line_set_points(line_x, line_points_x, 2);
|
||||
lv_line_set_points(line_y, line_points_y, 2);
|
||||
lv_obj_set_style_line_width(line_x, 1, 0);
|
||||
lv_obj_set_style_line_width(line_y, 1, 0);
|
||||
|
||||
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
|
||||
lv_obj_align(line_x, LV_ALIGN_BOTTOM_LEFT, 0, -10);
|
||||
lv_obj_align(line_y, LV_ALIGN_BOTTOM_LEFT, 0, 1);
|
||||
#else
|
||||
lv_obj_align(line_x, LV_ALIGN_BOTTOM_RIGHT, 1, -10);
|
||||
lv_obj_align(line_y, LV_ALIGN_BOTTOM_RIGHT, -10, 1);
|
||||
#endif
|
||||
|
||||
while (true){
|
||||
lv_handler();
|
||||
|
||||
if (point[0] != 0 && point[1] != 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lv_coord_t x2 = point[0];
|
||||
lv_coord_t y2 = point[1];
|
||||
|
||||
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
|
||||
int16_t xDist = CYD_SCREEN_HEIGHT_PX - 20;
|
||||
int16_t yDist = CYD_SCREEN_WIDTH_PX - 20;
|
||||
#else
|
||||
int16_t xDist = CYD_SCREEN_WIDTH_PX - 20;
|
||||
int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20;
|
||||
#endif
|
||||
|
||||
global_config.screen_cal_x_mult = (float)xDist / (float)(x2 - x1);
|
||||
global_config.screen_cal_x_offset = 10.0 - ((float)x1 * global_config.screen_cal_x_mult);
|
||||
|
||||
global_config.screen_cal_y_mult = (float)yDist / (float)(y2 - y1);
|
||||
global_config.screen_cal_y_offset = 10.0 - ((float)y1 * global_config.screen_cal_y_mult);
|
||||
|
||||
if (global_config.screen_cal_x_mult == std::numeric_limits<float>::infinity() || global_config.screen_cal_y_mult == std::numeric_limits<float>::infinity()){
|
||||
LOG_LN("Calibration failed, please try again");
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
global_config.screen_calibrated = true;
|
||||
write_global_config();
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
LOG_F(("Calibration done: X*%.2f + %.2f, Y*%.2f + %.2f\n", global_config.screen_cal_x_mult, global_config.screen_cal_x_offset, global_config.screen_cal_y_mult, global_config.screen_cal_y_offset))
|
||||
}
|
||||
|
||||
void set_screen_brightness()
|
||||
{
|
||||
if (global_config.brightness < 32)
|
||||
screen_setBrightness(255);
|
||||
else
|
||||
screen_setBrightness(global_config.brightness);
|
||||
}
|
||||
|
||||
void screen_timer_wake()
|
||||
{
|
||||
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
|
||||
lv_timer_reset(screen_sleep_timer);
|
||||
|
||||
if (!is_screen_in_sleep){
|
||||
return;
|
||||
}
|
||||
|
||||
is_screen_in_sleep = false;
|
||||
set_screen_brightness();
|
||||
|
||||
// Reset cpu freq
|
||||
setCpuFrequencyMhz(CPU_FREQ_HIGH);
|
||||
LOG_F(("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz()))
|
||||
#endif
|
||||
}
|
||||
|
||||
void screen_timer_sleep(lv_timer_t *timer)
|
||||
{
|
||||
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
|
||||
screen_setBrightness(0);
|
||||
is_screen_in_sleep = true;
|
||||
|
||||
// Screen is off, no need to make the cpu run fast, the user won't notice ;)
|
||||
setCpuFrequencyMhz(CPU_FREQ_LOW);
|
||||
LOG_F(("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz()))
|
||||
#endif
|
||||
}
|
||||
|
||||
void screen_timer_setup()
|
||||
{
|
||||
screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screen_timeout * 1000 * 60, NULL);
|
||||
lv_timer_pause(screen_sleep_timer);
|
||||
}
|
||||
|
||||
void screen_timer_start()
|
||||
{
|
||||
lv_timer_resume(screen_sleep_timer);
|
||||
}
|
||||
|
||||
void screen_timer_stop()
|
||||
{
|
||||
lv_timer_pause(screen_sleep_timer);
|
||||
}
|
||||
|
||||
void screen_timer_period(unsigned int period)
|
||||
{
|
||||
lv_timer_set_period(screen_sleep_timer, period);
|
||||
}
|
||||
|
||||
void set_screen_timer_period()
|
||||
{
|
||||
screen_timer_period(global_config.screen_timeout * 1000 * 60);
|
||||
}
|
||||
|
||||
void set_color_scheme()
|
||||
{
|
||||
PrinterConfiguration *config = &global_config.printer_config[global_config.printer_index];
|
||||
lv_disp_t *dispp = lv_disp_get_default();
|
||||
lv_color_t main_color = {0};
|
||||
ColorDefinition color_def = color_defs[config->color_scheme];
|
||||
|
||||
if (color_defs[config->color_scheme].primary_color_light > 0){
|
||||
main_color = lv_palette_lighten(color_def.primary_color, color_def.primary_color_light);
|
||||
}
|
||||
else if (color_defs[config->color_scheme].primary_color_light < 0) {
|
||||
main_color = lv_palette_darken(color_def.primary_color, color_def.primary_color_light * -1);
|
||||
}
|
||||
else {
|
||||
main_color = lv_palette_main(color_defs[config->color_scheme].primary_color);
|
||||
}
|
||||
|
||||
lv_theme_t *theme = lv_theme_default_init(dispp, main_color, lv_palette_main(color_def.secondary_color), !config->light_mode, &CYD_SCREEN_FONT);
|
||||
lv_disp_set_theme(dispp, theme);
|
||||
}
|
||||
|
||||
void lv_setup()
|
||||
{
|
||||
set_screen_brightness();
|
||||
|
||||
lv_indev_t * display_driver = lv_indev_get_next(NULL);
|
||||
|
||||
if (original_touch_driver == NULL)
|
||||
{
|
||||
original_touch_driver = display_driver->driver->read_cb;
|
||||
}
|
||||
|
||||
set_color_scheme();
|
||||
|
||||
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
|
||||
lv_do_calibration();
|
||||
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
|
||||
|
||||
display_driver->driver->read_cb = lv_touch_intercept;
|
||||
|
||||
screen_timer_setup();
|
||||
screen_timer_start();
|
||||
lv_png_init();
|
||||
}
|
||||
|
||||
bool is_screen_asleep()
|
||||
{
|
||||
return is_screen_in_sleep;
|
||||
}
|
||||
11
CYD-Klipper/src/core/lv_setup.h
Normal file
11
CYD-Klipper/src/core/lv_setup.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
void set_screen_brightness();
|
||||
void set_screen_timer_period();
|
||||
void screen_timer_wake();
|
||||
void screen_timer_start();
|
||||
void screen_timer_stop();
|
||||
void set_color_scheme();
|
||||
void lv_setup();
|
||||
bool is_screen_asleep();
|
||||
void lv_handler();
|
||||
450
CYD-Klipper/src/core/octoprint/octoprint_printer_integration.cpp
Normal file
450
CYD-Klipper/src/core/octoprint/octoprint_printer_integration.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
#include "octoprint_printer_integration.hpp"
|
||||
#include "../../conf/global_config.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <UrlEncode.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <list>
|
||||
|
||||
const char* COMMAND_CONNECT = "{\"command\":\"connect\"}";
|
||||
const char* COMMAND_DISCONNECT = "{\"command\":\"disconnect\"}";
|
||||
const char* COMMAND_HOME = "{\"command\":\"home\",\"axes\":[\"x\",\"y\",\"z\"]}";
|
||||
const char* COMMAND_PRINT = "{\"command\":\"select\",\"print\":true}";
|
||||
const char* COMMAND_CANCEL_PRINT = "{\"command\":\"cancel\"}";
|
||||
const char* COMMAND_PAUSE_PRINT = "{\"command\":\"pause\",\"action\":\"pause\"}";
|
||||
const char* COMMAND_RESUME_PRINT = "{\"command\":\"pause\",\"action\":\"resume\"}";
|
||||
const char* COMMAND_EXTRUDE = "{\"command\":\"extrude\",\"amount\":25}";
|
||||
const char* COMMAND_RETRACT = "{\"command\":\"extrude\",\"amount\":-25}";
|
||||
|
||||
void configure_http_client(HTTPClient &client, String url_part, bool stream, int timeout, PrinterConfiguration* printer_config)
|
||||
{
|
||||
client.useHTTP10(stream);
|
||||
|
||||
if (timeout > 0){
|
||||
client.setTimeout(timeout);
|
||||
client.setConnectTimeout(timeout);
|
||||
}
|
||||
|
||||
client.begin("http://" + String(printer_config->printer_host) + ":" + String(printer_config->klipper_port) + url_part);
|
||||
|
||||
if (printer_config->auth_configured) {
|
||||
client.addHeader("X-Api-Key", printer_config->printer_auth);
|
||||
}
|
||||
}
|
||||
|
||||
bool OctoPrinter::get_request(const char* endpoint, int timeout_ms)
|
||||
{
|
||||
HTTPClient client;
|
||||
|
||||
if (timeout_ms <= 0)
|
||||
{
|
||||
timeout_ms = 500;
|
||||
}
|
||||
|
||||
configure_http_client(client, endpoint, false, timeout_ms, printer_config);
|
||||
int result = client.GET();
|
||||
return result >= 200 && result < 300;
|
||||
}
|
||||
|
||||
bool OctoPrinter::post_request(const char* endpoint, const char* body, int timeout_ms)
|
||||
{
|
||||
HTTPClient client;
|
||||
|
||||
if (timeout_ms <= 0)
|
||||
{
|
||||
timeout_ms = 500;
|
||||
}
|
||||
|
||||
LOG_F(("POST >>> %s %s\n", endpoint, body));
|
||||
configure_http_client(client, endpoint, false, timeout_ms, printer_config);
|
||||
|
||||
if (body[0] == '{' || body[0] == '[')
|
||||
{
|
||||
client.addHeader("Content-Type", "application/json");
|
||||
}
|
||||
|
||||
int http_code = client.POST(body);
|
||||
bool result = http_code >= 200 && http_code < 300;
|
||||
LOG_F(("<<< %d\n", http_code));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OctoPrinter::send_gcode(const char* gcode, bool wait)
|
||||
{
|
||||
char* gcode_copy = (char*)malloc(sizeof(char) * (strlen(gcode) + 1));
|
||||
size_t out_buff_size = sizeof(char) * (strlen(gcode) * 2 + 51);
|
||||
char* out_buff = (char*)malloc(out_buff_size);
|
||||
strcpy(gcode_copy, gcode);
|
||||
JsonDocument doc;
|
||||
JsonArray array = doc["commands"].to<JsonArray>();
|
||||
const char* last_line_start = gcode_copy;
|
||||
|
||||
for (char* iter = gcode_copy;; iter++)
|
||||
{
|
||||
char cur_iter = *iter;
|
||||
if (cur_iter == '\n' || cur_iter == '\0')
|
||||
{
|
||||
if (iter != last_line_start)
|
||||
{
|
||||
*iter = '\0';
|
||||
array.add(last_line_start);
|
||||
}
|
||||
|
||||
last_line_start = iter + 1;
|
||||
}
|
||||
|
||||
if (cur_iter == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (serializeJson(doc, out_buff, out_buff_size) == out_buff_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
free(gcode_copy);
|
||||
bool result = post_request("/api/printer/command", out_buff);
|
||||
free(out_buff);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OctoPrinter::move_printer(const char* axis, float amount, bool relative)
|
||||
{
|
||||
JsonDocument doc;
|
||||
char out_buff[512];
|
||||
out_buff[0] = tolower(axis[0]);
|
||||
out_buff[1] = '\0';
|
||||
|
||||
doc["command"] = "jog";
|
||||
doc[out_buff] = amount;
|
||||
doc["absolute"] = !relative;
|
||||
|
||||
if (serializeJson(doc, out_buff, 512) >= 512)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return post_request("/api/printer/printhead", out_buff);
|
||||
}
|
||||
|
||||
bool OctoPrinter::execute_feature(PrinterFeatures feature)
|
||||
{
|
||||
switch (feature)
|
||||
{
|
||||
case PrinterFeatureRetryError:
|
||||
if (no_printer)
|
||||
{
|
||||
bool a = post_request("/api/connection", COMMAND_CONNECT);
|
||||
LOG_F(("Retry error: %d\n", a));
|
||||
return a;
|
||||
}
|
||||
case PrinterFeatureHome:
|
||||
return post_request("/api/printer/printhead", COMMAND_HOME);
|
||||
case PrinterFeatureDisableSteppers:
|
||||
return send_gcode("M18");
|
||||
case PrinterFeaturePause:
|
||||
return post_request("/api/job", COMMAND_PAUSE_PRINT);
|
||||
case PrinterFeatureResume:
|
||||
return post_request("/api/job", COMMAND_RESUME_PRINT);
|
||||
case PrinterFeatureStop:
|
||||
return post_request("/api/job", COMMAND_CANCEL_PRINT);
|
||||
case PrinterFeatureCooldown:
|
||||
return set_target_temperature(PrinterTemperatureDeviceNozzle1, 0)
|
||||
&& set_target_temperature(PrinterTemperatureDeviceBed, 0);
|
||||
case PrinterFeatureExtrude:
|
||||
return post_request("/api/printer/tool", COMMAND_EXTRUDE);
|
||||
case PrinterFeatureRetract:
|
||||
return post_request("/api/printer/tool", COMMAND_RETRACT);
|
||||
default:
|
||||
LOG_F(("Unsupported printer feature %d", feature));
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OctoPrinter::connect()
|
||||
{
|
||||
return connection_test_octoprint(printer_config) == OctoConnectionStatus::OctoConnectOk;
|
||||
}
|
||||
|
||||
bool OctoPrinter::fetch()
|
||||
{
|
||||
HTTPClient client;
|
||||
HTTPClient client2;
|
||||
configure_http_client(client, "/api/printer", true, 1000, printer_config);
|
||||
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
no_printer = false;
|
||||
request_consecutive_fail_count = 0;
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
parse_printer_status(doc);
|
||||
|
||||
doc.clear();
|
||||
configure_http_client(client2, "/api/job", true, 1000, printer_config);
|
||||
if (client2.GET() == 200)
|
||||
{
|
||||
deserializeJson(doc, client2.getStream());
|
||||
parse_job_state(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_data.state = PrinterStateOffline;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (http_code == 409)
|
||||
{
|
||||
no_printer = true;
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
parse_error(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
request_consecutive_fail_count++;
|
||||
LOG_LN("Failed to fetch printer data");
|
||||
|
||||
if (request_consecutive_fail_count >= 5)
|
||||
{
|
||||
printer_data.state = PrinterStateOffline;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PrinterDataMinimal OctoPrinter::fetch_min()
|
||||
{
|
||||
PrinterDataMinimal min = {};
|
||||
min.success = true;
|
||||
min.print_progress = 0;
|
||||
min.power_devices = 0;
|
||||
min.state = PrinterState::PrinterStateOffline;
|
||||
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/api/printer", true, 1000, printer_config);
|
||||
int http_code = client.GET();
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
min.state = parse_printer_state(doc);
|
||||
}
|
||||
else if (http_code == 409)
|
||||
{
|
||||
min.state = PrinterState::PrinterStateError;
|
||||
return min;
|
||||
}
|
||||
else
|
||||
{
|
||||
return min;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/api/job", true, 1000, printer_config);
|
||||
|
||||
if (client.GET() == 200)
|
||||
{
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, client.getStream());
|
||||
min.print_progress = parse_job_state_progress(doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
min.state = PrinterState::PrinterStateError;
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
void OctoPrinter::disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
const char* MACRO_AUTOLEVEL = "Auto-Level (G28+G29)";
|
||||
const char* MACRO_DISCONNECT = "Disconnect printer";
|
||||
|
||||
Macros OctoPrinter::get_macros()
|
||||
{
|
||||
if (printer_data.state == PrinterStatePrinting || printer_data.state == PrinterStateOffline)
|
||||
{
|
||||
Macros macros = {0};
|
||||
macros.success = false;
|
||||
return macros;
|
||||
}
|
||||
|
||||
Macros macros = {0};
|
||||
macros.count = 2;
|
||||
macros.macros = (char **)malloc(sizeof(char *) * macros.count);
|
||||
macros.macros[0] = (char *)malloc(strlen(MACRO_AUTOLEVEL) + 1);
|
||||
strcpy(macros.macros[0], MACRO_AUTOLEVEL);
|
||||
macros.macros[1] = (char *)malloc(strlen(MACRO_DISCONNECT) + 1);
|
||||
strcpy(macros.macros[1], MACRO_DISCONNECT);
|
||||
macros.success = true;
|
||||
return macros;
|
||||
}
|
||||
|
||||
int OctoPrinter::get_macros_count()
|
||||
{
|
||||
return (printer_data.state == PrinterStatePrinting || printer_data.state == PrinterStateOffline) ? 0 : 2;
|
||||
}
|
||||
|
||||
bool OctoPrinter::execute_macro(const char* macro)
|
||||
{
|
||||
if (strcmp(macro, MACRO_AUTOLEVEL) == 0)
|
||||
{
|
||||
return send_gcode("G28\nG29");
|
||||
}
|
||||
else if (strcmp(macro, MACRO_DISCONNECT) == 0)
|
||||
{
|
||||
if (printer_data.state == PrinterStatePrinting || printer_data.state == PrinterStateOffline)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return post_request("/api/connection", COMMAND_DISCONNECT);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PowerDevices OctoPrinter::get_power_devices()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
int OctoPrinter::get_power_devices_count()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool OctoPrinter::set_power_device_state(const char* device_name, bool state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#define OCTO_FILE_FETCH_LIMIT 20
|
||||
|
||||
Files OctoPrinter::get_files()
|
||||
{
|
||||
LOG_F(("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()));
|
||||
|
||||
Files files_result = {0};
|
||||
HTTPClient client;
|
||||
JsonDocument filter;
|
||||
std::list<OctoFileSystemFile> files;
|
||||
|
||||
filter["files"][0]["path"] = true;
|
||||
filter["files"][0]["date"] = true;
|
||||
filter["files"][0]["origin"] = true;
|
||||
|
||||
auto timer_request = millis();
|
||||
configure_http_client(client, "/api/files?recursive=true", true, 5000, printer_config);
|
||||
|
||||
int http_code = client.GET();
|
||||
auto timer_parse = millis();
|
||||
|
||||
if (http_code == 200)
|
||||
{
|
||||
JsonDocument doc;
|
||||
auto parseResult = deserializeJson(doc, client.getStream(), DeserializationOption::Filter(filter));
|
||||
LOG_F(("Json parse: %s\n", parseResult.c_str()))
|
||||
parse_file_list(doc, files, OCTO_FILE_FETCH_LIMIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return files_result;
|
||||
}
|
||||
|
||||
files_result.available_files = (char**)malloc(sizeof(char*) * files.size());
|
||||
|
||||
if (files_result.available_files == NULL){
|
||||
LOG_LN("Failed to allocate memory");
|
||||
|
||||
for (auto file : files){
|
||||
free(file.name);
|
||||
}
|
||||
|
||||
return files_result;
|
||||
}
|
||||
|
||||
for (auto file : files){
|
||||
files_result.available_files[files_result.count++] = file.name;
|
||||
}
|
||||
|
||||
files_result.success = true;
|
||||
|
||||
LOG_F(("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()))
|
||||
LOG_F(("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse))
|
||||
return files_result;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool OctoPrinter::start_file(const char* filename)
|
||||
{
|
||||
char buff[512];
|
||||
sprintf(buff, "/api/files/local/%s", filename);
|
||||
return post_request(buff, COMMAND_PRINT);
|
||||
}
|
||||
|
||||
Thumbnail OctoPrinter::get_32_32_png_image_thumbnail(const char* gcode_filename)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool OctoPrinter::set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature)
|
||||
{
|
||||
JsonDocument doc;
|
||||
char out_buff[512];
|
||||
|
||||
doc["command"] = "target";
|
||||
|
||||
if (device == PrinterTemperatureDevice::PrinterTemperatureDeviceNozzle1)
|
||||
{
|
||||
doc["targets"]["tool0"] = temperature;
|
||||
}
|
||||
else
|
||||
{
|
||||
doc["target"] = temperature;
|
||||
}
|
||||
|
||||
if (serializeJson(doc, out_buff, 512) >= 512)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return post_request(device == PrinterTemperatureDevice::PrinterTemperatureDeviceBed ? "/api/printer/bed" : "/api/printer/tool", out_buff);
|
||||
}
|
||||
|
||||
OctoConnectionStatus connection_test_octoprint(PrinterConfiguration* config)
|
||||
{
|
||||
HTTPClient client;
|
||||
configure_http_client(client, "/api/version", false, 1000, config);
|
||||
|
||||
int http_code = client.GET();
|
||||
if (http_code == 200)
|
||||
{
|
||||
return OctoConnectionStatus::OctoConnectOk;
|
||||
}
|
||||
else if (http_code == 401 || http_code == 403)
|
||||
{
|
||||
return OctoConnectionStatus::OctoConnectKeyFail;
|
||||
}
|
||||
else
|
||||
{
|
||||
return OctoConnectionStatus::OctoConnectFail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "../printer_integration.hpp"
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <list>
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
float modified;
|
||||
} OctoFileSystemFile;
|
||||
|
||||
class OctoPrinter : public BasePrinter
|
||||
{
|
||||
protected:
|
||||
bool no_printer = false;
|
||||
unsigned char request_consecutive_fail_count{};
|
||||
|
||||
void parse_printer_status(JsonDocument& in);
|
||||
PrinterState parse_printer_state(JsonDocument& in);
|
||||
void parse_job_state(JsonDocument& in);
|
||||
float parse_job_state_progress(JsonDocument& in);
|
||||
void parse_error(JsonDocument& in);
|
||||
void parse_file_list(JsonDocument &in, std::list<OctoFileSystemFile> &files, int fetch_limit);
|
||||
|
||||
bool get_request(const char* endpoint, int timeout_ms = 1000);
|
||||
void init_ui_panels();
|
||||
|
||||
public:
|
||||
OctoPrinter(int index) : BasePrinter(index)
|
||||
{
|
||||
supported_features = PrinterFeatureHome
|
||||
| PrinterFeatureDisableSteppers
|
||||
| PrinterFeaturePause
|
||||
| PrinterFeatureResume
|
||||
| PrinterFeatureStop
|
||||
| PrinterFeatureExtrude
|
||||
| PrinterFeatureRetract
|
||||
| PrinterFeatureCooldown
|
||||
| PrinterFeatureRetryError;
|
||||
|
||||
supported_temperature_devices = PrinterTemperatureDeviceBed
|
||||
| PrinterTemperatureDeviceNozzle1;
|
||||
|
||||
printer_data.error_screen_features = PrinterFeatureRetryError;
|
||||
|
||||
init_ui_panels();
|
||||
}
|
||||
|
||||
bool post_request(const char* endpoint, const char* body, int timeout_ms = 1000);
|
||||
bool move_printer(const char* axis, float amount, bool relative);
|
||||
bool execute_feature(PrinterFeatures feature);
|
||||
bool connect();
|
||||
bool fetch();
|
||||
PrinterDataMinimal fetch_min();
|
||||
void disconnect();
|
||||
|
||||
Macros get_macros();
|
||||
int get_macros_count();
|
||||
bool execute_macro(const char* macro);
|
||||
|
||||
PowerDevices get_power_devices();
|
||||
int get_power_devices_count();
|
||||
bool set_power_device_state(const char* device_name, bool state);
|
||||
|
||||
Files get_files();
|
||||
bool start_file(const char* filename);
|
||||
|
||||
Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename);
|
||||
bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature);
|
||||
|
||||
bool send_gcode(const char* gcode, bool wait = true);
|
||||
};
|
||||
|
||||
enum OctoConnectionStatus {
|
||||
OctoConnectFail = 0,
|
||||
OctoConnectOk = 1,
|
||||
OctoConnectKeyFail = 2,
|
||||
};
|
||||
|
||||
OctoConnectionStatus connection_test_octoprint(PrinterConfiguration* config);
|
||||
111
CYD-Klipper/src/core/octoprint/octoprint_printer_panels.cpp
Normal file
111
CYD-Klipper/src/core/octoprint/octoprint_printer_panels.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "octoprint_printer_integration.hpp"
|
||||
#include "lvgl.h"
|
||||
#include "../../ui/ui_utils.h"
|
||||
#include <stdio.h>
|
||||
#include "../common/constants.h"
|
||||
|
||||
const char* COMMAND_EXTRUDE_MULT = "{\"command\":\"flowrate\",\"factor\":%d}";
|
||||
|
||||
#define OCTO_TIMEOUT_POPUP_MESSAGES 4000
|
||||
|
||||
static void set_fan_speed_text(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, "Fan");
|
||||
}
|
||||
|
||||
static void set_speed_mult_text(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, "Speed");
|
||||
}
|
||||
|
||||
static void set_extruder_mult_text(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
lv_label_set_text(label, "Flowrate");
|
||||
}
|
||||
|
||||
bool get_range(lv_event_t * e, int min, int max, int* out)
|
||||
{
|
||||
char buff[64];
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
const char * txt = lv_textarea_get_text(ta);
|
||||
|
||||
if (txt == NULL || *txt == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int parsed_input = atoi(txt);
|
||||
if (parsed_input < min || parsed_input > max)
|
||||
{
|
||||
sprintf(buff, "Value out of range (%d -> %d)", min, max);
|
||||
lv_create_popup_message(buff, OCTO_TIMEOUT_POPUP_MESSAGES);
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = parsed_input;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_fan_speed(lv_event_t * e)
|
||||
{
|
||||
int speed = (int)lv_event_get_user_data(e);
|
||||
int actual_fan_speed = fan_percent_to_byte(speed);
|
||||
char buff[16];
|
||||
sprintf(buff, "M106 S%d", actual_fan_speed);
|
||||
((OctoPrinter*)get_current_printer())->send_gcode(buff);
|
||||
}
|
||||
|
||||
FAN_SPEED_COLUMN(set_fan_speed, octo_fan_speed_columns)
|
||||
|
||||
static void open_fan_speed_panel(lv_event_t * e)
|
||||
{
|
||||
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, octo_fan_speed_columns, 3);
|
||||
}
|
||||
|
||||
static void set_speed_mult(lv_event_t * e)
|
||||
{
|
||||
int speed_mult = 0;
|
||||
if (get_range(e, 50, 300, &speed_mult))
|
||||
{
|
||||
char buff[16];
|
||||
sprintf(buff, "M220 S%d", speed_mult);
|
||||
((OctoPrinter*)get_current_printer())->send_gcode(buff);
|
||||
}
|
||||
}
|
||||
|
||||
static void open_speed_mult_keypad(lv_event_t * e)
|
||||
{
|
||||
lv_create_keyboard_text_entry(set_speed_mult, "New speed multiplier %", LV_KEYBOARD_MODE_NUMBER);
|
||||
}
|
||||
|
||||
static void set_extrude_mult(lv_event_t * e)
|
||||
{
|
||||
int extrude_mult = 0;
|
||||
if (get_range(e, 75, 125, &extrude_mult))
|
||||
{
|
||||
char buff[64];
|
||||
sprintf(buff, COMMAND_EXTRUDE_MULT, extrude_mult);
|
||||
((OctoPrinter*)get_current_printer())->post_request("/api/printer/tool", buff);
|
||||
}
|
||||
}
|
||||
|
||||
static void open_extrude_mult_keypad(lv_event_t * e)
|
||||
{
|
||||
lv_create_keyboard_text_entry(set_extrude_mult, "New extrude multiplier %", LV_KEYBOARD_MODE_NUMBER);
|
||||
}
|
||||
|
||||
static PrinterUiPanel klipper_ui_panels[4] {
|
||||
{ .set_label = (void*)set_fan_speed_text, .open_panel = (void*)open_fan_speed_panel },
|
||||
{ .set_label = (void*)set_speed_mult_text, .open_panel = (void*)open_speed_mult_keypad },
|
||||
{ .set_label = (void*)set_extruder_mult_text, .open_panel = (void*)open_extrude_mult_keypad },
|
||||
};
|
||||
|
||||
void OctoPrinter::init_ui_panels()
|
||||
{
|
||||
custom_menus_count = 3;
|
||||
custom_menus = klipper_ui_panels;
|
||||
}
|
||||
170
CYD-Klipper/src/core/octoprint/octoprint_printer_parsers.cpp
Normal file
170
CYD-Klipper/src/core/octoprint/octoprint_printer_parsers.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "../printer_integration.hpp"
|
||||
#include "octoprint_printer_integration.hpp"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
PrinterState OctoPrinter::parse_printer_state(JsonDocument& in)
|
||||
{
|
||||
JsonObject flags = in["state"]["flags"];
|
||||
bool cancelling = flags["cancelling"];
|
||||
bool closedOrError = flags["closedOrError"];
|
||||
bool error = flags["error"];
|
||||
bool finishing = flags["finishing"];
|
||||
bool operational = flags["operational"];
|
||||
bool paused = flags["paused"];
|
||||
bool pausing = flags["pausing"];
|
||||
bool printing = flags["printing"];
|
||||
bool ready = flags["ready"];
|
||||
bool resuming = flags["resuming"];
|
||||
bool sdReady = flags["sdReady"];
|
||||
|
||||
if (printing || resuming)
|
||||
{
|
||||
return PrinterState::PrinterStatePrinting;
|
||||
}
|
||||
else if (pausing || paused)
|
||||
{
|
||||
return PrinterState::PrinterStatePaused;
|
||||
}
|
||||
else if (cancelling || finishing || ready)
|
||||
{
|
||||
return PrinterState::PrinterStateIdle;
|
||||
}
|
||||
|
||||
return PrinterState::PrinterStateError;
|
||||
}
|
||||
|
||||
void OctoPrinter::parse_printer_status(JsonDocument& in)
|
||||
{
|
||||
const char* text = in["state"]["text"];
|
||||
printer_data.state = parse_printer_state(in);
|
||||
|
||||
if (printer_data.state == PrinterState::PrinterStateError)
|
||||
{
|
||||
if (text != NULL && (printer_data.state_message == NULL || strcmp(printer_data.state_message, text)))
|
||||
{
|
||||
printer_data.state_message = (char *)malloc(strlen(text) + 1);
|
||||
strcpy(printer_data.state_message, text);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject temperature = in["temperature"];
|
||||
|
||||
if (temperature.containsKey("bed"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexBed] = temperature["bed"]["actual"];
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexBed] = temperature["bed"]["target"];
|
||||
}
|
||||
|
||||
if (temperature.containsKey("tool0"))
|
||||
{
|
||||
printer_data.temperatures[PrinterTemperatureDeviceIndexNozzle1] = temperature["tool0"]["actual"];
|
||||
printer_data.target_temperatures[PrinterTemperatureDeviceIndexNozzle1] = temperature["tool0"]["target"];
|
||||
}
|
||||
|
||||
printer_data.can_extrude = printer_data.temperatures[PrinterTemperatureDeviceIndexNozzle1] >= MIN_EXTRUDER_EXTRUDE_TEMP;
|
||||
printer_data.homed_axis = true;
|
||||
}
|
||||
|
||||
void OctoPrinter::parse_job_state(JsonDocument& in)
|
||||
{
|
||||
JsonObject job = in["job"];
|
||||
|
||||
if (job.containsKey("file"))
|
||||
{
|
||||
const char* name = job["file"]["name"];
|
||||
|
||||
if (name != NULL && (printer_data.print_filename == NULL || strcmp(printer_data.print_filename, name)))
|
||||
{
|
||||
printer_data.print_filename = (char *)malloc(strlen(name) + 1);
|
||||
strcpy(printer_data.print_filename, name);
|
||||
}
|
||||
}
|
||||
|
||||
if (job.containsKey("filament") && job["filament"].as<JsonObject>() != NULL && job["filament"].containsKey("tool0"))
|
||||
{
|
||||
printer_data.filament_used_mm = job["filament"]["tool0"]["length"];
|
||||
}
|
||||
|
||||
JsonObject progress = in["progress"];
|
||||
float completion = progress["completion"];
|
||||
printer_data.print_progress = completion / 100;
|
||||
printer_data.elapsed_time_s = progress["printTime"];
|
||||
printer_data.printed_time_s = progress["printTime"];
|
||||
printer_data.remaining_time_s = progress["printTimeLeft"];
|
||||
}
|
||||
|
||||
float OctoPrinter::parse_job_state_progress(JsonDocument& in)
|
||||
{
|
||||
float completion = in["progress"]["completion"];
|
||||
return completion / 100;
|
||||
}
|
||||
|
||||
void OctoPrinter::parse_error(JsonDocument& in)
|
||||
{
|
||||
const char* error = in["error"];
|
||||
if (error != NULL)
|
||||
{
|
||||
printer_data.state = PrinterState::PrinterStateError;
|
||||
|
||||
if (printer_data.state_message == NULL || strcmp(printer_data.state_message, error))
|
||||
{
|
||||
printer_data.state_message = (char *)malloc(strlen(error) + 1);
|
||||
strcpy(printer_data.state_message, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OctoPrinter::parse_file_list(JsonDocument &in, std::list<OctoFileSystemFile> &files, int fetch_limit)
|
||||
{
|
||||
JsonArray result = in["files"];
|
||||
|
||||
for (JsonObject file : result)
|
||||
{
|
||||
const char *path = file["path"];
|
||||
if (strcmp("local", file["origin"]))
|
||||
{
|
||||
LOG_F(("Skipping non-local file %s\n", path))
|
||||
continue;
|
||||
}
|
||||
|
||||
OctoFileSystemFile f = {0};
|
||||
|
||||
float modified = file["date"];
|
||||
auto file_iter = files.begin();
|
||||
|
||||
while (file_iter != files.end())
|
||||
{
|
||||
if ((*file_iter).modified < modified)
|
||||
break;
|
||||
|
||||
file_iter++;
|
||||
}
|
||||
|
||||
if (file_iter == files.end() && files.size() >= fetch_limit)
|
||||
continue;
|
||||
|
||||
f.name = (char *)malloc(strlen(path) + 1);
|
||||
if (f.name == NULL)
|
||||
{
|
||||
LOG_LN("Failed to allocate memory");
|
||||
continue;
|
||||
}
|
||||
strcpy(f.name, path);
|
||||
f.modified = modified;
|
||||
|
||||
if (file_iter != files.end())
|
||||
files.insert(file_iter, f);
|
||||
else
|
||||
files.push_back(f);
|
||||
|
||||
if (files.size() > fetch_limit)
|
||||
{
|
||||
auto last_entry = files.back();
|
||||
|
||||
if (last_entry.name != NULL)
|
||||
free(last_entry.name);
|
||||
|
||||
files.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
141
CYD-Klipper/src/core/printer_integration.cpp
Normal file
141
CYD-Klipper/src/core/printer_integration.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "printer_integration.hpp"
|
||||
#include "lv_setup.h"
|
||||
#include "screen_driver.h"
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
static char blank[] = { '\0' };
|
||||
static unsigned char current_printer_index = 0;
|
||||
static unsigned char last_announced_printer_index = 0;
|
||||
static unsigned char total_printers;
|
||||
static BasePrinter** registered_printers;
|
||||
static PrinterDataMinimal* minimal_data_copy;
|
||||
static PrinterData* printer_data_copy;
|
||||
|
||||
BasePrinter::BasePrinter(unsigned char index)
|
||||
{
|
||||
config_index = index;
|
||||
printer_config = &global_config.printer_config[index];
|
||||
memset(&printer_data, 0, sizeof(PrinterData));
|
||||
// TODO: Fetch printer config and global config
|
||||
}
|
||||
|
||||
PrinterData* BasePrinter::AnnouncePrinterData()
|
||||
{
|
||||
char* old_state_message = printer_data_copy->state_message;
|
||||
char* old_print_filename = printer_data_copy->print_filename;
|
||||
char* old_popup_message = printer_data_copy->popup_message;
|
||||
PrinterState old_state = printer_data_copy->state;
|
||||
bool no_free = current_printer_index != last_announced_printer_index;
|
||||
|
||||
last_announced_printer_index = current_printer_index;
|
||||
memcpy(printer_data_copy, &printer_data, sizeof(PrinterData));
|
||||
|
||||
if (printer_data_copy->state_message == NULL)
|
||||
{
|
||||
printer_data_copy->state_message = blank;
|
||||
}
|
||||
|
||||
if (printer_data_copy->print_filename == NULL)
|
||||
{
|
||||
printer_data_copy->print_filename = blank;
|
||||
}
|
||||
|
||||
if (printer_data_copy->popup_message == NULL)
|
||||
{
|
||||
printer_data_copy->popup_message = blank;
|
||||
}
|
||||
|
||||
if (old_state_message != printer_data_copy->state_message && old_state_message != NULL && old_state_message != blank && !no_free)
|
||||
{
|
||||
LOG_F(("Freeing state message '%s' (%x)\n", old_state_message, old_state_message));
|
||||
free(old_state_message);
|
||||
}
|
||||
|
||||
if (old_print_filename != printer_data_copy->print_filename && old_print_filename != NULL && old_print_filename != blank && !no_free)
|
||||
{
|
||||
LOG_F(("Freeing print filename '%s' (%x)\n", old_print_filename, old_print_filename));
|
||||
free(old_print_filename);
|
||||
}
|
||||
|
||||
if (old_state != printer_data_copy->state)
|
||||
{
|
||||
lv_msg_send(DATA_PRINTER_STATE, get_current_printer());
|
||||
}
|
||||
|
||||
if (old_popup_message != printer_data_copy->popup_message)
|
||||
{
|
||||
if (old_popup_message != NULL && old_popup_message != blank && !no_free)
|
||||
{
|
||||
LOG_F(("Freeing popup message '%s' (%x)\n", old_popup_message, old_popup_message));
|
||||
free(old_popup_message);
|
||||
}
|
||||
|
||||
if (printer_data_copy->popup_message != NULL && printer_data_copy->popup_message != blank)
|
||||
{
|
||||
lv_msg_send(DATA_PRINTER_POPUP, get_current_printer());
|
||||
}
|
||||
}
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, get_current_printer());
|
||||
return printer_data_copy;
|
||||
}
|
||||
|
||||
void initialize_printers(BasePrinter** printers, unsigned char total)
|
||||
{
|
||||
LOG_F(("Initializing %d printers\n", total))
|
||||
printer_data_copy = (PrinterData*)malloc(sizeof(PrinterData));
|
||||
minimal_data_copy = (PrinterDataMinimal*)malloc(sizeof(PrinterDataMinimal) * total);
|
||||
memset(printer_data_copy, 0, sizeof(PrinterData));
|
||||
memset(minimal_data_copy, 0, sizeof(PrinterDataMinimal) * total);
|
||||
registered_printers = printers;
|
||||
total_printers = total;
|
||||
}
|
||||
|
||||
BasePrinter* get_current_printer()
|
||||
{
|
||||
return get_printer(current_printer_index);
|
||||
}
|
||||
|
||||
BasePrinter* get_printer(int idx)
|
||||
{
|
||||
return registered_printers[idx];
|
||||
}
|
||||
|
||||
bool BasePrinter::supports_feature(PrinterFeatures feature)
|
||||
{
|
||||
return supported_features & feature == feature;
|
||||
}
|
||||
|
||||
int get_current_printer_index()
|
||||
{
|
||||
return current_printer_index;
|
||||
}
|
||||
|
||||
PrinterData* get_current_printer_data()
|
||||
{
|
||||
return printer_data_copy;
|
||||
}
|
||||
|
||||
unsigned int get_printer_count()
|
||||
{
|
||||
return total_printers;
|
||||
}
|
||||
|
||||
void announce_printer_data_minimal(PrinterDataMinimal* printer_data)
|
||||
{
|
||||
memcpy(minimal_data_copy, printer_data, sizeof(PrinterDataMinimal) * total_printers);
|
||||
lv_msg_send(DATA_PRINTER_MINIMAL, get_current_printer());
|
||||
}
|
||||
|
||||
PrinterDataMinimal* get_printer_data_minimal(int idx)
|
||||
{
|
||||
return &(minimal_data_copy[idx]);
|
||||
}
|
||||
|
||||
void set_current_printer(int idx)
|
||||
{
|
||||
current_printer_index = idx;
|
||||
global_config_set_printer(idx);
|
||||
set_color_scheme();
|
||||
set_invert_display();
|
||||
}
|
||||
201
CYD-Klipper/src/core/printer_integration.hpp
Normal file
201
CYD-Klipper/src/core/printer_integration.hpp
Normal file
@@ -0,0 +1,201 @@
|
||||
#pragma once
|
||||
#include "../conf/global_config.h"
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
#define MIN_EXTRUDER_EXTRUDE_TEMP 175
|
||||
|
||||
enum PrinterFeatures {
|
||||
PrinterFeatureRestart = BIT(0),
|
||||
PrinterFeatureFirmwareRestart = BIT(1),
|
||||
PrinterFeatureHome = BIT(2),
|
||||
PrinterFeatureDisableSteppers = BIT(3),
|
||||
PrinterFeaturePause = BIT(4),
|
||||
PrinterFeatureResume = BIT(5),
|
||||
PrinterFeatureStop = BIT(6),
|
||||
PrinterFeatureEmergencyStop = BIT(7),
|
||||
PrinterFeatureExtrude = BIT(8),
|
||||
PrinterFeatureRetract = BIT(9),
|
||||
PrinterFeatureIgnoreError = BIT(10),
|
||||
PrinterFeatureContinueError = BIT(11),
|
||||
PrinterFeatureCooldown = BIT(12),
|
||||
PrinterFeatureRetryError = BIT(13),
|
||||
};
|
||||
|
||||
inline PrinterFeatures operator|(PrinterFeatures a, PrinterFeatures b)
|
||||
{
|
||||
return static_cast<PrinterFeatures>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
enum PrinterTemperatureDevice
|
||||
{
|
||||
PrinterTemperatureDeviceBed = BIT(0),
|
||||
PrinterTemperatureDeviceNozzle1 = BIT(1),
|
||||
PrinterTemperatureDeviceNozzle2 = BIT(2),
|
||||
PrinterTemperatureDeviceNozzle3 = BIT(3),
|
||||
PrinterTemperatureDeviceNozzle4 = BIT(4),
|
||||
PrinterTemperatureDeviceNozzle5 = BIT(5),
|
||||
PrinterTemperatureDeviceNozzle6 = BIT(6),
|
||||
PrinterTemperatureDeviceNozzle7 = BIT(7),
|
||||
PrinterTemperatureDeviceNozzle8 = BIT(8),
|
||||
PrinterTemperatureDeviceChamber = BIT(9),
|
||||
};
|
||||
|
||||
enum PrinterTemperatureDeviceIndex
|
||||
{
|
||||
PrinterTemperatureDeviceIndexBed = 0,
|
||||
PrinterTemperatureDeviceIndexNozzle1 = 1,
|
||||
PrinterTemperatureDeviceIndexNozzle2 = 2,
|
||||
PrinterTemperatureDeviceIndexNozzle3 = 3,
|
||||
PrinterTemperatureDeviceIndexNozzle4 = 4,
|
||||
PrinterTemperatureDeviceIndexNozzle5 = 5,
|
||||
PrinterTemperatureDeviceIndexNozzle6 = 6,
|
||||
PrinterTemperatureDeviceIndexNozzle7 = 7,
|
||||
PrinterTemperatureDeviceIndexNozzle8 = 8,
|
||||
PrinterTemperatureDeviceIndexChamber = 9,
|
||||
};
|
||||
|
||||
inline PrinterTemperatureDevice operator|(PrinterTemperatureDevice a, PrinterTemperatureDevice b)
|
||||
{
|
||||
return static_cast<PrinterTemperatureDevice>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
enum PrinterState {
|
||||
PrinterStateOffline = 0,
|
||||
PrinterStateError = 1,
|
||||
PrinterStateIdle = 2,
|
||||
PrinterStatePrinting = 3,
|
||||
PrinterStatePaused = 4,
|
||||
};
|
||||
|
||||
typedef struct _PrinterData {
|
||||
union {
|
||||
struct {
|
||||
bool can_extrude : 1;
|
||||
bool homed_axis : 1;
|
||||
bool absolute_coords : 1;
|
||||
};
|
||||
unsigned char rawState;
|
||||
};
|
||||
PrinterState state;
|
||||
char* state_message;
|
||||
char* popup_message;
|
||||
float temperatures[10];
|
||||
float target_temperatures[10];
|
||||
float position[3];
|
||||
float elapsed_time_s;
|
||||
float printed_time_s;
|
||||
float remaining_time_s;
|
||||
float filament_used_mm;
|
||||
char* print_filename;
|
||||
float print_progress; // 0 -> 1
|
||||
float fan_speed; // 0 -> 1
|
||||
float speed_mult;
|
||||
float extrude_mult;
|
||||
int total_layers;
|
||||
int current_layer;
|
||||
float pressure_advance;
|
||||
float smooth_time;
|
||||
int feedrate_mm_per_s;
|
||||
PrinterFeatures error_screen_features;
|
||||
} PrinterData;
|
||||
|
||||
typedef struct {
|
||||
PrinterState state;
|
||||
float print_progress; // 0 -> 1
|
||||
unsigned int power_devices;
|
||||
bool success;
|
||||
} PrinterDataMinimal;
|
||||
|
||||
typedef struct {
|
||||
char** macros;
|
||||
unsigned int count;
|
||||
bool success;
|
||||
} Macros;
|
||||
|
||||
typedef struct {
|
||||
char** power_devices;
|
||||
bool* power_states;
|
||||
unsigned int count;
|
||||
bool success;
|
||||
} PowerDevices;
|
||||
|
||||
typedef struct {
|
||||
char** available_files;
|
||||
unsigned int count;
|
||||
bool success;
|
||||
} Files;
|
||||
|
||||
typedef struct {
|
||||
void* set_label; // type lv_event_cb_t
|
||||
void* open_panel; // type lv_event_cb_t
|
||||
} PrinterUiPanel;
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
unsigned int size;
|
||||
unsigned char* png;
|
||||
} Thumbnail;
|
||||
|
||||
enum HttpRequestType
|
||||
{
|
||||
HttpPost,
|
||||
HttpGet
|
||||
};
|
||||
|
||||
class BasePrinter
|
||||
{
|
||||
protected:
|
||||
unsigned char config_index{};
|
||||
PrinterData printer_data{};
|
||||
|
||||
public:
|
||||
short popup_message_timeout_s = 10;
|
||||
bool no_confirm_print_file = false;
|
||||
|
||||
PrinterConfiguration* printer_config{};
|
||||
PrinterFeatures supported_features{};
|
||||
PrinterTemperatureDevice supported_temperature_devices{};
|
||||
PrinterUiPanel* custom_menus{};
|
||||
unsigned char custom_menus_count{};
|
||||
|
||||
virtual bool move_printer(const char* axis, float amount, bool relative) = 0;
|
||||
virtual bool execute_feature(PrinterFeatures feature) = 0;
|
||||
virtual bool connect() = 0;
|
||||
virtual bool fetch() = 0;
|
||||
virtual PrinterDataMinimal fetch_min() = 0;
|
||||
virtual void disconnect() = 0;
|
||||
// Free macros externally when done
|
||||
virtual Macros get_macros() = 0;
|
||||
virtual int get_macros_count() = 0;
|
||||
virtual bool execute_macro(const char* macro) = 0;
|
||||
// Free power devices externally when done
|
||||
virtual PowerDevices get_power_devices() = 0;
|
||||
virtual int get_power_devices_count() = 0;
|
||||
virtual bool set_power_device_state(const char* device_name, bool state) = 0;
|
||||
// Free files externally when done
|
||||
virtual Files get_files() = 0;
|
||||
virtual bool start_file(const char* filename) = 0;
|
||||
// Free thumbnail externally when done
|
||||
virtual Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename) = 0;
|
||||
virtual bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature) = 0;
|
||||
|
||||
BasePrinter(unsigned char index);
|
||||
PrinterData* AnnouncePrinterData();
|
||||
bool supports_feature(PrinterFeatures feature);
|
||||
};
|
||||
|
||||
#define DATA_PRINTER_STATE 1
|
||||
#define DATA_PRINTER_DATA 2
|
||||
#define DATA_PRINTER_TEMP_PRESET 3
|
||||
#define DATA_PRINTER_MINIMAL 4
|
||||
#define DATA_PRINTER_POPUP 5
|
||||
|
||||
BasePrinter* get_current_printer();
|
||||
BasePrinter* get_printer(int idx);
|
||||
void initialize_printers(BasePrinter** printers, unsigned char total);
|
||||
PrinterData* get_current_printer_data();
|
||||
unsigned int get_printer_count();
|
||||
void announce_printer_data_minimal(PrinterDataMinimal* printer_data);
|
||||
PrinterDataMinimal* get_printer_data_minimal(int idx);
|
||||
int get_current_printer_index();
|
||||
void set_current_printer(int idx);
|
||||
6
CYD-Klipper/src/core/screen_driver.h
Normal file
6
CYD-Klipper/src/core/screen_driver.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
// Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h
|
||||
|
||||
void screen_setBrightness(unsigned char brightness);
|
||||
void screen_setup();
|
||||
void set_invert_display();
|
||||
28
CYD-Klipper/src/core/semaphore.cpp
Normal file
28
CYD-Klipper/src/core/semaphore.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "semaphore.h"
|
||||
#include <UrlEncode.h>
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
|
||||
|
||||
void semaphore_init(){
|
||||
freezeRenderThreadSemaphore = xSemaphoreCreateMutex();
|
||||
freezeRequestThreadSemaphore = xSemaphoreCreateMutex();
|
||||
xSemaphoreGive(freezeRenderThreadSemaphore);
|
||||
xSemaphoreGive(freezeRequestThreadSemaphore);
|
||||
}
|
||||
|
||||
void freeze_request_thread(){
|
||||
xSemaphoreTake(freezeRequestThreadSemaphore, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void unfreeze_request_thread(){
|
||||
xSemaphoreGive(freezeRequestThreadSemaphore);
|
||||
}
|
||||
|
||||
void freeze_render_thread(){
|
||||
xSemaphoreTake(freezeRenderThreadSemaphore, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void unfreeze_render_thread(){
|
||||
xSemaphoreGive(freezeRenderThreadSemaphore);
|
||||
}
|
||||
11
CYD-Klipper/src/core/semaphore.h
Normal file
11
CYD-Klipper/src/core/semaphore.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
void semaphore_init();
|
||||
|
||||
void freeze_request_thread();
|
||||
void unfreeze_request_thread();
|
||||
|
||||
// Don't use unless you want trouble
|
||||
void freeze_render_thread();
|
||||
// Don't use unless you want trouble
|
||||
void unfreeze_render_thread();
|
||||
230
CYD-Klipper/src/lib/ESP32OTAPull.h
Normal file
230
CYD-Klipper/src/lib/ESP32OTAPull.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
ESP32-OTA-Pull - a library for doing "pull" based OTA ("Over The Air") firmware
|
||||
updates, where the image updates are posted on the web.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022-3 Mikal Hart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <Update.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
class ESP32OTAPull
|
||||
{
|
||||
public:
|
||||
enum ActionType { DONT_DO_UPDATE, UPDATE_BUT_NO_BOOT, UPDATE_AND_BOOT };
|
||||
|
||||
// Return codes from CheckForOTAUpdate
|
||||
enum ErrorCode { UPDATE_AVAILABLE = -3, NO_UPDATE_PROFILE_FOUND = -2, NO_UPDATE_AVAILABLE = -1, UPDATE_OK = 0, HTTP_FAILED = 1, WRITE_ERROR = 2, JSON_PROBLEM = 3, OTA_UPDATE_FAIL = 4 };
|
||||
|
||||
private:
|
||||
void (*Callback)(int offset, int totallength) = NULL;
|
||||
ActionType Action = UPDATE_AND_BOOT;
|
||||
String Board = ARDUINO_BOARD;
|
||||
String Device = "";
|
||||
String Config = "";
|
||||
String CVersion = "";
|
||||
bool DowngradesAllowed = false;
|
||||
|
||||
int DownloadJson(const char* URL, String& payload)
|
||||
{
|
||||
HTTPClient http;
|
||||
http.begin(URL);
|
||||
|
||||
// Send HTTP GET request
|
||||
int httpResponseCode = http.GET();
|
||||
|
||||
if (httpResponseCode == 200)
|
||||
{
|
||||
payload = http.getString();
|
||||
}
|
||||
|
||||
// Free resources
|
||||
http.end();
|
||||
return httpResponseCode;
|
||||
}
|
||||
|
||||
int DoOTAUpdate(const char* URL, ActionType Action)
|
||||
{
|
||||
HTTPClient http;
|
||||
http.begin(URL);
|
||||
|
||||
// Send HTTP GET request
|
||||
int httpResponseCode = http.GET();
|
||||
|
||||
if (httpResponseCode == 200)
|
||||
{
|
||||
int totalLength = http.getSize();
|
||||
|
||||
// this is required to start firmware update process
|
||||
if (!Update.begin(UPDATE_SIZE_UNKNOWN))
|
||||
return OTA_UPDATE_FAIL;
|
||||
|
||||
// create buffer for read
|
||||
uint8_t buff[1280] = { 0 };
|
||||
|
||||
// get tcp stream
|
||||
WiFiClient* stream = http.getStreamPtr();
|
||||
|
||||
// read all data from server
|
||||
int offset = 0;
|
||||
while (http.connected() && offset < totalLength)
|
||||
{
|
||||
size_t sizeAvail = stream->available();
|
||||
if (sizeAvail > 0)
|
||||
{
|
||||
size_t bytes_to_read = min(sizeAvail, sizeof(buff));
|
||||
size_t bytes_read = stream->readBytes(buff, bytes_to_read);
|
||||
size_t bytes_written = Update.write(buff, bytes_read);
|
||||
if (bytes_read != bytes_written)
|
||||
{
|
||||
// LOG_F(("Unexpected error in OTA: %d %d %d\n", bytes_to_read, bytes_read, bytes_written))
|
||||
break;
|
||||
}
|
||||
offset += bytes_written;
|
||||
if (Callback != NULL)
|
||||
Callback(offset, totalLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == totalLength)
|
||||
{
|
||||
Update.end(true);
|
||||
delay(1000);
|
||||
|
||||
// Restart ESP32 to see changes
|
||||
if (Action == UPDATE_BUT_NO_BOOT)
|
||||
return UPDATE_OK;
|
||||
ESP.restart();
|
||||
}
|
||||
return WRITE_ERROR;
|
||||
}
|
||||
|
||||
http.end();
|
||||
return httpResponseCode;
|
||||
}
|
||||
|
||||
public:
|
||||
/// @brief Return the version string of the binary, as reported by the JSON
|
||||
/// @return The firmware version
|
||||
String GetVersion()
|
||||
{
|
||||
return CVersion;
|
||||
}
|
||||
|
||||
/// @brief Override the default "Device" id (MAC Address)
|
||||
/// @param device A string identifying the particular device (instance) (typically e.g., a MAC address)
|
||||
/// @return The current ESP32OTAPull object for chaining
|
||||
ESP32OTAPull &OverrideDevice(const char *device)
|
||||
{
|
||||
Device = device;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Override the default "Board" value of ARDUINO_BOARD
|
||||
/// @param board A string identifying the board (class) being targeted
|
||||
/// @return The current ESP32OTAPull object for chaining
|
||||
ESP32OTAPull &OverrideBoard(const char *board)
|
||||
{
|
||||
Board = board;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Specify a configuration string that must match any "Config" in JSON
|
||||
/// @param config An arbitrary string showing the current configuration
|
||||
/// @return The current ESP32OTAPull object for chaining
|
||||
ESP32OTAPull &SetConfig(const char *config)
|
||||
{
|
||||
Config = config;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Specify whether downgrades (posted version is lower) are allowed
|
||||
/// @param allow_downgrades true if downgrades are allowed
|
||||
/// @return The current ESP32OTAPull object for chaining
|
||||
ESP32OTAPull &AllowDowngrades(bool allow_downgrades)
|
||||
{
|
||||
DowngradesAllowed = allow_downgrades;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief Specify a callback function to monitor update progress
|
||||
/// @param callback Pointer to a function that is called repeatedly during update
|
||||
/// @return The current ESP32OTAPull object for chaining
|
||||
ESP32OTAPull &SetCallback(void (*callback)(int offset, int totallength))
|
||||
{
|
||||
Callback = callback;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief The main entry point for OTA Update
|
||||
/// @param JSON_URL The URL for the JSON filter file
|
||||
/// @param CurrentVersion The version # of the current (i.e. to be replaced) sketch
|
||||
/// @param ActionType The action to be performed. May be any of DONT_DO_UPDATE, UPDATE_BUT_NO_BOOT, UPDATE_AND_BOOT (default)
|
||||
/// @return ErrorCode or HTTP failure code (see enum above)
|
||||
int CheckForOTAUpdate(const char* JSON_URL, const char *CurrentVersion, ActionType Action = UPDATE_AND_BOOT)
|
||||
{
|
||||
CurrentVersion = CurrentVersion == NULL ? "" : CurrentVersion;
|
||||
|
||||
// Downloading OTA Json...
|
||||
String Payload;
|
||||
int httpResponseCode = DownloadJson(JSON_URL, Payload);
|
||||
if (httpResponseCode != 200)
|
||||
return httpResponseCode > 0 ? httpResponseCode : HTTP_FAILED;
|
||||
|
||||
// Deserialize the JSON file downloaded from user's site
|
||||
JsonDocument doc;
|
||||
DeserializationError deserialization = deserializeJson(doc, Payload.c_str());
|
||||
if (deserialization != DeserializationError::Ok)
|
||||
return JSON_PROBLEM;
|
||||
|
||||
String DeviceName = Device.isEmpty() ? WiFi.macAddress() : Device;
|
||||
String BoardName = Board.isEmpty() ? ARDUINO_BOARD : Board;
|
||||
String ConfigName = Config.isEmpty() ? "" : Config;
|
||||
bool foundProfile = false;
|
||||
|
||||
// Step through the configurations looking for a match
|
||||
for (auto config : doc["Configurations"].as<JsonArray>())
|
||||
{
|
||||
String CBoard = config["Board"].isNull() ? "" : (const char *)config["Board"];
|
||||
String CDevice = config["Device"].isNull() ? "" : (const char *)config["Device"];
|
||||
CVersion = config["Version"].isNull() ? "" : (const char *)config["Version"];
|
||||
String CConfig = config["Config"].isNull() ? "" : (const char *)config["Config"];
|
||||
//LOG_F(("Checking %s %s %s %s\n", CBoard.c_str(), CDevice.c_str(), CVersion.c_str(), CConfig.c_str()))
|
||||
//LOG_F(("Against %s %s %s %s\n", BoardName.c_str(), DeviceName.c_str(), CurrentVersion, ConfigName.c_str()))
|
||||
if ((CBoard.isEmpty() || CBoard == BoardName) &&
|
||||
(CDevice.isEmpty() || CDevice == DeviceName) &&
|
||||
(CConfig.isEmpty() || CConfig == ConfigName))
|
||||
{
|
||||
if (CVersion.isEmpty() || CVersion > String(CurrentVersion) ||
|
||||
(DowngradesAllowed && CVersion != String(CurrentVersion)))
|
||||
return Action == DONT_DO_UPDATE ? UPDATE_AVAILABLE : DoOTAUpdate(config["URL"], Action);
|
||||
foundProfile = true;
|
||||
}
|
||||
}
|
||||
return foundProfile ? NO_UPDATE_AVAILABLE : NO_UPDATE_PROFILE_FOUND;
|
||||
}
|
||||
};
|
||||
|
||||
41
CYD-Klipper/src/main.cpp
Normal file
41
CYD-Klipper/src/main.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "conf/global_config.h"
|
||||
#include "core/screen_driver.h"
|
||||
#include "ui/wifi_setup.h"
|
||||
#include "ui/ip_setup.h"
|
||||
#include "ui/serial/serial_console.h"
|
||||
#include "lvgl.h"
|
||||
#include "core/data_setup.h"
|
||||
#include "ui/main_ui.h"
|
||||
#include "ui/nav_buttons.h"
|
||||
#include <Esp.h>
|
||||
#include "core/lv_setup.h"
|
||||
#include "ui/ota_setup.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
serial_console::greet();
|
||||
load_global_config();
|
||||
screen_setup();
|
||||
lv_setup();
|
||||
LOG_LN("Screen init done");
|
||||
|
||||
wifi_init();
|
||||
ota_init();
|
||||
ip_init();
|
||||
data_setup();
|
||||
|
||||
nav_style_setup();
|
||||
main_ui_setup();
|
||||
}
|
||||
|
||||
void loop(){
|
||||
wifi_ok();
|
||||
data_loop();
|
||||
lv_handler();
|
||||
serial_console::run();
|
||||
|
||||
if (is_ready_for_ota_update())
|
||||
{
|
||||
ota_do_update();
|
||||
}
|
||||
}
|
||||
506
CYD-Klipper/src/ui/ip_setup.cpp
Normal file
506
CYD-Klipper/src/ui/ip_setup.cpp
Normal file
@@ -0,0 +1,506 @@
|
||||
#include "ip_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "lvgl.h"
|
||||
#include <HTTPClient.h>
|
||||
#include "core/data_setup.h"
|
||||
#include "ui_utils.h"
|
||||
#include "panels/panel.h"
|
||||
#include "macros.h"
|
||||
#include "../core/lv_setup.h"
|
||||
#include "serial/serial_console.h"
|
||||
#include "../core/klipper/klipper_printer_integration.hpp"
|
||||
#include "../core/bambu/bambu_printer_integration.hpp"
|
||||
#include "../core/screen_driver.h"
|
||||
#include "../core/klipper-serial/serial_klipper_printer_integration.hpp"
|
||||
#include "../core/octoprint/octoprint_printer_integration.hpp"
|
||||
|
||||
void show_ip_entry();
|
||||
void choose_printer_type();
|
||||
|
||||
lv_obj_t * main_label;
|
||||
|
||||
/* Create a custom keyboard to allow hostnames or ip addresses (a-z, 0 - 9, and -) */
|
||||
static const char * kb_map[] = {
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n",
|
||||
"a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_OK, "\n",
|
||||
LV_SYMBOL_LEFT, "z", "x", "c", "v", "b", "n", "m", ".", "-", LV_SYMBOL_RIGHT, NULL
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t kb_ctrl[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 5,
|
||||
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6
|
||||
};
|
||||
|
||||
static const char * hex_numpad_map[] = {
|
||||
"1", "2", "3", "F", LV_SYMBOL_BACKSPACE, "\n",
|
||||
"4", "5", "6", "E", LV_SYMBOL_OK, "\n",
|
||||
"7", "8", "9", "D", LV_SYMBOL_LEFT, "\n",
|
||||
"0", "A", "B", "C", LV_SYMBOL_RIGHT, NULL
|
||||
};
|
||||
|
||||
static const lv_btnmatrix_ctrl_t hex_numpad_ctrl[] = {
|
||||
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
|
||||
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
|
||||
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
|
||||
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
|
||||
};
|
||||
|
||||
static void btn_switch_printer(lv_event_t *e){
|
||||
lv_obj_t *btn = lv_event_get_target(e);
|
||||
PrinterConfiguration * config = (PrinterConfiguration*)lv_event_get_user_data(e);
|
||||
int index = config - global_config.printer_config;
|
||||
|
||||
global_config_set_printer(index);
|
||||
set_color_scheme();
|
||||
set_invert_display();
|
||||
lv_obj_del(lv_obj_get_parent(lv_obj_get_parent(btn)));
|
||||
}
|
||||
|
||||
long last_request = 0;
|
||||
|
||||
void serial_check_connection()
|
||||
{
|
||||
if ((millis() - last_request) < 5000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = connection_test_serial_klipper(&global_config.printer_config[global_config.printer_index]);
|
||||
last_request = millis();
|
||||
|
||||
if (result == KlipperConnectionStatus::ConnectOk)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].setup_complete = true;
|
||||
strcpy(global_config.printer_config[global_config.printer_index].printer_host, "Serial");
|
||||
write_global_config();
|
||||
}
|
||||
}
|
||||
|
||||
void switch_printer_init() {
|
||||
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
|
||||
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_layout_flex_column(parent);
|
||||
|
||||
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
|
||||
|
||||
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(parent);
|
||||
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
|
||||
lv_obj_center(label);
|
||||
|
||||
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
|
||||
PrinterConfiguration * config = &global_config.printer_config[i];
|
||||
const char* printer_name = (config->printer_name[0] == 0) ? config->printer_host : config->printer_name;
|
||||
|
||||
if (i == global_config.printer_index && config->setup_complete)
|
||||
{
|
||||
lv_create_custom_menu_label(printer_name, parent, "Active");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config->setup_complete) {
|
||||
lv_create_custom_menu_button(printer_name, parent, btn_switch_printer, "Switch", config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void show_switch_printer_screen(lv_event_t * e){
|
||||
switch_printer_init();
|
||||
}
|
||||
|
||||
static void host_update(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
const char* text = lv_textarea_get_text(ta);
|
||||
strcpy(global_config.printer_config[global_config.printer_index].printer_host, text);
|
||||
global_config.printer_config[global_config.printer_index].ip_configured = text[0] != '\0';
|
||||
}
|
||||
|
||||
static void port_update(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
const char* text = lv_textarea_get_text(ta);
|
||||
if (text[0] != '\0')
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].klipper_port = atoi(text);
|
||||
}
|
||||
}
|
||||
|
||||
static void auth_update(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
const char* text = lv_textarea_get_text(ta);
|
||||
strcpy(global_config.printer_config[global_config.printer_index].printer_auth, text);
|
||||
global_config.printer_config[global_config.printer_index].auth_configured = text[0] != '\0';
|
||||
}
|
||||
|
||||
static void return_to_choose_printer_type(lv_event_t * e)
|
||||
{
|
||||
choose_printer_type();
|
||||
}
|
||||
|
||||
static void keyboard_event_ip_entry(lv_event_t * e) {
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
|
||||
if ((code == LV_EVENT_FOCUSED || code == LV_EVENT_DEFOCUSED) && ta != NULL)
|
||||
{
|
||||
// make sure we alter the keymap before taking actions that might
|
||||
// destroy the keyboard
|
||||
if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_1))
|
||||
{
|
||||
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);
|
||||
}
|
||||
else if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_2))
|
||||
{
|
||||
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_2);
|
||||
}
|
||||
else if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_3))
|
||||
{
|
||||
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_LOWER);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
if(code == LV_EVENT_FOCUSED) {
|
||||
lv_keyboard_set_textarea(kb, ta);
|
||||
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else if(code == LV_EVENT_DEFOCUSED) {
|
||||
lv_keyboard_set_textarea(kb, NULL);
|
||||
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
else if (code == LV_EVENT_READY)
|
||||
{
|
||||
PrinterType type = global_config.printer_config[global_config.printer_index].printer_type;
|
||||
|
||||
if (type == PrinterType::PrinterTypeKlipper)
|
||||
{
|
||||
KlipperConnectionStatus klipper_status = connection_test_klipper(&global_config.printer_config[global_config.printer_index]);
|
||||
if (klipper_status == KlipperConnectionStatus::ConnectOk)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].setup_complete = true;
|
||||
write_global_config();
|
||||
}
|
||||
else if (klipper_status == KlipperConnectionStatus::ConnectAuthRequired)
|
||||
{
|
||||
lv_label_set_text(main_label, "Incorrect authorisation");
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_label_set_text(main_label, "Failed to connect");
|
||||
}
|
||||
}
|
||||
else if (type == PrinterType::PrinterTypeBambuLocal)
|
||||
{
|
||||
BambuConnectionStatus bambu_status = connection_test_bambu(&global_config.printer_config[global_config.printer_index]);
|
||||
if (bambu_status == BambuConnectionStatus::BambuConnectOk)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].setup_complete = true;
|
||||
write_global_config();
|
||||
}
|
||||
else if (bambu_status == BambuConnectionStatus::BambuConnectSNFail)
|
||||
{
|
||||
lv_label_set_text(main_label, "Incorrect serial number");
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_label_set_text(main_label, "Incorrect IP/Access code");
|
||||
}
|
||||
}
|
||||
else if (type == PrinterType::PrinterTypeOctoprint)
|
||||
{
|
||||
OctoConnectionStatus octo_status = connection_test_octoprint(&global_config.printer_config[global_config.printer_index]);
|
||||
if (octo_status == OctoConnectionStatus::OctoConnectOk)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].setup_complete = true;
|
||||
write_global_config();
|
||||
}
|
||||
else if (octo_status == OctoConnectionStatus::OctoConnectKeyFail)
|
||||
{
|
||||
lv_label_set_text(main_label, "Incorrect API key");
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_label_set_text(main_label, "Failed to connect");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void show_ip_entry()
|
||||
{
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_layout_flex_column(root);
|
||||
lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t * top_root = lv_create_empty_panel(root);
|
||||
lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX);
|
||||
lv_layout_flex_column(top_root);
|
||||
lv_obj_set_flex_grow(top_root, 1);
|
||||
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0);
|
||||
lv_obj_clear_flag(top_root, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t * button_row = lv_create_empty_panel(top_root);
|
||||
lv_obj_set_size(button_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
|
||||
lv_layout_flex_row(button_row);
|
||||
|
||||
lv_obj_t * button_back = lv_btn_create(button_row);
|
||||
lv_obj_set_height(button_back, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX / 2);
|
||||
lv_obj_set_flex_grow(button_back, 1);
|
||||
lv_obj_add_event_cb(button_back, return_to_choose_printer_type, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t * label = lv_label_create(button_back);
|
||||
lv_label_set_text(label, LV_SYMBOL_LEFT);
|
||||
lv_obj_center(label);
|
||||
|
||||
main_label = lv_label_create(button_row);
|
||||
|
||||
if (global_config.multi_printer_mode)
|
||||
{
|
||||
lv_obj_t * button_switch_printer = lv_btn_create(button_row);
|
||||
lv_obj_set_height(button_switch_printer, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX / 2);
|
||||
lv_obj_set_flex_grow(button_switch_printer, 1);
|
||||
lv_obj_add_event_cb(button_switch_printer, show_switch_printer_screen, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
label = lv_label_create(button_switch_printer);
|
||||
lv_label_set_text(label, LV_SYMBOL_HOME);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
lv_obj_t * ip_row = lv_create_empty_panel(top_root);
|
||||
lv_obj_set_size(ip_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
|
||||
lv_layout_flex_row(ip_row);
|
||||
|
||||
lv_obj_t * host_entry = lv_textarea_create(ip_row);
|
||||
lv_textarea_set_one_line(host_entry, true);
|
||||
lv_obj_add_flag(host_entry, LV_OBJ_FLAG_USER_1);
|
||||
lv_textarea_set_max_length(host_entry, 64);
|
||||
lv_obj_set_flex_grow(host_entry, 2);
|
||||
|
||||
lv_obj_t * port_entry = lv_textarea_create(ip_row);
|
||||
lv_textarea_set_one_line(port_entry, true);
|
||||
lv_obj_set_flex_grow(port_entry, 1);
|
||||
|
||||
lv_obj_t * auth_row = lv_create_empty_panel(top_root);
|
||||
lv_obj_set_size(auth_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
|
||||
lv_layout_flex_row(auth_row);
|
||||
|
||||
lv_obj_t * auth_entry = lv_textarea_create(auth_row);
|
||||
lv_textarea_set_one_line(auth_entry, true);
|
||||
lv_obj_add_flag(auth_entry, LV_OBJ_FLAG_USER_2);
|
||||
lv_obj_set_flex_grow(auth_entry, 1);
|
||||
lv_textarea_set_max_length(auth_entry, 32);
|
||||
|
||||
if (global_config.printer_config[global_config.printer_index].ip_configured)
|
||||
{
|
||||
char buff[10] = {0};
|
||||
sprintf(buff, "%d", global_config.printer_config[global_config.printer_index].klipper_port);
|
||||
lv_textarea_set_text(host_entry, global_config.printer_config[global_config.printer_index].printer_host);
|
||||
lv_textarea_set_text(port_entry, buff);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_textarea_set_text(host_entry, "");
|
||||
|
||||
if (global_config.printer_config[global_config.printer_index].printer_type == PrinterType::PrinterTypeBambuLocal)
|
||||
{
|
||||
lv_textarea_set_text(port_entry, "");
|
||||
global_config.printer_config[global_config.printer_index].klipper_port = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_textarea_set_text(port_entry, "80");
|
||||
global_config.printer_config[global_config.printer_index].klipper_port = 80;
|
||||
}
|
||||
|
||||
global_config.printer_config[global_config.printer_index].printer_host[0] = '\0';
|
||||
|
||||
}
|
||||
|
||||
if (global_config.printer_config[global_config.printer_index].auth_configured)
|
||||
{
|
||||
lv_textarea_set_text(auth_entry, global_config.printer_config[global_config.printer_index].printer_auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_textarea_set_text(auth_entry, "");
|
||||
global_config.printer_config[global_config.printer_index].printer_auth[0] = '\0';
|
||||
}
|
||||
|
||||
lv_obj_add_event_cb(host_entry, host_update, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_event_cb(port_entry, port_update, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_event_cb(auth_entry, auth_update, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
||||
lv_obj_t * keyboard = lv_keyboard_create(root);
|
||||
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
|
||||
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_2, hex_numpad_map, hex_numpad_ctrl);
|
||||
lv_obj_add_event_cb(host_entry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
|
||||
lv_obj_add_event_cb(port_entry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
|
||||
lv_obj_add_event_cb(auth_entry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard);
|
||||
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
|
||||
lv_keyboard_set_textarea(keyboard, host_entry);
|
||||
|
||||
switch (global_config.printer_config[global_config.printer_index].printer_type)
|
||||
{
|
||||
case PrinterType::PrinterTypeKlipper:
|
||||
lv_label_set_text(main_label, "Klipper Setup");
|
||||
lv_textarea_set_max_length(port_entry, 5);
|
||||
lv_textarea_set_placeholder_text(host_entry, "Klipper host");
|
||||
lv_textarea_set_placeholder_text(port_entry, "Port");
|
||||
lv_textarea_set_placeholder_text(auth_entry, "Autorisation key (optional)");
|
||||
break;
|
||||
case PrinterType::PrinterTypeBambuLocal:
|
||||
lv_label_set_text(main_label, "Bambu (Local) Setup");
|
||||
lv_obj_set_flex_grow(port_entry, 4);
|
||||
lv_obj_set_flex_grow(host_entry, 6);
|
||||
lv_textarea_set_max_length(port_entry, 8);
|
||||
lv_textarea_set_placeholder_text(host_entry, "Printer IP");
|
||||
lv_textarea_set_placeholder_text(port_entry, "Access code");
|
||||
lv_textarea_set_placeholder_text(auth_entry, "Printer serial number");
|
||||
lv_obj_clear_flag(auth_entry, LV_OBJ_FLAG_USER_2);
|
||||
lv_obj_add_flag(auth_entry, LV_OBJ_FLAG_USER_3);
|
||||
break;
|
||||
case PrinterType::PrinterTypeOctoprint:
|
||||
lv_obj_clear_flag(auth_entry, LV_OBJ_FLAG_USER_2);
|
||||
lv_obj_add_flag(auth_entry, LV_OBJ_FLAG_USER_3);
|
||||
lv_textarea_set_max_length(auth_entry, 48);
|
||||
lv_label_set_text(main_label, "Octoprint Setup");
|
||||
lv_textarea_set_max_length(port_entry, 5);
|
||||
lv_textarea_set_placeholder_text(host_entry, "Octoprint Host");
|
||||
lv_textarea_set_placeholder_text(port_entry, "Port");
|
||||
lv_textarea_set_placeholder_text(auth_entry, "API key");
|
||||
break;
|
||||
case PrinterType::PrinterTypeKlipperSerial:
|
||||
lv_label_set_text(main_label, "Klipper (Serial) Setup");
|
||||
lv_obj_del(ip_row);
|
||||
lv_obj_del(auth_row);
|
||||
lv_obj_del(keyboard);
|
||||
|
||||
lv_obj_t * bottom_root = lv_create_empty_panel(top_root);
|
||||
lv_obj_set_width(bottom_root, CYD_SCREEN_WIDTH_PX);
|
||||
lv_obj_set_flex_grow(bottom_root, 1);
|
||||
|
||||
label = lv_label_create(bottom_root);
|
||||
lv_obj_center(label);
|
||||
lv_label_set_text(label, "Connect CYD-Klipper to a host\nrunning the CYD-Klipper server");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printer_type_klipper(lv_event_t * e)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].printer_type = PrinterType::PrinterTypeKlipper;
|
||||
show_ip_entry();
|
||||
}
|
||||
|
||||
static void printer_type_bambu_local(lv_event_t * e)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].printer_type = PrinterType::PrinterTypeBambuLocal;
|
||||
show_ip_entry();
|
||||
}
|
||||
|
||||
static void printer_type_serial_klipper(lv_event_t * e)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].printer_type = PrinterType::PrinterTypeKlipperSerial;
|
||||
show_ip_entry();
|
||||
}
|
||||
|
||||
static void printer_type_octoprint(lv_event_t * e)
|
||||
{
|
||||
global_config.printer_config[global_config.printer_index].printer_type = PrinterType::PrinterTypeOctoprint;
|
||||
show_ip_entry();
|
||||
}
|
||||
|
||||
static void return_to_wifi_configuration(lv_event_t * e)
|
||||
{
|
||||
global_config.wifi_configuration_skipped = false;
|
||||
write_global_config();
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
static inline void create_printer_type_button(lv_obj_t * root, const char * label, lv_event_cb_t event, bool require_wifi = true)
|
||||
{
|
||||
if (require_wifi && !global_config.wifi_configured)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(root);
|
||||
lv_obj_set_size(btn, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
lv_obj_add_event_cb(btn, event, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t * label_obj = lv_label_create(btn);
|
||||
lv_label_set_text(label_obj, label);
|
||||
lv_obj_center(label_obj);
|
||||
}
|
||||
|
||||
void choose_printer_type()
|
||||
{
|
||||
lv_obj_t * btn;
|
||||
lv_obj_clean(lv_scr_act());
|
||||
global_config.printer_config[global_config.printer_index].ip_configured = false;
|
||||
global_config.printer_config[global_config.printer_index].auth_configured = false;
|
||||
|
||||
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_layout_flex_column(root);
|
||||
lv_obj_set_flex_grow(root, 1);
|
||||
lv_obj_set_style_pad_all(root, CYD_SCREEN_GAP_PX, 0);
|
||||
lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t * label = lv_label_create(root);
|
||||
lv_label_set_text(label, "Choose printer type");
|
||||
|
||||
create_printer_type_button(root, "Klipper (Wifi)", printer_type_klipper);
|
||||
create_printer_type_button(root, "Klipper (Serial/USB)", printer_type_serial_klipper, false);
|
||||
create_printer_type_button(root, "Bambu (Wifi, Local) [BETA]", printer_type_bambu_local);
|
||||
create_printer_type_button(root, "Octoprint (Wifi) [BETA]", printer_type_octoprint);
|
||||
|
||||
if (global_config.wifi_configuration_skipped)
|
||||
{
|
||||
create_printer_type_button(root, "Return to WiFi configuration", return_to_wifi_configuration, false);
|
||||
}
|
||||
}
|
||||
|
||||
void ip_init(){
|
||||
if (!global_config.printer_config[global_config.printer_index].setup_complete)
|
||||
{
|
||||
if (global_config.printer_config[global_config.printer_index].printer_type == PrinterType::PrinterTypeNone)
|
||||
{
|
||||
choose_printer_type();
|
||||
}
|
||||
else
|
||||
{
|
||||
show_ip_entry();
|
||||
}
|
||||
}
|
||||
|
||||
while (!global_config.printer_config[global_config.printer_index].setup_complete)
|
||||
{
|
||||
if (global_config.printer_config[global_config.printer_index].printer_type == PrinterType::PrinterTypeKlipperSerial)
|
||||
{
|
||||
serial_check_connection();
|
||||
}
|
||||
|
||||
lv_handler();
|
||||
serial_console::run();
|
||||
}
|
||||
}
|
||||
3
CYD-Klipper/src/ui/ip_setup.h
Normal file
3
CYD-Klipper/src/ui/ip_setup.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void ip_init();
|
||||
114
CYD-Klipper/src/ui/macros.cpp
Normal file
114
CYD-Klipper/src/ui/macros.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "macros.h"
|
||||
#include "ui_utils.h"
|
||||
#include <Esp.h>
|
||||
#include "../core/current_printer.h"
|
||||
#include "../core/data_setup.h"
|
||||
#include "../core/semaphore.h"
|
||||
|
||||
typedef struct {
|
||||
const char* power_device_name;
|
||||
BasePrinter* printer;
|
||||
} DoubleStorage;
|
||||
|
||||
static void macro_run(lv_event_t * e){
|
||||
lv_obj_t * btn = lv_event_get_target(e);
|
||||
const char* macro = (const char*)lv_event_get_user_data(e);
|
||||
LOG_F(("Macro: %s\n", macro))
|
||||
current_printer_execute_macro(macro);
|
||||
}
|
||||
|
||||
int macros_add_macros_to_panel(lv_obj_t * root_panel, BasePrinter* printer)
|
||||
{
|
||||
freeze_request_thread();
|
||||
Macros macros = printer->get_macros();
|
||||
unfreeze_request_thread();
|
||||
|
||||
if (!macros.success)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (global_config.sort_macros)
|
||||
{
|
||||
std::sort(macros.macros, macros.macros + macros.count, [](const char *a, const char *b)
|
||||
{ return strcmp(a, b) < 0; });
|
||||
}
|
||||
|
||||
for (int i = 0; i < macros.count; i++)
|
||||
{
|
||||
const char* macro = macros.macros[i];
|
||||
lv_obj_on_destroy_free_data(root_panel, macro);
|
||||
lv_create_custom_menu_button(macro, root_panel, macro_run, "Run", (void*)macro);
|
||||
}
|
||||
|
||||
free(macros.macros);
|
||||
return macros.count;
|
||||
}
|
||||
|
||||
static void power_device_toggle(lv_event_t * e)
|
||||
{
|
||||
auto state = lv_obj_get_state(lv_event_get_target(e));
|
||||
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||
DoubleStorage* device = (DoubleStorage*)lv_event_get_user_data(e);
|
||||
LOG_F(("Power Device: %s, State: %d -> %d\n", device->power_device_name, !checked, checked))
|
||||
|
||||
freeze_request_thread();
|
||||
device->printer->set_power_device_state(device->power_device_name, checked);
|
||||
unfreeze_request_thread();
|
||||
}
|
||||
|
||||
int macros_add_power_devices_to_panel(lv_obj_t * root_panel, BasePrinter* printer)
|
||||
{
|
||||
freeze_request_thread();
|
||||
PowerDevices devices = printer->get_power_devices();
|
||||
unfreeze_request_thread();
|
||||
|
||||
if (!devices.success)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < devices.count; i++)
|
||||
{
|
||||
const char* power_device_name = devices.power_devices[i];
|
||||
const bool power_device_state = devices.power_states[i];
|
||||
DoubleStorage* storage = (DoubleStorage*)malloc(sizeof(DoubleStorage));
|
||||
storage->printer = printer;
|
||||
storage->power_device_name = power_device_name;
|
||||
lv_obj_on_destroy_free_data(root_panel, storage);
|
||||
lv_obj_on_destroy_free_data(root_panel, power_device_name);
|
||||
lv_create_custom_menu_switch(power_device_name, root_panel, power_device_toggle, power_device_state, (void*)storage);
|
||||
}
|
||||
|
||||
free(devices.power_devices);
|
||||
free(devices.power_states);
|
||||
return devices.count;
|
||||
}
|
||||
|
||||
void macros_draw_power_fullscreen(BasePrinter* printer)
|
||||
{
|
||||
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
|
||||
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_layout_flex_column(parent);
|
||||
|
||||
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
|
||||
|
||||
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(parent);
|
||||
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
|
||||
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn);
|
||||
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
|
||||
lv_obj_center(label);
|
||||
|
||||
macros_add_power_devices_to_panel(parent, printer);
|
||||
}
|
||||
|
||||
void macros_draw_power_fullscreen()
|
||||
{
|
||||
macros_draw_power_fullscreen(get_current_printer());
|
||||
}
|
||||
10
CYD-Klipper/src/ui/macros.h
Normal file
10
CYD-Klipper/src/ui/macros.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "../core/printer_integration.hpp"
|
||||
|
||||
int macros_add_macros_to_panel(lv_obj_t * root_panel, BasePrinter* printer);
|
||||
int macros_add_power_devices_to_panel(lv_obj_t * root_panel, BasePrinter* printer);
|
||||
void macros_draw_power_fullscreen(BasePrinter* printer);
|
||||
void macros_draw_power_fullscreen();
|
||||
51
CYD-Klipper/src/ui/main_ui.cpp
Normal file
51
CYD-Klipper/src/ui/main_ui.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "main_ui.h"
|
||||
#include "../core/data_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "../core/screen_driver.h"
|
||||
#include "../core/printer_integration.hpp"
|
||||
#include "lvgl.h"
|
||||
#include "nav_buttons.h"
|
||||
#include "ui_utils.h"
|
||||
#include "panels/panel.h"
|
||||
#include "../core/lv_setup.h"
|
||||
#include "macros.h"
|
||||
|
||||
void check_if_screen_needs_to_be_disabled(){
|
||||
if (global_config.on_during_print && get_current_printer_data()->state == PrinterState::PrinterStatePrinting){
|
||||
screen_timer_wake();
|
||||
screen_timer_stop();
|
||||
}
|
||||
else {
|
||||
screen_timer_start();
|
||||
}
|
||||
}
|
||||
|
||||
static void on_state_change(void * s, lv_msg_t * m){
|
||||
check_if_screen_needs_to_be_disabled();
|
||||
|
||||
PrinterData* printer = get_current_printer_data();
|
||||
|
||||
if (printer->state == PrinterState::PrinterStateOffline){
|
||||
nav_buttons_setup(PANEL_CONNECTING);
|
||||
}
|
||||
else if (printer->state == PrinterState::PrinterStateError){
|
||||
nav_buttons_setup(PANEL_ERROR);
|
||||
}
|
||||
else if (printer->state == PrinterState::PrinterStateIdle) {
|
||||
nav_buttons_setup(PANEL_FILES);
|
||||
}
|
||||
else {
|
||||
nav_buttons_setup(PANEL_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_popup_message(void * s, lv_msg_t * m)
|
||||
{
|
||||
lv_create_popup_message(get_current_printer_data()->popup_message, get_current_printer()->popup_message_timeout_s * 1000);
|
||||
}
|
||||
|
||||
void main_ui_setup(){
|
||||
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
|
||||
lv_msg_subscribe(DATA_PRINTER_POPUP, on_popup_message, NULL);
|
||||
on_state_change(NULL, NULL);
|
||||
}
|
||||
241
CYD-Klipper/src/ui/nav_buttons.cpp
Normal file
241
CYD-Klipper/src/ui/nav_buttons.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
#include "lvgl.h"
|
||||
#include "panels/panel.h"
|
||||
#include "nav_buttons.h"
|
||||
#include "ui_utils.h"
|
||||
#include <stdio.h>
|
||||
#include "../conf/global_config.h"
|
||||
#include "../core/printer_integration.hpp"
|
||||
|
||||
static lv_style_t nav_button_style;
|
||||
static lv_style_t nav_button_text_style;
|
||||
|
||||
static void update_printer_data_z_pos(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char z_pos_buffer[10];
|
||||
|
||||
sprintf(z_pos_buffer, "Z%.2f", get_current_printer_data()->position[2]);
|
||||
lv_label_set_text(label, z_pos_buffer);
|
||||
}
|
||||
|
||||
static void update_printer_data_temp(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char temp_buffer[10];
|
||||
|
||||
sprintf(temp_buffer, "%.0f/%.0f", get_current_printer_data()->temperatures[PrinterTemperatureDeviceIndex::PrinterTemperatureDeviceIndexNozzle1], get_current_printer_data()->temperatures[PrinterTemperatureDeviceIndex::PrinterTemperatureDeviceIndexBed]);
|
||||
lv_label_set_text(label, temp_buffer);
|
||||
}
|
||||
|
||||
static void update_printer_data_time(lv_event_t * e){
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
char time_buffer[10];
|
||||
|
||||
if (get_current_printer_data()->state == PrinterState::PrinterStateIdle){
|
||||
lv_label_set_text(label, "Idle");
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_current_printer_data()->state == PrinterState::PrinterStatePaused){
|
||||
lv_label_set_text(label, "Paused");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long time = get_current_printer_data()->remaining_time_s;
|
||||
unsigned long hours = time / 3600;
|
||||
unsigned long minutes = (time % 3600) / 60;
|
||||
unsigned long seconds = (time % 3600) % 60;
|
||||
|
||||
if (hours >= 10){
|
||||
sprintf(time_buffer, "%luh", hours);
|
||||
} else if (hours >= 1){
|
||||
sprintf(time_buffer, "%luh%02lum", hours, minutes);
|
||||
} else {
|
||||
sprintf(time_buffer, "%lum", minutes);
|
||||
}
|
||||
|
||||
lv_label_set_text(label, time_buffer);
|
||||
}
|
||||
|
||||
static void update_multi_printer_label(lv_event_t * e) {
|
||||
lv_obj_t * label = lv_event_get_target(e);
|
||||
|
||||
int idle_count = 0;
|
||||
for (int i = 0; i < get_printer_count(); i++)
|
||||
{
|
||||
PrinterDataMinimal* data = get_printer_data_minimal(i);
|
||||
if (data->state == PrinterState::PrinterStateIdle)
|
||||
{
|
||||
idle_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (idle_count > 0)
|
||||
{
|
||||
lv_label_set_text_fmt(label, "%d idle", idle_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_label_set_text(label, "Printer");
|
||||
}
|
||||
}
|
||||
|
||||
static void btn_click_files(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_FILES);
|
||||
}
|
||||
|
||||
static void btn_click_progress(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_PROGRESS);
|
||||
}
|
||||
|
||||
static void btn_click_move(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_MOVE);
|
||||
}
|
||||
|
||||
static void btn_click_extrude(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_TEMP);
|
||||
}
|
||||
|
||||
static void btn_click_settings(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_SETTINGS);
|
||||
}
|
||||
|
||||
static void btn_click_macros(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_MACROS);
|
||||
}
|
||||
|
||||
static void btn_click_printer(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_PRINTER);
|
||||
}
|
||||
|
||||
static void btn_click_err(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_ERROR);
|
||||
}
|
||||
|
||||
static void btn_click_conn(lv_event_t * e){
|
||||
nav_buttons_setup(PANEL_CONNECTING);
|
||||
}
|
||||
|
||||
void create_button(const char* icon, const char* name, lv_event_cb_t button_click, lv_event_cb_t label_update, lv_obj_t * root){
|
||||
lv_obj_t* btn = lv_btn_create(root);
|
||||
lv_obj_set_flex_grow(btn, 1);
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
lv_obj_set_height(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
|
||||
#else
|
||||
lv_obj_set_width(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
|
||||
#endif
|
||||
|
||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||
if (button_click != NULL)
|
||||
lv_obj_add_event_cb(btn, button_click, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t* label = lv_label_create(btn);
|
||||
lv_label_set_text(label, icon);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * CYD_SCREEN_GAP_PX);
|
||||
|
||||
label = lv_label_create(btn);
|
||||
lv_label_set_text(label, name);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX);
|
||||
lv_obj_add_event_cb(label, label_update, LV_EVENT_MSG_RECEIVED, NULL);
|
||||
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||
}
|
||||
|
||||
void nav_buttons_setup(PANEL_TYPE active_panel){
|
||||
lv_obj_clean(lv_scr_act());
|
||||
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t * root_panel = lv_create_empty_panel(lv_scr_act());
|
||||
|
||||
#ifdef CYD_SCREEN_VERTICAL
|
||||
lv_obj_set_size(root_panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_SIDEBAR_SIZE_PX);
|
||||
lv_obj_align(root_panel, LV_ALIGN_BOTTOM_LEFT, 0, 0);
|
||||
lv_layout_flex_row(root_panel, LV_FLEX_ALIGN_START, 0, 0);
|
||||
#else
|
||||
lv_obj_set_size(root_panel, CYD_SCREEN_SIDEBAR_SIZE_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_obj_align(root_panel, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_START, 0, 0);
|
||||
|
||||
#endif
|
||||
|
||||
if (get_current_printer_data()->state > PrinterState::PrinterStateError){
|
||||
// Files/Print
|
||||
if (get_current_printer_data()->state == PrinterState::PrinterStateIdle)
|
||||
{
|
||||
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_button(LV_SYMBOL_FILE, "Paused", btn_click_progress, update_printer_data_time, root_panel);
|
||||
}
|
||||
|
||||
// Move
|
||||
create_button(get_current_printer_data()->state == PrinterState::PrinterStatePrinting ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel);
|
||||
|
||||
// Extrude/Temp
|
||||
create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel);
|
||||
}
|
||||
else if (get_current_printer_data()->state == PrinterState::PrinterStateError) {
|
||||
// Error UI
|
||||
create_button(LV_SYMBOL_WARNING, "Error", btn_click_err, NULL, root_panel);
|
||||
}
|
||||
else {
|
||||
// Connecting
|
||||
create_button(LV_SYMBOL_REFRESH, "Link", btn_click_conn, NULL, root_panel);
|
||||
}
|
||||
|
||||
// Macros
|
||||
create_button(LV_SYMBOL_GPS, "Macro", btn_click_macros, NULL, root_panel);
|
||||
|
||||
if (global_config.multi_printer_mode)
|
||||
{
|
||||
// Printers
|
||||
create_button(LV_SYMBOL_HOME, "Printer", btn_click_printer, update_multi_printer_label, root_panel);
|
||||
}
|
||||
|
||||
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
|
||||
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
|
||||
switch (active_panel){
|
||||
case PANEL_FILES:
|
||||
files_panel_init(panel);
|
||||
break;
|
||||
case PANEL_MOVE:
|
||||
move_panel_init(panel);
|
||||
break;
|
||||
case PANEL_TEMP:
|
||||
temp_panel_init(panel);
|
||||
break;
|
||||
case PANEL_SETTINGS:
|
||||
settings_panel_init(panel);
|
||||
break;
|
||||
case PANEL_MACROS:
|
||||
macros_panel_init(panel);
|
||||
break;
|
||||
case PANEL_STATS:
|
||||
stats_panel_init(panel);
|
||||
break;
|
||||
case PANEL_PRINTER:
|
||||
printer_panel_init(panel);
|
||||
break;
|
||||
case PANEL_ERROR:
|
||||
error_panel_init(panel);
|
||||
break;
|
||||
case PANEL_CONNECTING:
|
||||
connecting_panel_init(panel);
|
||||
break;
|
||||
case PANEL_PROGRESS:
|
||||
progress_panel_init(panel);
|
||||
break;
|
||||
}
|
||||
|
||||
lv_msg_send(DATA_PRINTER_DATA, get_current_printer());
|
||||
}
|
||||
|
||||
void nav_style_setup(){
|
||||
lv_style_init(&nav_button_style);
|
||||
lv_style_set_radius(&nav_button_style, 0);
|
||||
|
||||
lv_style_init(&nav_button_text_style);
|
||||
lv_style_set_text_font(&nav_button_text_style, &CYD_SCREEN_FONT_SMALL);
|
||||
}
|
||||
17
CYD-Klipper/src/ui/nav_buttons.h
Normal file
17
CYD-Klipper/src/ui/nav_buttons.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
enum PANEL_TYPE {
|
||||
PANEL_FILES = 0,
|
||||
PANEL_MOVE = 1,
|
||||
PANEL_TEMP = 2,
|
||||
PANEL_SETTINGS = 3,
|
||||
PANEL_MACROS = 4,
|
||||
PANEL_STATS = 5,
|
||||
PANEL_PRINTER = 6,
|
||||
PANEL_ERROR = 7,
|
||||
PANEL_CONNECTING = 8,
|
||||
PANEL_PROGRESS = 9,
|
||||
};
|
||||
|
||||
void nav_buttons_setup(PANEL_TYPE active_panel);
|
||||
void nav_style_setup();
|
||||
104
CYD-Klipper/src/ui/ota_setup.cpp
Normal file
104
CYD-Klipper/src/ui/ota_setup.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "../lib/ESP32OTAPull.h"
|
||||
#include "lvgl.h"
|
||||
#include "ui_utils.h"
|
||||
#include "../core/lv_setup.h"
|
||||
#include "../core/data_setup.h"
|
||||
#include "../conf/global_config.h"
|
||||
#include "ota_setup.h"
|
||||
#include "../core/semaphore.h"
|
||||
|
||||
//const char *ota_url = "https://gist.githubusercontent.com/suchmememanyskill/ece418fe199e155340de6c224a0badf2/raw/0d6762d68bc807cbecc71e40d55b76692397a7b3/update.json"; // Test url
|
||||
const char *ota_url = "https://suchmememanyskill.github.io/CYD-Klipper/OTA.json"; // Prod url
|
||||
ESP32OTAPull ota_pull;
|
||||
static bool update_available;
|
||||
static bool ready_for_ota_update = false;
|
||||
|
||||
String ota_new_version_name()
|
||||
{
|
||||
return ota_pull.GetVersion();
|
||||
}
|
||||
|
||||
bool ota_has_update()
|
||||
{
|
||||
return update_available;
|
||||
}
|
||||
|
||||
static int last_callback_time = 0;
|
||||
lv_obj_t *percentage_bar;
|
||||
lv_obj_t *update_label;
|
||||
void do_update_callback(int offset, int totallength)
|
||||
{
|
||||
int now = millis();
|
||||
if (now - last_callback_time < 1000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
last_callback_time = now;
|
||||
|
||||
float percentage = (float)offset / (float)totallength; // 0 -> 1
|
||||
lv_bar_set_value(percentage_bar, percentage * 100, LV_ANIM_OFF);
|
||||
lv_label_set_text_fmt(update_label, "%d/%d bytes", offset, totallength);
|
||||
|
||||
lv_refr_now(NULL);
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
}
|
||||
|
||||
void ota_do_update(bool variant_automatic)
|
||||
{
|
||||
LOG_LN("Starting OTA Update");
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_obj_t *panel = lv_create_empty_panel(lv_scr_act());
|
||||
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
|
||||
lv_obj_align(panel, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t *label = lv_label_create(panel);
|
||||
lv_label_set_text(label, "Updating OTA...");
|
||||
|
||||
percentage_bar = lv_bar_create(panel);
|
||||
lv_obj_set_size(percentage_bar, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 0.75f);
|
||||
|
||||
update_label = lv_label_create(panel);
|
||||
lv_label_set_text(update_label, "0/0");
|
||||
|
||||
if (!variant_automatic) {
|
||||
LOG_LN("Freezing Background Tasks");
|
||||
screen_timer_wake();
|
||||
screen_timer_stop();
|
||||
freeze_request_thread();
|
||||
}
|
||||
|
||||
lv_refr_now(NULL);
|
||||
lv_timer_handler();
|
||||
lv_task_handler();
|
||||
|
||||
ota_pull.SetCallback(do_update_callback);
|
||||
ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::UPDATE_AND_BOOT);
|
||||
}
|
||||
|
||||
void ota_init()
|
||||
{
|
||||
//ota_pull.AllowDowngrades(true);
|
||||
int result = ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::DONT_DO_UPDATE);
|
||||
LOG_F(("OTA Update Result: %d\n", result))
|
||||
update_available = result == ESP32OTAPull::UPDATE_AVAILABLE;
|
||||
|
||||
if (global_config.auto_ota_update && update_available)
|
||||
{
|
||||
ota_do_update(true);
|
||||
}
|
||||
}
|
||||
|
||||
void set_ready_for_ota_update()
|
||||
{
|
||||
ready_for_ota_update = true;
|
||||
}
|
||||
|
||||
bool is_ready_for_ota_update()
|
||||
{
|
||||
return ready_for_ota_update;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user