diff --git a/.cproject b/.cproject
index e693ff0..df4b438 100644
--- a/.cproject
+++ b/.cproject
@@ -24,6 +24,7 @@
+
@@ -39,6 +40,10 @@
+
+
+
@@ -71,7 +124,14 @@
-
+
+
+
+
+
+
+
+
@@ -109,27 +169,27 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
-
-
-
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
@@ -179,6 +268,7 @@
+
@@ -187,11 +277,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
index 2938e6d..d3119fd 100644
--- a/.project
+++ b/.project
@@ -28,5 +28,6 @@
com.st.stm32cube.ide.mcu.MCURootProjectNature
org.eclipse.cdt.managedbuilder.core.managedBuildNature
org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ org.eclipse.cdt.core.ccnature
diff --git a/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs b/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
new file mode 100644
index 0000000..76abb92
--- /dev/null
+++ b/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+svd_custom_file_path=
+svd_file_path=platform\:/plugin/com.st.stm32cube.ide.mcu.productdb.debug/resources/cmsis/STMicroelectronics_CMSIS_SVD/STM32L496.svd
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index 75dc854..e6bf7e2 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,7 +5,7 @@
-
+
@@ -16,7 +16,7 @@
-
+
diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..2e279ce
--- /dev/null
+++ b/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,74 @@
+com.st.stm32cube.ide.mcu.ide.oss.source.checker.libnano.problem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Float formatting support\\")"}
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
+org.eclipse.cdt.codan.checkers.localvarreturn=-Warning
+org.eclipse.cdt.codan.checkers.localvarreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Returning the address of a local variable\\")"}
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
+org.eclipse.cdt.codan.internal.checkers.BlacklistProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.BlacklistProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function or method is blacklisted\\")",blacklist\=>()}
+org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"C-Style cast instead of C++ cast\\")",checkMacro\=>true}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.CopyrightProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.CopyrightProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Lack of copyright information\\")",regex\=>".*Copyright.*"}
+org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.FloatCompareProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.FloatCompareProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Direct float comparison\\")"}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Goto statement used\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MagicNumberProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MagicNumberProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Avoid magic numbers\\")",checkArray\=>true,checkOperatorParen\=>true,exceptions\=>(1,0,-1,2,1.0,0.0,-1.0)}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.MissCaseProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissCaseProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing cases in switch\\")"}
+org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing default in switch\\")",defaultWithAllEnums\=>false}
+org.eclipse.cdt.codan.internal.checkers.MissReferenceProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing reference return value in assignment operator\\")"}
+org.eclipse.cdt.codan.internal.checkers.MissSelfCheckProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissSelfCheckProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing self check in assignment operator\\")"}
+org.eclipse.cdt.codan.internal.checkers.MultipleDeclarationsProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MultipleDeclarationsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Multiple variable declaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NoDiscardProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NoDiscardProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return value not evaluated\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
+org.eclipse.cdt.codan.internal.checkers.ShallowCopyProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ShallowCopyProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Miss copy constructor or assignment operator\\")",onlynew\=>false}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.StaticVariableInHeaderProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.StaticVariableInHeaderProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Static variable in header file\\")"}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.SymbolShadowingProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.SymbolShadowingProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol shadowing\\")",paramFuncParameters\=>true}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Using directive in header\\")"}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Virtual method call in constructor/destructor\\")"}
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
new file mode 100644
index 0000000..c8ec5df
--- /dev/null
+++ b/.settings/org.eclipse.cdt.core.prefs
@@ -0,0 +1,6 @@
+doxygen/doxygen_new_line_after_brief=true
+doxygen/doxygen_use_brief_tag=false
+doxygen/doxygen_use_javadoc_tags=true
+doxygen/doxygen_use_pre_tag=false
+doxygen/doxygen_use_structural_commands=false
+eclipse.preferences.version=1
diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..b196c64
--- /dev/null
+++ b/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/Debug/Core/Src/subdir.mk b/Debug/Core/Src/subdir.mk
index 1354904..ce93510 100644
--- a/Debug/Core/Src/subdir.mk
+++ b/Debug/Core/Src/subdir.mk
@@ -27,29 +27,6 @@ C_SRCS += \
../Core/Src/tim.c \
../Core/Src/usart.c
-OBJS += \
-./Core/Src/adc.o \
-./Core/Src/crc.o \
-./Core/Src/dma2d.o \
-./Core/Src/fmc.o \
-./Core/Src/freertos.o \
-./Core/Src/gpio.o \
-./Core/Src/i2c.o \
-./Core/Src/lcd.o \
-./Core/Src/main.o \
-./Core/Src/quadspi.o \
-./Core/Src/sai.o \
-./Core/Src/sdmmc.o \
-./Core/Src/spi.o \
-./Core/Src/stm32l4xx_hal_msp.o \
-./Core/Src/stm32l4xx_hal_timebase_tim.o \
-./Core/Src/stm32l4xx_it.o \
-./Core/Src/syscalls.o \
-./Core/Src/sysmem.o \
-./Core/Src/system_stm32l4xx.o \
-./Core/Src/tim.o \
-./Core/Src/usart.o
-
C_DEPS += \
./Core/Src/adc.d \
./Core/Src/crc.d \
@@ -73,10 +50,33 @@ C_DEPS += \
./Core/Src/tim.d \
./Core/Src/usart.d
+OBJS += \
+./Core/Src/adc.o \
+./Core/Src/crc.o \
+./Core/Src/dma2d.o \
+./Core/Src/fmc.o \
+./Core/Src/freertos.o \
+./Core/Src/gpio.o \
+./Core/Src/i2c.o \
+./Core/Src/lcd.o \
+./Core/Src/main.o \
+./Core/Src/quadspi.o \
+./Core/Src/sai.o \
+./Core/Src/sdmmc.o \
+./Core/Src/spi.o \
+./Core/Src/stm32l4xx_hal_msp.o \
+./Core/Src/stm32l4xx_hal_timebase_tim.o \
+./Core/Src/stm32l4xx_it.o \
+./Core/Src/syscalls.o \
+./Core/Src/sysmem.o \
+./Core/Src/system_stm32l4xx.o \
+./Core/Src/tim.o \
+./Core/Src/usart.o
+
# Each subdirectory must supply rules for building sources it contributes
Core/Src/%.o Core/Src/%.su: ../Core/Src/%.c Core/Src/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Core-2f-Src
diff --git a/Debug/Core/Startup/subdir.mk b/Debug/Core/Startup/subdir.mk
index d2092df..0b4468f 100644
--- a/Debug/Core/Startup/subdir.mk
+++ b/Debug/Core/Startup/subdir.mk
@@ -7,12 +7,12 @@
S_SRCS += \
../Core/Startup/startup_stm32l496agix.s
-OBJS += \
-./Core/Startup/startup_stm32l496agix.o
-
S_DEPS += \
./Core/Startup/startup_stm32l496agix.d
+OBJS += \
+./Core/Startup/startup_stm32l496agix.o
+
# Each subdirectory must supply rules for building sources it contributes
Core/Startup/%.o: ../Core/Startup/%.s Core/Startup/subdir.mk
diff --git a/Debug/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk b/Debug/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
index 30fa255..c8a83e4 100644
--- a/Debug/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
+++ b/Debug/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
@@ -44,46 +44,6 @@ C_SRCS += \
../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.c \
../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c
-OBJS += \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma2d.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lcd.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sram.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_fmc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.o
-
C_DEPS += \
./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.d \
./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.d \
@@ -124,10 +84,50 @@ C_DEPS += \
./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.d \
./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.d
+OBJS += \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma2d.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lcd.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sram.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_fmc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.o \
+./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.o
+
# Each subdirectory must supply rules for building sources it contributes
Drivers/STM32L4xx_HAL_Driver/Src/%.o Drivers/STM32L4xx_HAL_Driver/Src/%.su: ../Drivers/STM32L4xx_HAL_Driver/Src/%.c Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Drivers-2f-STM32L4xx_HAL_Driver-2f-Src
diff --git a/Debug/FATFS/App/subdir.mk b/Debug/FATFS/App/subdir.mk
index 3a176a1..cb01e05 100644
--- a/Debug/FATFS/App/subdir.mk
+++ b/Debug/FATFS/App/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../FATFS/App/fatfs.c
-OBJS += \
-./FATFS/App/fatfs.o
-
C_DEPS += \
./FATFS/App/fatfs.d
+OBJS += \
+./FATFS/App/fatfs.o
+
# Each subdirectory must supply rules for building sources it contributes
FATFS/App/%.o FATFS/App/%.su: ../FATFS/App/%.c FATFS/App/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-FATFS-2f-App
diff --git a/Debug/FATFS/Target/subdir.mk b/Debug/FATFS/Target/subdir.mk
index 748bca0..b95d09e 100644
--- a/Debug/FATFS/Target/subdir.mk
+++ b/Debug/FATFS/Target/subdir.mk
@@ -9,20 +9,20 @@ C_SRCS += \
../FATFS/Target/fatfs_platform.c \
../FATFS/Target/sd_diskio.c
-OBJS += \
-./FATFS/Target/bsp_driver_sd.o \
-./FATFS/Target/fatfs_platform.o \
-./FATFS/Target/sd_diskio.o
-
C_DEPS += \
./FATFS/Target/bsp_driver_sd.d \
./FATFS/Target/fatfs_platform.d \
./FATFS/Target/sd_diskio.d
+OBJS += \
+./FATFS/Target/bsp_driver_sd.o \
+./FATFS/Target/fatfs_platform.o \
+./FATFS/Target/sd_diskio.o
+
# Each subdirectory must supply rules for building sources it contributes
FATFS/Target/%.o FATFS/Target/%.su: ../FATFS/Target/%.c FATFS/Target/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-FATFS-2f-Target
diff --git a/Debug/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/subdir.mk b/Debug/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/subdir.mk
index b1e484e..c6c7aaa 100644
--- a/Debug/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/subdir.mk
+++ b/Debug/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
-OBJS += \
-./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.o
-
C_DEPS += \
./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.d
+OBJS += \
+./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/%.o Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/%.su: ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/%.c Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-ST-2f-STM32_USB_Device_Library-2f-Class-2f-CDC-2f-Src
diff --git a/Debug/Middlewares/ST/STM32_USB_Device_Library/Core/Src/subdir.mk b/Debug/Middlewares/ST/STM32_USB_Device_Library/Core/Src/subdir.mk
index ca2f57b..1426e54 100644
--- a/Debug/Middlewares/ST/STM32_USB_Device_Library/Core/Src/subdir.mk
+++ b/Debug/Middlewares/ST/STM32_USB_Device_Library/Core/Src/subdir.mk
@@ -9,20 +9,20 @@ C_SRCS += \
../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \
../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
-OBJS += \
-./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.o \
-./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.o \
-./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.o
-
C_DEPS += \
./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.d \
./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.d \
./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.d
+OBJS += \
+./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.o \
+./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.o \
+./Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/ST/STM32_USB_Device_Library/Core/Src/%.o Middlewares/ST/STM32_USB_Device_Library/Core/Src/%.su: ../Middlewares/ST/STM32_USB_Device_Library/Core/Src/%.c Middlewares/ST/STM32_USB_Device_Library/Core/Src/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-ST-2f-STM32_USB_Device_Library-2f-Core-2f-Src
diff --git a/Debug/Middlewares/Third_Party/FatFs/src/option/subdir.mk b/Debug/Middlewares/Third_Party/FatFs/src/option/subdir.mk
index 93a7460..e11c42e 100644
--- a/Debug/Middlewares/Third_Party/FatFs/src/option/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FatFs/src/option/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../Middlewares/Third_Party/FatFs/src/option/syscall.c
-OBJS += \
-./Middlewares/Third_Party/FatFs/src/option/syscall.o
-
C_DEPS += \
./Middlewares/Third_Party/FatFs/src/option/syscall.d
+OBJS += \
+./Middlewares/Third_Party/FatFs/src/option/syscall.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FatFs/src/option/%.o Middlewares/Third_Party/FatFs/src/option/%.su: ../Middlewares/Third_Party/FatFs/src/option/%.c Middlewares/Third_Party/FatFs/src/option/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FatFs-2f-src-2f-option
diff --git a/Debug/Middlewares/Third_Party/FatFs/src/subdir.mk b/Debug/Middlewares/Third_Party/FatFs/src/subdir.mk
index 14de317..cd7f813 100644
--- a/Debug/Middlewares/Third_Party/FatFs/src/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FatFs/src/subdir.mk
@@ -9,20 +9,20 @@ C_SRCS += \
../Middlewares/Third_Party/FatFs/src/ff.c \
../Middlewares/Third_Party/FatFs/src/ff_gen_drv.c
-OBJS += \
-./Middlewares/Third_Party/FatFs/src/diskio.o \
-./Middlewares/Third_Party/FatFs/src/ff.o \
-./Middlewares/Third_Party/FatFs/src/ff_gen_drv.o
-
C_DEPS += \
./Middlewares/Third_Party/FatFs/src/diskio.d \
./Middlewares/Third_Party/FatFs/src/ff.d \
./Middlewares/Third_Party/FatFs/src/ff_gen_drv.d
+OBJS += \
+./Middlewares/Third_Party/FatFs/src/diskio.o \
+./Middlewares/Third_Party/FatFs/src/ff.o \
+./Middlewares/Third_Party/FatFs/src/ff_gen_drv.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FatFs/src/%.o Middlewares/Third_Party/FatFs/src/%.su: ../Middlewares/Third_Party/FatFs/src/%.c Middlewares/Third_Party/FatFs/src/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FatFs-2f-src
diff --git a/Debug/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk b/Debug/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
index 9f52bc0..aba7136 100644
--- a/Debug/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c
-OBJS += \
-./Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.o
-
C_DEPS += \
./Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.d
+OBJS += \
+./Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/%.o Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/%.su: ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/%.c Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FreeRTOS-2f-Source-2f-CMSIS_RTOS_V2
diff --git a/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk b/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
index 065de35..65d628b 100644
--- a/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
-OBJS += \
-./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.o
-
C_DEPS += \
./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.d
+OBJS += \
+./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/%.o Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/%.su: ../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/%.c Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FreeRTOS-2f-Source-2f-portable-2f-GCC-2f-ARM_CM4F
diff --git a/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk b/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
index aaf898f..216bce6 100644
--- a/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c
-OBJS += \
-./Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.o
-
C_DEPS += \
./Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.d
+OBJS += \
+./Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/%.o Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/%.su: ../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/%.c Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FreeRTOS-2f-Source-2f-portable-2f-MemMang
diff --git a/Debug/Middlewares/Third_Party/FreeRTOS/Source/subdir.mk b/Debug/Middlewares/Third_Party/FreeRTOS/Source/subdir.mk
index 0429d23..c10c23a 100644
--- a/Debug/Middlewares/Third_Party/FreeRTOS/Source/subdir.mk
+++ b/Debug/Middlewares/Third_Party/FreeRTOS/Source/subdir.mk
@@ -13,15 +13,6 @@ C_SRCS += \
../Middlewares/Third_Party/FreeRTOS/Source/tasks.c \
../Middlewares/Third_Party/FreeRTOS/Source/timers.c
-OBJS += \
-./Middlewares/Third_Party/FreeRTOS/Source/croutine.o \
-./Middlewares/Third_Party/FreeRTOS/Source/event_groups.o \
-./Middlewares/Third_Party/FreeRTOS/Source/list.o \
-./Middlewares/Third_Party/FreeRTOS/Source/queue.o \
-./Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.o \
-./Middlewares/Third_Party/FreeRTOS/Source/tasks.o \
-./Middlewares/Third_Party/FreeRTOS/Source/timers.o
-
C_DEPS += \
./Middlewares/Third_Party/FreeRTOS/Source/croutine.d \
./Middlewares/Third_Party/FreeRTOS/Source/event_groups.d \
@@ -31,10 +22,19 @@ C_DEPS += \
./Middlewares/Third_Party/FreeRTOS/Source/tasks.d \
./Middlewares/Third_Party/FreeRTOS/Source/timers.d
+OBJS += \
+./Middlewares/Third_Party/FreeRTOS/Source/croutine.o \
+./Middlewares/Third_Party/FreeRTOS/Source/event_groups.o \
+./Middlewares/Third_Party/FreeRTOS/Source/list.o \
+./Middlewares/Third_Party/FreeRTOS/Source/queue.o \
+./Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.o \
+./Middlewares/Third_Party/FreeRTOS/Source/tasks.o \
+./Middlewares/Third_Party/FreeRTOS/Source/timers.o
+
# Each subdirectory must supply rules for building sources it contributes
Middlewares/Third_Party/FreeRTOS/Source/%.o Middlewares/Third_Party/FreeRTOS/Source/%.su: ../Middlewares/Third_Party/FreeRTOS/Source/%.c Middlewares/Third_Party/FreeRTOS/Source/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-Middlewares-2f-Third_Party-2f-FreeRTOS-2f-Source
diff --git a/Debug/Middlewares/eez/core/subdir.mk b/Debug/Middlewares/eez/core/subdir.mk
new file mode 100644
index 0000000..e91e82d
--- /dev/null
+++ b/Debug/Middlewares/eez/core/subdir.mk
@@ -0,0 +1,48 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/core/alloc.cpp \
+../Middlewares/eez/core/debug.cpp \
+../Middlewares/eez/core/eeprom.cpp \
+../Middlewares/eez/core/hmi.cpp \
+../Middlewares/eez/core/memory.cpp \
+../Middlewares/eez/core/os.cpp \
+../Middlewares/eez/core/unit.cpp \
+../Middlewares/eez/core/util.cpp
+
+OBJS += \
+./Middlewares/eez/core/alloc.o \
+./Middlewares/eez/core/debug.o \
+./Middlewares/eez/core/eeprom.o \
+./Middlewares/eez/core/hmi.o \
+./Middlewares/eez/core/memory.o \
+./Middlewares/eez/core/os.o \
+./Middlewares/eez/core/unit.o \
+./Middlewares/eez/core/util.o
+
+CPP_DEPS += \
+./Middlewares/eez/core/alloc.d \
+./Middlewares/eez/core/debug.d \
+./Middlewares/eez/core/eeprom.d \
+./Middlewares/eez/core/hmi.d \
+./Middlewares/eez/core/memory.d \
+./Middlewares/eez/core/os.d \
+./Middlewares/eez/core/unit.d \
+./Middlewares/eez/core/util.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/core/%.o Middlewares/eez/core/%.su: ../Middlewares/eez/core/%.cpp Middlewares/eez/core/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-core
+
+clean-Middlewares-2f-eez-2f-core:
+ -$(RM) ./Middlewares/eez/core/alloc.d ./Middlewares/eez/core/alloc.o ./Middlewares/eez/core/alloc.su ./Middlewares/eez/core/debug.d ./Middlewares/eez/core/debug.o ./Middlewares/eez/core/debug.su ./Middlewares/eez/core/eeprom.d ./Middlewares/eez/core/eeprom.o ./Middlewares/eez/core/eeprom.su ./Middlewares/eez/core/hmi.d ./Middlewares/eez/core/hmi.o ./Middlewares/eez/core/hmi.su ./Middlewares/eez/core/memory.d ./Middlewares/eez/core/memory.o ./Middlewares/eez/core/memory.su ./Middlewares/eez/core/os.d ./Middlewares/eez/core/os.o ./Middlewares/eez/core/os.su ./Middlewares/eez/core/unit.d ./Middlewares/eez/core/unit.o ./Middlewares/eez/core/unit.su ./Middlewares/eez/core/util.d ./Middlewares/eez/core/util.o ./Middlewares/eez/core/util.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-core
+
diff --git a/Debug/Middlewares/eez/flow/components/subdir.mk b/Debug/Middlewares/eez/flow/components/subdir.mk
new file mode 100644
index 0000000..693368c
--- /dev/null
+++ b/Debug/Middlewares/eez/flow/components/subdir.mk
@@ -0,0 +1,111 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/flow/components/animate.cpp \
+../Middlewares/eez/flow/components/call_action.cpp \
+../Middlewares/eez/flow/components/catch_error.cpp \
+../Middlewares/eez/flow/components/compare.cpp \
+../Middlewares/eez/flow/components/constant.cpp \
+../Middlewares/eez/flow/components/counter.cpp \
+../Middlewares/eez/flow/components/delay.cpp \
+../Middlewares/eez/flow/components/end.cpp \
+../Middlewares/eez/flow/components/error.cpp \
+../Middlewares/eez/flow/components/expr_eval.cpp \
+../Middlewares/eez/flow/components/input.cpp \
+../Middlewares/eez/flow/components/is_true.cpp \
+../Middlewares/eez/flow/components/layout_view_widget.cpp \
+../Middlewares/eez/flow/components/log.cpp \
+../Middlewares/eez/flow/components/loop.cpp \
+../Middlewares/eez/flow/components/noop.cpp \
+../Middlewares/eez/flow/components/on_event.cpp \
+../Middlewares/eez/flow/components/output.cpp \
+../Middlewares/eez/flow/components/roller_widget.cpp \
+../Middlewares/eez/flow/components/select_language.cpp \
+../Middlewares/eez/flow/components/set_page_direction.cpp \
+../Middlewares/eez/flow/components/set_variable.cpp \
+../Middlewares/eez/flow/components/show_keyboard.cpp \
+../Middlewares/eez/flow/components/show_keypad.cpp \
+../Middlewares/eez/flow/components/show_message_box.cpp \
+../Middlewares/eez/flow/components/show_page.cpp \
+../Middlewares/eez/flow/components/start.cpp \
+../Middlewares/eez/flow/components/switch.cpp \
+../Middlewares/eez/flow/components/watch_variable.cpp
+
+OBJS += \
+./Middlewares/eez/flow/components/animate.o \
+./Middlewares/eez/flow/components/call_action.o \
+./Middlewares/eez/flow/components/catch_error.o \
+./Middlewares/eez/flow/components/compare.o \
+./Middlewares/eez/flow/components/constant.o \
+./Middlewares/eez/flow/components/counter.o \
+./Middlewares/eez/flow/components/delay.o \
+./Middlewares/eez/flow/components/end.o \
+./Middlewares/eez/flow/components/error.o \
+./Middlewares/eez/flow/components/expr_eval.o \
+./Middlewares/eez/flow/components/input.o \
+./Middlewares/eez/flow/components/is_true.o \
+./Middlewares/eez/flow/components/layout_view_widget.o \
+./Middlewares/eez/flow/components/log.o \
+./Middlewares/eez/flow/components/loop.o \
+./Middlewares/eez/flow/components/noop.o \
+./Middlewares/eez/flow/components/on_event.o \
+./Middlewares/eez/flow/components/output.o \
+./Middlewares/eez/flow/components/roller_widget.o \
+./Middlewares/eez/flow/components/select_language.o \
+./Middlewares/eez/flow/components/set_page_direction.o \
+./Middlewares/eez/flow/components/set_variable.o \
+./Middlewares/eez/flow/components/show_keyboard.o \
+./Middlewares/eez/flow/components/show_keypad.o \
+./Middlewares/eez/flow/components/show_message_box.o \
+./Middlewares/eez/flow/components/show_page.o \
+./Middlewares/eez/flow/components/start.o \
+./Middlewares/eez/flow/components/switch.o \
+./Middlewares/eez/flow/components/watch_variable.o
+
+CPP_DEPS += \
+./Middlewares/eez/flow/components/animate.d \
+./Middlewares/eez/flow/components/call_action.d \
+./Middlewares/eez/flow/components/catch_error.d \
+./Middlewares/eez/flow/components/compare.d \
+./Middlewares/eez/flow/components/constant.d \
+./Middlewares/eez/flow/components/counter.d \
+./Middlewares/eez/flow/components/delay.d \
+./Middlewares/eez/flow/components/end.d \
+./Middlewares/eez/flow/components/error.d \
+./Middlewares/eez/flow/components/expr_eval.d \
+./Middlewares/eez/flow/components/input.d \
+./Middlewares/eez/flow/components/is_true.d \
+./Middlewares/eez/flow/components/layout_view_widget.d \
+./Middlewares/eez/flow/components/log.d \
+./Middlewares/eez/flow/components/loop.d \
+./Middlewares/eez/flow/components/noop.d \
+./Middlewares/eez/flow/components/on_event.d \
+./Middlewares/eez/flow/components/output.d \
+./Middlewares/eez/flow/components/roller_widget.d \
+./Middlewares/eez/flow/components/select_language.d \
+./Middlewares/eez/flow/components/set_page_direction.d \
+./Middlewares/eez/flow/components/set_variable.d \
+./Middlewares/eez/flow/components/show_keyboard.d \
+./Middlewares/eez/flow/components/show_keypad.d \
+./Middlewares/eez/flow/components/show_message_box.d \
+./Middlewares/eez/flow/components/show_page.d \
+./Middlewares/eez/flow/components/start.d \
+./Middlewares/eez/flow/components/switch.d \
+./Middlewares/eez/flow/components/watch_variable.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/flow/components/%.o Middlewares/eez/flow/components/%.su: ../Middlewares/eez/flow/components/%.cpp Middlewares/eez/flow/components/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-flow-2f-components
+
+clean-Middlewares-2f-eez-2f-flow-2f-components:
+ -$(RM) ./Middlewares/eez/flow/components/animate.d ./Middlewares/eez/flow/components/animate.o ./Middlewares/eez/flow/components/animate.su ./Middlewares/eez/flow/components/call_action.d ./Middlewares/eez/flow/components/call_action.o ./Middlewares/eez/flow/components/call_action.su ./Middlewares/eez/flow/components/catch_error.d ./Middlewares/eez/flow/components/catch_error.o ./Middlewares/eez/flow/components/catch_error.su ./Middlewares/eez/flow/components/compare.d ./Middlewares/eez/flow/components/compare.o ./Middlewares/eez/flow/components/compare.su ./Middlewares/eez/flow/components/constant.d ./Middlewares/eez/flow/components/constant.o ./Middlewares/eez/flow/components/constant.su ./Middlewares/eez/flow/components/counter.d ./Middlewares/eez/flow/components/counter.o ./Middlewares/eez/flow/components/counter.su ./Middlewares/eez/flow/components/delay.d ./Middlewares/eez/flow/components/delay.o ./Middlewares/eez/flow/components/delay.su ./Middlewares/eez/flow/components/end.d ./Middlewares/eez/flow/components/end.o ./Middlewares/eez/flow/components/end.su ./Middlewares/eez/flow/components/error.d ./Middlewares/eez/flow/components/error.o ./Middlewares/eez/flow/components/error.su ./Middlewares/eez/flow/components/expr_eval.d ./Middlewares/eez/flow/components/expr_eval.o ./Middlewares/eez/flow/components/expr_eval.su ./Middlewares/eez/flow/components/input.d ./Middlewares/eez/flow/components/input.o ./Middlewares/eez/flow/components/input.su ./Middlewares/eez/flow/components/is_true.d ./Middlewares/eez/flow/components/is_true.o ./Middlewares/eez/flow/components/is_true.su ./Middlewares/eez/flow/components/layout_view_widget.d ./Middlewares/eez/flow/components/layout_view_widget.o ./Middlewares/eez/flow/components/layout_view_widget.su ./Middlewares/eez/flow/components/log.d ./Middlewares/eez/flow/components/log.o ./Middlewares/eez/flow/components/log.su ./Middlewares/eez/flow/components/loop.d ./Middlewares/eez/flow/components/loop.o ./Middlewares/eez/flow/components/loop.su ./Middlewares/eez/flow/components/noop.d ./Middlewares/eez/flow/components/noop.o ./Middlewares/eez/flow/components/noop.su ./Middlewares/eez/flow/components/on_event.d ./Middlewares/eez/flow/components/on_event.o ./Middlewares/eez/flow/components/on_event.su ./Middlewares/eez/flow/components/output.d ./Middlewares/eez/flow/components/output.o ./Middlewares/eez/flow/components/output.su ./Middlewares/eez/flow/components/roller_widget.d ./Middlewares/eez/flow/components/roller_widget.o ./Middlewares/eez/flow/components/roller_widget.su ./Middlewares/eez/flow/components/select_language.d ./Middlewares/eez/flow/components/select_language.o ./Middlewares/eez/flow/components/select_language.su ./Middlewares/eez/flow/components/set_page_direction.d ./Middlewares/eez/flow/components/set_page_direction.o ./Middlewares/eez/flow/components/set_page_direction.su ./Middlewares/eez/flow/components/set_variable.d ./Middlewares/eez/flow/components/set_variable.o ./Middlewares/eez/flow/components/set_variable.su ./Middlewares/eez/flow/components/show_keyboard.d ./Middlewares/eez/flow/components/show_keyboard.o ./Middlewares/eez/flow/components/show_keyboard.su ./Middlewares/eez/flow/components/show_keypad.d ./Middlewares/eez/flow/components/show_keypad.o ./Middlewares/eez/flow/components/show_keypad.su ./Middlewares/eez/flow/components/show_message_box.d ./Middlewares/eez/flow/components/show_message_box.o ./Middlewares/eez/flow/components/show_message_box.su ./Middlewares/eez/flow/components/show_page.d ./Middlewares/eez/flow/components/show_page.o ./Middlewares/eez/flow/components/show_page.su ./Middlewares/eez/flow/components/start.d ./Middlewares/eez/flow/components/start.o ./Middlewares/eez/flow/components/start.su ./Middlewares/eez/flow/components/switch.d ./Middlewares/eez/flow/components/switch.o ./Middlewares/eez/flow/components/switch.su ./Middlewares/eez/flow/components/watch_variable.d ./Middlewares/eez/flow/components/watch_variable.o ./Middlewares/eez/flow/components/watch_variable.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-flow-2f-components
+
diff --git a/Debug/Middlewares/eez/flow/subdir.mk b/Debug/Middlewares/eez/flow/subdir.mk
new file mode 100644
index 0000000..c539b49
--- /dev/null
+++ b/Debug/Middlewares/eez/flow/subdir.mk
@@ -0,0 +1,51 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/flow/components.cpp \
+../Middlewares/eez/flow/dashboard_api.cpp \
+../Middlewares/eez/flow/debugger.cpp \
+../Middlewares/eez/flow/expression.cpp \
+../Middlewares/eez/flow/flow.cpp \
+../Middlewares/eez/flow/hooks.cpp \
+../Middlewares/eez/flow/operations.cpp \
+../Middlewares/eez/flow/private.cpp \
+../Middlewares/eez/flow/queue.cpp
+
+OBJS += \
+./Middlewares/eez/flow/components.o \
+./Middlewares/eez/flow/dashboard_api.o \
+./Middlewares/eez/flow/debugger.o \
+./Middlewares/eez/flow/expression.o \
+./Middlewares/eez/flow/flow.o \
+./Middlewares/eez/flow/hooks.o \
+./Middlewares/eez/flow/operations.o \
+./Middlewares/eez/flow/private.o \
+./Middlewares/eez/flow/queue.o
+
+CPP_DEPS += \
+./Middlewares/eez/flow/components.d \
+./Middlewares/eez/flow/dashboard_api.d \
+./Middlewares/eez/flow/debugger.d \
+./Middlewares/eez/flow/expression.d \
+./Middlewares/eez/flow/flow.d \
+./Middlewares/eez/flow/hooks.d \
+./Middlewares/eez/flow/operations.d \
+./Middlewares/eez/flow/private.d \
+./Middlewares/eez/flow/queue.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/flow/%.o Middlewares/eez/flow/%.su: ../Middlewares/eez/flow/%.cpp Middlewares/eez/flow/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-flow
+
+clean-Middlewares-2f-eez-2f-flow:
+ -$(RM) ./Middlewares/eez/flow/components.d ./Middlewares/eez/flow/components.o ./Middlewares/eez/flow/components.su ./Middlewares/eez/flow/dashboard_api.d ./Middlewares/eez/flow/dashboard_api.o ./Middlewares/eez/flow/dashboard_api.su ./Middlewares/eez/flow/debugger.d ./Middlewares/eez/flow/debugger.o ./Middlewares/eez/flow/debugger.su ./Middlewares/eez/flow/expression.d ./Middlewares/eez/flow/expression.o ./Middlewares/eez/flow/expression.su ./Middlewares/eez/flow/flow.d ./Middlewares/eez/flow/flow.o ./Middlewares/eez/flow/flow.su ./Middlewares/eez/flow/hooks.d ./Middlewares/eez/flow/hooks.o ./Middlewares/eez/flow/hooks.su ./Middlewares/eez/flow/operations.d ./Middlewares/eez/flow/operations.o ./Middlewares/eez/flow/operations.su ./Middlewares/eez/flow/private.d ./Middlewares/eez/flow/private.o ./Middlewares/eez/flow/private.su ./Middlewares/eez/flow/queue.d ./Middlewares/eez/flow/queue.o ./Middlewares/eez/flow/queue.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-flow
+
diff --git a/Debug/Middlewares/eez/fs/simulator/subdir.mk b/Debug/Middlewares/eez/fs/simulator/subdir.mk
new file mode 100644
index 0000000..b04377a
--- /dev/null
+++ b/Debug/Middlewares/eez/fs/simulator/subdir.mk
@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/fs/simulator/fs.cpp
+
+OBJS += \
+./Middlewares/eez/fs/simulator/fs.o
+
+CPP_DEPS += \
+./Middlewares/eez/fs/simulator/fs.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/fs/simulator/%.o Middlewares/eez/fs/simulator/%.su: ../Middlewares/eez/fs/simulator/%.cpp Middlewares/eez/fs/simulator/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-fs-2f-simulator
+
+clean-Middlewares-2f-eez-2f-fs-2f-simulator:
+ -$(RM) ./Middlewares/eez/fs/simulator/fs.d ./Middlewares/eez/fs/simulator/fs.o ./Middlewares/eez/fs/simulator/fs.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-fs-2f-simulator
+
diff --git a/Debug/Middlewares/eez/fs/stm32/subdir.mk b/Debug/Middlewares/eez/fs/stm32/subdir.mk
new file mode 100644
index 0000000..9113d1a
--- /dev/null
+++ b/Debug/Middlewares/eez/fs/stm32/subdir.mk
@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/fs/stm32/fs.cpp
+
+OBJS += \
+./Middlewares/eez/fs/stm32/fs.o
+
+CPP_DEPS += \
+./Middlewares/eez/fs/stm32/fs.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/fs/stm32/%.o Middlewares/eez/fs/stm32/%.su: ../Middlewares/eez/fs/stm32/%.cpp Middlewares/eez/fs/stm32/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-fs-2f-stm32
+
+clean-Middlewares-2f-eez-2f-fs-2f-stm32:
+ -$(RM) ./Middlewares/eez/fs/stm32/fs.d ./Middlewares/eez/fs/stm32/fs.o ./Middlewares/eez/fs/stm32/fs.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-fs-2f-stm32
+
diff --git a/Debug/Middlewares/eez/gui/subdir.mk b/Debug/Middlewares/eez/gui/subdir.mk
new file mode 100644
index 0000000..97c479e
--- /dev/null
+++ b/Debug/Middlewares/eez/gui/subdir.mk
@@ -0,0 +1,90 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/gui/action_impl.cpp \
+../Middlewares/eez/gui/animation.cpp \
+../Middlewares/eez/gui/app_context.cpp \
+../Middlewares/eez/gui/assets.cpp \
+../Middlewares/eez/gui/assets_fix_offsets.cpp \
+../Middlewares/eez/gui/data.cpp \
+../Middlewares/eez/gui/display.cpp \
+../Middlewares/eez/gui/draw.cpp \
+../Middlewares/eez/gui/event.cpp \
+../Middlewares/eez/gui/font.cpp \
+../Middlewares/eez/gui/geometry.cpp \
+../Middlewares/eez/gui/gui.cpp \
+../Middlewares/eez/gui/hooks.cpp \
+../Middlewares/eez/gui/keypad.cpp \
+../Middlewares/eez/gui/overlay.cpp \
+../Middlewares/eez/gui/page.cpp \
+../Middlewares/eez/gui/thread.cpp \
+../Middlewares/eez/gui/touch.cpp \
+../Middlewares/eez/gui/touch_calibration.cpp \
+../Middlewares/eez/gui/touch_filter.cpp \
+../Middlewares/eez/gui/update.cpp \
+../Middlewares/eez/gui/widget.cpp
+
+OBJS += \
+./Middlewares/eez/gui/action_impl.o \
+./Middlewares/eez/gui/animation.o \
+./Middlewares/eez/gui/app_context.o \
+./Middlewares/eez/gui/assets.o \
+./Middlewares/eez/gui/assets_fix_offsets.o \
+./Middlewares/eez/gui/data.o \
+./Middlewares/eez/gui/display.o \
+./Middlewares/eez/gui/draw.o \
+./Middlewares/eez/gui/event.o \
+./Middlewares/eez/gui/font.o \
+./Middlewares/eez/gui/geometry.o \
+./Middlewares/eez/gui/gui.o \
+./Middlewares/eez/gui/hooks.o \
+./Middlewares/eez/gui/keypad.o \
+./Middlewares/eez/gui/overlay.o \
+./Middlewares/eez/gui/page.o \
+./Middlewares/eez/gui/thread.o \
+./Middlewares/eez/gui/touch.o \
+./Middlewares/eez/gui/touch_calibration.o \
+./Middlewares/eez/gui/touch_filter.o \
+./Middlewares/eez/gui/update.o \
+./Middlewares/eez/gui/widget.o
+
+CPP_DEPS += \
+./Middlewares/eez/gui/action_impl.d \
+./Middlewares/eez/gui/animation.d \
+./Middlewares/eez/gui/app_context.d \
+./Middlewares/eez/gui/assets.d \
+./Middlewares/eez/gui/assets_fix_offsets.d \
+./Middlewares/eez/gui/data.d \
+./Middlewares/eez/gui/display.d \
+./Middlewares/eez/gui/draw.d \
+./Middlewares/eez/gui/event.d \
+./Middlewares/eez/gui/font.d \
+./Middlewares/eez/gui/geometry.d \
+./Middlewares/eez/gui/gui.d \
+./Middlewares/eez/gui/hooks.d \
+./Middlewares/eez/gui/keypad.d \
+./Middlewares/eez/gui/overlay.d \
+./Middlewares/eez/gui/page.d \
+./Middlewares/eez/gui/thread.d \
+./Middlewares/eez/gui/touch.d \
+./Middlewares/eez/gui/touch_calibration.d \
+./Middlewares/eez/gui/touch_filter.d \
+./Middlewares/eez/gui/update.d \
+./Middlewares/eez/gui/widget.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/gui/%.o Middlewares/eez/gui/%.su: ../Middlewares/eez/gui/%.cpp Middlewares/eez/gui/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-gui
+
+clean-Middlewares-2f-eez-2f-gui:
+ -$(RM) ./Middlewares/eez/gui/action_impl.d ./Middlewares/eez/gui/action_impl.o ./Middlewares/eez/gui/action_impl.su ./Middlewares/eez/gui/animation.d ./Middlewares/eez/gui/animation.o ./Middlewares/eez/gui/animation.su ./Middlewares/eez/gui/app_context.d ./Middlewares/eez/gui/app_context.o ./Middlewares/eez/gui/app_context.su ./Middlewares/eez/gui/assets.d ./Middlewares/eez/gui/assets.o ./Middlewares/eez/gui/assets.su ./Middlewares/eez/gui/assets_fix_offsets.d ./Middlewares/eez/gui/assets_fix_offsets.o ./Middlewares/eez/gui/assets_fix_offsets.su ./Middlewares/eez/gui/data.d ./Middlewares/eez/gui/data.o ./Middlewares/eez/gui/data.su ./Middlewares/eez/gui/display.d ./Middlewares/eez/gui/display.o ./Middlewares/eez/gui/display.su ./Middlewares/eez/gui/draw.d ./Middlewares/eez/gui/draw.o ./Middlewares/eez/gui/draw.su ./Middlewares/eez/gui/event.d ./Middlewares/eez/gui/event.o ./Middlewares/eez/gui/event.su ./Middlewares/eez/gui/font.d ./Middlewares/eez/gui/font.o ./Middlewares/eez/gui/font.su ./Middlewares/eez/gui/geometry.d ./Middlewares/eez/gui/geometry.o ./Middlewares/eez/gui/geometry.su ./Middlewares/eez/gui/gui.d ./Middlewares/eez/gui/gui.o ./Middlewares/eez/gui/gui.su ./Middlewares/eez/gui/hooks.d ./Middlewares/eez/gui/hooks.o ./Middlewares/eez/gui/hooks.su ./Middlewares/eez/gui/keypad.d ./Middlewares/eez/gui/keypad.o ./Middlewares/eez/gui/keypad.su ./Middlewares/eez/gui/overlay.d ./Middlewares/eez/gui/overlay.o ./Middlewares/eez/gui/overlay.su ./Middlewares/eez/gui/page.d ./Middlewares/eez/gui/page.o ./Middlewares/eez/gui/page.su ./Middlewares/eez/gui/thread.d ./Middlewares/eez/gui/thread.o ./Middlewares/eez/gui/thread.su ./Middlewares/eez/gui/touch.d ./Middlewares/eez/gui/touch.o ./Middlewares/eez/gui/touch.su ./Middlewares/eez/gui/touch_calibration.d ./Middlewares/eez/gui/touch_calibration.o ./Middlewares/eez/gui/touch_calibration.su ./Middlewares/eez/gui/touch_filter.d ./Middlewares/eez/gui/touch_filter.o ./Middlewares/eez/gui/touch_filter.su ./Middlewares/eez/gui/update.d ./Middlewares/eez/gui/update.o ./Middlewares/eez/gui/update.su ./Middlewares/eez/gui/widget.d ./Middlewares/eez/gui/widget.o ./Middlewares/eez/gui/widget.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-gui
+
diff --git a/Debug/Middlewares/eez/gui/widgets/containers/subdir.mk b/Debug/Middlewares/eez/gui/widgets/containers/subdir.mk
new file mode 100644
index 0000000..58feee6
--- /dev/null
+++ b/Debug/Middlewares/eez/gui/widgets/containers/subdir.mk
@@ -0,0 +1,42 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/gui/widgets/containers/app_view.cpp \
+../Middlewares/eez/gui/widgets/containers/container.cpp \
+../Middlewares/eez/gui/widgets/containers/grid.cpp \
+../Middlewares/eez/gui/widgets/containers/layout_view.cpp \
+../Middlewares/eez/gui/widgets/containers/list.cpp \
+../Middlewares/eez/gui/widgets/containers/select.cpp
+
+OBJS += \
+./Middlewares/eez/gui/widgets/containers/app_view.o \
+./Middlewares/eez/gui/widgets/containers/container.o \
+./Middlewares/eez/gui/widgets/containers/grid.o \
+./Middlewares/eez/gui/widgets/containers/layout_view.o \
+./Middlewares/eez/gui/widgets/containers/list.o \
+./Middlewares/eez/gui/widgets/containers/select.o
+
+CPP_DEPS += \
+./Middlewares/eez/gui/widgets/containers/app_view.d \
+./Middlewares/eez/gui/widgets/containers/container.d \
+./Middlewares/eez/gui/widgets/containers/grid.d \
+./Middlewares/eez/gui/widgets/containers/layout_view.d \
+./Middlewares/eez/gui/widgets/containers/list.d \
+./Middlewares/eez/gui/widgets/containers/select.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/gui/widgets/containers/%.o Middlewares/eez/gui/widgets/containers/%.su: ../Middlewares/eez/gui/widgets/containers/%.cpp Middlewares/eez/gui/widgets/containers/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-gui-2f-widgets-2f-containers
+
+clean-Middlewares-2f-eez-2f-gui-2f-widgets-2f-containers:
+ -$(RM) ./Middlewares/eez/gui/widgets/containers/app_view.d ./Middlewares/eez/gui/widgets/containers/app_view.o ./Middlewares/eez/gui/widgets/containers/app_view.su ./Middlewares/eez/gui/widgets/containers/container.d ./Middlewares/eez/gui/widgets/containers/container.o ./Middlewares/eez/gui/widgets/containers/container.su ./Middlewares/eez/gui/widgets/containers/grid.d ./Middlewares/eez/gui/widgets/containers/grid.o ./Middlewares/eez/gui/widgets/containers/grid.su ./Middlewares/eez/gui/widgets/containers/layout_view.d ./Middlewares/eez/gui/widgets/containers/layout_view.o ./Middlewares/eez/gui/widgets/containers/layout_view.su ./Middlewares/eez/gui/widgets/containers/list.d ./Middlewares/eez/gui/widgets/containers/list.o ./Middlewares/eez/gui/widgets/containers/list.su ./Middlewares/eez/gui/widgets/containers/select.d ./Middlewares/eez/gui/widgets/containers/select.o ./Middlewares/eez/gui/widgets/containers/select.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-gui-2f-widgets-2f-containers
+
diff --git a/Debug/Middlewares/eez/gui/widgets/subdir.mk b/Debug/Middlewares/eez/gui/widgets/subdir.mk
new file mode 100644
index 0000000..31f4c83
--- /dev/null
+++ b/Debug/Middlewares/eez/gui/widgets/subdir.mk
@@ -0,0 +1,87 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/gui/widgets/bar_graph.cpp \
+../Middlewares/eez/gui/widgets/bitmap.cpp \
+../Middlewares/eez/gui/widgets/button.cpp \
+../Middlewares/eez/gui/widgets/button_group.cpp \
+../Middlewares/eez/gui/widgets/canvas.cpp \
+../Middlewares/eez/gui/widgets/display_data.cpp \
+../Middlewares/eez/gui/widgets/drop_down_list.cpp \
+../Middlewares/eez/gui/widgets/gauge.cpp \
+../Middlewares/eez/gui/widgets/input.cpp \
+../Middlewares/eez/gui/widgets/list_graph.cpp \
+../Middlewares/eez/gui/widgets/multiline_text.cpp \
+../Middlewares/eez/gui/widgets/progress.cpp \
+../Middlewares/eez/gui/widgets/rectangle.cpp \
+../Middlewares/eez/gui/widgets/roller.cpp \
+../Middlewares/eez/gui/widgets/scroll_bar.cpp \
+../Middlewares/eez/gui/widgets/slider.cpp \
+../Middlewares/eez/gui/widgets/switch.cpp \
+../Middlewares/eez/gui/widgets/text.cpp \
+../Middlewares/eez/gui/widgets/toggle_button.cpp \
+../Middlewares/eez/gui/widgets/up_down.cpp \
+../Middlewares/eez/gui/widgets/yt_graph.cpp
+
+OBJS += \
+./Middlewares/eez/gui/widgets/bar_graph.o \
+./Middlewares/eez/gui/widgets/bitmap.o \
+./Middlewares/eez/gui/widgets/button.o \
+./Middlewares/eez/gui/widgets/button_group.o \
+./Middlewares/eez/gui/widgets/canvas.o \
+./Middlewares/eez/gui/widgets/display_data.o \
+./Middlewares/eez/gui/widgets/drop_down_list.o \
+./Middlewares/eez/gui/widgets/gauge.o \
+./Middlewares/eez/gui/widgets/input.o \
+./Middlewares/eez/gui/widgets/list_graph.o \
+./Middlewares/eez/gui/widgets/multiline_text.o \
+./Middlewares/eez/gui/widgets/progress.o \
+./Middlewares/eez/gui/widgets/rectangle.o \
+./Middlewares/eez/gui/widgets/roller.o \
+./Middlewares/eez/gui/widgets/scroll_bar.o \
+./Middlewares/eez/gui/widgets/slider.o \
+./Middlewares/eez/gui/widgets/switch.o \
+./Middlewares/eez/gui/widgets/text.o \
+./Middlewares/eez/gui/widgets/toggle_button.o \
+./Middlewares/eez/gui/widgets/up_down.o \
+./Middlewares/eez/gui/widgets/yt_graph.o
+
+CPP_DEPS += \
+./Middlewares/eez/gui/widgets/bar_graph.d \
+./Middlewares/eez/gui/widgets/bitmap.d \
+./Middlewares/eez/gui/widgets/button.d \
+./Middlewares/eez/gui/widgets/button_group.d \
+./Middlewares/eez/gui/widgets/canvas.d \
+./Middlewares/eez/gui/widgets/display_data.d \
+./Middlewares/eez/gui/widgets/drop_down_list.d \
+./Middlewares/eez/gui/widgets/gauge.d \
+./Middlewares/eez/gui/widgets/input.d \
+./Middlewares/eez/gui/widgets/list_graph.d \
+./Middlewares/eez/gui/widgets/multiline_text.d \
+./Middlewares/eez/gui/widgets/progress.d \
+./Middlewares/eez/gui/widgets/rectangle.d \
+./Middlewares/eez/gui/widgets/roller.d \
+./Middlewares/eez/gui/widgets/scroll_bar.d \
+./Middlewares/eez/gui/widgets/slider.d \
+./Middlewares/eez/gui/widgets/switch.d \
+./Middlewares/eez/gui/widgets/text.d \
+./Middlewares/eez/gui/widgets/toggle_button.d \
+./Middlewares/eez/gui/widgets/up_down.d \
+./Middlewares/eez/gui/widgets/yt_graph.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/gui/widgets/%.o Middlewares/eez/gui/widgets/%.su: ../Middlewares/eez/gui/widgets/%.cpp Middlewares/eez/gui/widgets/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-gui-2f-widgets
+
+clean-Middlewares-2f-eez-2f-gui-2f-widgets:
+ -$(RM) ./Middlewares/eez/gui/widgets/bar_graph.d ./Middlewares/eez/gui/widgets/bar_graph.o ./Middlewares/eez/gui/widgets/bar_graph.su ./Middlewares/eez/gui/widgets/bitmap.d ./Middlewares/eez/gui/widgets/bitmap.o ./Middlewares/eez/gui/widgets/bitmap.su ./Middlewares/eez/gui/widgets/button.d ./Middlewares/eez/gui/widgets/button.o ./Middlewares/eez/gui/widgets/button.su ./Middlewares/eez/gui/widgets/button_group.d ./Middlewares/eez/gui/widgets/button_group.o ./Middlewares/eez/gui/widgets/button_group.su ./Middlewares/eez/gui/widgets/canvas.d ./Middlewares/eez/gui/widgets/canvas.o ./Middlewares/eez/gui/widgets/canvas.su ./Middlewares/eez/gui/widgets/display_data.d ./Middlewares/eez/gui/widgets/display_data.o ./Middlewares/eez/gui/widgets/display_data.su ./Middlewares/eez/gui/widgets/drop_down_list.d ./Middlewares/eez/gui/widgets/drop_down_list.o ./Middlewares/eez/gui/widgets/drop_down_list.su ./Middlewares/eez/gui/widgets/gauge.d ./Middlewares/eez/gui/widgets/gauge.o ./Middlewares/eez/gui/widgets/gauge.su ./Middlewares/eez/gui/widgets/input.d ./Middlewares/eez/gui/widgets/input.o ./Middlewares/eez/gui/widgets/input.su ./Middlewares/eez/gui/widgets/list_graph.d ./Middlewares/eez/gui/widgets/list_graph.o ./Middlewares/eez/gui/widgets/list_graph.su ./Middlewares/eez/gui/widgets/multiline_text.d ./Middlewares/eez/gui/widgets/multiline_text.o ./Middlewares/eez/gui/widgets/multiline_text.su ./Middlewares/eez/gui/widgets/progress.d ./Middlewares/eez/gui/widgets/progress.o ./Middlewares/eez/gui/widgets/progress.su ./Middlewares/eez/gui/widgets/rectangle.d ./Middlewares/eez/gui/widgets/rectangle.o ./Middlewares/eez/gui/widgets/rectangle.su ./Middlewares/eez/gui/widgets/roller.d ./Middlewares/eez/gui/widgets/roller.o ./Middlewares/eez/gui/widgets/roller.su ./Middlewares/eez/gui/widgets/scroll_bar.d ./Middlewares/eez/gui/widgets/scroll_bar.o ./Middlewares/eez/gui/widgets/scroll_bar.su ./Middlewares/eez/gui/widgets/slider.d ./Middlewares/eez/gui/widgets/slider.o ./Middlewares/eez/gui/widgets/slider.su ./Middlewares/eez/gui/widgets/switch.d ./Middlewares/eez/gui/widgets/switch.o ./Middlewares/eez/gui/widgets/switch.su ./Middlewares/eez/gui/widgets/text.d ./Middlewares/eez/gui/widgets/text.o ./Middlewares/eez/gui/widgets/text.su ./Middlewares/eez/gui/widgets/toggle_button.d ./Middlewares/eez/gui/widgets/toggle_button.o ./Middlewares/eez/gui/widgets/toggle_button.su ./Middlewares/eez/gui/widgets/up_down.d ./Middlewares/eez/gui/widgets/up_down.o ./Middlewares/eez/gui/widgets/up_down.su ./Middlewares/eez/gui/widgets/yt_graph.d ./Middlewares/eez/gui/widgets/yt_graph.o ./Middlewares/eez/gui/widgets/yt_graph.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-gui-2f-widgets
+
diff --git a/Debug/Middlewares/eez/libs/agg/subdir.mk b/Debug/Middlewares/eez/libs/agg/subdir.mk
new file mode 100644
index 0000000..3444d3c
--- /dev/null
+++ b/Debug/Middlewares/eez/libs/agg/subdir.mk
@@ -0,0 +1,105 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/libs/agg/agg2d.cpp \
+../Middlewares/eez/libs/agg/agg_arc.cpp \
+../Middlewares/eez/libs/agg/agg_arrowhead.cpp \
+../Middlewares/eez/libs/agg/agg_bezier_arc.cpp \
+../Middlewares/eez/libs/agg/agg_bspline.cpp \
+../Middlewares/eez/libs/agg/agg_color_rgba.cpp \
+../Middlewares/eez/libs/agg/agg_curves.cpp \
+../Middlewares/eez/libs/agg/agg_embedded_raster_fonts.cpp \
+../Middlewares/eez/libs/agg/agg_gsv_text.cpp \
+../Middlewares/eez/libs/agg/agg_image_filters.cpp \
+../Middlewares/eez/libs/agg/agg_line_aa_basics.cpp \
+../Middlewares/eez/libs/agg/agg_line_profile_aa.cpp \
+../Middlewares/eez/libs/agg/agg_rounded_rect.cpp \
+../Middlewares/eez/libs/agg/agg_sqrt_tables.cpp \
+../Middlewares/eez/libs/agg/agg_trans_affine.cpp \
+../Middlewares/eez/libs/agg/agg_trans_double_path.cpp \
+../Middlewares/eez/libs/agg/agg_trans_single_path.cpp \
+../Middlewares/eez/libs/agg/agg_trans_warp_magnifier.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_bspline.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_contour.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_dash.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_markers_term.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.cpp \
+../Middlewares/eez/libs/agg/agg_vcgen_stroke.cpp \
+../Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.cpp \
+../Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.cpp \
+../Middlewares/eez/libs/agg/agg_vpgen_segmentator.cpp
+
+OBJS += \
+./Middlewares/eez/libs/agg/agg2d.o \
+./Middlewares/eez/libs/agg/agg_arc.o \
+./Middlewares/eez/libs/agg/agg_arrowhead.o \
+./Middlewares/eez/libs/agg/agg_bezier_arc.o \
+./Middlewares/eez/libs/agg/agg_bspline.o \
+./Middlewares/eez/libs/agg/agg_color_rgba.o \
+./Middlewares/eez/libs/agg/agg_curves.o \
+./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.o \
+./Middlewares/eez/libs/agg/agg_gsv_text.o \
+./Middlewares/eez/libs/agg/agg_image_filters.o \
+./Middlewares/eez/libs/agg/agg_line_aa_basics.o \
+./Middlewares/eez/libs/agg/agg_line_profile_aa.o \
+./Middlewares/eez/libs/agg/agg_rounded_rect.o \
+./Middlewares/eez/libs/agg/agg_sqrt_tables.o \
+./Middlewares/eez/libs/agg/agg_trans_affine.o \
+./Middlewares/eez/libs/agg/agg_trans_double_path.o \
+./Middlewares/eez/libs/agg/agg_trans_single_path.o \
+./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.o \
+./Middlewares/eez/libs/agg/agg_vcgen_bspline.o \
+./Middlewares/eez/libs/agg/agg_vcgen_contour.o \
+./Middlewares/eez/libs/agg/agg_vcgen_dash.o \
+./Middlewares/eez/libs/agg/agg_vcgen_markers_term.o \
+./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.o \
+./Middlewares/eez/libs/agg/agg_vcgen_stroke.o \
+./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.o \
+./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.o \
+./Middlewares/eez/libs/agg/agg_vpgen_segmentator.o
+
+CPP_DEPS += \
+./Middlewares/eez/libs/agg/agg2d.d \
+./Middlewares/eez/libs/agg/agg_arc.d \
+./Middlewares/eez/libs/agg/agg_arrowhead.d \
+./Middlewares/eez/libs/agg/agg_bezier_arc.d \
+./Middlewares/eez/libs/agg/agg_bspline.d \
+./Middlewares/eez/libs/agg/agg_color_rgba.d \
+./Middlewares/eez/libs/agg/agg_curves.d \
+./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.d \
+./Middlewares/eez/libs/agg/agg_gsv_text.d \
+./Middlewares/eez/libs/agg/agg_image_filters.d \
+./Middlewares/eez/libs/agg/agg_line_aa_basics.d \
+./Middlewares/eez/libs/agg/agg_line_profile_aa.d \
+./Middlewares/eez/libs/agg/agg_rounded_rect.d \
+./Middlewares/eez/libs/agg/agg_sqrt_tables.d \
+./Middlewares/eez/libs/agg/agg_trans_affine.d \
+./Middlewares/eez/libs/agg/agg_trans_double_path.d \
+./Middlewares/eez/libs/agg/agg_trans_single_path.d \
+./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.d \
+./Middlewares/eez/libs/agg/agg_vcgen_bspline.d \
+./Middlewares/eez/libs/agg/agg_vcgen_contour.d \
+./Middlewares/eez/libs/agg/agg_vcgen_dash.d \
+./Middlewares/eez/libs/agg/agg_vcgen_markers_term.d \
+./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.d \
+./Middlewares/eez/libs/agg/agg_vcgen_stroke.d \
+./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.d \
+./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.d \
+./Middlewares/eez/libs/agg/agg_vpgen_segmentator.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/libs/agg/%.o Middlewares/eez/libs/agg/%.su: ../Middlewares/eez/libs/agg/%.cpp Middlewares/eez/libs/agg/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-libs-2f-agg
+
+clean-Middlewares-2f-eez-2f-libs-2f-agg:
+ -$(RM) ./Middlewares/eez/libs/agg/agg2d.d ./Middlewares/eez/libs/agg/agg2d.o ./Middlewares/eez/libs/agg/agg2d.su ./Middlewares/eez/libs/agg/agg_arc.d ./Middlewares/eez/libs/agg/agg_arc.o ./Middlewares/eez/libs/agg/agg_arc.su ./Middlewares/eez/libs/agg/agg_arrowhead.d ./Middlewares/eez/libs/agg/agg_arrowhead.o ./Middlewares/eez/libs/agg/agg_arrowhead.su ./Middlewares/eez/libs/agg/agg_bezier_arc.d ./Middlewares/eez/libs/agg/agg_bezier_arc.o ./Middlewares/eez/libs/agg/agg_bezier_arc.su ./Middlewares/eez/libs/agg/agg_bspline.d ./Middlewares/eez/libs/agg/agg_bspline.o ./Middlewares/eez/libs/agg/agg_bspline.su ./Middlewares/eez/libs/agg/agg_color_rgba.d ./Middlewares/eez/libs/agg/agg_color_rgba.o ./Middlewares/eez/libs/agg/agg_color_rgba.su ./Middlewares/eez/libs/agg/agg_curves.d ./Middlewares/eez/libs/agg/agg_curves.o ./Middlewares/eez/libs/agg/agg_curves.su ./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.d ./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.o ./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.su ./Middlewares/eez/libs/agg/agg_gsv_text.d ./Middlewares/eez/libs/agg/agg_gsv_text.o ./Middlewares/eez/libs/agg/agg_gsv_text.su ./Middlewares/eez/libs/agg/agg_image_filters.d ./Middlewares/eez/libs/agg/agg_image_filters.o ./Middlewares/eez/libs/agg/agg_image_filters.su ./Middlewares/eez/libs/agg/agg_line_aa_basics.d ./Middlewares/eez/libs/agg/agg_line_aa_basics.o ./Middlewares/eez/libs/agg/agg_line_aa_basics.su ./Middlewares/eez/libs/agg/agg_line_profile_aa.d ./Middlewares/eez/libs/agg/agg_line_profile_aa.o ./Middlewares/eez/libs/agg/agg_line_profile_aa.su ./Middlewares/eez/libs/agg/agg_rounded_rect.d ./Middlewares/eez/libs/agg/agg_rounded_rect.o ./Middlewares/eez/libs/agg/agg_rounded_rect.su ./Middlewares/eez/libs/agg/agg_sqrt_tables.d ./Middlewares/eez/libs/agg/agg_sqrt_tables.o ./Middlewares/eez/libs/agg/agg_sqrt_tables.su ./Middlewares/eez/libs/agg/agg_trans_affine.d ./Middlewares/eez/libs/agg/agg_trans_affine.o ./Middlewares/eez/libs/agg/agg_trans_affine.su ./Middlewares/eez/libs/agg/agg_trans_double_path.d ./Middlewares/eez/libs/agg/agg_trans_double_path.o ./Middlewares/eez/libs/agg/agg_trans_double_path.su ./Middlewares/eez/libs/agg/agg_trans_single_path.d ./Middlewares/eez/libs/agg/agg_trans_single_path.o ./Middlewares/eez/libs/agg/agg_trans_single_path.su ./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.d ./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.o ./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.su ./Middlewares/eez/libs/agg/agg_vcgen_bspline.d ./Middlewares/eez/libs/agg/agg_vcgen_bspline.o ./Middlewares/eez/libs/agg/agg_vcgen_bspline.su ./Middlewares/eez/libs/agg/agg_vcgen_contour.d ./Middlewares/eez/libs/agg/agg_vcgen_contour.o ./Middlewares/eez/libs/agg/agg_vcgen_contour.su ./Middlewares/eez/libs/agg/agg_vcgen_dash.d ./Middlewares/eez/libs/agg/agg_vcgen_dash.o ./Middlewares/eez/libs/agg/agg_vcgen_dash.su ./Middlewares/eez/libs/agg/agg_vcgen_markers_term.d ./Middlewares/eez/libs/agg/agg_vcgen_markers_term.o ./Middlewares/eez/libs/agg/agg_vcgen_markers_term.su ./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.d ./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.o ./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.su ./Middlewares/eez/libs/agg/agg_vcgen_stroke.d ./Middlewares/eez/libs/agg/agg_vcgen_stroke.o ./Middlewares/eez/libs/agg/agg_vcgen_stroke.su ./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.d ./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.o ./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.su ./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.d ./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.o ./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.su ./Middlewares/eez/libs/agg/agg_vpgen_segmentator.d ./Middlewares/eez/libs/agg/agg_vpgen_segmentator.o ./Middlewares/eez/libs/agg/agg_vpgen_segmentator.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-libs-2f-agg
+
diff --git a/Debug/Middlewares/eez/libs/libscpi/src/subdir.mk b/Debug/Middlewares/eez/libs/libscpi/src/subdir.mk
new file mode 100644
index 0000000..55c69ea
--- /dev/null
+++ b/Debug/Middlewares/eez/libs/libscpi/src/subdir.mk
@@ -0,0 +1,51 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../Middlewares/eez/libs/libscpi/src/error.c \
+../Middlewares/eez/libs/libscpi/src/expression.c \
+../Middlewares/eez/libs/libscpi/src/fifo.c \
+../Middlewares/eez/libs/libscpi/src/ieee488.c \
+../Middlewares/eez/libs/libscpi/src/lexer.c \
+../Middlewares/eez/libs/libscpi/src/minimal.c \
+../Middlewares/eez/libs/libscpi/src/parser.c \
+../Middlewares/eez/libs/libscpi/src/units.c \
+../Middlewares/eez/libs/libscpi/src/utils.c
+
+C_DEPS += \
+./Middlewares/eez/libs/libscpi/src/error.d \
+./Middlewares/eez/libs/libscpi/src/expression.d \
+./Middlewares/eez/libs/libscpi/src/fifo.d \
+./Middlewares/eez/libs/libscpi/src/ieee488.d \
+./Middlewares/eez/libs/libscpi/src/lexer.d \
+./Middlewares/eez/libs/libscpi/src/minimal.d \
+./Middlewares/eez/libs/libscpi/src/parser.d \
+./Middlewares/eez/libs/libscpi/src/units.d \
+./Middlewares/eez/libs/libscpi/src/utils.d
+
+OBJS += \
+./Middlewares/eez/libs/libscpi/src/error.o \
+./Middlewares/eez/libs/libscpi/src/expression.o \
+./Middlewares/eez/libs/libscpi/src/fifo.o \
+./Middlewares/eez/libs/libscpi/src/ieee488.o \
+./Middlewares/eez/libs/libscpi/src/lexer.o \
+./Middlewares/eez/libs/libscpi/src/minimal.o \
+./Middlewares/eez/libs/libscpi/src/parser.o \
+./Middlewares/eez/libs/libscpi/src/units.o \
+./Middlewares/eez/libs/libscpi/src/utils.o
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/libs/libscpi/src/%.o Middlewares/eez/libs/libscpi/src/%.su: ../Middlewares/eez/libs/libscpi/src/%.c Middlewares/eez/libs/libscpi/src/subdir.mk
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-libs-2f-libscpi-2f-src
+
+clean-Middlewares-2f-eez-2f-libs-2f-libscpi-2f-src:
+ -$(RM) ./Middlewares/eez/libs/libscpi/src/error.d ./Middlewares/eez/libs/libscpi/src/error.o ./Middlewares/eez/libs/libscpi/src/error.su ./Middlewares/eez/libs/libscpi/src/expression.d ./Middlewares/eez/libs/libscpi/src/expression.o ./Middlewares/eez/libs/libscpi/src/expression.su ./Middlewares/eez/libs/libscpi/src/fifo.d ./Middlewares/eez/libs/libscpi/src/fifo.o ./Middlewares/eez/libs/libscpi/src/fifo.su ./Middlewares/eez/libs/libscpi/src/ieee488.d ./Middlewares/eez/libs/libscpi/src/ieee488.o ./Middlewares/eez/libs/libscpi/src/ieee488.su ./Middlewares/eez/libs/libscpi/src/lexer.d ./Middlewares/eez/libs/libscpi/src/lexer.o ./Middlewares/eez/libs/libscpi/src/lexer.su ./Middlewares/eez/libs/libscpi/src/minimal.d ./Middlewares/eez/libs/libscpi/src/minimal.o ./Middlewares/eez/libs/libscpi/src/minimal.su ./Middlewares/eez/libs/libscpi/src/parser.d ./Middlewares/eez/libs/libscpi/src/parser.o ./Middlewares/eez/libs/libscpi/src/parser.su ./Middlewares/eez/libs/libscpi/src/units.d ./Middlewares/eez/libs/libscpi/src/units.o ./Middlewares/eez/libs/libscpi/src/units.su ./Middlewares/eez/libs/libscpi/src/utils.d ./Middlewares/eez/libs/libscpi/src/utils.o ./Middlewares/eez/libs/libscpi/src/utils.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-libs-2f-libscpi-2f-src
+
diff --git a/Debug/Middlewares/eez/libs/lz4/subdir.mk b/Debug/Middlewares/eez/libs/lz4/subdir.mk
new file mode 100644
index 0000000..281e0df
--- /dev/null
+++ b/Debug/Middlewares/eez/libs/lz4/subdir.mk
@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+C_SRCS += \
+../Middlewares/eez/libs/lz4/lz4.c
+
+C_DEPS += \
+./Middlewares/eez/libs/lz4/lz4.d
+
+OBJS += \
+./Middlewares/eez/libs/lz4/lz4.o
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/libs/lz4/%.o Middlewares/eez/libs/lz4/%.su: ../Middlewares/eez/libs/lz4/%.c Middlewares/eez/libs/lz4/subdir.mk
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-libs-2f-lz4
+
+clean-Middlewares-2f-eez-2f-libs-2f-lz4:
+ -$(RM) ./Middlewares/eez/libs/lz4/lz4.d ./Middlewares/eez/libs/lz4/lz4.o ./Middlewares/eez/libs/lz4/lz4.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-libs-2f-lz4
+
diff --git a/Debug/Middlewares/eez/platform/simulator/subdir.mk b/Debug/Middlewares/eez/platform/simulator/subdir.mk
new file mode 100644
index 0000000..f54bb7e
--- /dev/null
+++ b/Debug/Middlewares/eez/platform/simulator/subdir.mk
@@ -0,0 +1,36 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/platform/simulator/cmsis_os2.cpp \
+../Middlewares/eez/platform/simulator/display.cpp \
+../Middlewares/eez/platform/simulator/events.cpp \
+../Middlewares/eez/platform/simulator/touch.cpp
+
+OBJS += \
+./Middlewares/eez/platform/simulator/cmsis_os2.o \
+./Middlewares/eez/platform/simulator/display.o \
+./Middlewares/eez/platform/simulator/events.o \
+./Middlewares/eez/platform/simulator/touch.o
+
+CPP_DEPS += \
+./Middlewares/eez/platform/simulator/cmsis_os2.d \
+./Middlewares/eez/platform/simulator/display.d \
+./Middlewares/eez/platform/simulator/events.d \
+./Middlewares/eez/platform/simulator/touch.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/platform/simulator/%.o Middlewares/eez/platform/simulator/%.su: ../Middlewares/eez/platform/simulator/%.cpp Middlewares/eez/platform/simulator/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-platform-2f-simulator
+
+clean-Middlewares-2f-eez-2f-platform-2f-simulator:
+ -$(RM) ./Middlewares/eez/platform/simulator/cmsis_os2.d ./Middlewares/eez/platform/simulator/cmsis_os2.o ./Middlewares/eez/platform/simulator/cmsis_os2.su ./Middlewares/eez/platform/simulator/display.d ./Middlewares/eez/platform/simulator/display.o ./Middlewares/eez/platform/simulator/display.su ./Middlewares/eez/platform/simulator/events.d ./Middlewares/eez/platform/simulator/events.o ./Middlewares/eez/platform/simulator/events.su ./Middlewares/eez/platform/simulator/touch.d ./Middlewares/eez/platform/simulator/touch.o ./Middlewares/eez/platform/simulator/touch.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-platform-2f-simulator
+
diff --git a/Debug/Middlewares/eez/platform/stm32/subdir.mk b/Debug/Middlewares/eez/platform/stm32/subdir.mk
new file mode 100644
index 0000000..03cb421
--- /dev/null
+++ b/Debug/Middlewares/eez/platform/stm32/subdir.mk
@@ -0,0 +1,30 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+# Toolchain: GNU Tools for STM32 (10.3-2021.10)
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables
+CPP_SRCS += \
+../Middlewares/eez/platform/stm32/display.cpp \
+../Middlewares/eez/platform/stm32/touch.cpp
+
+OBJS += \
+./Middlewares/eez/platform/stm32/display.o \
+./Middlewares/eez/platform/stm32/touch.o
+
+CPP_DEPS += \
+./Middlewares/eez/platform/stm32/display.d \
+./Middlewares/eez/platform/stm32/touch.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+Middlewares/eez/platform/stm32/%.o Middlewares/eez/platform/stm32/%.su: ../Middlewares/eez/platform/stm32/%.cpp Middlewares/eez/platform/stm32/subdir.mk
+ arm-none-eabi-g++ "$<" -mcpu=cortex-m4 -std=gnu++14 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -O0 -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+
+clean: clean-Middlewares-2f-eez-2f-platform-2f-stm32
+
+clean-Middlewares-2f-eez-2f-platform-2f-stm32:
+ -$(RM) ./Middlewares/eez/platform/stm32/display.d ./Middlewares/eez/platform/stm32/display.o ./Middlewares/eez/platform/stm32/display.su ./Middlewares/eez/platform/stm32/touch.d ./Middlewares/eez/platform/stm32/touch.o ./Middlewares/eez/platform/stm32/touch.su
+
+.PHONY: clean-Middlewares-2f-eez-2f-platform-2f-stm32
+
diff --git a/Debug/USB_DEVICE/App/subdir.mk b/Debug/USB_DEVICE/App/subdir.mk
index bedf675..feb68f8 100644
--- a/Debug/USB_DEVICE/App/subdir.mk
+++ b/Debug/USB_DEVICE/App/subdir.mk
@@ -9,20 +9,20 @@ C_SRCS += \
../USB_DEVICE/App/usbd_cdc_if.c \
../USB_DEVICE/App/usbd_desc.c
-OBJS += \
-./USB_DEVICE/App/usb_device.o \
-./USB_DEVICE/App/usbd_cdc_if.o \
-./USB_DEVICE/App/usbd_desc.o
-
C_DEPS += \
./USB_DEVICE/App/usb_device.d \
./USB_DEVICE/App/usbd_cdc_if.d \
./USB_DEVICE/App/usbd_desc.d
+OBJS += \
+./USB_DEVICE/App/usb_device.o \
+./USB_DEVICE/App/usbd_cdc_if.o \
+./USB_DEVICE/App/usbd_desc.o
+
# Each subdirectory must supply rules for building sources it contributes
USB_DEVICE/App/%.o USB_DEVICE/App/%.su: ../USB_DEVICE/App/%.c USB_DEVICE/App/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-USB_DEVICE-2f-App
diff --git a/Debug/USB_DEVICE/Target/subdir.mk b/Debug/USB_DEVICE/Target/subdir.mk
index 8bab21a..e4a7f1d 100644
--- a/Debug/USB_DEVICE/Target/subdir.mk
+++ b/Debug/USB_DEVICE/Target/subdir.mk
@@ -7,16 +7,16 @@
C_SRCS += \
../USB_DEVICE/Target/usbd_conf.c
-OBJS += \
-./USB_DEVICE/Target/usbd_conf.o
-
C_DEPS += \
./USB_DEVICE/Target/usbd_conf.d
+OBJS += \
+./USB_DEVICE/Target/usbd_conf.o
+
# Each subdirectory must supply rules for building sources it contributes
USB_DEVICE/Target/%.o USB_DEVICE/Target/%.su: ../USB_DEVICE/Target/%.c USB_DEVICE/Target/subdir.mk
- arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
+ arm-none-eabi-gcc "$<" -mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DUSE_STM32469I_DISCO_REVB -DEEZ_PLATFORM_STM32 -DEEZ_PLATFORM_STM32F469I_DISCO -DLZ4_FORCE_MEMORY_ACCESS=0 -DSTM32L496xx -c -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Drivers/STM32L4xx_HAL_Driver/Inc -I../Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Middlewares/Third_Party/FatFs/src -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../Drivers/CMSIS/Device/ST/STM32L4xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../FATFS/Target -I../FATFS/App -I../Drivers/BSP/STM32469I-Discovery -I../Drivers/BSP/Components/Common -I../Utilities/CPU -I../Utilities/Log -I../Src/conf -I../Middlewares -I../Middlewares/eez/libs/agg -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "$@"
clean: clean-USB_DEVICE-2f-Target
diff --git a/Debug/makefile b/Debug/makefile
index 175c955..ca22e81 100644
--- a/Debug/makefile
+++ b/Debug/makefile
@@ -11,6 +11,19 @@ RM := rm -rf
-include sources.mk
-include USB_DEVICE/Target/subdir.mk
-include USB_DEVICE/App/subdir.mk
+-include Middlewares/eez/platform/stm32/subdir.mk
+-include Middlewares/eez/platform/simulator/subdir.mk
+-include Middlewares/eez/libs/lz4/subdir.mk
+-include Middlewares/eez/libs/libscpi/src/subdir.mk
+-include Middlewares/eez/libs/agg/subdir.mk
+-include Middlewares/eez/gui/widgets/containers/subdir.mk
+-include Middlewares/eez/gui/widgets/subdir.mk
+-include Middlewares/eez/gui/subdir.mk
+-include Middlewares/eez/fs/stm32/subdir.mk
+-include Middlewares/eez/fs/simulator/subdir.mk
+-include Middlewares/eez/flow/components/subdir.mk
+-include Middlewares/eez/flow/subdir.mk
+-include Middlewares/eez/core/subdir.mk
-include Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/subdir.mk
-include Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/subdir.mk
-include Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/subdir.mk
@@ -27,6 +40,18 @@ RM := rm -rf
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(CC_DEPS)),)
+-include $(CC_DEPS)
+endif
+ifneq ($(strip $(C++_DEPS)),)
+-include $(C++_DEPS)
+endif
+ifneq ($(strip $(C_UPPER_DEPS)),)
+-include $(C_UPPER_DEPS)
+endif
+ifneq ($(strip $(CXX_DEPS)),)
+-include $(CXX_DEPS)
+endif
ifneq ($(strip $(S_DEPS)),)
-include $(S_DEPS)
endif
@@ -36,6 +61,9 @@ endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
+ifneq ($(strip $(CPP_DEPS)),)
+-include $(CPP_DEPS)
+endif
endif
-include ../makefile.defs
@@ -64,6 +92,9 @@ default.size.stdout \
OBJDUMP_LIST += \
stm32l496g-disco.list \
+OBJCOPY_HEX += \
+stm32l496g-disco.hex \
+
# All Target
all: main-build
@@ -72,8 +103,8 @@ all: main-build
main-build: stm32l496g-disco.elf secondary-outputs
# Tool invocations
-stm32l496g-disco.elf stm32l496g-disco.map: $(OBJS) $(USER_OBJS) D:\projects\envox\flow\eez-flow-template-stm32l496g-disco\STM32L496AGIX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
- arm-none-eabi-gcc -o "stm32l496g-disco.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m4 -T"D:\projects\envox\flow\eez-flow-template-stm32l496g-disco\STM32L496AGIX_FLASH.ld" --specs=nosys.specs -Wl,-Map="stm32l496g-disco.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
+stm32l496g-disco.elf stm32l496g-disco.map: $(OBJS) $(USER_OBJS) /media/internal/Programs/studio_build/templates/eez-flow-template-stm32l496g-disco/STM32L496AGIX_FLASH.ld makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-g++ -o "stm32l496g-disco.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m4 -T"/media/internal/Programs/studio_build/templates/eez-flow-template-stm32l496g-disco/STM32L496AGIX_FLASH.ld" -Wl,-Map="stm32l496g-disco.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
@echo 'Finished building target: $@'
@echo ' '
@@ -87,12 +118,17 @@ stm32l496g-disco.list: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS
@echo 'Finished building: $@'
@echo ' '
+stm32l496g-disco.hex: $(EXECUTABLES) makefile objects.list $(OPTIONAL_TOOL_DEPS)
+ arm-none-eabi-objcopy -O ihex $(EXECUTABLES) "stm32l496g-disco.hex"
+ @echo 'Finished building: $@'
+ @echo ' '
+
# Other Targets
clean:
- -$(RM) default.size.stdout stm32l496g-disco.elf stm32l496g-disco.list stm32l496g-disco.map
+ -$(RM) default.size.stdout stm32l496g-disco.elf stm32l496g-disco.hex stm32l496g-disco.list stm32l496g-disco.map
-@echo ' '
-secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST)
+secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST) $(OBJCOPY_HEX)
fail-specified-linker-script-missing:
@echo 'Error: Cannot find the specified linker script. Check the linker settings in the build configuration.'
diff --git a/Debug/objects.list b/Debug/objects.list
index 87adae2..09cb4a7 100644
--- a/Debug/objects.list
+++ b/Debug/objects.list
@@ -80,6 +80,146 @@
"./Middlewares/Third_Party/FreeRTOS/Source/timers.o"
"./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.o"
"./Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.o"
+"./Middlewares/eez/core/alloc.o"
+"./Middlewares/eez/core/debug.o"
+"./Middlewares/eez/core/eeprom.o"
+"./Middlewares/eez/core/hmi.o"
+"./Middlewares/eez/core/memory.o"
+"./Middlewares/eez/core/os.o"
+"./Middlewares/eez/core/unit.o"
+"./Middlewares/eez/core/util.o"
+"./Middlewares/eez/flow/components/animate.o"
+"./Middlewares/eez/flow/components/call_action.o"
+"./Middlewares/eez/flow/components/catch_error.o"
+"./Middlewares/eez/flow/components/compare.o"
+"./Middlewares/eez/flow/components/constant.o"
+"./Middlewares/eez/flow/components/counter.o"
+"./Middlewares/eez/flow/components/delay.o"
+"./Middlewares/eez/flow/components/end.o"
+"./Middlewares/eez/flow/components/error.o"
+"./Middlewares/eez/flow/components/expr_eval.o"
+"./Middlewares/eez/flow/components/input.o"
+"./Middlewares/eez/flow/components/is_true.o"
+"./Middlewares/eez/flow/components/layout_view_widget.o"
+"./Middlewares/eez/flow/components/log.o"
+"./Middlewares/eez/flow/components/loop.o"
+"./Middlewares/eez/flow/components/noop.o"
+"./Middlewares/eez/flow/components/on_event.o"
+"./Middlewares/eez/flow/components/output.o"
+"./Middlewares/eez/flow/components/roller_widget.o"
+"./Middlewares/eez/flow/components/select_language.o"
+"./Middlewares/eez/flow/components/set_page_direction.o"
+"./Middlewares/eez/flow/components/set_variable.o"
+"./Middlewares/eez/flow/components/show_keyboard.o"
+"./Middlewares/eez/flow/components/show_keypad.o"
+"./Middlewares/eez/flow/components/show_message_box.o"
+"./Middlewares/eez/flow/components/show_page.o"
+"./Middlewares/eez/flow/components/start.o"
+"./Middlewares/eez/flow/components/switch.o"
+"./Middlewares/eez/flow/components/watch_variable.o"
+"./Middlewares/eez/flow/components.o"
+"./Middlewares/eez/flow/dashboard_api.o"
+"./Middlewares/eez/flow/debugger.o"
+"./Middlewares/eez/flow/expression.o"
+"./Middlewares/eez/flow/flow.o"
+"./Middlewares/eez/flow/hooks.o"
+"./Middlewares/eez/flow/operations.o"
+"./Middlewares/eez/flow/private.o"
+"./Middlewares/eez/flow/queue.o"
+"./Middlewares/eez/fs/simulator/fs.o"
+"./Middlewares/eez/fs/stm32/fs.o"
+"./Middlewares/eez/gui/action_impl.o"
+"./Middlewares/eez/gui/animation.o"
+"./Middlewares/eez/gui/app_context.o"
+"./Middlewares/eez/gui/assets.o"
+"./Middlewares/eez/gui/assets_fix_offsets.o"
+"./Middlewares/eez/gui/data.o"
+"./Middlewares/eez/gui/display.o"
+"./Middlewares/eez/gui/draw.o"
+"./Middlewares/eez/gui/event.o"
+"./Middlewares/eez/gui/font.o"
+"./Middlewares/eez/gui/geometry.o"
+"./Middlewares/eez/gui/gui.o"
+"./Middlewares/eez/gui/hooks.o"
+"./Middlewares/eez/gui/keypad.o"
+"./Middlewares/eez/gui/overlay.o"
+"./Middlewares/eez/gui/page.o"
+"./Middlewares/eez/gui/thread.o"
+"./Middlewares/eez/gui/touch.o"
+"./Middlewares/eez/gui/touch_calibration.o"
+"./Middlewares/eez/gui/touch_filter.o"
+"./Middlewares/eez/gui/update.o"
+"./Middlewares/eez/gui/widget.o"
+"./Middlewares/eez/gui/widgets/bar_graph.o"
+"./Middlewares/eez/gui/widgets/bitmap.o"
+"./Middlewares/eez/gui/widgets/button.o"
+"./Middlewares/eez/gui/widgets/button_group.o"
+"./Middlewares/eez/gui/widgets/canvas.o"
+"./Middlewares/eez/gui/widgets/display_data.o"
+"./Middlewares/eez/gui/widgets/drop_down_list.o"
+"./Middlewares/eez/gui/widgets/gauge.o"
+"./Middlewares/eez/gui/widgets/input.o"
+"./Middlewares/eez/gui/widgets/list_graph.o"
+"./Middlewares/eez/gui/widgets/multiline_text.o"
+"./Middlewares/eez/gui/widgets/progress.o"
+"./Middlewares/eez/gui/widgets/rectangle.o"
+"./Middlewares/eez/gui/widgets/roller.o"
+"./Middlewares/eez/gui/widgets/scroll_bar.o"
+"./Middlewares/eez/gui/widgets/slider.o"
+"./Middlewares/eez/gui/widgets/switch.o"
+"./Middlewares/eez/gui/widgets/text.o"
+"./Middlewares/eez/gui/widgets/toggle_button.o"
+"./Middlewares/eez/gui/widgets/up_down.o"
+"./Middlewares/eez/gui/widgets/yt_graph.o"
+"./Middlewares/eez/gui/widgets/containers/app_view.o"
+"./Middlewares/eez/gui/widgets/containers/container.o"
+"./Middlewares/eez/gui/widgets/containers/grid.o"
+"./Middlewares/eez/gui/widgets/containers/layout_view.o"
+"./Middlewares/eez/gui/widgets/containers/list.o"
+"./Middlewares/eez/gui/widgets/containers/select.o"
+"./Middlewares/eez/libs/agg/agg2d.o"
+"./Middlewares/eez/libs/agg/agg_arc.o"
+"./Middlewares/eez/libs/agg/agg_arrowhead.o"
+"./Middlewares/eez/libs/agg/agg_bezier_arc.o"
+"./Middlewares/eez/libs/agg/agg_bspline.o"
+"./Middlewares/eez/libs/agg/agg_color_rgba.o"
+"./Middlewares/eez/libs/agg/agg_curves.o"
+"./Middlewares/eez/libs/agg/agg_embedded_raster_fonts.o"
+"./Middlewares/eez/libs/agg/agg_gsv_text.o"
+"./Middlewares/eez/libs/agg/agg_image_filters.o"
+"./Middlewares/eez/libs/agg/agg_line_aa_basics.o"
+"./Middlewares/eez/libs/agg/agg_line_profile_aa.o"
+"./Middlewares/eez/libs/agg/agg_rounded_rect.o"
+"./Middlewares/eez/libs/agg/agg_sqrt_tables.o"
+"./Middlewares/eez/libs/agg/agg_trans_affine.o"
+"./Middlewares/eez/libs/agg/agg_trans_double_path.o"
+"./Middlewares/eez/libs/agg/agg_trans_single_path.o"
+"./Middlewares/eez/libs/agg/agg_trans_warp_magnifier.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_bspline.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_contour.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_dash.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_markers_term.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_smooth_poly1.o"
+"./Middlewares/eez/libs/agg/agg_vcgen_stroke.o"
+"./Middlewares/eez/libs/agg/agg_vpgen_clip_polygon.o"
+"./Middlewares/eez/libs/agg/agg_vpgen_clip_polyline.o"
+"./Middlewares/eez/libs/agg/agg_vpgen_segmentator.o"
+"./Middlewares/eez/libs/libscpi/src/error.o"
+"./Middlewares/eez/libs/libscpi/src/expression.o"
+"./Middlewares/eez/libs/libscpi/src/fifo.o"
+"./Middlewares/eez/libs/libscpi/src/ieee488.o"
+"./Middlewares/eez/libs/libscpi/src/lexer.o"
+"./Middlewares/eez/libs/libscpi/src/minimal.o"
+"./Middlewares/eez/libs/libscpi/src/parser.o"
+"./Middlewares/eez/libs/libscpi/src/units.o"
+"./Middlewares/eez/libs/libscpi/src/utils.o"
+"./Middlewares/eez/libs/lz4/lz4.o"
+"./Middlewares/eez/platform/simulator/cmsis_os2.o"
+"./Middlewares/eez/platform/simulator/display.o"
+"./Middlewares/eez/platform/simulator/events.o"
+"./Middlewares/eez/platform/simulator/touch.o"
+"./Middlewares/eez/platform/stm32/display.o"
+"./Middlewares/eez/platform/stm32/touch.o"
"./USB_DEVICE/App/usb_device.o"
"./USB_DEVICE/App/usbd_cdc_if.o"
"./USB_DEVICE/App/usbd_desc.o"
diff --git a/Debug/sources.mk b/Debug/sources.mk
index 2e8de11..c9163fc 100644
--- a/Debug/sources.mk
+++ b/Debug/sources.mk
@@ -4,20 +4,31 @@
################################################################################
ELF_SRCS :=
+C_UPPER_SRCS :=
+CXX_SRCS :=
+C++_SRCS :=
OBJ_SRCS :=
S_SRCS :=
+CC_SRCS :=
C_SRCS :=
+CPP_SRCS :=
S_UPPER_SRCS :=
O_SRCS :=
-SIZE_OUTPUT :=
OBJDUMP_LIST :=
+C_UPPER_DEPS :=
+S_DEPS :=
+C_DEPS :=
+CC_DEPS :=
+OBJCOPY_HEX :=
+SIZE_OUTPUT :=
+C++_DEPS :=
SU_FILES :=
EXECUTABLES :=
OBJS :=
+CXX_DEPS :=
MAP_FILES :=
-S_DEPS :=
S_UPPER_DEPS :=
-C_DEPS :=
+CPP_DEPS :=
# Every subdirectory with source files must be described here
SUBDIRS := \
@@ -34,6 +45,19 @@ Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
Middlewares/Third_Party/FreeRTOS/Source \
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang \
+Middlewares/eez/core \
+Middlewares/eez/flow/components \
+Middlewares/eez/flow \
+Middlewares/eez/fs/simulator \
+Middlewares/eez/fs/stm32 \
+Middlewares/eez/gui \
+Middlewares/eez/gui/widgets \
+Middlewares/eez/gui/widgets/containers \
+Middlewares/eez/libs/agg \
+Middlewares/eez/libs/libscpi/src \
+Middlewares/eez/libs/lz4 \
+Middlewares/eez/platform/simulator \
+Middlewares/eez/platform/stm32 \
USB_DEVICE/App \
USB_DEVICE/Target \
diff --git a/Middlewares/eez/README.md b/Middlewares/eez/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/Middlewares/eez/core/alloc.cpp b/Middlewares/eez/core/alloc.cpp
new file mode 100644
index 0000000..413b7ac
--- /dev/null
+++ b/Middlewares/eez/core/alloc.cpp
@@ -0,0 +1,201 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+namespace eez {
+
+static const size_t ALIGNMENT = 8;
+static const size_t MIN_BLOCK_SIZE = 8;
+
+struct AllocBlock {
+ AllocBlock *next;
+ int free;
+ size_t size;
+ uint32_t id;
+};
+
+static uint8_t *g_heap;
+
+#if defined(EEZ_PLATFORM_STM32)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wparentheses"
+#endif
+
+EEZ_MUTEX_DECLARE(alloc);
+
+#if defined(EEZ_PLATFORM_STM32)
+#pragma GCC diagnostic pop
+#endif
+
+void initAllocHeap(uint8_t *heap, size_t heapSize) {
+ g_heap = heap;
+
+ AllocBlock *first = (AllocBlock *)g_heap;
+ first->next = 0;
+ first->free = 1;
+ first->size = heapSize - sizeof(AllocBlock);
+
+ EEZ_MUTEX_CREATE(alloc);
+}
+
+void *alloc(size_t size, uint32_t id) {
+ if (size == 0) {
+ return nullptr;
+ }
+
+ if (EEZ_MUTEX_WAIT(alloc, 0)) {
+ AllocBlock *firstBlock = (AllocBlock *)g_heap;
+
+ AllocBlock *block = firstBlock;
+ size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
+
+ // find free block with enough size
+ // TODO merge multiple free consecutive blocks into one that has enough size
+ while (block) {
+ if (block->free && block->size >= size) {
+ break;
+ }
+ block = block->next;
+ }
+
+ if (!block) {
+ EEZ_MUTEX_RELEASE(alloc);
+ return nullptr;
+ }
+
+ int remainingSize = block->size - size - sizeof(AllocBlock);
+ if (remainingSize >= (int)MIN_BLOCK_SIZE) {
+ // remainingSize is enough to create a new block
+ auto newBlock = (AllocBlock *)((uint8_t *)block + sizeof(AllocBlock) + size);
+ newBlock->next = block->next;
+ newBlock->free = 1;
+ newBlock->size = remainingSize;
+
+ block->next = newBlock;
+ block->size = size;
+ }
+
+ block->free = 0;
+ block->id = id;
+
+ EEZ_MUTEX_RELEASE(alloc);
+
+ return block + 1;
+ }
+
+ return nullptr;
+}
+
+void free(void *ptr) {
+ if (ptr == 0) {
+ return;
+ }
+
+ if (EEZ_MUTEX_WAIT(alloc, 0)) {
+ AllocBlock *firstBlock = (AllocBlock *)g_heap;
+
+ AllocBlock *prevBlock = nullptr;
+ AllocBlock *block = firstBlock;
+
+ while (block && block + 1 < ptr) {
+ prevBlock = block;
+ block = block->next;
+ }
+
+ if (!block || block + 1 != ptr || block->free) {
+ assert(false);
+ EEZ_MUTEX_RELEASE(alloc);
+ return;
+ }
+
+ // reset memory to catch errors when memory is used after free is called
+ memset(ptr, 0xCC, block->size);
+
+ auto nextBlock = block->next;
+ if (nextBlock && nextBlock->free) {
+ if (prevBlock && prevBlock->free) {
+ // both next and prev blocks are free, merge 3 blocks into one
+ prevBlock->next = nextBlock->next;
+ prevBlock->size += sizeof(AllocBlock) + block->size + sizeof(AllocBlock) + nextBlock->size;
+ } else {
+ // next block is free, merge 2 blocks into one
+ block->next = nextBlock->next;
+ block->size += sizeof(AllocBlock) + nextBlock->size;
+ block->free = 1;
+ }
+ } else if (prevBlock && prevBlock->free) {
+ // prev block is free, merge 2 blocks into one
+ prevBlock->next = nextBlock;
+ prevBlock->size += sizeof(AllocBlock) + block->size;
+ } else {
+ // just free
+ block->free = 1;
+ }
+
+ EEZ_MUTEX_RELEASE(alloc);
+ }
+}
+
+template void freeObject(T *ptr) {
+ ptr->~T();
+ free(ptr);
+}
+
+#if OPTION_SCPI
+void dumpAlloc(scpi_t *context) {
+ AllocBlock *first = (AllocBlock *)g_heap;
+ AllocBlock *block = first;
+ while (block) {
+ char buffer[100];
+ if (block->free) {
+ snprintf(buffer, sizeof(buffer), "FREE: %d", (int)block->size);
+ } else {
+ snprintf(buffer, sizeof(buffer), "ALOC (0x%08x): %d", (unsigned int)block->id, (int)block->size);
+ }
+ SCPI_ResultText(context, buffer);
+ block = block->next;
+ }
+}
+#endif
+
+void getAllocInfo(uint32_t &free, uint32_t &alloc) {
+ free = 0;
+ alloc = 0;
+ if (EEZ_MUTEX_WAIT(alloc, 0)) {
+ AllocBlock *first = (AllocBlock *)g_heap;
+ AllocBlock *block = first;
+ while (block) {
+ if (block->free) {
+ free += block->size;
+ } else {
+ alloc += block->size;
+ }
+ block = block->next;
+ }
+ EEZ_MUTEX_RELEASE(alloc);
+ }
+}
+
+} // eez
diff --git a/Middlewares/eez/core/alloc.h b/Middlewares/eez/core/alloc.h
new file mode 100644
index 0000000..bd36383
--- /dev/null
+++ b/Middlewares/eez/core/alloc.h
@@ -0,0 +1,53 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+#include
+
+#if OPTION_SCPI
+#include
+#endif
+
+namespace eez {
+
+void initAllocHeap(uint8_t *heap, size_t heapSize);
+
+void *alloc(size_t size, uint32_t id);
+void free(void *ptr);
+
+template struct ObjectAllocator {
+ static T *allocate(uint32_t id) {
+ auto ptr = alloc(sizeof(T), id);
+ return new (ptr) T;
+ }
+ static void deallocate(T* ptr) {
+ ptr->~T();
+ free(ptr);
+ }
+};
+
+#if OPTION_SCPI
+void dumpAlloc(scpi_t *context);
+#endif
+
+void getAllocInfo(uint32_t &free, uint32_t &alloc);
+
+} // eez
\ No newline at end of file
diff --git a/Middlewares/eez/core/debug.cpp b/Middlewares/eez/core/debug.cpp
new file mode 100644
index 0000000..47cd0ee
--- /dev/null
+++ b/Middlewares/eez/core/debug.cpp
@@ -0,0 +1,58 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#ifdef DEBUG
+
+#include
+#include
+#include
+
+#include
+
+namespace eez {
+namespace debug {
+
+void Trace(TraceType traceType, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+
+ static const size_t BUFFER_SIZE = 256;
+ char buffer[BUFFER_SIZE + 1];
+
+ vsnprintf(buffer, BUFFER_SIZE, format, args);
+ buffer[BUFFER_SIZE] = 0;
+
+ va_end(args);
+
+ if (traceType == TRACE_TYPE_DEBUG) {
+ pushDebugTraceHook(buffer, strlen(buffer));
+ } else if (traceType == TRACE_TYPE_INFO) {
+ pushInfoTraceHook(buffer, strlen(buffer));
+ } else {
+ pushErrorTraceHook(buffer, strlen(buffer));
+ }
+}
+
+} // namespace debug
+} // namespace eez
+
+extern "C" void debug_trace(const char *str, size_t len) {
+ eez::debug::pushDebugTraceHook(str, len);
+}
+
+#endif // DEBUG
diff --git a/Middlewares/eez/core/debug.h b/Middlewares/eez/core/debug.h
new file mode 100644
index 0000000..3a8485d
--- /dev/null
+++ b/Middlewares/eez/core/debug.h
@@ -0,0 +1,54 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#ifdef DEBUG
+
+#include
+#include
+
+namespace eez {
+namespace debug {
+
+void pushDebugTraceHook(const char *message, size_t messageLength);
+void pushInfoTraceHook(const char *message, size_t messageLength);
+void pushErrorTraceHook(const char *message, size_t messageLength);
+
+enum TraceType {
+ TRACE_TYPE_DEBUG,
+ TRACE_TYPE_INFO,
+ TRACE_TYPE_ERROR
+};
+
+void Trace(TraceType traceType, const char *format, ...);
+
+} // namespace debug
+} // namespace eez
+
+#define InfoTrace(...) ::eez::debug::Trace(::eez::debug::TRACE_TYPE_INFO, __VA_ARGS__)
+#define ErrorTrace(...) ::eez::debug::Trace(::eez::debug::TRACE_TYPE_ERROR, __VA_ARGS__)
+#define DebugTrace(...) ::eez::debug::Trace(::eez::debug::TRACE_TYPE_DEBUG, __VA_ARGS__)
+
+#else // NO DEBUG
+
+#define InfoTrace(...) 0
+#define ErrorTrace(...) 0
+#define DebugTrace(...) 0
+
+#endif
diff --git a/Middlewares/eez/core/eeprom.cpp b/Middlewares/eez/core/eeprom.cpp
new file mode 100644
index 0000000..4212588
--- /dev/null
+++ b/Middlewares/eez/core/eeprom.cpp
@@ -0,0 +1,211 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2015-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+
+//#include
+//#include
+
+#if defined(EEZ_PLATFORM_STM32) && !CONF_SURVIVE_MODE
+#define USE_EEPROM 1
+#else
+#define USE_EEPROM 0
+#endif
+
+#if defined(EEZ_PLATFORM_STM32)
+#ifdef EEZ_PLATFORM_STM32F469I_DISCO
+#else
+#include
+#endif
+#endif
+
+#if !USE_EEPROM
+#include
+#endif
+
+#if OPTION_SCPI
+#include
+#endif
+
+namespace eez {
+namespace eeprom {
+
+#if defined(EEZ_PLATFORM_STM32)
+// opcodes
+static const uint8_t WREN = 6;
+static const uint8_t WRDI = 4;
+static const uint8_t RDSR = 5;
+static const uint8_t WRSR = 1;
+static const uint8_t READ = 3;
+static const uint8_t WRITE = 2;
+
+// EEPROM AT24C256C
+// I2C-Compatible (2-Wire) Serial EEPROM
+// 256-Kbit (32,768 x 8)
+// http://ww1.microchip.com/downloads/en/devicedoc/atmel-8568-seeprom-at24c256c-datasheet.pdf
+static const uint16_t EEPROM_ADDRESS = 0b10100000;
+#endif
+
+TestResult g_testResult = TEST_FAILED;
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(EEZ_PLATFORM_STM32)
+
+const int MAX_READ_CHUNK_SIZE = 16;
+const int MAX_WRITE_CHUNK_SIZE = 16;
+
+bool readFromEEPROM(uint8_t *buffer, uint16_t bufferSize, uint16_t address) {
+#ifdef EEZ_PLATFORM_STM32F469I_DISCO
+ return false;
+#else
+ for (uint16_t i = 0; i < bufferSize; i += MAX_READ_CHUNK_SIZE) {
+ uint16_t chunkAddress = address + i;
+
+ uint16_t chunkSize = MIN(MAX_READ_CHUNK_SIZE, bufferSize - i);
+
+ uint8_t data[2] = {
+ I2C_MEM_ADD_MSB(chunkAddress),
+ I2C_MEM_ADD_LSB(chunkAddress)
+ };
+
+ HAL_StatusTypeDef returnValue;
+
+ taskENTER_CRITICAL();
+ returnValue = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, data, 2, HAL_MAX_DELAY);
+ if (returnValue != HAL_OK) {
+ taskEXIT_CRITICAL();
+ return false;
+ }
+ returnValue = HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, buffer + i, chunkSize, HAL_MAX_DELAY);
+ taskEXIT_CRITICAL();
+ if (returnValue != HAL_OK) {
+ return false;
+ }
+ }
+
+ return true;
+#endif
+}
+
+bool writeToEEPROM(const uint8_t *buffer, uint16_t bufferSize, uint16_t address) {
+#ifdef EEZ_PLATFORM_STM32F469I_DISCO
+ return false;
+#else
+ for (uint16_t i = 0; i < bufferSize; i += MAX_WRITE_CHUNK_SIZE) {
+ uint16_t chunkAddress = address + i;
+
+ uint16_t chunkSize = MIN(MAX_WRITE_CHUNK_SIZE, bufferSize - i);
+
+ HAL_StatusTypeDef returnValue;
+
+ taskENTER_CRITICAL();
+ returnValue = HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, chunkAddress, I2C_MEMADD_SIZE_16BIT, (uint8_t *)buffer + i, chunkSize, HAL_MAX_DELAY);
+ taskEXIT_CRITICAL();
+
+ if (returnValue != HAL_OK) {
+ return false;
+ }
+
+ osDelay(5);
+
+ // verify
+ uint8_t verify[MAX_WRITE_CHUNK_SIZE];
+
+ uint8_t data[2] = {
+ I2C_MEM_ADD_MSB(chunkAddress),
+ I2C_MEM_ADD_LSB(chunkAddress)
+ };
+
+ taskENTER_CRITICAL();
+ returnValue = HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, data, 2, HAL_MAX_DELAY);
+ if (returnValue != HAL_OK) {
+ taskEXIT_CRITICAL();
+ return false;
+ }
+ returnValue = HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDRESS, verify, chunkSize, HAL_MAX_DELAY);
+ taskEXIT_CRITICAL();
+ if (returnValue != HAL_OK) {
+ return false;
+ }
+
+ for (int j = 0; j < chunkSize; ++j) {
+ if (buffer[i+j] != verify[j]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+#endif
+}
+
+#endif
+
+#if !USE_EEPROM
+const char *EEPROM_FILE_PATH = "/EEPROM.state";
+#endif
+
+bool read(uint8_t *buffer, uint16_t bufferSize, uint16_t address) {
+#if USE_EEPROM
+ return readFromEEPROM(buffer, bufferSize, address);
+#else
+ File file;
+ if (!file.open(EEPROM_FILE_PATH, FILE_READ)) {
+ return false;
+ }
+ file.seek(address);
+ size_t readBytes = file.read(buffer, bufferSize);
+ if (readBytes < bufferSize) {
+ memset(buffer + readBytes, 0xFF, bufferSize - readBytes);
+ }
+ file.close();
+ return true;
+#endif
+}
+
+bool write(const uint8_t *buffer, uint16_t bufferSize, uint16_t address) {
+#if USE_EEPROM
+ return writeToEEPROM(buffer, bufferSize, address);
+#else
+ File file;
+ if (!file.open(EEPROM_FILE_PATH, FILE_OPEN_ALWAYS | FILE_WRITE)) {
+ return false;
+ }
+ file.seek(address);
+ file.write(buffer, bufferSize);
+ file.close();
+ return true;
+#endif
+}
+
+void init() {
+ g_testResult = TEST_OK;
+}
+
+bool test() {
+ // TODO add test
+ return g_testResult == TEST_OK;
+}
+
+} // namespace eeprom
+} // namespace eez
diff --git a/Middlewares/eez/core/eeprom.h b/Middlewares/eez/core/eeprom.h
new file mode 100644
index 0000000..403ea84
--- /dev/null
+++ b/Middlewares/eez/core/eeprom.h
@@ -0,0 +1,39 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2015-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+
+#include
+
+namespace eez {
+namespace eeprom {
+
+static const uint16_t EEPROM_SIZE = 32768;
+
+void init();
+bool test();
+
+extern TestResult g_testResult;
+
+bool read(uint8_t *buffer, uint16_t buffer_size, uint16_t address);
+bool write(const uint8_t *buffer, uint16_t buffer_size, uint16_t address);
+
+} // namespace eeprom
+} // namespace eez
diff --git a/Middlewares/eez/core/encoder.h b/Middlewares/eez/core/encoder.h
new file mode 100644
index 0000000..7c3429d
--- /dev/null
+++ b/Middlewares/eez/core/encoder.h
@@ -0,0 +1,32 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+namespace eez {
+namespace mcu {
+namespace encoder {
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+void write(int counter, bool clicked);
+void setButtonState(bool pressed);
+#endif
+
+} // namespace encoder
+} // namespace mcu
+} // namespace eez
diff --git a/Middlewares/eez/core/hmi.cpp b/Middlewares/eez/core/hmi.cpp
new file mode 100644
index 0000000..acd817b
--- /dev/null
+++ b/Middlewares/eez/core/hmi.cpp
@@ -0,0 +1,61 @@
+/*
+* EEZ PSU Firmware
+* Copyright (C) 2015-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#include
+#include
+
+namespace eez {
+namespace hmi {
+
+#define MAX_GUI_OR_ENCODER_INACTIVITY_TIME_MS 60 * 1000
+
+static uint32_t g_timeOfLastActivity;
+static bool g_inactivityTimeMaxed = true;
+
+void tick() {
+ if (!g_inactivityTimeMaxed) {
+ uint32_t inactivityPeriod = getInactivityPeriodMs();
+ if (inactivityPeriod >= MAX_GUI_OR_ENCODER_INACTIVITY_TIME_MS) {
+ g_inactivityTimeMaxed = true;
+ }
+ }
+}
+
+void noteActivity() {
+ g_timeOfLastActivity = millis();
+ g_inactivityTimeMaxed = false;
+}
+
+uint32_t getInactivityPeriodMs() {
+ if (g_inactivityTimeMaxed) {
+ return MAX_GUI_OR_ENCODER_INACTIVITY_TIME_MS;
+ } else {
+ return millis() - g_timeOfLastActivity;
+ }
+}
+
+uint32_t getTimeOfLastActivity() {
+ if (g_inactivityTimeMaxed) {
+ return millis() - MAX_GUI_OR_ENCODER_INACTIVITY_TIME_MS;
+ } else {
+ return g_timeOfLastActivity;
+ }
+}
+
+} // namespace hmi
+} // namespace eez
\ No newline at end of file
diff --git a/Middlewares/eez/core/hmi.h b/Middlewares/eez/core/hmi.h
new file mode 100644
index 0000000..1b4e78a
--- /dev/null
+++ b/Middlewares/eez/core/hmi.h
@@ -0,0 +1,33 @@
+/*
+* EEZ PSU Firmware
+* Copyright (C) 2017-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace hmi {
+
+void tick();
+
+void noteActivity();
+uint32_t getInactivityPeriodMs();
+uint32_t getTimeOfLastActivity();
+
+}
+} // namespace eez::hmi
diff --git a/Middlewares/eez/core/keyboard.h b/Middlewares/eez/core/keyboard.h
new file mode 100644
index 0000000..59d3c98
--- /dev/null
+++ b/Middlewares/eez/core/keyboard.h
@@ -0,0 +1,285 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2020-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+#include
+
+#if defined(EEZ_PLATFORM_STM32)
+#if OPTION_KEYBOARD
+#include
+#endif
+#endif
+
+#if defined(EEZ_PLATFORM_SIMULATOR) && !defined(__EMSCRIPTEN__)
+#include
+#endif
+
+namespace eez {
+namespace keyboard {
+
+#if defined(EEZ_PLATFORM_STM32)
+#if OPTION_KEYBOARD
+void onKeyboardEvent(USBH_HandleTypeDef *phost);
+#endif
+#endif
+
+#if defined(EEZ_PLATFORM_SIMULATOR) && !defined(__EMSCRIPTEN__)
+void onKeyboardEvent(SDL_KeyboardEvent *key);
+#endif
+
+bool isDisplayDirty();
+void updateDisplay();
+
+void onPageChanged();
+
+static const uint8_t KEY_MOD_LCTRL = 1 << 0;
+static const uint8_t KEY_MOD_LSHIFT = 1 << 1;
+static const uint8_t KEY_MOD_LALT = 1 << 2;
+static const uint8_t KEY_MOD_LGUI = 1 << 3;
+static const uint8_t KEY_MOD_RCTRL = 1 << 4;
+static const uint8_t KEY_MOD_RSHIFT = 1 << 5;
+static const uint8_t KEY_MOD_RALT = 1 << 6;
+static const uint8_t KEY_MOD_RGUI = 1 << 7;
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+#define KEY_NONE 0x00
+#define KEY_ERRORROLLOVER 0x01
+#define KEY_POSTFAIL 0x02
+#define KEY_ERRORUNDEFINED 0x03
+#define KEY_A 0x04
+#define KEY_B 0x05
+#define KEY_C 0x06
+#define KEY_D 0x07
+#define KEY_E 0x08
+#define KEY_F 0x09
+#define KEY_G 0x0A
+#define KEY_H 0x0B
+#define KEY_I 0x0C
+#define KEY_J 0x0D
+#define KEY_K 0x0E
+#define KEY_L 0x0F
+#define KEY_M 0x10
+#define KEY_N 0x11
+#define KEY_O 0x12
+#define KEY_P 0x13
+#define KEY_Q 0x14
+#define KEY_R 0x15
+#define KEY_S 0x16
+#define KEY_T 0x17
+#define KEY_U 0x18
+#define KEY_V 0x19
+#define KEY_W 0x1A
+#define KEY_X 0x1B
+#define KEY_Y 0x1C
+#define KEY_Z 0x1D
+#define KEY_1_EXCLAMATION_MARK 0x1E
+#define KEY_2_AT 0x1F
+#define KEY_3_NUMBER_SIGN 0x20
+#define KEY_4_DOLLAR 0x21
+#define KEY_5_PERCENT 0x22
+#define KEY_6_CARET 0x23
+#define KEY_7_AMPERSAND 0x24
+#define KEY_8_ASTERISK 0x25
+#define KEY_9_OPARENTHESIS 0x26
+#define KEY_0_CPARENTHESIS 0x27
+#define KEY_ENTER 0x28
+#define KEY_ESCAPE 0x29
+#define KEY_BACKSPACE 0x2A
+#define KEY_TAB 0x2B
+#define KEY_SPACEBAR 0x2C
+#define KEY_MINUS_UNDERSCORE 0x2D
+#define KEY_EQUAL_PLUS 0x2E
+#define KEY_OBRACKET_AND_OBRACE 0x2F
+#define KEY_CBRACKET_AND_CBRACE 0x30
+#define KEY_BACKSLASH_VERTICAL_BAR 0x31
+#define KEY_NONUS_NUMBER_SIGN_TILDE 0x32
+#define KEY_SEMICOLON_COLON 0x33
+#define KEY_SINGLE_AND_DOUBLE_QUOTE 0x34
+#define KEY_GRAVE ACCENT AND TILDE 0x35
+#define KEY_COMMA_AND_LESS 0x36
+#define KEY_DOT_GREATER 0x37
+#define KEY_SLASH_QUESTION 0x38
+#define KEY_CAPS LOCK 0x39
+#define KEY_F1 0x3A
+#define KEY_F2 0x3B
+#define KEY_F3 0x3C
+#define KEY_F4 0x3D
+#define KEY_F5 0x3E
+#define KEY_F6 0x3F
+#define KEY_F7 0x40
+#define KEY_F8 0x41
+#define KEY_F9 0x42
+#define KEY_F10 0x43
+#define KEY_F11 0x44
+#define KEY_F12 0x45
+#define KEY_PRINTSCREEN 0x46
+#define KEY_SCROLL LOCK 0x47
+#define KEY_PAUSE 0x48
+#define KEY_INSERT 0x49
+#define KEY_HOME 0x4A
+#define KEY_PAGEUP 0x4B
+#define KEY_DELETE 0x4C
+#define KEY_END1 0x4D
+#define KEY_PAGEDOWN 0x4E
+#define KEY_RIGHTARROW 0x4F
+#define KEY_LEFTARROW 0x50
+#define KEY_DOWNARROW 0x51
+#define KEY_UPARROW 0x52
+#define KEY_KEYPAD_NUM_LOCK_AND_CLEAR 0x53
+#define KEY_KEYPAD_SLASH 0x54
+#define KEY_KEYPAD_ASTERIKS 0x55
+#define KEY_KEYPAD_MINUS 0x56
+#define KEY_KEYPAD_PLUS 0x57
+#define KEY_KEYPAD_ENTER 0x58
+#define KEY_KEYPAD_1_END 0x59
+#define KEY_KEYPAD_2_DOWN_ARROW 0x5A
+#define KEY_KEYPAD_3_PAGEDN 0x5B
+#define KEY_KEYPAD_4_LEFT_ARROW 0x5C
+#define KEY_KEYPAD_5 0x5D
+#define KEY_KEYPAD_6_RIGHT_ARROW 0x5E
+#define KEY_KEYPAD_7_HOME 0x5F
+#define KEY_KEYPAD_8_UP_ARROW 0x60
+#define KEY_KEYPAD_9_PAGEUP 0x61
+#define KEY_KEYPAD_0_INSERT 0x62
+#define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE 0x63
+#define KEY_NONUS_BACK_SLASH_VERTICAL_BAR 0x64
+#define KEY_APPLICATION 0x65
+#define KEY_POWER 0x66
+#define KEY_KEYPAD_EQUAL 0x67
+#define KEY_F13 0x68
+#define KEY_F14 0x69
+#define KEY_F15 0x6A
+#define KEY_F16 0x6B
+#define KEY_F17 0x6C
+#define KEY_F18 0x6D
+#define KEY_F19 0x6E
+#define KEY_F20 0x6F
+#define KEY_F21 0x70
+#define KEY_F22 0x71
+#define KEY_F23 0x72
+#define KEY_F24 0x73
+// #define KEY_EXECUTE 0x74
+#define KEY_HELP 0x75
+#define KEY_MENU 0x76
+#define KEY_SELECT 0x77
+#define KEY_STOP 0x78
+#define KEY_AGAIN 0x79
+#define KEY_UNDO 0x7A
+#define KEY_CUT 0x7B
+#define KEY_COPY 0x7C
+#define KEY_PASTE 0x7D
+#define KEY_FIND 0x7E
+#define KEY_MUTE 0x7F
+#define KEY_VOLUME_UP 0x80
+#define KEY_VOLUME_DOWN 0x81
+#define KEY_LOCKING_CAPS_LOCK 0x82
+#define KEY_LOCKING_NUM_LOCK 0x83
+#define KEY_LOCKING_SCROLL_LOCK 0x84
+#define KEY_KEYPAD_COMMA 0x85
+#define KEY_KEYPAD_EQUAL_SIGN 0x86
+#define KEY_INTERNATIONAL1 0x87
+#define KEY_INTERNATIONAL2 0x88
+#define KEY_INTERNATIONAL3 0x89
+#define KEY_INTERNATIONAL4 0x8A
+#define KEY_INTERNATIONAL5 0x8B
+#define KEY_INTERNATIONAL6 0x8C
+#define KEY_INTERNATIONAL7 0x8D
+#define KEY_INTERNATIONAL8 0x8E
+#define KEY_INTERNATIONAL9 0x8F
+#define KEY_LANG1 0x90
+#define KEY_LANG2 0x91
+#define KEY_LANG3 0x92
+#define KEY_LANG4 0x93
+#define KEY_LANG5 0x94
+#define KEY_LANG6 0x95
+#define KEY_LANG7 0x96
+#define KEY_LANG8 0x97
+#define KEY_LANG9 0x98
+#define KEY_ALTERNATE_ERASE 0x99
+#define KEY_SYSREQ 0x9A
+#define KEY_CANCEL 0x9B
+#define KEY_CLEAR 0x9C
+#define KEY_PRIOR 0x9D
+#define KEY_RETURN 0x9E
+#define KEY_SEPARATOR 0x9F
+#define KEY_OUT 0xA0
+#define KEY_OPER 0xA1
+#define KEY_CLEAR_AGAIN 0xA2
+#define KEY_CRSEL 0xA3
+#define KEY_EXSEL 0xA4
+#define KEY_KEYPAD_00 0xB0
+#define KEY_KEYPAD_000 0xB1
+#define KEY_THOUSANDS_SEPARATOR 0xB2
+#define KEY_DECIMAL_SEPARATOR 0xB3
+#define KEY_CURRENCY_UNIT 0xB4
+#define KEY_CURRENCY_SUB_UNIT 0xB5
+#define KEY_KEYPAD_OPARENTHESIS 0xB6
+#define KEY_KEYPAD_CPARENTHESIS 0xB7
+#define KEY_KEYPAD_OBRACE 0xB8
+#define KEY_KEYPAD_CBRACE 0xB9
+#define KEY_KEYPAD_TAB 0xBA
+#define KEY_KEYPAD_BACKSPACE 0xBB
+#define KEY_KEYPAD_A 0xBC
+#define KEY_KEYPAD_B 0xBD
+#define KEY_KEYPAD_C 0xBE
+#define KEY_KEYPAD_D 0xBF
+#define KEY_KEYPAD_E 0xC0
+#define KEY_KEYPAD_F 0xC1
+#define KEY_KEYPAD_XOR 0xC2
+#define KEY_KEYPAD_CARET 0xC3
+#define KEY_KEYPAD_PERCENT 0xC4
+#define KEY_KEYPAD_LESS 0xC5
+#define KEY_KEYPAD_GREATER 0xC6
+#define KEY_KEYPAD_AMPERSAND 0xC7
+#define KEY_KEYPAD_LOGICAL_AND 0xC8
+#define KEY_KEYPAD_VERTICAL_BAR 0xC9
+#define KEY_KEYPAD_LOGIACL_OR 0xCA
+#define KEY_KEYPAD_COLON 0xCB
+#define KEY_KEYPAD_NUMBER_SIGN 0xCC
+#define KEY_KEYPAD_SPACE 0xCD
+#define KEY_KEYPAD_AT 0xCE
+#define KEY_KEYPAD_EXCLAMATION_MARK 0xCF
+#define KEY_KEYPAD_MEMORY_STORE 0xD0
+#define KEY_KEYPAD_MEMORY_RECALL 0xD1
+#define KEY_KEYPAD_MEMORY_CLEAR 0xD2
+#define KEY_KEYPAD_MEMORY_ADD 0xD3
+#define KEY_KEYPAD_MEMORY_SUBTRACT 0xD4
+#define KEY_KEYPAD_MEMORY_MULTIPLY 0xD5
+#define KEY_KEYPAD_MEMORY_DIVIDE 0xD6
+#define KEY_KEYPAD_PLUSMINUS 0xD7
+#define KEY_KEYPAD_CLEAR 0xD8
+#define KEY_KEYPAD_CLEAR_ENTRY 0xD9
+#define KEY_KEYPAD_BINARY 0xDA
+#define KEY_KEYPAD_OCTAL 0xDB
+#define KEY_KEYPAD_DECIMAL 0xDC
+#define KEY_KEYPAD_HEXADECIMAL 0xDD
+#define KEY_LEFTCONTROL 0xE0
+#define KEY_LEFTSHIFT 0xE1
+#define KEY_LEFTALT 0xE2
+#define KEY_LEFT_GUI 0xE3
+#define KEY_RIGHTCONTROL 0xE4
+#define KEY_RIGHTSHIFT 0xE5
+#define KEY_RIGHTALT 0xE6
+#define KEY_RIGHT_GUI 0xE7
+#endif // EEZ_PLATFORM_STM32
+
+} // keyboard
+} // eez
diff --git a/Middlewares/eez/core/memory.cpp b/Middlewares/eez/core/memory.cpp
new file mode 100644
index 0000000..4175834
--- /dev/null
+++ b/Middlewares/eez/core/memory.cpp
@@ -0,0 +1,99 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2015-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+
+namespace eez {
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+uint8_t g_memory[MEMORY_SIZE] = { 0 };
+#endif
+
+uint8_t *DECOMPRESSED_ASSETS_START_ADDRESS;
+uint8_t *FLOW_TO_DEBUGGER_MESSAGE_BUFFER;
+
+uint8_t *VRAM_BUFFER1_START_ADDRESS;
+uint8_t *VRAM_BUFFER2_START_ADDRESS;
+
+uint8_t *VRAM_ANIMATION_BUFFER1_START_ADDRESS;
+uint8_t *VRAM_ANIMATION_BUFFER2_START_ADDRESS;
+
+uint8_t *VRAM_AUX_BUFFER1_START_ADDRESS;
+uint8_t *VRAM_AUX_BUFFER2_START_ADDRESS;
+uint8_t *VRAM_AUX_BUFFER3_START_ADDRESS;
+uint8_t *VRAM_AUX_BUFFER4_START_ADDRESS;
+uint8_t *VRAM_AUX_BUFFER5_START_ADDRESS;
+uint8_t *VRAM_AUX_BUFFER6_START_ADDRESS;
+
+uint8_t *SCREENSHOOT_BUFFER_START_ADDRESS;
+
+uint8_t *GUI_STATE_BUFFER;
+
+uint8_t *ALLOC_BUFFER;
+uint32_t ALLOC_BUFFER_SIZE;
+
+void initMemory() {
+ initAssetsMemory();
+ initOtherMemory();
+}
+
+void initAssetsMemory() {
+ ALLOC_BUFFER = MEMORY_BEGIN;
+ ALLOC_BUFFER_SIZE = MEMORY_SIZE;
+
+ DECOMPRESSED_ASSETS_START_ADDRESS = allocBuffer(MAX_DECOMPRESSED_ASSETS_SIZE);
+}
+
+void initOtherMemory() {
+ FLOW_TO_DEBUGGER_MESSAGE_BUFFER = allocBuffer(FLOW_TO_DEBUGGER_MESSAGE_BUFFER_SIZE);
+
+ uint32_t VRAM_BUFFER_SIZE = DISPLAY_WIDTH * DISPLAY_HEIGHT * DISPLAY_BPP / 8;
+
+ VRAM_BUFFER1_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_BUFFER2_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+
+ VRAM_ANIMATION_BUFFER1_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_ANIMATION_BUFFER2_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+
+ VRAM_AUX_BUFFER1_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_AUX_BUFFER2_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_AUX_BUFFER3_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_AUX_BUFFER4_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_AUX_BUFFER5_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+ VRAM_AUX_BUFFER6_START_ADDRESS = allocBuffer(VRAM_BUFFER_SIZE);
+
+ GUI_STATE_BUFFER = allocBuffer(GUI_STATE_BUFFER_SIZE);
+
+ SCREENSHOOT_BUFFER_START_ADDRESS = VRAM_ANIMATION_BUFFER1_START_ADDRESS;
+}
+
+uint8_t *allocBuffer(uint32_t size) {
+ size = ((size + 1023) / 1024) * 1024;
+
+ auto buffer = ALLOC_BUFFER;
+
+ assert(ALLOC_BUFFER_SIZE > size);
+ ALLOC_BUFFER += size;
+ ALLOC_BUFFER_SIZE -= size;
+
+ return buffer;
+}
+
+} // eez
diff --git a/Middlewares/eez/core/memory.h b/Middlewares/eez/core/memory.h
new file mode 100644
index 0000000..248474b
--- /dev/null
+++ b/Middlewares/eez/core/memory.h
@@ -0,0 +1,84 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2015-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace eez {
+
+#if defined(EEZ_PLATFORM_STM32)
+static uint8_t * const MEMORY_BEGIN = (uint8_t *)0xc0000000u;
+#if CONF_OPTION_FPGA
+static const uint32_t MEMORY_SIZE = 32 * 1024 * 1024;
+#elif defined(EEZ_PLATFORM_STM32F469I_DISCO)
+static const uint32_t MEMORY_SIZE = 16 * 1024 * 1024;
+#else
+static const uint32_t MEMORY_SIZE = 8 * 1024 * 1024;
+#endif
+#endif
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+extern uint8_t g_memory[];
+static uint8_t * const MEMORY_BEGIN = g_memory;
+static const uint32_t MEMORY_SIZE = 64 * 1024 * 1024;
+#endif
+
+extern uint8_t *ALLOC_BUFFER;
+extern uint32_t ALLOC_BUFFER_SIZE;
+
+extern uint8_t *DECOMPRESSED_ASSETS_START_ADDRESS;
+#if defined(EEZ_PLATFORM_STM32)
+static const uint32_t MAX_DECOMPRESSED_ASSETS_SIZE = 2 * 1024 * 1024;
+#endif
+#if defined(EEZ_PLATFORM_SIMULATOR)
+static const uint32_t MAX_DECOMPRESSED_ASSETS_SIZE = 8 * 1024 * 1024;
+#endif
+
+extern uint8_t *FLOW_TO_DEBUGGER_MESSAGE_BUFFER;
+#if defined(EEZ_PLATFORM_STM32)
+static const uint32_t FLOW_TO_DEBUGGER_MESSAGE_BUFFER_SIZE = 32 * 1024;
+#endif
+#if defined(EEZ_PLATFORM_SIMULATOR)
+static const uint32_t FLOW_TO_DEBUGGER_MESSAGE_BUFFER_SIZE = 1024 * 1024;
+#endif
+
+extern uint8_t *VRAM_BUFFER1_START_ADDRESS;
+extern uint8_t *VRAM_BUFFER2_START_ADDRESS;
+
+extern uint8_t *VRAM_ANIMATION_BUFFER1_START_ADDRESS;
+extern uint8_t *VRAM_ANIMATION_BUFFER2_START_ADDRESS;
+
+extern uint8_t *VRAM_AUX_BUFFER1_START_ADDRESS;
+extern uint8_t *VRAM_AUX_BUFFER2_START_ADDRESS;
+extern uint8_t *VRAM_AUX_BUFFER3_START_ADDRESS;
+extern uint8_t *VRAM_AUX_BUFFER4_START_ADDRESS;
+extern uint8_t *VRAM_AUX_BUFFER5_START_ADDRESS;
+extern uint8_t *VRAM_AUX_BUFFER6_START_ADDRESS;
+
+extern uint8_t* SCREENSHOOT_BUFFER_START_ADDRESS;
+
+extern uint8_t* GUI_STATE_BUFFER;
+
+void initMemory();
+void initAssetsMemory();
+void initOtherMemory();
+uint8_t *allocBuffer(uint32_t size);
+
+} // eez
diff --git a/Middlewares/eez/core/mouse.h b/Middlewares/eez/core/mouse.h
new file mode 100644
index 0000000..6c38e5e
--- /dev/null
+++ b/Middlewares/eez/core/mouse.h
@@ -0,0 +1,38 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2020-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace mouse {
+
+bool isMouseEnabled();
+
+bool isDisplayDirty();
+void updateDisplay();
+
+void onPageChanged();
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+void onMouseEvent(bool mouseButton1IsPressed, int mouseX, int mouseY);
+#endif
+
+} // mouse
+} // eez
diff --git a/Middlewares/eez/core/os.cpp b/Middlewares/eez/core/os.cpp
new file mode 100644
index 0000000..3ed285f
--- /dev/null
+++ b/Middlewares/eez/core/os.cpp
@@ -0,0 +1,37 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#if defined(EEZ_PLATFORM_STM32)
+#include
+#endif
+
+#include
+
+namespace eez {
+
+uint32_t millis() {
+#if defined(EEZ_PLATFORM_STM32)
+ return HAL_GetTick();
+#endif
+
+#if defined(EEZ_PLATFORM_SIMULATOR)
+ return osKernelGetTickCount();
+#endif
+}
+
+} // namespace eez
diff --git a/Middlewares/eez/core/os.h b/Middlewares/eez/core/os.h
new file mode 100644
index 0000000..ae5a16e
--- /dev/null
+++ b/Middlewares/eez/core/os.h
@@ -0,0 +1,102 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+
+#include "cmsis_os2.h"
+
+#if defined(EEZ_PLATFORM_STM32)
+#include "FreeRTOS.h"
+#include "task.h"
+#endif
+
+#define EEZ_THREAD_DECLARE(NAME, PRIORITY, STACK_SIZE) \
+ osThreadId_t g_##NAME##TaskHandle; \
+ const osThreadAttr_t g_##NAME##TaskAttributes = { \
+ #NAME, \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ STACK_SIZE, \
+ osPriority##PRIORITY, \
+ 0, \
+ 0, \
+ }
+#define EEZ_THREAD_CREATE(NAME, THREAD_FUNC) g_##NAME##TaskHandle = osThreadNew(THREAD_FUNC, nullptr, &g_##NAME##TaskAttributes);
+#define EEZ_THREAD_TERMINATE(NAME) osThreadTerminate(g_##NAME##TaskHandle)
+
+#define EEZ_MESSAGE_QUEUE_DECLARE(NAME, OBJECT_DEF) \
+ struct NAME##MessageQueueObject OBJECT_DEF; \
+ osMessageQueueId_t g_##NAME##MessageQueueId
+#define EEZ_MESSAGE_QUEUE_CREATE(NAME, QUEUE_SIZE) g_##NAME##MessageQueueId = osMessageQueueNew(QUEUE_SIZE, sizeof(NAME##MessageQueueObject), nullptr)
+#define EEZ_MESSAGE_QUEUE_GET(NAME, OBJ, TIMEOUT) (osMessageQueueGet(g_##NAME##MessageQueueId, &OBJ, nullptr, TIMEOUT) == osOK)
+#define EEZ_MESSAGE_QUEUE_PUT(NAME, OBJ, TIMEOUT) osMessageQueuePut(g_##NAME##MessageQueueId, &OBJ, 0, TIMEOUT)
+
+#define EEZ_MUTEX_DECLARE(NAME) \
+ osMutexId_t g_##NAME##mutexId;\
+ const osMutexAttr_t g_##NAME##mutexAttr = { \
+ #NAME, \
+ osMutexRecursive | osMutexPrioInherit, \
+ NULL, \
+ 0U \
+ }
+#define EEZ_MUTEX_CREATE(NAME) g_##NAME##mutexId = osMutexNew(&g_##NAME##mutexAttr)
+#define EEZ_MUTEX_WAIT(NAME, TIMEOUT) osMutexAcquire(g_##NAME##mutexId, TIMEOUT) == osOK
+#define EEZ_MUTEX_RELEASE(NAME) osMutexRelease(g_##NAME##mutexId)
+
+#if defined(__EMSCRIPTEN__)
+#ifndef EM_PORT_API
+# if defined(__EMSCRIPTEN__)
+# include
+# if defined(__cplusplus)
+# define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
+# else
+# define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
+# endif
+# else
+# if defined(__cplusplus)
+# define EM_PORT_API(rettype) extern "C" rettype
+# else
+# define EM_PORT_API(rettype) rettype
+# endif
+# endif
+#endif
+#else
+# define EM_PORT_API(rettype) rettype
+#endif
+
+namespace eez {
+
+enum TestResult {
+ TEST_NONE,
+ TEST_FAILED,
+ TEST_OK,
+ TEST_CONNECTING,
+ TEST_SKIPPED,
+ TEST_WARNING
+};
+
+uint32_t millis();
+
+extern bool g_shutdown;
+void shutdown();
+
+} // namespace eez
diff --git a/Middlewares/eez/core/sound.h b/Middlewares/eez/core/sound.h
new file mode 100644
index 0000000..74ea996
--- /dev/null
+++ b/Middlewares/eez/core/sound.h
@@ -0,0 +1,51 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2015-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace sound {
+
+void init();
+void tick();
+
+/// Play power up tune.
+enum PlayPowerUpCondition {
+ PLAY_POWER_UP_CONDITION_NONE,
+ PLAY_POWER_UP_CONDITION_TEST_SUCCESSFUL,
+ PLAY_POWER_UP_CONDITION_WELCOME_PAGE_IS_ACTIVE
+};
+
+void playPowerUp(PlayPowerUpCondition condition);
+
+/// Play power down tune.
+void playPowerDown();
+
+/// Play beep sound.
+void playBeep(bool force = false);
+
+/// Play click sound
+void playClick();
+
+/// Play shutter sound
+void playShutter();
+
+} // namespace sound
+} // namespace eez
diff --git a/Middlewares/eez/core/step_values.h b/Middlewares/eez/core/step_values.h
new file mode 100644
index 0000000..780a303
--- /dev/null
+++ b/Middlewares/eez/core/step_values.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include
+
+namespace eez {
+
+enum EncoderMode {
+ ENCODER_MODE_MIN,
+ ENCODER_MODE_AUTO = ENCODER_MODE_MIN,
+ ENCODER_MODE_STEP1,
+ ENCODER_MODE_STEP2,
+ ENCODER_MODE_STEP3,
+ ENCODER_MODE_STEP4,
+ ENCODER_MODE_STEP5,
+ ENCODER_MODE_MAX = ENCODER_MODE_STEP5
+};
+
+struct StepValues {
+ int count;
+ const float *values;
+ Unit unit;
+ struct {
+ bool accelerationEnabled;
+ float range;
+ float step;
+ EncoderMode mode;
+ } encoderSettings;
+};
+
+} // namespace eez
\ No newline at end of file
diff --git a/Middlewares/eez/core/unit.cpp b/Middlewares/eez/core/unit.cpp
new file mode 100644
index 0000000..3be5fc9
--- /dev/null
+++ b/Middlewares/eez/core/unit.cpp
@@ -0,0 +1,309 @@
+ /*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#include
+
+#include
+
+#if OPTION_SCPI
+#include
+#endif
+
+namespace eez {
+
+const char *g_unitNames[] = {
+ "", // UNIT_NONE
+ "V", // UNIT_VOLT
+ "mV", // UNIT_MILLI_VOLT
+ "A", // UNIT_AMPER
+ "mA", // UNIT_MILLI_AMPER
+ "uA", // UNIT_MICRO_AMPER
+ "W", // UNIT_WATT
+ "mW", // UNIT_MILLI_WATT
+ "s", // UNIT_SECOND
+ "ms", // UNIT_MILLI_SECOND
+ DEGREE_SYMBOL"C", // UNIT_CELSIUS
+ "rpm", // UNIT_RPM
+ "\xb4", // UNIT_OHM
+ "K\xb4", // UNIT_KOHM
+ "M\xb4", // UNIT_MOHM
+ "%", // UNIT_PERCENT
+ "Hz", // UNIT_HERTZ
+ "mHz", // UNIT_MILLI_HERTZ
+ "KHz", // UNIT_KHERTZ
+ "MHz", // UNIT_MHERTZ
+ "J", // UNIT_JOULE
+ "F", // UNIT_FARAD
+ "mF", // UNIT_MILLI_FARAD
+ "uF", // UNIT_MICRO_FARAD
+ "nF", // UNIT_NANO_FARAD
+ "pF", // UNIT_PICO_FARAD
+ "minutes", // UNIT_MINUTE
+ "VA", // UNIT_VOLT_AMPERE
+ "VAR", // UNIT_VOLT_AMPERE_REACTIVE
+ DEGREE_SYMBOL, // UNIT_DEGREE
+ "Vpp", // UNIT_VOLT_PP
+ "mVpp", // UNIT_MILLI_VOLT_PP
+ "App", // UNIT_AMPER_PP
+ "mApp", // UNIT_MILLI_AMPER_PP
+ "uApp", // UNIT_MICRO_AMPER_PP
+};
+
+const Unit g_baseUnit[] = {
+ UNIT_NONE, // UNIT_NONE
+ UNIT_VOLT, // UNIT_VOLT
+ UNIT_VOLT, // UNIT_MILLI_VOLT
+ UNIT_AMPER, // UNIT_AMPER
+ UNIT_AMPER, // UNIT_MILLI_AMPER
+ UNIT_AMPER, // UNIT_MICRO_AMPER
+ UNIT_WATT, // UNIT_WATT
+ UNIT_WATT, // UNIT_MILLI_WATT
+ UNIT_SECOND, // UNIT_SECOND
+ UNIT_SECOND, // UNIT_MILLI_SECOND
+ UNIT_CELSIUS, // UNIT_CELSIUS
+ UNIT_RPM, // UNIT_RPM
+ UNIT_OHM, // UNIT_OHM
+ UNIT_OHM, // UNIT_KOHM
+ UNIT_OHM, // UNIT_MOHM
+ UNIT_PERCENT, // UNIT_PERCENT
+ UNIT_HERTZ, // UNIT_HERTZ
+ UNIT_HERTZ, // UNIT_MILLI_HERTZ
+ UNIT_HERTZ, // UNIT_KHERTZ
+ UNIT_HERTZ, // UNIT_MHERTZ
+ UNIT_JOULE, // UNIT_JOULE
+ UNIT_FARAD, // UNIT_FARAD
+ UNIT_FARAD, // UNIT_MILLI_FARAD
+ UNIT_FARAD, // UNIT_MICRO_FARAD
+ UNIT_FARAD, // UNIT_NANO_FARAD
+ UNIT_FARAD, // UNIT_PICO_FARAD
+ UNIT_SECOND, // UNIT_MINUTE
+ UNIT_VOLT_AMPERE, // UNIT_VOLT_AMPERE
+ UNIT_VOLT_AMPERE, //UNIT_VOLT_AMPERE_REACTIVE
+ UNIT_DEGREE, // UNIT_DEGREE
+ UNIT_VOLT_PP, // UNIT_VOLT_PP
+ UNIT_VOLT_PP, // UNIT_MILLI_VOLT_PP
+ UNIT_AMPER_PP, // UNIT_AMPER_PP
+ UNIT_AMPER_PP, // UNIT_MILLI_AMPER_PP
+ UNIT_AMPER_PP, // UNIT_MICRO_AMPER_PP
+};
+
+const float g_unitFactor[] = {
+ 1.0f, // UNIT_NONE
+ 1.0f, // UNIT_VOLT
+ 1E-3f, // UNIT_MILLI_VOLT
+ 1.0f, // UNIT_AMPER
+ 1E-3f, // UNIT_MILLI_AMPER
+ 1E-6f, // UNIT_MICRO_AMPER
+ 1.0f, // UNIT_WATT
+ 1E-3f, // UNIT_MILLI_WATT
+ 1.0f, // UNIT_SECOND
+ 1E-3f, // UNIT_MILLI_SECOND
+ 1.0f, // UNIT_CELSIUS
+ 1.0f, // UNIT_RPM
+ 1.0f, // UNIT_OHM
+ 1E3f, // UNIT_KOHM
+ 1E6f, // UNIT_MOHM
+ 1.0f, // UNIT_PERCENT
+ 1.0f, // UNIT_HERTZ
+ 1E-3f, // UNIT_MILLI_HERTZ
+ 1E3f, // UNIT_KHERTZ
+ 1E6f, // UNIT_MHERTZ
+ 1.0f, // UNIT_JOULE
+ 1.0f, // UNIT_FARAD
+ 1E-3f, // UNIT_MILLI_FARAD
+ 1E-6f, // UNIT_MICRO_FARAD
+ 1E-9f, // UNIT_NANO_FARAD
+ 1E-12f, // UNIT_PICO_FARAD
+ 60.0f, // UNIT_MINUTE
+ 1.0f, // UNIT_VOLT_AMPERE
+ 1.0f, //UNIT_VOLT_AMPERE_REACTIVE
+ 1.0f, // UNIT_DEGREE
+ 1.0f, // UNIT_VOLT_PP
+ 1E-3f, // UNIT_MILLI_VOLT_PP
+ 1.0f, // UNIT_AMPER_PP
+ 1E-3f, // UNIT_MILLI_AMPER_PP
+ 1E-6f, // UNIT_MICRO_AMPER_PP
+};
+
+#if OPTION_SCPI
+static const int g_scpiUnits[] = {
+ SCPI_UNIT_NONE, // UNIT_NONE
+ SCPI_UNIT_VOLT, // UNIT_VOLT
+ SCPI_UNIT_VOLT, // UNIT_MILLI_VOLT
+ SCPI_UNIT_AMPER, // UNIT_AMPER
+ SCPI_UNIT_AMPER, // UNIT_MILLI_AMPER
+ SCPI_UNIT_AMPER, // UNIT_MICRO_AMPER
+ SCPI_UNIT_WATT, // UNIT_WATT
+ SCPI_UNIT_WATT, // UNIT_MILLI_WATT
+ SCPI_UNIT_SECOND, // UNIT_SECOND
+ SCPI_UNIT_SECOND, // UNIT_MILLI_SECOND
+ SCPI_UNIT_CELSIUS, // UNIT_CELSIUS
+ SCPI_UNIT_NONE, // UNIT_RPM
+ SCPI_UNIT_OHM, // UNIT_OHM
+ SCPI_UNIT_OHM, // UNIT_KOHM
+ SCPI_UNIT_OHM, // UNIT_MOHM
+ SCPI_UNIT_NONE, // UNIT_PERCENT
+ SCPI_UNIT_HERTZ, // UNIT_HERTZ
+ SCPI_UNIT_HERTZ, // UNIT_MILLI_HERTZ
+ SCPI_UNIT_HERTZ, // UNIT_KHERTZ
+ SCPI_UNIT_HERTZ, // UNIT_MHERTZ
+ SCPI_UNIT_JOULE, // UNIT_JOULE
+ SCPI_UNIT_FARAD, // UNIT_FARAD
+ SCPI_UNIT_FARAD, // UNIT_MILLI_FARAD
+ SCPI_UNIT_FARAD, // UNIT_MICRO_FARAD
+ SCPI_UNIT_FARAD, // UNIT_NANO_FARAD
+ SCPI_UNIT_FARAD, // UNIT_PICO_FARAD
+ SCPI_UNIT_SECOND, // UNIT_MINUTE
+ SCPI_UNIT_WATT, // UNIT_VOLT_AMPERE
+ SCPI_UNIT_WATT, // UNIT_VOLT_AMPERE_REACTIVE
+ SCPI_UNIT_DEGREE, // UNIT_DEGREE
+ SCPI_UNIT_VOLT, // UNIT_VOLT_PP
+ SCPI_UNIT_VOLT, // UNIT_MILLI_VOLT_PP
+ SCPI_UNIT_AMPER, // UNIT_AMPER_PP
+ SCPI_UNIT_AMPER, // UNIT_MILLI_AMPER_PP
+ SCPI_UNIT_AMPER, // UNIT_MICRO_AMPER_PP
+};
+#endif
+
+Unit getUnitFromName(const char *unitName) {
+ if (unitName) {
+ for (unsigned i = 0; i < sizeof(g_unitNames) / sizeof(const char *); i++) {
+ if (strcmp(g_unitNames[i], unitName) == 0) {
+ return (Unit)i;
+ }
+ }
+ }
+ return UNIT_NONE;
+}
+
+#if OPTION_SCPI
+int getScpiUnit(Unit unit) {
+ if (unit == UNIT_UNKNOWN) {
+ return SCPI_UNIT_NONE;
+ }
+ return g_scpiUnits[unit];
+}
+#endif
+
+Unit getBaseUnit(Unit unit) {
+ if (unit == UNIT_UNKNOWN) {
+ return UNIT_UNKNOWN;
+ }
+ return g_baseUnit[unit];
+}
+
+float getUnitFactor(Unit unit) {
+ if (unit == UNIT_UNKNOWN) {
+ return 1.0f;
+ }
+ return g_unitFactor[unit];
+}
+
+static Unit getDerivedUnit(Unit unit, float factor) {
+ if (unit == UNIT_UNKNOWN) {
+ return UNIT_UNKNOWN;
+ }
+
+ for (size_t i = 0; i < sizeof(g_baseUnit); i++) {
+ if (g_baseUnit[i] == g_baseUnit[unit] && g_unitFactor[i] == factor) {
+ return (Unit)i;
+ }
+ }
+
+ return UNIT_UNKNOWN;
+}
+
+static const float FACTORS[] = { 1E-12F, 1E-9F, 1E-6F, 1E-3F, 1E0F, 1E3F, 1E6F, 1E9F, 1E12F };
+
+Unit findDerivedUnit(float value, Unit unit) {
+ Unit result;
+
+ for (int factorIndex = 1; ; factorIndex++) {
+ float factor = FACTORS[factorIndex];
+ if (factor > 1.0F) {
+ break;
+ }
+ if (value < factor) {
+ result = getDerivedUnit(unit, FACTORS[factorIndex - 1]);
+ if (result != UNIT_UNKNOWN) {
+ return result;
+ }
+ }
+ }
+
+ for (int factorIndex = sizeof(FACTORS) / sizeof(float) - 1; factorIndex >= 0; factorIndex--) {
+ float factor = FACTORS[factorIndex];
+ if (factor == 1.0F) {
+ break;
+ }
+ if (value >= factor) {
+ result = getDerivedUnit(unit, factor);
+ if (result != UNIT_UNKNOWN) {
+ return result;
+ }
+ }
+ }
+
+ return unit;
+}
+
+float getSmallerFactor(float factor) {
+ for (int factorIndex = sizeof(FACTORS) / sizeof(float) - 1; factorIndex > 0; factorIndex--) {
+ float itFactor = FACTORS[factorIndex];
+ if (itFactor < factor) {
+ return itFactor;
+ }
+ }
+ return FACTORS[0];
+}
+
+Unit getSmallerUnit(Unit unit, float min, float precision) {
+ float factor = getUnitFactor(unit);
+ if (precision <= factor || min <= factor) {
+ return getDerivedUnit(unit, getSmallerFactor(factor));
+ }
+ return UNIT_UNKNOWN;
+}
+
+Unit getBiggestUnit(Unit unit, float max) {
+ for (int factorIndex = sizeof(FACTORS) / sizeof(float) - 1; factorIndex >= 0; factorIndex--) {
+ float factor = FACTORS[factorIndex];
+ if (max >= factor) {
+ auto result = getDerivedUnit(unit, factor);
+ if (result != UNIT_UNKNOWN) {
+ return result;
+ }
+ }
+ }
+ return UNIT_UNKNOWN;
+}
+
+Unit getSmallestUnit(Unit unit, float min, float precision) {
+ for (int factorIndex = 0; factorIndex < int(sizeof(FACTORS) / sizeof(float)); factorIndex++) {
+ float factor = FACTORS[factorIndex];
+ if (precision <= factor || min <= factor) {
+ auto result = getDerivedUnit(unit, factor);
+ if (result != UNIT_UNKNOWN) {
+ return result;
+ }
+ }
+ }
+ return UNIT_UNKNOWN;
+}
+
+} // namespace eez
diff --git a/Middlewares/eez/core/unit.h b/Middlewares/eez/core/unit.h
new file mode 100644
index 0000000..cb287fd
--- /dev/null
+++ b/Middlewares/eez/core/unit.h
@@ -0,0 +1,94 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#define INFINITY_SYMBOL "\x91"
+#define DEGREE_SYMBOL "\x8a"
+
+namespace eez {
+
+// order of units should not be changed since it is used in DLOG files
+enum Unit {
+ UNIT_UNKNOWN = 255,
+ UNIT_NONE = 0,
+ UNIT_VOLT,
+ UNIT_MILLI_VOLT,
+ UNIT_AMPER,
+ UNIT_MILLI_AMPER,
+ UNIT_MICRO_AMPER,
+ UNIT_WATT,
+ UNIT_MILLI_WATT,
+ UNIT_SECOND,
+ UNIT_MILLI_SECOND,
+ UNIT_CELSIUS,
+ UNIT_RPM,
+ UNIT_OHM,
+ UNIT_KOHM,
+ UNIT_MOHM,
+ UNIT_PERCENT,
+ UNIT_HERTZ,
+ UNIT_MILLI_HERTZ,
+ UNIT_KHERTZ,
+ UNIT_MHERTZ,
+ UNIT_JOULE,
+ UNIT_FARAD,
+ UNIT_MILLI_FARAD,
+ UNIT_MICRO_FARAD,
+ UNIT_NANO_FARAD,
+ UNIT_PICO_FARAD,
+ UNIT_MINUTE,
+ UNIT_VOLT_AMPERE,
+ UNIT_VOLT_AMPERE_REACTIVE,
+ UNIT_DEGREE,
+ UNIT_VOLT_PP,
+ UNIT_MILLI_VOLT_PP,
+ UNIT_AMPER_PP,
+ UNIT_MILLI_AMPER_PP,
+ UNIT_MICRO_AMPER_PP,
+};
+
+extern const char *g_unitNames[];
+
+inline const char *getUnitName(Unit unit) {
+ if (unit == UNIT_UNKNOWN) {
+ return "";
+ }
+ return g_unitNames[unit];
+}
+
+Unit getUnitFromName(const char *unitName);
+
+#if OPTION_SCPI
+int getScpiUnit(Unit unit);
+#endif
+
+// for UNIT_MILLI_VOLT returns UNIT_VOLT, etc...
+Unit getBaseUnit(Unit unit);
+
+// returns 1.0 form UNIT_VOLT, returns 1E-3 for UNIT_MILLI_VOLT, 1E-6 for UNIT_MICRO_AMPER, 1E3 for UNIT_KOHM, etc
+float getUnitFactor(Unit unit);
+
+// if value is 0.01 and unit is UNIT_VOLT returns UNIT_MILLI_VOLT, etc
+Unit findDerivedUnit(float value, Unit unit);
+
+Unit getSmallerUnit(Unit unit, float min, float precision);
+Unit getBiggestUnit(Unit unit, float max);
+Unit getSmallestUnit(Unit unit, float min, float precision);
+
+} // namespace eez
\ No newline at end of file
diff --git a/Middlewares/eez/core/utf8.h b/Middlewares/eez/core/utf8.h
new file mode 100644
index 0000000..114d7c2
--- /dev/null
+++ b/Middlewares/eez/core/utf8.h
@@ -0,0 +1,43 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+#ifndef UTF8_SUPPORT
+#define UTF8_SUPPORT 1
+#endif
+
+#if UTF8_SUPPORT
+
+#include
+
+#else
+
+typedef char utf8_int8_t;
+typedef int32_t utf8_int32_t;
+
+inline const utf8_int8_t* utf8codepoint(const utf8_int8_t *str, utf8_int32_t *out_codepoint) {
+ *out_codepoint = *((uint8_t *)str);
+ return str + 1;
+}
+
+#define utf8len strlen
+
+#endif
diff --git a/Middlewares/eez/core/util.cpp b/Middlewares/eez/core/util.cpp
new file mode 100644
index 0000000..1699111
--- /dev/null
+++ b/Middlewares/eez/core/util.cpp
@@ -0,0 +1,921 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#include
+
+#define _USE_MATH_DEFINES
+#include
+#include
+#include
+#include
+
+#if defined(EEZ_PLATFORM_STM32)
+#include
+#endif
+
+namespace eez {
+
+float remap(float x, float x1, float y1, float x2, float y2) {
+ return y1 + (x - x1) * (y2 - y1) / (x2 - x1);
+}
+
+float remapQuad(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t * t;
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapOutQuad(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t * (2 - t);
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapInOutQuad(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t < .5 ? 2 * t*t : -1 + (4 - 2 * t)*t;
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapCubic(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t * t * t;
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapOutCubic(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t - 1;
+ t = 1 + t * t * t;
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapExp(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t == 0 ? 0 : float(pow(2, 10 * (t - 1)));
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float remapOutExp(float x, float x1, float y1, float x2, float y2) {
+ float t = remap(x, x1, 0, x2, 1);
+ t = t == 1 ? 1 : float(1 - pow(2, -10 * t));
+ x = remap(t, 0, x1, 1, x2);
+ return remap(x, x1, y1, x2, y2);
+}
+
+float clamp(float x, float min, float max) {
+ if (x < min) {
+ return min;
+ }
+ if (x > max) {
+ return max;
+ }
+ return x;
+}
+
+void stringCopy(char *dst, size_t maxStrLength, const char *src) {
+ strncpy(dst, src, maxStrLength);
+ dst[maxStrLength - 1] = 0;
+}
+
+void stringCopyLength(char *dst, size_t maxStrLength, const char *src, size_t length) {
+ size_t n = MIN(length, maxStrLength);
+ strncpy(dst, src, n);
+ dst[n] = 0;
+}
+
+void stringAppendString(char *str, size_t maxStrLength, const char *value) {
+ int n = maxStrLength - strlen(str) - 1;
+ if (n >= 0) {
+ strncat(str, value, n);
+ }
+}
+
+void stringAppendStringLength(char *str, size_t maxStrLength, const char *value, size_t length) {
+ int n = MIN(maxStrLength - strlen(str) - 1, length);
+ if (n >= 0) {
+ strncat(str, value, n);
+ }
+}
+
+void stringAppendInt(char *str, size_t maxStrLength, int value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%d", value);
+}
+
+void stringAppendUInt32(char *str, size_t maxStrLength, uint32_t value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%lu", (unsigned long)value);
+}
+
+void stringAppendInt64(char *str, size_t maxStrLength, int64_t value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%jd", value);
+}
+
+void stringAppendUInt64(char *str, size_t maxStrLength, uint64_t value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%ju", value);
+}
+
+void stringAppendFloat(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%g", value);
+}
+
+void stringAppendFloat(char *str, size_t maxStrLength, float value, int numDecimalPlaces) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%.*f", numDecimalPlaces, value);
+}
+
+void stringAppendDouble(char *str, size_t maxStrLength, double value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%g", value);
+}
+
+void stringAppendDouble(char *str, size_t maxStrLength, double value, int numDecimalPlaces) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%.*f", numDecimalPlaces, value);
+}
+
+void stringAppendVoltage(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%g V", value);
+}
+
+void stringAppendCurrent(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%g A", value);
+}
+
+void stringAppendPower(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ snprintf(str + n, maxStrLength - n, "%g W", value);
+}
+
+void stringAppendDuration(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ if (value > 0.1) {
+ snprintf(str + n, maxStrLength - n, "%g s", value);
+ } else {
+ snprintf(str + n, maxStrLength - n, "%g ms", value * 1000);
+ }
+}
+
+void stringAppendLoad(char *str, size_t maxStrLength, float value) {
+ auto n = strlen(str);
+ if (value < 1000) {
+ snprintf(str + n, maxStrLength - n, "%g ohm", value);
+ } else if (value < 1000000) {
+ snprintf(str + n, maxStrLength - n, "%g Kohm", value / 1000);
+ } else {
+ snprintf(str + n, maxStrLength - n, "%g Mohm", value / 1000000);
+ }
+}
+
+#if defined(EEZ_PLATFORM_STM32)
+uint32_t crc32(const uint8_t *mem_block, size_t block_size) {
+ return HAL_CRC_Calculate(&hcrc, (uint32_t *)mem_block, block_size);
+}
+#else
+/*
+From http://www.hackersdelight.org/hdcodetxt/crc.c.txt:
+
+This is the basic CRC-32 calculation with some optimization but no
+table lookup. The the byte reversal is avoided by shifting the crc reg
+right instead of left and by using a reversed 32-bit word to represent
+the polynomial.
+When compiled to Cyclops with GCC, this function executes in 8 + 72n
+instructions, where n is the number of bytes in the input message. It
+should be doable in 4 + 61n instructions.
+If the inner loop is strung out (approx. 5*8 = 40 instructions),
+it would take about 6 + 46n instructions.
+*/
+
+uint32_t crc32(const uint8_t *mem_block, size_t block_size) {
+ uint32_t crc = 0xFFFFFFFF;
+ for (size_t i = 0; i < block_size; ++i) {
+ uint32_t byte = mem_block[i]; // Get next byte.
+ crc = crc ^ byte;
+ for (int j = 0; j < 8; ++j) { // Do eight times.
+ uint32_t mask = -((int32_t)crc & 1);
+ crc = (crc >> 1) ^ (0xEDB88320 & mask);
+ }
+ }
+ return ~crc;
+}
+#endif
+
+uint8_t toBCD(uint8_t bin) {
+ return ((bin / 10) << 4) | (bin % 10);
+}
+
+uint8_t fromBCD(uint8_t bcd) {
+ return ((bcd >> 4) & 0xF) * 10 + (bcd & 0xF);
+}
+
+float roundPrec(float a, float prec) {
+ float r = 1 / prec;
+ return roundf(a * r) / r;
+}
+
+float floorPrec(float a, float prec) {
+ float r = 1 / prec;
+ return floorf(a * r) / r;
+}
+
+float ceilPrec(float a, float prec) {
+ float r = 1 / prec;
+ return ceilf(a * r) / r;
+}
+
+bool isNaN(float x) {
+ return x != x;
+}
+
+bool isNaN(double x) {
+ return x != x;
+}
+
+bool isDigit(char ch) {
+ return ch >= '0' && ch <= '9';
+}
+
+bool isHexDigit(char ch) {
+ return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
+}
+
+bool isUperCaseLetter(char ch) {
+ return ch >= 'A' && ch <= 'Z';
+}
+
+char toHexDigit(int num) {
+ if (num >= 0 && num <= 9) {
+ return '0' + num;
+ } else {
+ return 'A' + (num - 10);
+ }
+}
+
+int fromHexDigit(char ch) {
+ if (ch >= '0' && ch <= '9') {
+ return ch - '0';
+ }
+
+ if (ch >= 'a' && ch <= 'f') {
+ return 10 + (ch - 'a');
+ }
+
+ return 10 + (ch - 'A');
+}
+
+bool pointInsideRect(int xPoint, int yPoint, int xRect, int yRect, int wRect, int hRect) {
+ return xPoint >= xRect && xPoint < xRect + wRect && yPoint >= yRect && yPoint < yRect + hRect;
+}
+
+void getParentDir(const char *path, char *parentDirPath) {
+ int lastPathSeparatorIndex;
+
+ for (lastPathSeparatorIndex = strlen(path) - 1;
+ lastPathSeparatorIndex >= 0 && path[lastPathSeparatorIndex] != PATH_SEPARATOR[0];
+ --lastPathSeparatorIndex)
+ ;
+
+ int i;
+ for (i = 0; i < lastPathSeparatorIndex; ++i) {
+ parentDirPath[i] = path[i];
+ }
+ parentDirPath[i] = 0;
+}
+
+bool parseMacAddress(const char *macAddressStr, size_t macAddressStrLength, uint8_t *macAddress) {
+ int state = 0;
+ int a = 0;
+ int i = 0;
+ uint8_t resultMacAddress[6];
+
+ const char *end = macAddressStr + macAddressStrLength;
+ for (const char *p = macAddressStr; p < end; ++p) {
+ if (state == 0) {
+ if (*p == '-' || *p == ' ') {
+ continue;
+ } else if (isHexDigit(*p)) {
+ a = fromHexDigit(*p);
+ state = 1;
+ } else {
+ return false;
+ }
+ } else if (state == 1) {
+ if (isHexDigit(*p)) {
+ if (i < 6) {
+ resultMacAddress[i++] = (a << 4) | fromHexDigit(*p);
+ state = 0;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ if (state != 0 || i != 6) {
+ return false;
+ }
+
+ memcpy(macAddress, resultMacAddress, 6);
+
+ return true;
+}
+
+bool parseIpAddress(const char *ipAddressStr, size_t ipAddressStrLength, uint32_t &ipAddress) {
+ const char *p = ipAddressStr;
+ const char *q = ipAddressStr + ipAddressStrLength;
+
+ uint8_t ipAddressArray[4];
+
+ for (int i = 0; i < 4; ++i) {
+ if (p == q) {
+ return false;
+ }
+
+ uint32_t part = 0;
+ for (int j = 0; j < 3; ++j) {
+ if (p == q) {
+ if (j > 0 && i == 3) {
+ break;
+ } else {
+ return false;
+ }
+ } else if (isDigit(*p)) {
+ part = part * 10 + (*p++ - '0');
+ } else if (j > 0 && *p == '.') {
+ break;
+ } else {
+ return false;
+ }
+ }
+
+ if (part > 255) {
+ return false;
+ }
+
+ if ((i < 3 && *p++ != '.') || (i == 3 && p != q)) {
+ return false;
+ }
+
+ ipAddressArray[i] = part;
+ }
+
+ ipAddress = arrayToIpAddress(ipAddressArray);
+
+ return true;
+}
+
+int getIpAddressPartA(uint32_t ipAddress) {
+ return ((uint8_t *)&ipAddress)[0];
+}
+
+void setIpAddressPartA(uint32_t *ipAddress, uint8_t value) {
+ ((uint8_t *)ipAddress)[0] = value;
+}
+
+int getIpAddressPartB(uint32_t ipAddress) {
+ return ((uint8_t *)&ipAddress)[1];
+}
+
+void setIpAddressPartB(uint32_t *ipAddress, uint8_t value) {
+ ((uint8_t *)ipAddress)[1] = value;
+}
+
+int getIpAddressPartC(uint32_t ipAddress) {
+ return ((uint8_t *)&ipAddress)[2];
+}
+
+void setIpAddressPartC(uint32_t *ipAddress, uint8_t value) {
+ ((uint8_t *)ipAddress)[2] = value;
+}
+
+int getIpAddressPartD(uint32_t ipAddress) {
+ return ((uint8_t *)&ipAddress)[3];
+}
+
+void setIpAddressPartD(uint32_t *ipAddress, uint8_t value) {
+ ((uint8_t *)ipAddress)[3] = value;
+}
+
+void ipAddressToArray(uint32_t ipAddress, uint8_t *ipAddressArray) {
+ ipAddressArray[0] = getIpAddressPartA(ipAddress);
+ ipAddressArray[1] = getIpAddressPartB(ipAddress);
+ ipAddressArray[2] = getIpAddressPartC(ipAddress);
+ ipAddressArray[3] = getIpAddressPartD(ipAddress);
+}
+
+uint32_t arrayToIpAddress(uint8_t *ipAddressArray) {
+ return getIpAddress(ipAddressArray[0], ipAddressArray[1], ipAddressArray[2], ipAddressArray[3]);
+}
+
+uint32_t getIpAddress(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+ uint32_t ipAddress;
+
+ setIpAddressPartA(&ipAddress, a);
+ setIpAddressPartB(&ipAddress, b);
+ setIpAddressPartC(&ipAddress, c);
+ setIpAddressPartD(&ipAddress, d);
+
+ return ipAddress;
+}
+
+void ipAddressToString(uint32_t ipAddress, char *ipAddressStr, size_t maxIpAddressStrLength) {
+ snprintf(ipAddressStr, maxIpAddressStrLength, "%d.%d.%d.%d",
+ getIpAddressPartA(ipAddress), getIpAddressPartB(ipAddress),
+ getIpAddressPartC(ipAddress), getIpAddressPartD(ipAddress));
+}
+
+void macAddressToString(const uint8_t *macAddress, char *macAddressStr) {
+ for (int i = 0; i < 6; ++i) {
+ macAddressStr[3 * i] = toHexDigit((macAddress[i] & 0xF0) >> 4);
+ macAddressStr[3 * i + 1] = toHexDigit(macAddress[i] & 0xF);
+ macAddressStr[3 * i + 2] = i < 5 ? '-' : 0;
+ }
+}
+
+void formatTimeZone(int16_t timeZone, char *text, int count) {
+ if (timeZone == 0) {
+ stringCopy(text, count, "GMT");
+ } else {
+ char sign;
+ int16_t value;
+ if (timeZone > 0) {
+ sign = '+';
+ value = timeZone;
+ } else {
+ sign = '-';
+ value = -timeZone;
+ }
+ snprintf(text, count, "%c%02d:%02d GMT", sign, value / 100, value % 100);
+ }
+}
+
+bool parseTimeZone(const char *timeZoneStr, size_t timeZoneLength, int16_t &timeZone) {
+ int state = 0;
+
+ int sign = 1;
+ int integerPart = 0;
+ int fractionPart = 0;
+
+ const char *end = timeZoneStr + timeZoneLength;
+ for (const char *p = timeZoneStr; p < end; ++p) {
+ if (*p == ' ') {
+ continue;
+ }
+
+ if (state == 0) {
+ if (*p == '+') {
+ state = 1;
+ } else if (*p == '-') {
+ sign = -1;
+ state = 1;
+ } else if (isDigit(*p)) {
+ integerPart = *p - '0';
+ state = 2;
+ } else {
+ return false;
+ }
+ } else if (state == 1) {
+ if (isDigit(*p)) {
+ integerPart = (*p - '0');
+ state = 2;
+ } else {
+ return false;
+ }
+ } else if (state == 2) {
+ if (*p == ':') {
+ state = 4;
+ } else if (isDigit(*p)) {
+ integerPart = integerPart * 10 + (*p - '0');
+ state = 3;
+ } else {
+ return false;
+ }
+ } else if (state == 3) {
+ if (*p == ':') {
+ state = 4;
+ } else {
+ return false;
+ }
+ } else if (state == 4) {
+ if (isDigit(*p)) {
+ fractionPart = (*p - '0');
+ state = 5;
+ } else {
+ return false;
+ }
+ } else if (state == 5) {
+ if (isDigit(*p)) {
+ fractionPart = fractionPart * 10 + (*p - '0');
+ state = 6;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ if (state != 2 && state != 3 && state != 6) {
+ return false;
+ }
+
+ int value = sign * (integerPart * 100 + fractionPart);
+
+ if (value < -1200 || value > 1400) {
+ return false;
+ }
+
+ timeZone = (int16_t)value;
+
+ return true;
+}
+
+void replaceCharacter(char *str, char ch, char repl) {
+ while (*str) {
+ if (*str == ch) {
+ *str = repl;
+ }
+ ++str;
+ }
+}
+
+int strcicmp(char const *a, char const *b) {
+ for (;; a++, b++) {
+ int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
+ if (d != 0 || !*a)
+ return d;
+ }
+}
+
+int strncicmp(char const *a, char const *b, int n) {
+ for (; n--; a++, b++) {
+ int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
+ if (d != 0 || !*a)
+ return d;
+ }
+ return 0;
+}
+
+bool isStringEmpty(char const *s) {
+ for (; *s; s++) {
+ if (!isspace(*s)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool startsWith(const char *str, const char *prefix) {
+ if (!str || !prefix)
+ return false;
+ size_t strLen = strlen(str);
+ size_t prefixLen = strlen(prefix);
+ if (prefixLen > strLen)
+ return false;
+ return strncmp(str, prefix, prefixLen) == 0;
+}
+
+bool startsWithNoCase(const char *str, const char *prefix) {
+ if (!str || !prefix)
+ return false;
+ size_t strLen = strlen(str);
+ size_t prefixLen = strlen(prefix);
+ if (prefixLen > strLen)
+ return false;
+ return strncicmp(str, prefix, prefixLen) == 0;
+}
+
+bool endsWith(const char *str, const char *suffix) {
+ if (!str || !suffix)
+ return false;
+ size_t strLen = strlen(str);
+ size_t suffixLen = strlen(suffix);
+ if (suffixLen > strLen)
+ return false;
+ return strncmp(str + strLen - suffixLen, suffix, suffixLen) == 0;
+}
+
+bool endsWithNoCase(const char *str, const char *suffix) {
+ if (!str || !suffix)
+ return false;
+ size_t strLen = strlen(str);
+ size_t suffixLen = strlen(suffix);
+ if (suffixLen > strLen)
+ return false;
+ return strncicmp(str + strLen - suffixLen, suffix, suffixLen) == 0;
+}
+
+void formatBytes(uint64_t bytes, char *text, int count) {
+ if (bytes == 0) {
+ stringCopy(text, count, "0 Bytes");
+ } else {
+ double c = 1024.0;
+ const char *e[] = { "Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
+ uint64_t f = (uint64_t)floor(log((double)bytes) / log(c));
+ double g = round((bytes / pow(c, (double)f)) * 100) / 100;
+ snprintf(text, count, "%g %s", g, e[f]);
+ }
+}
+
+void getFileName(const char *path, char *fileName, unsigned fileNameSize) {
+ const char *a = strrchr(path, '/');
+ if (a) {
+ a++;
+ } else {
+ a = path;
+ }
+
+ const char *b = path + strlen(path);
+
+ unsigned n = b - a;
+ n = MIN(fileNameSize - 1, n);
+ if (n > 0) {
+ memcpy(fileName, a, n);
+ }
+ fileName[n] = 0;
+}
+
+void getBaseFileName(const char *path, char *baseName, unsigned baseNameSize) {
+ const char *a = strrchr(path, '/');
+ if (a) {
+ a++;
+ } else {
+ a = path;
+ }
+
+ const char *b = strrchr(path, '.');
+ if (!b || !(b >= a)) {
+ b = path + strlen(path);
+ }
+
+ unsigned n = b - a;
+ n = MIN(baseNameSize - 1, n);
+ if (n > 0) {
+ memcpy(baseName, a, n);
+ }
+ baseName[n] = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static const float PI = (float)M_PI;
+static const float c1 = 1.70158f;
+static const float c2 = c1 * 1.525f;
+static const float c3 = c1 + 1.0f;
+static const float c4 = (2 * PI) / 3;
+static const float c5 = (2 * PI) / 4.5f;
+
+float linear(float x) {
+ return x;
+}
+
+float easeInQuad(float x) {
+ return x * x;
+}
+
+float easeOutQuad(float x) {
+ return 1 - (1 - x) * (1 - x);
+}
+
+float easeInOutQuad(float x) {
+ return x < 0.5f ? 2 * x * x : 1 - powf(-2 * x + 2, 2) / 2;
+}
+
+float easeInCubic(float x) {
+ return x * x * x;
+}
+
+float easeOutCubic(float x) {
+ return 1 - pow(1 - x, 3);
+}
+
+float easeInOutCubic(float x) {
+ return x < 0.5f ? 4 * x * x * x : 1 - powf(-2 * x + 2, 3) / 2;
+}
+
+float easeInQuart(float x) {
+ return x * x * x * x;
+}
+
+float easeOutQuart(float x) {
+ return 1 - powf(1 - x, 4);
+}
+
+float easeInOutQuart(float x) {
+ return x < 0.5 ? 8 * x * x * x * x : 1 - powf(-2 * x + 2, 4) / 2;
+}
+
+float easeInQuint(float x) {
+ return x * x * x * x * x;
+}
+
+float easeOutQuint(float x) {
+ return 1 - powf(1 - x, 5);
+}
+
+float easeInOutQuint(float x) {
+ return x < 0.5f ? 16 * x * x * x * x * x : 1 - powf(-2 * x + 2, 5) / 2;
+}
+
+float easeInSine(float x) {
+ return 1 - cosf((x * PI) / 2);
+}
+
+float easeOutSine(float x) {
+ return sinf((x * PI) / 2);
+}
+
+float easeInOutSine(float x) {
+ return -(cosf(PI * x) - 1) / 2;
+}
+
+float easeInExpo(float x) {
+ return x == 0 ? 0 : powf(2, 10 * x - 10);
+}
+
+float easeOutExpo(float x) {
+ return x == 1 ? 1 : 1 - powf(2, -10 * x);
+}
+
+float easeInOutExpo(float x) {
+ return x == 0
+ ? 0
+ : x == 1
+ ? 1
+ : x < 0.5
+ ? powf(2, 20 * x - 10) / 2
+ : (2 - powf(2, -20 * x + 10)) / 2;
+}
+
+float easeInCirc(float x) {
+ return 1 - sqrtf(1 - powf(x, 2));
+}
+
+float easeOutCirc(float x) {
+ return sqrtf(1 - powf(x - 1, 2));
+}
+
+float easeInOutCirc(float x) {
+ return x < 0.5
+ ? (1 - sqrtf(1 - pow(2 * x, 2))) / 2
+ : (sqrtf(1 - powf(-2 * x + 2, 2)) + 1) / 2;
+}
+
+float easeInBack(float x) {
+ return c3 * x * x * x - c1 * x * x;
+}
+
+float easeOutBack(float x) {
+ return 1 + c3 * powf(x - 1, 3) + c1 * powf(x - 1, 2);
+}
+
+float easeInOutBack(float x) {
+ return x < 0.5
+ ? (powf(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
+ : (powf(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
+}
+
+float easeInElastic(float x) {
+ return x == 0
+ ? 0
+ : x == 1
+ ? 1
+ : -powf(2, 10 * x - 10) * sinf((x * 10 - 10.75f) * c4);
+}
+
+float easeOutElastic(float x) {
+ return x == 0
+ ? 0
+ : x == 1
+ ? 1
+ : powf(2, -10 * x) * sinf((x * 10 - 0.75f) * c4) + 1;
+}
+
+float easeInOutElastic(float x) {
+ return x == 0
+ ? 0
+ : x == 1
+ ? 1
+ : x < 0.5
+ ? -(powf(2, 20 * x - 10) * sinf((20 * x - 11.125f) * c5)) / 2
+ : (powf(2, -20 * x + 10) * sinf((20 * x - 11.125f) * c5)) / 2 + 1;
+}
+
+float easeOutBounce(float x);
+
+float easeInBounce(float x) {
+ return 1 -easeOutBounce(1 - x);
+}
+
+float easeOutBounce(float x) {
+ static const float n1 = 7.5625f;
+ static const float d1 = 2.75f;
+
+ if (x < 1 / d1) {
+ return n1 * x * x;
+ } else if (x < 2 / d1) {
+ x -= 1.5f / d1;
+ return n1 * x * x + 0.75f;
+ } else if (x < 2.5f / d1) {
+ x -= 2.25f / d1;
+ return n1 * x * x + 0.9375f;
+ } else {
+ x -= 2.625f / d1;
+ return n1 * x * x + 0.984375f;
+ }
+};
+
+float easeInOutBounce(float x) {
+ return x < 0.5
+ ? (1 - easeOutBounce(1 - 2 * x)) / 2
+ : (1 + easeOutBounce(2 * x - 1)) / 2;
+}
+
+EasingFuncType g_easingFuncs[] = {
+ linear,
+ easeInQuad,
+ easeOutQuad,
+ easeInOutQuad,
+ easeInCubic,
+ easeOutCubic,
+ easeInOutCubic,
+ easeInQuart,
+ easeOutQuart,
+ easeInOutQuart,
+ easeInQuint,
+ easeOutQuint,
+ easeInOutQuint,
+ easeInSine,
+ easeOutSine,
+ easeInOutSine,
+ easeInExpo,
+ easeOutExpo,
+ easeInOutExpo,
+ easeInCirc,
+ easeOutCirc,
+ easeInOutCirc,
+ easeInBack,
+ easeOutBack,
+ easeInOutBack,
+ easeInElastic,
+ easeOutElastic,
+ easeInOutElastic,
+ easeInBounce,
+ easeOutBounce,
+ easeInOutBounce,
+};
+
+} // namespace eez
+
+#ifdef EEZ_PLATFORM_SIMULATOR_WIN32
+char *strnstr(const char *s1, const char *s2, size_t n) {
+ char c = *s2;
+
+ if (c == '\0')
+ return (char *)s1;
+
+ for (size_t len = strlen(s2); len <= n; n--, s1++) {
+ if (*s1 == c) {
+ for (size_t i = 1;; i++) {
+ if (i == len) {
+ return (char *)s1;
+ }
+ if (s1[i] != s2[i]) {
+ break;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+#endif
diff --git a/Middlewares/eez/core/util.h b/Middlewares/eez/core/util.h
new file mode 100644
index 0000000..d561697
--- /dev/null
+++ b/Middlewares/eez/core/util.h
@@ -0,0 +1,209 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2018-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+
+#define clear_bit(reg, bitmask) *reg &= ~bitmask
+#define set_bit(reg, bitmask) *reg |= bitmask
+#define util_swap(type, i, j) \
+ { \
+ type t = i; \
+ i = j; \
+ j = t; \
+ }
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define PATH_SEPARATOR "/"
+
+namespace eez {
+
+float remap(float x, float x1, float y1, float x2, float y2);
+float remapQuad(float x, float x1, float y1, float x2, float y2);
+float remapOutQuad(float x, float x1, float y1, float x2, float y2);
+float remapInOutQuad(float x, float x1, float y1, float x2, float y2);
+float remapCubic(float x, float x1, float y1, float x2, float y2);
+float remapOutCubic(float x, float x1, float y1, float x2, float y2);
+float remapExp(float x, float x1, float y1, float x2, float y2);
+float remapOutExp(float x, float x1, float y1, float x2, float y2);
+float clamp(float x, float min, float max);
+
+void stringCopy(char *dst, size_t maxStrLength, const char *src);
+void stringCopyLength(char *dst, size_t maxStrLength, const char *src, size_t length);
+
+void stringAppendString(char *str, size_t maxStrLength, const char *value);
+void stringAppendStringLength(char *str, size_t maxStrLength, const char *value, size_t length);
+
+void stringAppendInt(char *str, size_t maxStrLength, int value);
+void stringAppendUInt32(char *str, size_t maxStrLength, uint32_t value);
+void stringAppendInt64(char *str, size_t maxStrLength, int64_t value);
+void stringAppendUInt64(char *str, size_t maxStrLength, uint64_t value);
+void stringAppendFloat(char *str, size_t maxStrLength, float value);
+void stringAppendFloat(char *str, size_t maxStrLength, float value, int numDecimalPlaces);
+void stringAppendDouble(char *str, size_t maxStrLength, double value);
+void stringAppendDouble(char *str, size_t maxStrLength, double value, int numDecimalPlaces);
+
+void stringAppendVoltage(char *str, size_t maxStrLength, float value);
+void stringAppendCurrent(char *str, size_t maxStrLength, float value);
+void stringAppendPower(char *str, size_t maxStrLength, float value);
+void stringAppendDuration(char *str, size_t maxStrLength, float value);
+void stringAppendLoad(char *str, size_t maxStrLength, float value);
+
+uint32_t crc32(const uint8_t *message, size_t size);
+
+uint8_t toBCD(uint8_t bin);
+uint8_t fromBCD(uint8_t bcd);
+
+float roundPrec(float a, float prec);
+float floorPrec(float a, float prec);
+float ceilPrec(float a, float prec);
+
+bool isNaN(float x);
+bool isNaN(double x);
+
+bool isDigit(char ch);
+bool isHexDigit(char ch);
+bool isUperCaseLetter(char ch);
+
+char toHexDigit(int num);
+int fromHexDigit(char ch);
+
+bool pointInsideRect(int xPoint, int yPoint, int xRect, int yRect, int wRect, int hRect);
+
+void getParentDir(const char *path, char *parentDirPath);
+
+bool parseMacAddress(const char *macAddressStr, size_t macAddressStrLength, uint8_t *macAddress);
+
+int getIpAddressPartA(uint32_t ipAddress);
+void setIpAddressPartA(uint32_t *ipAddress, uint8_t value);
+
+int getIpAddressPartB(uint32_t ipAddress);
+void setIpAddressPartB(uint32_t *ipAddress, uint8_t value);
+
+int getIpAddressPartC(uint32_t ipAddress);
+void setIpAddressPartC(uint32_t *ipAddress, uint8_t value);
+
+int getIpAddressPartD(uint32_t ipAddress);
+void setIpAddressPartD(uint32_t *ipAddress, uint8_t value);
+
+void ipAddressToArray(uint32_t ipAddress, uint8_t *ipAddressArray);
+uint32_t arrayToIpAddress(uint8_t *ipAddressArray);
+
+uint32_t getIpAddress(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
+
+bool parseIpAddress(const char *ipAddressStr, size_t ipAddressStrLength, uint32_t &ipAddress);
+void ipAddressToString(uint32_t ipAddress, char *ipAddressStr, size_t maxIpAddressStrLength);
+
+void macAddressToString(const uint8_t *macAddress, char *macAddressStr);
+
+void formatTimeZone(int16_t timeZone, char *text, int count);
+bool parseTimeZone(const char *timeZoneStr, size_t timeZoneLength, int16_t &timeZone);
+
+void replaceCharacter(char *str, char ch, char repl);
+
+int strcicmp(char const *a, char const *b);
+int strncicmp(char const *a, char const *b, int n);
+bool isStringEmpty(char const *a);
+bool startsWith(const char *str, const char *prefix);
+bool startsWithNoCase(const char *str, const char *prefix);
+bool endsWith(const char *str, const char *suffix);
+bool endsWithNoCase(const char *str, const char *suffix);
+
+void formatBytes(uint64_t bytes, char *text, int count);
+
+void getFileName(const char *path, char *fileName, unsigned fileNameSize);
+void getBaseFileName(const char *path, char *baseName, unsigned baseNameSize);
+
+typedef float (*EasingFuncType)(float x);
+extern EasingFuncType g_easingFuncs[];
+
+class Interval {
+public:
+ // Returns true when called for the first time,
+ // and later returns true after interval, interval * 2, interval * 3, ...
+ // Interval is in milliseconds.
+ bool test(uint32_t interval) {
+ auto time = millis();
+
+ if (lastTime == 0) {
+ lastTime = time == 0 ? 1 : time;
+ return true;
+ }
+
+ if (time >= lastTime + interval) {
+ lastTime += ((uint32_t)(time - lastTime) / interval) * interval;
+ return true;
+ }
+
+ return false;
+ }
+
+private:
+ uint32_t lastTime = 0;
+};
+
+template
+class MovingAverage {
+public:
+ void operator()(T sample) {
+ if (m_numSamples < N) {
+ m_samples[m_numSamples++] = sample;
+ m_total += sample;
+ } else {
+ T& oldest = m_samples[m_numSamples++ % N];
+ m_total += sample - oldest;
+ oldest = sample;
+ }
+ }
+
+ operator T() const {
+ if (m_numSamples < N) {
+ return m_total / m_numSamples;
+ } else {
+ return m_total / N;
+ }
+ }
+
+ void reset() {
+ m_numSamples = 0;
+ m_total = 0;
+ }
+
+private:
+ T m_samples[N];
+ uint64_t m_numSamples{0};
+ Total m_total{0};
+};
+
+} // namespace eez
+
+#ifdef EEZ_PLATFORM_SIMULATOR_WIN32
+char *strnstr(const char *s1, const char *s2, size_t n);
+#endif
diff --git a/Middlewares/eez/core/value_types.h b/Middlewares/eez/core/value_types.h
new file mode 100644
index 0000000..c097440
--- /dev/null
+++ b/Middlewares/eez/core/value_types.h
@@ -0,0 +1,66 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2020-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+
+#define VALUE_TYPES \
+ VALUE_TYPE(UNDEFINED) /* 0 */ \
+ VALUE_TYPE(NULL) /* 1 */ \
+ VALUE_TYPE(BOOLEAN) /* 2 */ \
+ VALUE_TYPE(INT8) /* 3 */ \
+ VALUE_TYPE(UINT8) /* 4 */ \
+ VALUE_TYPE(INT16) /* 5 */ \
+ VALUE_TYPE(UINT16) /* 6 */ \
+ VALUE_TYPE(INT32) /* 7 */ \
+ VALUE_TYPE(UINT32) /* 8 */ \
+ VALUE_TYPE(INT64) /* 9 */ \
+ VALUE_TYPE(UINT64) /* 10 */ \
+ VALUE_TYPE(FLOAT) /* 11 */ \
+ VALUE_TYPE(DOUBLE) /* 12 */ \
+ VALUE_TYPE(STRING) /* 13 */ \
+ VALUE_TYPE(ARRAY) /* 14 */ \
+ VALUE_TYPE(STRING_REF) /* 15 */ \
+ VALUE_TYPE(ARRAY_REF) /* 16 */ \
+ VALUE_TYPE(BLOB_REF) /* 17 */ \
+ VALUE_TYPE(STREAM) /* 18 */ \
+ VALUE_TYPE(DATE) /* 19 */ \
+ VALUE_TYPE(VERSIONED_STRING) /* 20 */ \
+ VALUE_TYPE(VALUE_PTR) /* 21 */ \
+ VALUE_TYPE(ARRAY_ELEMENT_VALUE) /* 22 */ \
+ VALUE_TYPE(FLOW_OUTPUT) /* 23 */ \
+ VALUE_TYPE(NATIVE_VARIABLE) /* 24 */ \
+ VALUE_TYPE(RANGE) /* 25 */ \
+ VALUE_TYPE(POINTER) /* 26 */ \
+ VALUE_TYPE(ENUM) /* 27 */ \
+ VALUE_TYPE(IP_ADDRESS) /* 28 */ \
+ VALUE_TYPE(TIME_ZONE) /* 29 */ \
+ VALUE_TYPE(YT_DATA_GET_VALUE_FUNCTION_POINTER) /* 30 */ \
+ CUSTOM_VALUE_TYPES
+
+namespace eez {
+
+#define VALUE_TYPE(NAME) VALUE_TYPE_##NAME,
+enum ValueType {
+ VALUE_TYPES
+};
+#undef VALUE_TYPE
+
+}
diff --git a/Middlewares/eez/flow/components.cpp b/Middlewares/eez/flow/components.cpp
new file mode 100644
index 0000000..aa27e0c
--- /dev/null
+++ b/Middlewares/eez/flow/components.cpp
@@ -0,0 +1,142 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#if defined(__EMSCRIPTEN__)
+#include
+#endif
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeStartComponent(FlowState *flowState, unsigned componentIndex);
+void executeEndComponent(FlowState *flowState, unsigned componentIndex);
+void executeInputComponent(FlowState *flowState, unsigned componentIndex);
+void executeOutputComponent(FlowState *flowState, unsigned componentIndex);
+void executeWatchVariableComponent(FlowState *flowState, unsigned componentIndex);
+void executeEvalExprComponent(FlowState *flowState, unsigned componentIndex);
+void executeSetVariableComponent(FlowState *flowState, unsigned componentIndex);
+void executeSwitchComponent(FlowState *flowState, unsigned componentIndex);
+void executeCompareComponent(FlowState *flowState, unsigned componentIndex);
+void executeIsTrueComponent(FlowState *flowState, unsigned componentIndex);
+void executeConstantComponent(FlowState *flowState, unsigned componentIndex);
+void executeLogComponent(FlowState *flowState, unsigned componentIndex);
+void executeCallActionComponent(FlowState *flowState, unsigned componentIndex);
+void executeDelayComponent(FlowState *flowState, unsigned componentIndex);
+void executeErrorComponent(FlowState *flowState, unsigned componentIndex);
+void executeCatchErrorComponent(FlowState *flowState, unsigned componentIndex);
+void executeCounterComponent(FlowState *flowState, unsigned componentIndex);
+void executeLoopComponent(FlowState *flowState, unsigned componentIndex);
+void executeShowPageComponent(FlowState *flowState, unsigned componentIndex);
+void executeShowMessageBoxComponent(FlowState *flowState, unsigned componentIndex);
+void executeShowKeyboardComponent(FlowState *flowState, unsigned componentIndex);
+void executeShowKeypadComponent(FlowState *flowState, unsigned componentIndex);
+void executeSelectLanguageComponent(FlowState *flowState, unsigned componentIndex);
+void executeSetPageDirectionComponent(FlowState *flowState, unsigned componentIndex);
+void executeAnimateComponent(FlowState *flowState, unsigned componentIndex);
+void executeNoopComponent(FlowState *flowState, unsigned componentIndex);
+void executeOnEventComponent(FlowState *flowState, unsigned componentIndex);
+
+void executeLayoutViewWidgetComponent(FlowState *flowState, unsigned componentIndex);
+void executeRollerWidgetComponent(FlowState *flowState, unsigned componentIndex);
+
+typedef void (*ExecuteComponentFunctionType)(FlowState *flowState, unsigned componentIndex);
+
+static ExecuteComponentFunctionType g_executeComponentFunctions[] = {
+ executeStartComponent,
+ executeEndComponent,
+ executeInputComponent,
+ executeOutputComponent,
+ executeWatchVariableComponent,
+ executeEvalExprComponent,
+ executeSetVariableComponent,
+ executeSwitchComponent,
+ executeCompareComponent,
+ executeIsTrueComponent,
+ executeConstantComponent,
+ executeLogComponent,
+ executeCallActionComponent,
+ executeDelayComponent,
+ executeErrorComponent,
+ executeCatchErrorComponent,
+ executeCounterComponent, // COMPONENT_TYPE_COUNTER_ACTION
+ executeLoopComponent,
+ executeShowPageComponent,
+ nullptr, // COMPONENT_TYPE_SCPIACTION
+ executeShowMessageBoxComponent,
+ executeShowKeyboardComponent,
+ executeShowKeypadComponent,
+ executeNoopComponent, // COMPONENT_TYPE_NOOP_ACTION
+ nullptr, // COMPONENT_TYPE_COMMENT_ACTION
+ executeSelectLanguageComponent, // COMPONENT_TYPE_SELECT_LANGUAGE_ACTION
+ executeSetPageDirectionComponent, // COMPONENT_TYPE_SET_PAGE_DIRECTION_ACTION
+ executeAnimateComponent, // COMPONENT_TYPE_ANIMATE_ACTION
+ executeOnEventComponent, // COMPONENT_TYPE_ON_EVENT_ACTION
+};
+
+void registerComponent(ComponentTypes componentType, ExecuteComponentFunctionType executeComponentFunction) {
+ if (componentType >= defs_v3::COMPONENT_TYPE_START_ACTION) {
+ g_executeComponentFunctions[componentType - defs_v3::COMPONENT_TYPE_START_ACTION] = executeComponentFunction;
+ }
+}
+
+void executeComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = flowState->flow->components[componentIndex];
+
+#if defined(__EMSCRIPTEN__)
+ if (component->type >= defs_v3::FIRST_DASHBOARD_COMPONENT_TYPE) {
+ if (executeDashboardComponentHook) {
+ executeDashboardComponentHook(component->type, getFlowStateIndex(flowState), componentIndex);
+ return;
+ }
+ } else
+#endif // __EMSCRIPTEN__
+ if (component->type >= defs_v3::COMPONENT_TYPE_START_ACTION) {
+ auto executeComponentFunction = g_executeComponentFunctions[component->type - defs_v3::COMPONENT_TYPE_START_ACTION];
+ if (executeComponentFunction != nullptr) {
+ executeComponentFunction(flowState, componentIndex);
+ return;
+ }
+ } else if (component->type < 1000) {
+ if (component->type == defs_v3::COMPONENT_TYPE_LAYOUT_VIEW_WIDGET) {
+ executeLayoutViewWidgetComponent(flowState, componentIndex);
+ } else if (component->type == defs_v3::COMPONENT_TYPE_ROLLER_WIDGET) {
+ executeRollerWidgetComponent(flowState, componentIndex);
+ }
+ return;
+ }
+
+ char errorMessage[100];
+ snprintf(errorMessage, sizeof(errorMessage), "Unknown component at index = %d, type = %d\n", componentIndex, component->type);
+ throwError(flowState, componentIndex, errorMessage);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components.h b/Middlewares/eez/flow/components.h
new file mode 100644
index 0000000..e7a18b1
--- /dev/null
+++ b/Middlewares/eez/flow/components.h
@@ -0,0 +1,35 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+namespace eez {
+namespace flow {
+
+using defs_v3::ComponentTypes;
+
+typedef void (*ExecuteComponentFunctionType)(FlowState *flowState, unsigned componentIndex);
+void registerComponent(ComponentTypes componentType, ExecuteComponentFunctionType executeComponentFunction);
+
+void executeComponent(FlowState *flowState, unsigned componentIndex);
+
+} // flow
+} // eez
\ No newline at end of file
diff --git a/Middlewares/eez/flow/components/animate.cpp b/Middlewares/eez/flow/components/animate.cpp
new file mode 100644
index 0000000..41968a2
--- /dev/null
+++ b/Middlewares/eez/flow/components/animate.cpp
@@ -0,0 +1,110 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct AnimateComponenentExecutionState : public ComponenentExecutionState {
+ float startPosition;
+ float endPosition;
+ float speed;
+ uint32_t startTimestamp;
+};
+
+void executeAnimateComponent(FlowState *flowState, unsigned componentIndex) {
+ auto state = (AnimateComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (!state) {
+ Value fromValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::ANIMATE_ACTION_COMPONENT_PROPERTY_FROM, fromValue, "Failed to evaluate From in Animate")) {
+ return;
+ }
+
+ Value toValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::ANIMATE_ACTION_COMPONENT_PROPERTY_TO, toValue, "Failed to evaluate To in Animate")) {
+ return;
+ }
+
+ Value speedValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::ANIMATE_ACTION_COMPONENT_PROPERTY_SPEED, speedValue, "Failed to evaluate Speed in Animate")) {
+ return;
+ }
+
+ float from = fromValue.toFloat();
+ float to = toValue.toFloat();
+ float speed = speedValue.toFloat();
+
+ if (speed == 0) {
+ flowState->timelinePosition = to;
+ onFlowStateTimelineChanged(flowState);
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+ } else {
+ state = allocateComponentExecutionState(flowState, componentIndex);
+
+ state->startPosition = from;
+ state->endPosition = to;
+ state->speed = speed;
+ state->startTimestamp = millis();
+
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ }
+ } else {
+ float currentTime;
+
+ if (state->startPosition < state->endPosition) {
+ currentTime = state->startPosition + state->speed * (millis() - state->startTimestamp) / 1000.0f;
+ if (currentTime >= state->endPosition) {
+ currentTime = state->endPosition;
+ }
+ } else {
+ currentTime = state->startPosition - state->speed * (millis() - state->startTimestamp) / 1000.0f;
+ if (currentTime <= state->endPosition) {
+ currentTime = state->endPosition;
+ }
+ }
+
+ flowState->timelinePosition = currentTime;
+ onFlowStateTimelineChanged(flowState);
+
+ if (currentTime == state->endPosition) {
+ deallocateComponentExecutionState(flowState, componentIndex);
+ propagateValueThroughSeqout(flowState, componentIndex);
+ } else {
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ }
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/call_action.cpp b/Middlewares/eez/flow/components/call_action.cpp
new file mode 100644
index 0000000..c1cd127
--- /dev/null
+++ b/Middlewares/eez/flow/components/call_action.cpp
@@ -0,0 +1,77 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+CallActionComponenentExecutionState::~CallActionComponenentExecutionState() {
+ freeFlowState(flowState);
+}
+
+void executeCallAction(FlowState *flowState, unsigned componentIndex, int flowIndex) {
+ if (flowIndex >= (int)flowState->flowDefinition->flows.count) {
+ executeActionFunction(flowIndex - flowState->flowDefinition->flows.count);
+ propagateValueThroughSeqout(flowState, componentIndex);
+ return;
+ }
+
+ auto callActionComponenentExecutionState = (CallActionComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (callActionComponenentExecutionState) {
+ if (canFreeFlowState(callActionComponenentExecutionState->flowState)) {
+ freeFlowState(callActionComponenentExecutionState->flowState);
+ } else {
+ throwError(flowState, componentIndex, "CallAction is already running\n");
+ return;
+ }
+ }
+
+ FlowState *actionFlowState = initActionFlowState(flowIndex, flowState, componentIndex);
+
+ if (canFreeFlowState(actionFlowState)) {
+ freeFlowState(actionFlowState);
+ propagateValueThroughSeqout(flowState, componentIndex);
+ } else {
+ callActionComponenentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ callActionComponenentExecutionState->flowState = actionFlowState;
+ }
+}
+
+void executeCallActionComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (CallActionActionComponent *)flowState->flow->components[componentIndex];
+
+ auto flowIndex = component->flowIndex;
+ if (flowIndex < 0) {
+ throwError(flowState, componentIndex, "Invalid action flow index in CallAction\n");
+ return;
+ }
+
+ executeCallAction(flowState, componentIndex, flowIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/call_action.h b/Middlewares/eez/flow/components/call_action.h
new file mode 100644
index 0000000..11c6cc6
--- /dev/null
+++ b/Middlewares/eez/flow/components/call_action.h
@@ -0,0 +1,41 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct CallActionActionComponent : public Component {
+ int16_t flowIndex;
+ uint8_t inputsStartIndex;
+ uint8_t outputsStartIndex;
+};
+
+typedef CallActionActionComponent LayoutViewWidgetComponent;
+
+struct CallActionComponenentExecutionState : public ComponenentExecutionState {
+ FlowState *flowState;
+
+ ~CallActionComponenentExecutionState();
+};
+
+} // flow
+} // eez
diff --git a/Middlewares/eez/flow/components/catch_error.cpp b/Middlewares/eez/flow/components/catch_error.cpp
new file mode 100644
index 0000000..2aacde3
--- /dev/null
+++ b/Middlewares/eez/flow/components/catch_error.cpp
@@ -0,0 +1,36 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeCatchErrorComponent(FlowState *flowState, unsigned componentIndex) {
+ auto catchErrorComponentExecutionState = (CatchErrorComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ propagateValue(flowState, componentIndex, 1, catchErrorComponentExecutionState->message);
+ deallocateComponentExecutionState(flowState, componentIndex);
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/compare.cpp b/Middlewares/eez/flow/components/compare.cpp
new file mode 100644
index 0000000..a815d7b
--- /dev/null
+++ b/Middlewares/eez/flow/components/compare.cpp
@@ -0,0 +1,57 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct CompareActionComponent : public Component {
+ uint8_t conditionInstructions[1];
+};
+
+void executeCompareComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (CompareActionComponent *)flowState->flow->components[componentIndex];
+
+ Value conditionValue;
+ if (!evalExpression(flowState, componentIndex, component->conditionInstructions, conditionValue, "Failed to evaluate Condition in Compare")) {
+ return;
+ }
+
+ int err;
+ bool result = conditionValue.toBool(&err);
+ if (err == 0) {
+ if (result) {
+ propagateValue(flowState, componentIndex, 1, Value(true, VALUE_TYPE_BOOLEAN));
+ } else {
+ propagateValue(flowState, componentIndex, 2, Value(false, VALUE_TYPE_BOOLEAN));
+ }
+ } else {
+ throwError(flowState, componentIndex, "Failed to convert Value to boolean in IsTrue\n");
+ return;
+ }
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/constant.cpp b/Middlewares/eez/flow/components/constant.cpp
new file mode 100644
index 0000000..58fbb8a
--- /dev/null
+++ b/Middlewares/eez/flow/components/constant.cpp
@@ -0,0 +1,41 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct ConstantActionComponent : public Component {
+ uint16_t valueIndex;
+};
+
+void executeConstantComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (ConstantActionComponent *)flowState->flow->components[componentIndex];
+
+ auto &sourceValue = *flowState->flowDefinition->constants[component->valueIndex];
+
+ propagateValue(flowState, componentIndex, 1, sourceValue);
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/counter.cpp b/Middlewares/eez/flow/components/counter.cpp
new file mode 100644
index 0000000..5b2e1fe
--- /dev/null
+++ b/Middlewares/eez/flow/components/counter.cpp
@@ -0,0 +1,57 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct CounterComponenentExecutionState : public ComponenentExecutionState {
+ int counter;
+};
+
+void executeCounterComponent(FlowState *flowState, unsigned componentIndex) {
+ auto counterComponenentExecutionState = (CounterComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+
+ if (!counterComponenentExecutionState) {
+ Value counterValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::COUNTER_ACTION_COMPONENT_PROPERTY_COUNT_VALUE, counterValue, "Failed to evaluate countValue in Counter")) {
+ return;
+ }
+
+ counterComponenentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ counterComponenentExecutionState->counter = counterValue.getInt();
+ }
+
+ if (counterComponenentExecutionState->counter > 0) {
+ counterComponenentExecutionState->counter--;
+ propagateValueThroughSeqout(flowState, componentIndex);
+ } else {
+ // done
+ deallocateComponentExecutionState(flowState, componentIndex);
+ propagateValue(flowState, componentIndex, 1);
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/delay.cpp b/Middlewares/eez/flow/components/delay.cpp
new file mode 100644
index 0000000..f8b1b78
--- /dev/null
+++ b/Middlewares/eez/flow/components/delay.cpp
@@ -0,0 +1,72 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct DelayComponenentExecutionState : public ComponenentExecutionState {
+ uint32_t waitUntil;
+};
+
+void executeDelayComponent(FlowState *flowState, unsigned componentIndex) {
+ auto delayComponentExecutionState = (DelayComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+
+ if (!delayComponentExecutionState) {
+ Value value;
+ if (!evalProperty(flowState, componentIndex, defs_v3::DELAY_ACTION_COMPONENT_PROPERTY_MILLISECONDS, value, "Failed to evaluate Milliseconds in Delay")) {
+ return;
+ }
+
+ double milliseconds = value.toDouble();
+ if (!isNaN(milliseconds)) {
+ delayComponentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ delayComponentExecutionState->waitUntil = millis() + (uint32_t)floor(milliseconds);
+ } else {
+ throwError(flowState, componentIndex, "Invalid Milliseconds value in Delay\n");
+ return;
+ }
+
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ } else {
+ if (millis() >= delayComponentExecutionState->waitUntil) {
+ deallocateComponentExecutionState(flowState, componentIndex);
+ propagateValueThroughSeqout(flowState, componentIndex);
+ } else {
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ }
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/end.cpp b/Middlewares/eez/flow/components/end.cpp
new file mode 100644
index 0000000..ccde926
--- /dev/null
+++ b/Middlewares/eez/flow/components/end.cpp
@@ -0,0 +1,37 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeEndComponent(FlowState *flowState, unsigned componentIndex) {
+ if (flowState->parentFlowState && flowState->isAction) {
+ propagateValueThroughSeqout(flowState->parentFlowState, flowState->parentComponentIndex);
+ } else {
+ stopScriptHook();
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/error.cpp b/Middlewares/eez/flow/components/error.cpp
new file mode 100644
index 0000000..7f67e5f
--- /dev/null
+++ b/Middlewares/eez/flow/components/error.cpp
@@ -0,0 +1,38 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeErrorComponent(FlowState *flowState, unsigned componentIndex) {
+ Value expressionValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::EVAL_EXPR_ACTION_COMPONENT_PROPERTY_EXPRESSION, expressionValue, "Failed to evaluate Message in Error")) {
+ return;
+ }
+
+ throwError(flowState, componentIndex, expressionValue.getString());
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/expr_eval.cpp b/Middlewares/eez/flow/components/expr_eval.cpp
new file mode 100644
index 0000000..523fc66
--- /dev/null
+++ b/Middlewares/eez/flow/components/expr_eval.cpp
@@ -0,0 +1,40 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeEvalExprComponent(FlowState *flowState, unsigned componentIndex) {
+ Value expressionValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::EVAL_EXPR_ACTION_COMPONENT_PROPERTY_EXPRESSION, expressionValue, "Failed to evaluate Expression in EvalExpr")) {
+ return;
+ }
+
+ propagateValue(flowState, componentIndex, 1, expressionValue);
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/input.cpp b/Middlewares/eez/flow/components/input.cpp
new file mode 100644
index 0000000..c1241e2
--- /dev/null
+++ b/Middlewares/eez/flow/components/input.cpp
@@ -0,0 +1,84 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+bool getCallActionValue(FlowState *flowState, unsigned componentIndex, Value &value) {
+ auto component = (InputActionComponent *)flowState->flow->components[componentIndex];
+
+ if (!flowState->parentFlowState) {
+ throwError(flowState, componentIndex, "No parentFlowState in Input\n");
+ return false;
+ }
+
+ if (!flowState->parentComponent) {
+ throwError(flowState, componentIndex, "No parentComponent in Input\n");
+ return false;
+ }
+
+ auto callActionComponent = (CallActionActionComponent *)flowState->parentComponent;
+
+ uint8_t parentComponentInputIndex = callActionComponent->inputsStartIndex + component->inputIndex;
+ if (component->type == defs_v3::COMPONENT_TYPE_INPUT_ACTION) {
+ parentComponentInputIndex = callActionComponent->inputsStartIndex + component->inputIndex;
+ } else {
+ parentComponentInputIndex = 0;
+ }
+
+ if (parentComponentInputIndex >= flowState->parentComponent->inputs.count) {
+ throwError(flowState, componentIndex, "Invalid input index in Input\n");
+ return false;
+ }
+
+ auto parentComponentInputs = flowState->parentComponent->inputs;
+ auto flowInputIndex = parentComponentInputs[parentComponentInputIndex];
+
+ auto parentFlow = flowState->flowDefinition->flows[flowState->parentFlowState->flowIndex];
+ if (flowInputIndex >= parentFlow->componentInputs.count) {
+ throwError(flowState, componentIndex, "Invalid input index of parent component in Input\n");
+ return false;
+ }
+
+ value = flowState->parentFlowState->values[flowInputIndex];
+ return true;
+}
+
+void executeInputComponent(FlowState *flowState, unsigned componentIndex) {
+ Value value;
+ if (getCallActionValue(flowState, componentIndex, value)) {
+ auto inputActionComponentExecutionState = (InputActionComponentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (!inputActionComponentExecutionState) {
+ inputActionComponentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ }
+
+ propagateValue(flowState, componentIndex, 0, value);
+ inputActionComponentExecutionState->value = value;
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/input.h b/Middlewares/eez/flow/components/input.h
new file mode 100644
index 0000000..deaa52e
--- /dev/null
+++ b/Middlewares/eez/flow/components/input.h
@@ -0,0 +1,38 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct InputActionComponent : public Component {
+ uint8_t inputIndex;
+};
+
+struct InputActionComponentExecutionState : public ComponenentExecutionState {
+ Value value;
+};
+
+
+bool getCallActionValue(FlowState *flowState, unsigned componentIndex, Value &value);
+
+} // flow
+} // eez
diff --git a/Middlewares/eez/flow/components/is_true.cpp b/Middlewares/eez/flow/components/is_true.cpp
new file mode 100644
index 0000000..eb26cc0
--- /dev/null
+++ b/Middlewares/eez/flow/components/is_true.cpp
@@ -0,0 +1,51 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeIsTrueComponent(FlowState *flowState, unsigned componentIndex) {
+ Value srcValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::IS_TRUE_ACTION_COMPONENT_PROPERTY_VALUE, srcValue, "Failed to evaluate Value in IsTrue")) {
+ return;
+ }
+
+ int err;
+ bool result = srcValue.toBool(&err);
+ if (err == 0) {
+ if (result) {
+ propagateValue(flowState, componentIndex, 1, Value(true, VALUE_TYPE_BOOLEAN));
+ } else {
+ propagateValue(flowState, componentIndex, 2, Value(false, VALUE_TYPE_BOOLEAN));
+ }
+ } else {
+ throwError(flowState, componentIndex, "Failed to convert Value to boolean in IsTrue\n");
+ return;
+ }
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/layout_view_widget.cpp b/Middlewares/eez/flow/components/layout_view_widget.cpp
new file mode 100644
index 0000000..f7c800c
--- /dev/null
+++ b/Middlewares/eez/flow/components/layout_view_widget.cpp
@@ -0,0 +1,100 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct LayoutViewWidgetExecutionState : public ComponenentExecutionState {
+ FlowState *flowState;
+
+ ~LayoutViewWidgetExecutionState() {
+ freeFlowState(flowState);
+ }
+};
+
+static LayoutViewWidgetExecutionState *createLayoutViewFlowState(FlowState *flowState, uint16_t layoutViewWidgetComponentIndex, int16_t pageId) {
+ auto layoutViewFlowState = initPageFlowState(flowState->assets, pageId, flowState, layoutViewWidgetComponentIndex);
+ auto layoutViewWidgetExecutionState = allocateComponentExecutionState(flowState, layoutViewWidgetComponentIndex);
+ layoutViewWidgetExecutionState->flowState = layoutViewFlowState;
+ return layoutViewWidgetExecutionState;
+}
+
+FlowState *getLayoutViewFlowState(FlowState *flowState, uint16_t layoutViewWidgetComponentIndex, int16_t pageId) {
+ auto layoutViewWidgetExecutionState = (LayoutViewWidgetExecutionState *)flowState->componenentExecutionStates[layoutViewWidgetComponentIndex];
+ if (!layoutViewWidgetExecutionState) {
+ layoutViewWidgetExecutionState = createLayoutViewFlowState(flowState, layoutViewWidgetComponentIndex, pageId);
+ }
+
+ return layoutViewWidgetExecutionState->flowState;
+}
+
+void executeLayoutViewWidgetComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (CallActionActionComponent *)flowState->flow->components[componentIndex];
+
+ auto layoutViewWidgetExecutionState = (LayoutViewWidgetExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (!layoutViewWidgetExecutionState) {
+ createLayoutViewFlowState(flowState, componentIndex, component->flowIndex);
+ } else {
+ auto layoutViewFlowState = layoutViewWidgetExecutionState->flowState;
+ for (
+ unsigned layoutViewComponentIndex = 0;
+ layoutViewComponentIndex < layoutViewFlowState->flow->components.count;
+ layoutViewComponentIndex++
+ ) {
+ auto layoutViewComponent = layoutViewFlowState->flow->components[layoutViewComponentIndex];
+ if (layoutViewComponent->type == defs_v3::COMPONENT_TYPE_INPUT_ACTION) {
+ auto inputActionComponentExecutionState = (InputActionComponentExecutionState *)layoutViewFlowState->componenentExecutionStates[layoutViewComponentIndex];
+ if (inputActionComponentExecutionState) {
+ Value value;
+ if (getCallActionValue(layoutViewFlowState, layoutViewComponentIndex, value)) {
+ if (inputActionComponentExecutionState->value != value) {
+ addToQueue(layoutViewWidgetExecutionState->flowState, layoutViewComponentIndex);
+ inputActionComponentExecutionState->value = value;
+ }
+ } else {
+ return;
+ }
+ }
+ } else if (layoutViewComponent->type == defs_v3::COMPONENT_TYPE_START_ACTION) {
+ Value value;
+ if (getCallActionValue(layoutViewFlowState, layoutViewComponentIndex, value)) {
+ if (value.getType() != VALUE_TYPE_UNDEFINED) {
+ addToQueue(layoutViewWidgetExecutionState->flowState, layoutViewComponentIndex);
+ }
+ } else {
+ return;
+ }
+ }
+ }
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/log.cpp b/Middlewares/eez/flow/components/log.cpp
new file mode 100644
index 0000000..cece2a0
--- /dev/null
+++ b/Middlewares/eez/flow/components/log.cpp
@@ -0,0 +1,47 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeLogComponent(FlowState *flowState, unsigned componentIndex) {
+ Value value;
+ if (!evalProperty(flowState, componentIndex, defs_v3::LOG_ACTION_COMPONENT_PROPERTY_VALUE, value, "Failed to evaluate Message in Log")) {
+ return;
+ }
+
+ Value strValue = value.toString(0x0f9812ee);
+ const char *valueStr = strValue.getString();
+ if (valueStr && *valueStr) {
+ logInfo(flowState, componentIndex, valueStr);
+ }
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/loop.cpp b/Middlewares/eez/flow/components/loop.cpp
new file mode 100644
index 0000000..b7f941e
--- /dev/null
+++ b/Middlewares/eez/flow/components/loop.cpp
@@ -0,0 +1,102 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct LoopComponenentExecutionState : public ComponenentExecutionState {
+ Value dstValue;
+ Value toValue;
+ Value currentValue;
+};
+
+void executeLoopComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = flowState->flow->components[componentIndex];
+
+ auto loopComponentExecutionState = (LoopComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+
+ // restart loop if entered through "start" input
+ static const unsigned START_INPUT_INDEX = 0;
+ auto startInputIndex = component->inputs[START_INPUT_INDEX];
+ if (flowState->values[startInputIndex].type != VALUE_TYPE_UNDEFINED) {
+ if (loopComponentExecutionState) {
+ deallocateComponentExecutionState(flowState, componentIndex);
+ loopComponentExecutionState = nullptr;
+ }
+ } else {
+ if (!loopComponentExecutionState) {
+ return;
+ }
+ }
+
+ Value stepValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::LOOP_ACTION_COMPONENT_PROPERTY_STEP, stepValue, "Failed to evaluate Step in Loop")) {
+ return;
+ }
+
+ if (!loopComponentExecutionState) {
+ Value dstValue;
+ if (!evalAssignableProperty(flowState, componentIndex, defs_v3::LOOP_ACTION_COMPONENT_PROPERTY_VARIABLE, dstValue, "Failed to evaluate Variable in Loop")) {
+ return;
+ }
+
+ Value fromValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::LOOP_ACTION_COMPONENT_PROPERTY_FROM, fromValue, "Failed to evaluate From in Loop")) {
+ return;
+ }
+
+ Value toValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::LOOP_ACTION_COMPONENT_PROPERTY_TO, toValue, "Failed to evaluate To in Loop")) {
+ return;
+ }
+
+ loopComponentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ loopComponentExecutionState->dstValue = dstValue;
+ loopComponentExecutionState->toValue = toValue;
+
+ loopComponentExecutionState->currentValue = fromValue;
+ } else {
+ loopComponentExecutionState->currentValue = op_add(loopComponentExecutionState->currentValue, stepValue);
+ }
+
+ bool condition;
+ if (stepValue.getInt() > 0) {
+ condition = op_great(loopComponentExecutionState->currentValue, loopComponentExecutionState->toValue).toBool();
+ } else {
+ condition = op_less(loopComponentExecutionState->currentValue, loopComponentExecutionState->toValue).toBool();
+ }
+
+ if (condition) {
+ // done
+ deallocateComponentExecutionState(flowState, componentIndex);
+ propagateValue(flowState, componentIndex, component->outputs.count - 1);
+ } else {
+ assignValue(flowState, componentIndex, loopComponentExecutionState->dstValue, loopComponentExecutionState->currentValue);
+ propagateValueThroughSeqout(flowState, componentIndex);
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/noop.cpp b/Middlewares/eez/flow/components/noop.cpp
new file mode 100644
index 0000000..a5bde41
--- /dev/null
+++ b/Middlewares/eez/flow/components/noop.cpp
@@ -0,0 +1,36 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeNoopComponent(FlowState *flowState, unsigned componentIndex) {
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/on_event.cpp b/Middlewares/eez/flow/components/on_event.cpp
new file mode 100644
index 0000000..484453c
--- /dev/null
+++ b/Middlewares/eez/flow/components/on_event.cpp
@@ -0,0 +1,31 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeOnEventComponent(FlowState *flowState, unsigned componentIndex) {
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/output.cpp b/Middlewares/eez/flow/components/output.cpp
new file mode 100644
index 0000000..1786de1
--- /dev/null
+++ b/Middlewares/eez/flow/components/output.cpp
@@ -0,0 +1,64 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct OutputActionComponent : public Component {
+ uint8_t outputIndex;
+};
+
+void executeOutputComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (OutputActionComponent *)flowState->flow->components[componentIndex];
+
+ if (!flowState->parentFlowState) {
+ throwError(flowState, componentIndex, "No parentFlowState in Output\n");
+ return;
+ }
+
+ if (!flowState->parentComponent) {
+ throwError(flowState, componentIndex, "No parentComponent in Output\n");
+ return;
+ }
+
+ auto inputIndex = component->inputs[0];
+ if (inputIndex >= flowState->flow->componentInputs.count) {
+ throwError(flowState, componentIndex, "Invalid input index in Output\n");
+ return;
+ }
+
+ auto value = flowState->values[inputIndex];
+
+ auto callActionComponent = (CallActionActionComponent *)flowState->parentComponent;
+
+ uint8_t parentComponentOutputIndex = callActionComponent->outputsStartIndex + component->outputIndex;
+
+ if (parentComponentOutputIndex >= flowState->parentComponent->outputs.count) {
+ throwError(flowState, componentIndex, "Output action component, invalid output index\n");
+ return;
+ }
+
+ propagateValue(flowState->parentFlowState, flowState->parentComponentIndex, parentComponentOutputIndex, value);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/roller_widget.cpp b/Middlewares/eez/flow/components/roller_widget.cpp
new file mode 100644
index 0000000..afba520
--- /dev/null
+++ b/Middlewares/eez/flow/components/roller_widget.cpp
@@ -0,0 +1,43 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeRollerWidgetComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = flowState->flow->components[componentIndex];
+
+ static const unsigned START_INPUT_INDEX = 0;
+ auto startInputIndex = component->inputs[START_INPUT_INDEX];
+ if (flowState->values[startInputIndex].type != VALUE_TYPE_UNDEFINED) {
+ auto executionState = (RollerWidgetComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (!executionState) {
+ executionState = allocateComponentExecutionState(flowState, componentIndex);
+ }
+ executionState->clear = true;
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/roller_widget.h b/Middlewares/eez/flow/components/roller_widget.h
new file mode 100644
index 0000000..65ae3e2
--- /dev/null
+++ b/Middlewares/eez/flow/components/roller_widget.h
@@ -0,0 +1,31 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct RollerWidgetComponenentExecutionState : public ComponenentExecutionState {
+ bool clear;
+};
+
+} // flow
+} // eez
\ No newline at end of file
diff --git a/Middlewares/eez/flow/components/select_language.cpp b/Middlewares/eez/flow/components/select_language.cpp
new file mode 100644
index 0000000..4132f6a
--- /dev/null
+++ b/Middlewares/eez/flow/components/select_language.cpp
@@ -0,0 +1,53 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeSelectLanguageComponent(FlowState *flowState, unsigned componentIndex) {
+ Value languageValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SELECT_LANGUAGE_ACTION_COMPONENT_PROPERTY_LANGUAGE, languageValue, "Failed to evaluate Language in SelectLanguage")) {
+ return;
+ }
+
+ const char *language = languageValue.getString();
+
+ auto languages = flowState->assets->languages;
+
+ for (uint32_t languageIndex = 0; languageIndex < languages.count; languageIndex++) {
+ if (strcmp(languages[languageIndex]->languageID, language) == 0) {
+ g_selectedLanguage = languageIndex;
+ propagateValueThroughSeqout(flowState, componentIndex);
+ return;
+ }
+ }
+
+ char message[256];
+ snprintf(message, sizeof(message), "Unknown language %s", language);
+ throwError(flowState, componentIndex, message);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/set_page_direction.cpp b/Middlewares/eez/flow/components/set_page_direction.cpp
new file mode 100644
index 0000000..f292072
--- /dev/null
+++ b/Middlewares/eez/flow/components/set_page_direction.cpp
@@ -0,0 +1,49 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+#define PAGE_DIRECTION_LTR 0
+#define PAGE_DIRECTION_RTL 1
+
+struct SetPageDirectionComponent : public Component {
+ uint8_t direction;
+};
+
+void executeSetPageDirectionComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (SetPageDirectionComponent *)flowState->flow->components[componentIndex];
+
+ gui::g_isRTL = component->direction == PAGE_DIRECTION_RTL;
+
+ gui::refreshScreen();
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/set_variable.cpp b/Middlewares/eez/flow/components/set_variable.cpp
new file mode 100644
index 0000000..3dfaeef
--- /dev/null
+++ b/Middlewares/eez/flow/components/set_variable.cpp
@@ -0,0 +1,57 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeSetVariableComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (SetVariableActionComponent *)flowState->flow->components[componentIndex];
+
+ for (uint32_t entryIndex = 0; entryIndex < component->entries.count; entryIndex++) {
+ auto entry = component->entries[entryIndex];
+
+ char strErrorMessage[256];
+ snprintf(strErrorMessage, sizeof(strErrorMessage), "Failed to evaluate Variable no. %d in SetVariable", (int)(entryIndex + 1));
+
+ Value dstValue;
+ if (!evalAssignableExpression(flowState, componentIndex, entry->variable, dstValue, strErrorMessage)) {
+ return;
+ }
+
+ snprintf(strErrorMessage, sizeof(strErrorMessage), "Failed to evaluate Value no. %d in SetVariable", (int)(entryIndex + 1));
+
+ Value srcValue;
+ if (!evalExpression(flowState, componentIndex, entry->value, srcValue, strErrorMessage)) {
+ return;
+ }
+
+ assignValue(flowState, componentIndex, dstValue, srcValue);
+ }
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/set_variable.h b/Middlewares/eez/flow/components/set_variable.h
new file mode 100644
index 0000000..70f7deb
--- /dev/null
+++ b/Middlewares/eez/flow/components/set_variable.h
@@ -0,0 +1,36 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2022-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct SetVariableEntry {
+ eez::gui::AssetsPtr variable;
+ eez::gui::AssetsPtr value;
+};
+
+struct SetVariableActionComponent : public Component {
+ eez::gui::ListOfAssetsPtr entries;
+};
+
+} // flow
+} // eez
diff --git a/Middlewares/eez/flow/components/show_keyboard.cpp b/Middlewares/eez/flow/components/show_keyboard.cpp
new file mode 100644
index 0000000..85a8aa8
--- /dev/null
+++ b/Middlewares/eez/flow/components/show_keyboard.cpp
@@ -0,0 +1,88 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct ShowKeyboardActionComponent : public Component {
+ uint8_t password;
+};
+
+void executeShowKeyboardComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (ShowKeyboardActionComponent *)flowState->flow->components[componentIndex];
+
+ Value labelValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYBOARD_ACTION_COMPONENT_PROPERTY_LABEL, labelValue, "Failed to evaluate Label in ShowKeyboard")) {
+ return;
+ }
+
+ Value initialTextValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYBOARD_ACTION_COMPONENT_PROPERTY_INITAL_TEXT, initialTextValue, "Failed to evaluate InitialText in ShowKeyboard")) {
+ return;
+ }
+
+ Value minCharsValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYBOARD_ACTION_COMPONENT_PROPERTY_MIN_CHARS, minCharsValue, "Failed to evaluate MinChars in ShowKeyboard")) {
+ return;
+ }
+
+ Value maxCharsValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYBOARD_ACTION_COMPONENT_PROPERTY_MAX_CHARS, maxCharsValue, "Failed to evaluate MaxChars in ShowKeyboard")) {
+ return;
+ }
+
+ static FlowState *g_showKeyboardFlowState;
+ static unsigned g_showKeyboardComponentIndex;
+
+ g_showKeyboardFlowState = flowState;
+ g_showKeyboardComponentIndex = componentIndex;
+
+ startAsyncExecution(flowState, componentIndex);
+
+ auto onOk = [](char *value) {
+ propagateValue(g_showKeyboardFlowState, g_showKeyboardComponentIndex, 0, Value::makeStringRef(value, -1, 0x87d32fe2));
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->popPage();
+ endAsyncExecution(g_showKeyboardFlowState, g_showKeyboardComponentIndex);
+ };
+
+ auto onCancel = []() {
+ propagateValue(g_showKeyboardFlowState, g_showKeyboardComponentIndex, 1, Value());
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->popPage();
+ endAsyncExecution(g_showKeyboardFlowState, g_showKeyboardComponentIndex);
+ };
+
+ const char *label = labelValue.getString();
+ if (label && *label) {
+ labelValue = op_add(labelValue, Value(": "));
+ }
+
+ showKeyboardHook(labelValue, initialTextValue, minCharsValue, maxCharsValue, component->password, onOk, onCancel);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/show_keypad.cpp b/Middlewares/eez/flow/components/show_keypad.cpp
new file mode 100644
index 0000000..6224440
--- /dev/null
+++ b/Middlewares/eez/flow/components/show_keypad.cpp
@@ -0,0 +1,109 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct ShowKeyboardActionComponent : public Component {
+ uint8_t password;
+};
+
+void executeShowKeypadComponent(FlowState *flowState, unsigned componentIndex) {
+ Value labelValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYBOARD_ACTION_COMPONENT_PROPERTY_LABEL, labelValue, "Failed to evaluate Label in ShowKeypad")) {
+ return;
+ }
+
+ Value initialValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_INITAL_VALUE, initialValue, "Failed to evaluate InitialValue in ShowKeypad")) {
+ return;
+ }
+
+ Value minValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_MIN, minValue, "Failed to evaluate Min in ShowKeypad")) {
+ return;
+ }
+
+ Value maxValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_MAX, maxValue, "Failed to evaluate Max in ShowKeypad")) {
+ return;
+ }
+
+ Value unitValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_UNIT, unitValue, "Failed to evaluate Unit in ShowKeypad")) {
+ return;
+ }
+
+ static FlowState *g_showKeyboardFlowState;
+ static unsigned g_showKeyboardComponentIndex;
+
+ g_showKeyboardFlowState = flowState;
+ g_showKeyboardComponentIndex = componentIndex;
+
+ startAsyncExecution(flowState, componentIndex);
+
+ auto onOk = [](float value) {
+ Value precisionValue;
+ if (!evalProperty(g_showKeyboardFlowState, g_showKeyboardComponentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_PRECISION, precisionValue, "Failed to evaluate Precision in ShowKeypad")) {
+ return;
+ }
+
+ float precision = precisionValue.toFloat();
+
+ Value unitValue;
+ if (!evalProperty(g_showKeyboardFlowState, g_showKeyboardComponentIndex, defs_v3::SHOW_KEYPAD_ACTION_COMPONENT_PROPERTY_UNIT, unitValue, "Failed to evaluate Unit in ShowKeypad")) {
+ return;
+ }
+
+ Unit unit = getUnitFromName(unitValue.getString());
+
+ value = roundPrec(value, precision) / getUnitFactor(unit);
+
+ propagateValue(g_showKeyboardFlowState, g_showKeyboardComponentIndex, 0, Value(value, VALUE_TYPE_FLOAT));
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->popPage();
+ endAsyncExecution(g_showKeyboardFlowState, g_showKeyboardComponentIndex);
+ };
+
+ auto onCancel = []() {
+ propagateValue(g_showKeyboardFlowState, g_showKeyboardComponentIndex, 1, Value());
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->popPage();
+ endAsyncExecution(g_showKeyboardFlowState, g_showKeyboardComponentIndex);
+ };
+
+ const char *label = labelValue.getString();
+ if (label && *label) {
+ labelValue = op_add(labelValue, Value(": "));
+ }
+
+ Unit unit = getUnitFromName(unitValue.getString());
+
+ showKeypadHook(labelValue, initialValue, minValue, maxValue, unit, onOk, onCancel);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/show_message_box.cpp b/Middlewares/eez/flow/components/show_message_box.cpp
new file mode 100644
index 0000000..dfc0446
--- /dev/null
+++ b/Middlewares/eez/flow/components/show_message_box.cpp
@@ -0,0 +1,52 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+
+namespace eez {
+namespace flow {
+
+const uint8_t MESSAGE_BOX_TYPE_INFO = 1;
+const uint8_t MESSAGE_BOX_TYPE_ERROR = 2;
+
+struct ShowMessagePageActionComponent : public Component {
+ uint8_t type;
+};
+
+void executeShowMessageBoxComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (ShowMessagePageActionComponent *)flowState->flow->components[componentIndex];
+
+ Value messageValue;
+ if (!evalProperty(flowState, componentIndex, defs_v3::SHOW_MESSAGE_BOX_ACTION_COMPONENT_PROPERTY_MESSAGE, messageValue, "Failed to evaluate Message in ShowMessageBox")) {
+ return;
+ }
+
+ if (component->type == MESSAGE_BOX_TYPE_INFO) {
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->infoMessage(messageValue);
+ } else if (component->type == MESSAGE_BOX_TYPE_ERROR) {
+ getAppContextFromId(APP_CONTEXT_ID_DEVICE)->errorMessage(messageValue);
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/show_page.cpp b/Middlewares/eez/flow/components/show_page.cpp
new file mode 100644
index 0000000..b291525
--- /dev/null
+++ b/Middlewares/eez/flow/components/show_page.cpp
@@ -0,0 +1,40 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+namespace eez {
+namespace flow {
+
+struct ShowPageActionComponent : public Component {
+ int16_t page;
+};
+
+void executeShowPageComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (ShowPageActionComponent *)flowState->flow->components[componentIndex];
+
+ replacePageHook(component->page);
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/start.cpp b/Middlewares/eez/flow/components/start.cpp
new file mode 100644
index 0000000..c31fb00
--- /dev/null
+++ b/Middlewares/eez/flow/components/start.cpp
@@ -0,0 +1,31 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+void executeStartComponent(FlowState *flowState, unsigned componentIndex) {
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/switch.cpp b/Middlewares/eez/flow/components/switch.cpp
new file mode 100644
index 0000000..5614dbd
--- /dev/null
+++ b/Middlewares/eez/flow/components/switch.cpp
@@ -0,0 +1,61 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+#include
+
+namespace eez {
+namespace flow {
+
+void executeSwitchComponent(FlowState *flowState, unsigned componentIndex) {
+ auto component = (SwitchActionComponent *)flowState->flow->components[componentIndex];
+
+ for (uint32_t testIndex = 0; testIndex < component->tests.count; testIndex++) {
+ auto test = component->tests[testIndex];
+
+ char strMessage[256];
+ snprintf(strMessage, sizeof(strMessage), "Failed to evaluate test condition no. %d in Switch", (int)(testIndex + 1));
+
+ Value conditionValue;
+ if (!evalExpression(flowState, componentIndex, test->conditionInstructions, conditionValue, strMessage)) {
+ return;
+ }
+
+ int err;
+ bool result = conditionValue.toBool(&err);
+ if (err == 0) {
+ if (result) {
+ propagateValue(flowState, componentIndex, test->outputIndex);
+ break;
+ }
+ } else {
+ char strMessage[256];
+ snprintf(strMessage, sizeof(strMessage), "Failed to convert Value no. %d to boolean in Switch\n", (int)(testIndex + 1));
+ throwError(flowState, componentIndex, strMessage);
+ return;
+ }
+ }
+
+ propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/components/switch.h b/Middlewares/eez/flow/components/switch.h
new file mode 100644
index 0000000..1a30767
--- /dev/null
+++ b/Middlewares/eez/flow/components/switch.h
@@ -0,0 +1,36 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2022-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+struct SwitchTest {
+ uint8_t outputIndex;
+ uint8_t conditionInstructions[1];
+};
+
+struct SwitchActionComponent : public Component {
+ eez::gui::ListOfAssetsPtr tests;
+};
+
+} // flow
+} // eez
\ No newline at end of file
diff --git a/Middlewares/eez/flow/components/watch_variable.cpp b/Middlewares/eez/flow/components/watch_variable.cpp
new file mode 100644
index 0000000..d700c51
--- /dev/null
+++ b/Middlewares/eez/flow/components/watch_variable.cpp
@@ -0,0 +1,74 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+using namespace eez::gui;
+
+namespace eez {
+namespace flow {
+
+struct WatchVariableComponenentExecutionState : public ComponenentExecutionState {
+ Value value;
+};
+
+void executeWatchVariableComponent(FlowState *flowState, unsigned componentIndex) {
+ auto watchVariableComponentExecutionState = (WatchVariableComponenentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+
+ Value value;
+ if (!evalProperty(flowState, componentIndex, defs_v3::WATCH_VARIABLE_ACTION_COMPONENT_PROPERTY_VARIABLE, value, "Failed to evaluate Variable in WatchVariable")) {
+ return;
+ }
+
+ if (!watchVariableComponentExecutionState) {
+ watchVariableComponentExecutionState = allocateComponentExecutionState(flowState, componentIndex);
+ watchVariableComponentExecutionState->value = value;
+
+ propagateValue(flowState, componentIndex, 1, value);
+
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ } else {
+ if (value != watchVariableComponentExecutionState->value) {
+ watchVariableComponentExecutionState->value = value;
+ propagateValue(flowState, componentIndex, 1, value);
+ }
+
+ if (canFreeFlowState(flowState, false)) {
+ deallocateComponentExecutionState(flowState, componentIndex);
+ } else {
+ if (!addToQueue(flowState, componentIndex, -1, -1, -1, true)) {
+ throwError(flowState, componentIndex, "Execution queue is full\n");
+ return;
+ }
+ }
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/dashboard_api.cpp b/Middlewares/eez/flow/dashboard_api.cpp
new file mode 100644
index 0000000..d6d12a1
--- /dev/null
+++ b/Middlewares/eez/flow/dashboard_api.cpp
@@ -0,0 +1,378 @@
+
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#if defined(__EMSCRIPTEN__)
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+using namespace eez;
+using namespace eez::gui;
+using namespace eez::flow;
+
+namespace eez {
+namespace flow {
+
+int getFlowStateIndex(FlowState *flowState) {
+ return (int)((uint8_t *)flowState - ALLOC_BUFFER);
+}
+
+struct DashboardComponentExecutionState : public ComponenentExecutionState {
+ ~DashboardComponentExecutionState() {
+ EM_ASM({
+ freeComponentExecutionState($0, $1);
+ }, g_wasmModuleId, state);
+ }
+ int32_t state;
+};
+
+} // flow
+} // eez
+
+static inline FlowState *getFlowState(int flowStateIndex) {
+ return (FlowState *)(ALLOC_BUFFER + flowStateIndex);
+}
+
+static void updateArrayValue(ArrayValue *arrayValue1, ArrayValue *arrayValue2) {
+ for (uint32_t i = 0; i < arrayValue1->arraySize; i++) {
+ if (arrayValue1->values[i].getType() == VALUE_TYPE_ARRAY || arrayValue1->values[i].getType() == VALUE_TYPE_ARRAY_REF) {
+ updateArrayValue(arrayValue1->values[i].getArray(), arrayValue2->values[i].getArray());
+ } else {
+ arrayValue1->values[i] = arrayValue2->values[i];
+ }
+ }
+}
+
+EM_PORT_API(Value *) createUndefinedValue() {
+ auto pValue = ObjectAllocator::allocate(0x2e821285);
+ *pValue = Value(0, VALUE_TYPE_UNDEFINED);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createNullValue() {
+ auto pValue = ObjectAllocator::allocate(0x69debded);
+ *pValue = Value(0, VALUE_TYPE_NULL);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createIntValue(int value) {
+ auto pValue = ObjectAllocator::allocate(0x20ea356c);
+ *pValue = Value(value, VALUE_TYPE_INT32);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createDoubleValue(double value) {
+ auto pValue = ObjectAllocator::allocate(0xecfb69a9);
+ *pValue = Value(value, VALUE_TYPE_DOUBLE);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createBooleanValue(int value) {
+ auto pValue = ObjectAllocator::allocate(0x76071378);
+ *pValue = Value(value, VALUE_TYPE_BOOLEAN);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createStringValue(const char *value) {
+ auto pValue = ObjectAllocator::allocate(0x0a8a7ed1);
+ Value stringValue = Value::makeStringRef(value, strlen(value), 0x5b1e51d7);
+ *pValue = stringValue;
+ return pValue;
+}
+
+EM_PORT_API(Value *) createArrayValue(int arraySize, int arrayType) {
+ Value value = Value::makeArrayRef(arraySize, arrayType, 0xeabb7edc);
+ auto pValue = ObjectAllocator::allocate(0xbab14c6a);
+ if (pValue) {
+ *pValue = value;
+ }
+ return pValue;
+}
+
+EM_PORT_API(Value *) createStreamValue(double value) {
+ auto pValue = ObjectAllocator::allocate(0x53a2e660);
+ *pValue = Value(value, VALUE_TYPE_STREAM);
+ return pValue;
+}
+
+EM_PORT_API(Value *) createDateValue(double value) {
+ auto pValue = ObjectAllocator::allocate(0x90b7ce70);
+ *pValue = Value(value, VALUE_TYPE_DATE);
+ return pValue;
+}
+
+EM_PORT_API(void) arrayValueSetElementValue(Value *arrayValuePtr, int elementIndex, Value *valuePtr) {
+ auto array = arrayValuePtr->getArray();
+ array->values[elementIndex] = *valuePtr;
+}
+
+EM_PORT_API(void) valueFree(Value *valuePtr) {
+ ObjectAllocator::deallocate(valuePtr);
+}
+
+EM_PORT_API(void) setGlobalVariable(int globalVariableIndex, Value *valuePtr) {
+ auto flowDefinition = static_cast(g_mainAssets->flowDefinition);
+ Value *globalVariableValuePtr = flowDefinition->globalVariables[globalVariableIndex];
+ *globalVariableValuePtr = *valuePtr;
+}
+
+EM_PORT_API(void) updateGlobalVariable(int globalVariableIndex, Value *valuePtr) {
+ auto flowDefinition = static_cast(g_mainAssets->flowDefinition);
+ Value *globalVariableValuePtr = flowDefinition->globalVariables[globalVariableIndex];
+ updateArrayValue(globalVariableValuePtr->getArray(), valuePtr->getArray());
+}
+
+EM_PORT_API(int) getFlowIndex(int flowStateIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ return flowState->flowIndex;
+}
+
+EM_PORT_API(int) getComponentExecutionState(int flowStateIndex, int componentIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ auto component = flowState->flow->components[componentIndex];
+ auto executionState = (DashboardComponentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (executionState) {
+ return executionState->state;
+ }
+ return -1;
+}
+
+EM_PORT_API(void) setComponentExecutionState(int flowStateIndex, int componentIndex, int state) {
+ auto flowState = getFlowState(flowStateIndex);
+ auto component = flowState->flow->components[componentIndex];
+ auto executionState = (DashboardComponentExecutionState *)flowState->componenentExecutionStates[componentIndex];
+ if (executionState) {
+ if (state != -1) {
+ executionState->state = state;
+ } else {
+ deallocateComponentExecutionState(flowState, componentIndex);
+ }
+ } else {
+ if (state != -1) {
+ executionState = allocateComponentExecutionState(flowState, componentIndex);
+ executionState->state = state;
+ }
+ }
+}
+
+EM_PORT_API(const char *) getStringParam(int flowStateIndex, int componentIndex, int offset) {
+ auto flowState = getFlowState(flowStateIndex);
+ auto component = flowState->flow->components[componentIndex];
+ auto ptr = (const uint32_t *)((const uint8_t *)component + sizeof(Component) + offset);
+ return (const char *)(MEMORY_BEGIN + 4 + *ptr);
+}
+
+struct ExpressionList {
+ uint32_t count;
+ Value values[1];
+};
+
+EM_PORT_API(void *) getExpressionListParam(int flowStateIndex, int componentIndex, int offset) {
+ auto flowState = getFlowState(flowStateIndex);
+ auto component = flowState->flow->components[componentIndex];
+
+ struct List {
+ uint32_t count;
+ uint32_t items;
+ };
+ auto list = (const List *)((const uint8_t *)component + sizeof(Component) + offset);
+
+ auto expressionList = (ExpressionList *)::malloc((list->count + 1) * sizeof(Value));
+
+ expressionList->count = list->count;
+
+ auto items = (const uint32_t *)(MEMORY_BEGIN + 4 + list->items);
+
+ for (uint32_t i = 0; i < list->count; i++) {
+ // call Value constructor
+ new (expressionList->values + i) Value();
+
+ auto valueExpression = (const uint8_t *)(MEMORY_BEGIN + 4 + items[i]);
+ if (!evalExpression(flowState, componentIndex, valueExpression, expressionList->values[i], "Failed to evaluate expression")) {
+ return nullptr;
+ }
+ }
+
+ return expressionList;
+}
+
+EM_PORT_API(void) freeExpressionListParam(void *ptr) {
+ auto expressionList = (ExpressionList*)ptr;
+
+ for (uint32_t i = 0; i < expressionList->count; i++) {
+ // call Value desctructor
+ (expressionList->values + i)->~Value();
+ }
+
+ ::free(ptr);
+}
+
+EM_PORT_API(Value*) getInputValue(int flowStateIndex, int inputIndex) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+ return flowState->values + inputIndex;
+}
+
+EM_PORT_API(void) clearInputValue(int flowStateIndex, int inputIndex) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+ flowState->values[inputIndex] = Value();
+ onValueChanged(flowState->values + inputIndex);
+}
+
+EM_PORT_API(Value *) evalProperty(int flowStateIndex, int componentIndex, int propertyIndex, int32_t *iterators) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+
+ Value result;
+ if (!eez::flow::evalProperty(flowState, componentIndex, propertyIndex, result, "Failed to evaluate property", nullptr, iterators)) {
+ return nullptr;
+ }
+
+ auto pValue = ObjectAllocator::allocate(0xb7e697b8);
+ if (!pValue) {
+ throwError(flowState, componentIndex, "Out of memory\n");
+ return nullptr;
+ }
+
+ *pValue = result;
+
+ return pValue;
+}
+
+EM_PORT_API(void) assignProperty(int flowStateIndex, int componentIndex, int propertyIndex, int32_t *iterators, Value *srcValuePtr) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+
+ Value dstValue;
+ if (evalAssignableProperty(flowState, componentIndex, propertyIndex, dstValue, nullptr, nullptr, iterators)) {
+ assignValue(flowState, componentIndex, dstValue, *srcValuePtr);
+ }
+}
+
+EM_PORT_API(void) setPropertyField(int flowStateIndex, int componentIndex, int propertyIndex, int fieldIndex, Value *valuePtr) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+
+ Value result;
+ if (!eez::flow::evalProperty(flowState, componentIndex, propertyIndex, result, "Failed to evaluate property")) {
+ return;
+ }
+
+ if (result.getType() == VALUE_TYPE_VALUE_PTR) {
+ result = *result.pValueValue;
+ }
+
+ if (result.getType() != VALUE_TYPE_ARRAY && result.getType() != VALUE_TYPE_ARRAY_REF) {
+ throwError(flowState, componentIndex, "Property is not an array");
+ return;
+ }
+
+ auto array = result.getArray();
+
+ if (fieldIndex < 0 || fieldIndex >= array->arraySize) {
+ throwError(flowState, componentIndex, "Invalid field index");
+ return;
+ }
+
+ array->values[fieldIndex] = *valuePtr;
+ onValueChanged(array->values + fieldIndex);
+}
+
+EM_PORT_API(void) propagateValue(int flowStateIndex, int componentIndex, int outputIndex, Value *valuePtr) {
+ auto flowState = getFlowState(g_mainAssets, flowStateIndex);
+ eez::flow::propagateValue(flowState, componentIndex, outputIndex, *valuePtr);
+}
+
+EM_PORT_API(void) propagateValueThroughSeqout(int flowStateIndex, int componentIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::propagateValueThroughSeqout(flowState, componentIndex);
+}
+
+EM_PORT_API(void) startAsyncExecution(int flowStateIndex, int componentIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::startAsyncExecution(flowState, componentIndex);
+}
+
+EM_PORT_API(void) endAsyncExecution(int flowStateIndex, int componentIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::endAsyncExecution(flowState, componentIndex);
+}
+
+EM_PORT_API(void) executeCallAction(int flowStateIndex, int componentIndex, int flowIndex) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::executeCallAction(flowState, componentIndex, flowIndex);
+}
+
+EM_PORT_API(void) logInfo(int flowStateIndex, int componentIndex, const char *infoMessage) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::logInfo(flowState, componentIndex, infoMessage);
+}
+
+EM_PORT_API(void) throwError(int flowStateIndex, int componentIndex, const char *errorMessage) {
+ auto flowState = getFlowState(flowStateIndex);
+ eez::flow::throwError(flowState, componentIndex, errorMessage);
+}
+
+EM_PORT_API(int) getFirstRootFlowState() {
+ if (!g_firstFlowState) {
+ return -1;
+ }
+ return getFlowStateIndex(g_firstFlowState);
+}
+
+EM_PORT_API(int) getFirstChildFlowState(int flowStateIndex) {
+ if (flowStateIndex == -1) {
+ return -1;
+ }
+ auto flowState = getFlowState(flowStateIndex);
+ auto firstChildFlowState = flowState->firstChild;
+ if (!firstChildFlowState) {
+ return -1;
+ }
+ return getFlowStateIndex(firstChildFlowState);
+}
+
+EM_PORT_API(int) getNextSiblingFlowState(int flowStateIndex) {
+ if (flowStateIndex == -1) {
+ return -1;
+ }
+ auto flowState = getFlowState(flowStateIndex);
+ auto nextSiblingFlowState = flowState->nextSibling;
+ if (!nextSiblingFlowState) {
+ return -1;
+ }
+ return getFlowStateIndex(nextSiblingFlowState);
+}
+
+EM_PORT_API(int) getFlowStateFlowIndex(int flowStateIndex) {
+ if (flowStateIndex == -1) {
+ return -1;
+ }
+ auto flowState = getFlowState(flowStateIndex);
+ return flowState->flowIndex;
+}
+
+EM_PORT_API(bool) isRTL() {
+ return g_isRTL;
+}
+
+
+#endif // __EMSCRIPTEN__
diff --git a/Middlewares/eez/flow/dashboard_api.h b/Middlewares/eez/flow/dashboard_api.h
new file mode 100644
index 0000000..c92c655
--- /dev/null
+++ b/Middlewares/eez/flow/dashboard_api.h
@@ -0,0 +1,29 @@
+/*
+* EEZ Framework
+* Copyright (C) 2022-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+namespace eez {
+namespace flow {
+
+int getFlowStateIndex(FlowState *flowState);
+
+} // flow
+} // eez
diff --git a/Middlewares/eez/flow/debugger.cpp b/Middlewares/eez/flow/debugger.cpp
new file mode 100644
index 0000000..d0ef12b
--- /dev/null
+++ b/Middlewares/eez/flow/debugger.cpp
@@ -0,0 +1,760 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace eez {
+namespace flow {
+
+enum MessagesToDebugger {
+ MESSAGE_TO_DEBUGGER_STATE_CHANGED, // STATE
+
+ MESSAGE_TO_DEBUGGER_ADD_TO_QUEUE, // FLOW_STATE_INDEX, SOURCE_COMPONENT_INDEX, SOURCE_OUTPUT_INDEX, TARGET_COMPONENT_INDEX, TARGET_INPUT_INDEX, FREE_MEMORT, ALLOC_MEMORY
+ MESSAGE_TO_DEBUGGER_REMOVE_FROM_QUEUE, // no params
+
+ MESSAGE_TO_DEBUGGER_GLOBAL_VARIABLE_INIT, // GLOBAL_VARIABLE_INDEX, VALUE_ADDR, VALUE
+ MESSAGE_TO_DEBUGGER_LOCAL_VARIABLE_INIT, // FLOW_STATE_INDEX, LOCAL_VARIABLE_INDEX, VALUE_ADDR, VALUE
+ MESSAGE_TO_DEBUGGER_COMPONENT_INPUT_INIT, // FLOW_STATE_INDEX, COMPONENT_INPUT_INDEX, VALUE_ADDR, VALUE
+
+ MESSAGE_TO_DEBUGGER_VALUE_CHANGED, // VALUE_ADDR, VALUE
+
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_CREATED, // FLOW_STATE_INDEX, FLOW_INDEX, PARENT_FLOW_STATE_INDEX (-1 - NO PARENT), PARENT_COMPONENT_INDEX (-1 - NO PARENT COMPONENT)
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_TIMELINE_CHANGED, // FLOW_STATE_INDEX, TIMELINE_POSITION
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_DESTROYED, // FLOW_STATE_INDEX
+
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_ERROR, // FLOW_STATE_INDEX, COMPONENT_INDEX, ERROR_MESSAGE
+
+ MESSAGE_TO_DEBUGGER_LOG, // LOG_ITEM_TYPE, FLOW_STATE_INDEX, COMPONENT_INDEX, MESSAGE
+
+ MESSAGE_TO_DEBUGGER_PAGE_CHANGED, // PAGE_ID
+
+ MESSAGE_TO_DEBUGGER_COMPONENT_EXECUTION_STATE_CHANGED, // FLOW_STATE_INDEX, COMPONENT_INDEX, STATE
+ MESSAGE_TO_DEBUGGER_COMPONENT_ASYNC_STATE_CHANGED // FLOW_STATE_INDEX, COMPONENT_INDEX, STATE
+};
+
+enum MessagesFromDebugger {
+ MESSAGE_FROM_DEBUGGER_RESUME, // no params
+ MESSAGE_FROM_DEBUGGER_PAUSE, // no params
+ MESSAGE_FROM_DEBUGGER_SINGLE_STEP, // no params
+
+ MESSAGE_FROM_DEBUGGER_ADD_BREAKPOINT, // FLOW_INDEX, COMPONENT_INDEX
+ MESSAGE_FROM_DEBUGGER_REMOVE_BREAKPOINT, // FLOW_INDEX, COMPONENT_INDEX
+ MESSAGE_FROM_DEBUGGER_ENABLE_BREAKPOINT, // FLOW_INDEX, COMPONENT_INDEX
+ MESSAGE_FROM_DEBUGGER_DISABLE_BREAKPOINT, // FLOW_INDEX, COMPONENT_INDEX
+
+ MESSAGE_FROM_DEBUGGER_MODE // MODE (0:RUN | 1:DEBUG)
+};
+
+enum LogItemType {
+ LOG_ITEM_TYPE_FATAL,
+ LOG_ITEM_TYPE_ERROR,
+ LOG_ITEM_TYPE_WARNING ,
+ LOG_ITEM_TYPE_SCPI,
+ LOG_ITEM_TYPE_INFO,
+ LOG_ITEM_TYPE_DEBUG
+};
+
+enum DebuggerState {
+ DEBUGGER_STATE_RESUMED,
+ DEBUGGER_STATE_PAUSED,
+ DEBUGGER_STATE_SINGLE_STEP,
+ DEBUGGER_STATE_STOPPED,
+};
+
+bool g_debuggerIsConnected;
+static DebuggerState g_debuggerState;
+static bool g_skipNextBreakpoint;
+
+static char g_inputFromDebugger[64];
+static unsigned g_inputFromDebuggerPosition;
+
+int g_debuggerMode = DEBUGGER_MODE_RUN;
+
+////////////////////////////////////////////////////////////////////////////////
+
+static void setDebuggerState(DebuggerState newState) {
+ if (newState != g_debuggerState) {
+ g_debuggerState = newState;
+
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_STATE_CHANGED,
+ g_debuggerState
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void onDebuggerClientConnected() {
+ g_debuggerIsConnected = true;
+
+ g_skipNextBreakpoint = false;
+ g_inputFromDebuggerPosition = 0;
+
+ setDebuggerState(DEBUGGER_STATE_PAUSED);
+}
+
+void onDebuggerClientDisconnected() {
+ g_debuggerIsConnected = false;
+ setDebuggerState(DEBUGGER_STATE_RESUMED);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void processDebuggerInput(char *buffer, uint32_t length) {
+ for (uint32_t i = 0; i < length; i++) {
+ if (buffer[i] == '\n') {
+ int messageFromDebugger = g_inputFromDebugger[0] - '0';
+
+ if (messageFromDebugger == MESSAGE_FROM_DEBUGGER_RESUME) {
+ setDebuggerState(DEBUGGER_STATE_RESUMED);
+ } else if (messageFromDebugger == MESSAGE_FROM_DEBUGGER_PAUSE) {
+ setDebuggerState(DEBUGGER_STATE_PAUSED);
+ } else if (messageFromDebugger == MESSAGE_FROM_DEBUGGER_SINGLE_STEP) {
+ setDebuggerState(DEBUGGER_STATE_SINGLE_STEP);
+ } else if (
+ messageFromDebugger >= MESSAGE_FROM_DEBUGGER_ADD_BREAKPOINT &&
+ messageFromDebugger <= MESSAGE_FROM_DEBUGGER_DISABLE_BREAKPOINT
+ ) {
+ char *p;
+ auto flowIndex = (uint32_t)strtol(g_inputFromDebugger + 2, &p, 10);
+ auto componentIndex = (uint32_t)strtol(p + 1, nullptr, 10);
+
+ auto assets = g_firstFlowState->assets;
+ auto flowDefinition = static_cast(assets->flowDefinition);
+ if (flowIndex >= 0 && flowIndex < flowDefinition->flows.count) {
+ auto flow = flowDefinition->flows[flowIndex];
+ if (componentIndex >= 0 && componentIndex < flow->components.count) {
+ auto component = flow->components[componentIndex];
+
+ component->breakpoint = messageFromDebugger == MESSAGE_FROM_DEBUGGER_ADD_BREAKPOINT ||
+ messageFromDebugger == MESSAGE_FROM_DEBUGGER_ENABLE_BREAKPOINT ? 1 : 0;
+ } else {
+ ErrorTrace("Invalid breakpoint component index\n");
+ }
+ } else {
+ ErrorTrace("Invalid breakpoint flow index\n");
+ }
+ } else if (messageFromDebugger == MESSAGE_FROM_DEBUGGER_MODE) {
+ g_debuggerMode = strtol(g_inputFromDebugger + 2, nullptr, 10);
+ gui::refreshScreen();
+ }
+
+ g_inputFromDebuggerPosition = 0;
+ } else {
+ if (g_inputFromDebuggerPosition < sizeof(g_inputFromDebugger)) {
+ g_inputFromDebugger[g_inputFromDebuggerPosition++] = buffer[i];
+ } else if (g_inputFromDebuggerPosition == sizeof(g_inputFromDebugger)) {
+ ErrorTrace("Input from debugger buffer overflow\n");
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool canExecuteStep(FlowState *&flowState, unsigned &componentIndex) {
+ if (!g_debuggerIsConnected) {
+ return true;
+ }
+
+ if (g_debuggerState == DEBUGGER_STATE_PAUSED) {
+ return false;
+ }
+
+ if (g_debuggerState == DEBUGGER_STATE_SINGLE_STEP) {
+ g_skipNextBreakpoint = false;
+ setDebuggerState(DEBUGGER_STATE_PAUSED);
+ return true;
+ }
+
+ // g_debuggerState == DEBUGGER_STATE_RESUMED
+
+ if (g_skipNextBreakpoint) {
+ g_skipNextBreakpoint = false;
+ } else {
+ auto component = flowState->flow->components[componentIndex];
+ if (component->breakpoint) {
+ g_skipNextBreakpoint = true;
+ setDebuggerState(DEBUGGER_STATE_PAUSED);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__EMSCRIPTEN__)
+char outputBuffer[1024 * 1024];
+#else
+char outputBuffer[64];
+#endif
+int outputBufferPosition = 0;
+
+#define WRITE_TO_OUTPUT_BUFFER(ch) \
+ outputBuffer[outputBufferPosition++] = ch; \
+ if (outputBufferPosition == sizeof(outputBuffer)) { \
+ writeDebuggerBufferHook(outputBuffer, outputBufferPosition); \
+ outputBufferPosition = 0; \
+ }
+
+#define FLUSH_OUTPUT_BUFFER() \
+ if (outputBufferPosition > 0) { \
+ writeDebuggerBufferHook(outputBuffer, outputBufferPosition); \
+ outputBufferPosition = 0; \
+ }
+
+void writeValueAddr(const void *pValue) {
+ char tmpStr[32];
+ snprintf(tmpStr, sizeof(tmpStr), "%p", pValue);
+ auto len = strlen(tmpStr);
+ for (size_t i = 0; i < len; i++) {
+ WRITE_TO_OUTPUT_BUFFER(tmpStr[i]);
+ }
+}
+
+void writeString(const char *str) {
+ WRITE_TO_OUTPUT_BUFFER('"');
+
+ for (const char *p = str; *p; p++) {
+ if (*p == '"') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('"');
+ } else if (*p == '\t') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('t');
+ } else if (*p == '\n') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('n');
+ } else {
+ WRITE_TO_OUTPUT_BUFFER(*p);
+ }
+ }
+
+ WRITE_TO_OUTPUT_BUFFER('"');
+ WRITE_TO_OUTPUT_BUFFER('\n');
+ FLUSH_OUTPUT_BUFFER();
+}
+
+void writeArrayType(uint32_t arrayType) {
+ char tmpStr[32];
+ snprintf(tmpStr, sizeof(tmpStr), "%x", (int)arrayType);
+ auto len = strlen(tmpStr);
+ for (size_t i = 0; i < len; i++) {
+ WRITE_TO_OUTPUT_BUFFER(tmpStr[i]);
+ }
+}
+
+void writeArray(const ArrayValue *arrayValue) {
+ WRITE_TO_OUTPUT_BUFFER('{');
+
+ writeValueAddr(arrayValue);
+
+ WRITE_TO_OUTPUT_BUFFER(',');
+ writeArrayType(arrayValue->arrayType);
+
+ for (uint32_t i = 0; i < arrayValue->arraySize; i++) {
+ WRITE_TO_OUTPUT_BUFFER(',');
+ writeValueAddr(&arrayValue->values[i]);
+ }
+
+ WRITE_TO_OUTPUT_BUFFER('}');
+ WRITE_TO_OUTPUT_BUFFER('\n');
+ FLUSH_OUTPUT_BUFFER();
+
+ for (uint32_t i = 0; i < arrayValue->arraySize; i++) {
+ onValueChanged(&arrayValue->values[i]);
+ }
+}
+
+void writeHex(char *dst, uint8_t *src, size_t srcLength) {
+ *dst++ = 'H';
+ for (size_t i = 0; i < srcLength; i++) {
+ *dst++ = toHexDigit(src[i] / 16);
+ *dst++ = toHexDigit(src[i] % 16);
+ }
+ *dst++ = 0;
+}
+
+void writeValue(const Value &value) {
+ char tempStr[64];
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4474)
+#endif
+
+ switch (value.getType()) {
+ case VALUE_TYPE_UNDEFINED:
+ stringCopy(tempStr, sizeof(tempStr) - 1, "undefined\n");
+ break;
+
+ case VALUE_TYPE_NULL:
+ stringCopy(tempStr, sizeof(tempStr) - 1, "null\n");
+ break;
+
+ case VALUE_TYPE_BOOLEAN:
+ stringCopy(tempStr, sizeof(tempStr) - 1, value.getBoolean() ? "true" : "false");
+ break;
+
+ case VALUE_TYPE_INT8:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRId8 "", value.int8Value);
+ break;
+
+ case VALUE_TYPE_UINT8:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRIu8 "", value.uint8Value);
+ break;
+
+ case VALUE_TYPE_INT16:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRId16 "", value.int16Value);
+ break;
+
+ case VALUE_TYPE_UINT16:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRIu16 "", value.uint16Value);
+ break;
+
+ case VALUE_TYPE_INT32:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRId32 "", value.int32Value);
+ break;
+
+ case VALUE_TYPE_UINT32:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRIu32 "", value.uint32Value);
+ break;
+
+ case VALUE_TYPE_INT64:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRId64 "", value.int64Value);
+ break;
+
+ case VALUE_TYPE_UINT64:
+ snprintf(tempStr, sizeof(tempStr) - 1, "%" PRIu64 "", value.uint64Value);
+ break;
+
+ case VALUE_TYPE_DOUBLE:
+ writeHex(tempStr, (uint8_t *)&value.doubleValue, sizeof(double));
+ break;
+
+ case VALUE_TYPE_FLOAT:
+ writeHex(tempStr, (uint8_t *)&value.floatValue, sizeof(float));
+ break;
+
+ case VALUE_TYPE_STRING:
+ case VALUE_TYPE_STRING_REF:
+ writeString(value.getString());
+ return;
+
+ case VALUE_TYPE_ARRAY:
+ case VALUE_TYPE_ARRAY_REF:
+ writeArray(value.getArray());
+ return;
+
+ case VALUE_TYPE_BLOB_REF:
+ snprintf(tempStr, sizeof(tempStr) - 1, "@%d", (int)((BlobRef *)value.refValue)->len);
+ break;
+
+ case VALUE_TYPE_STREAM:
+ snprintf(tempStr, sizeof(tempStr) - 1, ">%d", (int)(value.int32Value));
+ break;
+
+ case VALUE_TYPE_DATE:
+ tempStr[0] = '!';
+ writeHex(tempStr + 1, (uint8_t *)&value.doubleValue, sizeof(double));
+ break;
+
+ default:
+ tempStr[0] = 0;
+ break;
+ }
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+ stringAppendString(tempStr, sizeof(tempStr), "\n");
+
+ writeDebuggerBufferHook(tempStr, strlen(tempStr));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void onStarted(Assets *assets) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ auto flowDefinition = static_cast(assets->flowDefinition);
+
+ for (uint32_t i = 0; i < flowDefinition->globalVariables.count; i++) {
+ auto pValue = flowDefinition->globalVariables[i];
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%p\t",
+ MESSAGE_TO_DEBUGGER_GLOBAL_VARIABLE_INIT,
+ (int)i,
+ (const void *)pValue
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+
+ writeValue(*pValue);
+ }
+ }
+}
+
+void onStopped() {
+ setDebuggerState(DEBUGGER_STATE_STOPPED);
+}
+
+void onAddToQueue(FlowState *flowState, int sourceComponentIndex, int sourceOutputIndex, unsigned targetComponentIndex, int targetInputIndex) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ uint32_t free;
+ uint32_t alloc;
+ getAllocInfo(free, alloc);
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_ADD_TO_QUEUE,
+ (int)flowState->flowStateIndex,
+ sourceComponentIndex,
+ sourceOutputIndex,
+ targetComponentIndex,
+ targetInputIndex,
+ (int)free,
+ (int)ALLOC_BUFFER_SIZE
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void onRemoveFromQueue() {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\n",
+ MESSAGE_TO_DEBUGGER_REMOVE_FROM_QUEUE
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void onValueChanged(const Value *pValue) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%p\t",
+ MESSAGE_TO_DEBUGGER_VALUE_CHANGED,
+ (const void *)pValue
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+
+ writeValue(*pValue);
+ }
+}
+
+void onFlowStateCreated(FlowState *flowState) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_CREATED,
+ (int)flowState->flowStateIndex,
+ flowState->flowIndex,
+ (int)(flowState->parentFlowState ? flowState->parentFlowState->flowStateIndex : -1),
+ flowState->parentComponentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+
+ auto flow = flowState->flow;
+
+ for (uint32_t i = 0; i < flow->localVariables.count; i++) {
+ auto pValue = &flowState->values[flow->componentInputs.count + i];
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%p\t",
+ MESSAGE_TO_DEBUGGER_LOCAL_VARIABLE_INIT,
+ (int)flowState->flowStateIndex,
+ (int)i,
+ (const void *)pValue
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+
+ writeValue(*pValue);
+ }
+
+ for (uint32_t i = 0; i < flow->componentInputs.count; i++) {
+ //auto &input = flow->componentInputs[i];
+ //if (!(input & COMPONENT_INPUT_FLAG_IS_SEQ_INPUT)) {
+ auto pValue = &flowState->values[i];
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%p\t",
+ MESSAGE_TO_DEBUGGER_COMPONENT_INPUT_INIT,
+ (int)flowState->flowStateIndex,
+ (int)i,
+ (const void *)pValue
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+
+ writeValue(*pValue);
+ //}
+ }
+ }
+}
+
+void onFlowStateDestroyed(FlowState *flowState) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_DESTROYED,
+ (int)flowState->flowStateIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void onFlowStateTimelineChanged(FlowState *flowState) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%g\n",
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_TIMELINE_CHANGED,
+ (int)flowState->flowStateIndex,
+ flowState->timelinePosition
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void onFlowError(FlowState *flowState, int componentIndex, const char *errorMessage) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t",
+ MESSAGE_TO_DEBUGGER_FLOW_STATE_ERROR,
+ (int)flowState->flowStateIndex,
+ componentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ writeString(errorMessage);
+ }
+}
+
+void onComponentExecutionStateChanged(FlowState *flowState, int componentIndex) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_COMPONENT_EXECUTION_STATE_CHANGED,
+ (int)flowState->flowStateIndex,
+ componentIndex,
+ flowState->componenentExecutionStates[componentIndex] ? 1 : 0
+ );
+
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void onComponentAsyncStateChanged(FlowState *flowState, int componentIndex) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_COMPONENT_ASYNC_STATE_CHANGED,
+ (int)flowState->flowStateIndex,
+ componentIndex,
+ flowState->componenentAsyncStates[componentIndex] ? 1 : 0
+ );
+
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+void writeLogMessage(const char *str) {
+ for (const char *p = str; *p; p++) {
+ if (*p == '\t') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('t');
+ } if (*p == '\n') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('n');
+ } else {
+ WRITE_TO_OUTPUT_BUFFER(*p);
+ }
+ }
+
+ WRITE_TO_OUTPUT_BUFFER('\n');
+ FLUSH_OUTPUT_BUFFER();
+}
+
+void writeLogMessage(const char *str, size_t len) {
+ for (size_t i = 0; i < len; i++) {
+ if (str[i] == '\t') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('t');
+ } if (str[i] == '\n') {
+ WRITE_TO_OUTPUT_BUFFER('\\');
+ WRITE_TO_OUTPUT_BUFFER('n');
+ } else {
+ WRITE_TO_OUTPUT_BUFFER(str[i]);
+ }
+ }
+
+ WRITE_TO_OUTPUT_BUFFER('\n');
+ FLUSH_OUTPUT_BUFFER();
+}
+
+void logInfo(FlowState *flowState, unsigned componentIndex, const char *message) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\t",
+ MESSAGE_TO_DEBUGGER_LOG,
+ LOG_ITEM_TYPE_INFO,
+ (int)flowState->flowStateIndex,
+ componentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ writeLogMessage(message);
+ }
+}
+
+void logScpiCommand(FlowState *flowState, unsigned componentIndex, const char *cmd) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\tSCPI COMMAND: ",
+ MESSAGE_TO_DEBUGGER_LOG,
+ LOG_ITEM_TYPE_SCPI,
+ (int)flowState->flowStateIndex,
+ componentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ writeLogMessage(cmd);
+ }
+}
+
+void logScpiQuery(FlowState *flowState, unsigned componentIndex, const char *query) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\t%d\t%d\tSCPI QUERY: ",
+ MESSAGE_TO_DEBUGGER_LOG,
+ LOG_ITEM_TYPE_SCPI,
+ (int)flowState->flowStateIndex,
+ componentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ writeLogMessage(query);
+ }
+}
+
+void logScpiQueryResult(FlowState *flowState, unsigned componentIndex, const char *resultText, size_t resultTextLen) {
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer) - 1, "%d\t%d\t%d\t%d\tSCPI QUERY RESULT: ",
+ MESSAGE_TO_DEBUGGER_LOG,
+ LOG_ITEM_TYPE_SCPI,
+ (int)flowState->flowStateIndex,
+ componentIndex
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ writeLogMessage(resultText, resultTextLen);
+ }
+}
+
+void onPageChanged(int previousPageId, int activePageId) {
+ if (flow::isFlowStopped()) {
+ return;
+ }
+
+ if (previousPageId == activePageId) {
+ return;
+ }
+
+ if (previousPageId > 0 && previousPageId < FIRST_INTERNAL_PAGE_ID) {
+ auto flowState = getFlowState(g_mainAssets, previousPageId - 1, WidgetCursor());
+ if (flowState) {
+ onEvent(flowState, FLOW_EVENT_CLOSE_PAGE);
+ }
+ } else if (previousPageId < 0) {
+ auto flowState = getFlowState(g_externalAssets, -previousPageId - 1, WidgetCursor());
+ if (flowState) {
+ onEvent(flowState, FLOW_EVENT_CLOSE_PAGE);
+ }
+ }
+
+ if (activePageId > 0 && activePageId < FIRST_INTERNAL_PAGE_ID) {
+ auto flowState = getFlowState(g_mainAssets, activePageId - 1, WidgetCursor());
+ if (flowState) {
+ onEvent(flowState, FLOW_EVENT_OPEN_PAGE);
+ }
+ } else if (activePageId < 0) {
+ auto flowState = getFlowState(g_externalAssets, -activePageId - 1, WidgetCursor());
+ if (flowState) {
+ onEvent(flowState, FLOW_EVENT_OPEN_PAGE);
+ }
+ }
+
+ if (g_debuggerIsConnected) {
+ startToDebuggerMessageHook();
+
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%d\t%d\n",
+ MESSAGE_TO_DEBUGGER_PAGE_CHANGED,
+ activePageId
+ );
+ writeDebuggerBufferHook(buffer, strlen(buffer));
+ }
+}
+
+} // namespace flow
+} // namespace eez
diff --git a/Middlewares/eez/flow/debugger.h b/Middlewares/eez/flow/debugger.h
new file mode 100644
index 0000000..f8a0c37
--- /dev/null
+++ b/Middlewares/eez/flow/debugger.h
@@ -0,0 +1,62 @@
+/*
+* EEZ Generic Firmware
+* Copyright (C) 2021-present, Envox d.o.o.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+namespace eez {
+namespace flow {
+
+extern bool g_debuggerIsConnected;
+
+enum {
+ DEBUGGER_MODE_RUN,
+ DEBUGGER_MODE_DEBUG,
+};
+extern int g_debuggerMode;
+
+bool canExecuteStep(FlowState *&flowState, unsigned &componentIndex);
+
+void onStarted(gui::Assets *assets);
+void onStopped();
+
+void onAddToQueue(FlowState *flowState, int sourceComponentIndex, int sourceOutputIndex, unsigned targetComponentIndex, int targetInputIndex);
+void onRemoveFromQueue();
+
+void onValueChanged(const gui::Value *pValue);
+
+void onFlowStateCreated(FlowState *flowState);
+void onFlowStateDestroyed(FlowState *flowState);
+void onFlowStateTimelineChanged(FlowState *flowState);
+
+void onFlowError(FlowState *flowState, int componentIndex, const char *errorMessage);
+
+void onComponentExecutionStateChanged(FlowState *flowState, int componentIndex);
+void onComponentAsyncStateChanged(FlowState *flowState, int componentIndex);
+
+void logInfo(FlowState *flowState, unsigned componentIndex, const char *message);
+
+void logScpiCommand(FlowState *flowState, unsigned componentIndex, const char *cmd);
+void logScpiQuery(FlowState *flowState, unsigned componentIndex, const char *query);
+void logScpiQueryResult(FlowState *flowState, unsigned componentIndex, const char *resultText, size_t resultTextLen);
+
+void onPageChanged(int previousPageId, int activePageId);
+
+void processDebuggerInput(char *buffer, uint32_t length);
+
+} // flow
+} // eez
diff --git a/Middlewares/eez/flow/expression.cpp b/Middlewares/eez/flow/expression.cpp
new file mode 100644
index 0000000..fed70a3
--- /dev/null
+++ b/Middlewares/eez/flow/expression.cpp
@@ -0,0 +1,221 @@
+/*
+ * EEZ Modular Firmware
+ * Copyright (C) 2021-present, Envox d.o.o.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include