├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── README.md
├── components
├── GCodeRenderer
│ ├── CMakeLists.txt
│ ├── GCodeRenderer.cpp
│ └── include
│ │ └── GCodeRenderer.h
└── dbg_log
│ ├── CMakeLists.txt
│ ├── LICENSE
│ ├── dbg_log.c
│ └── include
│ └── dbg_log.h
├── data
├── Move_48.bmp
├── SDcard_64.bmp
├── Settings_48.bmp
├── arrowL_48.bmp
├── arrowR_48.bmp
├── extruder_32.bmp
├── fan_32.bmp
├── file_24.bmp
├── folder_24.bmp
├── gcode_24.bmp
├── heatbed_32.bmp
├── home_24.bmp
└── return_48.bmp
├── dependencies.lock
├── hardware
└── 3D_Printer_Screen_V2.pdf
├── images
├── screenshots
│ ├── screenshot_2021_1_15_23_4_27.png
│ ├── screenshot_2021_1_15_23_4_46.png
│ ├── screenshot_2021_1_15_23_4_5.png
│ ├── screenshot_2021_1_15_23_4_56.png
│ ├── screenshot_2021_1_15_23_5_20.png
│ ├── screenshot_2021_1_15_23_6_17.png
│ ├── screenshot_2021_1_15_23_7_13.png
│ ├── screenshot_2021_1_18_18_55_15.png
│ └── screenshot_2021_1_18_3_1_7.png
└── wiring.jpg
├── main
├── CMakeLists.txt
├── Free_Fonts.h
├── Kconfig.projbuild
├── Menu
│ ├── black_Scr.cpp
│ ├── black_Scr.h
│ ├── config_Scr.cpp
│ ├── config_Scr.h
│ ├── displayConf_Scr.cpp
│ ├── displayConf_Scr.h
│ ├── fileBrowser_Scr.cpp
│ ├── fileBrowser_Scr.h
│ ├── info_Scr.cpp
│ ├── info_Scr.h
│ ├── preview_Scr.cpp
│ └── preview_Scr.h
├── Screen.cpp
├── Screen.h
├── lcdUI.cpp
├── lcdUI.h
├── main.cpp
├── tftLCD.cpp
├── tftLCD.h
├── utility.cpp
└── utility.h
├── partitions_two_ota_SPIFFS.csv
└── sdkconfig
/.gitignore:
--------------------------------------------------------------------------------
1 | # Our automatic versioning scheme generates the following file
2 | # NEVER put it in the repository
3 | _Version.h
4 |
5 | #
6 | # OS
7 | #
8 | applet/
9 | *.DS_Store
10 |
11 |
12 | #
13 | # Misc
14 | #
15 | *~
16 | *.orig
17 | *.rej
18 | *.bak
19 | *.idea
20 | *.s
21 | *.i
22 | *.ii
23 | *.swp
24 | tags
25 |
26 | #
27 | # C++
28 | #
29 | # Compiled Object files
30 | *.slo
31 | *.lo
32 | *.o
33 | *.obj
34 | *.ino.cpp
35 |
36 | # Precompiled Headers
37 | *.gch
38 | *.pch
39 |
40 | # Compiled Dynamic libraries
41 | *.so
42 | *.dylib
43 | *.dll
44 |
45 | # Fortran module files
46 | *.mod
47 | *.smod
48 |
49 | # Compiled Static libraries
50 | *.lai
51 | *.la
52 | *.a
53 | *.lib
54 |
55 | # Executables
56 | *.exe
57 | *.out
58 | *.app
59 |
60 |
61 | #
62 | # C
63 | #
64 | # Object files
65 | *.o
66 | *.ko
67 | *.obj
68 | *.elf
69 |
70 | # Precompiled Headers
71 | *.gch
72 | *.pch
73 |
74 | # Libraries
75 | *.lib
76 | *.a
77 | *.la
78 | *.lo
79 |
80 | # Shared objects (inc. Windows DLLs)
81 | *.dll
82 | *.so
83 | *.so.*
84 | *.dylib
85 |
86 | # Executables
87 | *.exe
88 | *.out
89 | *.app
90 | *.i*86
91 | *.x86_64
92 | *.hex
93 |
94 | # Debug files
95 | *.dSYM/
96 | *.su
97 |
98 | # PlatformIO files/dirs
99 | .pio*
100 | .pioenvs
101 | .piolibdeps
102 | lib/readme.txt
103 |
104 | #Visual Studio
105 | *.sln
106 | *.vcxproj
107 | *.vcxproj.user
108 | *.vcxproj.filters
109 | Release/
110 | Debug/
111 | __vm/
112 | .vs/
113 | vc-fileutils.settings
114 |
115 | #Visual Studio Code
116 | .vscode
117 | .vscode/.browse.c_cpp.db*
118 | .vscode/c_cpp_properties.json
119 | .vscode/launch.json
120 | .vscode/*.db
121 | .code-workspace
122 |
123 | #CLion
124 | cmake-build-*
125 | BetsyScreen.code-workspace
126 |
127 | # ESP-IDF default build directory name
128 | build
129 | sdkconfig.old
130 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "components/arduino"]
2 | path = components/arduino
3 | url = https://github.com/espressif/arduino-esp32.git
4 | [submodule "components/TchScr_Drv"]
5 | path = components/TchScr_Drv
6 | url = https://github.com/dracir9/TchScr_Drv.git
7 | [submodule "components/Vector"]
8 | path = components/Vector
9 | url = https://github.com/dracir9/Vector.git
10 | [submodule "components/TFT_eSPI"]
11 | path = components/TFT_eSPI
12 | url = https://github.com/Bodmer/TFT_eSPI
13 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The following lines of boilerplate have to be in your project's
2 | # CMakeLists in this exact order for cmake to work correctly
3 | cmake_minimum_required(VERSION 3.5)
4 |
5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6 | project(3DPrintScreen)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 |
3 | GNU GENERAL PUBLIC LICENSE
4 | Version 3, 29 June 2007
5 |
6 | Copyright (c) 2007 Free Software Foundation, Inc.
7 | Everyone is permitted to copy and distribute verbatim copies
8 | of this license document, but changing it is not allowed.
9 |
10 | Preamble
11 |
12 | The GNU General Public License is a free, copyleft license for
13 | software and other kinds of works.
14 |
15 | The licenses for most software and other practical works are designed
16 | to take away your freedom to share and change the works. By contrast,
17 | the GNU General Public License is intended to guarantee your freedom to
18 | share and change all versions of a program--to make sure it remains free
19 | software for all its users. We, the Free Software Foundation, use the
20 | GNU General Public License for most of our software; it applies also to
21 | any other work released this way by its authors. You can apply it to
22 | your programs, too.
23 |
24 | When we speak of free software, we are referring to freedom, not
25 | price. Our General Public Licenses are designed to make sure that you
26 | have the freedom to distribute copies of free software (and charge for
27 | them if you wish), that you receive source code or can get it if you
28 | want it, that you can change the software or use pieces of it in new
29 | free programs, and that you know you can do these things.
30 |
31 | To protect your rights, we need to prevent others from denying you
32 | these rights or asking you to surrender the rights. Therefore, you have
33 | certain responsibilities if you distribute copies of the software, or if
34 | you modify it: responsibilities to respect the freedom of others.
35 |
36 | For example, if you distribute copies of such a program, whether
37 | gratis or for a fee, you must pass on to the recipients the same
38 | freedoms that you received. You must make sure that they, too, receive
39 | or can get the source code. And you must show them these terms so they
40 | know their rights.
41 |
42 | Developers that use the GNU GPL protect your rights with two steps:
43 | (1) assert copyright on the software, and (2) offer you this License
44 | giving you legal permission to copy, distribute and/or modify it.
45 |
46 | For the developers' and authors' protection, the GPL clearly explains
47 | that there is no warranty for this free software. For both users' and
48 | authors' sake, the GPL requires that modified versions be marked as
49 | changed, so that their problems will not be attributed erroneously to
50 | authors of previous versions.
51 |
52 | Some devices are designed to deny users access to install or run
53 | modified versions of the software inside them, although the manufacturer
54 | can do so. This is fundamentally incompatible with the aim of
55 | protecting users' freedom to change the software. The systematic
56 | pattern of such abuse occurs in the area of products for individuals to
57 | use, which is precisely where it is most unacceptable. Therefore, we
58 | have designed this version of the GPL to prohibit the practice for those
59 | products. If such problems arise substantially in other domains, we
60 | stand ready to extend this provision to those domains in future versions
61 | of the GPL, as needed to protect the freedom of users.
62 |
63 | Finally, every program is threatened constantly by software patents.
64 | States should not allow patents to restrict development and use of
65 | software on general-purpose computers, but in those that do, we wish to
66 | avoid the special danger that patents applied to a free program could
67 | make it effectively proprietary. To prevent this, the GPL assures that
68 | patents cannot be used to render the program non-free.
69 |
70 | The precise terms and conditions for copying, distribution and
71 | modification follow.
72 |
73 | TERMS AND CONDITIONS
74 |
75 | 0. Definitions.
76 |
77 | "This License" refers to version 3 of the GNU General Public License.
78 |
79 | "Copyright" also means copyright-like laws that apply to other kinds of
80 | works, such as semiconductor masks.
81 |
82 | "The Program" refers to any copyrightable work licensed under this
83 | License. Each licensee is addressed as "you". "Licensees" and
84 | "recipients" may be individuals or organizations.
85 |
86 | To "modify" a work means to copy from or adapt all or part of the work
87 | in a fashion requiring copyright permission, other than the making of an
88 | exact copy. The resulting work is called a "modified version" of the
89 | earlier work or a work "based on" the earlier work.
90 |
91 | A "covered work" means either the unmodified Program or a work based
92 | on the Program.
93 |
94 | To "propagate" a work means to do anything with it that, without
95 | permission, would make you directly or secondarily liable for
96 | infringement under applicable copyright law, except executing it on a
97 | computer or modifying a private copy. Propagation includes copying,
98 | distribution (with or without modification), making available to the
99 | public, and in some countries other activities as well.
100 |
101 | To "convey" a work means any kind of propagation that enables other
102 | parties to make or receive copies. Mere interaction with a user through
103 | a computer network, with no transfer of a copy, is not conveying.
104 |
105 | An interactive user interface displays "Appropriate Legal Notices"
106 | to the extent that it includes a convenient and prominently visible
107 | feature that (1) displays an appropriate copyright notice, and (2)
108 | tells the user that there is no warranty for the work (except to the
109 | extent that warranties are provided), that licensees may convey the
110 | work under this License, and how to view a copy of this License. If
111 | the interface presents a list of user commands or options, such as a
112 | menu, a prominent item in the list meets this criterion.
113 |
114 | 1. Source Code.
115 |
116 | The "source code" for a work means the preferred form of the work
117 | for making modifications to it. "Object code" means any non-source
118 | form of a work.
119 |
120 | A "Standard Interface" means an interface that either is an official
121 | standard defined by a recognized standards body, or, in the case of
122 | interfaces specified for a particular programming language, one that
123 | is widely used among developers working in that language.
124 |
125 | The "System Libraries" of an executable work include anything, other
126 | than the work as a whole, that (a) is included in the normal form of
127 | packaging a Major Component, but which is not part of that Major
128 | Component, and (b) serves only to enable use of the work with that
129 | Major Component, or to implement a Standard Interface for which an
130 | implementation is available to the public in source code form. A
131 | "Major Component", in this context, means a major essential component
132 | (kernel, window system, and so on) of the specific operating system
133 | (if any) on which the executable work runs, or a compiler used to
134 | produce the work, or an object code interpreter used to run it.
135 |
136 | The "Corresponding Source" for a work in object code form means all
137 | the source code needed to generate, install, and (for an executable
138 | work) run the object code and to modify the work, including scripts to
139 | control those activities. However, it does not include the work's
140 | System Libraries, or general-purpose tools or generally available free
141 | programs which are used unmodified in performing those activities but
142 | which are not part of the work. For example, Corresponding Source
143 | includes interface definition files associated with source files for
144 | the work, and the source code for shared libraries and dynamically
145 | linked subprograms that the work is specifically designed to require,
146 | such as by intimate data communication or control flow between those
147 | subprograms and other parts of the work.
148 |
149 | The Corresponding Source need not include anything that users
150 | can regenerate automatically from other parts of the Corresponding
151 | Source.
152 |
153 | The Corresponding Source for a work in source code form is that
154 | same work.
155 |
156 | 2. Basic Permissions.
157 |
158 | All rights granted under this License are granted for the term of
159 | copyright on the Program, and are irrevocable provided the stated
160 | conditions are met. This License explicitly affirms your unlimited
161 | permission to run the unmodified Program. The output from running a
162 | covered work is covered by this License only if the output, given its
163 | content, constitutes a covered work. This License acknowledges your
164 | rights of fair use or other equivalent, as provided by copyright law.
165 |
166 | You may make, run and propagate covered works that you do not
167 | convey, without conditions so long as your license otherwise remains
168 | in force. You may convey covered works to others for the sole purpose
169 | of having them make modifications exclusively for you, or provide you
170 | with facilities for running those works, provided that you comply with
171 | the terms of this License in conveying all material for which you do
172 | not control copyright. Those thus making or running the covered works
173 | for you must do so exclusively on your behalf, under your direction
174 | and control, on terms that prohibit them from making any copies of
175 | your copyrighted material outside their relationship with you.
176 |
177 | Conveying under any other circumstances is permitted solely under
178 | the conditions stated below. Sublicensing is not allowed; section 10
179 | makes it unnecessary.
180 |
181 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
182 |
183 | No covered work shall be deemed part of an effective technological
184 | measure under any applicable law fulfilling obligations under article
185 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
186 | similar laws prohibiting or restricting circumvention of such
187 | measures.
188 |
189 | When you convey a covered work, you waive any legal power to forbid
190 | circumvention of technological measures to the extent such circumvention
191 | is effected by exercising rights under this License with respect to
192 | the covered work, and you disclaim any intention to limit operation or
193 | modification of the work as a means of enforcing, against the work's
194 | users, your or third parties' legal rights to forbid circumvention of
195 | technological measures.
196 |
197 | 4. Conveying Verbatim Copies.
198 |
199 | You may convey verbatim copies of the Program's source code as you
200 | receive it, in any medium, provided that you conspicuously and
201 | appropriately publish on each copy an appropriate copyright notice;
202 | keep intact all notices stating that this License and any
203 | non-permissive terms added in accord with section 7 apply to the code;
204 | keep intact all notices of the absence of any warranty; and give all
205 | recipients a copy of this License along with the Program.
206 |
207 | You may charge any price or no price for each copy that you convey,
208 | and you may offer support or warranty protection for a fee.
209 |
210 | 5. Conveying Modified Source Versions.
211 |
212 | You may convey a work based on the Program, or the modifications to
213 | produce it from the Program, in the form of source code under the
214 | terms of section 4, provided that you also meet all of these conditions:
215 |
216 | a) The work must carry prominent notices stating that you modified
217 | it, and giving a relevant date.
218 |
219 | b) The work must carry prominent notices stating that it is
220 | released under this License and any conditions added under section
221 | 7. This requirement modifies the requirement in section 4 to
222 | "keep intact all notices".
223 |
224 | c) You must license the entire work, as a whole, under this
225 | License to anyone who comes into possession of a copy. This
226 | License will therefore apply, along with any applicable section 7
227 | additional terms, to the whole of the work, and all its parts,
228 | regardless of how they are packaged. This License gives no
229 | permission to license the work in any other way, but it does not
230 | invalidate such permission if you have separately received it.
231 |
232 | d) If the work has interactive user interfaces, each must display
233 | Appropriate Legal Notices; however, if the Program has interactive
234 | interfaces that do not display Appropriate Legal Notices, your
235 | work need not make them do so.
236 |
237 | A compilation of a covered work with other separate and independent
238 | works, which are not by their nature extensions of the covered work,
239 | and which are not combined with it such as to form a larger program,
240 | in or on a volume of a storage or distribution medium, is called an
241 | "aggregate" if the compilation and its resulting copyright are not
242 | used to limit the access or legal rights of the compilation's users
243 | beyond what the individual works permit. Inclusion of a covered work
244 | in an aggregate does not cause this License to apply to the other
245 | parts of the aggregate.
246 |
247 | 6. Conveying Non-Source Forms.
248 |
249 | You may convey a covered work in object code form under the terms
250 | of sections 4 and 5, provided that you also convey the
251 | machine-readable Corresponding Source under the terms of this License,
252 | in one of these ways:
253 |
254 | a) Convey the object code in, or embodied in, a physical product
255 | (including a physical distribution medium), accompanied by the
256 | Corresponding Source fixed on a durable physical medium
257 | customarily used for software interchange.
258 |
259 | b) Convey the object code in, or embodied in, a physical product
260 | (including a physical distribution medium), accompanied by a
261 | written offer, valid for at least three years and valid for as
262 | long as you offer spare parts or customer support for that product
263 | model, to give anyone who possesses the object code either (1) a
264 | copy of the Corresponding Source for all the software in the
265 | product that is covered by this License, on a durable physical
266 | medium customarily used for software interchange, for a price no
267 | more than your reasonable cost of physically performing this
268 | conveying of source, or (2) access to copy the
269 | Corresponding Source from a network server at no charge.
270 |
271 | c) Convey individual copies of the object code with a copy of the
272 | written offer to provide the Corresponding Source. This
273 | alternative is allowed only occasionally and noncommercially, and
274 | only if you received the object code with such an offer, in accord
275 | with subsection 6b.
276 |
277 | d) Convey the object code by offering access from a designated
278 | place (gratis or for a charge), and offer equivalent access to the
279 | Corresponding Source in the same way through the same place at no
280 | further charge. You need not require recipients to copy the
281 | Corresponding Source along with the object code. If the place to
282 | copy the object code is a network server, the Corresponding Source
283 | may be on a different server (operated by you or a third party)
284 | that supports equivalent copying facilities, provided you maintain
285 | clear directions next to the object code saying where to find the
286 | Corresponding Source. Regardless of what server hosts the
287 | Corresponding Source, you remain obligated to ensure that it is
288 | available for as long as needed to satisfy these requirements.
289 |
290 | e) Convey the object code using peer-to-peer transmission, provided
291 | you inform other peers where the object code and Corresponding
292 | Source of the work are being offered to the general public at no
293 | charge under subsection 6d.
294 |
295 | A separable portion of the object code, whose source code is excluded
296 | from the Corresponding Source as a System Library, need not be
297 | included in conveying the object code work.
298 |
299 | A "User Product" is either (1) a "consumer product", which means any
300 | tangible personal property which is normally used for personal, family,
301 | or household purposes, or (2) anything designed or sold for incorporation
302 | into a dwelling. In determining whether a product is a consumer product,
303 | doubtful cases shall be resolved in favor of coverage. For a particular
304 | product received by a particular user, "normally used" refers to a
305 | typical or common use of that class of product, regardless of the status
306 | of the particular user or of the way in which the particular user
307 | actually uses, or expects or is expected to use, the product. A product
308 | is a consumer product regardless of whether the product has substantial
309 | commercial, industrial or non-consumer uses, unless such uses represent
310 | the only significant mode of use of the product.
311 |
312 | "Installation Information" for a User Product means any methods,
313 | procedures, authorization keys, or other information required to install
314 | and execute modified versions of a covered work in that User Product from
315 | a modified version of its Corresponding Source. The information must
316 | suffice to ensure that the continued functioning of the modified object
317 | code is in no case prevented or interfered with solely because
318 | modification has been made.
319 |
320 | If you convey an object code work under this section in, or with, or
321 | specifically for use in, a User Product, and the conveying occurs as
322 | part of a transaction in which the right of possession and use of the
323 | User Product is transferred to the recipient in perpetuity or for a
324 | fixed term (regardless of how the transaction is characterized), the
325 | Corresponding Source conveyed under this section must be accompanied
326 | by the Installation Information. But this requirement does not apply
327 | if neither you nor any third party retains the ability to install
328 | modified object code on the User Product (for example, the work has
329 | been installed in ROM).
330 |
331 | The requirement to provide Installation Information does not include a
332 | requirement to continue to provide support service, warranty, or updates
333 | for a work that has been modified or installed by the recipient, or for
334 | the User Product in which it has been modified or installed. Access to a
335 | network may be denied when the modification itself materially and
336 | adversely affects the operation of the network or violates the rules and
337 | protocols for communication across the network.
338 |
339 | Corresponding Source conveyed, and Installation Information provided,
340 | in accord with this section must be in a format that is publicly
341 | documented (and with an implementation available to the public in
342 | source code form), and must require no special password or key for
343 | unpacking, reading or copying.
344 |
345 | 7. Additional Terms.
346 |
347 | "Additional permissions" are terms that supplement the terms of this
348 | License by making exceptions from one or more of its conditions.
349 | Additional permissions that are applicable to the entire Program shall
350 | be treated as though they were included in this License, to the extent
351 | that they are valid under applicable law. If additional permissions
352 | apply only to part of the Program, that part may be used separately
353 | under those permissions, but the entire Program remains governed by
354 | this License without regard to the additional permissions.
355 |
356 | When you convey a copy of a covered work, you may at your option
357 | remove any additional permissions from that copy, or from any part of
358 | it. (Additional permissions may be written to require their own
359 | removal in certain cases when you modify the work.) You may place
360 | additional permissions on material, added by you to a covered work,
361 | for which you have or can give appropriate copyright permission.
362 |
363 | Notwithstanding any other provision of this License, for material you
364 | add to a covered work, you may (if authorized by the copyright holders of
365 | that material) supplement the terms of this License with terms:
366 |
367 | a) Disclaiming warranty or limiting liability differently from the
368 | terms of sections 15 and 16 of this License; or
369 |
370 | b) Requiring preservation of specified reasonable legal notices or
371 | author attributions in that material or in the Appropriate Legal
372 | Notices displayed by works containing it; or
373 |
374 | c) Prohibiting misrepresentation of the origin of that material, or
375 | requiring that modified versions of such material be marked in
376 | reasonable ways as different from the original version; or
377 |
378 | d) Limiting the use for publicity purposes of names of licensors or
379 | authors of the material; or
380 |
381 | e) Declining to grant rights under trademark law for use of some
382 | trade names, trademarks, or service marks; or
383 |
384 | f) Requiring indemnification of licensors and authors of that
385 | material by anyone who conveys the material (or modified versions of
386 | it) with contractual assumptions of liability to the recipient, for
387 | any liability that these contractual assumptions directly impose on
388 | those licensors and authors.
389 |
390 | All other non-permissive additional terms are considered "further
391 | restrictions" within the meaning of section 10. If the Program as you
392 | received it, or any part of it, contains a notice stating that it is
393 | governed by this License along with a term that is a further
394 | restriction, you may remove that term. If a license document contains
395 | a further restriction but permits relicensing or conveying under this
396 | License, you may add to a covered work material governed by the terms
397 | of that license document, provided that the further restriction does
398 | not survive such relicensing or conveying.
399 |
400 | If you add terms to a covered work in accord with this section, you
401 | must place, in the relevant source files, a statement of the
402 | additional terms that apply to those files, or a notice indicating
403 | where to find the applicable terms.
404 |
405 | Additional terms, permissive or non-permissive, may be stated in the
406 | form of a separately written license, or stated as exceptions;
407 | the above requirements apply either way.
408 |
409 | 8. Termination.
410 |
411 | You may not propagate or modify a covered work except as expressly
412 | provided under this License. Any attempt otherwise to propagate or
413 | modify it is void, and will automatically terminate your rights under
414 | this License (including any patent licenses granted under the third
415 | paragraph of section 11).
416 |
417 | However, if you cease all violation of this License, then your
418 | license from a particular copyright holder is reinstated (a)
419 | provisionally, unless and until the copyright holder explicitly and
420 | finally terminates your license, and (b) permanently, if the copyright
421 | holder fails to notify you of the violation by some reasonable means
422 | prior to 60 days after the cessation.
423 |
424 | Moreover, your license from a particular copyright holder is
425 | reinstated permanently if the copyright holder notifies you of the
426 | violation by some reasonable means, this is the first time you have
427 | received notice of violation of this License (for any work) from that
428 | copyright holder, and you cure the violation prior to 30 days after
429 | your receipt of the notice.
430 |
431 | Termination of your rights under this section does not terminate the
432 | licenses of parties who have received copies or rights from you under
433 | this License. If your rights have been terminated and not permanently
434 | reinstated, you do not qualify to receive new licenses for the same
435 | material under section 10.
436 |
437 | 9. Acceptance Not Required for Having Copies.
438 |
439 | You are not required to accept this License in order to receive or
440 | run a copy of the Program. Ancillary propagation of a covered work
441 | occurring solely as a consequence of using peer-to-peer transmission
442 | to receive a copy likewise does not require acceptance. However,
443 | nothing other than this License grants you permission to propagate or
444 | modify any covered work. These actions infringe copyright if you do
445 | not accept this License. Therefore, by modifying or propagating a
446 | covered work, you indicate your acceptance of this License to do so.
447 |
448 | 10. Automatic Licensing of Downstream Recipients.
449 |
450 | Each time you convey a covered work, the recipient automatically
451 | receives a license from the original licensors, to run, modify and
452 | propagate that work, subject to this License. You are not responsible
453 | for enforcing compliance by third parties with this License.
454 |
455 | An "entity transaction" is a transaction transferring control of an
456 | organization, or substantially all assets of one, or subdividing an
457 | organization, or merging organizations. If propagation of a covered
458 | work results from an entity transaction, each party to that
459 | transaction who receives a copy of the work also receives whatever
460 | licenses to the work the party's predecessor in interest had or could
461 | give under the previous paragraph, plus a right to possession of the
462 | Corresponding Source of the work from the predecessor in interest, if
463 | the predecessor has it or can get it with reasonable efforts.
464 |
465 | You may not impose any further restrictions on the exercise of the
466 | rights granted or affirmed under this License. For example, you may
467 | not impose a license fee, royalty, or other charge for exercise of
468 | rights granted under this License, and you may not initiate litigation
469 | (including a cross-claim or counterclaim in a lawsuit) alleging that
470 | any patent claim is infringed by making, using, selling, offering for
471 | sale, or importing the Program or any portion of it.
472 |
473 | 11. Patents.
474 |
475 | A "contributor" is a copyright holder who authorizes use under this
476 | License of the Program or a work on which the Program is based. The
477 | work thus licensed is called the contributor's "contributor version".
478 |
479 | A contributor's "essential patent claims" are all patent claims
480 | owned or controlled by the contributor, whether already acquired or
481 | hereafter acquired, that would be infringed by some manner, permitted
482 | by this License, of making, using, or selling its contributor version,
483 | but do not include claims that would be infringed only as a
484 | consequence of further modification of the contributor version. For
485 | purposes of this definition, "control" includes the right to grant
486 | patent sublicenses in a manner consistent with the requirements of
487 | this License.
488 |
489 | Each contributor grants you a non-exclusive, worldwide, royalty-free
490 | patent license under the contributor's essential patent claims, to
491 | make, use, sell, offer for sale, import and otherwise run, modify and
492 | propagate the contents of its contributor version.
493 |
494 | In the following three paragraphs, a "patent license" is any express
495 | agreement or commitment, however denominated, not to enforce a patent
496 | (such as an express permission to practice a patent or covenant not to
497 | sue for patent infringement). To "grant" such a patent license to a
498 | party means to make such an agreement or commitment not to enforce a
499 | patent against the party.
500 |
501 | If you convey a covered work, knowingly relying on a patent license,
502 | and the Corresponding Source of the work is not available for anyone
503 | to copy, free of charge and under the terms of this License, through a
504 | publicly available network server or other readily accessible means,
505 | then you must either (1) cause the Corresponding Source to be so
506 | available, or (2) arrange to deprive yourself of the benefit of the
507 | patent license for this particular work, or (3) arrange, in a manner
508 | consistent with the requirements of this License, to extend the patent
509 | license to downstream recipients. "Knowingly relying" means you have
510 | actual knowledge that, but for the patent license, your conveying the
511 | covered work in a country, or your recipient's use of the covered work
512 | in a country, would infringe one or more identifiable patents in that
513 | country that you have reason to believe are valid.
514 |
515 | If, pursuant to or in connection with a single transaction or
516 | arrangement, you convey, or propagate by procuring conveyance of, a
517 | covered work, and grant a patent license to some of the parties
518 | receiving the covered work authorizing them to use, propagate, modify
519 | or convey a specific copy of the covered work, then the patent license
520 | you grant is automatically extended to all recipients of the covered
521 | work and works based on it.
522 |
523 | A patent license is "discriminatory" if it does not include within
524 | the scope of its coverage, prohibits the exercise of, or is
525 | conditioned on the non-exercise of one or more of the rights that are
526 | specifically granted under this License. You may not convey a covered
527 | work if you are a party to an arrangement with a third party that is
528 | in the business of distributing software, under which you make payment
529 | to the third party based on the extent of your activity of conveying
530 | the work, and under which the third party grants, to any of the
531 | parties who would receive the covered work from you, a discriminatory
532 | patent license (a) in connection with copies of the covered work
533 | conveyed by you (or copies made from those copies), or (b) primarily
534 | for and in connection with specific products or compilations that
535 | contain the covered work, unless you entered into that arrangement,
536 | or that patent license was granted, prior to 28 March 2007.
537 |
538 | Nothing in this License shall be construed as excluding or limiting
539 | any implied license or other defenses to infringement that may
540 | otherwise be available to you under applicable patent law.
541 |
542 | 12. No Surrender of Others' Freedom.
543 |
544 | If conditions are imposed on you (whether by court order, agreement or
545 | otherwise) that contradict the conditions of this License, they do not
546 | excuse you from the conditions of this License. If you cannot convey a
547 | covered work so as to satisfy simultaneously your obligations under this
548 | License and any other pertinent obligations, then as a consequence you may
549 | not convey it at all. For example, if you agree to terms that obligate you
550 | to collect a royalty for further conveying from those to whom you convey
551 | the Program, the only way you could satisfy both those terms and this
552 | License would be to refrain entirely from conveying the Program.
553 |
554 | 13. Use with the GNU Affero General Public License.
555 |
556 | Notwithstanding any other provision of this License, you have
557 | permission to link or combine any covered work with a work licensed
558 | under version 3 of the GNU Affero General Public License into a single
559 | combined work, and to convey the resulting work. The terms of this
560 | License will continue to apply to the part which is the covered work,
561 | but the special requirements of the GNU Affero General Public License,
562 | section 13, concerning interaction through a network will apply to the
563 | combination as such.
564 |
565 | 14. Revised Versions of this License.
566 |
567 | The Free Software Foundation may publish revised and/or new versions of
568 | the GNU General Public License from time to time. Such new versions will
569 | be similar in spirit to the present version, but may differ in detail to
570 | address new problems or concerns.
571 |
572 | Each version is given a distinguishing version number. If the
573 | Program specifies that a certain numbered version of the GNU General
574 | Public License "or any later version" applies to it, you have the
575 | option of following the terms and conditions either of that numbered
576 | version or of any later version published by the Free Software
577 | Foundation. If the Program does not specify a version number of the
578 | GNU General Public License, you may choose any version ever published
579 | by the Free Software Foundation.
580 |
581 | If the Program specifies that a proxy can decide which future
582 | versions of the GNU General Public License can be used, that proxy's
583 | public statement of acceptance of a version permanently authorizes you
584 | to choose that version for the Program.
585 |
586 | Later license versions may give you additional or different
587 | permissions. However, no additional obligations are imposed on any
588 | author or copyright holder as a result of your choosing to follow a
589 | later version.
590 |
591 | 15. Disclaimer of Warranty.
592 |
593 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
594 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
595 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
596 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
597 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
598 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
599 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
600 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
601 |
602 | 16. Limitation of Liability.
603 |
604 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
605 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
606 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
607 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
608 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
609 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
610 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
611 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
612 | SUCH DAMAGES.
613 |
614 | 17. Interpretation of Sections 15 and 16.
615 |
616 | If the disclaimer of warranty and limitation of liability provided
617 | above cannot be given local legal effect according to their terms,
618 | reviewing courts shall apply local law that most closely approximates
619 | an absolute waiver of all civil liability in connection with the
620 | Program, unless a warranty or assumption of liability accompanies a
621 | copy of the Program in return for a fee.
622 |
623 | END OF TERMS AND CONDITIONS
624 |
625 | How to Apply These Terms to Your New Programs
626 |
627 | If you develop a new program, and you want it to be of the greatest
628 | possible use to the public, the best way to achieve this is to make it
629 | free software which everyone can redistribute and change under these terms.
630 |
631 | To do so, attach the following notices to the program. It is safest
632 | to attach them to the start of each source file to most effectively
633 | state the exclusion of warranty; and each file should have at least
634 | the "copyright" line and a pointer to where the full notice is found.
635 |
636 | {one line to give the program's name and a brief idea of what it does.}
637 | Copyright (c) {year} {name of author}
638 |
639 | This program is free software: you can redistribute it and/or modify
640 | it under the terms of the GNU General Public License as published by
641 | the Free Software Foundation, either version 3 of the License, or
642 | (at your option) any later version.
643 |
644 | This program is distributed in the hope that it will be useful,
645 | but WITHOUT ANY WARRANTY; without even the implied warranty of
646 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
647 | GNU General Public License for more details.
648 |
649 | You should have received a copy of the GNU General Public License
650 | along with this program. If not, see .
651 |
652 | Also add information on how to contact you by electronic and paper mail.
653 |
654 | If the program does terminal interaction, make it output a short
655 | notice like this when it starts in an interactive mode:
656 |
657 | {project} Copyright (c) {year} {fullname}
658 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
659 | This is free software, and you are welcome to redistribute it
660 | under certain conditions; type `show c' for details.
661 |
662 | The hypothetical commands `show w' and `show c' should show the appropriate
663 | parts of the General Public License. Of course, your program's commands
664 | might be different; for a GUI interface, you would use an "about box".
665 |
666 | You should also get your employer (if you work as a programmer) or school,
667 | if any, to sign a "copyright disclaimer" for the program, if necessary.
668 | For more information on this, and how to apply and follow the GNU GPL, see
669 | .
670 |
671 | The GNU General Public License does not permit incorporating your program
672 | into proprietary programs. If your program is a subroutine library, you
673 | may consider it more useful to permit linking proprietary applications with
674 | the library. If this is what you want to do, use the GNU Lesser General
675 | Public License instead of this License. But first, please read
676 | .
677 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 3D Printer Screen
2 | 3D Printer Screen is a 3d printer controller project based arround ESP32. The purpose of this project is to add wireless connectivity to the printer and simplify its operation through LCD and touchscreen interfaces.
3 |
4 | **_Early development_**
5 |
6 | ## Hardware Prerequisites
7 | -  or another with similar wiring similar
8 | - TFT LCD display compatible with [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI) library and SPI communication
9 | - ESP32 Wrover-e Rev 3 with at least 4MB of SPIRAM
10 | - EFM8BB10F8G microcontroller
11 |
12 | ## Current features
13 | - [x] SD card browser
14 | - [x] Gcode preview
15 |
16 | ## Screenshots
17 | #### Main screen
18 | 
19 | #### SD card browser
20 | 
21 | 
22 | 
23 | 
24 | #### Gcode preview
25 |  Based on [this design](https://www.thingiverse.com/thing:2508515)
26 |  Based on [this design](https://www.thingiverse.com/thing:2914080)
27 |  Based on [this design](https://www.thingiverse.com/thing:826836)
28 |  Based on [this design](https://www.thingiverse.com/thing:1657791)
29 |
30 | ## Planned features
31 | - [ ] Movement, temperature, settings, file selection, etc. menus
32 | - [ ] SD card printing
33 | - [ ] WiFi printing
34 |
--------------------------------------------------------------------------------
/components/GCodeRenderer/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | idf_component_register(SRCS "GCodeRenderer.cpp"
2 | INCLUDE_DIRS "include"
3 | PRIV_REQUIRES Vector dbg_log)
--------------------------------------------------------------------------------
/components/GCodeRenderer/include/GCodeRenderer.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file GCodeRenderer.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 07-12-2021
5 | * -----
6 | * Last Modified: 26-03-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2021 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef GCODERENDERER_H
26 | #define GCODERENDERER_H
27 |
28 | #include
29 | #include
30 | #include "freertos/FreeRTOS.h"
31 | #include "freertos/queue.h"
32 | #include "freertos/task.h"
33 | #include "freertos/semphr.h"
34 | #include "Vector.h"
35 | #include "dbg_log.h"
36 | #include "Matrix.h"
37 |
38 | struct FileInfo
39 | {
40 | bool filamentReady:1;
41 | bool timeReady:1;
42 | Vec3f camPos;
43 | time_t timestamp;
44 | float filament = 0.0f;
45 | uint32_t printTime = 0;
46 | };
47 |
48 | class GCodeRenderer
49 | {
50 | public:
51 | constexpr static int32_t cacheLen = 3500000;
52 | constexpr static uint8_t rQueueLen = 2;
53 | constexpr static int32_t bufferLen = 4096;
54 | constexpr static uint8_t vecQueueLen = 2;
55 | constexpr static int32_t vecBufferLen = 350;
56 | constexpr static int32_t maxLineLen = 96;
57 |
58 | private:
59 | struct Pixel
60 | {
61 | int16_t x;
62 | int16_t y;
63 | uint16_t color;
64 | float z;
65 | };
66 |
67 | struct JobData
68 | {
69 | int32_t size = -1;
70 | char* data = nullptr;
71 | };
72 |
73 | struct VectorData
74 | {
75 | int32_t size = -1;
76 | Vec3f* data = nullptr;
77 | };
78 |
79 | struct PrinterState
80 | {
81 | bool absPos = true;
82 | bool absEPos = true;
83 | Vec3f currentPos = Vec3f();
84 | Vec3f nextPos = Vec3f();
85 | Vec3f offset = Vec3f();
86 | float currentE = 0.0f;
87 | float nextE = 0.0f;
88 | float offsetE = 0.0f;
89 | };
90 |
91 | /**
92 | * Block contains
93 | * · Header:
94 | * - Table of the stored vector components
95 | * - Size: number of float values stored
96 | * · Data:
97 | * The actual float values corresponding to 3D vector components (X,Y,Z)
98 | */
99 | struct GBlock
100 | {
101 | uint32_t table : 24;
102 | uint32_t size : 8;
103 | float data[];
104 |
105 | constexpr static int32_t headBytes() { return sizeof(uint32_t); }
106 | constexpr static int32_t minBytes() { return sizeof(uint32_t) + sizeof(float)*3; }
107 | constexpr static int32_t maxSize() { return 24; }
108 | void reset();
109 | uint16_t addPoint(Vec3f &vec, Vec3f &oldV, uint8_t &i);
110 | };
111 |
112 | /**
113 | * Chunk contains
114 | * · Header:
115 | * - Size: number of bytes occupied by the chunk
116 | * · block: A bunch of blocks
117 | */
118 | struct GChunk
119 | {
120 | constexpr static int32_t headBytes() { return sizeof(chunkSize[0]); }
121 | void nextBlock();
122 | void reset();
123 | void rewind();
124 | int16_t addPoint(Vec3f &vec, Vec3f &oldV);
125 | int16_t readPoint(Vec3f &oldP);
126 |
127 | /**
128 | * @brief Load chunk from file
129 | *
130 | * @param buff Memory buffer to store the chunk. MUST BE OF AT LEAST 'bufferLen' BYTES!
131 | * @param file File struct where the chunk is stored
132 | * @return size_t Return the number of bytes read. Returns 0 on error.
133 | */
134 | size_t read(void* buff, FILE* file);
135 | void setChunk(void* ptr);
136 | int16_t getSize() const { return *chunkSize; }
137 |
138 | private:
139 | uint8_t idx = 0;
140 | uint32_t mask = 1;
141 | int16_t* chunkSize;
142 | GBlock* block;
143 | };
144 |
145 | /**
146 | * Cache contains
147 | * · size: number of bytes stored in cache
148 | * · camPos: Calculated camera position
149 | * · chunk: the current active chunk being written
150 | */
151 | struct GCache
152 | {
153 | Vec3f camPos;
154 | GChunk chunk;
155 |
156 | GCache();
157 | ~GCache();
158 | void nextChunk();
159 | void reset();
160 | void rewind();
161 |
162 | /**
163 | * @brief Add point to cache
164 | *
165 | * @param vec New point
166 | * @param oldV Previous point
167 | * @return int16_t Returns number of bytes written. Returns -1 on error
168 | */
169 | int16_t addPoint(Vec3f &vec, Vec3f &oldV);
170 | size_t write(int32_t maxSize, FILE* file);
171 |
172 | /**
173 | * @brief Load cache from file. Only one chunk is read
174 | *
175 | * @param buff Memory buffer to store the cache. MUST BE OF AT LEAST 'bufferLen' BYTES!
176 | * @param file File struct where the cache is stored
177 | * @return size_t Return the number of bytes read. Returns 0 on error.
178 | */
179 | size_t read(void* buff, FILE* file);
180 | int16_t readPoint(Vec3f &oldP);
181 |
182 | int32_t getSize() const { return size; }
183 |
184 | private:
185 | char* buffer;
186 | int32_t size = 0;
187 | int32_t readPtr = 0;
188 | int32_t nextStop = 0;
189 | int32_t lastReadPtr = 0;
190 | };
191 |
192 | struct Boundary
193 | {
194 | Vec3f Xmax;
195 | Vec3f Xmin;
196 | Vec3f Ymax;
197 | Vec3f Ymin;
198 | };
199 |
200 | enum renderState
201 | {
202 | STOP, // Suspended state
203 | READY, // Task ready
204 | INIT, // Initialize G Code rendering
205 | PRE_PROCESS, // PreProcess step
206 | RENDER, // Render step
207 | END, // Finalize G Code rendering
208 | ERROR
209 | };
210 |
211 | static bool _init;
212 | static GCodeRenderer _instance;
213 |
214 | static uint8_t eState;
215 | static uint8_t isReady; // Bitmap [0: main task, 1: worker, 2: assembler]
216 | float progress = 0.0f;
217 |
218 | GCache tmpCache;
219 | bool isTmpOnRam = false;
220 | uint16_t* outImg = nullptr;
221 | float* zbuf = nullptr;
222 |
223 | FILE* rfile;
224 | FILE* wfile;
225 | char readBuffers[rQueueLen][bufferLen]; // Buffers where data to be processed is stored
226 | char vectorBuffer[vecQueueLen][vecBufferLen*sizeof(Vec3f)]; // Buffer for movement vectors and pixel data
227 | char tmpBuffer[maxLineLen]; // Temporal buffer to hold incomplete lines when reading gcode
228 | char rBuffer[bufferLen]; // System buffer for fread
229 | char wBuffer[bufferLen]; // System buffer for fwrite
230 | std::string filePath;
231 | std::string tmpPath;
232 | std::string imgPath;
233 |
234 | Vec3f camPos;
235 | static constexpr int32_t near = 200;
236 | static constexpr Vec3f lightDir = Vec3f(1.0f, 0.0f, 0.0f);
237 | static constexpr Vec3f scrOff = Vec3f(160.0f, 160.0f, 0.0f);
238 | static constexpr float camTheta = M_PI/6.0f;
239 | static constexpr float camPhi = M_PI*2.0f/3.0f;
240 | Mat3 rotMat;
241 | Mat4 projMat;
242 |
243 | FileInfo info;
244 | bool isShell = true;
245 |
246 | QueueHandle_t threadQueue;
247 | QueueHandle_t thrdRetQueue;
248 | QueueHandle_t vectorQueue;
249 | QueueHandle_t vectRetQueue;
250 | SemaphoreHandle_t readyFlag;
251 |
252 | TaskHandle_t main;
253 | TaskHandle_t worker;
254 | TaskHandle_t assembler;
255 |
256 | GCodeRenderer();
257 | ~GCodeRenderer();
258 |
259 | static void mainTask(void* arg);
260 | static void threadTask(void* arg);
261 | static void assemblerTask(void* arg);
262 |
263 | // Stage 1
264 | esp_err_t readFile();
265 | esp_err_t readTmp();
266 |
267 | // Stage 2
268 | void processGcode();
269 |
270 | // Stage 3
271 | esp_err_t generatePath();
272 | esp_err_t renderMesh();
273 |
274 | // Helpers
275 | int8_t parseGcode(char* &p, PrinterState &state);
276 | void parseComment(const char* str);
277 | void checkCamPos(const Vec3f &u, Boundary &limit);
278 |
279 | // Rendering
280 | void projectLine(const Vec3f &u, const Vec3f &v);
281 | void drawLine(const Vec3f &u, const Vec3f &v, uint16_t color);
282 | void putPixel(const Pixel pix);
283 |
284 | // General functions
285 | void generateFilenames();
286 | esp_err_t loadImg();
287 | void init();
288 | void stopTasks();
289 | esp_err_t waitIdle();
290 |
291 | public:
292 | esp_err_t begin(std::string file);
293 | void stop();
294 | esp_err_t getRender(uint16_t** outPtr, TickType_t timeout);
295 | static GCodeRenderer* instance();
296 | void printMinStack();
297 | float getProgress() { return progress; };
298 | const FileInfo* getInfo() { return &info; };
299 | };
300 |
301 | #endif // GCODERENDERER_H
302 |
--------------------------------------------------------------------------------
/components/dbg_log/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | idf_component_register(SRCS "dbg_log.c"
2 | INCLUDE_DIRS "include")
--------------------------------------------------------------------------------
/components/dbg_log/LICENSE:
--------------------------------------------------------------------------------
1 |
2 |
3 | GNU GENERAL PUBLIC LICENSE
4 | Version 3, 29 June 2007
5 |
6 | Copyright (c) 2007 Free Software Foundation, Inc.
7 | Everyone is permitted to copy and distribute verbatim copies
8 | of this license document, but changing it is not allowed.
9 |
10 | Preamble
11 |
12 | The GNU General Public License is a free, copyleft license for
13 | software and other kinds of works.
14 |
15 | The licenses for most software and other practical works are designed
16 | to take away your freedom to share and change the works. By contrast,
17 | the GNU General Public License is intended to guarantee your freedom to
18 | share and change all versions of a program--to make sure it remains free
19 | software for all its users. We, the Free Software Foundation, use the
20 | GNU General Public License for most of our software; it applies also to
21 | any other work released this way by its authors. You can apply it to
22 | your programs, too.
23 |
24 | When we speak of free software, we are referring to freedom, not
25 | price. Our General Public Licenses are designed to make sure that you
26 | have the freedom to distribute copies of free software (and charge for
27 | them if you wish), that you receive source code or can get it if you
28 | want it, that you can change the software or use pieces of it in new
29 | free programs, and that you know you can do these things.
30 |
31 | To protect your rights, we need to prevent others from denying you
32 | these rights or asking you to surrender the rights. Therefore, you have
33 | certain responsibilities if you distribute copies of the software, or if
34 | you modify it: responsibilities to respect the freedom of others.
35 |
36 | For example, if you distribute copies of such a program, whether
37 | gratis or for a fee, you must pass on to the recipients the same
38 | freedoms that you received. You must make sure that they, too, receive
39 | or can get the source code. And you must show them these terms so they
40 | know their rights.
41 |
42 | Developers that use the GNU GPL protect your rights with two steps:
43 | (1) assert copyright on the software, and (2) offer you this License
44 | giving you legal permission to copy, distribute and/or modify it.
45 |
46 | For the developers' and authors' protection, the GPL clearly explains
47 | that there is no warranty for this free software. For both users' and
48 | authors' sake, the GPL requires that modified versions be marked as
49 | changed, so that their problems will not be attributed erroneously to
50 | authors of previous versions.
51 |
52 | Some devices are designed to deny users access to install or run
53 | modified versions of the software inside them, although the manufacturer
54 | can do so. This is fundamentally incompatible with the aim of
55 | protecting users' freedom to change the software. The systematic
56 | pattern of such abuse occurs in the area of products for individuals to
57 | use, which is precisely where it is most unacceptable. Therefore, we
58 | have designed this version of the GPL to prohibit the practice for those
59 | products. If such problems arise substantially in other domains, we
60 | stand ready to extend this provision to those domains in future versions
61 | of the GPL, as needed to protect the freedom of users.
62 |
63 | Finally, every program is threatened constantly by software patents.
64 | States should not allow patents to restrict development and use of
65 | software on general-purpose computers, but in those that do, we wish to
66 | avoid the special danger that patents applied to a free program could
67 | make it effectively proprietary. To prevent this, the GPL assures that
68 | patents cannot be used to render the program non-free.
69 |
70 | The precise terms and conditions for copying, distribution and
71 | modification follow.
72 |
73 | TERMS AND CONDITIONS
74 |
75 | 0. Definitions.
76 |
77 | "This License" refers to version 3 of the GNU General Public License.
78 |
79 | "Copyright" also means copyright-like laws that apply to other kinds of
80 | works, such as semiconductor masks.
81 |
82 | "The Program" refers to any copyrightable work licensed under this
83 | License. Each licensee is addressed as "you". "Licensees" and
84 | "recipients" may be individuals or organizations.
85 |
86 | To "modify" a work means to copy from or adapt all or part of the work
87 | in a fashion requiring copyright permission, other than the making of an
88 | exact copy. The resulting work is called a "modified version" of the
89 | earlier work or a work "based on" the earlier work.
90 |
91 | A "covered work" means either the unmodified Program or a work based
92 | on the Program.
93 |
94 | To "propagate" a work means to do anything with it that, without
95 | permission, would make you directly or secondarily liable for
96 | infringement under applicable copyright law, except executing it on a
97 | computer or modifying a private copy. Propagation includes copying,
98 | distribution (with or without modification), making available to the
99 | public, and in some countries other activities as well.
100 |
101 | To "convey" a work means any kind of propagation that enables other
102 | parties to make or receive copies. Mere interaction with a user through
103 | a computer network, with no transfer of a copy, is not conveying.
104 |
105 | An interactive user interface displays "Appropriate Legal Notices"
106 | to the extent that it includes a convenient and prominently visible
107 | feature that (1) displays an appropriate copyright notice, and (2)
108 | tells the user that there is no warranty for the work (except to the
109 | extent that warranties are provided), that licensees may convey the
110 | work under this License, and how to view a copy of this License. If
111 | the interface presents a list of user commands or options, such as a
112 | menu, a prominent item in the list meets this criterion.
113 |
114 | 1. Source Code.
115 |
116 | The "source code" for a work means the preferred form of the work
117 | for making modifications to it. "Object code" means any non-source
118 | form of a work.
119 |
120 | A "Standard Interface" means an interface that either is an official
121 | standard defined by a recognized standards body, or, in the case of
122 | interfaces specified for a particular programming language, one that
123 | is widely used among developers working in that language.
124 |
125 | The "System Libraries" of an executable work include anything, other
126 | than the work as a whole, that (a) is included in the normal form of
127 | packaging a Major Component, but which is not part of that Major
128 | Component, and (b) serves only to enable use of the work with that
129 | Major Component, or to implement a Standard Interface for which an
130 | implementation is available to the public in source code form. A
131 | "Major Component", in this context, means a major essential component
132 | (kernel, window system, and so on) of the specific operating system
133 | (if any) on which the executable work runs, or a compiler used to
134 | produce the work, or an object code interpreter used to run it.
135 |
136 | The "Corresponding Source" for a work in object code form means all
137 | the source code needed to generate, install, and (for an executable
138 | work) run the object code and to modify the work, including scripts to
139 | control those activities. However, it does not include the work's
140 | System Libraries, or general-purpose tools or generally available free
141 | programs which are used unmodified in performing those activities but
142 | which are not part of the work. For example, Corresponding Source
143 | includes interface definition files associated with source files for
144 | the work, and the source code for shared libraries and dynamically
145 | linked subprograms that the work is specifically designed to require,
146 | such as by intimate data communication or control flow between those
147 | subprograms and other parts of the work.
148 |
149 | The Corresponding Source need not include anything that users
150 | can regenerate automatically from other parts of the Corresponding
151 | Source.
152 |
153 | The Corresponding Source for a work in source code form is that
154 | same work.
155 |
156 | 2. Basic Permissions.
157 |
158 | All rights granted under this License are granted for the term of
159 | copyright on the Program, and are irrevocable provided the stated
160 | conditions are met. This License explicitly affirms your unlimited
161 | permission to run the unmodified Program. The output from running a
162 | covered work is covered by this License only if the output, given its
163 | content, constitutes a covered work. This License acknowledges your
164 | rights of fair use or other equivalent, as provided by copyright law.
165 |
166 | You may make, run and propagate covered works that you do not
167 | convey, without conditions so long as your license otherwise remains
168 | in force. You may convey covered works to others for the sole purpose
169 | of having them make modifications exclusively for you, or provide you
170 | with facilities for running those works, provided that you comply with
171 | the terms of this License in conveying all material for which you do
172 | not control copyright. Those thus making or running the covered works
173 | for you must do so exclusively on your behalf, under your direction
174 | and control, on terms that prohibit them from making any copies of
175 | your copyrighted material outside their relationship with you.
176 |
177 | Conveying under any other circumstances is permitted solely under
178 | the conditions stated below. Sublicensing is not allowed; section 10
179 | makes it unnecessary.
180 |
181 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
182 |
183 | No covered work shall be deemed part of an effective technological
184 | measure under any applicable law fulfilling obligations under article
185 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
186 | similar laws prohibiting or restricting circumvention of such
187 | measures.
188 |
189 | When you convey a covered work, you waive any legal power to forbid
190 | circumvention of technological measures to the extent such circumvention
191 | is effected by exercising rights under this License with respect to
192 | the covered work, and you disclaim any intention to limit operation or
193 | modification of the work as a means of enforcing, against the work's
194 | users, your or third parties' legal rights to forbid circumvention of
195 | technological measures.
196 |
197 | 4. Conveying Verbatim Copies.
198 |
199 | You may convey verbatim copies of the Program's source code as you
200 | receive it, in any medium, provided that you conspicuously and
201 | appropriately publish on each copy an appropriate copyright notice;
202 | keep intact all notices stating that this License and any
203 | non-permissive terms added in accord with section 7 apply to the code;
204 | keep intact all notices of the absence of any warranty; and give all
205 | recipients a copy of this License along with the Program.
206 |
207 | You may charge any price or no price for each copy that you convey,
208 | and you may offer support or warranty protection for a fee.
209 |
210 | 5. Conveying Modified Source Versions.
211 |
212 | You may convey a work based on the Program, or the modifications to
213 | produce it from the Program, in the form of source code under the
214 | terms of section 4, provided that you also meet all of these conditions:
215 |
216 | a) The work must carry prominent notices stating that you modified
217 | it, and giving a relevant date.
218 |
219 | b) The work must carry prominent notices stating that it is
220 | released under this License and any conditions added under section
221 | 7. This requirement modifies the requirement in section 4 to
222 | "keep intact all notices".
223 |
224 | c) You must license the entire work, as a whole, under this
225 | License to anyone who comes into possession of a copy. This
226 | License will therefore apply, along with any applicable section 7
227 | additional terms, to the whole of the work, and all its parts,
228 | regardless of how they are packaged. This License gives no
229 | permission to license the work in any other way, but it does not
230 | invalidate such permission if you have separately received it.
231 |
232 | d) If the work has interactive user interfaces, each must display
233 | Appropriate Legal Notices; however, if the Program has interactive
234 | interfaces that do not display Appropriate Legal Notices, your
235 | work need not make them do so.
236 |
237 | A compilation of a covered work with other separate and independent
238 | works, which are not by their nature extensions of the covered work,
239 | and which are not combined with it such as to form a larger program,
240 | in or on a volume of a storage or distribution medium, is called an
241 | "aggregate" if the compilation and its resulting copyright are not
242 | used to limit the access or legal rights of the compilation's users
243 | beyond what the individual works permit. Inclusion of a covered work
244 | in an aggregate does not cause this License to apply to the other
245 | parts of the aggregate.
246 |
247 | 6. Conveying Non-Source Forms.
248 |
249 | You may convey a covered work in object code form under the terms
250 | of sections 4 and 5, provided that you also convey the
251 | machine-readable Corresponding Source under the terms of this License,
252 | in one of these ways:
253 |
254 | a) Convey the object code in, or embodied in, a physical product
255 | (including a physical distribution medium), accompanied by the
256 | Corresponding Source fixed on a durable physical medium
257 | customarily used for software interchange.
258 |
259 | b) Convey the object code in, or embodied in, a physical product
260 | (including a physical distribution medium), accompanied by a
261 | written offer, valid for at least three years and valid for as
262 | long as you offer spare parts or customer support for that product
263 | model, to give anyone who possesses the object code either (1) a
264 | copy of the Corresponding Source for all the software in the
265 | product that is covered by this License, on a durable physical
266 | medium customarily used for software interchange, for a price no
267 | more than your reasonable cost of physically performing this
268 | conveying of source, or (2) access to copy the
269 | Corresponding Source from a network server at no charge.
270 |
271 | c) Convey individual copies of the object code with a copy of the
272 | written offer to provide the Corresponding Source. This
273 | alternative is allowed only occasionally and noncommercially, and
274 | only if you received the object code with such an offer, in accord
275 | with subsection 6b.
276 |
277 | d) Convey the object code by offering access from a designated
278 | place (gratis or for a charge), and offer equivalent access to the
279 | Corresponding Source in the same way through the same place at no
280 | further charge. You need not require recipients to copy the
281 | Corresponding Source along with the object code. If the place to
282 | copy the object code is a network server, the Corresponding Source
283 | may be on a different server (operated by you or a third party)
284 | that supports equivalent copying facilities, provided you maintain
285 | clear directions next to the object code saying where to find the
286 | Corresponding Source. Regardless of what server hosts the
287 | Corresponding Source, you remain obligated to ensure that it is
288 | available for as long as needed to satisfy these requirements.
289 |
290 | e) Convey the object code using peer-to-peer transmission, provided
291 | you inform other peers where the object code and Corresponding
292 | Source of the work are being offered to the general public at no
293 | charge under subsection 6d.
294 |
295 | A separable portion of the object code, whose source code is excluded
296 | from the Corresponding Source as a System Library, need not be
297 | included in conveying the object code work.
298 |
299 | A "User Product" is either (1) a "consumer product", which means any
300 | tangible personal property which is normally used for personal, family,
301 | or household purposes, or (2) anything designed or sold for incorporation
302 | into a dwelling. In determining whether a product is a consumer product,
303 | doubtful cases shall be resolved in favor of coverage. For a particular
304 | product received by a particular user, "normally used" refers to a
305 | typical or common use of that class of product, regardless of the status
306 | of the particular user or of the way in which the particular user
307 | actually uses, or expects or is expected to use, the product. A product
308 | is a consumer product regardless of whether the product has substantial
309 | commercial, industrial or non-consumer uses, unless such uses represent
310 | the only significant mode of use of the product.
311 |
312 | "Installation Information" for a User Product means any methods,
313 | procedures, authorization keys, or other information required to install
314 | and execute modified versions of a covered work in that User Product from
315 | a modified version of its Corresponding Source. The information must
316 | suffice to ensure that the continued functioning of the modified object
317 | code is in no case prevented or interfered with solely because
318 | modification has been made.
319 |
320 | If you convey an object code work under this section in, or with, or
321 | specifically for use in, a User Product, and the conveying occurs as
322 | part of a transaction in which the right of possession and use of the
323 | User Product is transferred to the recipient in perpetuity or for a
324 | fixed term (regardless of how the transaction is characterized), the
325 | Corresponding Source conveyed under this section must be accompanied
326 | by the Installation Information. But this requirement does not apply
327 | if neither you nor any third party retains the ability to install
328 | modified object code on the User Product (for example, the work has
329 | been installed in ROM).
330 |
331 | The requirement to provide Installation Information does not include a
332 | requirement to continue to provide support service, warranty, or updates
333 | for a work that has been modified or installed by the recipient, or for
334 | the User Product in which it has been modified or installed. Access to a
335 | network may be denied when the modification itself materially and
336 | adversely affects the operation of the network or violates the rules and
337 | protocols for communication across the network.
338 |
339 | Corresponding Source conveyed, and Installation Information provided,
340 | in accord with this section must be in a format that is publicly
341 | documented (and with an implementation available to the public in
342 | source code form), and must require no special password or key for
343 | unpacking, reading or copying.
344 |
345 | 7. Additional Terms.
346 |
347 | "Additional permissions" are terms that supplement the terms of this
348 | License by making exceptions from one or more of its conditions.
349 | Additional permissions that are applicable to the entire Program shall
350 | be treated as though they were included in this License, to the extent
351 | that they are valid under applicable law. If additional permissions
352 | apply only to part of the Program, that part may be used separately
353 | under those permissions, but the entire Program remains governed by
354 | this License without regard to the additional permissions.
355 |
356 | When you convey a copy of a covered work, you may at your option
357 | remove any additional permissions from that copy, or from any part of
358 | it. (Additional permissions may be written to require their own
359 | removal in certain cases when you modify the work.) You may place
360 | additional permissions on material, added by you to a covered work,
361 | for which you have or can give appropriate copyright permission.
362 |
363 | Notwithstanding any other provision of this License, for material you
364 | add to a covered work, you may (if authorized by the copyright holders of
365 | that material) supplement the terms of this License with terms:
366 |
367 | a) Disclaiming warranty or limiting liability differently from the
368 | terms of sections 15 and 16 of this License; or
369 |
370 | b) Requiring preservation of specified reasonable legal notices or
371 | author attributions in that material or in the Appropriate Legal
372 | Notices displayed by works containing it; or
373 |
374 | c) Prohibiting misrepresentation of the origin of that material, or
375 | requiring that modified versions of such material be marked in
376 | reasonable ways as different from the original version; or
377 |
378 | d) Limiting the use for publicity purposes of names of licensors or
379 | authors of the material; or
380 |
381 | e) Declining to grant rights under trademark law for use of some
382 | trade names, trademarks, or service marks; or
383 |
384 | f) Requiring indemnification of licensors and authors of that
385 | material by anyone who conveys the material (or modified versions of
386 | it) with contractual assumptions of liability to the recipient, for
387 | any liability that these contractual assumptions directly impose on
388 | those licensors and authors.
389 |
390 | All other non-permissive additional terms are considered "further
391 | restrictions" within the meaning of section 10. If the Program as you
392 | received it, or any part of it, contains a notice stating that it is
393 | governed by this License along with a term that is a further
394 | restriction, you may remove that term. If a license document contains
395 | a further restriction but permits relicensing or conveying under this
396 | License, you may add to a covered work material governed by the terms
397 | of that license document, provided that the further restriction does
398 | not survive such relicensing or conveying.
399 |
400 | If you add terms to a covered work in accord with this section, you
401 | must place, in the relevant source files, a statement of the
402 | additional terms that apply to those files, or a notice indicating
403 | where to find the applicable terms.
404 |
405 | Additional terms, permissive or non-permissive, may be stated in the
406 | form of a separately written license, or stated as exceptions;
407 | the above requirements apply either way.
408 |
409 | 8. Termination.
410 |
411 | You may not propagate or modify a covered work except as expressly
412 | provided under this License. Any attempt otherwise to propagate or
413 | modify it is void, and will automatically terminate your rights under
414 | this License (including any patent licenses granted under the third
415 | paragraph of section 11).
416 |
417 | However, if you cease all violation of this License, then your
418 | license from a particular copyright holder is reinstated (a)
419 | provisionally, unless and until the copyright holder explicitly and
420 | finally terminates your license, and (b) permanently, if the copyright
421 | holder fails to notify you of the violation by some reasonable means
422 | prior to 60 days after the cessation.
423 |
424 | Moreover, your license from a particular copyright holder is
425 | reinstated permanently if the copyright holder notifies you of the
426 | violation by some reasonable means, this is the first time you have
427 | received notice of violation of this License (for any work) from that
428 | copyright holder, and you cure the violation prior to 30 days after
429 | your receipt of the notice.
430 |
431 | Termination of your rights under this section does not terminate the
432 | licenses of parties who have received copies or rights from you under
433 | this License. If your rights have been terminated and not permanently
434 | reinstated, you do not qualify to receive new licenses for the same
435 | material under section 10.
436 |
437 | 9. Acceptance Not Required for Having Copies.
438 |
439 | You are not required to accept this License in order to receive or
440 | run a copy of the Program. Ancillary propagation of a covered work
441 | occurring solely as a consequence of using peer-to-peer transmission
442 | to receive a copy likewise does not require acceptance. However,
443 | nothing other than this License grants you permission to propagate or
444 | modify any covered work. These actions infringe copyright if you do
445 | not accept this License. Therefore, by modifying or propagating a
446 | covered work, you indicate your acceptance of this License to do so.
447 |
448 | 10. Automatic Licensing of Downstream Recipients.
449 |
450 | Each time you convey a covered work, the recipient automatically
451 | receives a license from the original licensors, to run, modify and
452 | propagate that work, subject to this License. You are not responsible
453 | for enforcing compliance by third parties with this License.
454 |
455 | An "entity transaction" is a transaction transferring control of an
456 | organization, or substantially all assets of one, or subdividing an
457 | organization, or merging organizations. If propagation of a covered
458 | work results from an entity transaction, each party to that
459 | transaction who receives a copy of the work also receives whatever
460 | licenses to the work the party's predecessor in interest had or could
461 | give under the previous paragraph, plus a right to possession of the
462 | Corresponding Source of the work from the predecessor in interest, if
463 | the predecessor has it or can get it with reasonable efforts.
464 |
465 | You may not impose any further restrictions on the exercise of the
466 | rights granted or affirmed under this License. For example, you may
467 | not impose a license fee, royalty, or other charge for exercise of
468 | rights granted under this License, and you may not initiate litigation
469 | (including a cross-claim or counterclaim in a lawsuit) alleging that
470 | any patent claim is infringed by making, using, selling, offering for
471 | sale, or importing the Program or any portion of it.
472 |
473 | 11. Patents.
474 |
475 | A "contributor" is a copyright holder who authorizes use under this
476 | License of the Program or a work on which the Program is based. The
477 | work thus licensed is called the contributor's "contributor version".
478 |
479 | A contributor's "essential patent claims" are all patent claims
480 | owned or controlled by the contributor, whether already acquired or
481 | hereafter acquired, that would be infringed by some manner, permitted
482 | by this License, of making, using, or selling its contributor version,
483 | but do not include claims that would be infringed only as a
484 | consequence of further modification of the contributor version. For
485 | purposes of this definition, "control" includes the right to grant
486 | patent sublicenses in a manner consistent with the requirements of
487 | this License.
488 |
489 | Each contributor grants you a non-exclusive, worldwide, royalty-free
490 | patent license under the contributor's essential patent claims, to
491 | make, use, sell, offer for sale, import and otherwise run, modify and
492 | propagate the contents of its contributor version.
493 |
494 | In the following three paragraphs, a "patent license" is any express
495 | agreement or commitment, however denominated, not to enforce a patent
496 | (such as an express permission to practice a patent or covenant not to
497 | sue for patent infringement). To "grant" such a patent license to a
498 | party means to make such an agreement or commitment not to enforce a
499 | patent against the party.
500 |
501 | If you convey a covered work, knowingly relying on a patent license,
502 | and the Corresponding Source of the work is not available for anyone
503 | to copy, free of charge and under the terms of this License, through a
504 | publicly available network server or other readily accessible means,
505 | then you must either (1) cause the Corresponding Source to be so
506 | available, or (2) arrange to deprive yourself of the benefit of the
507 | patent license for this particular work, or (3) arrange, in a manner
508 | consistent with the requirements of this License, to extend the patent
509 | license to downstream recipients. "Knowingly relying" means you have
510 | actual knowledge that, but for the patent license, your conveying the
511 | covered work in a country, or your recipient's use of the covered work
512 | in a country, would infringe one or more identifiable patents in that
513 | country that you have reason to believe are valid.
514 |
515 | If, pursuant to or in connection with a single transaction or
516 | arrangement, you convey, or propagate by procuring conveyance of, a
517 | covered work, and grant a patent license to some of the parties
518 | receiving the covered work authorizing them to use, propagate, modify
519 | or convey a specific copy of the covered work, then the patent license
520 | you grant is automatically extended to all recipients of the covered
521 | work and works based on it.
522 |
523 | A patent license is "discriminatory" if it does not include within
524 | the scope of its coverage, prohibits the exercise of, or is
525 | conditioned on the non-exercise of one or more of the rights that are
526 | specifically granted under this License. You may not convey a covered
527 | work if you are a party to an arrangement with a third party that is
528 | in the business of distributing software, under which you make payment
529 | to the third party based on the extent of your activity of conveying
530 | the work, and under which the third party grants, to any of the
531 | parties who would receive the covered work from you, a discriminatory
532 | patent license (a) in connection with copies of the covered work
533 | conveyed by you (or copies made from those copies), or (b) primarily
534 | for and in connection with specific products or compilations that
535 | contain the covered work, unless you entered into that arrangement,
536 | or that patent license was granted, prior to 28 March 2007.
537 |
538 | Nothing in this License shall be construed as excluding or limiting
539 | any implied license or other defenses to infringement that may
540 | otherwise be available to you under applicable patent law.
541 |
542 | 12. No Surrender of Others' Freedom.
543 |
544 | If conditions are imposed on you (whether by court order, agreement or
545 | otherwise) that contradict the conditions of this License, they do not
546 | excuse you from the conditions of this License. If you cannot convey a
547 | covered work so as to satisfy simultaneously your obligations under this
548 | License and any other pertinent obligations, then as a consequence you may
549 | not convey it at all. For example, if you agree to terms that obligate you
550 | to collect a royalty for further conveying from those to whom you convey
551 | the Program, the only way you could satisfy both those terms and this
552 | License would be to refrain entirely from conveying the Program.
553 |
554 | 13. Use with the GNU Affero General Public License.
555 |
556 | Notwithstanding any other provision of this License, you have
557 | permission to link or combine any covered work with a work licensed
558 | under version 3 of the GNU Affero General Public License into a single
559 | combined work, and to convey the resulting work. The terms of this
560 | License will continue to apply to the part which is the covered work,
561 | but the special requirements of the GNU Affero General Public License,
562 | section 13, concerning interaction through a network will apply to the
563 | combination as such.
564 |
565 | 14. Revised Versions of this License.
566 |
567 | The Free Software Foundation may publish revised and/or new versions of
568 | the GNU General Public License from time to time. Such new versions will
569 | be similar in spirit to the present version, but may differ in detail to
570 | address new problems or concerns.
571 |
572 | Each version is given a distinguishing version number. If the
573 | Program specifies that a certain numbered version of the GNU General
574 | Public License "or any later version" applies to it, you have the
575 | option of following the terms and conditions either of that numbered
576 | version or of any later version published by the Free Software
577 | Foundation. If the Program does not specify a version number of the
578 | GNU General Public License, you may choose any version ever published
579 | by the Free Software Foundation.
580 |
581 | If the Program specifies that a proxy can decide which future
582 | versions of the GNU General Public License can be used, that proxy's
583 | public statement of acceptance of a version permanently authorizes you
584 | to choose that version for the Program.
585 |
586 | Later license versions may give you additional or different
587 | permissions. However, no additional obligations are imposed on any
588 | author or copyright holder as a result of your choosing to follow a
589 | later version.
590 |
591 | 15. Disclaimer of Warranty.
592 |
593 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
594 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
595 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
596 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
597 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
598 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
599 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
600 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
601 |
602 | 16. Limitation of Liability.
603 |
604 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
605 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
606 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
607 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
608 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
609 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
610 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
611 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
612 | SUCH DAMAGES.
613 |
614 | 17. Interpretation of Sections 15 and 16.
615 |
616 | If the disclaimer of warranty and limitation of liability provided
617 | above cannot be given local legal effect according to their terms,
618 | reviewing courts shall apply local law that most closely approximates
619 | an absolute waiver of all civil liability in connection with the
620 | Program, unless a warranty or assumption of liability accompanies a
621 | copy of the Program in return for a fee.
622 |
623 | END OF TERMS AND CONDITIONS
624 |
625 | How to Apply These Terms to Your New Programs
626 |
627 | If you develop a new program, and you want it to be of the greatest
628 | possible use to the public, the best way to achieve this is to make it
629 | free software which everyone can redistribute and change under these terms.
630 |
631 | To do so, attach the following notices to the program. It is safest
632 | to attach them to the start of each source file to most effectively
633 | state the exclusion of warranty; and each file should have at least
634 | the "copyright" line and a pointer to where the full notice is found.
635 |
636 | {one line to give the program's name and a brief idea of what it does.}
637 | Copyright (c) {year} {name of author}
638 |
639 | This program is free software: you can redistribute it and/or modify
640 | it under the terms of the GNU General Public License as published by
641 | the Free Software Foundation, either version 3 of the License, or
642 | (at your option) any later version.
643 |
644 | This program is distributed in the hope that it will be useful,
645 | but WITHOUT ANY WARRANTY; without even the implied warranty of
646 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
647 | GNU General Public License for more details.
648 |
649 | You should have received a copy of the GNU General Public License
650 | along with this program. If not, see .
651 |
652 | Also add information on how to contact you by electronic and paper mail.
653 |
654 | If the program does terminal interaction, make it output a short
655 | notice like this when it starts in an interactive mode:
656 |
657 | {project} Copyright (c) {year} {fullname}
658 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
659 | This is free software, and you are welcome to redistribute it
660 | under certain conditions; type `show c' for details.
661 |
662 | The hypothetical commands `show w' and `show c' should show the appropriate
663 | parts of the General Public License. Of course, your program's commands
664 | might be different; for a GUI interface, you would use an "about box".
665 |
666 | You should also get your employer (if you work as a programmer) or school,
667 | if any, to sign a "copyright disclaimer" for the program, if necessary.
668 | For more information on this, and how to apply and follow the GNU GPL, see
669 | .
670 |
671 | The GNU General Public License does not permit incorporating your program
672 | into proprietary programs. If your program is a subroutine library, you
673 | may consider it more useful to permit linking proprietary applications with
674 | the library. If this is what you want to do, use the GNU Lesser General
675 | Public License instead of this License. But first, please read
676 | .
677 |
--------------------------------------------------------------------------------
/components/dbg_log/dbg_log.c:
--------------------------------------------------------------------------------
1 | /**
2 | * @file dbg_log.c
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 04-12-2021
5 | * -----
6 | * Last Modified: 12-02-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2021 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include
26 | #include "esp_bit_defs.h"
27 | #include "dbg_log.h"
28 |
29 | static uint8_t activeSection = 0;
30 | static uint64_t sectionD_state = UINT64_MAX;
31 | static uint64_t sectionV_state = 0;
32 |
33 | void dbg_log_define_section(uint8_t id)
34 | {
35 | if (id >= 64) return;
36 |
37 | activeSection = id;
38 | }
39 |
40 | void dbg_log_Dlevel_set(uint8_t id, bool state)
41 | {
42 | if (id >= 64) return;
43 | if (state)
44 | {
45 | sectionD_state |= BIT64(id);
46 | }
47 | else
48 | {
49 | sectionD_state &= ~BIT64(id);
50 | }
51 | }
52 |
53 | void dbg_log_Vlevel_set(uint8_t id, bool state)
54 | {
55 | if (id >= 64) return;
56 | if (state)
57 | {
58 | sectionV_state |= BIT64(id);
59 | }
60 | else
61 | {
62 | sectionV_state &= ~BIT64(id);
63 | }
64 | }
65 |
66 | static bool should_output(uint8_t level, uint8_t section)
67 | {
68 | if (level == DBG_LOG_DEBUG)
69 | {
70 | return (bool)(sectionD_state & BIT64(section));
71 | }
72 | else if (level == DBG_LOG_VERBOSE)
73 | {
74 | return (bool)(sectionV_state & BIT64(section));
75 | }
76 |
77 | return true;
78 | }
79 |
80 | void dbg_log_write_s(uint8_t level, const char *format, ...)
81 | {
82 | va_list list;
83 | va_start(list, format);
84 | if (should_output(level, activeSection))
85 | {
86 | vprintf(format, list);
87 | }
88 | va_end(list);
89 | }
90 |
91 | void dbg_log_write(const char *format, ...)
92 | {
93 | va_list list;
94 | va_start(list, format);
95 | vprintf(format, list);
96 | va_end(list);
97 | }
98 |
--------------------------------------------------------------------------------
/components/dbg_log/include/dbg_log.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file dbg_log.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 28-09-2021
5 | * -----
6 | * Last Modified: 13-02-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2021 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef DBG_LOG_H
26 | #define DBG_LOG_H
27 |
28 | #include "esp_log.h"
29 |
30 | #ifdef __cplusplus
31 | extern "C" {
32 | #endif
33 |
34 | #define DBG_LOG_NONE 0 /*!< No log output */
35 | #define DBG_LOG_ERROR 1 /*!< Critical errors, software module can not recover on its own */
36 | #define DBG_LOG_WARN 2 /*!< Error conditions from which recovery measures have been taken */
37 | #define DBG_LOG_INFO 3 /*!< Information messages which describe normal flow of events */
38 | #define DBG_LOG_DEBUG 4 /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
39 | #define DBG_LOG_VERBOSE 5 /*!< All information of the process. */
40 |
41 | #define CONFIG_DBG_LOG_LEVEL DBG_LOG_DEBUG
42 |
43 |
44 | /**
45 | * @brief Create new section
46 | *
47 | * @param id Section number ID (0 < id < 64)
48 | */
49 | void dbg_log_define_section(uint8_t id);
50 |
51 | /**
52 | * @brief Enable/disable debug level sections
53 | *
54 | * @param id Section ID
55 | * @param state New section state
56 | */
57 | void dbg_log_Dlevel_set(uint8_t id, bool state);
58 |
59 | /**
60 | * @brief Enable/disable verbose level sections
61 | *
62 | * @param id Section ID
63 | * @param state New section state
64 | */
65 | void dbg_log_Vlevel_set(uint8_t id, bool state);
66 |
67 | /**
68 | * @brief If section is enabled for the corresponding level print message to UART
69 | *
70 | * @param level Logging level
71 | * @param format Message
72 | * @param ...
73 | */
74 | void dbg_log_write_s(uint8_t level, const char *format, ...);
75 |
76 | /**
77 | * @brief Print message to UART
78 | *
79 | * @param format Message
80 | * @param ...
81 | */
82 | void dbg_log_write(const char *format, ...);
83 |
84 | #ifndef __FILENAME__
85 | #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
86 | #endif
87 |
88 | #if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS
89 | #define DBG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%u) %s:%u: " format LOG_RESET_COLOR "\n", esp_log_timestamp(), __FILENAME__, __LINE__
90 | #elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM
91 | #define DBG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%s) %s:%u: " format LOG_RESET_COLOR "\n", esp_log_system_timestamp(), __FILENAME__, __LINE__
92 | #endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx
93 |
94 | #define DBG_LOG_EARLY_IMPL(format, level, letter, ...) if (LOG_LOCAL_LEVEL >= level) \
95 | esp_rom_printf(DBG_FORMAT(letter, format), ##__VA_ARGS__)
96 |
97 | /// macro to output logs in startup code, before heap allocator and syscalls have been initialized.
98 | #define DBG_EARLY_LOGE(format, ... ) DBG_LOG_EARLY_IMPL(format, ESP_LOG_ERROR, E, ##__VA_ARGS__)
99 | #define DBG_EARLY_LOGW(format, ... ) DBG_LOG_EARLY_IMPL(format, ESP_LOG_WARN, W, ##__VA_ARGS__)
100 | #define DBG_EARLY_LOGI(format, ... ) DBG_LOG_EARLY_IMPL(format, ESP_LOG_INFO, I, ##__VA_ARGS__)
101 | #define DBG_EARLY_LOGD(format, ... ) DBG_LOG_EARLY_IMPL(format, ESP_LOG_DEBUG, D, ##__VA_ARGS__)
102 | #define DBG_EARLY_LOGV(format, ... ) DBG_LOG_EARLY_IMPL(format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__)
103 |
104 | // Macros
105 | #ifndef BOOTLOADER_BUILD
106 | #if CONFIG_DBG_LOG_LEVEL >= DBG_LOG_VERBOSE
107 | #define DBG_LOGV(format, ...) dbg_log_write_s(DBG_LOG_VERBOSE, DBG_FORMAT(V, format), ##__VA_ARGS__)
108 | #else
109 | #define DBG_LOGV(format, ...)
110 | #endif
111 |
112 | #if CONFIG_DBG_LOG_LEVEL >= DBG_LOG_DEBUG
113 | #define DBG_LOGD(format, ...) dbg_log_write_s(DBG_LOG_DEBUG, DBG_FORMAT(D, format), ##__VA_ARGS__)
114 | #define DBG_LOGD_IF(__e, format, ...) ({if (__e) {DBG_LOGD(format, ##__VA_ARGS__);}})
115 | #else
116 | #define DBG_LOGD(format, ...)
117 | #define DBG_LOGD_IF(__e, format, ...)
118 | #endif
119 |
120 | #if CONFIG_DBG_LOG_LEVEL >= DBG_LOG_INFO
121 | #define DBG_LOGI(format, ...) dbg_log_write(DBG_FORMAT(I, format), ##__VA_ARGS__)
122 | #else
123 | #define DBG_LOGI(format, ...)
124 | #endif
125 |
126 | #if CONFIG_DBG_LOG_LEVEL >= DBG_LOG_WARN
127 | #define DBG_LOGW(format, ...) dbg_log_write(DBG_FORMAT(W, format), ##__VA_ARGS__)
128 | #define DBG_LOGW_IF(__e, format, ...) ({if (__e) {DBG_LOGW(format, ##__VA_ARGS__);}})
129 | #else
130 | #define DBG_LOGW(format, ...)
131 | #define DBG_LOGW_IF(__e, format, ...)
132 | #endif
133 |
134 | #if CONFIG_DBG_LOG_LEVEL >= DBG_LOG_ERROR
135 | #define DBG_LOGE(format, ...) dbg_log_write(DBG_FORMAT(E, format), ##__VA_ARGS__)
136 | #define DBG_LOGE_IF(__e, format, ...) ({if (__e) {DBG_LOGE(format, ##__VA_ARGS__);}})
137 | #define DBG_LOGE_AND_RETURN_IF(__e, ret, format, ...) ({ \
138 | if (__e) { \
139 | DBG_LOGE(format, ##__VA_ARGS__); \
140 | return ret; \
141 | }})
142 | #else
143 | #define DBG_LOGE(format, ...)
144 | #define DBG_LOGE_IF(__e, format, ...)
145 | #define DBG_LOGE_AND_RETURN_IF(__e, ret, format, ...)
146 | #endif
147 | #else
148 | #define DBG_LOGV(format, ...) DBG_EARLY_LOGE(tag, format, ##__VA_ARGS__)
149 | #define DBG_LOGD(format, ...) DBG_EARLY_LOGW(tag, format, ##__VA_ARGS__)
150 | #define DBG_LOGI(format, ...) DBG_EARLY_LOGI(tag, format, ##__VA_ARGS__)
151 | #define DBG_LOGW(format, ...) DBG_EARLY_LOGD(tag, format, ##__VA_ARGS__)
152 | #define DBG_LOGE(format, ...) DBG_EARLY_LOGV(tag, format, ##__VA_ARGS__)
153 | #endif // BOOTLOADER_BUILD
154 |
155 | #ifdef __cplusplus
156 | }
157 | #endif
158 |
159 | #endif // SAFESERIAL_H
160 |
--------------------------------------------------------------------------------
/data/Move_48.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/Move_48.bmp
--------------------------------------------------------------------------------
/data/SDcard_64.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/SDcard_64.bmp
--------------------------------------------------------------------------------
/data/Settings_48.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/Settings_48.bmp
--------------------------------------------------------------------------------
/data/arrowL_48.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/arrowL_48.bmp
--------------------------------------------------------------------------------
/data/arrowR_48.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/arrowR_48.bmp
--------------------------------------------------------------------------------
/data/extruder_32.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/extruder_32.bmp
--------------------------------------------------------------------------------
/data/fan_32.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/fan_32.bmp
--------------------------------------------------------------------------------
/data/file_24.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/file_24.bmp
--------------------------------------------------------------------------------
/data/folder_24.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/folder_24.bmp
--------------------------------------------------------------------------------
/data/gcode_24.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/gcode_24.bmp
--------------------------------------------------------------------------------
/data/heatbed_32.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/heatbed_32.bmp
--------------------------------------------------------------------------------
/data/home_24.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/home_24.bmp
--------------------------------------------------------------------------------
/data/return_48.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/data/return_48.bmp
--------------------------------------------------------------------------------
/dependencies.lock:
--------------------------------------------------------------------------------
1 | manifest_hash: c770a695e065f94af8cb38482af465269b65b1f159ce7f6157a3d0b20bea8145
2 | target: esp32
3 | version: 1.0.0
4 |
--------------------------------------------------------------------------------
/hardware/3D_Printer_Screen_V2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/hardware/3D_Printer_Screen_V2.pdf
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_4_27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_4_27.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_4_46.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_4_46.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_4_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_4_5.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_4_56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_4_56.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_5_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_5_20.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_6_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_6_17.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_15_23_7_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_15_23_7_13.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_18_18_55_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_18_18_55_15.png
--------------------------------------------------------------------------------
/images/screenshots/screenshot_2021_1_18_3_1_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/screenshots/screenshot_2021_1_18_3_1_7.png
--------------------------------------------------------------------------------
/images/wiring.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dracir9/3DPrinterScreen/3b9736767de0456ea1097454431573c981c682da/images/wiring.jpg
--------------------------------------------------------------------------------
/main/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | FILE(GLOB_RECURSE cpp_sources ${CMAKE_SOURCE_DIR}/main/*.cpp)
2 | FILE(GLOB_RECURSE c_sources ${CMAKE_SOURCE_DIR}/main/*.c)
3 |
4 | idf_component_register(
5 | # SRCS "main.cpp" "lcdUI.cpp" "tftLCD.cpp" "utility.cpp" "widgets.cpp" "Menu/blac_w.cpp" "Menu/fileBrowser_Scr.cpp" "Menu/gcodePreview_Scr.cpp" "Menu/info_w.cpp"
6 | SRCS ${cpp_sources} ${c_sources}
7 | INCLUDE_DIRS ""
8 | )
9 |
10 | #spiffs_create_partition_image(storage ../data FLASH_IN_PROJECT)
11 |
--------------------------------------------------------------------------------
/main/Free_Fonts.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef FREE_FONTS_H
3 | #define FREE_FONTS_H
4 |
5 | // Attach this header file to your sketch to use the GFX Free Fonts. You can write
6 | // sketches without it, but it makes referencing them easier.
7 |
8 | // This calls up ALL the fonts but they only get loaded if you actually
9 | // use them in your sketch.
10 | //
11 | // No changes are needed to this header file unless new fonts are added to the
12 | // library "Fonts/GFXFF" folder.
13 | //
14 | // To save a lot of typing long names, each font can easily be referenced in the
15 | // sketch in three ways, either with:
16 | //
17 | // 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
18 | // an example being:
19 | //
20 | // tft.setFreeFont(&FreeSansBoldOblique24pt7b);
21 | //
22 | // 2. FF# where # is a number determined by looking at the list below
23 | // an example being:
24 | //
25 | // tft.setFreeFont(FF32);
26 | //
27 | // 3. An abbreviation of the file name. Look at the list below to see
28 | // the abbreviations used, for example:
29 | //
30 | // tft.setFreeFont(FSSBO24)
31 | //
32 | // Where the letters mean:
33 | // F = Free font
34 | // M = Mono
35 | // SS = Sans Serif (double S to distinguish is form serif fonts)
36 | // S = Serif
37 | // B = Bold
38 | // O = Oblique (letter O not zero)
39 | // I = Italic
40 | // # = point size, either 9, 12, 18 or 24
41 | //
42 | // Setting the font to NULL will select the GLCD font:
43 | //
44 | // tft.setFreeFont(NULL); // Set font to GLCD
45 |
46 | //#define LOAD_GFXFF
47 |
48 | #ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h
49 |
50 | // Use these when printing or drawing text in GLCD and high rendering speed fonts
51 | // Call up the font using tft.setTextFont()
52 | #define GFXFF 1
53 | #define GLCD 0
54 | #define FONT2 2
55 | #define FONT4 4
56 | #define FONT6 6
57 | #define FONT7 7
58 | #define FONT8 8
59 |
60 | // Use the following when calling tft.setFreeFont()
61 | //
62 | // Reserved for GLCD font // FF0
63 | //
64 |
65 | #define TT1 &TomThumb
66 |
67 | #define FM9 &FreeMono9pt7b
68 | #define FM12 &FreeMono12pt7b
69 | #define FM18 &FreeMono18pt7b
70 | #define FM24 &FreeMono24pt7b
71 |
72 | #define FMB9 &FreeMonoBold9pt7b
73 | #define FMB12 &FreeMonoBold12pt7b
74 | #define FMB18 &FreeMonoBold18pt7b
75 | #define FMB24 &FreeMonoBold24pt7b
76 |
77 | #define FMO9 &FreeMonoOblique9pt7b
78 | #define FMO12 &FreeMonoOblique12pt7b
79 | #define FMO18 &FreeMonoOblique18pt7b
80 | #define FMO24 &FreeMonoOblique24pt7b
81 |
82 | #define FMBO9 &FreeMonoBoldOblique9pt7b
83 | #define FMBO12 &FreeMonoBoldOblique12pt7b
84 | #define FMBO18 &FreeMonoBoldOblique18pt7b
85 | #define FMBO24 &FreeMonoBoldOblique24pt7b
86 |
87 | #define FSS9 &FreeSans9pt7b
88 | #define FSS12 &FreeSans12pt7b
89 | #define FSS18 &FreeSans18pt7b
90 | #define FSS24 &FreeSans24pt7b
91 |
92 | #define FSSB9 &FreeSansBold9pt7b
93 | #define FSSB12 &FreeSansBold12pt7b
94 | #define FSSB18 &FreeSansBold18pt7b
95 | #define FSSB24 &FreeSansBold24pt7b
96 |
97 | #define FSSO9 &FreeSansOblique9pt7b
98 | #define FSSO12 &FreeSansOblique12pt7b
99 | #define FSSO18 &FreeSansOblique18pt7b
100 | #define FSSO24 &FreeSansOblique24pt7b
101 |
102 | #define FSSBO9 &FreeSansBoldOblique9pt7b
103 | #define FSSBO12 &FreeSansBoldOblique12pt7b
104 | #define FSSBO18 &FreeSansBoldOblique18pt7b
105 | #define FSSBO24 &FreeSansBoldOblique24pt7b
106 |
107 | #define FS9 &FreeSerif9pt7b
108 | #define FS12 &FreeSerif12pt7b
109 | #define FS18 &FreeSerif18pt7b
110 | #define FS24 &FreeSerif24pt7b
111 |
112 | #define FSI9 &FreeSerifItalic9pt7b
113 | #define FSI12 &FreeSerifItalic12pt7b
114 | #define FSI19 &FreeSerifItalic18pt7b
115 | #define FSI24 &FreeSerifItalic24pt7b
116 |
117 | #define FSB9 &FreeSerifBold9pt7b
118 | #define FSB12 &FreeSerifBold12pt7b
119 | #define FSB18 &FreeSerifBold18pt7b
120 | #define FSB24 &FreeSerifBold24pt7b
121 |
122 | #define FSBI9 &FreeSerifBoldItalic9pt7b
123 | #define FSBI12 &FreeSerifBoldItalic12pt7b
124 | #define FSBI18 &FreeSerifBoldItalic18pt7b
125 | #define FSBI24 &FreeSerifBoldItalic24pt7b
126 |
127 | #define FF0 NULL //ff0 reserved for GLCD
128 | #define FF1 &FreeMono9pt7b
129 | #define FF2 &FreeMono12pt7b
130 | #define FF3 &FreeMono18pt7b
131 | #define FF4 &FreeMono24pt7b
132 |
133 | #define FF5 &FreeMonoBold9pt7b
134 | #define FF6 &FreeMonoBold12pt7b
135 | #define FF7 &FreeMonoBold18pt7b
136 | #define FF8 &FreeMonoBold24pt7b
137 |
138 | #define FF9 &FreeMonoOblique9pt7b
139 | #define FF10 &FreeMonoOblique12pt7b
140 | #define FF11 &FreeMonoOblique18pt7b
141 | #define FF12 &FreeMonoOblique24pt7b
142 |
143 | #define FF13 &FreeMonoBoldOblique9pt7b
144 | #define FF14 &FreeMonoBoldOblique12pt7b
145 | #define FF15 &FreeMonoBoldOblique18pt7b
146 | #define FF16 &FreeMonoBoldOblique24pt7b
147 |
148 | #define FF17 &FreeSans9pt7b
149 | #define FF18 &FreeSans12pt7b
150 | #define FF19 &FreeSans18pt7b
151 | #define FF20 &FreeSans24pt7b
152 |
153 | #define FF21 &FreeSansBold9pt7b
154 | #define FF22 &FreeSansBold12pt7b
155 | #define FF23 &FreeSansBold18pt7b
156 | #define FF24 &FreeSansBold24pt7b
157 |
158 | #define FF25 &FreeSansOblique9pt7b
159 | #define FF26 &FreeSansOblique12pt7b
160 | #define FF27 &FreeSansOblique18pt7b
161 | #define FF28 &FreeSansOblique24pt7b
162 |
163 | #define FF29 &FreeSansBoldOblique9pt7b
164 | #define FF30 &FreeSansBoldOblique12pt7b
165 | #define FF31 &FreeSansBoldOblique18pt7b
166 | #define FF32 &FreeSansBoldOblique24pt7b
167 |
168 | #define FF33 &FreeSerif9pt7b
169 | #define FF34 &FreeSerif12pt7b
170 | #define FF35 &FreeSerif18pt7b
171 | #define FF36 &FreeSerif24pt7b
172 |
173 | #define FF37 &FreeSerifItalic9pt7b
174 | #define FF38 &FreeSerifItalic12pt7b
175 | #define FF39 &FreeSerifItalic18pt7b
176 | #define FF40 &FreeSerifItalic24pt7b
177 |
178 | #define FF41 &FreeSerifBold9pt7b
179 | #define FF42 &FreeSerifBold12pt7b
180 | #define FF43 &FreeSerifBold18pt7b
181 | #define FF44 &FreeSerifBold24pt7b
182 |
183 | #define FF45 &FreeSerifBoldItalic9pt7b
184 | #define FF46 &FreeSerifBoldItalic12pt7b
185 | #define FF47 &FreeSerifBoldItalic18pt7b
186 | #define FF48 &FreeSerifBoldItalic24pt7b
187 |
188 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
189 | // Now we define "s"tring versions for easy printing of the font name so:
190 | // tft.println(sFF5);
191 | // will print
192 | // Mono bold 9
193 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
194 |
195 | #define sFF0 "GLCD"
196 | #define sTT1 "Tom Thumb"
197 | #define sFF1 "Mono 9"
198 | #define sFF2 "Mono 12"
199 | #define sFF3 "Mono 18"
200 | #define sFF4 "Mono 24"
201 |
202 | #define sFF5 "Mono bold 9"
203 | #define sFF6 "Mono bold 12"
204 | #define sFF7 "Mono bold 18"
205 | #define sFF8 "Mono bold 24"
206 |
207 | #define sFF9 "Mono oblique 9"
208 | #define sFF10 "Mono oblique 12"
209 | #define sFF11 "Mono oblique 18"
210 | #define sFF12 "Mono oblique 24"
211 |
212 | #define sFF13 "Mono bold oblique 9"
213 | #define sFF14 "Mono bold oblique 12"
214 | #define sFF15 "Mono bold oblique 18"
215 | #define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen
216 |
217 | #define sFF17 "Sans 9"
218 | #define sFF18 "Sans 12"
219 | #define sFF19 "Sans 18"
220 | #define sFF20 "Sans 24"
221 |
222 | #define sFF21 "Sans bold 9"
223 | #define sFF22 "Sans bold 12"
224 | #define sFF23 "Sans bold 18"
225 | #define sFF24 "Sans bold 24"
226 |
227 | #define sFF25 "Sans oblique 9"
228 | #define sFF26 "Sans oblique 12"
229 | #define sFF27 "Sans oblique 18"
230 | #define sFF28 "Sans oblique 24"
231 |
232 | #define sFF29 "Sans bold oblique 9"
233 | #define sFF30 "Sans bold oblique 12"
234 | #define sFF31 "Sans bold oblique 18"
235 | #define sFF32 "Sans bold oblique 24"
236 |
237 | #define sFF33 "Serif 9"
238 | #define sFF34 "Serif 12"
239 | #define sFF35 "Serif 18"
240 | #define sFF36 "Serif 24"
241 |
242 | #define sFF37 "Serif italic 9"
243 | #define sFF38 "Serif italic 12"
244 | #define sFF39 "Serif italic 18"
245 | #define sFF40 "Serif italic 24"
246 |
247 | #define sFF41 "Serif bold 9"
248 | #define sFF42 "Serif bold 12"
249 | #define sFF43 "Serif bold 18"
250 | #define sFF44 "Serif bold 24"
251 |
252 | #define sFF45 "Serif bold italic 9"
253 | #define sFF46 "Serif bold italic 12"
254 | #define sFF47 "Serif bold italic 18"
255 | #define sFF48 "Serif bold italic 24"
256 |
257 | #else // LOAD_GFXFF not defined so setup defaults to prevent error messages
258 |
259 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
260 | // Free fonts are not loaded in User_Setup.h so we must define all as font 1
261 | // to prevent compile error messages
262 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
263 |
264 | #define GFXFF 1
265 | #define GLCD 1
266 | #define FONT2 2
267 | #define FONT4 4
268 | #define FONT6 6
269 | #define FONT7 7
270 | #define FONT8 8
271 |
272 | #define FF0 1
273 | #define FF1 1
274 | #define FF2 1
275 | #define FF3 1
276 | #define FF4 1
277 | #define FF5 1
278 | #define FF6 1
279 | #define FF7 1
280 | #define FF8 1
281 | #define FF9 1
282 | #define FF10 1
283 | #define FF11 1
284 | #define FF12 1
285 | #define FF13 1
286 | #define FF14 1
287 | #define FF15 1
288 | #define FF16 1
289 | #define FF17 1
290 | #define FF18 1
291 | #define FF19 1
292 | #define FF20 1
293 | #define FF21 1
294 | #define FF22 1
295 | #define FF23 1
296 | #define FF24 1
297 | #define FF25 1
298 | #define FF26 1
299 | #define FF27 1
300 | #define FF28 1
301 | #define FF29 1
302 | #define FF30 1
303 | #define FF31 1
304 | #define FF32 1
305 | #define FF33 1
306 | #define FF34 1
307 | #define FF35 1
308 | #define FF36 1
309 | #define FF37 1
310 | #define FF38 1
311 | #define FF39 1
312 | #define FF40 1
313 | #define FF41 1
314 | #define FF42 1
315 | #define FF43 1
316 | #define FF44 1
317 | #define FF45 1
318 | #define FF46 1
319 | #define FF47 1
320 | #define FF48 1
321 |
322 | #define FM9 1
323 | #define FM12 1
324 | #define FM18 1
325 | #define FM24 1
326 |
327 | #define FMB9 1
328 | #define FMB12 1
329 | #define FMB18 1
330 | #define FMB24 1
331 |
332 | #define FMO9 1
333 | #define FMO12 1
334 | #define FMO18 1
335 | #define FMO24 1
336 |
337 | #define FMBO9 1
338 | #define FMBO12 1
339 | #define FMBO18 1
340 | #define FMBO24 1
341 |
342 | #define FSS9 1
343 | #define FSS12 1
344 | #define FSS18 1
345 | #define FSS24 1
346 |
347 | #define FSSB9 1
348 | #define FSSB12 1
349 | #define FSSB18 1
350 | #define FSSB24 1
351 |
352 | #define FSSO9 1
353 | #define FSSO12 1
354 | #define FSSO18 1
355 | #define FSSO24 1
356 |
357 | #define FSSBO9 1
358 | #define FSSBO12 1
359 | #define FSSBO18 1
360 | #define FSSBO24 1
361 |
362 | #define FS9 1
363 | #define FS12 1
364 | #define FS18 1
365 | #define FS24 1
366 |
367 | #define FSI9 1
368 | #define FSI12 1
369 | #define FSI19 1
370 | #define FSI24 1
371 |
372 | #define FSB9 1
373 | #define FSB12 1
374 | #define FSB18 1
375 | #define FSB24 1
376 |
377 | #define FSBI9 1
378 | #define FSBI12 1
379 | #define FSBI18 1
380 | #define FSBI24 1
381 |
382 | #endif // LOAD_GFXFF
383 | #endif // FREE_FONTS_H
384 |
--------------------------------------------------------------------------------
/main/Kconfig.projbuild:
--------------------------------------------------------------------------------
1 | menu "Project Configuration"
2 | menu "Debug"
3 | config TOUCH_DBG
4 | bool
5 | prompt "Display touch points in LCD"
6 | default "n"
7 | help
8 | Draws a colored dot on screen when touch input is detected.
9 |
10 | config ENABLE_TIMER
11 | bool
12 | prompt "Enable tic-toc timer"
13 | default "n"
14 | help
15 | allows time to be measured with TIC and TOC macros
16 |
17 | endmenu
18 | endmenu
19 |
--------------------------------------------------------------------------------
/main/Menu/black_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file black_Scr.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 11-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "black_Scr.h"
26 |
27 | /*####################################################
28 | Black screen
29 | ####################################################*/
30 | Black_Scr::Black_Scr(lcdUI* UI, tftLCD& tft):
31 | Screen(UI)
32 | {
33 | tft.fillScreen(TFT_BLACK);
34 | }
35 |
36 | void Black_Scr::update(uint32_t deltaTime, TchScr_Drv& ts)
37 | {
38 |
39 | }
40 |
41 | void Black_Scr::render(tftLCD& tft)
42 | {
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/main/Menu/black_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file black_Scr.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 11-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef BLACK_W_H
26 | #define BLACK_W_H
27 |
28 | #include "../lcdUI.h"
29 |
30 | class Black_Scr final: public Screen
31 | {
32 | public:
33 | Black_Scr(lcdUI* UI, tftLCD& tft);
34 |
35 | void update(uint32_t deltaTime, TchScr_Drv& ts) override;
36 | void render(tftLCD& tft) override;
37 |
38 | private:
39 | };
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/main/Menu/config_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file config_Scr.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 11-04-2022
5 | * -----
6 | * Last Modified: 11-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "config_Scr.h"
26 |
27 | Config_Scr::Config_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts):
28 | Screen(UI)
29 | {
30 | tft.fillScreen(TFT_BLACK);
31 |
32 | // Bottom menu
33 | tft.drawBmpSPIFFS("/spiffs/return_48.bmp", 53, 272);
34 | tft.drawRoundRect(0, 256, 155, 64, 4, TFT_ORANGE);
35 |
36 | // Settings buttons
37 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
38 | tft.setTextFont(2);
39 | tft.setTextSize(1);
40 | tft.setTextDatum(CL_DATUM);
41 | tft.setTextPadding(202);
42 | tft.drawString("Display Settings", 10, 75);
43 | tft.drawRoundRect(0, 51, 239, 48, 4, TFT_OLIVE);
44 |
45 | Button tmpBut;
46 | tmpBut.id = 0;
47 | tmpBut.xmin = 0;
48 | tmpBut.xmax = 160;
49 | tmpBut.ymin = 256;
50 | tmpBut.ymax = 320;
51 | tmpBut.enReleaseEv = true;
52 |
53 | ts.setButton(&tmpBut); // Back to Info screen
54 |
55 | for (int i = 0; i < 2; i++) // Menu buttons
56 | {
57 | for (int j = 0; j < 4; j++)
58 | {
59 | tmpBut.id = j + i*4 + 1;
60 | tmpBut.xmin = i * 240;
61 | tmpBut.xmax = i * 240 + 240;
62 | tmpBut.ymin = 50 * j + 50;
63 | tmpBut.ymax = 50 * j + 100;
64 | ts.setButton(&tmpBut);
65 | }
66 | }
67 | }
68 |
69 | void Config_Scr::update(uint32_t deltaTime, TchScr_Drv& ts)
70 | {
71 |
72 | }
73 |
74 | void Config_Scr::render(tftLCD& tft)
75 | {
76 |
77 | }
78 |
79 | void Config_Scr::handleTouch(const TchEvent& event)
80 | {
81 | if (event.trigger != TrgSrc::RELEASE) return;
82 | if (event.id == 0)
83 | {
84 | _UI->setScreen(lcdUI::Info);
85 | }
86 | else if(event.id == 1)
87 | {
88 | _UI->setScreen(lcdUI::DisplayConf);
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/main/Menu/config_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file config_Scr.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 11-04-2022
5 | * -----
6 | * Last Modified: 11-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef CONFIG_SCR_H
26 | #define CONFIG_SCR_H
27 |
28 | #include "../lcdUI.h"
29 |
30 | class Config_Scr final: public Screen
31 | {
32 | public:
33 | Config_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts);
34 |
35 | void update(uint32_t deltaTime, TchScr_Drv& ts) override;
36 | void render(tftLCD& tft) override;
37 | void handleTouch(const TchEvent& event) override;
38 | };
39 |
40 | #endif // CONFIG_SCR_H
41 |
--------------------------------------------------------------------------------
/main/Menu/displayConf_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file displayConf_Scr.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 11-04-2022
5 | * -----
6 | * Last Modified: 15-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "displayConf_Scr.h"
26 |
27 | DisplayConf_Scr::DisplayConf_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts):
28 | Screen(UI)
29 | {
30 | tft.fillScreen(TFT_BLACK);
31 |
32 | // Bottom menu
33 | tft.drawBmpSPIFFS("/spiffs/return_48.bmp", 53, 272);
34 | tft.drawRoundRect(0, 256, 155, 64, 4, TFT_ORANGE);
35 |
36 | // Slider
37 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
38 | tft.setTextFont(2);
39 | tft.setTextSize(1);
40 | tft.setTextDatum(CL_DATUM);
41 | tft.setTextPadding(0);
42 | tft.drawString("Display Brightness:", 10, 75);
43 | tft.drawRoundRect(0, 51, 239, 48, 4, TFT_OLIVE);
44 | sliderX = _UI->getBrightness()*190/255;
45 | tft.drawRoundRect(241, 51, 239, 48, 4, TFT_OLIVE);
46 |
47 | Button tmpBut;
48 | tmpBut.id = 0;
49 | tmpBut.xmin = 0;
50 | tmpBut.xmax = 160;
51 | tmpBut.ymin = 256;
52 | tmpBut.ymax = 320;
53 | tmpBut.enReleaseEv = true;
54 |
55 | ts.setButton(&tmpBut); // Back to Config screen
56 |
57 | tmpBut.id = 1;
58 | tmpBut.enHoldEv = true;
59 | tmpBut.enHoldTickEv = true;
60 | tmpBut.enReleaseEv = false;
61 | tmpBut.holdTime = 0;
62 | tmpBut.xmin = 261;
63 | tmpBut.xmax = 461;
64 | tmpBut.ymin = 50;
65 | tmpBut.ymax = 100;
66 |
67 | ts.setButton(&tmpBut); // Brightness slider
68 | }
69 |
70 | void DisplayConf_Scr::update(uint32_t deltaTime, TchScr_Drv& ts)
71 | {
72 | _UI->setBrightness(sliderX*255/190);
73 | }
74 |
75 | void DisplayConf_Scr::render(tftLCD& tft)
76 | {
77 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
78 | tft.setTextFont(2);
79 | tft.setTextSize(1);
80 | tft.setTextDatum(CR_DATUM);
81 | tft.setTextPadding(40);
82 | tft.drawString(String(sliderX*100/190) + String(" %"), 229, 75);
83 |
84 | tft.img.setColorDepth(16);
85 | tft.img.createSprite(200, 40);
86 | //tft.img.fillSprite(TFT_BLACK);
87 | tft.img.fillRect(5, 20, 190, 2, TFT_WHITE);
88 | tft.img.fillRoundRect(sliderX, 0, 10, 40, 4, TFT_WHITE);
89 | tft.img.pushSprite(261, 55);
90 | tft.img.deleteSprite();
91 | }
92 |
93 | void DisplayConf_Scr::handleTouch(const TchEvent& event)
94 | {
95 | if (event.trigger == TrgSrc::RELEASE)
96 | {
97 | if (event.id == 0)
98 | {
99 | _UI->setScreen(lcdUI::Config);
100 | }
101 | }
102 | else if (event.trigger == TrgSrc::HOLD_TICK)
103 | {
104 | sliderX = event.pos.x - 266;
105 | if (sliderX > 190)
106 | {
107 | sliderX = 190;
108 | }
109 | else if (sliderX < 0)
110 | {
111 | sliderX = 0;
112 | }
113 | _UI->requestUpdate();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/main/Menu/displayConf_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file displayConf_Scr.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 11-04-2022
5 | * -----
6 | * Last Modified: 14-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef DISPLAY_CONF_SCR_H
26 | #define DISPLAY_CONF_SCR_H
27 |
28 | #include "../lcdUI.h"
29 |
30 | class DisplayConf_Scr final: public Screen
31 | {
32 | public:
33 | DisplayConf_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts);
34 |
35 | void update(uint32_t deltaTime, TchScr_Drv& ts) override;
36 | void render(tftLCD& tft) override;
37 | void handleTouch(const TchEvent& event) override;
38 |
39 | private:
40 | int16_t sliderX = 100;
41 | };
42 |
43 | #endif // DISPLAY_CONF_SCR_H
44 |
--------------------------------------------------------------------------------
/main/Menu/fileBrowser_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file fileBrowser_Scr.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 12-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "fileBrowser_Scr.h"
26 | #include "dbg_log.h"
27 |
28 | FileBrowser_Scr::FileBrowser_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts):
29 | Screen(UI)
30 | {
31 | tft.fillScreen(TFT_BLACK);
32 |
33 | // SD Home
34 | tft.drawRoundRect(0, 0, 50, 50, 4, TFT_ORANGE);
35 | tft.drawBmpSPIFFS("/spiffs/home_24.bmp", 13, 13);
36 |
37 | tft.drawBmpSPIFFS("/spiffs/return_48.bmp", 53, 272);
38 | tft.drawRoundRect(0, 256, 155, 64, 4, TFT_ORANGE);
39 | tft.drawRoundRect(288, 256, 66, 64, 4, TFT_CYAN);
40 |
41 | // Setup buttons
42 | Button tmpBut;
43 | tmpBut.id = 0;
44 | tmpBut.xmin = 0;
45 | tmpBut.xmax = 160;
46 | tmpBut.ymin = 256;
47 | tmpBut.ymax = 320;
48 | tmpBut.enReleaseEv = true;
49 |
50 | ts.setButton(&tmpBut); // Back to Info screen
51 |
52 | tmpBut.id = 1;
53 | tmpBut.xmin = 163;
54 | tmpBut.xmax = 280;
55 | tmpBut.ymin = 256;
56 | tmpBut.ymax = 320;
57 |
58 | ts.setButton(&tmpBut); // Prev page
59 |
60 | tmpBut.id = 2;
61 | tmpBut.xmin = 362;
62 | tmpBut.xmax = 480;
63 | tmpBut.ymin = 256;
64 | tmpBut.ymax = 320;
65 |
66 | ts.setButton(&tmpBut); // Next page
67 |
68 | for (int i = 0; i < 2; i++) // File buttons
69 | {
70 | for (int j = 0; j < 4; j++)
71 | {
72 | tmpBut.id = j + i*4 + 3;
73 | tmpBut.xmin = i * 240;
74 | tmpBut.xmax = i * 240 + 240;
75 | tmpBut.ymin = 50 * j + 50;
76 | tmpBut.ymax = 50 * j + 100;
77 | ts.setButton(&tmpBut);
78 | }
79 | }
80 |
81 | tmpBut.id = 11;
82 | tmpBut.xmin = 0;
83 | tmpBut.xmax = 50;
84 | tmpBut.ymin = 0;
85 | tmpBut.ymax = 50;
86 | tmpBut.enHoldEv = true;
87 | tmpBut.holdTime = 100;
88 |
89 | ts.setButton(&tmpBut); // Return to SD root
90 | tmpBut.enHoldEv = false;
91 |
92 | for (int i = 0; i < 5; i++) // Folder navigation
93 | {
94 | tmpBut.id = i + 12;
95 | tmpBut.xmin = 50 + 86*i;
96 | tmpBut.xmax = 136 + 86*i;
97 | tmpBut.ymin = 0;
98 | tmpBut.ymax = 50;
99 | ts.setButton(&tmpBut);
100 | }
101 | }
102 |
103 | void FileBrowser_Scr::update(const uint32_t deltaTime, TchScr_Drv& ts)
104 | {
105 | if (_UI->isSDinit())
106 | {
107 | loadPage();
108 | }
109 | else
110 | {
111 | _UI->setScreen(lcdUI::Info);
112 | }
113 | }
114 |
115 | void FileBrowser_Scr::render(tftLCD& tft)
116 | {
117 | renderPage(tft);
118 | }
119 |
120 | bool FileBrowser_Scr::isPageLoaded()
121 | {
122 | return pageLoaded == filePage;
123 | }
124 |
125 | void FileBrowser_Scr::setPageLoaded()
126 | {
127 | pageLoaded = filePage;
128 | pageRendered = false;
129 | }
130 |
131 | void FileBrowser_Scr::updatePath(const std::string &newPath, const bool relativePath)
132 | {
133 | if (relativePath)
134 | {
135 | size_t dot = newPath.find("/..");
136 | if (dot == -1)
137 | {
138 | path += "/" + newPath;
139 | }
140 | else
141 | {
142 | dot += 3;
143 | size_t slash = path.rfind('/');
144 | if (slash == -1 || (newPath[dot] < '0' && newPath[dot] > '9'))
145 | {
146 | DBG_LOGE("Invalid path!");
147 | return;
148 | }
149 |
150 | for (uint8_t i = newPath[dot]-'0'; i > 0; i--)
151 | {
152 | if (path.compare("/sdcard") == 0) break;
153 | path.erase(slash);
154 | slash = path.rfind('/');
155 | if (slash == -1) return;
156 | }
157 | }
158 | } else
159 | {
160 | path = newPath;
161 | }
162 | DBG_LOGD("New path: %s", path.c_str());
163 | numFilePages = 0; // Mark as new folder for reading
164 | filePage++; // Trigger page load
165 | }
166 |
167 | void FileBrowser_Scr::handleTouch(const TchEvent& event)
168 | {
169 | if (event.trigger == TrgSrc::HOLD_STRT && event.id == 11)
170 | {
171 | if (removeDir("/sdcard/.cache") == ESP_OK)
172 | DBG_LOGI("Cache deleted!");
173 | else
174 | DBG_LOGI("Failed to delete cache");
175 | return;
176 | }
177 |
178 | if (event.trigger != TrgSrc::RELEASE) return;
179 |
180 | bool update = true;
181 |
182 | if (event.id == 0) // Back to Main menu
183 | {
184 | _UI->setScreen(lcdUI::Info);
185 | }
186 | else if (event.id == 1 && filePage > 0) // Prev page
187 | {
188 | filePage--;
189 | }
190 | else if (event.id == 2 && filePage < numFilePages-1) // Next page
191 | {
192 | filePage++;
193 | }
194 | else if (event.id > 2 && event.id <= 10) // Open file
195 | {
196 | uint8_t idx = event.id - 3;
197 | DBG_LOGV("IDX: %d", idx);
198 | if ((isDir & (1 << idx)) > 0) updatePath(dirList[idx], true);
199 | else if (isGcode(dirList[idx]))
200 | sendFile(dirList[idx]);
201 | else
202 | update = false;
203 | }
204 | else if (event.id == 11) // Return to root
205 | {
206 | updatePath("/sdcard", false);
207 | }
208 | else if (event.id > 11 && event.id <= 16) // Navigation bar
209 | {
210 | int8_t k = fileDepth > 5 ? 5 : fileDepth;
211 | k -= event.id - 12;
212 | switch (k)
213 | {
214 | case 1:
215 | filePage = 0;
216 | break;
217 |
218 | case 2:
219 | updatePath("/..1", true);
220 | break;
221 |
222 | case 3:
223 | updatePath("/..2", true);
224 | break;
225 |
226 | case 4:
227 | updatePath("/..3", true);
228 | break;
229 |
230 | case 5:
231 | updatePath("/..4", true);
232 | break;
233 |
234 | default:
235 | update = false;
236 | break;
237 | }
238 | }
239 | else
240 | {
241 | update = false;
242 | }
243 |
244 | if (update)
245 | _UI->requestUpdate();
246 | }
247 |
248 | esp_err_t FileBrowser_Scr::removeDir(const char* path)
249 | {
250 | static char fullName[128];
251 | DIR *dp = opendir (path);
252 |
253 | if (dp != NULL)
254 | {
255 | struct dirent *ep;
256 | while ((ep = readdir (dp)))
257 | {
258 | if (ep->d_type == DT_DIR)
259 | {
260 | if (removeDir(ep->d_name) != ESP_OK)
261 | {
262 | closedir (dp);
263 | return ESP_FAIL;
264 | }
265 | }
266 | else
267 | {
268 | strcpy(fullName, path);
269 | strcat(fullName, "/");
270 | strcat(fullName, ep->d_name);
271 | DBG_LOGD("%s", fullName);
272 | if (remove(fullName) != 0)
273 | {
274 | closedir (dp);
275 | return ESP_FAIL;
276 | }
277 | }
278 | }
279 |
280 | closedir (dp);
281 | remove(path);
282 | }
283 | else
284 | {
285 | DBG_LOGE("Couldn't open the directory");
286 | return ESP_FAIL;
287 | }
288 | return ESP_OK;
289 | }
290 |
291 | void FileBrowser_Scr::renderPage(tftLCD& tft)
292 | {
293 | if (pageRendered) return;
294 |
295 | // Draw controls
296 | // Page +
297 | if (pageLoaded == 0)
298 | {
299 | tft.fillRect(163, 256, 117, 64, TFT_BLACK);
300 | }
301 | else
302 | {
303 | tft.drawBmpSPIFFS("/spiffs/arrowL_48.bmp", 197, 268);
304 | tft.drawRoundRect(163, 256, 117, 64, 4, TFT_ORANGE);
305 | }
306 |
307 | // Page -
308 | if (pageLoaded == numFilePages-1)
309 | {
310 | tft.fillRect(362, 256, 118, 64, TFT_BLACK);
311 | }
312 | else
313 | {
314 | tft.drawBmpSPIFFS("/spiffs/arrowR_48.bmp", 397, 268);
315 | tft.drawRoundRect(362, 256, 118, 64, 4, TFT_ORANGE);
316 | }
317 |
318 | // Folder path names
319 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
320 | tft.setTextFont(2);
321 | tft.setTextPadding(0);
322 | tft.setTextDatum(CC_DATUM);
323 |
324 | uint8_t idx = path.length()-1;
325 | for (uint8_t i = 5; i > 0; i--) // For each of the last 5 folders
326 | {
327 | if (i <= fileDepth)
328 | {
329 | tft.fillRect(86*i - 35, 1, 84, 48, TFT_BLACK);
330 | tft.drawRoundRect(86*i - 36, 0, 86, 50, 4, TFT_ORANGE);
331 | uint8_t len = 0;
332 | for (; idx > 0; idx--, len++)
333 | {
334 | if (path[idx] == '/') break;
335 | }
336 |
337 | std::string folderName = path.substr(idx-- +1, len);
338 | tft.drawStringWr(folderName.c_str(), 7 + 86*i, 25, 80, 48);
339 | }
340 | else
341 | {
342 | tft.fillRect(86*i - 36, 0, 86, 50, TFT_BLACK);
343 | }
344 | }
345 |
346 | tft.setTextPadding(48);
347 | tft.drawString("Page", 321, 280);
348 | tft.drawString(String(pageLoaded+1) + " of " + String(numFilePages), 321, 296);
349 |
350 | // Draw file table
351 | tft.setTextDatum(CL_DATUM);
352 | tft.setTextPadding(202); // Set pading to clear old text
353 | uint8_t k = 0;
354 | for (uint8_t i = 0; i < 2; i++)
355 | {
356 | for (uint8_t j = 0; j < 4; j++, k++)
357 | {
358 | if (dirList[k].length() == 0)
359 | {
360 | tft.fillRect(241*i, 51 + 50*j, 239, 48, TFT_BLACK); // Clear unused slots
361 | continue;
362 | }
363 | tft.fillRect(10 + 240*i, 52 + 50*j, 200, 46, TFT_BLACK);
364 |
365 | tft.drawStringWr(dirList[k].c_str(), 10 + 240*i, 75 + 50*j, 200, 48); // Write file name
366 |
367 | if ((isDir & 1< 0)
368 | tft.drawBmpSPIFFS("/spiffs/folder_24.bmp", 212 + 240*i, 63 + 50*j); // Draw folder icon
369 | else if (isGcode(dirList[k]))
370 | tft.drawBmpSPIFFS("/spiffs/gcode_24.bmp", 212 + 240*i, 63 + 50*j); // Draw gcode icon
371 | else
372 | tft.drawBmpSPIFFS("/spiffs/file_24.bmp", 212 + 240*i, 63 + 50*j); // Draw file icon
373 |
374 | tft.drawRoundRect(241*i, 51 + 50*j, 239, 48, 4, TFT_OLIVE); // Draw grid
375 | }
376 | }
377 | pageRendered = true;
378 | }
379 |
380 | void FileBrowser_Scr::loadPage()
381 | {
382 | if (isPageLoaded()) return;
383 | struct dirent *entry;
384 | DIR * dir = opendir(path.c_str());
385 | if (!dir)
386 | {
387 | DBG_LOGE("Error opening folder %s", path.c_str());
388 | return;
389 | }
390 |
391 | if (numFilePages == 0) // First directory read
392 | {
393 | uint16_t hidden = 0;
394 | while ((entry = readdir(dir)) && numFilePages < 255)
395 | {
396 | if (isHidden(entry->d_name))
397 | {
398 | hidden++;
399 | continue;
400 | }
401 | numFilePages++; // Count number of files
402 |
403 | if (numFilePages % 8 == 0) hiddenFiles[numFilePages / 8] = hidden;
404 | }
405 |
406 | if (numFilePages != 0)
407 | numFilePages = (numFilePages - 1) / 8; // Translate to screen pages
408 | numFilePages++;
409 | DBG_LOGD("File Pages: %d", numFilePages);
410 |
411 | fileDepth = 0;
412 | for (uint8_t i = 1; i < path.length(); i++)
413 | {
414 | if (path[i] == '/') fileDepth++;
415 | }
416 |
417 | rewinddir(dir);
418 | filePage = 0;
419 | }
420 |
421 | isDir = 0;
422 | seekdir(dir, filePage*8 + hiddenFiles[filePage]);
423 | uint8_t i = 0;
424 | while (i < 8)
425 | {
426 | entry = readdir(dir);
427 | if (!entry) break; // No more files
428 |
429 | if (isHidden(entry->d_name)) continue;
430 |
431 | dirList[i] = entry->d_name; // Save file name
432 |
433 | if (entry->d_type == DT_DIR) isDir |= 1<setFile(path + "/" + file) == ESP_OK)
473 | _UI->setScreen(lcdUI::GcodePreview);
474 | }
475 |
--------------------------------------------------------------------------------
/main/Menu/fileBrowser_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file fileBrowser_Scr.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 06-03-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef FILE_BROWSER_SCR_H
26 | #define FILE_BROWSER_SCR_H
27 |
28 | #include "stdio.h"
29 | #include "../lcdUI.h"
30 | #include "dirent.h"
31 |
32 | class FileBrowser_Scr final: public Screen
33 | {
34 | public:
35 | FileBrowser_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts);
36 |
37 | void update(const uint32_t deltaTime, TchScr_Drv& ts) override;
38 |
39 | void render(tftLCD& tft) override;
40 |
41 | void handleTouch(const TchEvent& event) override;
42 |
43 | private:
44 | esp_err_t removeDir(const char* path);
45 | void loadPage();
46 | void renderPage(tftLCD& tft);
47 | bool isPageLoaded();
48 | void setPageLoaded();
49 | void updatePath(const std::string &newPath, const bool relativePath);
50 | bool isHidden(const char * name);
51 | bool isGcode(const std::string &file);
52 | void sendFile(const std::string &file);
53 |
54 | std::string path = "/sdcard";
55 | std::string dirList[8];
56 | uint8_t fileDepth = 0;
57 | uint8_t isDir = 0;
58 | uint8_t numFilePages = 0;
59 | uint8_t filePage = 0;
60 | uint8_t pageLoaded = 1;
61 | bool pageRendered = false;
62 | uint8_t hiddenFiles[32] = {0};
63 | };
64 |
65 | #endif
--------------------------------------------------------------------------------
/main/Menu/info_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file info_w.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 12-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "info_Scr.h"
26 |
27 | Info_Scr::Info_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts):
28 | Screen(UI), cellAdv(416.0f/(items)), cellW(cellAdv-8)
29 | {
30 | tft.fillScreen(TFT_BLACK);
31 | tft.setTextFont(2);
32 | tft.setTextSize(1);
33 | tft.setTextPadding(0);
34 | tft.setTextDatum(CC_DATUM);
35 |
36 | tft.setTextColor(TFT_BLACK);
37 | uint8_t e = 1;
38 | for (uint8_t i = 0; i < items; i++)
39 | {
40 | tft.fillRoundRect(72 + cellAdv*i, 58, cellW, 25, 4, TFT_DARKCYAN);
41 | tft.fillRoundRect(72 + cellAdv*i, 91, cellW, 25, 4, TFT_DARKCYAN);
42 | if (i < heatbed)
43 | {
44 | tft.drawBmpSPIFFS("/spiffs/heatbed_32.bmp", 72+(cellW-32)/2+cellAdv*i, 13);
45 | }
46 | else if (i < tools+heatbed)
47 | {
48 | tft.drawBmpSPIFFS("/spiffs/extruder_32.bmp", 72+(cellW-32)/2+cellAdv*i, 13);
49 | if (tools > 1) tft.drawString(String(e++), 72+cellW/2+cellAdv*i, 22);
50 | }
51 | else
52 | {
53 | tft.drawBmpSPIFFS("/spiffs/fan_32.bmp", 72+(cellW-32)/2+cellAdv*i, 13);
54 | }
55 | }
56 | tft.fillRoundRect(0, 58, 64, 25, 4, TFT_NAVY);
57 | tft.setTextColor(TFT_WHITE);
58 | tft.drawString("Current", 32, 70);
59 | tft.fillRoundRect(0, 91, 64, 25, 4, TFT_NAVY);
60 | tft.drawString("Target", 32, 103);
61 | tft.drawRoundRect(0, 0, 480, 117, 4, TFT_GREEN);
62 |
63 | tft.drawRoundRect(0, 125, 480, 25, 4, TFT_GREEN);
64 |
65 | tft.drawString("Time:", 40, 195);
66 | tft.drawString("--D --:--:--", 40, 211);
67 | tft.drawString("Remaining:", 440, 195);
68 | tft.drawString("--D --:--:--", 440, 211);
69 | tft.drawRoundRect(0, 158, 480, 90, 4, TFT_GREEN);
70 |
71 | tft.drawBmpSPIFFS("/spiffs/SDcard_64.bmp", 45, 264);
72 | tft.drawRoundRect(0, 256, 155, 64, 4, TFT_ORANGE);
73 | tft.drawBmpSPIFFS("/spiffs/move_48.bmp", 216, 264);
74 | tft.drawRoundRect(163, 256, 154, 64, 4, TFT_ORANGE);
75 | tft.drawBmpSPIFFS("/spiffs/settings_48.bmp", 378, 264);
76 | tft.drawRoundRect(325, 256, 155, 64, 4, TFT_ORANGE);
77 |
78 | // Setup buttons
79 | Button tmpBut;
80 | tmpBut.id = 0;
81 | tmpBut.xmin = 0;
82 | tmpBut.xmax = 160;
83 | tmpBut.ymin = 256;
84 | tmpBut.ymax = 320;
85 | tmpBut.enReleaseEv = true;
86 |
87 | ts.setButton(&tmpBut); // SD card button
88 |
89 | tmpBut.id = 1;
90 | tmpBut.xmin = 160;
91 | tmpBut.xmax = 320;
92 | tmpBut.enHoldEv = true;
93 | tmpBut.holdTime = 100;
94 |
95 | ts.setButton(&tmpBut); // Move button
96 |
97 | tmpBut.id = 2;
98 | tmpBut.xmin = 320;
99 | tmpBut.xmax = 480;
100 | tmpBut.enHoldEv = false;
101 |
102 | ts.setButton(&tmpBut); // Config button
103 | }
104 |
105 | void Info_Scr::update(uint32_t deltaTime, TchScr_Drv& ts)
106 | {
107 |
108 | }
109 |
110 | void Info_Scr::render(tftLCD& tft)
111 | {
112 | _UI->requestUpdate();
113 | if (millis() < nextP) return;
114 | tft.setTextFont(2);
115 | tft.setTextSize(1);
116 | tft.setTextDatum(CC_DATUM);
117 | tft.setTextPadding(40);
118 |
119 | // Draw temperatures
120 | tft.setTextColor(TFT_WHITE, TFT_DARKCYAN);
121 | for (uint8_t i = 0; i < items; i++)
122 | {
123 | if (i < heatbed)
124 | {
125 | tft.drawString(String(random(50, 70)) + "`C", 72+cellW/2+cellAdv*i, 70);
126 | tft.drawString(String(random(50, 70)) + "`C", 72+cellW/2+cellAdv*i, 103);
127 | }
128 | else if (i < tools+heatbed)
129 | {
130 | tft.drawString(String(random(180, 250)) + "`C", 72+cellW/2+cellAdv*i, 70);
131 | tft.drawString(String(random(180, 250)) + "`C", 72+cellW/2+cellAdv*i, 103);
132 | }
133 | else
134 | {
135 | tft.drawString(String(random(0, 100)) + "%", 72+cellW/2+cellAdv*i, 70);
136 | tft.drawString(String(random(0, 100)) + "%", 72+cellW/2+cellAdv*i, 103);
137 | }
138 | }
139 |
140 | // Draw positions
141 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
142 | tft.setTextPadding(115);
143 | tft.drawString("X: " + String(random(-100, 500)), 60, 137);
144 | tft.drawString("Y: " + String(random(-100, 500)), 180, 137);
145 | tft.drawString("Z: " + String(random(-100, 500)), 300, 137);
146 | tft.drawString("Fr: " + String(random(70, 150)) + "%", 420, 137);
147 |
148 | nextP = millis() + 1000;
149 | }
150 |
151 | void Info_Scr::handleTouch(const TchEvent& event)
152 | {
153 | if (event.trigger != TrgSrc::RELEASE) return;
154 | if (event.id == 0)
155 | {
156 | if (_UI->isSDinit()) _UI->setScreen(lcdUI::FileBrowser);
157 | }
158 | else if (event.id == 1)
159 | {
160 | /* code */
161 | }
162 | else if (event.id == 2)
163 | {
164 | _UI->setScreen(lcdUI::Config);
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/main/Menu/info_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file info_w.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 11-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef INFO_W_H
26 | #define INFO_W_H
27 |
28 | #include "../lcdUI.h"
29 |
30 | class Info_Scr final: public Screen
31 | {
32 | public:
33 | Info_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts);
34 |
35 | void update(uint32_t deltaTime, TchScr_Drv& ts) override;
36 | void render(tftLCD& tft) override;
37 | void handleTouch(const TchEvent& event) override;
38 |
39 | private:
40 | const uint8_t heatbed = 1;//random(0,2);
41 | const uint8_t tools = 2;//random(1,6);
42 | const uint8_t fans = 2;//random(0, min(8-tools-heatbed, 4));
43 | const uint8_t items = heatbed + tools + fans;
44 | const float cellAdv;
45 | const uint16_t cellW;
46 | int nextP = 0;
47 | };
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/main/Menu/preview_Scr.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file gcodePreview_Scr.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 14-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "preview_Scr.h"
26 | #include "dbg_log.h"
27 |
28 | Preview_Scr::Preview_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts):
29 | Screen(UI)
30 | {
31 | renderEngine = GCodeRenderer::instance();
32 | if (renderEngine == nullptr)
33 | DBG_LOGE("Render engine uninitialized!");
34 |
35 | displayed.reset();
36 | tft.fillScreen(TFT_BLACK);
37 | tft.drawRoundRect(0, 0, 320, 320, 4, TFT_GREEN);
38 | tft.drawRoundRect(320, 0, 160, 50, 4, TFT_BLUE);
39 | tft.fillRoundRect(320, 220, 160, 50, 4, 0x0AE0);
40 | tft.drawRoundRect(320, 270, 160, 50, 4, TFT_ORANGE);
41 | tft.setTextFont(2);
42 | tft.setTextSize(1);
43 | tft.setTextDatum(CC_DATUM);
44 | tft.setTextPadding(0);
45 | tft.drawStringWr(_UI->getFile().substr(_UI->getFile().rfind('/')+1).c_str(), 400, 25, 150, 48); // Display filename
46 | tft.setTextColor(TFT_WHITE);
47 | tft.drawString("Start!", 400, 245);
48 | tft.drawString("Loading...", 160, 152);
49 | tft.drawBmpSPIFFS("/spiffs/return_48.bmp", 376, 277);
50 |
51 | // Setup buttons
52 | Button tmpBut;
53 | tmpBut.id = 0;
54 | tmpBut.xmin = 320;
55 | tmpBut.xmax = 480;
56 | tmpBut.ymin = 270;
57 | tmpBut.ymax = 320;
58 | tmpBut.enReleaseEv = true;
59 |
60 | ts.setButton(&tmpBut); // Back to Info screen
61 | }
62 |
63 | void Preview_Scr::update(const uint32_t deltaTime, TchScr_Drv& ts)
64 | {
65 | if (!started)
66 | {
67 | if (renderEngine->begin(_UI->getFile().c_str()) == ESP_OK)
68 | started = true;
69 | else
70 | _UI->requestUpdate();
71 | }
72 |
73 | if (!_UI->isSDinit())
74 | {
75 | _UI->setScreen(lcdUI::Info);
76 | }
77 | }
78 |
79 | void Preview_Scr::render(tftLCD& tft)
80 | {
81 | if (rendered) return;
82 | uint16_t* img = nullptr;
83 | // Main update loop is paused here
84 | esp_err_t ret = renderEngine->getRender(&img, pdMS_TO_TICKS(100));
85 | if (ret == ESP_OK)
86 | {
87 | bool oldBytes = tft.getSwapBytes();
88 | tft.setSwapBytes(true);
89 | tft.pushImage(0, 0, 320, 320, img);
90 | tft.setSwapBytes(oldBytes);
91 | tft.drawRoundRect(0, 0, 320, 320, 4, TFT_GREEN);
92 | rendered = true;
93 | drawInfo(tft);
94 | }
95 | else if (ret == ESP_FAIL)
96 | {
97 | tft.setTextDatum(CC_DATUM);
98 | tft.setTextFont(4);
99 | tft.setTextSize(1);
100 | tft.setTextPadding(150);
101 | tft.setTextColor(TFT_WHITE, TFT_RED);
102 | tft.drawString("Render error", 160, 160);
103 | rendered = true;
104 | }
105 | else
106 | {
107 | drawInfo(tft);
108 | _UI->requestUpdate();
109 | }
110 | }
111 |
112 | void Preview_Scr::handleTouch(const TchEvent& event)
113 | {
114 | if (event.trigger == TrgSrc::RELEASE && event.id == 0)
115 | {
116 | _UI->clearFile();
117 | _UI->setScreen(lcdUI::FileBrowser);
118 | }
119 | }
120 |
121 | void Preview_Scr::drawInfo(tftLCD& tft)
122 | {
123 | // Text settings
124 | tft.setTextDatum(TL_DATUM);
125 | tft.setTextFont(2);
126 | tft.setTextSize(1);
127 | tft.setTextPadding(0);
128 | tft.setTextColor(TFT_WHITE);
129 | String txt;
130 |
131 | const FileInfo* info = renderEngine->getInfo();
132 |
133 | if (info->filamentReady && !displayed[0])
134 | {
135 | tft.drawString("Filament cost: " , 328, 55);
136 | txt = String(info->filament, 3) + " m";
137 | tft.drawString(txt, 335, 71);
138 | displayed[0] = true;
139 | }
140 |
141 | if (info->timeReady && !displayed[1])
142 | {
143 | tft.drawString("Estimated time: " , 328, 95);
144 | int16_t seconds = info->printTime % 60;
145 | int16_t minutes = info->printTime/60 % 60;
146 | int16_t hours = info->printTime/3600 % 24;
147 | int16_t days = info->printTime/86400;
148 | txt = "";
149 | if (days > 0) txt += String(days) + "d ";
150 | if (hours > 0) txt += String(hours) + "h ";
151 | if (minutes > 0) txt += String(minutes) + "min ";
152 | txt += String(seconds) + "s";
153 | tft.drawString(txt, 335, 111);
154 | displayed[1] = true;
155 | }
156 |
157 | if (!rendered)
158 | {
159 | tft.setTextDatum(CC_DATUM);
160 | tft.setTextColor(TFT_WHITE, TFT_BLACK);
161 | tft.drawString(String(renderEngine->getProgress(), 0) + String("%"), 160, 168);
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/main/Menu/preview_Scr.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file gcodePreview_Scr.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 24-03-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef GCODEPREVIEW_SCR_H
26 | #define GCODEPREVIEW_SCR_H
27 |
28 | #include "../lcdUI.h"
29 | #include
30 | #include "../utility.h"
31 | #include "GCodeRenderer.h"
32 |
33 | class Preview_Scr final : public Screen
34 | {
35 | public:
36 | Preview_Scr(lcdUI* UI, tftLCD& tft, TchScr_Drv& ts);
37 |
38 | void update(const uint32_t deltaTime, TchScr_Drv& ts) override;
39 |
40 | void render(tftLCD& tft) override;
41 |
42 | void handleTouch(const TchEvent& event) override;
43 |
44 | private:
45 | void drawInfo(tftLCD& tft);
46 |
47 | // Status and info
48 | std::bitset<2> displayed;
49 | GCodeRenderer* renderEngine;
50 | bool started = false;
51 | bool rendered = false;
52 | };
53 |
54 | #endif
--------------------------------------------------------------------------------
/main/Screen.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "Screen.h"
3 | #include "dbg_log.h"
4 |
5 | /********************************************************************************
6 | Screen
7 | ********************************************************************************/
8 | Screen::Screen(lcdUI* UI)
9 | {
10 | DBG_LOGV("Create Screen\n");
11 | _UI = UI;
12 | }
13 |
14 | Screen::~Screen()
15 | {
16 | DBG_LOGV("Delete Screen\n");
17 | }
18 |
19 | void Screen::handleTouch(const TchEvent& event)
20 | {
21 | return;
22 | }
23 |
--------------------------------------------------------------------------------
/main/Screen.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef WIDGETS_H
4 | #define WIDGETS_H
5 |
6 | #include "tftLCD.h"
7 | #include "TchScr_Drv.h"
8 |
9 | class lcdUI;
10 |
11 | /**************************************************************************
12 | Base frame of the UI
13 | **************************************************************************/
14 | class Screen
15 | {
16 | protected:
17 | lcdUI *_UI;
18 |
19 | public:
20 | Screen(lcdUI* UI);
21 | virtual ~Screen();
22 |
23 | virtual void render(tftLCD& tft) = 0;
24 | virtual void update(const uint32_t deltaTime, TchScr_Drv& ts) = 0;
25 | virtual void handleTouch(const TchEvent& event);
26 | };
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/main/lcdUI.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file lcdUI.cpp
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 15-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include "lcdUI.h"
26 | #include "dbg_log.h"
27 | #include
28 | #include "driver/ledc.h"
29 | #include "Menu/info_Scr.h"
30 | #include "Menu/black_Scr.h"
31 | #include "Menu/fileBrowser_Scr.h"
32 | #include "Menu/preview_Scr.h"
33 | #include "Menu/config_Scr.h"
34 | #include "Menu/displayConf_Scr.h"
35 |
36 | bool lcdUI::init;
37 | lcdUI lcdUI::_instance;
38 | constexpr TchCalib lcdUI::calib;
39 |
40 | lcdUI::lcdUI() :
41 | touchScreen(I2C_NUM_0)
42 | {
43 | init = true;
44 | }
45 |
46 | lcdUI::~lcdUI()
47 | {
48 | vTaskDelete(cardTaskH);
49 | vTaskDelete(touchTaskH);
50 | vTaskDelete(updateTaskH);
51 | delete base;
52 | }
53 |
54 | lcdUI* lcdUI::instance()
55 | {
56 | return init ? &_instance : nullptr;
57 | }
58 |
59 | void IRAM_ATTR lcdUI::cardISRhandle(void* arg)
60 | {
61 | BaseType_t xHigherPriorityTaskWoken = false;
62 |
63 | lcdUI* UI = static_cast(arg);
64 | if (UI)
65 | vTaskNotifyGiveFromISR(UI->cardTaskH, &xHigherPriorityTaskWoken)
66 |
67 | portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
68 | }
69 |
70 | void lcdUI::cardDetectTask(void* arg)
71 | {
72 | DBG_LOGI("Starting card detect task");
73 |
74 | lcdUI* UI = static_cast(arg);
75 | gpio_config_t cardEmpty = {
76 | .pin_bit_mask = GPIO_SEL_27,
77 | .mode = GPIO_MODE_INPUT,
78 | .pull_up_en = GPIO_PULLUP_DISABLE,
79 | .pull_down_en = GPIO_PULLDOWN_DISABLE,
80 | .intr_type = GPIO_INTR_DISABLE
81 | };
82 |
83 | gpio_config_t cardInserted = {
84 | .pin_bit_mask = GPIO_SEL_27,
85 | .mode = GPIO_MODE_OUTPUT,
86 | .pull_up_en = GPIO_PULLUP_DISABLE,
87 | .pull_down_en = GPIO_PULLDOWN_DISABLE,
88 | .intr_type = GPIO_INTR_DISABLE
89 | };
90 | bool connected = false;
91 |
92 | while (UI)
93 | {
94 | bool prevRead = gpio_get_level(GPIO_NUM_34);
95 | if (prevRead && connected)
96 | {
97 | gpio_config(&cardEmpty);
98 |
99 | DBG_LOGD("Card disconnected");
100 | UI->endSD();
101 | connected = false;
102 | UI->requestUpdate();
103 | }
104 | else if (!prevRead && !connected)
105 | {
106 | gpio_config(&cardInserted);
107 | gpio_set_level(GPIO_NUM_27, HIGH);
108 |
109 | DBG_LOGD("Card connected");
110 | connected = UI->initSD();
111 | UI->requestUpdate();
112 | }
113 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
114 | }
115 |
116 | vTaskDelete(nullptr);
117 | }
118 |
119 | void lcdUI::touchTask(void* arg)
120 | {
121 | DBG_LOGI("Starting touch task");
122 | lcdUI* UI = static_cast(arg);
123 |
124 | esp_err_t err;
125 | err = UI->touchScreen.begin(I2C_MODE_MASTER, GPIO_NUM_32, GPIO_NUM_33, 0x22);
126 | if (err != ESP_OK)
127 | {
128 | DBG_LOGE("Error initializing touch driver");
129 | }
130 |
131 | err = UI->touchScreen.setCalibration(&UI->calib);
132 | if (err != ESP_OK)
133 | {
134 | DBG_LOGE("Error initializing touch driver");
135 | }
136 |
137 | err = UI->touchScreen.setThresholds(400, 10000);
138 | if (err != ESP_OK)
139 | {
140 | DBG_LOGE("Error initializing touch driver");
141 | }
142 |
143 | err = UI->touchScreen.setNotifications(false, true, true);
144 | if (err != ESP_OK)
145 | {
146 | DBG_LOGE("Error initializing touch driver");
147 | }
148 |
149 | while (UI) UI->processTouch();
150 |
151 | vTaskDelete(nullptr);
152 | }
153 |
154 | void lcdUI::updateTask(void* arg)
155 | {
156 | DBG_LOGI("Starting render task");
157 | lcdUI* UI = static_cast(arg);
158 | TickType_t xLastWakeTime = xTaskGetTickCount();
159 | const TickType_t xFrameTime = pdMS_TO_TICKS(100);
160 |
161 | while (UI)
162 | {
163 | esp_err_t ret = UI->updateDisplay();
164 | if (ret != ESP_OK)
165 | {
166 | DBG_LOGE("Update display failed");
167 | break;
168 | }
169 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
170 | vTaskDelayUntil(&xLastWakeTime, xFrameTime);
171 | xLastWakeTime = xTaskGetTickCount();
172 | }
173 | vTaskDelete(nullptr);
174 | }
175 |
176 | esp_err_t lcdUI::begin()
177 | {
178 | if (booted) return ESP_OK;
179 |
180 | tft.begin();
181 | tft.setRotation(1);
182 | tft.fillScreen(TFT_RED);
183 |
184 | // Crete semaphores
185 | touchMutex = xSemaphoreCreateMutex();
186 | if (touchMutex == nullptr)
187 | {
188 | DBG_LOGE("Failed to create touch mutex");
189 | return ESP_FAIL;
190 | }
191 |
192 | // Create tasks
193 | xTaskCreate(touchTask, "touch task", 4096, this, 1, &touchTaskH);
194 | if (touchTaskH == nullptr)
195 | {
196 | DBG_LOGE("Failed to create touch task");
197 | return ESP_FAIL;
198 | }
199 | vTaskDelay(pdMS_TO_TICKS(100));
200 |
201 | xTaskCreate(cardDetectTask, "cardTask", 4096, this, 0, &cardTaskH);
202 | if (cardTaskH == nullptr)
203 | {
204 | DBG_LOGE("Failed to create card detect task");
205 | return ESP_FAIL;
206 | }
207 | vTaskDelay(pdMS_TO_TICKS(100));
208 |
209 | xTaskCreate(updateTask, "Render task", 4096, this, 2, &updateTaskH);
210 | if (updateTaskH == nullptr)
211 | {
212 | DBG_LOGE("Failed to create render task");
213 | return ESP_FAIL;
214 | }
215 | vTaskDelay(pdMS_TO_TICKS(100)); // Allow some time for the task to start
216 |
217 | // Configure interrupts
218 | gpio_set_intr_type(GPIO_NUM_34, GPIO_INTR_ANYEDGE);
219 | gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
220 | gpio_isr_handler_add(GPIO_NUM_34, cardISRhandle, this);
221 |
222 | // Configure backlight PWM
223 | ledc_timer_config_t ledcTimer = {
224 | .speed_mode = LEDC_LOW_SPEED_MODE,
225 | .duty_resolution = LEDC_TIMER_8_BIT,
226 | .timer_num = LEDC_TIMER_0,
227 | .freq_hz = 10000,
228 | .clk_cfg = LEDC_AUTO_CLK
229 | };
230 |
231 | ESP_ERROR_CHECK(ledc_timer_config(&ledcTimer));
232 |
233 | ledc_channel_config_t ledcChannel = {
234 | .gpio_num = 26,
235 | .speed_mode = LEDC_LOW_SPEED_MODE,
236 | .channel = LEDC_CHANNEL_0,
237 | .intr_type = LEDC_INTR_DISABLE,
238 | .timer_sel = LEDC_TIMER_0,
239 | .duty = 255, // Set duty to 100%
240 | .hpoint = 0
241 | };
242 |
243 | ESP_ERROR_CHECK(ledc_channel_config(&ledcChannel));
244 |
245 | booted = true;
246 | return ESP_OK;
247 | }
248 |
249 | void lcdUI::setScreen(const menu screen)
250 | {
251 | newMenuID = screen;
252 | xTaskNotifyGive(updateTaskH);
253 | }
254 |
255 | bool lcdUI::initSD()
256 | {
257 | if (!SDinit && SD_MMC.begin("/sdcard"))
258 | {
259 | DBG_LOGD("SD Card initialized");
260 | SDinit = true;
261 | }
262 | return SDinit;
263 | }
264 |
265 | void lcdUI::endSD()
266 | {
267 | GCodeRenderer::instance()->stop();
268 | if (SDinit)
269 | SD_MMC.end();
270 |
271 | SDinit = false;
272 | }
273 |
274 | bool lcdUI::isSDinit() const
275 | {
276 | return SDinit;
277 | }
278 |
279 | esp_err_t lcdUI::setFile(const std::string& file)
280 | {
281 | if (access(file.c_str(), F_OK) == 0)
282 | {
283 | DBG_LOGD("Set file %s", file.c_str());
284 | selectedFile = file;
285 | }
286 | else
287 | return ESP_ERR_NOT_FOUND;
288 | return ESP_OK;
289 | }
290 |
291 | void lcdUI::processTouch()
292 | {
293 | TchEvent event;
294 | if (touchScreen.getEvent(&event, portMAX_DELAY) != ESP_OK) return;
295 |
296 | #ifdef CONFIG_TOUCH_DBG
297 | if (event.trigger == TrgSrc::PRESS) tft.fillCircle(event.pos.x, event.pos.y, 1, TFT_YELLOW);
298 | else if (event.trigger == TrgSrc::HOLD_STRT) tft.fillCircle(event.pos.x, event.pos.y, 1, TFT_MAGENTA);
299 | else if (event.trigger == TrgSrc::HOLD_TICK) tft.fillCircle(event.pos.x, event.pos.y, 1, TFT_RED);
300 | else if (event.trigger == TrgSrc::HOLD_END) tft.fillCircle(event.pos.x, event.pos.y, 1, TFT_ORANGE);
301 | else if (event.trigger == TrgSrc::RELEASE) tft.fillCircle(event.pos.x, event.pos.y, 1, TFT_CYAN);
302 | #endif
303 |
304 | if (!base) return;
305 | xSemaphoreTake(touchMutex, portMAX_DELAY);
306 | base->handleTouch(event);
307 | xSemaphoreGive(touchMutex);
308 | }
309 |
310 | esp_err_t lcdUI::updateDisplay()
311 | {
312 | int64_t deltaTime = esp_timer_get_time() - lastRender;
313 | lastRender = esp_timer_get_time();
314 |
315 | xSemaphoreTake(touchMutex, portMAX_DELAY);
316 | esp_err_t ret = updateObjects(); // Update to the latest screen
317 | xSemaphoreGive(touchMutex);
318 | if (ret != ESP_OK) return ret;
319 |
320 | base->update(deltaTime, touchScreen); // Update logic
321 |
322 | vTaskDelay(2); // Allow some time for other tasks
323 |
324 | base->render(tft); // Render frame
325 |
326 | updateTime = esp_timer_get_time() - lastRender;
327 |
328 | return ESP_OK;
329 | }
330 |
331 | esp_err_t lcdUI::updateObjects()
332 | {
333 | menu localMenu = newMenuID; // Local copy so that it remains unchanged
334 | if (menuID == localMenu) return ESP_OK;
335 | DBG_LOGD("Change screen to ID: %d", localMenu);
336 |
337 | tft.fillScreen(TFT_BLACK);
338 | Button clearBtn;
339 | clearBtn.id = 31;
340 | touchScreen.setButton(&clearBtn, portMAX_DELAY);
341 |
342 | delete base;
343 | base = nullptr;
344 |
345 | switch (localMenu)
346 | {
347 | case menu::black:
348 | base = new Black_Scr(this, tft);
349 | break;
350 | case menu::Info:
351 | base = new Info_Scr(this, tft, touchScreen);
352 | break;
353 | case menu::main:
354 | break;
355 | case menu::FileBrowser:
356 | base = new FileBrowser_Scr(this, tft, touchScreen);
357 | break;
358 | case menu::Config:
359 | base = new Config_Scr(this, tft, touchScreen);
360 | break;
361 | case menu::control:
362 | break;
363 | case menu::GcodePreview:
364 | base = new Preview_Scr(this, tft, touchScreen);
365 | break;
366 | case menu::DisplayConf:
367 | base = new DisplayConf_Scr(this, tft, touchScreen);
368 | break;
369 | default:
370 | base = nullptr;
371 | }
372 |
373 | if (base == nullptr)
374 | return ESP_ERR_NO_MEM;
375 |
376 | menuID = localMenu;
377 | return ESP_OK;
378 | }
379 |
380 | void lcdUI::requestUpdate()
381 | {
382 | xTaskNotifyGive(updateTaskH);
383 | }
384 |
385 | esp_err_t lcdUI::setBrightness(uint32_t duty)
386 | {
387 | if (duty > 255)
388 | duty = 255;
389 |
390 | esp_err_t ret = ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
391 | if (ret != ESP_OK)
392 | return ret;
393 |
394 | // Update duty
395 | ret = ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
396 | if (ret != ESP_OK)
397 | return ret;
398 |
399 | return ESP_OK;
400 | }
401 |
402 | uint32_t lcdUI::getBrightness()
403 | {
404 | return ledc_get_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
405 | }
406 |
--------------------------------------------------------------------------------
/main/lcdUI.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file lcdUI.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 15-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef LCD_UI_H
26 | #define LCD_UI_H
27 |
28 | #include "tftLCD.h"
29 | #include "Screen.h"
30 | #include "TchScr_Drv.h"
31 |
32 | class lcdUI
33 | {
34 | public:
35 | enum menu : uint8_t
36 | {
37 | none,
38 | black,
39 | Info,
40 | main,
41 | Config,
42 | FileBrowser,
43 | control,
44 | GcodePreview,
45 | DisplayConf
46 | };
47 |
48 | private:
49 | static lcdUI _instance;
50 | static bool init;
51 |
52 | static constexpr TchCalib calib = {
53 | .dx = 480,
54 | .rx_min = 900,
55 | .rx_max = 80,
56 | .dy = 320,
57 | .ry_min = 830,
58 | .ry_max = 100
59 | };
60 |
61 | tftLCD tft;
62 | Screen* base = nullptr;
63 | TchScr_Drv touchScreen;
64 |
65 | bool booted = false;
66 | bool SDinit = false;
67 |
68 | xTaskHandle updateTaskH = nullptr;
69 | xTaskHandle touchTaskH = nullptr;
70 | xTaskHandle cardTaskH = nullptr;
71 | SemaphoreHandle_t touchMutex;
72 |
73 | menu menuID = menu::none;
74 | menu newMenuID = menu::black;
75 | int64_t lastRender = 0;
76 | int64_t updateTime = 0;
77 |
78 | std::string selectedFile;
79 |
80 | lcdUI(/* args */);
81 | ~lcdUI();
82 |
83 | static void updateTask(void* arg);
84 | static void touchTask(void* arg);
85 | static void cardDetectTask(void* arg);
86 | static void cardISRhandle(void* arg);
87 |
88 | bool initSD();
89 | void processTouch();
90 | esp_err_t updateDisplay();
91 | esp_err_t updateObjects();
92 | public:
93 |
94 | static lcdUI* instance();
95 | esp_err_t begin();
96 | void setScreen(const menu screen);
97 | void endSD();
98 | bool isSDinit() const;
99 | esp_err_t setFile(const std::string& file);
100 | const std::string& getFile() const { return selectedFile; }
101 | void clearFile() { selectedFile.clear(); }
102 | void requestUpdate();
103 | esp_err_t setBrightness(uint32_t duty);
104 | uint32_t getBrightness();
105 | };
106 |
107 | #endif
108 |
--------------------------------------------------------------------------------
/main/main.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * @file main.c
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 21-01-2022
5 | * -----
6 | * Last Modified: 12-02-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #include
26 | #include
27 | #include "esp_system.h"
28 | #include "esp_spi_flash.h"
29 | #include "dbg_log.h"
30 | #include "esp_spiffs.h"
31 | #include "lcdUI.h"
32 |
33 | gpio_config_t input_conf = {
34 | .pin_bit_mask = GPIO_SEL_34 | GPIO_SEL_27,
35 | .mode = GPIO_MODE_INPUT,
36 | .pull_up_en = GPIO_PULLUP_DISABLE,
37 | .pull_down_en = GPIO_PULLDOWN_DISABLE,
38 | .intr_type = GPIO_INTR_DISABLE
39 | };
40 |
41 | extern "C" void app_main(void)
42 | {
43 | gpio_config(&input_conf);
44 | initArduino();
45 |
46 | esp_reset_reason_t reason = esp_reset_reason();
47 | if (reason != ESP_RST_POWERON)
48 | {
49 | DBG_LOGE("System unexpected reboot!");
50 | while (true) vTaskDelay(100);
51 | }
52 |
53 | printf("System ready!\n");
54 |
55 | printf("Free Heap at start: %d of %d\n", esp_get_free_heap_size(), ESP.getHeapSize());
56 |
57 | // INITIALIZE SPIFFS STORAGE
58 | DBG_LOGI("Initializing SPIFFS");
59 |
60 | esp_vfs_spiffs_conf_t conf = {
61 | .base_path = "/spiffs",
62 | .partition_label = NULL,
63 | .max_files = 5,
64 | .format_if_mount_failed = false
65 | };
66 |
67 | esp_err_t ret = esp_vfs_spiffs_register(&conf);
68 |
69 | if (ret != ESP_OK) {
70 | if (ret == ESP_FAIL) {
71 | DBG_LOGE("Failed to mount or format filesystem");
72 | } else if (ret == ESP_ERR_NOT_FOUND) {
73 | DBG_LOGE("Failed to find SPIFFS partition");
74 | } else {
75 | DBG_LOGE("Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
76 | }
77 | return;
78 | }
79 |
80 | // INITIALIZE UI
81 | ret = lcdUI::instance()->begin();
82 | if (ret != ESP_OK)
83 | {
84 | DBG_LOGE("Failed to initialize UI. Rebooting NOW!");
85 | esp_restart();
86 | }
87 |
88 | lcdUI::instance()->setScreen(lcdUI::Info);
89 |
90 | while (1)
91 | {
92 | vTaskDelay(1000);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/main/tftLCD.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "tftLCD.h"
3 | #include
4 |
5 | #ifdef LOAD_GFXFF
6 | inline GFXglyph * pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c)
7 | {
8 | #ifdef __AVR__
9 | return &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
10 | #else
11 | // expression in __AVR__ section may generate "dereferencing type-punned pointer will break strict-aliasing rules" warning
12 | // In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
13 | // So expression may be simplified
14 | return gfxFont->glyph + c;
15 | #endif //__AVR__
16 | }
17 |
18 | inline uint8_t * pgm_read_bitmap_ptr(const GFXfont *gfxFont)
19 | {
20 | #ifdef __AVR__
21 | return (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
22 | #else
23 | // expression in __AVR__ section generates "dereferencing type-punned pointer will break strict-aliasing rules" warning
24 | // In fact, on other platforms (such as STM32) there is no need to do this pointer magic as program memory may be read in a usual way
25 | // So expression may be simplified
26 | return gfxFont->bitmap;
27 | #endif //__AVR__
28 | }
29 | #endif
30 |
31 | /*####################################################
32 | tft Sprite class
33 | ####################################################*/
34 |
35 | /**************************************************************************/
36 | /*!
37 | @brief Print a string centered at cursor location (supports multy-line text)
38 | @param String to print
39 | */
40 | /**************************************************************************/
41 | void tftSprite::printCenter(const String &str)
42 | {
43 | uint8_t h = 1;
44 | for (unsigned int i = 0; i < str.length(); i++)
45 | {
46 | if(str[i] == '\n') h++;
47 | }
48 | h *= fontHeight();
49 | cursor_y -= h/2;
50 | int16_t center = cursor_x;
51 | setTextDatum(TC_DATUM);
52 | if (str.indexOf('\n') == -1)
53 | {
54 | drawString(str, cursor_x, cursor_y);
55 | }
56 | else
57 | {
58 | int a = 0;
59 | int b = str.indexOf('\n');
60 | while (a < str.length())
61 | {
62 | drawString(str.substring(a, b), center, cursor_y);
63 | print('\n');
64 | a = b+1;
65 | b = str.indexOf('\n', a);
66 | if (b == -1) b = str.length();
67 | }
68 | }
69 | }
70 |
71 | void tftSprite::printCenter(const char *str)
72 | {
73 | printCenter(String(str));
74 | }
75 |
76 | /*####################################################
77 | tft LCD class
78 | ####################################################*/
79 |
80 | /**************************************************************************/
81 | /*!
82 | @brief Draw single character over any rectangle without flickering (Only free fonts supported yet)
83 | May be slower than using sprites but less RAM intesive.
84 | @param pos Cursor position (2D vector)
85 | @param c Character to draw
86 | @param color Text color
87 | @param bg Rectangle color
88 | @param size Text size
89 | @param start Upper Left corner of the rectagle (2D vector)
90 | @param dim Width and height of the rectangle (2D vector)
91 | */
92 | /**************************************************************************/
93 | void tftLCD::drawCharBg(Vec2h pos, uint8_t c, uint16_t color, uint16_t bg, uint8_t size, Vec2h *start, Vec2h dim)
94 | {
95 | #ifdef LOAD_GFXFF
96 | int16_t minx = 0, miny = 0, maxx = 5, maxy = 8;
97 | if(gfxFont) // 'Classic' built-in font
98 | { // Custom font
99 | c -= (uint8_t)pgm_read_byte(&gfxFont->first);
100 | GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c);
101 | uint8_t *bitmap = pgm_read_bitmap_ptr(gfxFont);
102 |
103 | uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
104 | int16_t w = pgm_read_byte(&glyph->width),
105 | h = pgm_read_byte(&glyph->height);
106 | int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset),
107 | yo = (int8_t)pgm_read_byte(&glyph->yOffset);
108 | uint8_t bits = 0,
109 | oldbits = pgm_read_byte(&bitmap[bo]),
110 | bit = 0,
111 | oldbit = 0;
112 | uint16_t oldbo = bo;
113 | if (size > 1)
114 | {
115 | w *= size;
116 | h *= size;
117 | xo *= size;
118 | yo *= size;
119 | }
120 | maxx = w, maxy = h;
121 |
122 | if (dim.x != 0)
123 | {
124 | if ((*start).x < 0) (*start).x = 0;
125 | minx = (*start).x - pos.x - xo;
126 | maxx = dim.x + minx;
127 | }
128 | else if ((*start).x >= 0)
129 | {
130 | minx = (*start).x - pos.x - xo;
131 | }
132 |
133 | if (dim.y != 0)
134 | {
135 | if ((*start).y < 0) (*start).y = 0;
136 | miny = (*start).y - pos.y - yo;
137 | maxy = dim.y + miny;
138 | }
139 | else if ((*start).y >= 0)
140 | {
141 | miny = (*start).y - pos.y - yo;
142 | }
143 | dim.x = maxx-minx;
144 | dim.y = maxy-miny;
145 |
146 | if (miny < 0)
147 | {
148 | fillRect((*start).x, (*start).y, dim.x, min((int)dim.y, -miny), bg);
149 | }
150 | if (maxy > h)
151 | {
152 | fillRect((*start).x, max((int)(*start).y, h + pos.y + yo), dim.x, min(maxy-h, (int)dim.y), bg);
153 | dim.y -= maxy-h;
154 | }
155 | dim.y -= max(0, -miny);
156 | if (dim.y < 0) dim.y = 0;
157 | if (minx < 0)
158 | {
159 | fillRect((*start).x, max((int)(*start).y, pos.y+yo), min((int)dim.x, -minx), dim.y, bg);
160 | }
161 | if (maxx > w)
162 | {
163 | fillRect(max((int)(*start).x, w + pos.x + xo), max((int)(*start).y, pos.y+yo), min(maxx-w, (int)dim.x), dim.y, bg);
164 | }
165 |
166 | startWrite();
167 | for(uint16_t yy = 0; yy < h; yy++) // Start drawing
168 | {
169 | for(uint16_t xx = 0; xx < w; xx++)
170 | {
171 | if (xx % size == 0)
172 | {
173 | if(!(bit++ & 7))
174 | {
175 | bits = pgm_read_byte(&bitmap[bo++]);
176 | }
177 | if(bits & 0x80)
178 | {
179 | if(size == 1)
180 | {
181 | drawPixel(pos.x+xo+xx, pos.y+yo+yy, color);
182 | }
183 | else
184 | {
185 | drawFastHLine(pos.x+xo+xx, pos.y+yo+yy, size, color);
186 | xx += size-1;
187 | }
188 | }
189 | else if (bg != color && xx >= minx && xx < maxx && yy >= miny && yy < maxy)
190 | {
191 | drawPixel(pos.x+xo+xx, pos.y+yo+yy, bg);
192 | }
193 | bits <<= 1;
194 | }
195 | else if (xx >= minx && xx < maxx && yy >= miny && yy < maxy)
196 | {
197 | drawPixel(pos.x+xo+xx, pos.y+yo+yy, bg);
198 | }
199 | }
200 | if (yy % size == (size-1))
201 | {
202 | oldbit = bit;
203 | oldbo = bo;
204 | oldbits = bits;
205 | }
206 | else
207 | {
208 | bit = oldbit;
209 | bo = oldbo;
210 | bits = oldbits;
211 | }
212 | }
213 | endWrite();
214 | (*start).x = pos.x+xo+maxx;
215 | } // End classic vs custom font
216 | else
217 | #endif
218 | {
219 | if((pos.x >= _width) || // Clip right
220 | (pos.y >= _height) || // Clip bottom
221 | ((pos.x + 6 * size - 1) < 0) || // Clip left
222 | ((pos.y + 8 * size - 1) < 0)) // Clip top
223 | return;
224 |
225 | if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior
226 |
227 | startWrite();
228 | for(int8_t i=0; i<5; i++ )
229 | { // Char bitmap = 5 columns
230 | uint8_t line = pgm_read_byte(&font[c * 5 + i]);
231 | for(int8_t j=0; j<8; j++, line >>= 1)
232 | {
233 | if(line & 1)
234 | {
235 | if(size == 1)
236 | drawPixel(pos.x+i, pos.y+j, color);
237 | else
238 | fillRect(pos.x+i*size, pos.y+j*size, size, size, color);
239 | }
240 | else if(bg != color)
241 | {
242 | if(size == 1)
243 | drawPixel(pos.x+i, pos.y+j, bg);
244 | else
245 | fillRect(pos.x+i*size, pos.y+j*size, size, size, bg);
246 | }
247 | }
248 | }
249 | if(bg != color)
250 | { // If opaque, draw vertical line for last column
251 | if(size == 1) drawFastVLine(pos.x+5, pos.y, 8, bg);
252 | else fillRect(pos.x+5*size, pos.y, size, 8*size, bg);
253 | }
254 | endWrite();
255 | }
256 | }
257 |
258 | /**************************************************************************/
259 | /*!
260 | @brief Draw single character over any rectangle without flickering (Only free fonts supported yet)
261 | May be slower than using sprites but less RAM intesive.
262 | @param c Character to draw
263 | @param pos Upper Left corner of the rectagle (2D vector)
264 | @param dim Width and height of the rectangle (2D vector)
265 | */
266 | /**************************************************************************/
267 | size_t tftLCD::writeBg(uint8_t c, Vec2h *pos, Vec2h dim)
268 | {
269 | #ifdef LOAD_GFXFF
270 | if(gfxFont)
271 | {
272 | if(c == '\n')
273 | {
274 | cursor_x = 0;
275 | cursor_y += (int16_t)textsize *
276 | (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
277 | } else if(c != '\r')
278 | {
279 | uint8_t first = pgm_read_byte(&gfxFont->first);
280 | if((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last)))
281 | {
282 | GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
283 | uint8_t w = pgm_read_byte(&glyph->width),
284 | h = pgm_read_byte(&glyph->height);
285 | if((w > 0) && (h > 0))
286 | { // Is there an associated bitmap?
287 | int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
288 | if(textwrapX && ((cursor_x + textsize * (xo + w)) > _width))
289 | {
290 | cursor_x = 0;
291 | cursor_y += (int16_t)textsize *
292 | (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
293 | }
294 | drawCharBg(Vec2h(cursor_x, cursor_y), c, textcolor, textbgcolor, textsize, pos, dim);
295 | }
296 | cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
297 | }
298 | }
299 | }
300 | else // Custom font
301 | #endif
302 | { // 'Classic' built-in font
303 | if(c == '\n') { // Newline?
304 | cursor_x = 0; // Reset x to zero,
305 | cursor_y += textsize * 8; // advance y one line
306 | } else if(c != '\r') { // Ignore carriage returns
307 | if(textwrapX && ((cursor_x + textsize * 6) > _width)) { // Off right?
308 | cursor_x = 0; // Reset x to zero,
309 | cursor_y += textsize * 8; // advance y one line
310 | }
311 | drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
312 | cursor_x += textsize * 6; // Advance x one char
313 | }
314 | }
315 | return 1;
316 | }
317 |
318 | /**************************************************************************/
319 | /*!
320 | @brief Draw string with filled background without flickering (Support multy-line)
321 | May be slower than using sprites but less RAM intesive.
322 | @param str String to draw
323 | */
324 | /**************************************************************************/
325 | void tftLCD::printBg(const String &str)
326 | {
327 | printBg(str, Vector2());
328 | }
329 |
330 | /**************************************************************************/
331 | /*!
332 | @brief Draw string with filled background without flickering (Support multy-line)
333 | May be slower than using sprites but less RAM intesive.
334 | @param str String to draw
335 | @param pad Border width arround text
336 | */
337 | /**************************************************************************/
338 | void tftLCD::printBg(const String &str, uint8_t pad)
339 | {
340 | printBg(str, Vector2(pad, pad));
341 | }
342 |
343 | /**************************************************************************/
344 | /*!
345 | @brief Draw string with filled background without flickering (Support multy-line)
346 | May be slower than using sprites but less RAM intesive.
347 | @param str String to draw
348 | @param pad Border width arround text in X and Y directions (2D vector)
349 | */
350 | /**************************************************************************/
351 | void tftLCD::printBg(const String &str, Vector2 pad)
352 | {
353 | if (str.indexOf('\n') == -1)
354 | {
355 | int16_t x = 0, y = 0;
356 | Vec2h size = getTextBounds(str, &x, &y);
357 | Vec2h pos(x + cursor_x - pad.x, y + cursor_y - pad.y);
358 | size.y += 2*pad.y;
359 | for (unsigned int i = 0; i < str.length(); i++)
360 | {
361 | writeBg(str[i], &pos, Vec2h(0, size.y));
362 | }
363 | fillRect(pos.x, pos.y, pad.x, size.y, textbgcolor);
364 | }
365 | else
366 | {
367 | String buf;
368 | int a = 0;
369 | int b = str.indexOf('\n');
370 | while (a < str.length())
371 | {
372 | buf = str.substring(a, b);
373 | printBg(buf);
374 | print('\n');
375 | a = b+1;
376 | b = str.indexOf('\n', a);
377 | if (b == -1) b = str.length();
378 | }
379 | }
380 | }
381 |
382 | /**************************************************************************/
383 | /*!
384 | @brief Draw string over any rectangle without flickering (Support multy-line) ########## TO DO: -Add multy line, -Fix some single line issues
385 | May be slower than using sprites but less RAM intesive.
386 | @param str String to draw
387 | @param pos Upper Left corner of the rectagle (2D vector)
388 | @param dim Width and height of the rectangle (2D vector)
389 | */
390 | /**************************************************************************/
391 | void tftLCD::printBg(const String &str, Vec2h pos, Vector2 dim)
392 | {
393 | int16_t x = 0, y = 0;
394 | Vec2h start = pos;
395 | Vec2h end(0, 0);
396 |
397 | for (unsigned int i = 0; i < str.length(); i++)
398 | {
399 | Vec2h size = getTextBounds(String(str[i]), &x, &y);
400 | x += cursor_x;
401 | y += cursor_y;
402 | //charBounds(str[i], &x, &y, &minx, &miny, &maxx, &maxy);
403 |
404 | if (x < pos.x + dim.x && x+size.x > pos.x && y < pos.y + dim.y && y+size.y > pos.y) // Check for character and rectangle overlap
405 | {
406 | if (pos.x+dim.x < x+size.x || i == str.length()-1) end.x = pos.x+dim.x-start.x;
407 | if (pos.y+dim.y < y+size.y) end.y = pos.y+dim.y-start.y;
408 | writeBg(str[i], &start, end);
409 | }
410 | else
411 | {
412 | write(str[i]);
413 | }
414 | }
415 | }
416 |
417 | /**************************************************************************/
418 | /*!
419 | @brief Helper to determine size of a character with current font/size.
420 | Broke this out as it's used by both the PROGMEM- and RAM-resident getTextBounds() functions.
421 | @param c The ascii character in question
422 | @param x Pointer to x location of character
423 | @param y Pointer to y location of character
424 | @param minx Minimum clipping value for X
425 | @param miny Minimum clipping value for Y
426 | @param maxx Maximum clipping value for X
427 | @param maxy Maximum clipping value for Y
428 | */
429 | /**************************************************************************/
430 | #if defined(LOAD_GFXFF) || defined(LOAD_GLCD)
431 | void tftLCD::charBounds(char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy)
432 | {
433 | #ifdef LOAD_GFXFF
434 | if(gfxFont)
435 | {
436 | if(c == '\n')
437 | { // Newline?
438 | *x = 0; // Reset x to zero, advance y by one line
439 | *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
440 | }
441 | else if(c != '\r')
442 | { // Not a carriage return; is normal char
443 | uint8_t first = pgm_read_byte(&gfxFont->first),
444 | last = pgm_read_byte(&gfxFont->last);
445 | if((c >= first) && (c <= last)) { // Char present in this font?
446 | GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
447 | uint8_t gw = pgm_read_byte(&glyph->width),
448 | gh = pgm_read_byte(&glyph->height),
449 | xa = pgm_read_byte(&glyph->xAdvance);
450 | int8_t xo = pgm_read_byte(&glyph->xOffset),
451 | yo = pgm_read_byte(&glyph->yOffset);
452 | if(textwrapX && ((*x+(((int16_t)xo+gw)*textsize)) > _width))
453 | {
454 | *x = 0; // Reset x to zero, advance y by one line
455 | *y += textsize * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
456 | }
457 | int16_t tsx = (int16_t)textsize,
458 | tsy = (int16_t)textsize,
459 | x1 = *x + xo * tsx,
460 | y1 = *y + yo * tsy,
461 | x2 = x1 + gw * tsx - 1,
462 | y2 = y1 + gh * tsy - 1;
463 | if(x1 < *minx) *minx = x1;
464 | if(y1 < *miny) *miny = y1;
465 | if(x2 > *maxx) *maxx = x2;
466 | if(y2 > *maxy) *maxy = y2;
467 | *x += xa * tsx;
468 | }
469 | }
470 |
471 | }
472 | else
473 | #endif
474 | { // Default font
475 |
476 | if(c == '\n')
477 | { // Newline?
478 | *x = 0; // Reset x to zero,
479 | *y += textsize * 8; // advance y one line
480 | // min/max x/y unchaged -- that waits for next 'normal' character
481 | } else if(c != '\r')
482 | { // Normal char; ignore carriage returns
483 | if(textwrapX && ((*x + textsize * 6) > _width))
484 | { // Off right?
485 | *x = 0; // Reset x to zero,
486 | *y += textsize * 8; // advance y one line
487 | }
488 | int x2 = *x + textsize * 6 - 1, // Lower-right pixel of char
489 | y2 = *y + textsize * 8 - 1;
490 | if(x2 > *maxx) *maxx = x2; // Track max x, y
491 | if(y2 > *maxy) *maxy = y2;
492 | if(*x < *minx) *minx = *x; // Track min x, y
493 | if(*y < *miny) *miny = *y;
494 | *x += textsize * 6; // Advance x one char
495 | }
496 | }
497 | }
498 | #endif
499 |
500 | /**************************************************************************/
501 | /*!
502 | @brief Return a vector with the width and height of a text
503 | @param str String to evaluate
504 | */
505 | /**************************************************************************/
506 | Vec2h tftLCD::getTextBounds(const String &str)
507 | {
508 | int b = str.indexOf('\n');
509 | if (b == -1) // Single line
510 | {
511 | return Vec2h(textWidth(str), fontHeight());
512 | }
513 | else // Multy-line
514 | {
515 | int16_t w = 0, h = 0;
516 | String buf;
517 | int a = 0;
518 | while (a < str.length())
519 | {
520 | buf = str.substring(a, b)+'\n';
521 | w = max(textWidth(buf), w); // Find the widest line
522 | a = b+1;
523 | b = str.indexOf('\n', a);
524 | if (b == -1) b = str.length();
525 | h++; // number of lines
526 | }
527 | h *= fontHeight(); // Total height
528 | return Vec2h(w,h);
529 | }
530 | return Vec2h();
531 | }
532 |
533 | Vec2h tftLCD::getTextBounds(const String &str, int16_t *x, int16_t *y)
534 | {
535 | if(str.length() != 0)
536 | {
537 | return getTextBounds(str.c_str(), x, y);
538 | }
539 | return Vec2h();
540 | }
541 |
542 | Vec2h tftLCD::getTextBounds(const char *str)
543 | {
544 | ESP_LOGV(__FILE__, "getTextBounds start\n");
545 |
546 | return getTextBounds(String(str));
547 | }
548 |
549 | /**************************************************************************/
550 | /*!
551 | @brief Return the bounding box of a text
552 | @param str String to evaluate
553 | @param x X offset from cursor X position
554 | @param y Y offset from cursor Y position
555 | */
556 | /**************************************************************************/
557 | Vec2h tftLCD::getTextBounds(const char *str, int16_t *x, int16_t *y)
558 | {
559 | if (textfont != 1)
560 | {
561 | return getTextBounds(str);
562 | }
563 | #if defined(LOAD_GFXFF) || defined(LOAD_GLCD)
564 | uint8_t c; // Current character
565 |
566 | *x = 0;
567 | *y = 0;
568 | Vec2h size = Vec2h();
569 |
570 | int16_t minx = _width, miny = _height, maxx = -1, maxy = -1;
571 |
572 | while((c = *str++))
573 | charBounds(c, x, y, &minx, &miny, &maxx, &maxy);
574 |
575 | if(maxx >= minx) {
576 | *x = minx;
577 | size.x = maxx - minx + 1;
578 | }
579 | if(maxy >= miny) {
580 | *y = miny;
581 | size.y = maxy - miny + 1;
582 | }
583 | return size;
584 | #else
585 | return Vec2h();
586 | #endif
587 | }
588 |
589 | /**************************************************************************/
590 | /*!
591 | @brief Print a string centered at cursor location (supports multy-line text)
592 | @param String to print
593 | */
594 | /**************************************************************************/
595 | void tftLCD::printCenter(const String &str)
596 | {
597 | int16_t x,y;
598 | int16_t center;
599 |
600 | center = cursor_x; // Save central X position for later
601 | Vec2h size = getTextBounds(str, &x, &y); // Get bounding box
602 | int b = str.indexOf('\n');
603 | if (b == -1) // Single line text
604 | {
605 | setCursor(getCursorX()-size.x/2-x, getCursorY()-size.y/2-y);
606 | printBg(str);
607 |
608 | }
609 | else // Multy-line text
610 | {
611 | String buf;
612 | cursor_y -= size.y/2+y;
613 | int a = 0;
614 | while (a < str.length()) // handle each line at once
615 | {
616 | buf = str.substring(a, b)+'\n';
617 | size = getTextBounds(buf, &x, &y);
618 | cursor_x = center-size.x/2-x;
619 | printBg(buf);
620 | a = b+1;
621 | b = str.indexOf('\n', a);
622 | if (b == -1) b = str.length();
623 | }
624 | }
625 | }
626 |
627 | void tftLCD::printCenter(const char *str)
628 | {
629 | printCenter(String(str));
630 | }
631 |
632 | /**
633 | * @brief Draw string wrapped
634 | *
635 | * @param str String to draw
636 | * @param x String X position
637 | * @param y String Y position
638 | * @param w Max string width
639 | * @param h Max string height
640 | */
641 | void tftLCD::drawStringWr(const char *str, int32_t x, int32_t y, uint16_t w, uint16_t h)
642 | {
643 | const uint16_t cheight = fontHeight();
644 | const int16_t lines = min(textWidth(str)/w, h/cheight-1);
645 |
646 | uint16_t len = strlen(str);
647 | uint16_t cnt = 0;
648 | const uint16_t maxChar = w/3;
649 | char buffer[maxChar+1];
650 | for (int16_t i = 0; i <= lines; i++)
651 | {
652 | uint8_t charN = maxChar;
653 | strncpy(buffer, &str[cnt], maxChar);
654 | buffer[maxChar] = '\0';
655 |
656 | while (textWidth(buffer) > w)
657 | buffer[--charN] = '\0';
658 |
659 | drawString(buffer, x, y - cheight/2*lines + i*cheight);
660 |
661 | cnt += charN;
662 | if (cnt > len) break; // All characters read
663 | }
664 | }
665 |
666 | // These read 16- and 32-bit types from the SD card file.
667 | // BMP data is stored little-endian, Arduino is little-endian too.
668 | // May need to reverse subscript order if porting elsewhere.
669 |
670 | uint16_t SPIFFS_read16(FILE *f) {
671 | uint16_t result;
672 | ((uint8_t *)&result)[0] = fgetc(f); // LSB
673 | ((uint8_t *)&result)[1] = fgetc(f); // MSB
674 | return result;
675 | }
676 |
677 | uint32_t SPIFFS_read32(FILE *f) {
678 | uint32_t result;
679 | ((uint8_t *)&result)[0] = fgetc(f); // LSB
680 | ((uint8_t *)&result)[1] = fgetc(f);
681 | ((uint8_t *)&result)[2] = fgetc(f);
682 | ((uint8_t *)&result)[3] = fgetc(f); // MSB
683 | return result;
684 | }
685 |
686 | void tftLCD::drawBmpSPIFFS(const char *filename, int16_t x, int16_t y)
687 | {
688 | if ((x >= _width) || (y >= _height)) return;
689 |
690 | // Open requested file on SPIFFS
691 | FILE *bmpFS = fopen(filename, "r");
692 |
693 | if (!bmpFS)
694 | {
695 | ESP_LOGE(__FILE__, "File \"%s\" not found!", filename);
696 | return;
697 | }
698 |
699 | uint32_t seekOffset;
700 | uint16_t w, h, row;
701 |
702 | if (SPIFFS_read16(bmpFS) == 0x4D42)
703 | {
704 | SPIFFS_read32(bmpFS);
705 | SPIFFS_read32(bmpFS);
706 | seekOffset = SPIFFS_read32(bmpFS);
707 | SPIFFS_read32(bmpFS);
708 | w = SPIFFS_read32(bmpFS);
709 | h = SPIFFS_read32(bmpFS);
710 |
711 | if (SPIFFS_read16(bmpFS) == 1 && SPIFFS_read16(bmpFS) == 16 && SPIFFS_read32(bmpFS) == 3)
712 | {
713 | y += h - 1;
714 |
715 | bool oldSwapBytes = getSwapBytes();
716 | setSwapBytes(true);
717 | fseek(bmpFS, seekOffset, SEEK_SET);
718 | uint8_t lineBuffer[w * 2 + ((w & 1) << 1)];
719 |
720 | for (row = 0; row < h; row++)
721 | {
722 | fread(lineBuffer, 1, sizeof(lineBuffer), bmpFS);
723 |
724 | // Push the pixel row to screen, pushImage will crop the line if needed
725 | // y is decremented as the BMP image is drawn bottom up
726 | pushImage(x, y--, w, 1, (uint16_t*)lineBuffer);
727 | }
728 | setSwapBytes(oldSwapBytes);
729 | }
730 | else
731 | ESP_LOGE(__FILE__, "BMP format not recognized.");
732 | }
733 | fclose(bmpFS);
734 | }
735 |
--------------------------------------------------------------------------------
/main/tftLCD.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef TFTLCD_H
3 | #define TFTLCD_H
4 |
5 | #include
6 | #include
7 | #include "Free_Fonts.h"
8 | #include "Vector.h"
9 |
10 | class tftSprite : public TFT_eSprite
11 | {
12 | public:
13 | tftSprite(TFT_eSPI* tft): TFT_eSprite(tft){}
14 |
15 | void printCenter(const String &str);
16 | void printCenter(const char *str);
17 | };
18 |
19 | class tftLCD : public TFT_eSPI
20 | {
21 | public:
22 | void drawCharBg(Vec2h pos, uint8_t c, uint16_t color, uint16_t bg, uint8_t size, Vec2h *start, Vec2h dim);
23 | size_t writeBg(uint8_t c, Vec2h *pos, Vec2h dim);
24 | void printBg(const String &str);
25 | void printBg(const String &str, Vector2 pad);
26 | void printBg(const String &str, uint8_t pad);
27 | void printBg(const String &str, Vec2h pos, Vector2 dim);
28 |
29 | void charBounds(char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy);
30 | Vec2h getTextBounds(const char *str);
31 | Vec2h getTextBounds(const String &str);
32 | Vec2h getTextBounds(const char *str, int16_t *x, int16_t *y);
33 | Vec2h getTextBounds(const String &str, int16_t *x, int16_t *y);
34 |
35 | void printCenter(const String &str);
36 | void printCenter(const char *str);
37 |
38 | void drawStringWr(const char *str, int32_t x, int32_t y, uint16_t w, uint16_t h);
39 |
40 | void drawBmpSPIFFS(const char *filename, int16_t x, int16_t y);
41 |
42 | tftSprite img = tftSprite(this);
43 | };
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/main/utility.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "utility.h"
3 |
4 | #ifdef CONFIG_ENABLE_TIMER
5 | int64_t Timer::startTime;
6 |
7 | void Timer::tic()
8 | {
9 | startTime = esp_timer_get_time();
10 | }
11 |
12 | const int64_t Timer::toc()
13 | {
14 | int64_t eTime = esp_timer_get_time()-startTime;
15 | ESP_LOGD("Utility", "\nElapsed time: %lu\n", (unsigned long)eTime);
16 | return eTime;
17 | }
18 | #endif
19 |
20 | #ifdef SCREEN_SERVER_U
21 | bool ScreenServer::screenServer(TFT_eSPI& tft)
22 | {
23 | // With no filename the screenshot will be saved with a default name e.g. tft_screen_#.xxx
24 | // where # is a number 0-9 and xxx is a file type specified below
25 | return screenServer(DEFAULT_FILENAME, tft);
26 | }
27 |
28 | bool ScreenServer::screenServer(String filename, TFT_eSPI& tft)
29 | {
30 | uint32_t clearTime;
31 | uint32_t lastCmdTime = millis(); // Initialise start of command time-out
32 |
33 | // Check serial buffer
34 | if (Serial.available() > 0) {
35 | // Read the command byte
36 | uint8_t cmd = Serial.read();
37 | // If it is 'S' (start command) then clear the serial buffer for 100ms and stop waiting
38 | if ( cmd == 'S' ) {
39 | // Precautionary receive buffer garbage flush for 50ms
40 | clearTime = millis() + 50;
41 | while ( millis() < clearTime && Serial.read() >= 0) delay(1);
42 |
43 | lastCmdTime = millis(); // Set last received command time
44 |
45 | // Send screen size etc using a simple header with delimiters for client checks
46 | sendParameters(filename, tft);
47 | }
48 | else
49 | return false;
50 | }
51 | else
52 | return false;
53 |
54 | uint8_t color[3 * NPIXELS]; // RGB and 565 format color buffer for N pixels
55 |
56 | // Send all the pixels on the whole screen
57 | for ( uint32_t y = 0; y < tft.height(); y++)
58 | {
59 | // Increment x by NPIXELS as we send NPIXELS for every byte received
60 | for ( uint32_t x = 0; x < tft.width(); x += NPIXELS)
61 | {
62 | yield();
63 |
64 | // Wait here for serial data to arrive or a time-out elapses
65 | while ( Serial.available() == 0 )
66 | {
67 | if ( millis() > lastCmdTime + PIXEL_TIMEOUT) return false;
68 | delay(1);
69 | }
70 |
71 | // Serial data must be available to get here, read 1 byte and
72 | // respond with N pixels, i.e. N x 3 RGB bytes or N x 2 565 format bytes
73 | if ( Serial.read() == 'X' ) {
74 | // X command byte means abort, so clear the buffer and return
75 | clearTime = millis() + 50;
76 | while ( millis() < clearTime && Serial.read() >= 0) yield();
77 | return false;
78 | }
79 | // Save arrival time of the read command (for later time-out check)
80 | lastCmdTime = millis();
81 |
82 | #if defined BITS_PER_PIXEL && BITS_PER_PIXEL >= 24 && NPIXELS > 1
83 | // Fetch N RGB pixels from x,y and put in buffer
84 | tft.readRectRGB(x, y, NPIXELS, 1, color);
85 | // Send buffer to client
86 | Serial.write(color, 3 * NPIXELS); // Write all pixels in the buffer
87 | #else
88 | // Fetch N 565 format pixels from x,y and put in buffer
89 | #if NPIXELS > 1
90 | tft.readRect(x, y, NPIXELS, 1, (uint16_t *)color);
91 | #else
92 | uint16_t c = tft.readPixel(x, y);
93 | color[0] = c>>8;
94 | color[1] = c & 0xFF; // Swap bytes
95 | #endif
96 | // Send buffer to client
97 | Serial.write(color, 2 * NPIXELS); // Write all pixels in the buffer
98 | #endif
99 | }
100 | }
101 |
102 | Serial.flush(); // Make sure all pixel bytes have been despatched
103 |
104 | return true;
105 | }
106 |
107 | void ScreenServer::sendParameters(String filename, TFT_eSPI& tft)
108 | {
109 | Serial.write('W'); // Width
110 | Serial.write(tft.width() >> 8);
111 | Serial.write(tft.width() & 0xFF);
112 |
113 | Serial.write('H'); // Height
114 | Serial.write(tft.height() >> 8);
115 | Serial.write(tft.height() & 0xFF);
116 |
117 | Serial.write('Y'); // Bits per pixel (16 or 24)
118 | if (NPIXELS > 1) Serial.write(BITS_PER_PIXEL);
119 | else Serial.write(16); // readPixel() only provides 16 bit values
120 |
121 | Serial.write('?'); // Filename next
122 | Serial.print(filename);
123 |
124 | Serial.write('.'); // End of filename marker
125 |
126 | Serial.write(FILE_EXT); // Filename extension identifier
127 |
128 | Serial.write(*FILE_TYPE); // First character defines file type j,b,p,t
129 | }
130 | #endif
131 |
--------------------------------------------------------------------------------
/main/utility.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file utility.h
3 | * @author Ricard Bitriá Ribes (https://github.com/dracir9)
4 | * Created Date: 22-01-2022
5 | * -----
6 | * Last Modified: 10-04-2022
7 | * Modified By: Ricard Bitriá Ribes
8 | * -----
9 | * @copyright (c) 2022 Ricard Bitriá Ribes
10 | *
11 | * This program is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see .
23 | */
24 |
25 | #ifndef UTILITY_H
26 | #define UTILITY_H
27 |
28 | #ifdef CONFIG_ENABLE_TIMER
29 | #include
30 | class Timer
31 | {
32 | public:
33 |
34 | /**
35 | * @brief Sets time mark
36 | */
37 | static void tic();
38 |
39 | /**
40 | * @brief Print time elapsed since last tic() call in microseconds
41 | *
42 | * @return const int64_t Time elapsed in microseconds
43 | */
44 | static const int64_t toc();
45 |
46 | private:
47 | static int64_t startTime;
48 | };
49 |
50 | #define TIC Timer::tic();
51 | #define TOC Timer::toc();
52 | #else
53 | #define TIC
54 | #define TOC
55 | #endif
56 |
57 | #ifdef SCREEN_SERVER_U
58 | #if CORE_DEBUG_LEVEL > 3
59 | #warning "Debug messages may interfere in the image transfer. Please define CORE_DEBUG_LEVEL to be <= 3"
60 | #endif
61 | #include
62 | // Based on Bodmer's example sketch
63 |
64 | // Reads a screen image off the TFT and send it to a processing client sketch
65 | // over the serial port.
66 |
67 | // This sketch has been created to work with the TFT_eSPI library here:
68 | // https://github.com/Bodmer/TFT_eSPI
69 |
70 | // Created by: Bodmer 27/1/17
71 | // Updated by: Bodmer 10/3/17
72 | // Updated by: Bodmer 23/11/18 to support SDA reads and the ESP32
73 | // Updated by: dracir9 12/1/21 adapted to own project
74 | // Version: 0.08
75 |
76 | // MIT licence applies, all text above must be included in derivative works
77 | //====================================================================================
78 | // Definitions
79 | //====================================================================================
80 | #define PIXEL_TIMEOUT 100 // 100ms Time-out between pixel requests
81 | #define START_TIMEOUT 10000 // 10s Maximum time to wait at start transfer
82 |
83 | #define BITS_PER_PIXEL 16 // 24 for RGB colour format, 16 for 565 colour format
84 |
85 | // File names must be alpha-numeric characters (0-9, a-z, A-Z) or "/" underscore "_"
86 | // other ascii characters are stripped out by client, including / generates
87 | // sub-directories
88 | #define DEFAULT_FILENAME "tft_screenshots/screenshot" // In case none is specified
89 | #define FILE_TYPE "png" // jpg, bmp, png, tif are valid
90 |
91 | // Filename extension
92 | // '#' = add incrementing number, '@' = add timestamp, '%' add millis() timestamp,
93 | // '*' = add nothing
94 | // '@' and '%' will generate new unique filenames, so beware of cluttering up your
95 | // hard drive with lots of images! The PC client sketch is set to limit the number of
96 | // saved images to 1000 and will then prompt for a restart.
97 | #define FILE_EXT '@'
98 |
99 | // Number of pixels to send in a burst (minimum of 1), no benefit above 8
100 | // NPIXELS values and render times:
101 | // NPIXELS 1 = use readPixel() = >5s and 16 bit pixels only
102 | // NPIXELS >1 using rectRead() 2 = 1.75s, 4 = 1.68s, 8 = 1.67s
103 | #define NPIXELS 8 // Must be integer division of both TFT width and TFT height
104 |
105 | class ScreenServer
106 | {
107 | public:
108 | /**
109 | * @brief Start a screen dump server - no filename specified
110 | *
111 | * @param tft TFT_eSPI instance to print
112 | * @return true if image is sent properly otherwise it returns false
113 | */
114 | static bool screenServer(TFT_eSPI& tft);
115 |
116 | /**
117 | * @brief Start a screen dump server - filename specified
118 | *
119 | * @param filename Name of the saved image
120 | * @param tft TFT_eSPI instance to print
121 | * @return true if image is sent properly otherwise it returns false
122 | */
123 | static bool screenServer(String filename, TFT_eSPI& tft);
124 |
125 | /**
126 | * @brief Send screen size etc using a simple header with delimiters for client checks
127 | *
128 | * @param filename Name of the saved image
129 | * @param tft TFT_eSPI instance to print
130 | */
131 | static void sendParameters(String filename, TFT_eSPI& tft);
132 | };
133 |
134 | #define PRINT_SCR(tft) ScreenServer::screenServer(tft);
135 | #else
136 | #define PRINT_SCR(tft)
137 | #endif
138 |
139 | #endif
140 |
--------------------------------------------------------------------------------
/partitions_two_ota_SPIFFS.csv:
--------------------------------------------------------------------------------
1 | # Name, Type, SubType, Offset, Size, Flags
2 | # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 | nvs, data, nvs, , 0x4000,
4 | otadata, data, ota, , 0x2000,
5 | phy_init, data, phy, , 0x1000,
6 | factory, app, factory, , 1500K,
7 | ota_0, app, ota_0, , 1500K,
8 | ota_1, app, ota_1, , 1500K,
9 | storage, data, spiffs, , 500K,
10 |
--------------------------------------------------------------------------------