commit fa343db3347721dd01289a62cef9cb34a1f1025b Author: pvvx Date: Sat Apr 22 16:54:00 2017 +0300 first commit diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..e90b2e5 --- /dev/null +++ b/.cproject @@ -0,0 +1,735 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mingw32-make.exe + -s -j 4 + all + true + false + false + + + make + -s + clean + true + true + false + + + make + -s + flashburn + true + true + false + + + make + -s + reset + true + true + false + + + make + -s + test + true + true + false + + + mingw32-make.exe + -s + readfullflash + true + true + false + + + mingw32-make.exe + -s + runram + true + true + false + + + mingw32-make.exe + -s + mp + true + true + false + + + mingw32-make.exe + -s + webfs + true + true + true + + + mingw32-make.exe + -s + flashwebfs + true + true + true + + + mingw32-make.exe + -s + flash_OTA + true + true + true + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0372c5a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/AutoMake/ +/build/ \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..4ba9658 --- /dev/null +++ b/.project @@ -0,0 +1,117 @@ + + + RTL00_WEB + + + RTL00_SDKV35a + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + RTL00_SDKV35a + 2 + PARENT-1-PROJECT_LOC/RTL00MP3/RTL00_SDKV35a + + + + + 0 + RTL00_SDKV35a + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.h + + + + 0 + RTL00_SDKV35a + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.c + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-AutoMake + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-build + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-flasher + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-LibAutoMake + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-project + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.git + + + + 0 + RTL00_SDKV35a + 10 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-.settings + + + + diff --git a/.settings/ilg.gnuarmeclipse.managedbuild.cross.prefs b/.settings/ilg.gnuarmeclipse.managedbuild.cross.prefs new file mode 100644 index 0000000..ba91ca5 --- /dev/null +++ b/.settings/ilg.gnuarmeclipse.managedbuild.cross.prefs @@ -0,0 +1,3 @@ +buildTools.path=D\:\\MCU\\GNU_Tools_ARM_Embedded\\5.4_2016q2\\bin +eclipse.preferences.version=1 +toolchain.path.1287942917=D\:\\MCU\\GNU_Tools_ARM_Embedded\\5.4_2016q2\\ diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..baf2884 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000..77386c2 --- /dev/null +++ b/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,67 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.codan.checkers.errnoreturn=Warning +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},implicit\=>false} +org.eclipse.cdt.codan.checkers.errreturnvalue=Error +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}} +org.eclipse.cdt.codan.checkers.noreturn=Error +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},implicit\=>false} +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error +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}} +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning +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}} +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning +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},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false} +org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning +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},unknown\=>false,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning +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},skip\=>true} +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error +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}} +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info +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},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning +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}} +org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning +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}} +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning +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}} +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning +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},macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning +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},paramNot\=>false} +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning +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},else\=>false,afterelse\=>false} +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error +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}} +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning +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},macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning +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},macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning +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},macro\=>true,exceptions\=>("@(\#)","$Id")} +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error +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}} diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 0000000..d24cd11 --- /dev/null +++ b/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,52 @@ +eclipse.preferences.version=1 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MINGW_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MINGW_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MINGW_HOME/value=C\:\\MinGW +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MSYS_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MSYS_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/MSYS_HOME/value=C\:\\MinGW\\msys\\1.0 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/OCD_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/OCD_PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/OCD_PATH/value=D\:\\MCU\\OpenOCD\\bin +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/PATH/value=${TL_PATH}\\bin;${MINGW_HOME}\\mingw64\\bin;${MINGW_HOME}\\bin;${MSYS_HOME}\\bin;${OCD_PATH};C\:/Program Files (x86)/Java/jre1.8.0_101/bin/client;C\:/Program Files (x86)/Java/jre1.8.0_101/bin;C\:/Program Files (x86)/Java/jre1.8.0_101/lib/i386;C\:\\MinGW\\mingw64\\bin;C\:\\MinGW\\msys\\1.0\\bin;C\:\\MinGW\\bin;D\:\\MCU\\STMicroelectronics\\st_toolset\\asm;C\:\\Python27;C\:\\Utils\\FarUtils;C\:\\Utils\\FarUtils\\HIEW810;C\:\\Windows;C\:\\Windows\\system32;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0;D\:\\MCU\\Microchip\\xc32\\v1.42\\bin;D\:\\MCU\\Microchip\\mplabc30\\v3.31\\bin;D\:\\MCU\\Microchip\\MPLAB C32 Suite\\bin;D\:\\MCU\\Microchip\\mplabc32\\v1.12\\bin;D\:\\MCU\\Microchip\\mcc18\\mpasm;D\:\\MCU\\Microchip\\mcc18\\bin;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\binC\:\\Program Files (x86)\\Git\\cmd;C\:\\Program Files (x86)\\Borland\\Delphi7\\Bin;C\:\\Program Files (x86)\\Borland\\Delphi7\\Projects\\Bpl\\;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files (x86)\\Common Files\\Acronis\\SnapAPI;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit;C\:\\Program Files (x86)\\Microsoft SDKs\\TypeScript\\1.0;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files\\Microsoft SQL Server\\120\\Tools\\Binn;C\:\\Program Files\\Microsoft DNX\\Dnvm;C\:\\Program Files\\IVI Foundation\\VISA\\Win64\\Bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\X86\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\X86\\bin;C\:\\Users\\PVV\\.dnx\\bin;C\:\\ProgramData\\chocolatey\\bin;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\QuickTime\\QTSystem;C\:\\Program Files\\nodejs;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\Git\\cmd;D\:\\MentorGraphics\\Sourcery_CodeBench_Lite_for_MIPS_ELF\\bin;C\:\\Eclipse +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/TL_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/TL_PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/TL_PATH/value=D\:\\MCU\\GNU_Tools_ARM_Embedded\\5.4_2016q2 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/append=true +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/appendContributed=true +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MINGW_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MINGW_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MINGW_HOME/value=C\:\\MinGW +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MSYS_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MSYS_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/MSYS_HOME/value=C\:\\MinGW\\msys\\1.0 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/OCD_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/OCD_PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/OCD_PATH/value=D\:\\MCU\\OpenOCD\\bin +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/PATH/value=${TL_PATH}\\bin;${MINGW_HOME}\\mingw64\\bin;${MINGW_HOME}\\bin;${MSYS_HOME}\\bin;${OCD_PATH};C\:/Program Files (x86)/Java/jre1.8.0_101/bin/client;C\:/Program Files (x86)/Java/jre1.8.0_101/bin;C\:/Program Files (x86)/Java/jre1.8.0_101/lib/i386;C\:\\MinGW\\mingw64\\bin;C\:\\MinGW\\msys\\1.0\\bin;C\:\\MinGW\\bin;D\:\\MCU\\STMicroelectronics\\st_toolset\\asm;C\:\\Python27;C\:\\Utils\\FarUtils;C\:\\Utils\\FarUtils\\HIEW810;C\:\\Windows;C\:\\Windows\\system32;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0;D\:\\MCU\\Microchip\\xc32\\v1.42\\bin;D\:\\MCU\\Microchip\\mplabc30\\v3.31\\bin;D\:\\MCU\\Microchip\\MPLAB C32 Suite\\bin;D\:\\MCU\\Microchip\\mplabc32\\v1.12\\bin;D\:\\MCU\\Microchip\\mcc18\\mpasm;D\:\\MCU\\Microchip\\mcc18\\bin;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\binC\:\\Program Files (x86)\\Git\\cmd;C\:\\Program Files (x86)\\Borland\\Delphi7\\Bin;C\:\\Program Files (x86)\\Borland\\Delphi7\\Projects\\Bpl\\;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files (x86)\\Common Files\\Acronis\\SnapAPI;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit;C\:\\Program Files (x86)\\Microsoft SDKs\\TypeScript\\1.0;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files\\Microsoft SQL Server\\120\\Tools\\Binn;C\:\\Program Files\\Microsoft DNX\\Dnvm;C\:\\Program Files\\IVI Foundation\\VISA\\Win64\\Bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\X86\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\X86\\bin;C\:\\Users\\PVV\\.dnx\\bin;C\:\\ProgramData\\chocolatey\\bin;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\QuickTime\\QTSystem;C\:\\Program Files\\nodejs;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\Git\\cmd;D\:\\MentorGraphics\\Sourcery_CodeBench_Lite_for_MIPS_ELF\\bin;C\:\\Eclipse +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/TL_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/TL_PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/TL_PATH/value=D\:\\MCU\\GNU_Tools_ARM_Embedded\\5.4_2016q2 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/append=true +environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/appendContributed=true +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MINGW_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MINGW_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MINGW_HOME/value=C\:\\MinGW +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MSYS_HOME/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MSYS_HOME/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/MSYS_HOME/value=C\:\\MinGW\\msys\\1.0 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/OCD_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/OCD_PATH/operation=append +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/OCD_PATH/value=D\:\\MCU\\OpenOCD\\bin +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/PATH/value=${TL_PATH}\\bin;${MINGW_HOME}\\mingw64\\bin;${MINGW_HOME}\\bin;${MSYS_HOME}\\bin;${OCD_PATH};C\:/Program Files (x86)/Java/jre1.8.0_101/bin/client;C\:/Program Files (x86)/Java/jre1.8.0_101/bin;C\:/Program Files (x86)/Java/jre1.8.0_101/lib/i386;C\:\\MinGW\\mingw64\\bin;C\:\\MinGW\\msys\\1.0\\bin;C\:\\MinGW\\bin;D\:\\MCU\\STMicroelectronics\\st_toolset\\asm;C\:\\Python27;C\:\\Utils\\FarUtils;C\:\\Utils\\FarUtils\\HIEW810;C\:\\Windows;C\:\\Windows\\system32;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0;D\:\\MCU\\Microchip\\xc32\\v1.42\\bin;D\:\\MCU\\Microchip\\mplabc30\\v3.31\\bin;D\:\\MCU\\Microchip\\MPLAB C32 Suite\\bin;D\:\\MCU\\Microchip\\mplabc32\\v1.12\\bin;D\:\\MCU\\Microchip\\mcc18\\mpasm;D\:\\MCU\\Microchip\\mcc18\\bin;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\binC\:\\Program Files (x86)\\Git\\cmd;C\:\\Program Files (x86)\\Borland\\Delphi7\\Bin;C\:\\Program Files (x86)\\Borland\\Delphi7\\Projects\\Bpl\\;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files (x86)\\Common Files\\Acronis\\SnapAPI;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit;C\:\\Program Files (x86)\\Microsoft SDKs\\TypeScript\\1.0;C\:\\Program Files (x86)\\IVI Foundation\\VISA\\WinNT\\Bin;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files\\Microsoft SQL Server\\120\\Tools\\Binn;C\:\\Program Files\\Microsoft DNX\\Dnvm;C\:\\Program Files\\IVI Foundation\\VISA\\Win64\\Bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SKWorkshop\\Marco\\X86\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\HMI\\bin;D\:\\Automation\\Samcoon\\SK035AE\\SKWorkshop\\Marco\\X86\\bin;C\:\\Users\\PVV\\.dnx\\bin;C\:\\ProgramData\\chocolatey\\bin;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\QuickTime\\QTSystem;C\:\\Program Files\\nodejs;D\:\\WRK\\TortoiseGit\\bin;C\:\\Utils\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\Git\\cmd;D\:\\MentorGraphics\\Sourcery_CodeBench_Lite_for_MIPS_ELF\\bin;C\:\\Eclipse +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/TL_PATH/delimiter=; +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/TL_PATH/operation=replace +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/TL_PATH/value=D\:\\MCU\\GNU_Tools_ARM_Embedded\\5.4_2016q2 +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/append=true +environment/project/cdt.managedbuild.config.gnu.mingw.exe.release.510381534/appendContributed=true diff --git a/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/.settings/org.eclipse.cdt.managedbuilder.core.prefs new file mode 100644 index 0000000..4630071 --- /dev/null +++ b/.settings/org.eclipse.cdt.managedbuilder.core.prefs @@ -0,0 +1,25 @@ +eclipse.preferences.version=1 +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/CPATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/CPATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/CPLUS_INCLUDE_PATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/CPLUS_INCLUDE_PATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/C_INCLUDE_PATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/C_INCLUDE_PATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/append=true +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/appendContributed=true +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/CPATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/CPATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/CPLUS_INCLUDE_PATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/CPLUS_INCLUDE_PATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/C_INCLUDE_PATH/delimiter=; +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/C_INCLUDE_PATH/operation=remove +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/append=true +environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/appendContributed=true +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/LIBRARY_PATH/delimiter=; +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/LIBRARY_PATH/operation=remove +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/append=true +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404.1853483235/appendContributed=true +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/LIBRARY_PATH/delimiter=; +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/LIBRARY_PATH/operation=remove +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/append=true +environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.1273936404/appendContributed=true diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 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/DAPLink-RTL00Console.bat b/DAPLink-RTL00Console.bat new file mode 100644 index 0000000..bc0d13c --- /dev/null +++ b/DAPLink-RTL00Console.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "load_ram_binary RTL00Console_ROM.bin 0x10000BA8" -c "exit" +rem -c "shutdown" + + diff --git a/DAPLink-RdFullFlash.bat b/DAPLink-RdFullFlash.bat new file mode 100644 index 0000000..5861662 --- /dev/null +++ b/DAPLink-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 5000" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/DAPLink-Reset.bat b/DAPLink-Reset.bat new file mode 100644 index 0000000..aceee70 --- /dev/null +++ b/DAPLink-Reset.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +@cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "restart_from_falsh" -c "shutdown" +rem + diff --git a/DAPLink_WrFullFlash.bat b/DAPLink_WrFullFlash.bat new file mode 100644 index 0000000..bd1cf72 --- /dev/null +++ b/DAPLink_WrFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 3500" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" -c "rtl8710_flash_write fullflash.bin 0" -c "shutdown" +pause + diff --git a/JLink-RTL00ConsoleROM.bat b/JLink-RTL00ConsoleROM.bat new file mode 100644 index 0000000..d8488c6 --- /dev/null +++ b/JLink-RTL00ConsoleROM.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +start JLink.exe -Device CORTEX-M3 -If SWD -Speed 4000 flasher\RTL00ConsoleROM.JLinkScript diff --git a/JLink-RdFullFlash.bat b/JLink-RdFullFlash.bat new file mode 100644 index 0000000..de5d955 --- /dev/null +++ b/JLink-RdFullFlash.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +JLink.exe -Device CORTEX-M3 -If SWD -Speed 10000 flasher/RTL_FFlash.JLinkScript diff --git a/JLink-Reset.bat b/JLink-Reset.bat new file mode 100644 index 0000000..51ea2a8 --- /dev/null +++ b/JLink-Reset.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +JLink.exe -Device CORTEX-M3 -If SWD -Speed 1000 flasher\RTL_Reset.JLinkScript diff --git a/JLink-RunRAM.bat b/JLink-RunRAM.bat new file mode 100644 index 0000000..4282a8e --- /dev/null +++ b/JLink-RunRAM.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +start JLink.exe -Device CORTEX-M3 -If SWD -Speed 4000 flasher\RTL_RunRAM.JLinkScript diff --git a/JLinkGDB-RdFullFlash.bat b/JLinkGDB-RdFullFlash.bat new file mode 100644 index 0000000..76865da --- /dev/null +++ b/JLinkGDB-RdFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_rdflash.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/JLinkGDB-RunRAM.bat b/JLinkGDB-RunRAM.bat new file mode 100644 index 0000000..323aa3a --- /dev/null +++ b/JLinkGDB-RunRAM.bat @@ -0,0 +1,15 @@ +@echo off +call paths.bat +@if exist build\obj\build.axf goto run +echo File 'build\obj\build.axf' not found! +echo Build project... +mingw32-make.exe -f Makefile all +@if not exist build\obj\build.axf goto err +:run +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_run_ram.jlink +taskkill /F /IM JLinkGDBServer.exe +goto end +:err +echo Error! +:end \ No newline at end of file diff --git a/JLinkGDB-WrFlash.bat b/JLinkGDB-WrFlash.bat new file mode 100644 index 0000000..c70f651 --- /dev/null +++ b/JLinkGDB-WrFlash.bat @@ -0,0 +1,21 @@ +@echo off +call paths.bat +@if %1x==x goto xxx +set img_file=%1 +goto run +:xxx +set img_file=build/bin/ram_all.bin +:run +echo define call1>flasher/flash_file.jlink +echo SetFirwareSize %img_file%>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +echo define call2>>flasher/flash_file.jlink +echo FlasherWrite %img_file% 0 $Image1Size>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +echo define call3>>flasher/flash_file.jlink +echo FlasherWrite %img_file% $Image2Addr $Image2Size>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 3500 +arm-none-eabi-gdb.exe -x flasher/gdb_wrflash.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/JLinkGDBServer.bat b/JLinkGDBServer.bat new file mode 100644 index 0000000..c356ac1 --- /dev/null +++ b/JLinkGDBServer.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_init.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/JLinkGDB_OTA.bat b/JLinkGDB_OTA.bat new file mode 100644 index 0000000..f64317e --- /dev/null +++ b/JLinkGDB_OTA.bat @@ -0,0 +1,15 @@ +@echo off +call paths.bat +@if exist build\bin\ota.bin goto run +echo File 'build\obj\ota.bin' not found! +echo Build project... +mingw32-make.exe -f Makefile all +@if not exist build\bin\ota.bin goto err +:run +start start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_ota.jlink +taskkill /F /IM JLinkGDBServer.exe +goto end +:err +echo Error! +:end \ No newline at end of file diff --git a/JLinkOCD-RdFullFlash.bat b/JLinkOCD-RdFullFlash.bat new file mode 100644 index 0000000..4708bea --- /dev/null +++ b/JLinkOCD-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/Jlink.cfg -c "adapter_khz 3500" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 3900" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/JLink_RdFullFlash.bat b/JLink_RdFullFlash.bat new file mode 100644 index 0000000..450e141 --- /dev/null +++ b/JLink_RdFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +openocd -f interface/Jlink.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "adapter_khz 3500" -c "rtl8710_flash_read_id" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/JlinkOpenOCD.bat b/JlinkOpenOCD.bat new file mode 100644 index 0000000..6e354f6 --- /dev/null +++ b/JlinkOpenOCD.bat @@ -0,0 +1,4 @@ +@echo off +call paths.bat +taskkill /F /IM openocd.exe +start openocd -f interface\Jlink.cfg -f flasher\ameba1.cfg diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..794f882 --- /dev/null +++ b/Makefile @@ -0,0 +1,57 @@ + +all: ram_all +mp: ram_all_mp + +.PHONY: ram_all +ram_all: + @$(MAKE) -f sdkbuild.mk + @$(MAKE) -f flasher.mk genbin1 genbin23 + +.PHONY: ram_all_mp +ram_all_mp: + @$(MAKE) -f sdkbuild.mk mp + @$(MAKE) -f flasher.mk mp + +.PHONY: clean clean_all +clean: + @$(MAKE) -f sdkbuild.mk clean + +clean_all: + @$(MAKE) -f sdkbuild.mk clean_all + +.PHONY: flashburn runram reset test readfullflash flashwebfs +flashburn: + #JLinkGDB-WrFlash.bat + @$(MAKE) -f flasher.mk flashburn + +flash_OTA: + @$(MAKE) -f flasher.mk flash_OTA + +webfs: + @$(MAKE) -f webfs.mk + +flashwebfs: + @$(MAKE) -f webfs.mk + @$(MAKE) -f flasher.mk flashwebfs + #JLinkGDB-WrWebFs.bat + +runram: + #JLink-RunRAM.bat + @$(MAKE) --f flasher.mk runram + +reset: + #JLink-Reset.bat + @$(MAKE) -f flasher.mk reset + +test: + JLink-RTL00ConsoleROM.bat + #@make -f flasher.mk test + +readfullflash: + #JLink-RdFullFlash.bat + @$(MAKE) -f flasher.mk readfullflash + +.PHONY: prerequirement +prerequirement: + @$(file >DEPENDENCY_LIST.txt,$(DEPENDENCY_LIST)) + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f0ab692 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# RTL00 Web +--- +Проект на начальной стадии, не завершен!
+
+[форум](https://esp8266.ru/forum/threads/web-svalka-na-rtl871x.2403/)
+--- +Used Modules:
+RTL00(RTL8710AF), [F11AMIM13](http://fn-link.en.made-in-china.com/product/sSinPtAKZBke/China-RTL8711AM-Iot-Module.html) (RTL8711AM), [F11AFIM13-B1](http://fn-link.en.made-in-china.com/product/PSHnuEtJVXWh/China-RTL8711AF-IoT-Module-IEEE-802-11-B-G-N-2-4GHz-1T1R-WiFi-NFC-Module.html) (RTL8711AF)
+[PADI](https://www.pine64.org/?page_id=946) (RTL8710AF), [F10AFIM13-B1](http://en.ofeixin.com/products_detail/productId=65.html) (RTL8710AF), [TinyCon2005-A-BE](http://www.ralinwi.com/product.aspx?info_lb=54&flag=1) (RTL8711AF),
+[WFM-400](http://www.rayson.com/rayson/en/?pros=product&pros=product&b_cat_id=A03&m_cat_id=A0304&s_cat_id=A030401&prod_id=P0113&level=3) (RTL8711AM), [WFM-410](http://www.rayson.com/rayson/en/?pros=product&pros=product&b_cat_id=A03&m_cat_id=A0304&s_cat_id=A030401&prod_id=P0114&level=3) (RTL8711AF), [WFM-250](http://www.rayson.com/rayson/en/?pros=product&pros=product&b_cat_id=A03&m_cat_id=A0304&s_cat_id=A030401&prod_id=P0112&level=3) (RTL8195AM),
+[AW-CU238, AW-CU239](https://www.buyiot.net/pd-1) (RTL8711AM), [AW-CU245, AW-CU245, AW-CU245](https://www.buyiot.net/home-1) (RTL8711AM/RTL8195AM/RTL8711AF),
+[WG6611](http://www.jorjin.com/product.php?id=98) (RTL8711AM), [RAK473](http://www.rakwireless.com/en/download/RAK473/Firmware%20Upgrade) (RTL8711AM), [RAK474, RAK476](http://www.rakwireless.com/en/download/RAK473/Firmware%20Upgrade) (RTL8711AF), ...
diff --git a/STLink-RdFullFlash.bat b/STLink-RdFullFlash.bat new file mode 100644 index 0000000..af82648 --- /dev/null +++ b/STLink-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/stlink-v2.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 5000" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/STLink-Reset.bat b/STLink-Reset.bat new file mode 100644 index 0000000..d4aeb47 --- /dev/null +++ b/STLink-Reset.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +@cd flasher +openocd -f interface/stlink-v2.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "cortex_reboot" -c "shutdown" +rem + diff --git a/WEBFiles/$js.inc b/WEBFiles/$js.inc new file mode 100644 index 0000000..515a2a2 --- /dev/null +++ b/WEBFiles/$js.inc @@ -0,0 +1 @@ +var $ = function(id){return document.getElementById(id);} \ No newline at end of file diff --git a/WEBFiles/404.htm b/WEBFiles/404.htm new file mode 100644 index 0000000..8836bfc --- /dev/null +++ b/WEBFiles/404.htm @@ -0,0 +1,14 @@ + + + + 404 - Page not found + + + +

RTL871X Built-in Web server ©

+
+

404 - Page not found

+

Sorry, the page you are requesting was not found on this server.

+
+~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/adc.htm b/WEBFiles/adc.htm new file mode 100644 index 0000000..a4e492c --- /dev/null +++ b/WEBFiles/adc.htm @@ -0,0 +1,10 @@ +~inc:grfx1.inc~ +ADC: ? + +~inc:grfx2.inc~ \ No newline at end of file diff --git a/WEBFiles/disk_er1.htm b/WEBFiles/disk_er1.htm new file mode 100644 index 0000000..74a19e5 --- /dev/null +++ b/WEBFiles/disk_er1.htm @@ -0,0 +1,5 @@ +~inc:timer.inc~ +

Image Corrupt or Wrong Version!

+ +~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/disk_er2.htm b/WEBFiles/disk_er2.htm new file mode 100644 index 0000000..65e5a15 --- /dev/null +++ b/WEBFiles/disk_er2.htm @@ -0,0 +1,5 @@ +~inc:timer.inc~ +

File to big in flash!

+ +~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/disk_er3.htm b/WEBFiles/disk_er3.htm new file mode 100644 index 0000000..31552cb --- /dev/null +++ b/WEBFiles/disk_er3.htm @@ -0,0 +1,5 @@ +~inc:timer.inc~ +

Bad file!

+ +~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/disk_ok.htm b/WEBFiles/disk_ok.htm new file mode 100644 index 0000000..05e8f52 --- /dev/null +++ b/WEBFiles/disk_ok.htm @@ -0,0 +1,5 @@ +~inc:timer.inc~ +

Update Successful!

+ +~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/favicon.ico b/WEBFiles/favicon.ico new file mode 100644 index 0000000..8c3e438 Binary files /dev/null and b/WEBFiles/favicon.ico differ diff --git a/WEBFiles/footer.inc b/WEBFiles/footer.inc new file mode 100644 index 0000000..9cdeb41 --- /dev/null +++ b/WEBFiles/footer.inc @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/WEBFiles/grf.js b/WEBFiles/grf.js new file mode 100644 index 0000000..bf2669e --- /dev/null +++ b/WEBFiles/grf.js @@ -0,0 +1,613 @@ +; +(function(exports) { + var Util = { + extend : function() { + arguments[0] = arguments[0] || {}; + for (var i = 1; i < arguments.length; i++) { + for ( var key in arguments[i]) { + if (arguments[i].hasOwnProperty(key)) { + if (typeof (arguments[i][key]) === 'object') { + if (arguments[i][key] instanceof Array) { + arguments[0][key] = arguments[i][key] + } else { + arguments[0][key] = Util.extend( + arguments[0][key], arguments[i][key]) + } + } else { + arguments[0][key] = arguments[i][key] + } + } + } + } + return arguments[0] + } + }; + function TimeSeries(options) { + this.options = Util.extend({}, TimeSeries.defaultOptions, options); + this.clear() + } + TimeSeries.defaultOptions = { + resetBoundsInterval : 3000, + resetBounds : true + }; + TimeSeries.prototype.clear = function() { + this.data = []; + this.maxValue = Number.NaN; + this.minValue = Number.NaN + }; + TimeSeries.prototype.resetBounds = function() { + if (this.data.length) { + this.maxValue = this.data[0][1]; + this.minValue = this.data[0][1]; + for (var i = 1; i < this.data.length; i++) { + var value = this.data[i][1]; + if (value > this.maxValue) { + this.maxValue = value + } + if (value < this.minValue) { + this.minValue = value + } + } + } else { + this.maxValue = Number.NaN; + this.minValue = Number.NaN + } + }; + TimeSeries.prototype.append = function(timestamp, value, + sumRepeatedTimeStampValues) { + var i = this.data.length - 1; + while (i >= 0 && this.data[i][0] > timestamp) { + i-- + } + if (i === -1) { + this.data.splice(0, 0, [ timestamp, value ]) + } else if (this.data.length > 0 && this.data[i][0] === timestamp) { + if (sumRepeatedTimeStampValues) { + this.data[i][1] += value; + value = this.data[i][1] + } else { + this.data[i][1] = value + } + } else if (i < this.data.length - 1) { + this.data.splice(i + 1, 0, [ timestamp, value ]) + } else { + this.data.push([ timestamp, value ]) + } + this.maxValue = isNaN(this.maxValue) ? value : Math.max(this.maxValue, + value); + this.minValue = isNaN(this.minValue) ? value : Math.min(this.minValue, + value) + }; + TimeSeries.prototype.dropOldData = function(oldestValidTime, + maxDataSetLength) { + var removeCount = 0; + while (this.data.length - removeCount >= maxDataSetLength + && this.data[removeCount + 1][0] < oldestValidTime) { + removeCount++ + } + if (removeCount !== 0) { + this.data.splice(0, removeCount) + } + }; + function SmoothieChart(options) { + this.options = Util.extend({}, SmoothieChart.defaultChartOptions, + options); + this.seriesSet = []; + this.currentValueRange = 1; + this.currentVisMinValue = 0; + this.lastRenderTimeMillis = 0 + } + SmoothieChart.defaultChartOptions = { + millisPerPixel : 20, + enableDpiScaling : true, + yMinFormatter : function(min, precision) { + return parseFloat(min).toFixed(precision) + }, + yMaxFormatter : function(max, precision) { + return parseFloat(max).toFixed(precision) + }, + maxValueScale : 1, + interpolation : 'bezier', + scaleSmoothing : 0.125, + maxDataSetLength : 2, + grid : { + fillStyle : '#000000', + strokeStyle : '#777777', + lineWidth : 1, + sharpLines : false, + millisPerLine : 1000, + verticalSections : 2, + borderVisible : true + }, + labels : { + fillStyle : '#ffffff', + disabled : false, + fontSize : 10, + fontFamily : 'monospace', + precision : 2 + }, + horizontalLines : [] + }; + SmoothieChart.AnimateCompatibility = (function() { + var requestAnimationFrame = function(callback, element) { + var requestAnimationFrame = window.requestAnimationFrame + || window.webkitRequestAnimationFrame + || window.mozRequestAnimationFrame + || window.oRequestAnimationFrame + || window.msRequestAnimationFrame || function(callback) { + return window.setTimeout(function() { + callback(new Date().getTime()) + }, 16) + }; + return requestAnimationFrame.call(window, callback, element) + }, cancelAnimationFrame = function(id) { + var cancelAnimationFrame = window.cancelAnimationFrame + || function(id) { + clearTimeout(id) + }; + return cancelAnimationFrame.call(window, id) + }; + return { + requestAnimationFrame : requestAnimationFrame, + cancelAnimationFrame : cancelAnimationFrame + } + })(); + SmoothieChart.defaultSeriesPresentationOptions = { + lineWidth : 1, + strokeStyle : '#ffffff' + }; + SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { + this.seriesSet.push({ + timeSeries : timeSeries, + options : Util.extend({}, + SmoothieChart.defaultSeriesPresentationOptions, options) + }); + if (timeSeries.options.resetBounds + && timeSeries.options.resetBoundsInterval > 0) { + timeSeries.resetBoundsTimerId = setInterval(function() { + timeSeries.resetBounds() + }, timeSeries.options.resetBoundsInterval) + } + }; + SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + this.seriesSet.splice(i, 1); + break + } + } + if (timeSeries.resetBoundsTimerId) { + clearInterval(timeSeries.resetBoundsTimerId) + } + }; + SmoothieChart.prototype.getTimeSeriesOptions = function(timeSeries) { + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + return this.seriesSet[i].options + } + } + }; + SmoothieChart.prototype.bringToFront = function(timeSeries) { + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + var set = this.seriesSet.splice(i, 1); + this.seriesSet.push(set[0]); + break + } + } + }; + SmoothieChart.prototype.streamTo = function(canvas, delayMillis) { + this.canvas = canvas; + this.delay = delayMillis; + this.start() + }; + SmoothieChart.prototype.start = function() { + if (this.frame) { + return + } + if (this.options.enableDpiScaling && window + && window.devicePixelRatio !== 1) { + var canvasWidth = this.canvas.getAttribute('width'); + var canvasHeight = this.canvas.getAttribute('height'); + this.canvas.setAttribute('width', canvasWidth + * window.devicePixelRatio); + this.canvas.setAttribute('height', canvasHeight + * window.devicePixelRatio); + this.canvas.style.width = canvasWidth + 'px'; + this.canvas.style.height = canvasHeight + 'px'; + this.canvas.getContext('2d').scale(window.devicePixelRatio, + window.devicePixelRatio) + } + var animate = function() { + this.frame = SmoothieChart.AnimateCompatibility + .requestAnimationFrame(function() { + this.render(); + animate() + }.bind(this)) + }.bind(this); + animate() + }; + SmoothieChart.prototype.stop = function() { + if (this.frame) { + SmoothieChart.AnimateCompatibility.cancelAnimationFrame(this.frame); + delete this.frame + } + }; + SmoothieChart.prototype.updateValueRange = function() { + var chartOptions = this.options, chartMaxValue = Number.NaN, chartMinValue = Number.NaN; + for (var d = 0; d < this.seriesSet.length; d++) { + var timeSeries = this.seriesSet[d].timeSeries; + if (!isNaN(timeSeries.maxValue)) { + chartMaxValue = !isNaN(chartMaxValue) ? Math.max(chartMaxValue, + timeSeries.maxValue) : timeSeries.maxValue + } + if (!isNaN(timeSeries.minValue)) { + chartMinValue = !isNaN(chartMinValue) ? Math.min(chartMinValue, + timeSeries.minValue) : timeSeries.minValue + } + } + if (chartOptions.maxValue != null) { + chartMaxValue = chartOptions.maxValue + } else { + chartMaxValue *= chartOptions.maxValueScale + } + if (chartOptions.minValue != null) { + chartMinValue = chartOptions.minValue + } + if (this.options.yRangeFunction) { + var range = this.options.yRangeFunction({ + min : chartMinValue, + max : chartMaxValue + }); + chartMinValue = range.min; + chartMaxValue = range.max + } + if (!isNaN(chartMaxValue) && !isNaN(chartMinValue)) { + var targetValueRange = chartMaxValue - chartMinValue; + var valueRangeDiff = (targetValueRange - this.currentValueRange); + var minValueDiff = (chartMinValue - this.currentVisMinValue); + this.isAnimatingScale = Math.abs(valueRangeDiff) > 0.1 + || Math.abs(minValueDiff) > 0.1; + this.currentValueRange += chartOptions.scaleSmoothing + * valueRangeDiff; + this.currentVisMinValue += chartOptions.scaleSmoothing + * minValueDiff + } + this.valueRange = { + min : chartMinValue, + max : chartMaxValue + } + }; + SmoothieChart.prototype.render = function(canvas, time) { + var nowMillis = new Date().getTime(); + if (!this.isAnimatingScale) { + var maxIdleMillis = Math.min(1000 / 6, this.options.millisPerPixel); + if (nowMillis - this.lastRenderTimeMillis < maxIdleMillis) { + return + } + } + this.lastRenderTimeMillis = nowMillis; + canvas = canvas || this.canvas; + time = time || nowMillis - (this.delay || 0); + time -= time % this.options.millisPerPixel; + var context = canvas.getContext('2d'), chartOptions = this.options, dimensions = { + top : 0, + left : 0, + width : canvas.clientWidth, + height : canvas.clientHeight + }, oldestValidTime = time + - (dimensions.width * chartOptions.millisPerPixel), valueToYPixel = function( + value) { + var offset = value - this.currentVisMinValue; + return this.currentValueRange === 0 ? dimensions.height + : dimensions.height + - (Math.round((offset / this.currentValueRange) + * dimensions.height)) + }.bind(this), timeToXPixel = function(t) { + return Math.round(dimensions.width + - ((time - t) / chartOptions.millisPerPixel)) + }; + this.updateValueRange(); + context.font = chartOptions.labels.fontSize + 'px ' + + chartOptions.labels.fontFamily; + context.save(); + context.translate(dimensions.left, dimensions.top); + context.beginPath(); + context.rect(0, 0, dimensions.width, dimensions.height); + context.clip(); + context.save(); + context.fillStyle = chartOptions.grid.fillStyle; + context.clearRect(0, 0, dimensions.width, dimensions.height); + context.fillRect(0, 0, dimensions.width, dimensions.height); + context.restore(); + context.save(); + context.lineWidth = chartOptions.grid.lineWidth; + context.strokeStyle = chartOptions.grid.strokeStyle; + if (chartOptions.grid.millisPerLine > 0) { + context.beginPath(); + for (var t = time - (time % chartOptions.grid.millisPerLine); t >= oldestValidTime; t -= chartOptions.grid.millisPerLine) { + var gx = timeToXPixel(t); + if (chartOptions.grid.sharpLines) { + gx -= 0.5 + } + context.moveTo(gx, 0); + context.lineTo(gx, dimensions.height) + } + context.stroke(); + context.closePath() + } + for (var v = 1; v < chartOptions.grid.verticalSections; v++) { + var gy = Math.round(v * dimensions.height + / chartOptions.grid.verticalSections); + if (chartOptions.grid.sharpLines) { + gy -= 0.5 + } + context.beginPath(); + context.moveTo(0, gy); + context.lineTo(dimensions.width, gy); + context.stroke(); + context.closePath() + } + if (chartOptions.grid.borderVisible) { + context.beginPath(); + context.strokeRect(0, 0, dimensions.width, dimensions.height); + context.closePath() + } + context.restore(); + if (chartOptions.horizontalLines && chartOptions.horizontalLines.length) { + for (var hl = 0; hl < chartOptions.horizontalLines.length; hl++) { + var line = chartOptions.horizontalLines[hl], hly = Math + .round(valueToYPixel(line.value)) - 0.5; + context.strokeStyle = line.color || '#ffffff'; + context.lineWidth = line.lineWidth || 1; + context.beginPath(); + context.moveTo(0, hly); + context.lineTo(dimensions.width, hly); + context.stroke(); + context.closePath() + } + } + for (var d = 0; d < this.seriesSet.length; d++) { + context.save(); + var timeSeries = this.seriesSet[d].timeSeries, dataSet = timeSeries.data, seriesOptions = this.seriesSet[d].options; + timeSeries.dropOldData(oldestValidTime, + chartOptions.maxDataSetLength); + context.lineWidth = seriesOptions.lineWidth; + context.strokeStyle = seriesOptions.strokeStyle; + context.beginPath(); + var firstX = 0, lastX = 0, lastY = 0; + for (var i = 0; i < dataSet.length && dataSet.length !== 1; i++) { + var x = timeToXPixel(dataSet[i][0]), y = valueToYPixel(dataSet[i][1]); + if (i === 0) { + firstX = x; + context.moveTo(x, y) + } else { + switch (chartOptions.interpolation) { + case "linear": + case "line": { + context.lineTo(x, y); + break + } + case "bezier": + default: { + context.bezierCurveTo(Math.round((lastX + x) / 2), + lastY, Math.round((lastX + x)) / 2, y, x, y); + break + } + case "step": { + context.lineTo(x, lastY); + context.lineTo(x, y); + break + } + } + } + lastX = x; + lastY = y + } + if (dataSet.length > 1) { + if (seriesOptions.fillStyle) { + context.lineTo(dimensions.width + seriesOptions.lineWidth + + 1, lastY); + context.lineTo(dimensions.width + seriesOptions.lineWidth + + 1, dimensions.height + seriesOptions.lineWidth + + 1); + context.lineTo(firstX, dimensions.height + + seriesOptions.lineWidth); + context.fillStyle = seriesOptions.fillStyle; + context.fill() + } + if (seriesOptions.strokeStyle + && seriesOptions.strokeStyle !== 'none') { + context.stroke() + } + context.closePath() + } + context.restore() + } + if (!chartOptions.labels.disabled && !isNaN(this.valueRange.min) + && !isNaN(this.valueRange.max)) { + var maxValueString = chartOptions.yMaxFormatter( + this.valueRange.max, chartOptions.labels.precision), minValueString = chartOptions + .yMinFormatter(this.valueRange.min, + chartOptions.labels.precision); + context.fillStyle = chartOptions.labels.fillStyle; + context.fillText(maxValueString, dimensions.width + - context.measureText(maxValueString).width - 2, + chartOptions.labels.fontSize); + context.fillText(minValueString, dimensions.width + - context.measureText(minValueString).width - 2, + dimensions.height - 2) + } + if (chartOptions.timestampFormatter + && chartOptions.grid.millisPerLine > 0) { + var textUntilX = dimensions.width + - context.measureText(minValueString).width + 4; + for (var t = time - (time % chartOptions.grid.millisPerLine); t >= oldestValidTime; t -= chartOptions.grid.millisPerLine) { + var gx = timeToXPixel(t); + if (gx < textUntilX) { + var tx = new Date(t), ts = chartOptions + .timestampFormatter(tx), tsWidth = context + .measureText(ts).width; + textUntilX = gx - tsWidth - 2; + context.fillStyle = chartOptions.labels.fillStyle; + context.fillText(ts, gx - tsWidth, dimensions.height - 2) + } + } + } + context.restore() + }; + SmoothieChart.timeFormatter = function(date) { + function pad2(number) { + return (number < 10 ? '0' : '') + number + } + return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + + pad2(date.getSeconds()) + }; + exports.TimeSeries = TimeSeries; + exports.SmoothieChart = SmoothieChart +})(typeof exports === 'undefined' ? this : exports); +var line1 = new TimeSeries(); +var newval = 0; +function addpoint(xmlData) { + if (xmlData) { + newval = eval(getXMLValue(xmlData, 'value')); + line1.append(new Date().getTime(), newval); + document.getElementById('xdata').innerHTML = newval; + if (newval > xmax) + document.getElementById('xdata').style.color = '#0000A0'; + else if (newval < xmin) + document.getElementById('xdata').style.color = '#A00000'; + else + document.getElementById('xdata').style.color = '#00A000' + } else + line1.append(new Date().getTime(), newval) +} +var smoothie = new SmoothieChart({ + interpolation : 'linear', + minValue : 0, + millisPerPixel : millisPerPixel, + grid : { + strokeStyle : 'rgb(100, 110, 150)', + fillStyle : 'rgb(50, 55, 75)', + lineWidth : 1, + millisPerLine : millisPerLine, + verticalSections : 6 + }, + labels : { + precision : 0 + } +}); +smoothie.addTimeSeries(line1, { + strokeStyle : 'rgb(255, 0, 200)', + fillStyle : 'rgba(255, 0, 200, 0.3)', + lineWidth : 3 +}); +smoothie.streamTo(document.getElementById("mycanvas"), nextimeout); +setTimeout("newAJAXCommand(xmlfile, addpoint, true)", 100); +function slider(elemId, sliderWidth, range1, range2, step) { + var knobWidth = 17; + var knobHeight = 21; + var sliderHeight = 21; + var offsX, tmp; + var d = document; + var isIE = d.all || window.opera; + var point = (sliderWidth - knobWidth - 3) / (range2 - range1); + var slider = d.createElement('DIV'); + slider.id = elemId + '_slider'; + slider.className = 'slider'; + d.getElementById(elemId).appendChild(slider); + var knob = d.createElement('DIV'); + knob.id = elemId + '_knob'; + knob.className = 'knob'; + slider.appendChild(knob); + knob.style.left = 0; + knob.style.width = knobWidth + 'px'; + knob.style.height = knobHeight + 'px'; + slider.style.width = sliderWidth + 'px'; + slider.style.height = sliderHeight + 'px'; + var sliderOffset = slider.offsetLeft; + tmp = slider.offsetParent; + while (tmp.tagName != 'BODY') { + sliderOffset += tmp.offsetLeft; + tmp = tmp.offsetParent + } + if (isIE) { + knob.onmousedown = startCoord; + slider.onclick = sliderClick; + knob.onmouseup = endCoord; + slider.onmouseup = endCoord + } else { + knob.addEventListener("mousedown", startCoord, true); + slider.addEventListener("click", sliderClick, true); + knob.addEventListener("mouseup", endCoord, true); + slider.addEventListener("mouseup", endCoord, true) + } + function setValue(x) { + if (x < 0) + knob.style.left = 0; + else if (x > sliderWidth - knobWidth - 3) + knob.style.left = (sliderWidth - 3 - knobWidth) + 'px'; + else { + if (step == 0) + knob.style.left = x + 'px'; + else + knob.style.left = Math.round(x / (step * point)) * step * point + + 'px' + } + nextimeout = getValue(); + d.getElementById('toutid').value = nextimeout; + document.getElementById('toutid').innerHTML = nextimeout + } + function setValue2(x) { + if (x < range1 || x > range2) + alert('Value is not included into a slider range!'); + else + setValue((x - range1) * point); + nextimeout = getValue(); + d.getElementById('toutid').value = nextimeout; + document.getElementById('toutid').innerHTML = nextimeout + } + function getValue() { + return Math.round(parseInt(knob.style.left) / point) + range1 + } + function sliderClick(e) { + var x; + if (isIE) { + if (event.srcElement != slider) + return; + x = event.offsetX - Math.round(knobWidth / 2) + } else + x = e.pageX - sliderOffset - knobWidth / 2; + setValue(x) + } + function startCoord(e) { + if (isIE) { + offsX = event.clientX - parseInt(knob.style.left); + slider.onmousemove = mov + } else { + slider.addEventListener("mousemove", mov, true) + } + } + function mov(e) { + var x; + if (isIE) + x = event.clientX - offsX; + else + x = e.pageX - sliderOffset - knobWidth / 2; + setValue(x) + } + function endCoord() { + if (isIE) + slider.onmousemove = null; + else + slider.removeEventListener("mousemove", mov, true) + } + this.setValue = setValue2; + this.getValue = getValue +} +var mysl1 = new slider('sl', 333, 20, 10020, 0); +mysl1.setValue(500); +document.getElementById('toutid').innerHTML = mysl1.getValue(); \ No newline at end of file diff --git a/WEBFiles/grfx1.inc b/WEBFiles/grfx1.inc new file mode 100644 index 0000000..d3943eb --- /dev/null +++ b/WEBFiles/grfx1.inc @@ -0,0 +1,13 @@ + + + + RTL871X + + + +~inc:menu.inc~ + +
\ No newline at end of file diff --git a/WEBFiles/grfx2.inc b/WEBFiles/grfx2.inc new file mode 100644 index 0000000..30b1323 --- /dev/null +++ b/WEBFiles/grfx2.inc @@ -0,0 +1,6 @@ +
+
GET TimeOuts ? ms'
+
+ + +~inc:footer.inc~ diff --git a/WEBFiles/heap.htm b/WEBFiles/heap.htm new file mode 100644 index 0000000..1cf6850 --- /dev/null +++ b/WEBFiles/heap.htm @@ -0,0 +1,9 @@ +~inc:grfx1.inc~ +Heap Size: ? bytes +~inc:grfx2.inc~ diff --git a/WEBFiles/heap.xml b/WEBFiles/heap.xml new file mode 100644 index 0000000..edc3199 --- /dev/null +++ b/WEBFiles/heap.xml @@ -0,0 +1 @@ +Heap Size~sys_heap~ \ No newline at end of file diff --git a/WEBFiles/index.htm b/WEBFiles/index.htm new file mode 100644 index 0000000..881ec16 --- /dev/null +++ b/WEBFiles/index.htm @@ -0,0 +1,20 @@ + + + + RTL871X + + +~inc:menu.inc~ +
+

Info

+

+Name: ~wifi_ap_ssid~ Password: ~wifi_ap_psw~
+Web connect: ~web_remote~,
+WEB ver: ~sys_webver~, SDK ver: ~sys_sdkver~.
+ChipID: ~sys_cid~.

+DevTime: SNTP disable
+PowerStartTime: ?

+

+~inc:footer.inc~ +~inc:time.inc~ + \ No newline at end of file diff --git a/WEBFiles/logo.gif b/WEBFiles/logo.gif new file mode 100644 index 0000000..b930b2a Binary files /dev/null and b/WEBFiles/logo.gif differ diff --git a/WEBFiles/menu.inc b/WEBFiles/menu.inc new file mode 100644 index 0000000..a409e6c --- /dev/null +++ b/WEBFiles/menu.inc @@ -0,0 +1,26 @@ +

RTL871x Built-in Web server ©

+ + \ No newline at end of file diff --git a/WEBFiles/protect/chiprams.xml b/WEBFiles/protect/chiprams.xml new file mode 100644 index 0000000..5cad0a9 --- /dev/null +++ b/WEBFiles/protect/chiprams.xml @@ -0,0 +1,4 @@ + +~start~ +~xml_ram~ + diff --git a/WEBFiles/protect/cookie.js b/WEBFiles/protect/cookie.js new file mode 100644 index 0000000..ea8a307 --- /dev/null +++ b/WEBFiles/protect/cookie.js @@ -0,0 +1,70 @@ +function getCookie(name) { + var prefix = name + "="; + var cookieStartIndex = document.cookie.indexOf(prefix); + if (cookieStartIndex == -1) + return null; + var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + + prefix.length); + if (cookieEndIndex == -1) + cookieEndIndex = document.cookie.length; + return unescape(document.cookie.substring(cookieStartIndex + prefix.length, + cookieEndIndex)); +} +function setCookie(name, value) { + document.cookie = name + "=" + escape(value) + "; path=/"; +} +function setCookieElem(name, defv) { + var val = getCookie(name); + if (val == null || val.charAt(0) != '0' || val.charAt(1) != 'x') { + val = defv; + setCookie(name, val); + } + document.getElementById(name).value = val; +} +function NewCookie(add) { + var val = parseInt(document.getElementById('start').value, 16) & 0xFFFFFFF0; + if (val == NaN) + setCookieElem('start', '0x40000000'); + else { + val += add; + setCookie('start', '0x' + val.toString(16)); + var nval = val + 256; + setCookie('stop', '0x' + nval.toString(16)); + document.getElementById('start').value = '0x' + val.toString(16); + document.getElementById('pmem').contentWindow.location.reload(); + } +} +setCookieElem('start', '0x40000000'); +setCookieElem('set_ramaddr', '0x3FFF0000'); +setCookieElem('set_ramdata', '0x12345678'); +function UpTxt(xD, n, v) { + var x = getXMLValue(xD, n, v); + if (x == '?') + document.getElementById("id_" + n).style.color = "#833"; + else + document.getElementById("id_" + n).style.color = "#333"; + document.getElementById("id_" + n).innerHTML = x + v; +} +function UpdateValuesRam(xD) { + if (xD) { + UpTxt(xD, "ramaddr", ""); + UpTxt(xD, "ramdata", ""); + } +} +function SendRamVal(x) { + var addr = parseInt(document.getElementById('set_ramaddr').value, 16); + var val = parseInt(document.getElementById('set_ramdata').value, 16); + if (addr != NaN && val != NaN) { + document.getElementById('set_ramaddr').value = '0x' + addr.toString(16); + setCookie('set_ramaddr','0x' + addr.toString(16)); + document.getElementById('set_ramdata').value = '0x' + val.toString(16); + setCookie('set_ramdata','0x' + val.toString(16)); + if (x != 0) + newAJAXCommand('chiprams.xml?start=0x' + addr.toString(16), + UpdateValuesRam, 0); + else + newAJAXCommand('chiprams.xml?sys_ram0x' + addr.toString(16) + '=0x' + + val.toString(16) + '&start=0x' + addr.toString(16), + UpdateValuesRam, 0); + } +} \ No newline at end of file diff --git a/WEBFiles/protect/debug.htm b/WEBFiles/protect/debug.htm new file mode 100644 index 0000000..21c1e35 --- /dev/null +++ b/WEBFiles/protect/debug.htm @@ -0,0 +1,25 @@ + + + + RTL871X Debug and Tests + + +~inc:menu.inc~ +
+

Debug and Tests

+

+Chart 'heap', ST-AP RSSI

+System Restart

+Counter erase the last flash sector config: ~sys_rdec0x980FE000~

+

+
+
+

System constants?

+ + + +
+
+~inc:footer.inc~ + + \ No newline at end of file diff --git a/WEBFiles/protect/dsleep.htm b/WEBFiles/protect/dsleep.htm new file mode 100644 index 0000000..cbee35f --- /dev/null +++ b/WEBFiles/protect/dsleep.htm @@ -0,0 +1,30 @@ + + + + RTL871X + + + + + ~inc:menu.inc~ +
+

Test DeepSleep

+ + + + + + + + + + +
DeepSleep Time(ms):
DeepSleep Mode:
+

+ Reset event = ~sys_res_event~ (1-power, 2-reset, 3-software, 4-wdt)
+

+
+~inc:footer.inc~ + + + diff --git a/WEBFiles/protect/fullflash.bin b/WEBFiles/protect/fullflash.bin new file mode 100644 index 0000000..7bf721b --- /dev/null +++ b/WEBFiles/protect/fullflash.bin @@ -0,0 +1 @@ +~bin_flash_all~ \ No newline at end of file diff --git a/WEBFiles/protect/hexdmpb.htm b/WEBFiles/protect/hexdmpb.htm new file mode 100644 index 0000000..c7f4707 --- /dev/null +++ b/WEBFiles/protect/hexdmpb.htm @@ -0,0 +1,41 @@ + + + + RTL871X HexDump Byte + + + + ~inc:menu.inc~ +
+

HexDump Bytes

+ + + + + + + + +
RAM Start addr
+ + + + + + + + + + + + + + +
Write addr, value:
Read addr, value:??
+
+ + + \ No newline at end of file diff --git a/WEBFiles/protect/hexdmpb.txt b/WEBFiles/protect/hexdmpb.txt new file mode 100644 index 0000000..0331abd --- /dev/null +++ b/WEBFiles/protect/hexdmpb.txt @@ -0,0 +1 @@ +~hexdmpb~ \ No newline at end of file diff --git a/WEBFiles/protect/hexdmpd.htm b/WEBFiles/protect/hexdmpd.htm new file mode 100644 index 0000000..f754d8f --- /dev/null +++ b/WEBFiles/protect/hexdmpd.htm @@ -0,0 +1,41 @@ + + + + RTL871X HexDump DWord + + + + ~inc:menu.inc~ +
+

HexDump DWord

+ + + + + + + + +
RAM Start addr   
+ + + + + + + + + + + + + + +
Write addr, value:
Read addr, value:??
+
+ + + \ No newline at end of file diff --git a/WEBFiles/protect/hexdmpd.txt b/WEBFiles/protect/hexdmpd.txt new file mode 100644 index 0000000..8d03bdc --- /dev/null +++ b/WEBFiles/protect/hexdmpd.txt @@ -0,0 +1 @@ +~hexdmpd~ \ No newline at end of file diff --git a/WEBFiles/protect/ram.bin b/WEBFiles/protect/ram.bin new file mode 100644 index 0000000..cca0930 --- /dev/null +++ b/WEBFiles/protect/ram.bin @@ -0,0 +1 @@ +~bin_ram~ \ No newline at end of file diff --git a/WEBFiles/protect/scan.htm b/WEBFiles/protect/scan.htm new file mode 100644 index 0000000..4d30082 --- /dev/null +++ b/WEBFiles/protect/scan.htm @@ -0,0 +1,98 @@ + + + + +WiFi Scan + + + + ~inc:menu.inc~ +
+

+
Stations scanning...
+

+ + +
SSIDBSSIDAuthChRSSIHd
+ +
+
+ ~inc:footer.inc~ + + + + + diff --git a/WEBFiles/protect/scan.xml b/WEBFiles/protect/scan.xml new file mode 100644 index 0000000..fc7188e --- /dev/null +++ b/WEBFiles/protect/scan.xml @@ -0,0 +1 @@ +~wifi_scan~ diff --git a/WEBFiles/protect/setup.htm b/WEBFiles/protect/setup.htm new file mode 100644 index 0000000..3be19ef --- /dev/null +++ b/WEBFiles/protect/setup.htm @@ -0,0 +1,89 @@ + + + + RTL871X Setup + + + + +~inc:menu.inc~ +
+

System Setup

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WEB (HTTP) port:
WEB recved timeout:
WEB close timeout:
LogUART Printf() enable: + + +
Web pcb close enable: + + +
Checking pin WiFi cfg reset: + + +
NetBIOS enable: + + +
SNTP enable: + + +
Captive Portal AP: + + +
+

+ + + +

+
+
+~inc:footer.inc~ + + \ No newline at end of file diff --git a/WEBFiles/protect/tstfuncs.htm b/WEBFiles/protect/tstfuncs.htm new file mode 100644 index 0000000..417e3ed --- /dev/null +++ b/WEBFiles/protect/tstfuncs.htm @@ -0,0 +1,91 @@ + + + + RTL871X Download bin + + + +~inc:menu.inc~ +
+

Download bin

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ROM-BIOS:0x00000000..0x00080000512 kbytes
SRAM:0x10000000..0x10070000448 kbytes
TCM-RAM:0x1FFF0000..0x2000000064 kbytes
SDRAM:0x30000000..0x302000002048 kbytes
FLASH Bus:0x98000000..0x981000001024 kbytes
I/O SoC:0x40000000..0x40080000.. kbytes
ARM:0xEF000000..0xEFFFFFFF.. kbytes
+ + + + + + + + + + +
Start addr
End addr
+

+
+~inc:footer.inc~ + + + diff --git a/WEBFiles/protect/upload.htm b/WEBFiles/protect/upload.htm new file mode 100644 index 0000000..d8e355d --- /dev/null +++ b/WEBFiles/protect/upload.htm @@ -0,0 +1,23 @@ + + + + RTL871X WebFS Image Upload + + +~inc:menu.inc~ + +

WebFS Image Upload

+

+ Select WEBFiles.bin file...

+

+ +

+ +

+Curent Disk has ~wfs_files~ files, Disk Size: ~wfs_size~ bytes.
+Disk Addres: ~wfs_addr~, Max Disk Size: ~wfs_max_size~ bytes, Max 250 files.

+Flash ID: ~sys_fid~, Size: ~sys_fsize~ bytes.
+Download fullflash.bin

+

+~inc:footer.inc~ + \ No newline at end of file diff --git a/WEBFiles/protect/wifi.htm b/WEBFiles/protect/wifi.htm new file mode 100644 index 0000000..45af0a4 --- /dev/null +++ b/WEBFiles/protect/wifi.htm @@ -0,0 +1,192 @@ + + + + RTL871X WiFi + + + + ~inc:menu.inc~ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

WiFi SoftAP

WiFi Station

WiFi Mode:SSID:
AP SSID:Password:
Hidden SSID: + + + BSSID:
AP Password:Use BSSID: + + +
Channel:Auth Mode:
IEEE PHY:IP:
Auth Mode:Subnet Mask:
IP:Gateway:
Subnet Mask:AutoReConnect:
Gateway:ReConnectPause:
MAC:MAC:
DHCP: + + + DHCP: +
Country Code:RSSI:~wifi_st_rssi~ dB
RF Tx Power:Sleep Mode:
Max connections:Beacon (ms):
AP Host Name:ST Host Name:
+

+ + +

+
+
+~inc:footer.inc~ + + + \ No newline at end of file diff --git a/WEBFiles/rtl.gif b/WEBFiles/rtl.gif new file mode 100644 index 0000000..71b3e8d Binary files /dev/null and b/WEBFiles/rtl.gif differ diff --git a/WEBFiles/rtl1.gif b/WEBFiles/rtl1.gif new file mode 100644 index 0000000..ce3c45b Binary files /dev/null and b/WEBFiles/rtl1.gif differ diff --git a/WEBFiles/scripts.js b/WEBFiles/scripts.js new file mode 100644 index 0000000..a9cadab --- /dev/null +++ b/WEBFiles/scripts.js @@ -0,0 +1,33 @@ +var setFormValues = function(form, cfg) { + var name, field; + for (name in cfg){ + if (form[name]) { + field = form[name]; + if (field[1] && field[1].type === 'checkbox') { + field = field[1]; + } + if (field.type === 'checkbox'){ + field.checked = cfg[name] === '1' ? true : false; + } else { + field.value = cfg[name]; + } + } + } +} +var $ = function(id) { + return document.getElementById(id); +} +var reloadTimer={ + s:10, + reload:function(start) { + if(start) { + this.s = start; + } + $('timer').innerHTML = this.s < 10 ? '0' + this.s : this.s; + if (this.s == 0){ + document.location.href = document.referrer != '' ? document.referrer : '/'; + } + this.s--; + setTimeout('reloadTimer.reload()', 1000); + } +} diff --git a/WEBFiles/site.js b/WEBFiles/site.js new file mode 100644 index 0000000..c083aaa --- /dev/null +++ b/WEBFiles/site.js @@ -0,0 +1,95 @@ +/* Java for WEB device */ +var ajaxList = new Array(); // Stores a queue of AJAX events to process +var nextimeout = 500; +function newAJAXCommand(url, container, repeat, data) { + // Set up our object + var newAjax = new Object(); + var theTimer = new Date(); + newAjax.url = url; + newAjax.container = container; + newAjax.repeat = repeat; + newAjax.ajaxReq = null; + // Create and send the request + if (window.XMLHttpRequest) { + newAjax.ajaxReq = new XMLHttpRequest(); + newAjax.ajaxReq.open((data == null) ? "GET" : "POST", newAjax.url, true); + newAjax.ajaxReq.send(data); + // If we're using IE6 style (maybe 5.5 compatible too) + } else if (window.ActiveXObject) { + newAjax.ajaxReq = new ActiveXObject("Microsoft.XMLHTTP"); + if (newAjax.ajaxReq) { + newAjax.ajaxReq.open((data == null) ? "GET" : "POST", newAjax.url, true); + newAjax.ajaxReq.send(data); + } + } + newAjax.lastCalled = theTimer.getTime(); + // Store in our array + ajaxList.push(newAjax); +} +function pollAJAX() { + var curAjax = new Object(); + var theTimer = new Date(); + var elapsed; + // Read off the ajaxList objects one by one + for (i = ajaxList.length; i > 0; i--) { + curAjax = ajaxList.shift(); + if (!curAjax) + continue; + elapsed = theTimer.getTime() - curAjax.lastCalled; + // If we suceeded + if (curAjax.ajaxReq.readyState == 4 && curAjax.ajaxReq.status == 200) { + // If it has a container, write the result + if (typeof (curAjax.container) == 'function') + curAjax.container(curAjax.ajaxReq.responseXML.documentElement); + else if (typeof (curAjax.container) == 'string') + document.getElementById(curAjax.container).innerHTML = curAjax.ajaxReq.responseText; + // (otherwise do nothing for null values) + curAjax.ajaxReq.abort(); + curAjax.ajaxReq = null; + // If it's a repeatable request, then do so + if (curAjax.repeat) { + if (elapsed >= curAjax.repeat) + elapsed = 100; + else + elapsed = curAjax.repeat - elapsed; + setTimeout("newAJAXCommand('" + curAjax.url + "'," + + curAjax.container + "," + curAjax.repeat + ")", + elapsed); + } + continue; + } + // If we've waited over 4 second, then we timed out + if ((curAjax.ajaxReq.readyState == 4 && curAjax.ajaxReq.status == 404) + || (elapsed > 4000)) { + // Invoke the user function with null input + if (typeof (curAjax.container) == 'function') + curAjax.container(null); + else + // Alert the user + alert("Command failed.\nConnection to device was lost."); + curAjax.ajaxReq.abort(); + curAjax.ajaxReq = null; + // If it's a repeatable request, then do so + if (curAjax.repeat) + setTimeout("newAJAXCommand('" + curAjax.url + "'," + + curAjax.container + "," + curAjax.repeat + ")", 200); + continue; + } + // Otherwise, just keep waiting + ajaxList.push(curAjax); + } + // Call ourselves again in 10ms? + setTimeout("pollAJAX()", nextimeout); +}// End pollAjax +function getXMLValue(xmlData, field) { + try { + if (xmlData.getElementsByTagName(field)[0].firstChild.nodeValue) + return xmlData.getElementsByTagName(field)[0].firstChild.nodeValue; + else + return null; + } catch (err) { + return null; + } +} +//kick off the AJAX Updater +setTimeout("pollAJAX()", nextimeout); diff --git a/WEBFiles/slider.js b/WEBFiles/slider.js new file mode 100644 index 0000000..e6db7f7 --- /dev/null +++ b/WEBFiles/slider.js @@ -0,0 +1,97 @@ +function slider(elemId, sliderWidth, range1, range2, step) { + var knobWidth = 17; + var knobHeight = 21; + var sliderHeight = 21; + var offsX, tmp; + var d = document; + var isIE = d.all || window.opera; + var point = (sliderWidth - knobWidth - 3) / (range2 - range1); + var slider = d.createElement('DIV'); + slider.id = elemId + '_slider'; + slider.className = 'slider'; + d.getElementById(elemId).appendChild(slider); + var knob = d.createElement('DIV'); + knob.id = elemId + '_knob'; + knob.className = 'knob'; + slider.appendChild(knob); + knob.style.left = 0; + knob.style.width = knobWidth + 'px'; + knob.style.height = knobHeight + 'px'; + slider.style.width = sliderWidth + 'px'; + slider.style.height = sliderHeight + 'px'; + var sliderOffset = slider.offsetLeft; + tmp = slider.offsetParent; + while (tmp.tagName != 'BODY') { + sliderOffset += tmp.offsetLeft; + tmp = tmp.offsetParent + } + if (isIE) { + knob.onmousedown = startCoord; + slider.onclick = sliderClick; + knob.onmouseup = endCoord; + slider.onmouseup = endCoord + } else { + knob.addEventListener("mousedown", startCoord, true); + slider.addEventListener("click", sliderClick, true); + knob.addEventListener("mouseup", endCoord, true); + slider.addEventListener("mouseup", endCoord, true) + } + function setValue(x) { + if (x < 0) + knob.style.left = 0; + else if (x > sliderWidth - knobWidth - 3) + knob.style.left = (sliderWidth - 3 - knobWidth) + 'px'; + else { + if (step == 0) + knob.style.left = x + 'px'; + else + knob.style.left = Math.round(x / (step * point)) * step * point + + 'px' + } + NewTimeScale(getValue()) + } + function setValue2(x) { + if (x < range1 || x > range2) + alert('Value is not included into a slider range!'); + else + setValue((x - range1) * point); + NewTimeScale(getValue()) + } + function getValue() { + return Math.round(parseInt(knob.style.left) / point) + range1 + } + function sliderClick(e) { + var x; + if (isIE) { + if (event.srcElement != slider) + return; + x = event.offsetX - Math.round(knobWidth / 2) + } else + x = e.pageX - sliderOffset - knobWidth / 2; + setValue(x) + } + function startCoord(e) { + if (isIE) { + offsX = event.clientX - parseInt(knob.style.left); + slider.onmousemove = mov + } else { + slider.addEventListener("mousemove", mov, true) + } + } + function mov(e) { + var x; + if (isIE) + x = event.clientX - offsX; + else + x = e.pageX - sliderOffset - knobWidth / 2; + setValue(x) + } + function endCoord() { + if (isIE) + slider.onmousemove = null; + else + slider.removeEventListener("mousemove", mov, true) + } + this.setValue = setValue2; + this.getValue = getValue +} diff --git a/WEBFiles/smoothie.js b/WEBFiles/smoothie.js new file mode 100644 index 0000000..77bd785 --- /dev/null +++ b/WEBFiles/smoothie.js @@ -0,0 +1,808 @@ +// MIT License: +// +// Copyright (c) 2010-2013, Joe Walnes +// 2013-2014, Drew Noakes +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** + * Smoothie Charts - http://smoothiecharts.org/ + * (c) 2010-2013, Joe Walnes + * 2013-2014, Drew Noakes + * + * v1.0: Main charting library, by Joe Walnes + * v1.1: Auto scaling of axis, by Neil Dunn + * v1.2: fps (frames per second) option, by Mathias Petterson + * v1.3: Fix for divide by zero, by Paul Nikitochkin + * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds + * v1.5: Set default frames per second to 50... smoother. + * .start(), .stop() methods for conserving CPU, by Dmitry Vyal + * options.interpolation = 'bezier' or 'line', by Dmitry Vyal + * options.maxValue to fix scale, by Dmitry Vyal + * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla + * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin + * Smooth rescaling, by Kostas Michalopoulos + * v1.8: Set max length to customize number of live points in the dataset with options.maxDataSetLength, by Krishna Narni + * v1.9: Display timestamps along the bottom, by Nick and Stev-io + * (https://groups.google.com/forum/?fromgroups#!topic/smoothie-charts/-Ywse8FCpKI%5B1-25%5D) + * Refactored by Krishna Narni, to support timestamp formatting function + * v1.10: Switch to requestAnimationFrame, removed the now obsoleted options.fps, by Gergely Imreh + * v1.11: options.grid.sharpLines option added, by @drewnoakes + * Addressed warning seen in Firefox when seriesOption.fillStyle undefined, by @drewnoakes + * v1.12: Support for horizontalLines added, by @drewnoakes + * Support for yRangeFunction callback added, by @drewnoakes + * v1.13: Fixed typo (#32), by @alnikitich + * v1.14: Timer cleared when last TimeSeries removed (#23), by @davidgaleano + * Fixed diagonal line on chart at start/end of data stream, by @drewnoakes + * v1.15: Support for npm package (#18), by @dominictarr + * Fixed broken removeTimeSeries function (#24) by @davidgaleano + * Minor performance and tidying, by @drewnoakes + * v1.16: Bug fix introduced in v1.14 relating to timer creation/clearance (#23), by @drewnoakes + * TimeSeries.append now deals with out-of-order timestamps, and can merge duplicates, by @zacwitte (#12) + * Documentation and some local variable renaming for clarity, by @drewnoakes + * v1.17: Allow control over font size (#10), by @drewnoakes + * Timestamp text won't overlap, by @drewnoakes + * v1.18: Allow control of max/min label precision, by @drewnoakes + * Added 'borderVisible' chart option, by @drewnoakes + * Allow drawing series with fill but no stroke (line), by @drewnoakes + * v1.19: Avoid unnecessary repaints, and fixed flicker in old browsers having multiple charts in document (#40), by @asbai + * v1.20: Add SmoothieChart.getTimeSeriesOptions and SmoothieChart.bringToFront functions, by @drewnoakes + * v1.21: Add 'step' interpolation mode, by @drewnoakes + * v1.22: Add support for different pixel ratios. Also add optional y limit formatters, by @copacetic + * v1.23: Fix bug introduced in v1.22 (#44), by @drewnoakes + * v1.24: Fix bug introduced in v1.23, re-adding parseFloat to y-axis formatter defaults, by @siggy_sf + * v1.25: Fix bug seen when adding a data point to TimeSeries which is older than the current data, by @Nking92 + * Draw time labels on top of series, by @comolosabia + * Add TimeSeries.clear function, by @drewnoakes + * v1.26: Add support for resizing on high device pixel ratio screens, by @copacetic + * v1.27: Fix bug introduced in v1.26 for non whole number devicePixelRatio values, by @zmbush + * v1.28: Add 'minValueScale' option, by @megawac + */ + +;(function(exports) { + + var Util = { + extend: function() { + arguments[0] = arguments[0] || {}; + for (var i = 1; i < arguments.length; i++) + { + for (var key in arguments[i]) + { + if (arguments[i].hasOwnProperty(key)) + { + if (typeof(arguments[i][key]) === 'object') { + if (arguments[i][key] instanceof Array) { + arguments[0][key] = arguments[i][key]; + } else { + arguments[0][key] = Util.extend(arguments[0][key], arguments[i][key]); + } + } else { + arguments[0][key] = arguments[i][key]; + } + } + } + } + return arguments[0]; + } + }; + + /** + * Initialises a new TimeSeries with optional data options. + * + * Options are of the form (defaults shown): + * + *
+   * {
+   *   resetBounds: true,        // enables/disables automatic scaling of the y-axis
+   *   resetBoundsInterval: 3000 // the period between scaling calculations, in millis
+   * }
+   * 
+ * + * Presentation options for TimeSeries are specified as an argument to SmoothieChart.addTimeSeries. + * + * @constructor + */ + function TimeSeries(options) { + this.options = Util.extend({}, TimeSeries.defaultOptions, options); + this.clear(); + } + + TimeSeries.defaultOptions = { + resetBoundsInterval: 3000, + resetBounds: false // true + }; + + /** + * Clears all data and state from this TimeSeries object. + */ + TimeSeries.prototype.clear = function() { + this.data = []; + this.maxValue = Number.NaN; // The maximum value ever seen in this TimeSeries. + this.minValue = Number.NaN; // The minimum value ever seen in this TimeSeries. + }; + + /** + * Recalculate the min/max values for this TimeSeries object. + * + * This causes the graph to scale itself in the y-axis. + */ + TimeSeries.prototype.resetBounds = function() { + if (this.data.length) { + // Walk through all data points, finding the min/max value + this.maxValue = this.data[0][1]; + this.minValue = this.data[0][1]; + for (var i = 1; i < this.data.length; i++) { + var value = this.data[i][1]; + if (value > this.maxValue) { + this.maxValue = value; + } + if (value < this.minValue) { + this.minValue = value; + } + } + } else { + // No data exists, so set min/max to NaN + this.maxValue = Number.NaN; + this.minValue = Number.NaN; + } + }; + + /** + * Adds a new data point to the TimeSeries, preserving chronological order. + * + * @param timestamp the position, in time, of this data point + * @param value the value of this data point + * @param sumRepeatedTimeStampValues if timestamp has an exact match in the series, this flag controls + * whether it is replaced, or the values summed (defaults to false.) + */ + TimeSeries.prototype.append = function(timestamp, value, sumRepeatedTimeStampValues) { + // Rewind until we hit an older timestamp + var i = this.data.length - 1; + while (i >= 0 && this.data[i][0] > timestamp) { + i--; + } + + if (i === -1) { + // This new item is the oldest data + this.data.splice(0, 0, [timestamp, value]); + } else if (this.data.length > 0 && this.data[i][0] === timestamp) { + // Update existing values in the array + if (sumRepeatedTimeStampValues) { + // Sum this value into the existing 'bucket' +// this.data[i][1] += value; +// value = this.data[i][1]; + // + this.data[i][1] = (value + this.data[i][1])/2.0; + value = this.data[i]; + } else { + // Replace the previous value + this.data[i][1] = value; + } + } else if (i < this.data.length - 1) { + // Splice into the correct position to keep timestamps in order + this.data.splice(i + 1, 0, [timestamp, value]); + } else { + // Add to the end of the array + this.data.push([timestamp, value]); + } + + this.maxValue = isNaN(this.maxValue) ? value : Math.max(this.maxValue, value); + this.minValue = isNaN(this.minValue) ? value : Math.min(this.minValue, value); + }; + + TimeSeries.prototype.dropOldData = function(oldestValidTime, maxDataSetLength) { + // We must always keep one expired data point as we need this to draw the + // line that comes into the chart from the left, but any points prior to that can be removed. + var removeCount = 0; + while (this.data.length - removeCount >= maxDataSetLength && this.data[removeCount + 1][0] < oldestValidTime) { + removeCount++; + } + if (removeCount !== 0) { + this.data.splice(0, removeCount); + } + }; + + /** + * Initialises a new SmoothieChart. + * + * Options are optional, and should be of the form below. Just specify the values you + * need and the rest will be given sensible defaults as shown: + * + *
+   * {
+   *   minValue: undefined,                      // specify to clamp the lower y-axis to a given value
+   *   maxValue: undefined,                      // specify to clamp the upper y-axis to a given value
+   *   maxValueScale: 1,                         // allows proportional padding to be added above the chart. for 10% padding, specify 1.1.
+   *   minValueScale: 1,                         // allows proportional padding to be added below the chart. for 10% padding, specify 1.1.
+   *   yRangeFunction: undefined,                // function({min: , max: }) { return {min: , max: }; }
+   *   scaleSmoothing: 0.125,                    // controls the rate at which y-value zoom animation occurs
+   *   millisPerPixel: 20,                       // sets the speed at which the chart pans by
+   *   enableDpiScaling: true,                   // support rendering at different DPI depending on the device
+   *   yMinFormatter: function(min, precision) { // callback function that formats the min y value label
+   *     return parseFloat(min).toFixed(precision);
+   *   },
+   *   yMaxFormatter: function(max, precision) { // callback function that formats the max y value label
+   *     return parseFloat(max).toFixed(precision);
+   *   },
+   *   maxDataSetLength: 2,
+   *   interpolation: 'bezier'                   // one of 'bezier', 'linear', or 'step'
+   *   timestampFormatter: null,                 // optional function to format time stamps for bottom of chart
+   *                                             // you may use SmoothieChart.timeFormatter, or your own: function(date) { return ''; }
+   *   scrollBackwards: false,                   // reverse the scroll direction of the chart
+   *   horizontalLines: [],                      // [ { value: 0, color: '#ffffff', lineWidth: 1 } ]
+   *   grid:
+   *   {
+   *     fillStyle: '#000000',                   // the background colour of the chart
+   *     lineWidth: 1,                           // the pixel width of grid lines
+   *     strokeStyle: '#777777',                 // colour of grid lines
+   *     millisPerLine: 1000,                    // distance between vertical grid lines
+   *     sharpLines: false,                      // controls whether grid lines are 1px sharp, or softened
+   *     verticalSections: 2,                    // number of vertical sections marked out by horizontal grid lines
+   *     borderVisible: true                     // whether the grid lines trace the border of the chart or not
+   *   },
+   *   labels
+   *   {
+   *     disabled: false,                        // enables/disables labels showing the min/max values
+   *     fillStyle: '#ffffff',                   // colour for text of labels,
+   *     fontSize: 15,
+   *     fontFamily: 'sans-serif',
+   *     precision: 2
+   *   }
+   * }
+   * 
+ * + * @constructor + */ + function SmoothieChart(options) { + this.options = Util.extend({}, SmoothieChart.defaultChartOptions, options); + this.seriesSet = []; + this.currentValueRange = 1; + this.currentVisMinValue = 0; + this.lastRenderTimeMillis = 0; + } + + SmoothieChart.defaultChartOptions = { + millisPerPixel: 20, + enableDpiScaling: true, + yMinFormatter: function(min, precision) { + return parseFloat(min).toFixed(precision); + }, + yMaxFormatter: function(max, precision) { + return parseFloat(max).toFixed(precision); + }, + maxValueScale: 1, + minValueScale: 1, + interpolation: 'bezier', + scaleSmoothing: 0.125, + maxDataSetLength: 2, + scrollBackwards: false, + grid: { + fillStyle: '#000000', + strokeStyle: '#777777', + lineWidth: 1, + sharpLines: false, + millisPerLine: 1000, + verticalSections: 2, + borderVisible: true + }, + labels: { + fillStyle: '#ffffff', + disabled: false, + fontSize: 10, + fontFamily: 'monospace', + precision: 2 + }, + horizontalLines: [] + }; + + // Based on http://inspirit.github.com/jsfeat/js/compatibility.js + SmoothieChart.AnimateCompatibility = (function() { + var requestAnimationFrame = function(callback, element) { + var requestAnimationFrame = + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { + return window.setTimeout(function() { + callback(new Date().getTime()); + }, 16); + }; + return requestAnimationFrame.call(window, callback, element); + }, + cancelAnimationFrame = function(id) { + var cancelAnimationFrame = + window.cancelAnimationFrame || + function(id) { + clearTimeout(id); + }; + return cancelAnimationFrame.call(window, id); + }; + + return { + requestAnimationFrame: requestAnimationFrame, + cancelAnimationFrame: cancelAnimationFrame + }; + })(); + + SmoothieChart.defaultSeriesPresentationOptions = { + lineWidth: 1, + strokeStyle: '#ffffff' + }; + + /** + * Adds a TimeSeries to this chart, with optional presentation options. + * + * Presentation options should be of the form (defaults shown): + * + *
+   * {
+   *   lineWidth: 1,
+   *   strokeStyle: '#ffffff',
+   *   fillStyle: undefined
+   * }
+   * 
+ */ + SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { + this.seriesSet.push({timeSeries: timeSeries, options: Util.extend({}, SmoothieChart.defaultSeriesPresentationOptions, options)}); + if (timeSeries.options.resetBounds && timeSeries.options.resetBoundsInterval > 0) { + timeSeries.resetBoundsTimerId = setInterval( + function() { + timeSeries.resetBounds(); + }, + timeSeries.options.resetBoundsInterval + ); + } + }; + + /** + * Removes the specified TimeSeries from the chart. + */ + SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { + // Find the correct timeseries to remove, and remove it + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + this.seriesSet.splice(i, 1); + break; + } + } + // If a timer was operating for that timeseries, remove it + if (timeSeries.resetBoundsTimerId) { + // Stop resetting the bounds, if we were + clearInterval(timeSeries.resetBoundsTimerId); + } + }; + + /** + * Gets render options for the specified TimeSeries. + * + * As you may use a single TimeSeries in multiple charts with different formatting in each usage, + * these settings are stored in the chart. + */ + SmoothieChart.prototype.getTimeSeriesOptions = function(timeSeries) { + // Find the correct timeseries to remove, and remove it + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + return this.seriesSet[i].options; + } + } + }; + + /** + * Brings the specified TimeSeries to the top of the chart. It will be rendered last. + */ + SmoothieChart.prototype.bringToFront = function(timeSeries) { + // Find the correct timeseries to remove, and remove it + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + var set = this.seriesSet.splice(i, 1); + this.seriesSet.push(set[0]); + break; + } + } + }; + + /** + * Instructs the SmoothieChart to start rendering to the provided canvas, with specified delay. + * + * @param canvas the target canvas element + * @param delayMillis an amount of time to wait before a data point is shown. This can prevent the end of the series + * from appearing on screen, with new values flashing into view, at the expense of some latency. + */ + SmoothieChart.prototype.streamTo = function(canvas, delayMillis) { + this.canvas = canvas; + this.delay = delayMillis; + this.start(); + }; + + /** + * Make sure the canvas has the optimal resolution for the device's pixel ratio. + */ + SmoothieChart.prototype.resize = function() { + // TODO this function doesn't handle the value of enableDpiScaling changing during execution + if (!this.options.enableDpiScaling || !window || window.devicePixelRatio === 1) + return; + + var dpr = window.devicePixelRatio; + var width = parseInt(this.canvas.getAttribute('width')); + var height = parseInt(this.canvas.getAttribute('height')); + + if (!this.originalWidth || (Math.floor(this.originalWidth * dpr) !== width)) { + this.originalWidth = width; + this.canvas.setAttribute('width', (Math.floor(width * dpr)).toString()); + this.canvas.style.width = width + 'px'; + this.canvas.getContext('2d').scale(dpr, dpr); + } + + if (!this.originalHeight || (Math.floor(this.originalHeight * dpr) !== height)) { + this.originalHeight = height; + this.canvas.setAttribute('height', (Math.floor(height * dpr)).toString()); + this.canvas.style.height = height + 'px'; + this.canvas.getContext('2d').scale(dpr, dpr); + } + }; + + /** + * Starts the animation of this chart. + */ + SmoothieChart.prototype.start = function() { + if (this.frame) { + // We're already running, so just return + return; + } + + // Renders a frame, and queues the next frame for later rendering + var animate = function() { + this.frame = SmoothieChart.AnimateCompatibility.requestAnimationFrame(function() { + this.render(); + animate(); + }.bind(this)); + }.bind(this); + + animate(); + }; + + /** + * Stops the animation of this chart. + */ + SmoothieChart.prototype.stop = function() { + if (this.frame) { + SmoothieChart.AnimateCompatibility.cancelAnimationFrame(this.frame); + delete this.frame; + } + }; + + SmoothieChart.prototype.updateValueRange = function() { + // Calculate the current scale of the chart, from all time series. + var chartOptions = this.options, + chartMaxValue = Number.NaN, + chartMinValue = Number.NaN; + + for (var d = 0; d < this.seriesSet.length; d++) { + // TODO(ndunn): We could calculate / track these values as they stream in. + var timeSeries = this.seriesSet[d].timeSeries; + if (!isNaN(timeSeries.maxValue)) { + chartMaxValue = !isNaN(chartMaxValue) ? Math.max(chartMaxValue, timeSeries.maxValue) : timeSeries.maxValue; + } + + if (!isNaN(timeSeries.minValue)) { + chartMinValue = !isNaN(chartMinValue) ? Math.min(chartMinValue, timeSeries.minValue) : timeSeries.minValue; + } + } + + // Scale the chartMaxValue to add padding at the top if required + if (chartOptions.maxValue != null) { + chartMaxValue = chartOptions.maxValue; + } else { + chartMaxValue *= chartOptions.maxValueScale; + } + + // Set the minimum if we've specified one + if (chartOptions.minValue != null) { + chartMinValue = chartOptions.minValue; + } else { + chartMinValue -= Math.abs(chartMinValue * chartOptions.minValueScale - chartMinValue); + } + + // If a custom range function is set, call it + if (this.options.yRangeFunction) { + var range = this.options.yRangeFunction({min: chartMinValue, max: chartMaxValue}); + chartMinValue = range.min; + chartMaxValue = range.max; + } + + if (!isNaN(chartMaxValue) && !isNaN(chartMinValue)) { + var targetValueRange = chartMaxValue - chartMinValue; + var valueRangeDiff = (targetValueRange - this.currentValueRange); + var minValueDiff = (chartMinValue - this.currentVisMinValue); + this.isAnimatingScale = Math.abs(valueRangeDiff) > 0.01 || Math.abs(minValueDiff) > 0.01; + this.currentValueRange += chartOptions.scaleSmoothing * valueRangeDiff; + this.currentVisMinValue += chartOptions.scaleSmoothing * minValueDiff; + } + + this.valueRange = { min: chartMinValue, max: chartMaxValue }; + }; + + SmoothieChart.prototype.render = function(canvas, time) { + var nowMillis = new Date().getTime(); + + if (!this.isAnimatingScale) { + // We're not animating. We can use the last render time and the scroll speed to work out whether + // we actually need to paint anything yet. If not, we can return immediately. + + // Render at least every 1/6th of a second. The canvas may be resized, which there is + // no reliable way to detect. + var maxIdleMillis = Math.min(1000/6, this.options.millisPerPixel); + + if (nowMillis - this.lastRenderTimeMillis < maxIdleMillis) { + return; + } + } + + this.resize(); + + this.lastRenderTimeMillis = nowMillis; + + canvas = canvas || this.canvas; + time = time || nowMillis - (this.delay || 0); + + // Round time down to pixel granularity, so motion appears smoother. + time -= time % this.options.millisPerPixel; + + var context = canvas.getContext('2d'), + chartOptions = this.options, + dimensions = { top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight }, + // Calculate the threshold time for the oldest data points. + oldestValidTime = time - (dimensions.width * chartOptions.millisPerPixel), + valueToYPixel = function(value) { + var offset = value - this.currentVisMinValue; + return this.currentValueRange === 0 + ? dimensions.height + : dimensions.height - (Math.round((offset / this.currentValueRange) * dimensions.height)); + }.bind(this), + timeToXPixel = function(t) { + if(chartOptions.scrollBackwards) { + return Math.round((time - t) / chartOptions.millisPerPixel); + } + return Math.round(dimensions.width - ((time - t) / chartOptions.millisPerPixel)); + }; + + this.updateValueRange(); + + context.font = chartOptions.labels.fontSize + 'px ' + chartOptions.labels.fontFamily; + + // Save the state of the canvas context, any transformations applied in this method + // will get removed from the stack at the end of this method when .restore() is called. + context.save(); + + // Move the origin. + context.translate(dimensions.left, dimensions.top); + + // Create a clipped rectangle - anything we draw will be constrained to this rectangle. + // This prevents the occasional pixels from curves near the edges overrunning and creating + // screen cheese (that phrase should need no explanation). + context.beginPath(); + context.rect(0, 0, dimensions.width, dimensions.height); + context.clip(); + + // Clear the working area. + context.save(); + context.fillStyle = chartOptions.grid.fillStyle; + context.clearRect(0, 0, dimensions.width, dimensions.height); + context.fillRect(0, 0, dimensions.width, dimensions.height); + context.restore(); + + // Grid lines... + context.save(); + context.lineWidth = chartOptions.grid.lineWidth; + context.strokeStyle = chartOptions.grid.strokeStyle; + // Vertical (time) dividers. + if (chartOptions.grid.millisPerLine > 0) { + context.beginPath(); + for (var t = time - (time % chartOptions.grid.millisPerLine); + t >= oldestValidTime; + t -= chartOptions.grid.millisPerLine) { + var gx = timeToXPixel(t); + if (chartOptions.grid.sharpLines) { + gx -= 0.5; + } + context.moveTo(gx, 0); + context.lineTo(gx, dimensions.height); + } + context.stroke(); + context.closePath(); + } + + // Horizontal (value) dividers. + for (var v = 1; v < chartOptions.grid.verticalSections; v++) { + var gy = Math.round(v * dimensions.height / chartOptions.grid.verticalSections); + if (chartOptions.grid.sharpLines) { + gy -= 0.5; + } + context.beginPath(); + context.moveTo(0, gy); + context.lineTo(dimensions.width, gy); + context.stroke(); + context.closePath(); + } + // Bounding rectangle. + if (chartOptions.grid.borderVisible) { + context.beginPath(); + context.strokeRect(0, 0, dimensions.width, dimensions.height); + context.closePath(); + } + context.restore(); + + // Draw any horizontal lines... + if (chartOptions.horizontalLines && chartOptions.horizontalLines.length) { + for (var hl = 0; hl < chartOptions.horizontalLines.length; hl++) { + var line = chartOptions.horizontalLines[hl], + hly = Math.round(valueToYPixel(line.value)) - 0.5; + context.strokeStyle = line.color || '#ffffff'; + context.lineWidth = line.lineWidth || 1; + context.beginPath(); + context.moveTo(0, hly); + context.lineTo(dimensions.width, hly); + context.stroke(); + context.closePath(); + } + } + + // For each data set... + for (var d = 0; d < this.seriesSet.length; d++) { + context.save(); + var timeSeries = this.seriesSet[d].timeSeries, + dataSet = timeSeries.data, + seriesOptions = this.seriesSet[d].options; + + // Delete old data that's moved off the left of the chart. + timeSeries.dropOldData(oldestValidTime, chartOptions.maxDataSetLength); + + // Set style for this dataSet. + context.lineWidth = seriesOptions.lineWidth; + context.strokeStyle = seriesOptions.strokeStyle; + // Draw the line... + context.beginPath(); + // Retain lastX, lastY for calculating the control points of bezier curves. + var firstX = 0, lastX = 0, lastY = 0; + for (var i = 0; i < dataSet.length && dataSet.length !== 1; i++) { + var x = timeToXPixel(dataSet[i][0]), + y = valueToYPixel(dataSet[i][1]); + + if (i === 0) { + firstX = x; + context.moveTo(x, y); + } else { + switch (chartOptions.interpolation) { + case "linear": + case "line": { + context.lineTo(x,y); + break; + } + case "bezier": + default: { + // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_curves + // + // Assuming A was the last point in the line plotted and B is the new point, + // we draw a curve with control points P and Q as below. + // + // A---P + // | + // | + // | + // Q---B + // + // Importantly, A and P are at the same y coordinate, as are B and Q. This is + // so adjacent curves appear to flow as one. + // + context.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop + Math.round((lastX + x) / 2), lastY, // controlPoint1 (P) + Math.round((lastX + x)) / 2, y, // controlPoint2 (Q) + x, y); // endPoint (B) + break; + } + case "step": { + context.lineTo(x,lastY); + context.lineTo(x,y); + break; + } + } + } + + lastX = x; lastY = y; + } + + if (dataSet.length > 1) { + if (seriesOptions.fillStyle) { + // Close up the fill region. + context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY); + context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1); + context.lineTo(firstX, dimensions.height + seriesOptions.lineWidth); + context.fillStyle = seriesOptions.fillStyle; + context.fill(); + } + + if (seriesOptions.strokeStyle && seriesOptions.strokeStyle !== 'none') { + context.stroke(); + } + context.closePath(); + } + context.restore(); + } + + // Draw the axis values on the chart. + if (!chartOptions.labels.disabled && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max)) { + var maxValueString = chartOptions.yMaxFormatter(this.valueRange.max, chartOptions.labels.precision), + minValueString = chartOptions.yMinFormatter(this.valueRange.min, chartOptions.labels.precision), + labelPos = chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(maxValueString).width - 2; + context.fillStyle = chartOptions.labels.fillStyle; + context.fillText(maxValueString, labelPos, chartOptions.labels.fontSize); + context.fillText(minValueString, labelPos, dimensions.height - 2); + } + + // Display timestamps along x-axis at the bottom of the chart. + if (chartOptions.timestampFormatter && chartOptions.grid.millisPerLine > 0) { + var textUntilX = chartOptions.scrollBackwards + ? context.measureText(minValueString).width + : dimensions.width - context.measureText(minValueString).width + 4; + for (var t = time - (time % chartOptions.grid.millisPerLine); + t >= oldestValidTime; + t -= chartOptions.grid.millisPerLine) { + var gx = timeToXPixel(t); + // Only draw the timestamp if it won't overlap with the previously drawn one. + if ((!chartOptions.scrollBackwards && gx < textUntilX) || (chartOptions.scrollBackwards && gx > textUntilX)) { + // Formats the timestamp based on user specified formatting function + // SmoothieChart.timeFormatter function above is one such formatting option + var tx = new Date(t), + ts = chartOptions.timestampFormatter(tx), + tsWidth = context.measureText(ts).width; + + textUntilX = chartOptions.scrollBackwards + ? gx + tsWidth + 2 + : gx - tsWidth - 2; + + context.fillStyle = chartOptions.labels.fillStyle; + if(chartOptions.scrollBackwards) { + context.fillText(ts, gx, dimensions.height - 2); + } else { + context.fillText(ts, gx - tsWidth, dimensions.height - 2); + } + } + } + } + + context.restore(); // See .save() above. + }; +/* + // Sample timestamp formatting function + SmoothieChart.timeFormatter = function(date) { + function pad2(number) { return (number < 10 ? '0' : '') + number } + return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds()); + }; +*/ + exports.TimeSeries = TimeSeries; + exports.SmoothieChart = SmoothieChart; + +})(typeof exports === 'undefined' ? this : exports); + + diff --git a/WEBFiles/style.css b/WEBFiles/style.css new file mode 100644 index 0000000..f4874c0 --- /dev/null +++ b/WEBFiles/style.css @@ -0,0 +1,235 @@ +body{ +margin:4px auto; +width:640px; +color:black; +background:#fff; +font-size:14px; +font-family:"Lucida Grande", Tahoma, sans-serif; +} +img,table{ +border:0; +} +.top{ +color:#888; +background:url(logo.gif) no-repeat 0 0; +padding:3px 0 0 45px; +margin:0 0 10px 0; +} +.top img{ +vertical-align:middle; +} +h2.error{ +color:red; +} +h2.ok{ +color:green; +} +h2.title{ +text-align:center; +} +.menu{ +border-top:#fab548 5px solid; +background:#f1f1ed url(rtl.gif) no-repeat 10px 10px; +padding:5px 5px 5px 120px; +margin:0 0 10px 0; +min-height:120px; +border-radius:5px; +} +.menu div{ +width:220px; +float:left; +margin-right:10px; +} +.menu a, +.menu a:link{ +display:block; +font-weight:bold; +text-decoration:none; +color:#1486ba; +padding:0 5px 1px 10px; +font-size:13px; +border-radius:5px; +margin:0 0 1px 0; +border-bottom:#d6d9da 1px solid; +} +.menu a:visited{ +color:#777; +} +.menu a.active{ +color:#777; +background:#d6d9da; +} +.menu a:hover{ +color:#842; +background:#d6d9da; +} +table.form select{ +width:143px; +} +table.form{ +width:100%; +} +table.form td{ +font-size:13px; +padding:0; +} +table.form .label{ +width:45%; +font-weight:bold; +text-align:right; +padding-right:10px; +} +table.form .left{ +width:45%; +font-weight:bold; +text-align:left; +padding-left:10px; +} +table.scan{ +border-collapse:separate; +border-spacing: 0; +border:#aaa 2px solid; +text-align:center; +font-size:14px; +width:100%; +margin:0 0 10px 0; +background:#fff; +border-radius:5px; +} +table.scan th{ +color:#247; +border:#aaa 1px solid; +font-size:15px; +padding:2px 2px; +background:#fec; +} +table.scan td{ +border:#aaa 1px solid; +padding:2px 2px; +} +table.scan td.s:hover{ +background:#eef; +} +table.scan a:link{ +display:block; +font-weight:bold; +text-decoration:none; +color:#444; +border-radius:5px; +} +table.scan a:visited{ +color:#444; +} +table.scan a.active, +table.scan a:hover{ +color:#21e; +background:#d6d9da; +} +table.mdbtab{ +border-collapse:separate; +border-spacing: 0; +border:#aaa 2px solid; +text-align:center; +font-size:12px; +width:100%; +margin:0 0 10px 0; +background:#fff; +border-radius:5px; +} +table.mdbtab th{ +color:#247; +border:#aaa 1px solid; +font-size:12px; +padding:2px 2px; +background:#fec; +} +table.mdbtab td{ +border:#aaa 1px solid; +padding:2px 2px; +} +table.mdbtab td.s:hover{ +background:#eef; +} +table.mdbtab a:link{ +display:block; +font-weight:bold; +text-decoration:none; +color:#444; +border-radius:5px; +} +table.mdbtab a:visited{ +color:#444; +} +table.mdbtab a.active, +table.mdbtab a:hover{ +color:#21e; +background:#d6d9da; +} +.content{ +background:#f1f1ed; +border-radius:5px; +border-top:#1486ba 5px solid; +padding:10px; +margin:0 0 10px 0; +} +.footer{ +border-top:#75be45 5px solid;; +background:#d6d9da; +border-radius:5px; +padding:10px; +font-size:12px; +margin:0 0 5px 0; +} +.copyright{ +font-size:11px; +padding:0 0 0 10px; +text-align:right; +} +.button:visited, +.button{ +cursor:pointer; +display:inline-block; +font-weight:bold; +text-align:center; +text-decoration:none; +white-space:nowrap; +border-radius:5px; +background-image: linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); +background-color:#f0f0eb; +color:#312c2a; +border:1px solid #aaa; +border-color: rgba(0,0,0,0.3); +border-bottom-color: #777; +border-bottom-color: rgba(0,0,0,0.5); +box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.7), inset 0 0 0.08em rgba(255,255,255,0.5); +text-shadow: 0 1px 0 rgba(255,255,255,0.8); +padding:3px 15px; +} +.button:focus, +.button:hover{ +background-color:#ffffff; +background-image: linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); +} +#timer{ +color:red; +} +.center{ +text-align:center; +} +hr{ +border:0; +height:1px; +background:#333; +background-image:-webkit-linear-gradient(left, #ccc, #333, #ccc); +background-image:-moz-linear-gradient(left, #ccc, #333, #ccc); +background-image:-ms-linear-gradient(left, #ccc, #333, #ccc); +background-image: -o-linear-gradient(left, #ccc, #333, #ccc); +} +select, +input, +iframe{ +border-collapse:separate; +border-spacing: 0; +background:#fff; +border-radius:5px; +} \ No newline at end of file diff --git a/WEBFiles/time.inc b/WEBFiles/time.inc new file mode 100644 index 0000000..dfef378 --- /dev/null +++ b/WEBFiles/time.inc @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/WEBFiles/timeout.htm b/WEBFiles/timeout.htm new file mode 100644 index 0000000..e0e8588 --- /dev/null +++ b/WEBFiles/timeout.htm @@ -0,0 +1,16 @@ + + + + RTL871X WIFI + + + +

RTL871X Built-in Web server ©

+
+

Timeout ? sec...

+ * Redirect: http://~sys_url~/ *

+ Main +
+~inc:footer.inc~ + + diff --git a/WEBFiles/timer.inc b/WEBFiles/timer.inc new file mode 100644 index 0000000..5a4fa14 --- /dev/null +++ b/WEBFiles/timer.inc @@ -0,0 +1,12 @@ + + + + RTL871X WIFI + + + +

RTL871X Built-in Web server ©

+
+

Timeout ? sec...

+ Redirect: Main + diff --git a/WEBFiles/tst.htm b/WEBFiles/tst.htm new file mode 100644 index 0000000..bc74021 --- /dev/null +++ b/WEBFiles/tst.htm @@ -0,0 +1,9 @@ +~inc:grfx1.inc~ +Test: ? +~inc:grfx2.inc~ \ No newline at end of file diff --git a/WEBFiles/tst.xml b/WEBFiles/tst.xml new file mode 100644 index 0000000..f817f5a --- /dev/null +++ b/WEBFiles/tst.xml @@ -0,0 +1 @@ +Test~wifi_st_rssi~? diff --git a/WEBFiles/websock.htm b/WEBFiles/websock.htm new file mode 100644 index 0000000..85a2d39 --- /dev/null +++ b/WEBFiles/websock.htm @@ -0,0 +1,116 @@ + + + + +WebSocket Test +

WebSocket Test

+
+ + +
+
+
+ Log messages +
+ +
+ + diff --git a/WEBFiles/ws2.css b/WEBFiles/ws2.css new file mode 100644 index 0000000..688bba6 --- /dev/null +++ b/WEBFiles/ws2.css @@ -0,0 +1,12 @@ +#consoleLog { + overflow-y: scroll; + width: 480px; + height: 800px; + border: solid 1px #aaaaaa; + background-color: #ffffff; + padding-left: 5px; } +#consoleLog > pre { + margin-top: 0; + margin-bottom: 0; } +#consoleLog > pre:nth-child(even) { + background-color: #fafafa; } diff --git a/flasher.mk b/flasher.mk new file mode 100644 index 0000000..27141d5 --- /dev/null +++ b/flasher.mk @@ -0,0 +1,307 @@ +# RTL8710 Flasher v0.0.alfa +# pvvx 21.09.2016 +-include paths.mk +#--------------------------- +#FLASHER = stlink-v2-1 +#FLASHER = stlink-v2 +FLASHER ?= Jlink +JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/ +#--------------------------- +# Default +#--------------------------- +# TARGET dirs +TARGET ?= build +OBJ_DIR ?= build/obj +BIN_DIR ?= build/bin +ELFFILE ?= $(OBJ_DIR)/$(TARGET).axf +#--------------------------- +# Compilation tools +CROSS_COMPILE ?= $(GCC_PATH)arm-none-eabi- +AR ?= $(CROSS_COMPILE)ar +CC ?= $(CROSS_COMPILE)gcc +AS ?= $(CROSS_COMPILE)as +NM ?= $(CROSS_COMPILE)nm +LD ?= $(CROSS_COMPILE)gcc +GDB ?= $(CROSS_COMPILE)gdb +SIZE ?= $(CROSS_COMPILE)size +OBJCOPY ?= $(CROSS_COMPILE)objcopy +OBJDUMP ?= $(CROSS_COMPILE)objdump + +# Make bunary tools +TOOLS_PATH ?= component/soc/realtek/8195a/misc/iar_utility/common/tools/ +ifneq ($(shell uname), Linux) +EXE = .exe +endif +PICK = $(TOOLS_PATH)pick$(EXE) +PADDING = $(TOOLS_PATH)padding$(EXE) +CHCKSUM = $(TOOLS_PATH)checksum$(EXE) + +# openocd tools +OPENOCD = $(OPENOCD_PATH)openocd + +JLINK_GDB ?= JLinkGDBServer.exe +JLINK_EXE ?= JLink.exe + +ifeq ($(FLASHER), Jlink) +# Jlink FLASHER_SPEED ..4000 kHz +FLASHER_SPEED = 3500 +else +ifeq ($(FLASHER),stlink-v2) +# stlink-v2 FLASHER_SPEED ..1800 kHz +FLASHER_SPEED = 1800 +else +# over FLASHER_SPEED ..500 kHz ? +FLASHER_SPEED = 500 +endif +endif + +# COMPILED_BOOT if defined -> extract image1, boot head in elf +COMPILED_BOOT=1 +# COMPILED_BOOT_BIN if !defined -> use source startup boot +#COMPILED_BOOT_BIN=1 +# PADDINGSIZE defined -> image2 OTA +PADDINGSIZE =44k + +NMAPFILE = $(OBJ_DIR)/$(TARGET).nmap + +#FLASHER_PATH ?= flasher/ + +#RAM_IMAGE?= $(BIN_DIR)/ram.bin + +RAM1_IMAGE ?= $(BIN_DIR)/ram_1.bin +RAM1P_IMAGE ?= $(BIN_DIR)/ram_1.p.bin +RAM1R_IMAGE ?= $(BIN_DIR)/ram_1.r.bin + +RAM2_IMAGE = $(BIN_DIR)/ram_2.bin +RAM2P_IMAGE = $(BIN_DIR)/ram_2.p.bin +RAM2NS_IMAGE = $(BIN_DIR)/ram_2.ns.bin + +RAM3_IMAGE = $(BIN_DIR)/sdram.bin +RAM3P_IMAGE = $(BIN_DIR)/sdram.p.bin + +FLASH_IMAGE = $(BIN_DIR)/ram_all.bin +OTA_IMAGE = $(BIN_DIR)/ota.bin + +#all: FLASH_IMAGE = $(BIN_DIR)/ram_all.bin +#all: OTA_IMAGE = $(BIN_DIR)/ota.bin +mp: FLASH_IMAGE = $(BIN_DIR)/ram_all_mp.bin +mp: OTA_IMAGE = $(BIN_DIR)/ota_mp.bin + +TST_IMAGE = $(BIN_DIR)/ram_2.bin + +.PHONY: genbin1 genbin23 flashburn reset test readfullflash flashwebfs flash_OTA +.NOTPARALLEL: all mp genbin1 genbin23 flashburn reset test readfullflash _endgenbin flashwebfs flash_OTA + +all: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin +mp: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin + +genbin1: $(ELFFILE) $(RAM1P_IMAGE) + +genbin23: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin + + +_endgenbin: + @echo "-----------------------------------------------------------" + @echo "Image ($(OTA_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(OTA_IMAGE)) )) ) bytes" + @echo "Image ($(FLASH_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(FLASH_IMAGE)) )) ) bytes" + @echo "===========================================================" + +ifeq ($(FLASHER_TYPE), Jlink) + +reset: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_Reset.JLinkScript + +runram: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_RunRAM.JLinkScript + +readfullflash: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_FFlash.JLinkScript + + +flashburn: + @echo define call1>$(FLASHER_PATH)flash_file.jlink + @echo SetFirwareSize build/bin/ram_all.bin>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @echo define call2>>$(FLASHER_PATH)flash_file.jlink + @echo FlasherWrite build/bin/ram_all.bin 0 '$$'Image1Size>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @echo define call3>>$(FLASHER_PATH)flash_file.jlink + @echo FlasherWrite build/bin/ram_all.bin '$$'Image2Addr '$$'Image2Size>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_wrflash.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +flashwebfs: + @echo define call1>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageSize = $(shell printf '0x%X\n' $$(stat --printf="%s" $(BIN_DIR)/WEBFiles.bin))>>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageAddr = 0x0D0000>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @echo define call2>>$(FLASHER_PATH)file_info.jlink + @echo FlasherWrite $(BIN_DIR)/WEBFiles.bin '$$'ImageAddr '$$'ImageSize>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_wrfile.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +flash_OTA: + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_ota.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +else + +flashburn: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(RAM1P_IMAGE) 0" \ + -c "rtl8710_flash_write $(RAM2P_IMAGE) 0xb000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +flashimage2p: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(RAM2P_IMAGE) 0xb000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +flashwebfs: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(BIN_DIR)/webpages.espfs 0xd0000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + + +reset: +# @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed $(FLASHER_SPEED) flasher/RTLreset.JLinkScript + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_reboot" -c shutdown + +runram: +# @$(JLINK_PATH)$(JLINK_GDB) -device Cortex-M3 -if SWD -ir -endian little -speed $(FLASHER_SPEED) +# @$(GDB) -x flasher/gdb_run_ram.jlink +# @taskkill.exe -F -IM $(JLINK_GDB) + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "load_image $(RAM1R_IMAGE) 0x10000bc8 bin" \ + -c "load_image $(RAM2_IMAGE) 0x10006000 bin" \ + -c "mww 0x40000210 0x20200113" \ + -c "reset run" -c shutdown + +endif + +$(NMAPFILE): $(ELFFILE) + @echo "===========================================================" + @echo "Build names map file" + @echo $@ + @$(NM) $< | sort > $@ +# @echo "===========================================================" + +$(FLASH_IMAGE): $(RAM1P_IMAGE) $(RAM2P_IMAGE) $(RAM3P_IMAGE) + @echo "===========================================================" + @echo "Make Flash image ($(FLASH_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(FLASH_IMAGE) + @cat $(RAM1P_IMAGE) > $(FLASH_IMAGE) +# @chmod 777 $(FLASH_IMAGE) +ifdef PADDINGSIZE + @$(PADDING) $(PADDINGSIZE) 0xFF $(FLASH_IMAGE) +endif + @cat $(RAM2P_IMAGE) >> $(FLASH_IMAGE) + @cat $(RAM3P_IMAGE) >> $(FLASH_IMAGE) +# @echo "Image ($(FLASH_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(FLASH_IMAGE)) )) ) bytes" +# @echo "===========================================================" +# @rm $(BIN_DIR)/ram_*.p.bin + +$(OTA_IMAGE): $(RAM2NS_IMAGE) $(RAM3_IMAGE) + @echo "===========================================================" + @echo "Make OTA image ($(OTA_IMAGE))" + @rm -f $(OTA_IMAGE) + @cat $(RAM2NS_IMAGE) > $(OTA_IMAGE) + @cat $(RAM3P_IMAGE) >> $(OTA_IMAGE) +# @chmod 777 $(OTA_IMAGE) + @$(CHCKSUM) $(OTA_IMAGE) || true +# @echo "===========================================================" + +$(RAM1P_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image1r ($(RAM1R_IMAGE))" +# @echo "===========================================================" .bootloader +ifdef COMPILED_BOOT + @mkdir -p $(BIN_DIR) + @rm -f $(RAM1_IMAGE) $(RAM1R_IMAGE) +ifdef COMPILED_BOOT_BIN + @$(eval RAM1_START_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_start $(NMAPFILE) | awk '{print $$1}')) + @$(eval RAM1_END_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_end $(NMAPFILE) | awk '{print $$1}')) +else + @$(eval RAM1_START_ADDR := $(shell grep __ram_image1_text_start__ $(NMAPFILE) | awk '{print $$1}')) + @$(eval RAM1_END_ADDR := $(shell grep __ram_image1_text_end__ $(NMAPFILE) | awk '{print $$1}')) +endif + $(if $(RAM1_START_ADDR),,$(error "Not found __ram_image1_text_start__!")) + $(if $(RAM1_END_ADDR),,$(error "Not found __ram_image1_text_end__!")) +ifeq ($(RAM1_START_ADDR),$(RAM1_END_ADDR)) +ifdef COMPILED_BOOT_BIN + $(OBJCOPY) --change-section-address .boot.head=0x10000ba8 -j .boot.head -j .bootloader -Obinary $(ELFFILE) $(RAM1P_IMAGE) +else +# $(OBJCOPY) -j .rom_ram -Obinary $(ELFFILE) $(RAM_IMAGE) + $(OBJCOPY) -j .ram.start.table -j .ram_image1.text -Obinary $(ELFFILE) $(RAM1R_IMAGE) + $(PICK) 0x$(RAM1_START_ADDR) 0x$(RAM1_END_ADDR) $(RAM1R_IMAGE) $(RAM1P_IMAGE) head+reset_offset 0x0B000 +endif +else + $(error "BOOT-image size = 0") +# $(error Flasher: COMPILE_BOOT = No) +endif +else + @if [ -s $(RAM1R_IMAGE) ]; then echo "Use external $(RAM1R_IMAGE)!"; fi +endif + +$(RAM2P_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image2p ($(RAM2P_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(RAM2_IMAGE) $(RAM2P_IMAGE) + @$(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + @$(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!")) + $(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!")) + @$(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE) + @$(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2P_IMAGE) body+reset_offset+sig + +$(RAM2NS_IMAGE):$(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image2ns ($(RAM2NS_IMAGE))" +# @echo "===========================================================" + mkdir -p $(BIN_DIR) + rm -f $(RAM2_IMAGE) $(RAM2NS_IMAGE) + $(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + $(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!")) + $(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!")) + $(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE) + $(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2NS_IMAGE) body+reset_offset + +$(RAM3_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image3 (SDRAM, $(RAM3P_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE) + @$(eval RAM3_START_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + @$(eval RAM3_END_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM3_START_ADDR),,$(error "Not found __sdram_data_start__!")) + $(if $(RAM3_END_ADDR),,$(error "Not found __sdram_data_end__!")) +#ifneq ($(RAM3_START_ADDR),$(RAM3_END_ADDR)) + @echo $(RAM3_START_ADDR) $(RAM3_END_ADDR) + @$(OBJCOPY) -j .image3 -j .sdr_text -j .sdr_rodata -j .sdr_data -Obinary $(ELFFILE) $(RAM3_IMAGE) + $(PICK) 0x$(RAM3_START_ADDR) 0x$(RAM3_END_ADDR) $(RAM3_IMAGE) $(RAM3P_IMAGE) body+reset_offset +#else +# @rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE) +# @echo "SDRAM not used (size = 0)" +#endif + +$(ELFFILE): + $(error Falsher: file $@ not found) + +clean: + @rm -f $(BIN_DIR)/*.bin + \ No newline at end of file diff --git a/flasher/RTL00ConsoleROM.JLinkScript b/flasher/RTL00ConsoleROM.JLinkScript new file mode 100644 index 0000000..5b85200 --- /dev/null +++ b/flasher/RTL00ConsoleROM.JLinkScript @@ -0,0 +1,6 @@ +h +loadbin flasher/RTL00Console_ROM.bin 0x10000ba8 +r +w4 0x40000210,0x4011117 +g +q \ No newline at end of file diff --git a/flasher/RTL00Console_ROM.bin b/flasher/RTL00Console_ROM.bin new file mode 100644 index 0000000..e83cb16 Binary files /dev/null and b/flasher/RTL00Console_ROM.bin differ diff --git a/flasher/RTL8710.jflash b/flasher/RTL8710.jflash new file mode 100644 index 0000000..a5d0547 --- /dev/null +++ b/flasher/RTL8710.jflash @@ -0,0 +1,119 @@ + AppVersion = 47812 +[GENERAL] + ConnectMode = 0 + CurrentFile = "fullflash.bin" + DataFileSAddr = 0x98000000 + GUIMode = 0 + HostName = "" + TargetIF = 1 + USBPort = 0 + USBSerialNo = 0x00000000 +[JTAG] + IRLen = 0 + MultipleTargets = 0 + NumDevices = 0 + Speed0 = 400 + Speed1 = 12000 + TAP_Number = 0 + UseAdaptive0 = 0 + UseAdaptive1 = 0 + UseMaxSpeed0 = 0 + UseMaxSpeed1 = 0 +[CPU] + CheckCoreID = 0 + ChipName = "RTL8710AF" + ClockSpeed = 0x00000000 + Core = 0x030000FF + CoreID = 0x00000000 + CoreIDMask = 0x0F000FFF + DeviceFamily = 0x00000003 + EndianMode = 0 + HasInternalFlash = 0 + InitStep0_Action = "Reset" + InitStep0_Comment = "Reset and Halt" + InitStep0_Value0 = 0x00000000 + InitStep0_Value1 = 0x00000005 + InitStep1_Action = "Go" + InitStep1_Comment = "" + InitStep1_Value0 = 0x00000000 + InitStep1_Value1 = 0x00000000 + InitStep2_Action = "Reset" + InitStep2_Comment = "Reset and halt target" + InitStep2_Value0 = 0x00000000 + InitStep2_Value1 = 0x00000005 + InitStep3_Action = "Write Register" + InitStep3_Comment = "Only T=1" + InitStep3_Value0 = 0x00000010 + InitStep3_Value1 = 0x01000000 + InitStep4_Action = "Write 32bit" + InitStep4_Comment = "Setup SystemCoreClock" + InitStep4_Value0 = 0x40000014 + InitStep4_Value1 = 0x00000001 + InitStep5_Action = "Delay" + InitStep5_Comment = "" + InitStep5_Value0 = 0x00000000 + InitStep5_Value1 = 0x00000005 + InitStep6_Action = "Write 32bit" + InitStep6_Comment = "Write Page Size" + InitStep6_Value0 = 0x1FFFFFF0 + InitStep6_Value1 = 0x00000100 + InitStep7_Action = "Write 32bit" + InitStep7_Comment = "Write Sector Size" + InitStep7_Value0 = 0x1FFFFFF4 + InitStep7_Value1 = 0x00001000 + InitStep8_Action = "Write 32bit" + InitStep8_Comment = "Write Block Size" + InitStep8_Value0 = 0x1FFFFFF8 + InitStep8_Value1 = 0x00010000 + InitStep9_Action = "Write 32bit" + InitStep9_Comment = "Write Block Count" + InitStep9_Value0 = 0x1FFFFFFC + InitStep9_Value1 = 0x00000010 + NumExitSteps = 0 + NumInitSteps = 10 + RAMAddr = 0x10000000 + RAMSize = 0x00010000 + ScriptFile = "" + UseAutoSpeed = 0x00000001 + UseRAM = 1 + UseScriptFile = 0 +[FLASH] + aSectorSel[0] = + AutoDetect = 1 + BankName = "" + BankSelMode = 1 + BaseAddr = 0x98000000 + CheckId = 3 + CustomRAMCode = "RTL8710AF.hex" + DeviceName = "Auto detected flash memory" + EndBank = 8191 + NumBanks = 1 + OrgNumBits = 16 + OrgNumChips = 1 + StartBank = 0 + UseCustomRAMCode = 1 +[PRODUCTION] + AutoPerformsErase = 1 + AutoPerformsHardLock = 0 + AutoPerformsHardUnlock = 0 + AutoPerformsProgram = 1 + AutoPerformsSecure = 0 + AutoPerformsSoftLock = 0 + AutoPerformsSoftUnlock = 1 + AutoPerformsStartApp = 0 + AutoPerformsUnsecure = 0 + AutoPerformsVerify = 1 + EnableProductionMode = 0 + EnableTargetPower = 0 + EraseType = 2 + ProductionDelay = 0x000001F4 + ProductionThreshold = 0x00000BB8 + ProgramSN = 0 + SerialFile = "" + SNAddr = 0x00000000 + SNInc = 0x00000001 + SNLen = 0x00000004 + SNListFile = "" + SNValue = 0x00000001 + TargetPowerDelay = 0x00000014 + VerifyType = 1 diff --git a/flasher/RTL8710AF.hex b/flasher/RTL8710AF.hex new file mode 100644 index 0000000..fd2dc4c --- /dev/null +++ b/flasher/RTL8710AF.hex @@ -0,0 +1,130 @@ +:100000007D0439057F05FF056506D506D706000086 +:10001000D44908707047D44800680005FBD0D14827 +:100020000078C0B2704710B5D048006850F44070F6 +:10003000CE490860CE48006850F01000CC490860F6 +:10004000CC480468062000F0B7F934F00600C9492E +:100050000860C848006850F00100C64908600020E8 +:10006000C54908600020C54908600120C4490860EE +:100070000220C44908600020C34908600020C34929 +:1000800008600020C249086010BD2DE9F04104005D +:100090000D001600B6B2002E01D1002048E0B6B225 +:1000A000112E01DB102006004FF4407000F084F99F +:1000B00080465FF4401000F07FF95FF4403000F0BC +:1000C0007BF95FF4402000F077F9032010FA08F084 +:1000D00010F44070AF490860B6B2AF480660032024 +:1000E000FFF796FF200CC0B2FFF792FF200AC0B2C4 +:1000F000FFF78EFF2000C0B2FFF78AFF01209E4964 +:100100000860002007003800310080B289B28842C0 +:1001100005D2FFF780FFBFB2E8557F1CF3E79F4889 +:100120000068C007FBD4002093490860300080B20B +:10013000BDE8F08138B54FF4407000F03DF905009E +:100140005FF4401000F038F95FF4403000F034F90B +:100150005FF4402000F030F90320A84010F4407014 +:100160008C49086003208C4908600120824908609E +:100170009F20FFF74DFFFFF74EFF0400FFF74BFFF7 +:1001800054EA00200400FFF746FF54EA0040040050 +:1001900082480068C007FBD400207749086020002F +:1001A00032BD38B54FF4407000F006F905005FF439 +:1001B000401000F001F95FF4403000F0FDF85FF40A +:1001C000402000F0F9F80320A84010F44070714975 +:1001D0000860012070490860012067490860052017 +:1001E000FFF716FFFFF717FF04006C480068C00711 +:1001F000FBD40020604908602000C0B232BD38B591 +:1002000004004FF4407000F0D7F805005FF4401090 +:1002100000F0D2F85FF4403000F0CEF85FF44020F8 +:1002200000F0CAF80120A84010F440705949086055 +:100230000120514908602000C0B2FFF7E9FE57488D +:100240000068C007FBD400204B49086031BD38B5B9 +:1002500004004FF4407000F0AFF805005FF4401068 +:1002600000F0AAF85FF4403000F0A6F85FF44020F8 +:1002700000F0A2F80120A84010F440704549086041 +:1002800001203D4908602020FFF7C2FE200CC0B2CB +:10029000FFF7BEFE200AC0B2FFF7BAFE2000C0B2D0 +:1002A000FFF7B6FE3D480068C007FBD40020324986 +:1002B000086031BD2DE9F04104000D001600B6B212 +:1002C000002E01D100204BE0B6B2B6F5807F02DDF2 +:1002D0004FF4807006004FF4407000F06DF88046D7 +:1002E0005FF4401000F068F85FF4403000F064F80C +:1002F0005FF4402000F060F8012010FA08F010F4DC +:1003000040702449086001201B4908600220FFF763 +:100310007FFE200CC0B2FFF77BFE200AC0B2FFF7C1 +:1003200077FE2000C0B2FFF773FE00200700380000 +:10033000310080B289B2884205D2BFB2E85DFFF7D2 +:1003400067FE7F1CF3E7154800684007FBD513489C +:100350000068C007FBD4002007490860300080B265 +:10036000BDE8F08160600040246000403002004041 +:1003700010020040C0020040086000402C600040B5 +:100380001060004014600040186000401C60004095 +:100390004C60004000600040046000402860004065 +:1003A00080B5FFF7FEFEC007FBD401BD80B5FFF7A7 +:1003B000F8FE8007FBD501BD90FAA0F0B0FA80F0FE +:1003C00070470000010051EA510151EA910151EAE0 +:1003D000111151EA112151EA1141064A7A441432AD +:1003E000DFF8B03203FB01F3DB0E52F823201000DC +:1003F000704700BF80030000DFF89C02006850F0E7 +:100400004070DFF894120860DFF89002006850F442 +:100410008070DFF888120860FF20DFF8841208601F +:10042000FF20DFF880120860704780B500F054F9B3 +:1004300001BD0120DFF870120860704780B571B609 +:1004400072B6FFF7F6FFFFF7D7FFFFF7EEFF01BD2C +:1004500080B5FFF7E8FDFFF7A3FFFFF76BFEFFF79F +:100460009FFF92480068FFF7ADFF914908609148EF +:100470000068FFF7A7FF9049086001BDF8B50400C8 +:100480000D0016008D4800688D49884204D18D48C2 +:1004900000688D49884209D08948884908608A489F +:1004A00088490860FFF7CAFFFFF7D2FF814800685C +:1004B00086490968864A12685143B1FBF0F27368B5 +:1004C00040271F807A4F3F689F700027DF70012709 +:1004D0001F7101275F7100279F710127DF710127BD +:1004E0001F7200275F7201279F7201271F6100277B +:1004F000DFF8DCC1DCF800C067451CD2DFF8CCC1F6 +:10050000DCF800C00CFB07FC5FF00C0E0EFB07FED6 +:100510009E44CEF814C05FF00C0C0CFB07FC9C440E +:10052000CCF818205FF00C0C0CFB07FC9C44CCF8BA +:100530001C007F1CDCE7F1BD2DE9F04704000D0035 +:1005400016007769D6F81080D6F80490002F14D0E2 +:10055000200000F0C0F8112F02D35FF0100A00E075 +:10056000BA46524692B249464046FFF78EFD1AEB14 +:100570000808D144B7EB0A07E8E7BDE8F0872DE9A2 +:10058000F84F04000D0016000020286077694848E5 +:100590000068B84638FA00F8D6F810904448006869 +:1005A00039FA00F9D6F804A0B8F1000F25D0B7F554 +:1005B000807F02D94FF4807B00E0BB46FFF7F0FE5E +:1005C0000620FFF71CFEFFF7F1FE5A4692B2514695 +:1005D0003648006800FB09F0FFF76CFEFFF7E0FE0D +:1005E0000420FFF70CFEFFF7DBFEDA44B7EB0B0746 +:1005F000B8F1010819F10109D6E7BDE8F18F2DE93D +:10060000F84304000D00160030692B490968C84002 +:10061000070070698046002028602648006800FBBB +:1006200007F08146B8F1000F1AD0200000F053F80F +:10063000FFF7B6FE0620FFF7E2FDFFF7B7FE4846DC +:10064000FFF705FEFFF7ACFE0420FFF7D8FDFFF72C +:10065000A7FE1848006810EB0909B8F10108E1E7A6 +:10066000BDE8F18310B504001448006814498842BD +:1006700004D1144800681449884209D010480F4931 +:10068000086011480F490860FFF7D8FEFFF7E0FE49 +:1006900010BD0000DDACC407300200401C02004069 +:1006A000200300402403004014000040F0FFFF1F1F +:1006B000E0FFFF1FF4FFFF1FE4FFFF1FE8FFFF1F26 +:1006C000AA55AA55ECFFFF1F55AA55AAF8FFFF1F10 +:1006D000FCFFFF1F7047704710B51E48006850F4BC +:1006E00040501C4908601C48006850F480501A496A +:1006F00008601A4800684006FBD5194804685FF492 +:100700004000FFF759FE34F44000154908601448D2 +:10071000006850F4801012490860002011490860F8 +:100720001148006850F080000F49086044200F49CC +:10073000086000200B49086003240320FFF73CFEFB +:1007400014FA00F010F0030007490860002008497F +:10075000086010BD3002004010020040143000401C +:10076000C0020040043000400C3000400030004027 +:1007700008300040000000000900000001000000F7 +:100780000A0000000D00000015000000020000003B +:100790001D0000000B0000000E0000001000000013 +:1007A0001200000016000000190000000300000005 +:1007B0001E000000080000000C00000014000000F3 +:1007C0001C0000000F0000001100000018000000D5 +:1007D00007000000130000001B00000017000000CD +:1007E000060000001A0000000500000004000000E0 +:0407F0001F000000E6 +:0400000500000000F7 +:00000001FF diff --git a/flasher/RTL8710AF.jflash b/flasher/RTL8710AF.jflash new file mode 100644 index 0000000..ff1f6c4 --- /dev/null +++ b/flasher/RTL8710AF.jflash @@ -0,0 +1,153 @@ + AppVersion = 61001 + FileVersion = 2 +[GENERAL] + ConnectMode = 0 + CurrentFile = "" + DataFileSAddr = 0x00000000 + GUIMode = 0 + HostName = "" + TargetIF = 1 + USBPort = 0 + USBSerialNo = 0x00000000 +[JTAG] + IRLen = 0 + MultipleTargets = 0 + NumDevices = 0 + Speed0 = 6000 + Speed1 = 6000 + TAP_Number = 0 + UseAdaptive0 = 0 + UseAdaptive1 = 0 + UseMaxSpeed0 = 0 + UseMaxSpeed1 = 0 +[CPU] + NumInitSteps = 18 + InitStep0_Action = "Reset" + InitStep0_Value0 = 0x00000000 + InitStep0_Value1 = 0x00000000 + InitStep0_Comment = "Reset and halt target" + InitStep1_Action = "Read 32bit" + InitStep1_Value0 = 0x40000230 + InitStep1_Value1 = 0x00000000 + InitStep1_Comment = "enable spi flash peripheral clock" + InitStep2_Action = "Var OR" + InitStep2_Value0 = 0x00000000 + InitStep2_Value1 = 0x00000300 + InitStep2_Comment = "" + InitStep3_Action = "Var Write 32bit" + InitStep3_Value0 = 0x40000230 + InitStep3_Value1 = 0x00000000 + InitStep3_Comment = "" + InitStep4_Action = "Read 32bit" + InitStep4_Value0 = 0x40000210 + InitStep4_Value1 = 0x00000000 + InitStep4_Comment = "enable spi flash peripheral" + InitStep5_Action = "Var OR" + InitStep5_Value0 = 0x00000000 + InitStep5_Value1 = 0x00000010 + InitStep5_Comment = "" + InitStep6_Action = "Var Write 32bit" + InitStep6_Value0 = 0x40000210 + InitStep6_Value1 = 0x00000000 + InitStep6_Comment = "" + InitStep7_Action = "Read 32bit" + InitStep7_Value0 = 0x400002C0 + InitStep7_Value1 = 0x00000000 + InitStep7_Comment = "select spi flash pinout (0 - internal), enable spi flash pins" + InitStep8_Action = "Var AND" + InitStep8_Value0 = 0x00000000 + InitStep8_Value1 = 0xFFFFFFF8 + InitStep8_Comment = "" + InitStep9_Action = "Var OR" + InitStep9_Value0 = 0x00000000 + InitStep9_Value1 = 0x00000001 + InitStep9_Comment = "" + InitStep10_Action = "Var Write 32bit" + InitStep10_Value0 = 0x400002C0 + InitStep10_Value1 = 0x00000000 + InitStep10_Comment = "" + InitStep11_Action = "Write 32bit" + InitStep11_Value0 = 0x40006008 + InitStep11_Value1 = 0x00000000 + InitStep11_Comment = "disable SPI FLASH operation" + InitStep12_Action = "Write 32bit" + InitStep12_Value0 = 0x4000602C + InitStep12_Value1 = 0x00000000 + InitStep12_Comment = "disable all interrupts" + InitStep13_Action = "Write 32bit" + InitStep13_Value0 = 0x40006010 + InitStep13_Value1 = 0x00000001 + InitStep13_Comment = "use first 'slave select' pin" + InitStep14_Action = "Write 32bit" + InitStep14_Value0 = 0x40006014 + InitStep14_Value1 = 0x00000002 + InitStep14_Comment = "baud rate, default value" + InitStep15_Action = "Write 32bit" + InitStep15_Value0 = 0x40006018 + InitStep15_Value1 = 0x00000000 + InitStep15_Comment = "tx fifo threshold" + InitStep16_Action = "Write 32bit" + InitStep16_Value0 = 0x4000601C + InitStep16_Value1 = 0x00000000 + InitStep16_Comment = "rx fifo threshold" + InitStep17_Action = "Write 32bit" + InitStep17_Value0 = 0x4000604C + InitStep17_Value1 = 0x00000000 + InitStep17_Comment = "disable DMA" + NumExitSteps = 1 + ExitStep0_Action = "Write 32bit" + ExitStep0_Value0 = 0x40000210 + ExitStep0_Value1 = 0x00211157 + ExitStep0_Comment = "Boot from Flash" + UseScriptFile = 0 + ScriptFile = "" + UseRAM = 1 + RAMAddr = 0x10000000 + RAMSize = 0x00060000 + CheckCoreID = 1 + CoreID = 0x2BA01477 + CoreIDMask = 0xFFFFFFFF + UseAutoSpeed = 0x00000001 + ClockSpeed = 0x00000000 + EndianMode = 0 + ChipName = "Cortex-M3" +[FLASH] + aRangeSel[1] = 0-18 + BankSelMode = 1 + BaseAddr = 0x98000000 + CheckId = 0 + CustomRAMCode = "D:\MCU\SEGGER\JLink_V610a\Samples\JFlash\ProjectFiles\Atmel\AT91SAM9261_DataFlash_SPI0\RAMCodeV2_AT91SAM9261_DataFlash_SPI0_LE.mot" + DeviceName = "Am29F800BB" + NumBanks = 1 + OrgNumBits = 16 + OrgNumChips = 1 +[PRODUCTION] + AutoBlankCheck = 1 + AutoDisconnect = 0 + AutoMode = 0 + AutoPerformsErase = 0 + AutoPerformsProgram = 0 + AutoPerformsSecure = 0 + AutoPerformsStartApp = 0 + AutoPerformsUnsecure = 0 + AutoPerformsVerify = 1 + EnableTargetPower = 0 + EraseType = 2 + MonitorVTref = 0 + MonitorVTrefMax = 0x0000157C + MonitorVTrefMin = 0x000003E8 + OverrideTimeouts = 0 + ProgramSN = 0 + SerialFile = "" + SkipBlankOnRead = 0 + SNAddr = 0x00000000 + SNInc = 0x00000001 + SNLen = 0x00000008 + SNListFile = "" + SNValue = 0x00000001 + StartAppType = 0 + TargetPowerDelay = 0x00000014 + TimeoutErase = 0x00003A98 + TimeoutProgram = 0x00002710 + TimeoutVerify = 0x00002710 + VerifyType = 1 diff --git a/flasher/RTL_FFlash.JLinkScript b/flasher/RTL_FFlash.JLinkScript new file mode 100644 index 0000000..a9ed900 --- /dev/null +++ b/flasher/RTL_FFlash.JLinkScript @@ -0,0 +1,17 @@ +h +r +w4 0x40000230,0x0000D3C4 +w4 0x40000210,0x00200113 +w4 0x400002C0,0x00110001 +w4 0x40006008,0 +w4 0x4000602C,0 +w4 0x40006010,1 +w4 0x40006014,2 +w4 0x40006018,0 +w4 0x4000601C,0 +w4 0x4000604C,0 +savebin fullflash.bin 0x98000000 0x100000 +w4 0x40000210,0x211157 +r +g +q \ No newline at end of file diff --git a/flasher/RTL_Reset.JLinkScript b/flasher/RTL_Reset.JLinkScript new file mode 100644 index 0000000..196d12a --- /dev/null +++ b/flasher/RTL_Reset.JLinkScript @@ -0,0 +1,9 @@ +r0 +trst0 +r1 +trst1 +h +r +w4 0x40000210,0x111157 +g +q \ No newline at end of file diff --git a/flasher/RTL_RunRAM.JLinkScript b/flasher/RTL_RunRAM.JLinkScript new file mode 100644 index 0000000..5991456 --- /dev/null +++ b/flasher/RTL_RunRAM.JLinkScript @@ -0,0 +1,12 @@ +r0 +trst0 +r1 +trst1 +h +r +loadbin build/bin/ram_1.r.bin 0x10000bc8 +loadbin build/bin/ram_2.bin 0x10006000 +r +w4 0x40000210,0x20111157 +g +q \ No newline at end of file diff --git a/flasher/ameba1.cfg b/flasher/ameba1.cfg new file mode 100644 index 0000000..f3ee2db --- /dev/null +++ b/flasher/ameba1.cfg @@ -0,0 +1,124 @@ +# Main file for Ameba1 series Cortex-M3 parts +# +# !!!!!! +# + +set CHIPNAME rtl8195a +set CHIPSERIES ameba1 + +# Adapt based on what transport is active. +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + error "CHIPNAME not set. Please do not include ameba1.cfg directly." +} + +if { [info exists CHIPSERIES] } { + # Validate chip series is supported + if { $CHIPSERIES != "ameba1" } { + error "Unsupported chip series specified." + } + set _CHIPSERIES $CHIPSERIES +} else { + error "CHIPSERIES not set. Please do not include ameba1.cfg directly." +} + +if { [info exists CPUTAPID] } { + # Allow user override + set _CPUTAPID $CPUTAPID +} else { + # Ameba1 use a Cortex M3 core. + if { $_CHIPSERIES == "ameba1" } { + if { [using_jtag] } { + set _CPUTAPID 0x4ba00477 + } { + set _CPUTAPID 0x2ba01477 + } + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME + + +# Run with *real slow* clock by default since the +# boot rom could have been playing with the PLL, so +# we have no idea what clock the target is running at. +adapter_khz 1000 + +# delays on reset lines +adapter_nsrst_delay 200 +if {[using_jtag]} { + jtag_ntrst_delay 200 +} + + +# Ameba1 (Cortex M3 core) support SYSRESETREQ +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event reset-init {ameba1_init} + +# Ameba1 SDRAM enable +proc ameba1_init { } { + # init System + mww 0x40000014 0x00000021 + sleep 10 + mww 0x40000304 0x1fc00002 + sleep 10 + mww 0x40000250 0x00000400 + sleep 10 + mww 0x40000340 0x00000000 + sleep 10 + mww 0x40000230 0x0000dcc4 + sleep 10 + mww 0x40000210 0x00011117 + sleep 10 + mww 0x40000210 0x00011157 + sleep 10 + mww 0x400002c0 0x00110011 + sleep 10 + mww 0x40000320 0xffffffff + sleep 10 + # init SDRAM + mww 0x40000040 0x00fcc702 + sleep 10 + mdw 0x40000040 + mww 0x40005224 0x00000001 + sleep 10 + mww 0x40005004 0x00000208 + sleep 10 + mww 0x40005008 0xffffd000 + sleep 13 + mww 0x40005020 0x00000022 + sleep 13 + mww 0x40005010 0x09006201 + sleep 13 + mww 0x40005014 0x00002611 + sleep 13 + mww 0x40005018 0x00068413 + sleep 13 + mww 0x4000501c 0x00000042 + sleep 13 + mww 0x4000500c 0x700 ;# set Idle + sleep 20 + mww 0x40005000 0x1 ;# start init + sleep 100 + mdw 0x40005000 + mww 0x4000500c 0x600 ;# enter memory mode + sleep 30 + + mww 0x40005008 0x00000000 ;# 0xf00 + ;# mww 0x40005008 0x00000f00 + sleep 3 + mww 0x40000300 0x0006005e ;# 0x5e + ;# mww 0x40000300 0x0000005e + sleep 3 +} diff --git a/flasher/cortex.ocd b/flasher/cortex.ocd new file mode 100644 index 0000000..b0cdf18 --- /dev/null +++ b/flasher/cortex.ocd @@ -0,0 +1,99 @@ +proc cortex_bootstrap {start} { + # disable interrupts + reg faultmask 0x01 + set vectors "" + mem2array vectors 32 $start 2 + reg sp $vectors(0) + reg pc $vectors(1) + resume +} + +proc cortex_reboot {} { + set ddd [ format "0x%08x" [ rtl8710_flasher_mrw [ expr 0x40000210 ] ] ] +# set aaa [ format "0x%08x" [ expr 0x40000210 ] ] + echo "CLK_CTRL1 = $ddd" +# echo "# Set processor clock to default before system reset" + set ddd [ format "0x%08x" [ rtl8710_flasher_mrw [ expr 0x40000014 ] ] ] +# set aaa [ format "0x%08x" [ expr 0x40000014 ] ] + echo "SOC_FUNC_EN = $ddd" +# mww 0x40000014 0x00000021 + sleep 10 + echo "# Reboot (system reset)" + mww 0xE000ED0C 0x05FA0007 +} + +proc init_system {} { +# Set processor clock to default before system reset +# CLK_CTRL1 +# mww 0x40000014 0x00000011 + mww 0x40000014 0x00000021 + sleep 10 +# PESOC_SOC_CTRL +# mww 0x40000304 0x1fc00001 + mww 0x40000304 0x1fc00002 + sleep 10 +# PESOC_CLK_SEL + mww 0x40000250 0x00000400 + sleep 10 +# GPIO_PULL_CTRL4 + mww 0x40000340 0x00000000 + sleep 10 +# PESOC_CLK_CTRL +# mww 0x40000230 0x0000d3c4 + mww 0x40000230 0x0000dcc4 + sleep 10 +# SOC_FUNC_EN: FUN|OCP|LXBUS|FLASH|CPU|LOG_UART|GTIMER|SECURITY_ENGINE +# mww 0x40000210 0x00211117 + mww 0x40000210 0x00011117 + sleep 10 +# SOC_FUNC_EN: FUN|OCP|LXBUS|FLASH|CPU|LOG_UART|GTIMER|SECURITY_ENGINE + MEM_CTRL + mww 0x40000210 0x00011157 + sleep 10 +# CPU_PERIPHERAL_CTRL SPI_FLASH_PIN_EN|SDR_PIN_EN|SWD_PIN_EN|LOG_UART_PIN_EN ? +# mww 0x400002c0 0x00110000 + mww 0x400002c0 0x00110011 + sleep 10 +# GPIO_SHTDN_CTRL +# mww 0x40000320 0x00000033 + mww 0x40000320 0xffffffff + sleep 10 + + mww 0x40005008 0x00000000 + sleep 10 +# PESOC_MEM_CTRL + mww 0x40000300 0x0006005e + sleep 10 + + # set baudrate to 38400 +# mww 0x40003010 0x00000080 +# mww 0x40003008 0x00000022 +# mww 0x4000300C 0x00000000 +# mww 0x40003010 0x00000000 +} + +proc boot_from_flash {} { + echo "# skip sdram init, it has been init in openocd config" + mww 0x40000210 0x211157 +} + +proc boot_from_ram {} { + echo "# boot from ram, igonore loading flash" + mww 0x40000210 0x8011157 +} + +proc restart_from_falsh {} { + init + init_system + boot_from_flash + cortex_reboot +} + +proc load_ram_binary { local_filename address } { +# set address 0x10000BC8 + init + reset halt + set size [file size $local_filename] + load_image $local_filename $address bin $address $size + boot_from_ram + resume +} diff --git a/flasher/file_info.jlink b/flasher/file_info.jlink new file mode 100644 index 0000000..2b24f94 --- /dev/null +++ b/flasher/file_info.jlink @@ -0,0 +1,7 @@ +define call1 +set $ImageSize = 0xF1E0 +set $ImageAddr = 0x0D0000 +end +define call2 +FlasherWrite build/bin/WEBFiles.bin $ImageAddr $ImageSize +end diff --git a/flasher/flash_file.jlink b/flasher/flash_file.jlink new file mode 100644 index 0000000..83b04c0 --- /dev/null +++ b/flasher/flash_file.jlink @@ -0,0 +1,9 @@ +define call1 +SetFirwareSize build/bin/ram_all.bin +end +define call2 +FlasherWrite build/bin/ram_all.bin 0 $Image1Size +end +define call3 +FlasherWrite build/bin/ram_all.bin $Image2Addr $Image2Size +end diff --git a/flasher/gdb_flasher.jlink b/flasher/gdb_flasher.jlink new file mode 100644 index 0000000..f3aa851 --- /dev/null +++ b/flasher/gdb_flasher.jlink @@ -0,0 +1,198 @@ +#################################### +# J-LINK GDB SERVER initialization # +#################################### +define InitJlink +printf "Jlink Init:\n" +set verbose off +set complaints 0 +set confirm off +set exec-done-display off +show exec-done-display +set trace-commands off +#set debug aix-thread off +#set debug dwarf2-die 0 +set debug displaced off +set debug expression 0 +set debug frame 0 +set debug infrun 0 +set debug observer 0 +set debug overload 0 +#set debugvarobj 0 +set pagination off +set print address off +set print symbol-filename off +set print symbol off +set print pretty off +set print object off +#set debug notification off +set debug parser off +set debug remote 0 +target remote localhost:2331 +set remotetimeout 10000 +monitor device Cortex-M3 +monitor endian little +monitor reset +# Set max speed +monitor speed 4000 +set mem inaccessible-by-default off +# Setup GDB FOR FASTER DOWNLOADS +set remote memory-write-packet-size 8192 +set remote memory-write-packet-size fixed +end +############# +# Boot_Flash +define SetBootFlash +printf "SetBoot = Flash:\n" +monitor long 0x40000210 = 0x211157 +end +# Boot RAM start_addr0() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) +define SetBootCall0 +printf "SetBoot = Call0:\n" +monitor long 0x40000210 = 0x80111157 +end +# Boot RAM start_addr1() Run if ( v40000210 & 0x20000000 ) +define SetBootCall1 +printf "SetBoot = Call1:\n" +monitor long 0x40000210 = 0x20111157 +end +# Boot RAM start_addr2() Run if ( v40000210 & 0x10000000 ) +define SetBootCall2 +printf "SetBoot = Call2:\n" +monitor long 0x40000210 = 0x10111157 +end +# Boot RAM start_addr3() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) +define SetBootCall3 +printf "SetBoot = Call3:\n" +monitor long 0x40000210 = 0x8111157 +end +# Boot RAM start_addr4() Init console, Run if ( v40000210 & 0x4000000 ) +define SetBootCall4 +printf "SetBoot = Call4:\n" +monitor long 0x40000210 = 0x4111157 +end +# CPU CLK 166 MHz? +define SetClk166MHz +printf "SetCLK 166.66MHz:\n" +monitor long 0x40000014 = 0x00000011 +end +# CPU CLK 83 MHz? +define SetClk83MHz +printf "SetCLK 83.33MHz:\n" +monitor long 0x40000014 = 0x00000021 +end +############### +# System Init # +############### +define SystemInit +printf "System Init:\n" +monitor long 0x40000304 = 0x1FC00002 +monitor long 0x40000250 = 0x400 +monitor long 0x40000340 = 0x0 +monitor long 0x40000230 = 0xdcc4 +monitor long 0x40000210 = 0x11117 +monitor long 0x40000210 = 0x11157 +monitor long 0x400002c0 = 0x110011 +monitor long 0x40000320 = 0xffffffff +end +############ +# SPI Init # +############ +define SPI_Init +printf "Init SPI:\n" +#enable spi flash peripheral clock +set $Temp = {int}(0x40000230) +set $Temp = ($Temp | 0x300) +set {int}(0x40000230) = $Temp +#enable spi flash peripheral +set $Temp = {int}(0x40000210) +set $Temp = ($Temp | 0x10) +set {int}(0x40000210) = $Temp +#select spi flash pinout (0 - internal), enable spi flash pins +set $Temp = {int}(0x400002C0) +set $Temp = (($Temp & 0xFFFFFFF8) | 1) +set {int}(0x400002C0) = $Temp +#disable SPI FLASH operation +monitor long 0x40006008 = 0 +#disable all interrupts +monitor long 0x4000602C = 0 +#use first "slave select" pin +monitor long 0x40006010 = 1 +#baud rate, default value +monitor long 0x40006014 = 2 +#tx fifo threshold +monitor long 0x40006018 = 0 +#rx fifo threshold +monitor long 0x4000601C = 0 +#disable DMA +monitor long 0x4000604C = 0 +set $SPI_FLASH_BASE = 0x98000000 +end +################### +# SetFirwareSize # +################### +define SetFirwareSize +set $rambuffer = 0x10000300 +printf "Get ImagesSize:\n" +restore $arg0 binary $rambuffer 0 0x20 +set $Image1Size = {int}($rambuffer+0x10) + 32 +set $Image1LoadAddr = {int}($rambuffer+0x14) +set $Image2Addr = {short}($rambuffer+0x18) * 1024 +if $Image1Size != 0 && $Image1Size < 0x1000000 + if $Image2Addr == 0 + set $Image2Addr = $Image1Size + end + printf "Image1Size = %d\n", $Image1Size + printf "Image1LoadAddr = 0x%08x\n", $Image1LoadAddr + printf "Image2FlashAddr = 0x%08x\n", $Image2Addr + set $parms1 = $rambuffer - $Image2Addr + set $parms3 = $Image2Addr + 0x08 + restore $arg0 binary $parms1 $Image2Addr $parms3 + set $Image2Size = {int}($rambuffer) + set $Image2LoadAddr = {int}($rambuffer+0x4) + if $Image2Size != 0xFFFFFFFF && $Image2Size != 0 + set $Image2Size = $Image2Size + 16 + printf "Image2Size = %d\n", $Image2Size + printf "Image2LoadAddr = 0x%08x\n", $Image2LoadAddr + set $FirmwareSize = $Image2Addr + $Image2Size + printf "FirmwareSize = %d\n", $FirmwareSize + else + set $Image2Size = 0 + printf "Image2 - None\n" + set $FirmwareSize = $Image1Size + printf "FirmwareSize = %d\n", $FirmwareSize + end +else + set $Image1Size = 0 + set $Image2Size = 0 + set $Image2Addr = 0 + set $FirmwareSize = 0 + printf "Image not format Firmware!\n" +end +end +##################### +# Flash Images Info # +##################### +define FlashImagesInfo +printf "Flash Info:\n" +set $Image1Size = {int}($SPI_FLASH_BASE + 0x10) + 32 +set $Image1LoadAddr = {int}($SPI_FLASH_BASE + 0x14) +if $Image1LoadAddr == 0xFFFFFFFF +printf "Image1 - None\n" +else +set $Image2FlashAddr = {short}($SPI_FLASH_BASE + 0x18) * 1024 +if $Image2FlashAddr == 0 +$Image2FlashAddr = $Image1Size +end +set $Image2Size = {int}($Image2FlashAddr + $SPI_FLASH_BASE) +set $Image2LoadAddr = {int}($Image2FlashAddr + $SPI_FLASH_BASE + 0x4) +printf "Image1Size = %d\n", $Image1Size +printf "Image1LoadAddr = 0x%08x\n", $Image1LoadAddr +printf "Image2FlashAddr = 0x%08x\n", $Image2FlashAddr +if $Image2Size != 0xFFFFFFFF +printf "Image2Size = %d\n", $Image2Size +printf "Image2LoadAddr = 0x%08x\n", $Image2LoadAddr +else +printf "Image2 - None\n" +end +end +end diff --git a/flasher/gdb_init.jlink b/flasher/gdb_init.jlink new file mode 100644 index 0000000..0ffc247 --- /dev/null +++ b/flasher/gdb_init.jlink @@ -0,0 +1,30 @@ +# +# J-LINK GDB SERVER initialization +# +target remote localhost:2331 +set remotetimeout 10000 +monitor device Cortex-M3 +monitor endian little +monitor reset +# Set max speed +monitor speed 4000 +set mem inaccessible-by-default off +# Setup GDB FOR FASTER DOWNLOADS +#set remote memory-write-packet-size 4096 +#set remote memory-write-packet-size fixed +# Boot Flash +monitor long 0x40000210 = 0x211157 +# Boot RAM start_addr0() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) +#monitor long 0x40000210 = 0x80011117 +# Boot RAM start_addr1() Run if ( v40000210 & 0x20000000 ) +#monitor long 0x40000210 = 0x20011117 +# Boot RAM start_addr2() Run if ( v40000210 & 0x10000000 ) +#monitor long 0x40000210 = 0x10011117 +# Boot RAM start_addr3() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) +#monitor long 0x40000210 = 0x8011117 +# Boot RAM start_addr4() Init console, Run if ( v40000210 & 0x4000000 ) +monitor long 0x40000210 = 0x4011117 +# CPU CLK 166 MHz? +# monitor long 0x40000014 = 0x00000011 +# CPU CLK 83 MHz? +#monitor long 0x40000014 = 0x00000021 diff --git a/flasher/gdb_ota.jlink b/flasher/gdb_ota.jlink new file mode 100644 index 0000000..9ed1306 --- /dev/null +++ b/flasher/gdb_ota.jlink @@ -0,0 +1,374 @@ +#################################### +# J-LINK GDB SERVER initialization # +#################################### +define InitJlink +printf "Jlink Init:\n" +set verbose off +set complaints 0 +set confirm off +set exec-done-display off +show exec-done-display +set trace-commands off +#set debug aix-thread off +#set debug dwarf2-die 0 +set debug displaced off +set debug expression 0 +set debug frame 0 +set debug infrun 0 +set debug observer 0 +set debug overload 0 +#set debugvarobj 0 +set pagination off +set print address off +set print symbol-filename off +set print symbol off +set print pretty off +set print object off +#set debug notification off +set debug parser off +set debug remote 0 +target remote localhost:2331 +set remotetimeout 10000 +monitor device Cortex-M3 +monitor endian little +monitor reset +# Set max speed +monitor speed 4000 +set mem inaccessible-by-default off +# Setup GDB FOR FASTER DOWNLOADS +set remote memory-write-packet-size 8192 +set remote memory-write-packet-size fixed +end +############# +# Boot_Flash +define SetBootFlash +printf "SetBoot = Flash:\n" +monitor long 0x40000210 = 0x211157 +end +# Boot RAM start_addr0() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) +define SetBootCall0 +printf "SetBoot = Call0:\n" +monitor long 0x40000210 = 0x80011117 +end +# Boot RAM start_addr1() Run if ( v40000210 & 0x20000000 ) +define SetBootCall1 +printf "SetBoot = Call1:\n" +monitor long 0x40000210 = 0x20011117 +end +# Boot RAM start_addr2() Run if ( v40000210 & 0x10000000 ) +define SetBootCall2 +printf "SetBoot = Call2:\n" +monitor long 0x40000210 = 0x10011117 +end +# Boot RAM start_addr3() Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) +define SetBootCall3 +printf "SetBoot = Call3:\n" +monitor long 0x40000210 = 0x8011117 +end +# Boot RAM start_addr4() Init console, Run if ( v40000210 & 0x4000000 ) +define SetBootCall4 +printf "SetBoot = Call4:\n" +monitor long 0x40000210 = 0x4011117 +end +# CPU CLK 166 MHz? +define SetClk166MHz +printf "SetCLK 166.66MHz:\n" +monitor long 0x40000014 = 0x00000011 +end +# CPU CLK 83 MHz? +define SetClk83MHz +printf "SetCLK 83.33MHz:\n" +monitor long 0x40000014 = 0x00000021 +end +############### +# System Init # +############### +define SystemInit +printf "System Init:\n" +monitor long 0x40000304 = 0x1FC00002 +monitor long 0x40000250 = 0x400 +monitor long 0x40000340 = 0x0 +monitor long 0x40000230 = 0xdcc4 +monitor long 0x40000210 = 0x11117 +monitor long 0x40000210 = 0x11157 +monitor long 0x400002c0 = 0x110011 +monitor long 0x40000320 = 0xffffffff +end +############ +# SPI Init # +############ +define SPI_Init +printf "Init SPI:\n" +#enable spi flash peripheral clock +set $Temp = {int}(0x40000230) +set $Temp = ($Temp | 0x300) +set {int}(0x40000230) = $Temp +#enable spi flash peripheral +set $Temp = {int}(0x40000210) +set $Temp = ($Temp | 0x10) +set {int}(0x40000210) = $Temp +#select spi flash pinout (0 - internal), enable spi flash pins +set $Temp = {int}(0x400002C0) +set $Temp = (($Temp & 0xFFFFFFF8) | 1) +set {int}(0x400002C0) = $Temp +#disable SPI FLASH operation +monitor long 0x40006008 = 0 +#disable all interrupts +monitor long 0x4000602C = 0 +#use first "slave select" pin +monitor long 0x40006010 = 1 +#baud rate, default value +monitor long 0x40006014 = 2 +#tx fifo threshold +monitor long 0x40006018 = 0 +#rx fifo threshold +monitor long 0x4000601C = 0 +#disable DMA +monitor long 0x4000604C = 0 +set $SPI_FLASH_BASE = 0x98000000 +end +################### +# GetOtaSize # +################### +define GetOtaSize +set $rambuffer = 0x10000300 +printf "Get ImagesSize:\n" +set $ImageOtaSize = 0 +restore $arg0 binary $rambuffer 0 4 +set $ImageAddSize = {int}($rambuffer+0) +if $ImageAddSize != 0 + printf "Image2Size = %d\n", $ImageAddSize + set $ImageOtaSize = $ImageOtaSize + $ImageAddSize + 16 + set $parms1 = $rambuffer - $ImageOtaSize + set $parms3 = $ImageOtaSize + 4 + restore $arg0 binary $parms1 $ImageOtaSize $parms3 + set $ImageAddSize = {int}($rambuffer+0) + if $ImageAddSize < 0x200000 + printf "ImageSdramSize = %d\n", $ImageAddSize + set $ImageOtaSize = $ImageOtaSize + $ImageAddSize + 20 + end +else + printf "Image2Size = %d !\n", $ImageOtaSize +end +end +##################### +# Flash Images Info # +##################### +define FlashImagesInfo +printf "Flash Info:\n" +set $Image1Size = {int}($SPI_FLASH_BASE + 0x10) + 32 +set $Image1LoadAddr = {int}($SPI_FLASH_BASE + 0x14) +if $Image1LoadAddr == 0xFFFFFFFF +printf "Image1 - None\n" +else +set $Image2FlashAddr = {short}($SPI_FLASH_BASE + 0x18) * 1024 +if $Image2FlashAddr == 0 +$Image2FlashAddr = $Image1Size +end +set $Image2Size = {int}($Image2FlashAddr + $SPI_FLASH_BASE) +set $Image2LoadAddr = {int}($Image2FlashAddr + $SPI_FLASH_BASE + 0x4) +printf "Image1Size = %d\n", $Image1Size +printf "Image1LoadAddr = 0x%08x\n", $Image1LoadAddr +printf "Image2FlashAddr = 0x%08x\n", $Image2FlashAddr +if $Image2Size != 0xFFFFFFFF +printf "Image2Size = %d\n", $Image2Size +printf "Image2LoadAddr = 0x%08x\n", $Image2LoadAddr +else +printf "Image2 - None\n" +end +end +set $ImageOtaAddr = {int}($SPI_FLASH_BASE + 0x9000) +if $ImageOtaAddr != 0x80000 +printf "ImageOtaAddr = 0x%08x - Invalid!\n", $ImageOtaAddr +else +printf "ImageOtaAddr = 0x%08x\n", $ImageOtaAddr +end +end +############### +# FlasherInit # +############### +define FlasherInit +set $rtl8710_flasher_capacity = 0 +set $rtl8710_flasher_auto_erase = 1 +set $rtl8710_flasher_auto_verify = 1 +set $rtl8710_flasher_firmware_ptr = 0x10001000 +set $rtl8710_flasher_buffer = 0x10008000 +set $rtl8710_flasher_buffer_size = 421888 +set $rtl8710_flasher_sector_size = 4096 +set $rtl8710_flasher_auto_erase_sector = 0xFFFFFFFF +end +############### +# FlasherWait # +############### +define FlasherWait +set $fresult = {int}($rtl8710_flasher_buffer) +while ($fresult != 0) +set $fresult = {int}($rtl8710_flasher_buffer) +end +end +############### +# FlasherLoad # +############### +define FlasherLoad +if $rtl8710_flasher_capacity == 0 + printf "initializing RTL8710 flasher\n" + restore $arg0 binary $rtl8710_flasher_firmware_ptr 0 968 + monitor reset + set $pc = $rtl8710_flasher_firmware_ptr + set $sp = 0x1ffffffc + set {int}($rtl8710_flasher_buffer + 0x08) = 0 + set {int}($rtl8710_flasher_buffer + 0x00) = 1 + #continue + monitor go + FlasherWait + set $id = {int}($rtl8710_flasher_buffer + 0x0C) + set $rtl8710_flasher_capacity = 1 << (($id >> 16) & 0x0ff) + if ($id == 0x1420c2) + printf "Flash ID = 0x%08x : MX25L8006E (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + else + printf "Flash ID = 0x%08x : (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + end + printf "RTL8710 flasher initialized\n" +else +printf "reinitializing RTL8710 flasher\n" +end +end +################## +# FlasherRdBlock # +################## +define FlasherRdBlock +#printf "FlashRdBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 3 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "read error, offset 0x%08x", $arg0 +end +end +################## +# FlasherWrBlock # +################## +define FlasherWrBlock +#printf "FlashWrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 4 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "write error, offset 0x%08x", $arg0 +end +end +################## +# FlasherVrBlock # +################## +define FlasherVrBlock +#printf "FlashVrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 5 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + set $status = {int}($rtl8710_flasher_buffer + 0x0C) + set $status = {int}($status + $arg0) + error "verify error, offset 0x%08x", $status +end +end +################# +# FlashSecErase # +################# +define FlashSecErase +#printf "FlashSecErase 0x%08x, 0x%08x\n", $rtl8710_flasher_buffer, $arg0 +set {int}($rtl8710_flasher_buffer + 0x04) = 2 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +end +################ +# FlasherWrite # +################ +define FlasherWrite +set $sector = 0 +set $offset = 0 +set $size = $arg2 +while $offset < $size + set $len = $size - $offset + if $len > $rtl8710_flasher_buffer_size + set $len = $rtl8710_flasher_buffer_size + end + set $flash_offset = $arg1 + $offset + printf "write offset 0x%08x\n", $flash_offset + set $parms1 = $rtl8710_flasher_buffer + 0x20 - $offset + set $parms2 = $offset + set $parms3 = $offset + $len + restore $arg0 binary $parms1 $parms2 $parms3 + if $rtl8710_flasher_auto_erase != 0 + set $count_i = $flash_offset + while $count_i < ($flash_offset + $len) + set $sector = $count_i/$rtl8710_flasher_sector_size + if $rtl8710_flasher_auto_erase_sector != $sector + set $parms1 = $sector * $rtl8710_flasher_sector_size + printf "erase sector %d at 0x%08x\n", $sector, $parms1 + FlashSecErase $parms1 + set $rtl8710_flasher_auto_erase_sector = $sector + end + set $count_i = $count_i + 1 + end + end + FlasherWrBlock $flash_offset $len + printf "write %d bytes at 0x%08x\n", $len, $flash_offset + if $rtl8710_flasher_auto_verify != 0 + printf "verify offset 0x%08x len %d\n", $flash_offset, $len + FlasherVrBlock $flash_offset $len + end + set $offset = $offset + $rtl8710_flasher_buffer_size +end +end +######################################### +InitJlink +SystemInit +SetClk166MHz +SPI_Init +GetOtaSize build/bin/ota.bin +if $ImageOtaSize != 0 + FlasherInit + FlasherLoad flasher/rtl8710_flasher.bin + set $FixOtaAddr = 0x80000 + set $pbuffer = $rtl8710_flasher_buffer + 0x20 + FlasherRdBlock 0x9000 0x1000 + set $ImageOtaAddr = {int}($pbuffer) + if $ImageOtaAddr != $FixOtaAddr + printf "ImageOtaAddr = 0x%08x - Invalid!\n", $ImageOtaAddr + set {int}($pbuffer) = $FixOtaAddr + set $Temp = $ImageOtaAddr & $FixOtaAddr + if $Temp != $FixOtaAddr + printf "FlashSecErase at 0x9000\n" + FlashSecErase 0x9000 + printf "Write offset 0x9000 4096 bytes\n" + FlasherWrBlock 0x9000 0x1000 + else + printf "Write offset 0x9000 4 bytes\n" + FlasherWrBlock 0x9000 0x0004 + end + end + FlasherWrite build/bin/ota.bin $FixOtaAddr $ImageOtaSize + restore build/bin/ota.bin binary $pbuffer 0 0x1000 + set {int}($pbuffer + 0x08) = 0x35393138 + set {int}($pbuffer + 0x0C) = 0x31313738 + FlasherWrBlock $FixOtaAddr 0x10 + FlashImagesInfo +end +monitor reset +SetBootFlash +monitor go +quit diff --git a/flasher/gdb_rdflash.jlink b/flasher/gdb_rdflash.jlink new file mode 100644 index 0000000..674ce48 --- /dev/null +++ b/flasher/gdb_rdflash.jlink @@ -0,0 +1,17 @@ +# GDB Jlink read fullflash +# Init +source -v flasher/gdb_flasher.jlink +InitJlink +SystemInit +SPI_Init +monitor speed 12000 +#FlashInfo +# Read FullFlash +printf "Read FullFlash:\n" +set $dumpstartaddr = $SPI_FLASH_BASE +set $dumpendaddr = $SPI_FLASH_BASE + 0x100000 +printf "Start addr of dumping = 0x%08x\n", $dumpstartaddr +printf "End addr of dumping = 0x%08x\n", $dumpendaddr +dump binary memory ../fullflash.bin $dumpstartaddr $dumpendaddr +printf "FullFlash saved in ./build/bin/fullflash.bin - OK.\n" +quit diff --git a/flasher/gdb_run_ram.jlink b/flasher/gdb_run_ram.jlink new file mode 100644 index 0000000..ad6a86d --- /dev/null +++ b/flasher/gdb_run_ram.jlink @@ -0,0 +1,11 @@ +# +# J-LINK GDB SERVER initialization +# +source -v flasher/gdb_flasher.jlink +InitJlink +load build/obj/build.axf +SetBootCall4 +monitor reset +monitor go +quit + diff --git a/flasher/gdb_wrfile.jlink b/flasher/gdb_wrfile.jlink new file mode 100644 index 0000000..b81e8c4 --- /dev/null +++ b/flasher/gdb_wrfile.jlink @@ -0,0 +1,156 @@ +############### +# FlasherInit # +############### +define FlasherInit +set $rtl8710_flasher_capacity = 0 +set $rtl8710_flasher_auto_erase = 1 +set $rtl8710_flasher_auto_verify = 1 +set $rtl8710_flasher_firmware_ptr = 0x10001000 +set $rtl8710_flasher_buffer = 0x10008000 +set $rtl8710_flasher_buffer_size = 421888 +set $rtl8710_flasher_sector_size = 4096 +set $rtl8710_flasher_auto_erase_sector = 0xFFFFFFFF +end +############### +# FlasherWait # +############### +define FlasherWait +set $fresult = {int}($rtl8710_flasher_buffer) +while ($fresult != 0) +set $fresult = {int}($rtl8710_flasher_buffer) +end +end +############### +# FlasherLoad # +############### +define FlasherLoad +if $rtl8710_flasher_capacity == 0 + printf "initializing RTL8710 flasher\n" + restore $arg0 binary $rtl8710_flasher_firmware_ptr 0 968 + monitor reset + set $pc = $rtl8710_flasher_firmware_ptr + set $sp = 0x1ffffffc + set {int}($rtl8710_flasher_buffer + 0x08) = 0 + set {int}($rtl8710_flasher_buffer + 0x00) = 1 + #continue + monitor go + FlasherWait + set $id = {int}($rtl8710_flasher_buffer + 0x0C) + set $rtl8710_flasher_capacity = 1 << (($id >> 16) & 0x0ff) + if ($id == 0x1420c2) + printf "Flash ID = 0x%08x : MX25L8006E (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + else + printf "Flash ID = 0x%08x : (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + end + printf "RTL8710 flasher initialized\n" +else +printf "reinitializing RTL8710 flasher\n" +end +end +################## +# FlasherWrBlock # +################## +define FlasherWrBlock +#printf "FlashWrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 4 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "write error, offset 0x%08x", $arg0 +end +end +################## +# FlasherVrBlock # +################## +define FlasherVrBlock +#printf "FlashVrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 5 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + set $status = {int}($rtl8710_flasher_buffer + 0x0C) + set $status = {int}($status + $arg0) + error "verify error, offset 0x%08x", $status +end +end +################# +# FlashSecErase # +################# +define FlashSecErase +#printf "FlashSecErase 0x%08x, 0x%08x\n", $rtl8710_flasher_buffer, $arg0 +set {int}($rtl8710_flasher_buffer + 0x04) = 2 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +end +################ +# FlasherWrite # +################ +define FlasherWrite +set $sector = 0 +set $offset = 0 +set $size = $arg2 +while $offset < $size + set $len = $size - $offset + if $len > $rtl8710_flasher_buffer_size + set $len = $rtl8710_flasher_buffer_size + end + set $flash_offset = $arg1 + $offset + printf "write offset 0x%08x\n", $flash_offset + set $parms1 = $rtl8710_flasher_buffer + 0x20 - $offset + set $parms2 = $offset + set $parms3 = $offset + $len + restore $arg0 binary $parms1 $parms2 $parms3 + if $rtl8710_flasher_auto_erase != 0 + set $count_i = $flash_offset + while $count_i < ($flash_offset + $len) + set $sector = $count_i/$rtl8710_flasher_sector_size + if $rtl8710_flasher_auto_erase_sector != $sector + set $parms1 = $sector * $rtl8710_flasher_sector_size + printf "erase sector %d at 0x%08x\n", $sector, $parms1 + FlashSecErase $parms1 + set $rtl8710_flasher_auto_erase_sector = $sector + end + set $count_i = $count_i + 1 + end + end + FlasherWrBlock $flash_offset $len + printf "wrote %d bytes at 0x%08x\n", $len, $flash_offset + if $rtl8710_flasher_auto_verify != 0 + printf "verify offset 0x%08x len %d\n", $flash_offset, $len + FlasherVrBlock $flash_offset $len + end + set $offset = $offset + $rtl8710_flasher_buffer_size +end +end +######################################### +source -v flasher/gdb_flasher.jlink +source -v flasher/file_info.jlink +InitJlink +SystemInit +SetClk83MHz +SPI_Init +FlasherInit +FlasherLoad flasher/rtl8710_flasher.bin +call1 +if $ImageSize != 0 +set $ImageEnd = $ImageSize + $ImageAddr + 0x4000 +if $rtl8710_flasher_capacity >= $ImageEnd + printf "Write Image size %d to Flash addr 0x%08x:\n", $ImageSize, $ImageAddr + call2 +else + printf "Error: Image size is too big!\n" +end +else + printf "Error: Image size is zero!\n" +end +quit diff --git a/flasher/gdb_wrflash.jlink b/flasher/gdb_wrflash.jlink new file mode 100644 index 0000000..6d37642 --- /dev/null +++ b/flasher/gdb_wrflash.jlink @@ -0,0 +1,164 @@ +############### +# FlasherInit # +############### +define FlasherInit +set $rtl8710_flasher_capacity = 0 +set $rtl8710_flasher_auto_erase = 1 +set $rtl8710_flasher_auto_verify = 1 +set $rtl8710_flasher_firmware_ptr = 0x10001000 +set $rtl8710_flasher_buffer = 0x10008000 +set $rtl8710_flasher_buffer_size = 421888 +set $rtl8710_flasher_sector_size = 4096 +set $rtl8710_flasher_auto_erase_sector = 0xFFFFFFFF +end +############### +# FlasherWait # +############### +define FlasherWait +set $fresult = {int}($rtl8710_flasher_buffer) +while ($fresult != 0) +set $fresult = {int}($rtl8710_flasher_buffer) +end +end +############### +# FlasherLoad # +############### +define FlasherLoad +if $rtl8710_flasher_capacity == 0 + printf "initializing RTL8710 flasher\n" + restore $arg0 binary $rtl8710_flasher_firmware_ptr 0 968 + monitor reset + set $pc = $rtl8710_flasher_firmware_ptr + set $sp = 0x1ffffffc + set {int}($rtl8710_flasher_buffer + 0x08) = 0 + set {int}($rtl8710_flasher_buffer + 0x00) = 1 + #continue + monitor go + FlasherWait + set $id = {int}($rtl8710_flasher_buffer + 0x0C) + set $rtl8710_flasher_capacity = 1 << (($id >> 16) & 0x0ff) + if ($id == 0x1420c2) + printf "Flash ID = 0x%08x : MX25L8006E (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + else + printf "Flash ID = 0x%08x : (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + end + printf "RTL8710 flasher initialized\n" +else +printf "reinitializing RTL8710 flasher\n" +end +end +################## +# FlasherWrBlock # +################## +define FlasherWrBlock +#printf "FlashWrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 4 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "write error, offset 0x%08x", $arg0 +end +end +################## +# FlasherVrBlock # +################## +define FlasherVrBlock +#printf "FlashVrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 5 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + set $status = {int}($rtl8710_flasher_buffer + 0x0C) + set $status = {int}($status + $arg0) + error "verify error, offset 0x%08x", $status +end +end +################# +# FlashSecErase # +################# +define FlashSecErase +#printf "FlashSecErase 0x%08x, 0x%08x\n", $rtl8710_flasher_buffer, $arg0 +set {int}($rtl8710_flasher_buffer + 0x04) = 2 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +end +################ +# FlasherWrite # +################ +define FlasherWrite +set $sector = 0 +set $offset = 0 +set $size = $arg2 +while $offset < $size + set $len = $size - $offset + if $len > $rtl8710_flasher_buffer_size + set $len = $rtl8710_flasher_buffer_size + end + set $flash_offset = $arg1 + $offset + printf "write offset 0x%08x\n", $flash_offset + set $parms1 = $rtl8710_flasher_buffer + 0x20 - $flash_offset + set $parms2 = $flash_offset + set $parms3 = $flash_offset + $len + restore $arg0 binary $parms1 $parms2 $parms3 + if $rtl8710_flasher_auto_erase != 0 + set $count_i = $flash_offset + while $count_i < ($flash_offset + $len) + set $sector = $count_i/$rtl8710_flasher_sector_size + if $rtl8710_flasher_auto_erase_sector != $sector + set $parms1 = $sector * $rtl8710_flasher_sector_size + printf "erase sector %d at 0x%08x\n", $sector, $parms1 + FlashSecErase $parms1 + set $rtl8710_flasher_auto_erase_sector = $sector + end + set $count_i = $count_i + 1 + end + end + FlasherWrBlock $flash_offset $len + printf "wrote %d bytes at 0x%08x\n", $len, $flash_offset + if $rtl8710_flasher_auto_verify != 0 + printf "verify offset 0x%08x len %d\n", $flash_offset, $len + FlasherVrBlock $flash_offset $len + end + set $offset = $offset + $rtl8710_flasher_buffer_size +end +end +######################################### +source -v flasher/gdb_flasher.jlink +source -v flasher/flash_file.jlink +InitJlink +SystemInit +SetClk166MHz +SPI_Init +FlashImagesInfo +#SetFirwareSize $wr_flile +call1 +if $FirmwareSize == 0 + error "FirmwareSize = 0!" +end +FlasherInit +FlasherLoad flasher/rtl8710_flasher.bin +if $Image1Size != 0 + printf "Write Image1 size %d to Flash addr 0x00000000:\n", $Image1Size + #FlasherWrite $wr_flile 0 $Image1Size + call2 + if $Image2Size != 0 && $Image2Addr >= $Image1Size + printf "Write Image2 size %d to Flash addr 0x%08x:\n", $Image2Size, $Image2Addr + #FlasherWrite $wr_flile $Image2Addr $Image2Size + call3 + end +end +FlashImagesInfo +monitor reset +SetBootFlash +monitor go +quit diff --git a/flasher/rtl8710.ocd b/flasher/rtl8710.ocd new file mode 100644 index 0000000..2f2b102 --- /dev/null +++ b/flasher/rtl8710.ocd @@ -0,0 +1,340 @@ +# +# OpenOCD script for RTL8710 +# Copyright (C) 2016 Rebane, rebane@alkohol.ee +# +set CHIPNAME rtl8195a +set CHIPSERIES ameba1 + +# Adapt based on what transport is active. + +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME rtl8710 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x800 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x2ba01477 +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-phys 0x10001000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +# adapter_khz 500 +adapter_nsrst_delay 100 + +if {![using_hla]} { + cortex_m reset_config sysresetreq vectreset +} + +set rtl8710_flasher_firmware_ptr 0x10001000 +set rtl8710_flasher_buffer 0x10008000 +set rtl8710_flasher_buffer_size 262144 +set rtl8710_flasher_sector_size 4096 + +array set rtl8710_flasher_code { + 0 0xB671B57F 1 0x25FF4B58 2 0x6B196B1A 3 0x7040F042 4 0x69D96318 5 0xF4414E55 + 6 0x69D97480 7 0xF8D361DC 8 0xF8C32120 9 0xF8D35120 10 0xF8C31124 11 0x47B05124 + 12 0x47B04E4F 13 0x47984B4F 14 0x60104A4F 15 0x484F47B0 16 0x60012100 17 0x2C006804 + 18 0x4D4DD0FC 19 0xB93E682E 20 0x60264C49 21 0x47B04E46 22 0x47984B46 23 0xE7ED6020 + 24 0x2B01682B 25 0x4E42D109 26 0x4C4647B0 27 0x47A02006 28 0x47904A45 29 0x47A020C7 + 30 0x682AE00D 31 0xD10E2A02 32 0x47B04E3B 33 0x20064C3F 34 0x483F47A0 35 0x493F4780 + 36 0x68084D3F 37 0x47B047A8 38 0x47A02004 39 0x6828E7CE 40 0xD1132803 41 0x47A04C32 + 42 0x24004838 43 0x4E396805 44 0x68311960 45 0xD206428C 46 0x4B384A37 47 0x221018A1 + 48 0x34104798 49 0x4D2AE7F3 50 0xE7B847A8 51 0x29046829 52 0x2400D11B 53 0x6806482F + 54 0xD2B042B4 55 0x47A84D24 56 0x20064E28 57 0x4B2847B0 58 0x49284798 59 0x680A4B2A + 60 0x18A018E1 61 0xF44F4B2A 62 0x47987280 63 0x200447A8 64 0xF50447B0 65 0x47A87480 + 66 0x682CE7E4 67 0xD1232C05 68 0x47984B17 69 0x4D1F2400 70 0x4294682A 71 0x481BD28F + 72 0x68012210 73 0x18604E1D 74 0x47B04669 75 0x1B19682B 76 0xBF282910 77 0x23002110 + 78 0xD011428B 79 0xF81D4A16 80 0x18A05003 81 0x42B55CC6 82 0x3301D101 83 0x4A15E7F4 + 84 0x60112101 85 0xE7726054 86 0x25014E12 87 0xE76E6035 88 0x47A84D03 89 0xE7D63410 + 90 0x40000200 91 0x100011BD 92 0x100013DD 93 0x10001289 94 0x1000800C 95 0x10008000 + 96 0x10008004 97 0x1000130D 98 0x100013ED 99 0x10008010 100 0x10001335 101 0x10008014 + 102 0x10008020 103 0x10001221 104 0x10001375 105 0x10008008 106 0x6A5A4B03 107 0xD0FB0512 + 108 0x0060F893 109 0xBF004770 110 0x40006000 111 0x6B194B17 112 0xF4416B1A 113 0x63187040 + 114 0x69186919 115 0x0110F041 116 0xF8D36119 117 0x220000C0 118 0x0106F020 119 0x00C0F8D3 + 120 0x10C0F8C3 121 0x00C0F8D3 122 0x0101F040 123 0x00C0F8D3 124 0x10C0F8C3 125 0x43BCF503 + 126 0x609A6899 127 0x20016AD9 128 0x691962DA 129 0x69596118 130 0x61592102 131 0x619A6999 + 132 0x61DA69D9 133 0x64DA6CD9 134 0xBF004770 135 0x40000200 136 0x460EB570 137 0xB34A4614 + 138 0xF3C04B15 139 0x681A4507 140 0x7240F44F 141 0x685A601A 142 0xF3C02103 143 0x2C102207 + 144 0x2410BF28 145 0x605CB2C0 146 0x1060F883 147 0x5060F883 148 0xF8832101 149 0xF8832060 + 150 0x689A0060 151 0x60992500 152 0x47984B08 153 0x35015570 154 0x42A2B2AA 155 0x4804D3F8 + 156 0xF0116A81 157 0xD1FA0301 158 0x60836881 159 0xBD704620 160 0x40006000 161 0x100011A9 + 162 0x4C10B5F8 163 0x68232003 164 0x7340F44F 165 0x68636023 166 0x60602101 167 0x68A3229F + 168 0x60A14D0B 169 0x2060F884 170 0x460647A8 171 0x460747A8 172 0x040347A8 173 0x2707EA43 + 174 0x0006EA47 175 0x4B036AA1 176 0x0201F011 177 0x6899D1FA 178 0xBDF8609A 179 0x40006000 + 180 0x100011A9 181 0x4C0BB510 182 0x68232001 183 0x7340F44F 184 0x68636023 185 0x60602105 + 186 0x60A068A2 187 0xF8844A06 188 0x47901060 189 0x4B036AA1 190 0x0201F011 191 0x6899D1FA + 192 0xBD10609A 193 0x40006000 194 0x100011A9 195 0x21014B08 196 0xF44F681A 197 0x601A7280 + 198 0x6099689A 199 0x0060F883 200 0x48036A9A 201 0x0101F012 202 0x6883D1FA 203 0x47706081 + 204 0x40006000 205 0x21014B0E 206 0xF44F681A 207 0x601A7280 208 0x2220689A 209 0xF8836099 + 210 0xF3C02060 211 0xF3C04107 212 0xB2C02207 213 0x1060F883 214 0x2060F883 215 0x0060F883 + 216 0x4A036A99 217 0x0001F011 218 0x6893D1FA 219 0x47706090 220 0x40006000 221 0xB36AB530 + 222 0x25014B17 223 0xF44F681C 224 0x601C7480 225 0x2402689C 226 0xF883609D 227 0xF3C04060 + 228 0xF3C04507 229 0xB2C02407 230 0x5060F883 231 0x7F80F5B2 232 0xF44FBF28 233 0xF8837280 + 234 0xF8834060 235 0x20000060 236 0x4C095C0D 237 0xF8843001 238 0xB2855060 239 0xD3F74295 + 240 0x07496A99 241 0x6AA0D5FC 242 0xF0104B03 243 0xD1FA0101 244 0x60996898 245 0xBD304610 + 246 0x40006000 247 0x4B02B508 248 0x07C04798 249 0xBD08D4FB 250 0x100012D5 251 0x4B04B508 + 252 0xF0004798 253 0xB2C10002 254 0xD0F82900 255 0xBF00BD08 256 0x100012D5 +} + +set rtl8710_flasher_command_read_id 0 +set rtl8710_flasher_command_mass_erase 1 +set rtl8710_flasher_command_sector_erase 2 +set rtl8710_flasher_command_read 3 +set rtl8710_flasher_command_write 4 +set rtl8710_flasher_command_verify 5 + +set rtl8710_flasher_ready 0 +set rtl8710_flasher_capacity 0 +set rtl8710_flasher_auto_erase 0 +set rtl8710_flasher_auto_verify 0 +set rtl8710_flasher_auto_erase_sector 0xFFFFFFFF + +proc rtl8710_flasher_init {} { + global rtl8710_flasher_firmware_ptr + global rtl8710_flasher_buffer + global rtl8710_flasher_capacity + global rtl8710_flasher_ready + global rtl8710_flasher_code + + if {[expr {$rtl8710_flasher_ready == 0}]} { + echo "initializing RTL8710 flasher" + halt + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + array2mem rtl8710_flasher_code 32 $rtl8710_flasher_firmware_ptr [array size rtl8710_flasher_code] + reg faultmask 0x01 + reg sp 0x20000000 + reg pc $rtl8710_flasher_firmware_ptr + resume + rtl8710_flasher_wait + set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set rtl8710_flasher_capacity [expr {2 ** [expr {($id >> 16) & 0xFF}]}] + set rtl8710_flasher_ready 1 + echo "RTL8710 flasher initialized" + } + return "" +} + +proc rtl8710_flasher_mrw {reg} { + set value "" + mem2array value 32 $reg 1 + return $value(0) +} + +proc rtl8710_flasher_wait {} { + global rtl8710_flasher_buffer + while {[rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x00}]]} { } +} + +proc rtl8710_flasher_load_block {local_filename offset len} { + global rtl8710_flasher_buffer + load_image $local_filename [expr {$rtl8710_flasher_buffer + 0x20 - $offset}] bin [expr {$rtl8710_flasher_buffer + 0x20}] $len +} + +proc rtl8710_flasher_read_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_read + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + error "read error, offset $offset" + } +} + +proc rtl8710_flasher_write_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_write + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_write + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + error "write error, offset $offset" + } +} + +proc rtl8710_flasher_verify_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_verify + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_verify + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set status [expr {$status + $offset}] + error "verify error, offset $status" + } +} + +proc rtl8710_flash_read_id {} { + global rtl8710_flasher_buffer + global rtl8710_flasher_capacity + global rtl8710_flasher_command_read_id + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read_id + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set manufacturer_id [format "0x%02X" [expr {$id & 0xFF}]] + set memory_type [format "0x%02X" [expr {($id >> 8) & 0xFF}]] + set memory_capacity [expr {2 ** [expr {($id >> 16) & 0xFF}]}] + echo "manufacturer ID: $manufacturer_id, memory type: $memory_type, memory capacity: $memory_capacity bytes" +} + +proc rtl8710_flash_mass_erase {} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_mass_erase + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_mass_erase + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait +} + +proc rtl8710_flash_sector_erase {offset} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_sector_erase + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_sector_erase + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait +} + +proc rtl8710_flash_read {local_filename loc size} { + global rtl8710_flasher_buffer + global rtl8710_flasher_buffer_size + rtl8710_flasher_init + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "read offset $flash_offset" + rtl8710_flasher_read_block $flash_offset $len + dump_image _rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len + exec dd conv=notrunc if=_rtl8710_flasher.bin "of=$local_filename" bs=1 "seek=$offset" + echo "read $len bytes" + } +} + +proc rtl8710_flash_write {local_filename loc} { + global rtl8710_flasher_buffer_size + global rtl8710_flasher_sector_size + global rtl8710_flasher_auto_erase + global rtl8710_flasher_auto_verify + global rtl8710_flasher_auto_erase_sector + rtl8710_flasher_init + set sector 0 + set size [file size $local_filename] + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "write offset $flash_offset" + rtl8710_flasher_load_block $local_filename $offset $len + if {[expr {$rtl8710_flasher_auto_erase != 0}]} { + for {set i $flash_offset} {$i < [expr {$flash_offset + $len}]} {incr i} { + set sector [expr {$i / $rtl8710_flasher_sector_size}] + if {[expr {$rtl8710_flasher_auto_erase_sector != $sector}]} { + echo "erase sector $sector" + rtl8710_flash_sector_erase [expr {$sector * $rtl8710_flasher_sector_size}] + set rtl8710_flasher_auto_erase_sector $sector + } + } + } + rtl8710_flasher_write_block $flash_offset $len + echo "wrote $len bytes" + if {[expr {$rtl8710_flasher_auto_verify != 0}]} { + echo "verify offset $flash_offset" + rtl8710_flasher_verify_block $flash_offset $len + } + } +} + +proc rtl8710_flash_verify {local_filename loc} { + global rtl8710_flasher_buffer_size + rtl8710_flasher_init + set size [file size $local_filename] + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "read offset $flash_offset" + rtl8710_flasher_load_block $local_filename $offset $len + echo "verify offset $flash_offset" + rtl8710_flasher_verify_block $flash_offset $len + } +} + +proc rtl8710_flash_auto_erase {on} { + global rtl8710_flasher_auto_erase + if {[expr {$on != 0}]} { + set rtl8710_flasher_auto_erase 1 + echo "auto erase on" + } else { + set rtl8710_flasher_auto_erase 0 + echo "auto erase off" + } +} + +proc rtl8710_flash_auto_verify {on} { + global rtl8710_flasher_auto_verify + if {[expr {$on != 0}]} { + set rtl8710_flasher_auto_verify 1 + echo "auto verify on" + } else { + set rtl8710_flasher_auto_verify 0 + echo "auto verify off" + } +} + +proc rtl8710_reboot {} { + echo "# Set processor clock to default before system reset" + mww 0x40000014 0x00000021 + sleep 10 + echo "# Reboot (system reset)" + mww 0xE000ED0C 0x05FA0007 +} + diff --git a/flasher/rtl8710_flasher.bin b/flasher/rtl8710_flasher.bin new file mode 100644 index 0000000..6c7e36d Binary files /dev/null and b/flasher/rtl8710_flasher.bin differ diff --git a/paths.bat b/paths.bat new file mode 100644 index 0000000..374f93e --- /dev/null +++ b/paths.bat @@ -0,0 +1 @@ +PATH=D:\MCU\GNU_Tools_ARM_Embedded\5.4_2016q2\bin;D:\MCU\SEGGER\JLink_V612i;%PATH% \ No newline at end of file diff --git a/paths.mk b/paths.mk new file mode 100644 index 0000000..a7154c4 --- /dev/null +++ b/paths.mk @@ -0,0 +1,44 @@ +#--------------------------- +# User defined +#--------------------------- +SDK_PATH = ../RTL00MP3/RTL00_SDKV35a/ +#GCC_PATH = d:/MCU/GNU_Tools_ARM_Embedded/5.2_2015q4/bin/# + or set in PATH +#OPENOCD_PATH = d:/MCU/OpenOCD/bin/# + or set in PATH +TOOLS_PATH ?= $(SDK_PATH)component/soc/realtek/8195a/misc/iar_utility/common/tools/ +FLASHER_TYPE ?= Jlink +#FLASHER_TYPE ?= OCD +FLASHER_PATH ?= flasher/ +JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/ +JLINK_GDBSRV ?= JLinkGDBServer.exe +#--------------------------- +# Default +#--------------------------- +# Compilation tools +CROSS_COMPILE = $(GCC_PATH)arm-none-eabi- +AR = $(CROSS_COMPILE)ar +CC = $(CROSS_COMPILE)gcc +AS = $(CROSS_COMPILE)as +NM = $(CROSS_COMPILE)nm +LD = $(CROSS_COMPILE)gcc +GDB = $(CROSS_COMPILE)gdb +SIZE = $(CROSS_COMPILE)size +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +# TARGET dirs +TARGET ?= build +OBJ_DIR ?= $(TARGET)/obj +BIN_DIR ?= $(TARGET)/bin +ELFFILE ?= $(OBJ_DIR)/$(TARGET).axf + +# Make bunary tools +ifneq ($(shell uname), Linux) +EXE = .exe +endif +PICK = $(TOOLS_PATH)pick$(EXE) +PADDING = $(TOOLS_PATH)padding$(EXE) +CHCKSUM = $(TOOLS_PATH)checksum$(EXE) + +# openocd tools +OPENOCD = $(OPENOCD_PATH)openocd + diff --git a/project/inc/.gitignore b/project/inc/.gitignore new file mode 100644 index 0000000..ee42cd5 --- /dev/null +++ b/project/inc/.gitignore @@ -0,0 +1 @@ +build_info.h \ No newline at end of file diff --git a/project/inc/FreeRTOSConfig.h b/project/inc/FreeRTOSConfig.h new file mode 100644 index 0000000..3e414a1 --- /dev/null +++ b/project/inc/FreeRTOSConfig.h @@ -0,0 +1,210 @@ +/* + FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS 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 and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest versions, license + and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +#include +extern uint32_t SystemCoreClock; +#endif + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( uint32_t ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 90 * 1024 ) ) // use HEAP5 +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 1 +#define configUSE_MUTEXES 1 +#define configUSE_TIMERS 1 + +#define configMAX_PRIORITIES ( 11 ) +#define PRIORITIE_OFFSET ( 4 ) + +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 1 + +#if configGENERATE_RUN_TIME_STATS +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //( ulHighFrequencyTimerTicks = 0UL ) +#define portGET_RUN_TIME_COUNTER_VALUE() xTickCount //ulHighFrequencyTimerTicks +#undef configUSE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 1 +#define portCONFIGURE_STATS_PEROID_VALUE 1000 //unit Ticks +#endif + +#define configTIMER_TASK_PRIORITY ( 1 ) + +#ifdef CONFIG_UVC +#define configTIMER_QUEUE_LENGTH ( 20 ) +#else +#define configTIMER_QUEUE_LENGTH ( 10 ) +#endif + +#define configTIMER_TASK_STACK_DEPTH ( 512 ) //USE_MIN_STACK_SIZE modify from 512 to 256 + +#if (__IASMARM__ != 1) + +extern void freertos_pre_sleep_processing(unsigned int *expected_idle_time); +extern void freertos_post_sleep_processing(unsigned int *expected_idle_time); +extern int freertos_ready_to_sleep(); + +/* Enable tickless power saving. */ +#define configUSE_TICKLESS_IDLE 1 + +/* In wlan usage, this value is suggested to use value less than 80 milliseconds */ +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 + +/* It's magic trick that let us can use our own sleep function */ +#define configPRE_SLEEP_PROCESSING( x ) ( freertos_pre_sleep_processing(&x) ) + +#define configPOST_SLEEP_PROCESSING( x ) ( freertos_post_sleep_processing(&x) ) + +/* It's magic trick that let us can enable/disable tickless dynamically */ +#define traceLOW_POWER_IDLE_BEGIN(); do { \ + if (!freertos_ready_to_sleep()) { \ + mtCOVERAGE_TEST_MARKER(); \ + break; \ + } + + // portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + +#define traceLOW_POWER_IDLE_END(); } while (0); + +/* It's FreeRTOS related feature but it's not included in FreeRTOS design. */ +#define configUSE_WAKELOCK_PMU 1 + +#endif // #if (__IASMARM__ != 1) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_pcTaskGetTaskName 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 /* 15 priority levels */ +#endif + + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +//#define RTK_MODE_TIMER + + +#define INCLUDE_uxTaskGetStackHighWaterMark 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/project/inc/feep_config.h b/project/inc/feep_config.h new file mode 100644 index 0000000..3956a79 --- /dev/null +++ b/project/inc/feep_config.h @@ -0,0 +1,30 @@ +/* + * feep_config.h + * + * Created on: 06 нояб. 2016 г. + * Author: PVV + */ + +#ifndef _INC_FEEP_CONFIG_H_ +#define _INC_FEEP_CONFIG_H_ + +#define FEEP_ID_WIFI_CFG 0x5730 // id:'0W', type: struct wlan_fast_reconnect +#define FEEP_ID_WIFI_AP_CFG 0x5731 // id:'1W', type: struct rtw_wifi_config_t +#define FEEP_ID_UART_CFG 0x5530 // id:'0U', type: UART_LOG_CONF +#define FEEP_ID_LWIP_CFG 0x4C30 // id:'0L', type: struct atcmd_lwip_conf +#define FEEP_ID_DHCP_CFG 0x4430 // id:'0D', type: struct _sdhcp_cfg + +typedef struct _sdhcp_cfg { + u8 mode; // =0 dhcp off, =1 - dhcp on, =2 Static ip, =3 - auto + u32 ip; + u32 mask; + u32 gw; +}dhcp_cfg; + +/* +#define FEEP_WRITE_WIFI_CFG(x) flash_write_cfg(x, FEEP_ID_WIFI_CFG, sizeof(struct wlan_fast_reconnect)) +#define FEEP_READ_WIFI_CFG(x) flash_read_cfg(x, FEEP_ID_WIFI_CFG, sizeof(struct wlan_fast_reconnect)) +*/ + + +#endif /* _INC_FEEP_CONFIG_H_ */ diff --git a/project/inc/lwipopts.h b/project/inc/lwipopts.h new file mode 100644 index 0000000..54c7783 --- /dev/null +++ b/project/inc/lwipopts.h @@ -0,0 +1,381 @@ +/** + ****************************************************************************** + * @file lwipopts.h + * @author MCD Application Team + * @version V1.1.0 + * @date 07-October-2011 + * @brief lwIP Options Configuration. + * This file is based on Utilities\lwip_v1.3.2\src\include\lwip\opt.h + * and contains the lwIP configuration for the STM32F2x7 demonstration. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#include +#include "platform_opts.h" + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1 + +#define WIFI_LOGO_CERTIFICATION_CONFIG 1 //for ping 10k test buffer setting +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#define MEM_LIBC_MALLOC 1 +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#define MEMP_MEM_MALLOC 1 + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/* Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#define LWIP_COMPAT_MUTEX 1 + +#define ETHARP_TRUST_IP_MAC 0 +#define IP_REASSEMBLY 1 +#define IP_FRAG 1 +#define ARP_QUEUEING 0 + +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETIF_HOSTNAME_SIZE 16 +/** + * netif0: DEF_HOSTNAME "0", netif1: DEF_HOSTNAME "1", .. + */ +#define DEF_HOSTNAME "rtl871x" + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#define NO_SYS 0 + +/* ---------- Memory options ---------- */ +/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which + lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 + byte alignment -> define MEM_ALIGNMENT to 2. */ +#define MEM_ALIGNMENT 4 + +/* MEM_SIZE: the size of the heap memory. If the application will send +a lot of data that needs to be copied, this should be set high. */ +#if WIFI_LOGO_CERTIFICATION_CONFIG + #define MEM_SIZE (10*1024) //for ping 10k test +#else + #define MEM_SIZE (5*1024) +#endif + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 100 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 6 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 10 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 5 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 20 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 10 + + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#if WIFI_LOGO_CERTIFICATION_CONFIG + #define PBUF_POOL_SIZE 30 //for ping 10k test +#else + #define PBUF_POOL_SIZE 20 +#endif + +/* IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.*/ +#if WIFI_LOGO_CERTIFICATION_CONFIG + #define IP_REASS_MAX_PBUFS 30 //for ping 10k test +#else + #define IP_REASS_MAX_PBUFS 10 +#endif + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +#define PBUF_POOL_BUFSIZE 500 + + +/* ---------- TCP options ---------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 1 + +/* TCP Maximum segment size. */ +#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF (5*TCP_MSS) + +/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */ + +#define TCP_SND_QUEUELEN (4* TCP_SND_BUF/TCP_MSS) + +/* TCP receive window. */ +#define TCP_WND (4*TCP_MSS) // (2*TCP_MSS) + + +/* ---------- ICMP options ---------- */ +#define LWIP_ICMP 1 + +/* ---------- ARP options ----------- */ +#define LWIP_ARP 1 + +/* ---------- DHCP options ---------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. DHCP is not implemented in lwIP 0.5.1, however, so + turning this on does currently not work. */ +#define LWIP_DHCP 1 + +/* ---------- UDP options ---------- */ +#define LWIP_UDP 1 +#define UDP_TTL 255 +/* ---------- DNS options ---------- */ +#define LWIP_DNS 1 + +/* ---------- UPNP options --------- */ +#define LWIP_UPNP 0 + +/* Support Multicast */ +#define LWIP_IGMP 1 +#define LWIP_RAND() Rand() + +/* Support TCP Keepalive */ +#define LWIP_TCP_KEEPALIVE 1 + +/*LWIP_UART_ADAPTER==1: Enable LWIP_UART_ADAPTER when CONFIG_GAGENT is enabled, + because some GAGENT functions denpond on the following macro definitions.*/ +#if CONFIG_EXAMPLE_UART_ADAPTER +#define LWIP_UART_ADAPTER 1 +#else +#define LWIP_UART_ADAPTER 0 +#endif + +#if LWIP_UART_ADAPTER +#undef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 1 + +#undef SO_REUSE +#define SO_REUSE 1 + +#undef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 10 + +#undef TCP_WND +#define TCP_WND (4*TCP_MSS) + +#define TCP_KEEPIDLE_DEFAULT 10000UL +#define TCP_KEEPINTVL_DEFAULT 1000UL +#define TCP_KEEPCNT_DEFAULT 10U +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD +#undef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 1 + +#undef SO_REUSE +#define SO_REUSE 1 + +#undef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 10 + +#undef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB (MEMP_NUM_NETCONN) + +#undef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB (MEMP_NUM_NETCONN) + +#undef TCP_WND +#define TCP_WND (4*TCP_MSS) + +#define TCP_KEEPIDLE_DEFAULT 10000UL +#define TCP_KEEPINTVL_DEFAULT 1000UL +#define TCP_KEEPCNT_DEFAULT 10U + +#define ERRNO 1 +#endif + +/* ---------- Statistics options ---------- */ +#define LWIP_STATS 0 +#define LWIP_PROVIDE_ERRNO 1 + + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ + +/* +The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware: + - To use this feature let the following define uncommented. + - To disable it and process by CPU comment the the checksum. +*/ +//Do checksum by lwip - WLAN nic does not support Checksum offload +//#define CHECKSUM_BY_HARDWARE + + +#ifdef CHECKSUM_BY_HARDWARE + /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 0 + /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 0 + /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 0 + /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 0 + /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 0 + /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 0 +#else + /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 1 + /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 1 + /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 1 + /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 1 + /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 1 + /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 1 +#endif + + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#define LWIP_NETCONN 1 + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#define LWIP_SOCKET 1 + +/* + ----------------------------------- + ---------- DEBUG options ---------- + ----------------------------------- +*/ + +#define LWIP_DEBUG 0 + +/* + --------------------------------- + ---------- OS options ---------- + --------------------------------- +*/ + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_STACKSIZE 1000 +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#define TCPIP_MBOX_SIZE 6 +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_UDP_RECVMBOX_SIZE 6 +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_TCP_RECVMBOX_SIZE 6 +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_RAW_RECVMBOX_SIZE 6 +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#define DEFAULT_ACCEPTMBOX_SIZE 6 +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_STACKSIZE 500 +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2) + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#if defined(_SYS__TIMEVAL_H_) +#define LWIP_TIMEVAL_PRIVATE 0 +#endif + +#endif /* __LWIPOPTS_H__ */ + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/project/inc/main.h b/project/inc/main.h new file mode 100644 index 0000000..e05a0ab --- /dev/null +++ b/project/inc/main.h @@ -0,0 +1,119 @@ +#ifndef MAIN_H +#define MAIN_H + +#include + +#ifndef CONFIG_WLAN +#define CONFIG_WLAN 1 +#endif + +/* Header file declaration*/ +void wlan_network(); + +/* Interactive Mode */ +#define SERIAL_DEBUG_RX 1 + +/* WLAN and Netork */ +#define STA_MODE_SSID "ap" /* Set SSID here */ +#define AP_MODE_SSID "wlan_ap_ssid" /* Set SSID here */ +#define AP_DEFAULT_CH 6 +#define WLAN0_NAME "wlan0" +#define WLAN1_NAME "wlan1" +#define WPA_PASSPHRASE "1234567890" /* Max 32 cahracters */ +#define WEP40_KEY {0x12, 0x34, 0x56, 0x78, 0x90} + +#define ATVER_1 1 // For First AT command +#define ATVER_2 2 // For UART Module AT command + +#if CONFIG_EXAMPLE_UART_ATCMD +#define ATCMD_VER ATVER_2 +#else +#define ATCMD_VER ATVER_1 +#endif + +#if ATCMD_VER == ATVER_2 + +extern unsigned char sta_ip[4], sta_netmask[4], sta_gw[4]; +extern unsigned char ap_ip[4], ap_netmask[4], ap_gw[4]; + +/*Static IP ADDRESS*/ +#define IP_ADDR0 sta_ip[0] +#define IP_ADDR1 sta_ip[1] +#define IP_ADDR2 sta_ip[2] +#define IP_ADDR3 sta_ip[3] + +/*NETMASK*/ +#define NETMASK_ADDR0 sta_netmask[0] +#define NETMASK_ADDR1 sta_netmask[1] +#define NETMASK_ADDR2 sta_netmask[2] +#define NETMASK_ADDR3 sta_netmask[3] + +/*Gateway Address*/ +#define GW_ADDR0 sta_gw[0] +#define GW_ADDR1 sta_gw[1] +#define GW_ADDR2 sta_gw[2] +#define GW_ADDR3 sta_gw[3] + +/*******************************************/ + +/*Static IP ADDRESS*/ +#define AP_IP_ADDR0 ap_ip[0] +#define AP_IP_ADDR1 ap_ip[1] +#define AP_IP_ADDR2 ap_ip[2] +#define AP_IP_ADDR3 ap_ip[3] + +/*NETMASK*/ +#define AP_NETMASK_ADDR0 ap_netmask[0] +#define AP_NETMASK_ADDR1 ap_netmask[1] +#define AP_NETMASK_ADDR2 ap_netmask[2] +#define AP_NETMASK_ADDR3 ap_netmask[3] + +/*Gateway Address*/ +#define AP_GW_ADDR0 ap_gw[0] +#define AP_GW_ADDR1 ap_gw[1] +#define AP_GW_ADDR2 ap_gw[2] +#define AP_GW_ADDR3 ap_gw[3] + +#else + +/*Static IP ADDRESS*/ +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 3 +#define IP_ADDR3 80 + +/*NETMASK*/ +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 + +/*Gateway Address*/ +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 3 +#define GW_ADDR3 1 + +/*******************************************/ + +/*Static IP ADDRESS*/ +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 + +/*NETMASK*/ +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 + +/*Gateway Address*/ +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 + +#endif //#if ATCMD_VER == ATVER_2 + +#endif diff --git a/project/inc/platform_autoconf.h b/project/inc/platform_autoconf.h new file mode 100644 index 0000000..7377ec5 --- /dev/null +++ b/project/inc/platform_autoconf.h @@ -0,0 +1,251 @@ +/* + * Automatically generated by make menuconfig: don't edit + */ +#define AUTOCONF_INCLUDED + +#define RTL8710AF +//#define RTL8711AM +/* Image1 on project */ +#define PRESENT_IMAGE1 +/* Image2 on project */ +#define PRESENT_IMAGE2 +/* + * Target Platform Selection + */ +#define CONFIG_WITHOUT_MONITOR 1 + +#undef CONFIG_RTL8195A +#define CONFIG_RTL8195A 1 +#undef CONFIG_FPGA +#undef CONFIG_RTL_SIM +#undef CONFIG_POST_SIM +/* + * < Mass Production Option + */ +#undef CONFIG_MP +#undef CONFIG_CP +#undef CONFIG_FT +#define RTL8195A 1 +/* 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000? Hz, + 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000? Hz */ +#define CONFIG_CPU_CLK 1 +//166.6MHZ - RUN/IDLE/SLP ~63/21/6.4 mA +//83.3MHZ - RUN/IDLE/SLP ~55/15/6.4 mA +//41.6MHZ - RUN/IDLE ~51/11 mA +//20.8MHZ - RUN/IDLE ~49/9.5 mA +//4MHZ - IDLE ~8 mA +#undef CONFIG_FPGA_CLK +#define CONFIG_SDR_CLK 1 +#define CONFIG_SDR_100MHZ 1 +#undef CONFIG_SDR_50MHZ +#undef CONFIG_SDR_25MHZ +#undef CONFIG_SDR_12_5MHZ +#define SDR_CLOCK_SEL_VALUE (0) +#define CONFIG_BOOT_PROCEDURE 1 +#define CONFIG_IMAGE_PAGE_LOAD 1 +#undef CONFIG_IMAGE_AUTO_LOAD +#undef CONFIG_IMAGE_PAGE_LOAD +//#define CONFIG_IMAGE_AUTO_LOAD 1 +//#define CONFIG_BOOT_TO_UPGRADE_IMG2 1 +#undef CONFIG_PERI_UPDATE_IMG +#define CONFIG_BOOT_FROM_JTAG 1 +#undef CONFIG_ALIGNMENT_EXCEPTION_ENABLE +#define CONFIG_KERNEL 1 +#define PLATFORM_FREERTOS 1 +#undef PLATFORM_UCOSII +#undef PLATFORM_ECOS +#undef CONFIG_TASK_SCHEDUL_DIS +#define TASK_SCHEDULER_DISABLED (0) +#define CONFIG_NORMALL_MODE 1 +#undef CONFIG_MEMORY_VERIFY_MODE +#define CONFIG_TIMER_EN 1 +#define CONFIG_TIMER_NORMAL 1 +#undef CONFIG_TIMER_TEST +#define CONFIG_TIMER_MODULE 1 +#define CONFIG_WDG 1 +#undef CONFIG_WDG_NON +#define CONFIG_WDG_NORMAL 1 +#define CONFIG_WDG_ON_IDLE 10 // add pvvx: wdt on 10 s -> main.c + tasks.c +#define CONFIG_GDMA_EN 1 +#define CONFIG_GDMA_NORMAL 1 +#undef CONFIG_GDMA_TEST +#define CONFIG_GDMA_MODULE 1 +#define CONFIG_WIFI_EN 1 +#define CONFIG_WIFI_NORMAL 1 +#undef CONFIG_WIFI_TEST +#define CONFIG_WIFI_MODULE 1 +#define CONFIG_GPIO_EN 1 +#define CONFIG_GPIO_NORMAL 1 +#undef CONFIG_GPIO_TEST +#define CONFIG_GPIO_MODULE 1 +#if defined(CONFIG_INIC) || (CONFIG_SDIOD) +#define CONFIG_SDIO_DEVICE_EN 1 +#define CONFIG_SDIO_DEVICE_NORMAL 1 +#undef CONFIG_SDIO_DEVICE_TEST +#define CONFIG_SDIO_DEVICE_MODULE 1 +#else +#undef CONFIG_SDIO_DEVICE_EN +#endif +#define CONFIG_SDIO_HOST_EN 1 +//#define CONFIG_USB_EN 1 +#undef CONFIG_USB_NORMAL +#define CONFIG_USB_TEST 1 +#define CONFIG_USB_MODULE 1 +#define CONFIG_USB_VERIFY 1 +#undef CONFIG_USB_ROM_LIB +//#define CONFIG_USB_DBGINFO_EN 1 +#if defined(CONFIG_INIC) || (CONFIG_USBD) +#define DWC_DEVICE_ONLY 1 +#else +#define DWC_HOST_ONLY 1 +#define CONFIG_USB_HOST_ONLY 1 +#endif +#define CONFIG_SPI_COM_EN 1 +#define CONFIG_SPI_COM_NORMAL 1 +#undef CONFIG_SPI_COM_TEST +#define CONFIG_SPI_COM_MODULE 1 +#define CONFIG_UART_EN 1 +#define CONFIG_UART_NORMAL 1 +#undef CONFIG_UART_TEST +#define CONFIG_UART_MODULE 1 +#define CONFIG_I2C_EN 1 +#define CONFIG_I2C_NORMAL 1 +#undef CONFIG_I2C_TEST +#define CONFIG_I2C_MODULE 1 +#undef CONFIG_DEBUG_LOG_I2C_HAL +#undef CONFIG_PCM_EN +#define CONFIG_I2S_EN 1 +#define CONFIG_I2S_NORMAL 1 +#undef CONFIG_I2S_TEST +#define CONFIG_I2S_MODULE 1 +#undef CONFIG_DEBUG_LOG_I2S_HAL +#define CONFIG_NFC_EN 1 +#define CONFIG_NFC_NORMAL 1 +#undef CONFIG_NFC_TEST +#define CONFIG_NFC_MODULE 1 +#define CONFIG_SOC_PS_EN 1 +#define CONFIG_SOC_PS_NORMAL 1 +#undef CONFIG_SOC_PS_TEST +#define CONFIG_SOC_PS_MODULE 1 // hal_soc_ps_monitor.c +//#define CONFIG_SOC_PS_VERIFY 1 // hal_soc_ps_monitor.c +#define CONFIG_CRYPTO_EN 1 +#define CONFIG_CRYPTO_NORMAL 1 +#undef CONFIG_CRYPTO_TEST +#define CONFIG_CRYPTO_MODULE 1 +#define CONFIG_CRYPTO_STARTUP 1 +#define CONFIG_MII_EN 0 //1 +#define CONFIG_PWM_EN 1 +#define CONFIG_PWM_NORMAL 1 +#undef CONFIG_PWM_TEST +#define CONFIG_PWM_MODULE 1 +#define CONFIG_EFUSE_EN 1 // common/mbed/targets/hal/rtl8195a/efuse_api.c +#define CONFIG_EFUSE_NORMAL 1 +#undef CONFIG_EFUSE_TEST +#define CONFIG_EFUSE_MODULE 1 +#ifdef RTL8711AM +#define CONFIG_SDR_EN 1 +#endif +#define CONFIG_SDR_NORMAL 1 +#undef CONFIG_SDR_TEST +#define CONFIG_SDR_MODULE 1 +#define CONFIG_SPIC_EN 1 +#define CONFIG_SPIC_NORMAL 1 +#undef CONFIG_SPIC_TEST +#define CONFIG_SPIC_MODULE 1 +#define CONFIG_ADC_EN 1 +//#define CONFIG_DAC_EN 1 +#define CONFIG_NOR_FLASH 1 +#undef CONFIG_SPI_FLASH +#undef CONFIG_NAND_FLASH +#undef CONFIG_NONE_FLASH +#undef CONFIG_BTBX_EN + +// add pvvx +#define CONFIG_LOG_UART_EN 1 + +/* + * < Engineer Mode Config + */ +#undef CONFIG_JTAG +#undef CONFIG_COMPILE_FLASH_DOWNLOAD_CODE +#undef CONIFG_COMPILE_EXTERNAL_SRAM_CALIBRATE +#undef CONFIG_CMSIS_MATH_LIB_EN + +/* + * < Application Config + */ +#define CONFIG_NETWORK 1 +#define CONFIG_RTLIB_EN 1 +#define CONFIG_RTLIB_NORMAL 1 +#undef CONFIG_RTLIB_TEST +#define CONFIG_RTLIB_MODULE 1 + +/* + * < System Debug Message Config + */ +#define CONFIG_UART_LOG_HISTORY 1 +#undef CONFIG_CONSOLE_NORMALL_MODE +#define CONFIG_CONSOLE_VERIFY_MODE 1 + +/* CONFIG_DEBUG_LOG: +=0 Off all diag/debug msg, +=1 Only errors, +=2 errors + warning, (default) +=3 errors + warning + info, +=4 errors + warning + info + debug, +=5 full */ +#define CONFIG_DEBUG_LOG 2 +#if CONFIG_DEBUG_LOG > 0 +//#define CONFIG_DEBUG_ERR_MSG 1 +#define CONFIG_DEBUG_LOG_ADC_HAL 1 +#define CONFIG_DEBUG_LOG_I2S_HAL 1 +//#undef CONFIG_DEBUG_WARN_MSG +//#undef CONFIG_DEBUG_INFO_MSG +#endif // CONFIG_DEBUG_LOG +/* + * < SDK Option Config + */ +#undef CONFIG_MBED_ENABLED +#undef CONFIG_APP_DEMO + +/* + * < Select Chip Version + */ +#undef CONFIG_CHIP_A_CUT +#define CONFIG_CHIP_B_CUT 1 +#undef CONFIG_CHIP_C_CUT +#undef CONFIG_CHIP_E_CUT + +/* + * < Select toolchain + */ +#undef CONFIG_TOOLCHAIN_ASDK +#undef CONFIG_TOOLCHAIN_ARM_GCC + +/* + * < Build Option + */ +#define CONFIG_LINK_ROM_LIB 1 +#undef CONFIG_LINK_ROM_SYMB +#undef CONFIG_NORMAL_BUILD +#undef CONFIG_RELEASE_BUILD +#undef CONFIG_RELEASE_BUILD_LIBRARIES +#undef CONFIG_LIB_BUILD_RAM +#define CONFIG_RELEASE_BUILD_RAM_ALL 1 +#undef CONFIG_IMAGE_ALL +#define CONFIG_IMAGE_SEPARATE 1 + +#if CONFIG_CPU_CLK < 6 +#define CPU_CLOCK_SEL_DIV5_3 0 +#define CPU_CLOCK_SEL_VALUE CONFIG_CPU_CLK +#else +#define CPU_CLOCK_SEL_DIV5_3 1 +#define CPU_CLOCK_SEL_VALUE (CONFIG_CPU_CLK-6) +#endif + +#if CPU_CLOCK_SEL_DIV5_3 +#define PLATFORM_CLOCK (200000000ul>>CPU_CLOCK_SEL_VALUE) +#else +#define PLATFORM_CLOCK (((200000000ul*5ul)/6ul)>>CPU_CLOCK_SEL_VALUE) +#endif + diff --git a/project/inc/platform_opts.h b/project/inc/platform_opts.h new file mode 100644 index 0000000..90f29c8 --- /dev/null +++ b/project/inc/platform_opts.h @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + *This file contains general configurations for ameba platform + ****************************************************************************** +*/ + +#ifndef __PLATFORM_OPTS_H__ +#define __PLATFORM_OPTS_H__ + +/*For MP mode setting*/ +#define SUPPORT_MP_MODE 0 + +/** + * For AT cmd Log service configurations + */ +#define SUPPORT_LOG_SERVICE 0 +#if SUPPORT_LOG_SERVICE +#define LOG_SERVICE_BUFLEN 100 //can't larger than UART_LOG_CMD_BUFLEN(127) +#define CONFIG_LOG_HISTORY 0 +#if CONFIG_LOG_HISTORY +#define LOG_HISTORY_LEN 5 +#endif +#define SUPPORT_INTERACTIVE_MODE 0 //on/off wifi_interactive_mode +#define CONFIG_LOG_SERVICE_LOCK 0 +#endif + +/** + * For interactive mode configurations, depends on log service + */ +#if SUPPORT_INTERACTIVE_MODE +#define CONFIG_INTERACTIVE_MODE 1 +#define CONFIG_INTERACTIVE_EXT 0 +#else +#define CONFIG_INTERACTIVE_MODE 0 +#define CONFIG_INTERACTIVE_EXT 0 +#endif + +/** + * For FreeRTOS tickless configurations + */ +#define FREERTOS_PMU_TICKLESS_PLL_RESERVED 0 // In sleep mode, 0: close PLL clock, 1: reserve PLL clock +#define FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM 1 // In sleep mode, 1: suspend SDRAM, 0: no act + +/******************************************************************************/ + +/** +* For common flash usage +*/ +#define AP_SETTING_SECTOR 0x000FE000 +#define UART_SETTING_SECTOR 0x000FC000 +#define FAST_RECONNECT_DATA (0x80000 - 0x1000) + +/** + * For Wlan configurations + */ + +#define CONFIG_WLAN 1 +#if CONFIG_WLAN +#define CONFIG_LWIP_LAYER 1 +#define CONFIG_AT_USR 1 // add pvxx +//#define CONFIG_AT_LWIP 1 // add pvxx +//#define CONFIG_AT_SYS 1 // add pvxx +//#define CONFIG_AT_WIFI 1 // add pvxx +#define CONFIG_INIT_NET 1 // init lwip layer when start up +#define CONFIG_WIFI_IND_USE_THREAD 0 // wifi indicate worker thread + +//on/off relative commands in log service +#define CONFIG_SSL_CLIENT 0 +#define CONFIG_WEBSERVER 0 +#define CONFIG_OTA_UPDATE 0 +#define CONFIG_BSD_TCP 0 //NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size +#define CONFIG_AIRKISS 0 //on or off tencent airkiss +#define CONFIG_UART_SOCKET 0 // Set: CONFIG_UART_EN, CONFIG_UART_SOCKET +#define CONFIG_UART_XMODEM 0 //support uart xmodem upgrade or not +#define CONFIG_TRANSPORT 0 //on or off the at command for transport socket + +/* For WPS and P2P */ +#define CONFIG_ENABLE_WPS 0 +#define CONFIG_ENABLE_P2P 0 +#if CONFIG_ENABLE_P2P +#define CONFIG_ENABLE_WPS_AP 1 +#undef CONFIG_WIFI_IND_USE_THREAD +#define CONFIG_WIFI_IND_USE_THREAD 1 +#endif +#if (CONFIG_ENABLE_P2P && ((CONFIG_ENABLE_WPS_AP == 0) || (CONFIG_ENABLE_WPS == 0))) +#error "If CONFIG_ENABLE_P2P, need to define CONFIG_ENABLE_WPS_AP 1" +#endif + +/* For Simple Link */ +#define CONFIG_INCLUDE_SIMPLE_CONFIG 0 + +/*For wowlan service settings*/ +#define CONFIG_WOWLAN_SERVICE 0 + +#endif //end of #if CONFIG_WLAN +/*******************************************************************************/ + +/** + * For Ethernet configurations + */ +#define CONFIG_ETHERNET 0 +#if CONFIG_ETHERNET + +#define CONFIG_LWIP_LAYER 1 +#define CONFIG_INIT_NET 1 //init lwip layer when start up + +//on/off relative commands in log service +#define CONFIG_SSL_CLIENT 0 +#define CONFIG_BSD_TCP 0 //NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size + +#endif + + +/** + * For iNIC configurations + */ +#ifdef CONFIG_INIC //this flag is defined in IAR project +#define CONFIG_INIC_EN 1 //enable iNIC mode +#undef CONFIG_ENABLE_WPS +#define CONFIG_ENABLE_WPS 1 +#undef CONFIG_INCLUDE_SIMPLE_CONFIG +#define CONFIG_INCLUDE_SIMPLE_CONFIG 1 +#undef CONFIG_WOWLAN_SERVICE +#define CONFIG_WOWLAN_SERVICE 1 +#undef LOG_SERVICE_BUFLEN +#define LOG_SERVICE_BUFLEN 256 +#undef CONFIG_LWIP_LAYER +#define CONFIG_LWIP_LAYER 0 +#undef CONFIG_OTA_UPDATE +#define CONFIG_OTA_UPDATE 0 +#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0 +#define CONFIG_INIC_SDIO_HCI 1 //for SDIO or USB iNIC +#define CONFIG_INIC_USB_HCI 0 +#define CONFIG_INIC_CMD_RSP 1 //need to return msg to host +#endif +/******************End of iNIC configurations*******************/ + +/* For UART Module AT command example */ +#define CONFIG_EXAMPLE_UART_ATCMD 0 +#if CONFIG_EXAMPLE_UART_ATCMD +#undef FREERTOS_PMU_TICKLESS_PLL_RESERVED +#define FREERTOS_PMU_TICKLESS_PLL_RESERVED 1 +#undef CONFIG_OTA_UPDATE +#define CONFIG_OTA_UPDATE 1 +#undef CONFIG_TRANSPORT +#define CONFIG_TRANSPORT 1 +#undef LOG_SERVICE_BUFLEN +#define LOG_SERVICE_BUFLEN 1600 +#undef CONFIG_LOG_SERVICE_LOCK +#define CONFIG_LOG_SERVICE_LOCK 1 +#else +#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0 +#endif + +//#define CONFIG_EXAMPLE_UART_ADAPTER 1 +//#define CONFIG_EXAMPLE_MDNS +#define USE_FLASH_EEP 1 +#define CONFIG_WLAN_CONNECT_CB 1 + +//#define CONFIG_FATFS_EN 1 // FatFs & SD +#ifdef CONFIG_FATFS_EN +// fatfs version +#define FATFS_R_10C +// fatfs disk interface +#define FATFS_DISK_USB 0 +#define FATFS_DISK_SD 1 +#undef CONFIG_SDIO_HOST_EN +#define CONFIG_SDIO_HOST_EN 1 +#endif + +#endif //__PLATFORM_OPTS_H__ diff --git a/project/inc/rtl8195a/c_types.h b/project/inc/rtl8195a/c_types.h new file mode 100644 index 0000000..239d801 --- /dev/null +++ b/project/inc/rtl8195a/c_types.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010 - 2011 Espressif System + * + */ + +#ifndef _C_TYPES_H_ +#define _C_TYPES_H_ + +typedef unsigned char uint8_t; +typedef signed char sint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short sint16_t; +typedef signed short int16_t; +typedef unsigned long uint32_t; +typedef signed long sint32_t; +typedef signed long int32_t; +typedef signed long long sint64_t; +typedef unsigned long long uint64_t; +typedef unsigned long long u_int64_t; +typedef float real32_t; +typedef double real64_t; + +typedef unsigned char uint8; +typedef unsigned char u8; +typedef signed char sint8; +typedef signed char int8; +typedef signed char s8; +typedef unsigned short uint16; +typedef unsigned short u16; +typedef signed short sint16; +typedef signed short s16; +typedef unsigned int uint32; +typedef unsigned int u_int; +typedef unsigned int u32; +typedef signed int sint32; +typedef signed int s32; +typedef int int32; +typedef signed long long sint64; +typedef unsigned long long uint64; +typedef unsigned long long u64; +typedef float real32; +typedef double real64; + +#define __le16 u16 + +typedef unsigned int size_t; +typedef int ssize_t; + +#ifndef _SYS_CDEFS_H_ +#define __packed __attribute__((packed)) +#endif + +#define LOCAL static + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +/* probably should not put STATUS here */ +typedef enum { + OK = 0, + FAIL, + PENDING, + BUSY, + CANCEL, +} STATUS; + +#define BIT(nr) (1UL << (nr)) + +#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b)) +#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b)) + +#define DMEM_ATTR +#define SHMEM_ATTR + +#ifdef ICACHE_FLASH +#define ICACHE_FLASH_ATTR +#define ICACHE_RODATA_ATTR +#else +#define ICACHE_FLASH_ATTR +#define ICACHE_RODATA_ATTR +#endif /* ICACHE_FLASH */ + +#ifndef __cplusplus +typedef unsigned char bool; +//#define BOOL bool +#define true (1) +#define false (0) +#define TRUE true +#define FALSE false + + +#endif /* !__cplusplus */ + +#endif /* _C_TYPES_H_ */ diff --git a/project/inc/rtl8195a/os.h b/project/inc/rtl8195a/os.h new file mode 100644 index 0000000..2a0a4a7 --- /dev/null +++ b/project/inc/rtl8195a/os.h @@ -0,0 +1,593 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef OS_H +#define OS_H + +//#include "basic_types.h" +#include +#include "osdep_service.h" +#include "freertos/wrapper.h" +#include "utils/rom/rom_wps_os.h" + +typedef void* xqueue_handle_t; + +typedef long os_time_t; + +typedef _timer os_timer; + +/** + * os_sleep - Sleep (sec, usec) + * @sec: Number of seconds to sleep + * @usec: Number of microseconds to sleep + */ +void os_sleep(os_time_t sec, os_time_t usec); + +struct os_time { + os_time_t sec; + os_time_t usec; +}; + +struct os_reltime { + os_time_t sec; + os_time_t usec; +}; + +/** + * os_get_time - Get current time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_time(struct os_time *t); + +int os_get_reltime(struct os_reltime *t); +/* Helper macros for handling struct os_time */ +/* (&timeout->time, &tmp->time) */ +#define os_time_before(a, b) \ + ((a)->sec < (b)->sec || \ + ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) + +#define os_time_sub(a, b, res) do { \ + (res)->sec = (a)->sec - (b)->sec; \ + (res)->usec = (a)->usec - (b)->usec; \ + if ((res)->usec < 0) { \ + (res)->sec--; \ + (res)->usec += 1000000; \ + } \ +} while (0) + +/** + * os_mktime - Convert broken-down time into seconds since 1970-01-01 + * @year: Four digit year + * @month: Month (1 .. 12) + * @day: Day of month (1 .. 31) + * @hour: Hour (0 .. 23) + * @min: Minute (0 .. 59) + * @sec: Second (0 .. 60) + * @t: Buffer for returning calendar time representation (seconds since + * 1970-01-01 00:00:00) + * Returns: 0 on success, -1 on failure + * + * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time + * which is used by POSIX mktime(). + */ +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t); + +struct os_tm { + int sec; /* 0..59 or 60 for leap seconds */ + int min; /* 0..59 */ + int hour; /* 0..23 */ + int day; /* 1..31 */ + int month; /* 1..12 */ + int year; /* Four digit year */ +}; + +int os_gmtime(os_time_t t, struct os_tm *tm); + +/* Helpers for handling struct os_time */ + +/* Helpers for handling struct os_reltime */ + +static inline int os_reltime_before(struct os_reltime *a, + struct os_reltime *b) +{ + return os_time_before(a,b); +} + + +static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b, + struct os_reltime *res) +{ + os_time_sub(a,b,res); +} + + +static inline void os_reltime_age(struct os_reltime *start, + struct os_reltime *age) +{ + struct os_reltime now; + + os_get_time((struct os_time *)&now); + os_reltime_sub(&now, start, age); +} + + +static inline int os_reltime_expired(struct os_reltime *now, + struct os_reltime *ts, + os_time_t timeout_secs) +{ + struct os_reltime age; + + os_reltime_sub(now, ts, &age); + return (age.sec > timeout_secs) || + (age.sec == timeout_secs && age.usec > 0); +} + +/** + * os_daemonize - Run in the background (detach from the controlling terminal) + * @pid_file: File name to write the process ID to or %NULL to skip this + * Returns: 0 on success, -1 on failure + */ +int os_daemonize(const char *pid_file); + +/** + * os_daemonize_terminate - Stop running in the background (remove pid file) + * @pid_file: File name to write the process ID to or %NULL to skip this + */ +void os_daemonize_terminate(const char *pid_file); + +/** + * os_get_random - Get cryptographically strong pseudo random data + * @buf: Buffer for pseudo random data + * @len: Length of the buffer + * Returns: 0 on success, -1 on failure + */ +int os_get_random(unsigned char *buf, size_t len); + +/** + * os_random - Get pseudo random value (not necessarily very strong) + * Returns: Pseudo random value + */ +unsigned long os_random(void); + +/** + * os_rel2abs_path - Get an absolute path for a file + * @rel_path: Relative path to a file + * Returns: Absolute path for the file or %NULL on failure + * + * This function tries to convert a relative path of a file to an absolute path + * in order for the file to be found even if current working directory has + * changed. The returned value is allocated and caller is responsible for + * freeing it. It is acceptable to just return the same path in an allocated + * buffer, e.g., return strdup(rel_path). This function is only used to find + * configuration files when os_daemonize() may have changed the current working + * directory and relative path would be pointing to a different location. + */ +char * os_rel2abs_path(const char *rel_path); + +/** + * os_program_init - Program initialization (called at start) + * Returns: 0 on success, -1 on failure + * + * This function is called when a programs starts. If there are any OS specific + * processing that is needed, it can be placed here. It is also acceptable to + * just return 0 if not special processing is needed. + */ +int os_program_init(void); + +/** + * os_program_deinit - Program deinitialization (called just before exit) + * + * This function is called just before a program exists. If there are any OS + * specific processing, e.g., freeing resourced allocated in os_program_init(), + * it should be done here. It is also acceptable for this function to do + * nothing. + */ +void os_program_deinit(void); + +/** + * os_setenv - Set environment variable + * @name: Name of the variable + * @value: Value to set to the variable + * @overwrite: Whether existing variable should be overwritten + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_setenv(const char *name, const char *value, int overwrite); + +/** + * os_unsetenv - Delete environent variable + * @name: Name of the variable + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_unsetenv(const char *name); + +/** + * os_readfile - Read a file to an allocated memory buffer + * @name: Name of the file to read + * @len: For returning the length of the allocated buffer + * Returns: Pointer to the allocated buffer or %NULL on failure + * + * This function allocates memory and reads the given file to this buffer. Both + * binary and text files can be read with this function. The caller is + * responsible for freeing the returned buffer with os_free(). + */ +char * os_readfile(const char *name, size_t *len); + +//#if 0 +/** + * os_zalloc - Allocate and zero memory + * @size: Number of bytes to allocate + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_zalloc(size_t size); + +/** + * os_calloc - Allocate and zero memory for an array + * @nmemb: Number of members in the array + * @size: Number of bytes in each member + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * This function can be used as a wrapper for os_zalloc(nmemb * size) when an + * allocation is used for an array. The main benefit over os_zalloc() is in + * having an extra check to catch integer overflows in multiplication. + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +static inline void * os_calloc(size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_zalloc(nmemb * size); +} +//#endif + + +static inline int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + +/* + * The following functions are wrapper for standard ANSI C or POSIX functions. + * By default, they are just defined to use the standard function name and no + * os_*.c implementation is needed for them. This avoids extra function calls + * by allowing the C pre-processor take care of the function name mapping. + * + * If the target system uses a C library that does not provide these functions, + * build_config.h can be used to define the wrappers to use a different + * function name. This can be done on function-by-function basis since the + * defines here are only used if build_config.h does not define the os_* name. + * If needed, os_*.c file can be used to implement the functions that are not + * included in the C library on the target system. Alternatively, + * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case + * these functions need to be implemented in os_*.c file for the target system. + */ + +#ifdef OS_NO_C_LIB_DEFINES + +/** + * os_malloc - Allocate dynamic memory + * @size: Size of the buffer to allocate + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_malloc(size_t size); + +/** + * os_realloc - Re-allocate dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc() + * @size: Size of the new buffer + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + * If re-allocation fails, %NULL is returned and the original buffer (ptr) is + * not freed and caller is still responsible for freeing it. + */ +void * os_realloc(void *ptr, size_t size); + +/** + * os_free - Free dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL + */ +void os_free(void *ptr); + +/** + * os_memcpy - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst must not overlap. os_memmove() can be used with + * overlapping memory. + */ +void * os_memcpy(void *dest, const void *src, size_t n); + +/** + * os_memmove - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst may overlap. + */ +void *os_memmove(void *dest, const void *src, size_t n); + +/** + * os_memset - Fill memory with a constant byte + * @s: Memory area to be filled + * @c: Constant byte + * @n: Number of bytes started from s to fill with c + * Returns: s + */ +void *os_memset(void *s, int c, size_t n); + +/** + * os_memcmp - Compare memory areas + * @s1: First buffer + * @s2: Second buffer + * @n: Maximum numbers of octets to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_memcmp(const void *s1, const void *s2, size_t n); + +/** + * os_strdup - Duplicate a string + * @s: Source string + * Returns: Allocated buffer with the string copied into it or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +char *os_strdup(const char *s); + +/** + * os_strlen - Calculate the length of a string + * @s: '\0' terminated string + * Returns: Number of characters in s (not counting the '\0' terminator) + */ +size_t os_strlen(const char *s); + +/** + * os_strcasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcasecmp(const char *s1, const char *s2); + +/** + * os_strncasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncasecmp(const char *s1, const char *s2, size_t n); + +/** + * os_strchr - Locate the first occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char *os_strchr(const char *s, int c); + +/** + * os_strrchr - Locate the last occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char *os_strrchr(const char *s, int c); + +/** + * os_strcmp - Compare two strings + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcmp(const char *s1, const char *s2); + +/** + * os_strncmp - Compare two strings + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncmp(const char *s1, const char *s2, size_t n); + +/** + * os_strncpy - Copy a string + * @dest: Destination + * @src: Source + * @n: Maximum number of characters to copy + * Returns: dest + */ +char *os_strncpy(char *dest, const char *src, size_t n); + +/** + * os_strstr - Locate a substring + * @haystack: String (haystack) to search from + * @needle: Needle to search from haystack + * Returns: Pointer to the beginning of the substring or %NULL if not found + */ +char *os_strstr(const char *haystack, const char *needle); + +/** + * os_snprintf - Print to a memory buffer + * @str: Memory buffer to print into + * @size: Maximum length of the str buffer + * @format: printf format + * Returns: Number of characters printed (not including trailing '\0'). + * + * If the output buffer is truncated, number of characters which would have + * been written is returned. Since some C libraries return -1 in such a case, + * the caller must be prepared on that value, too, to indicate truncation. + * + * Note: Some C library implementations of snprintf() may not guarantee null + * termination in case the output is truncated. The OS wrapper function of + * os_snprintf() should provide this guarantee, i.e., to null terminate the + * output buffer if a C library version of the function is used and if that + * function does not guarantee null termination. + * + * If the target system does not include snprintf(), see, e.g., + * http://www.ijs.si/software/snprintf/ for an example of a portable + * implementation of snprintf. + */ +int os_snprintf(char *str, size_t size, const char *format, ...); + +#else /* OS_NO_C_LIB_DEFINES */ + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#ifdef CONFIG_MEM_MONITOR + u8* os_malloc(u32 sz); + void os_mfree(u8 *pbuf, u32 sz); + #ifndef os_free + #define os_free(p, sz) os_mfree(((u8*)(p)), (sz)) + #endif +#else + #ifndef os_malloc + #define os_malloc(sz) _rtw_malloc(sz) + #endif + #ifndef os_free + #define os_free(p, sz) _rtw_mfree(((u8*)(p)), (sz)) + #endif +#endif +#endif + extern void *os_zalloc(size_t size); + extern char *os_strdup(const char *string_copy_from); + + #ifndef os_sleep + #define os_sleep(s, us) rtw_mdelay_os((s)*1000 + (us)/1000) + #endif + #ifndef os_memcpy + #define os_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n)) + #endif + #ifndef os_memmove + #define os_memmove(d, s, n) memmove((d), (s), (n)) + #endif + #ifndef os_memset + #define os_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz) + #endif + #ifndef os_memcmp + #define os_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n)) + #endif + #ifndef os_memcmp_p2p + #define os_memcmp_p2p(s1, s2, n) memcmp((s1), (s2), (n)) + #endif + #ifndef os_get_random_bytes + #define os_get_random_bytes(d,sz) rtw_get_random_bytes(((void*)(d)), (sz)) + #endif + #ifndef os_strlen + #define os_strlen(s) strlen(s) + #endif + #ifndef os_strcasecmp + #ifdef _MSC_VER + #define os_strcasecmp(s1, s2) _stricmp((s1), (s2)) + #else + #define os_strcasecmp(s1, s2) strcasecmp((s1), (s2)) + #endif + #endif + #ifndef os_strncasecmp + #ifdef _MSC_VER + #define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n)) + #else + #define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n)) + #endif + #endif + #ifndef os_init_timer + #define os_init_timer(t, p, f, x, n) rtw_init_timer((t), (p), (f), (x), (n)) + #endif + #ifndef os_set_timer + #define os_set_timer(t, d) rtw_set_timer((t), (d)) + #endif + #ifndef os_cancel_timer + #define os_cancel_timer(t) rtw_cancel_timer(t) + #endif + #ifndef os_del_timer + #define os_del_timer(t) rtw_del_timer(t) + #endif + #ifndef os_atoi + #define os_atoi(s) rtw_atoi(s) + #endif + +#ifndef os_strchr +#define os_strchr(s, c) strchr((s), (c)) +#endif +#ifndef os_strcmp +#define os_strcmp(s1, s2) strcmp((s1), (s2)) +#endif +#ifndef os_strncmp +#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) +#endif +#ifndef os_strncpy +#define os_strncpy(d, s, n) strncpy((d), (s), (n)) +#endif +#ifndef os_strrchr +#define os_strrchr(s, c) strrchr((s), (c)) +#endif +#ifndef os_strstr +#define os_strstr(h, n) strstr((h), (n)) +#endif + +#ifndef os_snprintf + #ifdef _MSC_VER + #define os_snprintf _snprintf + #else + #define os_snprintf snprintf + #endif +#endif + +#endif /* OS_NO_C_LIB_DEFINES */ + + +static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_realloc(ptr, nmemb * size, nmemb * size); +} + +void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) ; + +int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait); + +void os_xqueue_delete(xqueue_handle_t xQueue ); + +int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait); + + +#endif /* OS_H */ diff --git a/project/inc/rtl8195a/queue.h b/project/inc/rtl8195a/queue.h new file mode 100644 index 0000000..a760c8d --- /dev/null +++ b/project/inc/rtl8195a/queue.h @@ -0,0 +1,204 @@ +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#define QMD_SAVELINK(name, link) +#define TRASHIT(x) + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ + TRASHIT(*oldnext); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ + struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ + } + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ + struct { \ + struct type *stqe_next; /* next element */ \ + } + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ + } while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ + } while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ + } while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ + } while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + } while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ + TRASHIT(*oldnext); \ + } while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ + } while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + } while (0) + +#define STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ + } while (0) + +#define STAILQ_INSERT_CHAIN_HEAD(head, elm_chead, elm_ctail, field) do { \ + if ((STAILQ_NEXT(elm_ctail, field) = STAILQ_FIRST(head)) == NULL ) { \ + (head)->stqh_last = &STAILQ_NEXT(elm_ctail, field); \ + } \ + STAILQ_FIRST(head) = (elm_chead); \ + } while (0) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/project/inc/rtl8195a/rom_wps_os.h b/project/inc/rtl8195a/rom_wps_os.h new file mode 100644 index 0000000..cd41061 --- /dev/null +++ b/project/inc/rtl8195a/rom_wps_os.h @@ -0,0 +1,24 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef ROM_WPS_OS_H +#define ROM_WPS_OS_H + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + +#include +extern struct _rom_wlan_ram_map rom_wlan_ram_map; +#define os_malloc(sz) rom_wlan_ram_map.rtw_malloc(sz) +#define os_free(p, sz) rom_wlan_ram_map.rtw_mfree(((u8*)(p)), (sz)) + +#endif + +extern u8 *WPS_realloc(u8 *old_buf, u32 old_sz, u32 new_sz); +#define os_realloc(p, os, ns) WPS_realloc(((u8*)(p)),(os),(ns)) + +#endif /* ROM_WPS_OS_H */ diff --git a/project/inc/rtl8195a/rtl_common.h b/project/inc/rtl8195a/rtl_common.h new file mode 100644 index 0000000..a107e16 --- /dev/null +++ b/project/inc/rtl8195a/rtl_common.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) + * + */ + +#ifndef __RTL_COMMON_H__ +#define __RTL_COMMON_H__ + +#include +#include +#include + +#include "c_types.h" + +#endif diff --git a/project/inc/rtl8195a/rtl_libc.h b/project/inc/rtl8195a/rtl_libc.h new file mode 100644 index 0000000..15733fc --- /dev/null +++ b/project/inc/rtl8195a/rtl_libc.h @@ -0,0 +1,164 @@ +/* +* ROM calls +*/ + +#ifndef _INC_RTL_LIBC_ +#define _INC_RTL_LIBC_ + +//#undef malloc +#define malloc(size) pvPortMalloc(size) +//#undef free +#define free(pbuf) vPortFree(pbuf) + +#define atoi(str) prvAtoi(str) + +#define calloc(nelements, elementSize) calloc_freertos(nelements, elementSize) + +#define snprintf rtl_snprintf +#define sprintf rtl_sprintf +#define printf rtl_printf +#define vprintf rtl_vprintf +#define vsnprintf rtl_vsnprintf +#define vfprintf rtl_vfprintf +#define memchr rtl_memchr +#define memcmp rtl_memcmp +#define memcpy rtl_memcpy +#define memmove rtl_memmove +#define memset rtl_memset +#define strcat rtl_strcat +#define strchr rtl_strchr +#define strcmp rtl_strcmp +#define strcpy rtl_strcpy +#define strlen rtl_strlen +#define strncat rtl_strncat +#define strncmp rtl_strncmp +#define strncpy rtl_strncpy +#define strstr rtl_strstr +#define strsep rtl_strsep +#define strtok rtl_strtok + +#define dtoi rtl_dtoi +#define dtoui rtl_dtoui +#define i2f rtl_i2f +#define i2d rtl_i2d +#define ui2f rtl_ui2f +#define ui2d rtl_ui2d +#define itoa rtl_itoa +#define ltoa rtl_ltoa +#define utoa rtl_utoa +#define ultoa rtl_ultoa +#define ftol rtl_ftol +#define ftod rtl_ftod +#define dtof rtl_dtof +#define fadd rtl_fadd +#define fsub rtl_fsub +#define fmul rtl_fmul +#define fdiv rtl_fdiv +#define dadd rtl_dadd +#define dsub rtl_dsub +#define dmul rtl_dmul +#define ddiv rtl_ddiv +#define dcmpeq rtl_dcmpeq +#define dcmplt rtl_dcmplt +#define dcmple rtl_dcmple +#define dcmpgt rtl_dcmpgt +#define fcmplt rtl_fcmplt +#define fcmpgt rtl_fcmpgt + +#define fabsf rtl_fabsf +#define fabs rtl_fabs +#define cos_f32 rtl_cos_f32 +#define sin_f32 rtl_sin_f32 + + +#if 0 +extern void *calloc_freertos(size_t nelements, size_t elementSize); +// ram_libc.c +extern int rtl_snprintf(char *str, size_t size, const char *fmt, ...); +extern int rtl_sprintf(char *str, const char *fmt, ...); +extern int rtl_printf(const char *fmt, ...); +extern int rtl_vprintf(const char *fmt, void *param); +extern int rtl_vsnprintf(char *str, size_t size, const char *fmt, void *param); +extern int rtl_vfprintf(FILE *fp, const char *fmt0, va_list ap); +extern int rtl_memchr(const void *src_void, int c, size_t length); +extern int rtl_memcmp(const void *m1, const void *m2, size_t n); +extern int rtl_memcpy(void *dst0, const void *src0, size_t len0); +extern int rtl_memmove(void *dst_void, const void *src_void, size_t length); +extern int rtl_memset(void *m, int c, size_t n); +extern char * rtl_strcat(char *s1, const char *s2); +extern char * rtl_strchr(const char *s1, int i); +extern int rtl_strcmp(const char *s1, const char *s2); +extern char * rtl_strcpy(char *dst0, const char *src0); +extern int rtl_strlen(const char *str); +extern char * rtl_strncat(char *s1, const char *s2, size_t n); +extern int rtl_strncmp(const char *s1, const char *s2, size_t n); +extern char * rtl_strncpy(char *dst0, const char *src0, size_t count); +extern char * rtl_strstr(const char *searchee, const char *lookfor); +extern char * rtl_strsep(char **source_ptr, const char *delim); +extern char * rtl_strtok(char *s, const char *delim); + +//rtl_eabi_cast_ram.c +extern int rtl_dtoi(double d); +extern int rtl_dtoui(double d); +extern float rtl_i2f(int val); +extern int rtl_i2d(int val); +extern float rtl_ui2f(unsigned int val); +extern int rtl_ui2d(unsigned int val); +extern char *rtl_itoa(int value, char *string, int radix); +extern char *rtl_ltoa(int value, char *string, int radix); +extern char *rtl_utoa(unsigned int value, char *string, int radix); +extern char *rtl_ultoa(unsigned int value, char *string, int radix); +extern int rtl_ftol(float f); +extern int rtl_ftod(float f); +extern float rtl_dtof(double d); +extern float rtl_fadd(float a, float b); +extern float rtl_fsub(float a, float b); +extern float rtl_fmul(float a, float b); +extern float rtl_fdiv(float a, float b); +extern int rtl_dadd(double a, double b); +extern int rtl_dsub(double a, double b); +extern int rtl_dmul(double a, double b); +extern int rtl_ddiv(double a, double b); +extern int rtl_dcmpeq(double a, double b); +extern int rtl_dcmplt(double a, double b); +extern int rtl_dcmple(double a, double b); +extern int rtl_dcmpgt(double a, double b); +extern int rtl_fcmplt(float a, float b); +extern int rtl_fcmpgt(float a, float b); + +// rtl_math_ram.c +extern float rtl_fabsf(float a); +extern int rtl_fabs(double a); +extern float rtl_cos_f32(float a); +extern float rtl_sin_f32(float a); + +// ram_pvvx_libc.c +extern int snprintf(char *str, size_t size, const char *fmt, ...); +extern int sprintf(char *str, const char *fmt, ...); +extern int printf(const char *fmt, ...); +extern int vprintf(const char *fmt, void *param); +extern int vsnprintf(char *str, size_t size, const char *fmt, void *param); +extern int vfprintf(FILE *fp, const char *fmt0, va_list ap); +extern int memchr(const void *src_void, int c, size_t length); +extern int memcmp(const void *m1, const void *m2, size_t n); +extern int memcpy(void *dst0, const void *src0, size_t len0); +extern int memmove(void *dst_void, const void *src_void, size_t length); +extern int memset(void *m, int c, size_t n); +extern char * strcat(char *s1, const char *s2); +extern char * strchr(const char *s1, int i); +extern int strcmp(const char *s1, const char *s2); +extern char * strcpy(char *dst0, const char *src0); +extern int strlen(const char *str); +extern char * strncat(char *s1, const char *s2, size_t n); +extern int strncmp(const char *s1, const char *s2, size_t n); +extern char * strncpy(char *dst0, const char *src0, size_t count); +extern char * strstr(const char *searchee, const char *lookfor); +extern char * strsep(char **source_ptr, const char *delim); +extern char * strtok(char *s, const char *delim); +extern int sscanf(const char *buf, const char *fmt, ...); +extern char toupper(char ch); +extern int _stricmp (const char *s1, const char *s2); +extern unsigned long long __aeabi_llsr(unsigned long long val, unsigned int shift); +#endif + +#endif // _INC_RTL_LIBC_ diff --git a/project/inc/tcpsrv/tcp_srv_conn.h b/project/inc/tcpsrv/tcp_srv_conn.h new file mode 100644 index 0000000..4468e0f --- /dev/null +++ b/project/inc/tcpsrv/tcp_srv_conn.h @@ -0,0 +1,191 @@ +#ifndef __TCP_SERV_CONN_H__ +/*********************************** + * FileName: tcp_srv_conn.h + * Tcp сервачек для ESP8266 + * PV` ver1.0 20/12/2014 + * PV` ver1.0 29/10/2016 для RTL87xx + ***********************************/ +#define __TCP_SERV_CONN_H__ + +//#include "user_interface.h" +//#include "os_type.h" + +#include "lwip/err.h" + +#define mMIN(a, b) ((a < b)? a : b) + +enum srvconn_state { + SRVCONN_NONE =0, + SRVCONN_CLOSEWAIT, // ожидает закрытия + SRVCONN_CLIENT, // установка соединения (клиент) + SRVCONN_LISTEN, // соединение открыто, ждет rx или tx + SRVCONN_CONNECT, // соединение открыто, было rx или tx + SRVCONN_CLOSED // соединение закрыто +}; + +// приоритет pcb 1..127 1 - min, 127 - max +#ifndef TCP_SRV_PRIO +#define TCP_SRV_PRIO 99 //TCP_PRIO_MIN +#endif + +// максимальное кол-во TCP c TIME_WAIT +#ifndef MAX_TIME_WAIT_PCB +#define MAX_TIME_WAIT_PCB 10 +#endif + +// кол-во одновременно открытых соединений по умолчанию +#ifndef TCP_SRV_MAX_CONNECTIONS + #define TCP_SRV_MAX_CONNECTIONS mMIN(MEMP_NUM_TCP_PCB, 10) +#endif + +// порт сервера по умолчанию +#ifndef TCP_SRV_SERVER_PORT + #define TCP_SRV_SERVER_PORT 80 +#endif + +/* уровень вывода отладочной инфы по умолчанию +#ifndef DEBUGSOO + #define DEBUGSOO 2 +#endif +*/ + +// время (сек), по умолчанию, ожидания запроса (передачи пакета) от клиента, до авто-закрытия соединения, +// при = 0 заменяется на эти 5 сек. +#ifndef TCP_SRV_RECV_WAIT + #define TCP_SRV_RECV_WAIT 5 +#endif +// время (сек), по умолчанию, до авто-закрытия соединения после приема или передачи, +// при = 0 заменяется на эти 5 сек. +#ifndef TCP_SRV_END_WAIT + #define TCP_SRV_END_WAIT 5 +#endif + +// время (в сек) до повтора закрытия соединения (исполняется до 3-х раз). +#define TCP_SRV_CLOSE_WAIT 5 // 5 сек + +// минимальный размер heap по умолчанию, при открытии нового соединения, при = 0 заменяется на это: +#define TCP_SRV_MIN_HEAP_SIZE 14528 // самый минимум от 6Kb + +// максимальный размер выделяемого буфера в heap для приема порции +#ifndef TCP_SRV_SERVER_MAX_RXBUF + #define TCP_SRV_SERVER_MAX_RXBUF (TCP_MSS*3) // 1460*2=2920, 1460*3=4380, 1460*4=5840 +#endif + +// размер выделяемого буфера в heap для передачи при буферизированном выводе +#ifndef TCP_SRV_SERVER_DEF_TXBUF + #define TCP_SRV_SERVER_DEF_TXBUF (TCP_MSS*3) // 1460*2=2920, 1460*3=4380, 1460*4=5840 +#endif + +#define ID_CLIENTS_PORT 3 // до 3-х clients +#define tcpsrv_init_client1() tcpsrv_init(1) // tcp2uart_client +#define tcpsrv_init_client2() tcpsrv_init(2) // mdb_tcp_client +#define tcpsrv_init_client3() tcpsrv_init(3) + +#define TCP_CLIENT_NEXT_CONNECT_S 5 // syscfg.tcp_client_twait // 5000 // через 5 сек +#define TCP_CLIENT_MAX_CONNECT_RETRY 7 // до 7 раз с интервалом TCP_CLIENT_NEXT_CONNECT_MS + +//-------------------------------------------------------------------------- +// Структура соединения +// +typedef struct t_tcpsrv_conn_flags { + uint16 client: 1; //0001 данное соединение не сервер, а клиент! + uint16 client_reconnect: 1; //0002 вечный реконнект + uint16 srv_reopen: 1; //0004 открытие нового соединения более max_conn ведет к закрытию наиболее старого соединения. + uint16 pcb_time_wait_free: 1; //0008 проверка на макс кол-во и уничтожение pcb с TIME_WAIT при вызове disconnect() (иначе pcb TIME_WAIT 60 сек http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html) + uint16 nagle_disabled: 1; //0010 выключение nagle + uint16 rx_buf: 1; //0020 прием в буфер, используется ручное управление размером окна TCP + uint16 rx_null: 1; //0040 отключение вызова func_received_data() и прием в null (устанавливается автоматически при вызове tcpsrv_disconnect()) + uint16 tx_null: 1; //0080 отключение вызова func_sent_callback() и передача в null (устанавливается автоматически при вызове tcpsrv_disconnect()) + uint16 wait_sent: 1; //0100 ожидет завершения/подтверждения передачи от lwip + uint16 busy_bufo: 1; //0200 идет обработка bufo + uint16 busy_bufi: 1; //0400 идет обработка bufi + // далее идут биты не относящиеся к работе tcp_srv_conn + uint16 user_flg1: 1; //0800 для нужд процедур уровнем выше (использован в tcp2uart.c) + uint16 user_flg2: 1; //1000 для нужд процедур уровнем выше (пока свободен) + uint16 user_option1: 1; //2000 для нужд процедур обработки переменных (использован для hexdump, xml_mdb в web_int_callbacks.c) + uint16 user_option2: 1; //4000 для нужд процедур обработки переменных (использован для xml_mdb в web_int_callbacks.c) +} __attribute__((packed)) tcpsrv_conn_flags; + +typedef struct t_TCP_SERV_CONN { + volatile tcpsrv_conn_flags flag;//+0 флаги соеднения + enum srvconn_state state; //+4 состояние + struct t_TCP_SERV_CFG *pcfg; //+8 указатель на базовую структуру сервера + uint16 recv_check; //+12 счет тиков соединения в tcpsrv_poll + uint16 remote_port; //+16 номер порта клиента + union { //+20 ip клиента + uint32 dw; + uint8 b[4]; + } remote_ip; + struct t_TCP_SERV_CONN *next; //+24 указатель на следующую структуру + struct tcp_pcb *pcb; //+28 указатель на pcb в Lwip + uint8 *pbufo; //+32 указатель на сегмент с передаваемыми данными + uint8 *ptrtx; //+36 указатель на ещё не переданные данные + uint8 *pbufi; //+40 указатель на сегмент буфера с принимаемыми данными + uint16 sizeo; //+44 размер буфера передачи + uint16 sizei; //+48 размер приемного буфера (кол-во принятых и ещё не обработанных байт) + uint16 cntro; //+52 кол-во обработанных байт в буфере передачи + uint16 cntri; //+56 кол-во обработанных байт в буфере приема + uint16 unrecved_bytes; //+60 используется при ручном управлении TCP WIN / This can be used to throttle data reception + // далее идут переменные не относящиеся к работе tcp_srv_conn + uint8 *linkd; //+64 указатель на прилепленные данные пользователя (при закрытии соединения вызывается os_close(linkd), если linkd != NULL; +} TCP_SERV_CONN; + + +//-------------------------------------------------------------------------- +// Вызываемые функции пользователя (calback-и) +// +typedef void (*func_disconect_calback)(TCP_SERV_CONN *ts_conn); // соединение закрыто +typedef err_t (*func_listen)(TCP_SERV_CONN *ts_conn); // новый клиент +typedef err_t (*func_received_data)(TCP_SERV_CONN *ts_conn); // принято всего ts_conn->sizei байт, лежат в буфере по ts_conn->pbufi, по выходу принимается обработанных ts_conn->cntri; +typedef err_t (*func_sent_callback)(TCP_SERV_CONN *ts_conn); // блок данных передан + +//-------------------------------------------------------------------------- +// Структура конфигурации tcp сервера +// +typedef struct t_TCP_SERV_CFG { + struct t_tcpsrv_conn_flags flag; // начальные флаги для соединения + uint16 port; // номер порта (=1 - client) + uint16 max_conn; // максимальное кол-во одновременных соединений, если client = кол-во повторов соединения + uint16 conn_count; // кол-во текущих соединений, при инициализации прописывает 0, если client = счетчик повторов соединения + uint16 min_heap; // минимальный размер heap при открытии нового соединения, при = 0 заменяется на 8192. + uint16 time_wait_rec; // время (сек) ожидания запроса (передачи пакета) от клиента, до авто-закрытия соединения, по умолчанию TCP_SRV_RECV_WAIT сек. + uint16 time_wait_cls; // время (сек) до авто-закрытия соединения после приема или передачи, по умолчанию TCP_SRV_END_WAIT сек. + TCP_SERV_CONN * conn_links; // указатель на цепочку активных соединений, при инициализации или отсуствии активных соединений = NULL + struct tcp_pcb *pcb; // начальный pcb [LISTEN] если сервер, иначе NULL + func_disconect_calback func_discon_cb; // функция вызываемая после закрытия соединения, если = NULL - не вызывается + func_listen func_listen; // функция вызываемая при присоединении клиента или коннекта к серверу, если = NULL - не вызывается + func_sent_callback func_sent_cb; // функция вызываемая после передачи данных или наличию места в ip стеке для следушей передачи данных, если = NULL - не вызывается (+см. флаги) + func_received_data func_recv; // функция вызываемая при приеме данных, если = NULL - не вызывается (+см. флаги) + struct t_TCP_SERV_CFG *next; // следующий экземпляр структуры сервера/клиента +}TCP_SERV_CFG; +//-------------------------------------------------------------------------- +// Данные +// +extern TCP_SERV_CFG *phcfg; // указатель на цепочку TCP_SERV_CFG (стартовавших серверов) +//-------------------------------------------------------------------------- +// Функции +// +err_t tcpsrv_int_sent_data(TCP_SERV_CONN * ts_conn, uint8 *psent, uint16 length); // передать length байт (внутрення функция - никаких проверок) +void tcpsrv_disconnect(TCP_SERV_CONN * ts_conn); // закрыть соединение +void tcpsrv_print_remote_info(TCP_SERV_CONN *ts_conn); // выводит remote_ip:remote_port [conn_count] os_printf("srv x.x.x.x:x [n] ") +TCP_SERV_CFG * tcpsrv_server_port2pcfg(uint16 portn); // поиск структуры конфига по номеру порта +TCP_SERV_CFG * tcpsrv_client_ip_port2conn(uint32 ip, uint16 portn); // поиск структуры конфига по номеру порта для клиента +void tcpsrv_unrecved_win(TCP_SERV_CONN *ts_conn); // Восстановить размер TCP WIN, если используется ручное управление размером окна TCP + +void tcpsrv_disconnect_calback_default(TCP_SERV_CONN *ts_conn); +err_t tcpsrv_listen_default(TCP_SERV_CONN *ts_conn); +err_t tcpsrv_sent_callback_default(TCP_SERV_CONN *ts_conn); +err_t tcpsrv_received_data_default(TCP_SERV_CONN *ts_conn); + +TCP_SERV_CFG *tcpsrv_init(uint16 portn); +err_t tcpsrv_start(TCP_SERV_CFG *p); +err_t tcpsrv_client_start(TCP_SERV_CFG * p, uint32 remote_ip, uint16 remote_port); +err_t tcpsrv_close(TCP_SERV_CFG *p); +err_t tcpsrv_close_port(uint16 portn); +err_t tcpsrv_close_all(void); + +char * tspsrv_error_msg(err_t err); +char * tspsrv_tcp_state_msg(enum tcp_state state); +char * tspsrv_srvconn_state_msg(enum srvconn_state state); + +#endif // __TCP_SERV_CONN_H__ diff --git a/project/inc/user/main.h b/project/inc/user/main.h new file mode 100644 index 0000000..d3cdef6 --- /dev/null +++ b/project/inc/user/main.h @@ -0,0 +1,68 @@ +#ifndef MAIN_H +#define MAIN_H + +#include + +#ifndef CONFIG_WLAN +#define CONFIG_WLAN 1 +#endif + +/* Header file declaration*/ +void wlan_network(); + +/* Interactive Mode */ +#define SERIAL_DEBUG_RX 1 + + +#define ATVER_1 1 // For First AT command +#define ATVER_2 2 // For UART Module AT command + +#if CONFIG_EXAMPLE_UART_ATCMD +#define ATCMD_VER ATVER_2 +#else +#define ATCMD_VER ATVER_1 +#endif + + + +/*Static IP ADDRESS*/ +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 3 +#define IP_ADDR3 80 + +/*NETMASK*/ +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 + +/*Gateway Address*/ +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 3 +#define GW_ADDR3 1 + +/*******************************************/ + +/*Static IP ADDRESS*/ +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 + +/*NETMASK*/ +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 + +/*Gateway Address*/ +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 + + + +#endif diff --git a/project/inc/user/sys_cfg.h b/project/inc/user/sys_cfg.h new file mode 100644 index 0000000..7b9117e --- /dev/null +++ b/project/inc/user/sys_cfg.h @@ -0,0 +1,64 @@ +/* + * sys_cfg.h + * + * Created on: 17/04/17 + * Author: pvvx + */ +#ifndef __SYS_CFG_H__ +#define __SYS_CFG_H__ +#include "user_config.h" +#define FEEP_ID_SYS_CFG 0x5359 + +struct sys_bits_config { + uint16 hi_speed_enable : 1; //0 0x0000001 =1 Set CPU 160 MHz ... + uint16 pin_clear_cfg_enable : 1; //1 0x0000002 =1 Проверять ножку RX на сброс конфигурации WiFi + uint16 debug_print_enable : 1; //2 0x0000004 =1 Вывод отладочной информации на GPIO2 + uint16 web_time_wait_delete : 1; //3 0x0000008 =1 Закрывать соединение и убивать pcb c TIME_WAIT + uint16 netbios_ena : 1; //4 0x0000010 =1 включить NetBios + uint16 sntp_ena : 1; //5 0x0000020 =1 включить SNTP + uint16 cdns_ena : 1; //6 0x0000040 =1 включить CAPDNS + uint16 tcp2uart_reopen : 1; //7 0x0000080 =1 открытие нового соединения tcp2uart ведет к закрытию старого соединения (в режиме tcp2uart = сервер) + uint16 mdb_reopen : 1; //8 0x0000100 =1 открытие нового соединения modbus ведет к закрытию старого соединения (в режиме modbus = сервер) +}; + +#define SYS_CFG_HI_SPEED 0x0000001 // Set CPU 160 MHz ... +#define SYS_CFG_PIN_CLR_ENA 0x0000002 // Проверять ножку RX на сброс конфигурации WiFi +#define SYS_CFG_DEBUG_ENA 0x0000004 // Вывод отладочной информации на GPIO2 +#define SYS_CFG_TWPCB_DEL 0x0000008 // Закрывать соединение и убивать pcb c TIME_WAIT +#define SYS_CFG_NETBIOS_ENA 0x0000010 // включить NetBios +#define SYS_CFG_SNTP_ENA 0x0000020 // включить SNTP +#define SYS_CFG_CDNS_ENA 0x0000040 // включить CAPDNS +#define SYS_CFG_T2U_REOPEN 0x0000080 // открытие нового соединения tcp2uart ведет к закрытию старого соединения (сервер) +#define SYS_CFG_MDB_REOPEN 0x0000100 // открытие нового соединения modbus ведет к закрытию старого соединения (сервер) + + +struct SystemCfg { // структура сохранения системных настроек в Flash + union { + struct sys_bits_config b; + uint16 w; + }cfg; + uint16 tcp_client_twait; // время (миллисек) до повтора соединения клиента +#ifdef USE_TCP2UART + uint16 tcp2uart_port; // номер порта TCP-UART (=0 - отключен) + uint16 tcp2uart_twrec; // время (сек) стартового ожидания приема/передачи первого пакета, до авто-закрытия соединения + uint16 tcp2uart_twcls; // время (сек) до авто-закрытия соединения после приема или передачи +#endif +#ifdef USE_WEB + uint16 web_port; // номер порта WEB (=0 - отключен) + uint16 web_twrec; // время (сек) стартового ожидания приема/передачи первого пакета, до авто-закрытия соединения + uint16 web_twcls; // время (сек) до авто-закрытия соединения после приема или передачи +#endif +#ifdef USE_MODBUS + uint16 mdb_port; // =0 - отключен + uint16 mdb_twrec; // время (сек) стартового ожидания приема/передачи первого пакета, до авто-закрытия соединения + uint16 mdb_twcls; // время (сек) до авто-закрытия соединения после приема или передачи + uint8 mdb_id; // номер устройства ESP8266 по шине modbus +#endif +} __attribute__((packed)); + + +extern void sys_write_cfg(void); + +extern struct SystemCfg syscfg; + +#endif // #define __SYS_CFG_H__ diff --git a/project/inc/user_config.h b/project/inc/user_config.h new file mode 100644 index 0000000..d628f15 --- /dev/null +++ b/project/inc/user_config.h @@ -0,0 +1,34 @@ +#ifndef _user_config_h_ +#define _user_config_h_ + +//#include "sdk/sdk_config.h" + +#define SYS_VERSION "1.0.0" +#define SDK_VERSION "3.5.3" + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Конфигурация для проекта MODBUS-RS-485 +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#define USE_WEB 80 // включить в трансялцию порт Web, если =0 - по умолчанию выключен +#define WEBSOCKET_ENA 1 // включить WEBSOCKET + +//#define USE_CPU_SPEED 166 // установить частоту CPU (по умолчанию 83) +/* +#define USE_NETBIOS 1 // включить в трансялцию драйвер NETBIOS, если =0 - по умолчанию выключен. + +#define USE_SNTP 1 // включить в трансялцию драйвер SNTP, если =0 - по умолчанию выключен, = 1 - по умолчанию включен. + +#define USE_RS485DRV // использовать RS-485 драйвер +#define MDB_RS485_MASTER // Modbus RTU RS-485 master & slave +#define USE_MODBUS 502 // включить в трансялцию Modbus TCP, если =0 - по умолчанию выключен +#define MDB_ID_ESP 50 // номер устройства RTL на шине modbus + +//#define USE_CAPTDNS 0 // включить в трансялцию DNS отвечающий на всё запросы клиента при соединении к AP модуля + // указанием на данный WebHttp (http://aesp8266/), если =0 - по умолчанию выключен + +*/ + +#endif // _user_config_h_ + + diff --git a/project/inc/web/web_srv.h b/project/inc/web/web_srv.h new file mode 100644 index 0000000..0126cec --- /dev/null +++ b/project/inc/web/web_srv.h @@ -0,0 +1,196 @@ +/* + * File: web_srv.h + * Description: The web server configration. + * Small WEB server ESP8266EX + * Author: PV` + */ + +#ifndef _INCLUDE_WEB_SRV_H_ +#define _INCLUDE_WEB_SRV_H_ + +#include "tcpsrv/tcp_srv_conn.h" +#ifdef WEBSOCKET_ENA +#include "websock.h" +#endif + +#define WEB_SVERSION "0.2.0" +#define DEFAULT_WEB_PORT USE_WEB // 80 + +/**************************************************************************** + Section: + Commands and Server Responses + ***************************************************************************/ + +// File type definitions +typedef enum +{ + HTTP_TXT = 0, // File is a text document + HTTP_HTML, // File is HTML (extension .htm) + HTTP_CGI, // File is HTML (extension .cgi) + HTTP_XML, // File is XML (extension .xml) + HTTP_CSS, // File is stylesheet (extension .css) + HTTP_ICO, // File is ICO vnd.microsoft.icon + HTTP_GIF, // File is GIF image (extension .gif) + HTTP_PNG, // File is PNG image (extension .png) + HTTP_JPG, // File is JPG image (extension .jpg) + HTTP_SVG, // File is SVG image (extension .svg) + HTTP_JAVA, // File is java (extension .js) + HTTP_SWF, // File is ShockWave-Flash (extension .swf) + HTTP_WAV, // File is audio (extension .wav) + HTTP_PDF, // File is PDF (extension .pdf) + HTTP_ZIP, // File is ZIP (extension .zip) + HTTP_BIN, // File is BIN (extension .bin) + HTTP_UNKNOWN // File type is unknown +} HTTP_FILE_TYPE; + + +// extended state data for each connection +#define FileNameSize 64 +#define VarNameSize 64 +#define CmdNameSize 32 + +typedef struct +{ + uint16 httpStatus; // Request method/status + uint16 uri_len; + uint16 head_len; + uint16 cookie_len; + uint8 pFilename[FileNameSize]; + uint8 *puri; // указатель на строку с переменными запроса к файлу + uint8 *phead; // HTTP Headers + uint8 *pcookie; // cookie + uint8 *pcontent; // content + uint32 content_len; // + uint8 httpver; // версия HTTP клиента в BCD (0x00 = неизвестен; 0x09 = HTTP/0.9; 0x10 = HTTP/1.0; 0x11 = HTTP/1.1) + uint8 fileType; // File type to return with Content-Type +} HTTP_CONN; + + +typedef void (* web_func_cb)(TCP_SERV_CONN *ts_conn); +typedef uint32 (* web_func_disc_cb)(uint32 flg); // отложенная функция, когда соединение закрыто + +typedef struct +{ + web_func_disc_cb fnk; + void * param; +} WEB_SRV_QFNK; + +typedef struct +{ + uint32 webflag; // флаги для http/web сервера + uint8 bffiles[4]; // четыре Files pointers для оработки вложенных файлов include + uint32 udata_start; // udata "start=0x..." + uint32 udata_stop; // udata "stop=0x..." + uint8 *msgbuf; // указатель на текущий буфер вывода + uint16 msgbuflen; // кол-во занятых байт в буфере msgbuf + uint16 msgbufsize; // размер буфера + web_func_cb func_web_cb; // calback функция у httpd для обработки приема/передачи кусками + uint32 content_len; // размер файла для передачи (GET/POST) или приема, если принимается внешний файл (POST + SCB_RXDATA) + web_func_disc_cb web_disc_cb; // функция вызываемая по закрытию соединения + uint32 web_disc_par; // параметры функции вызываемой по закрытию соединения +#ifdef WEBSOCKET_ENA + WS_FRSTAT ws; // параметры websoc +#endif + uint8 fileType; // File type to return with Content-Type (if SCB_FCALBACK) +} WEB_SRV_CONN; + +typedef enum +{ + WEBFS_MAX_HANDLE = 251, + WEBFS_NODISK_HANDLE, + WEBFS_WEBCGI_HANDLE, + WEBFS_UPLOAD_HANDLE +} WEBFS_NUM_HANDLE; + +// webflag: + +#define SCB_CLOSED 0x000001 // соединение закрыто +#define SCB_DISCONNECT 0x000002 // выход на DISCONNECT +#define SCB_FCLOSE 0x000004 // закрыть файлы +#define SCB_FOPEN 0x000008 // файл(ы) открыт(ы) +#define SCB_FCALBACK 0x000010 // file use ~calback~ +#define SCB_FGZIP 0x000020 // файл GZIP +#define SCB_CHUNKED 0x000040 // передача шинковкой +#define SCB_RETRYCB 0x000080 // вызвать повтор CalBack +#define SCB_POST 0x000100 // POST +#define SCB_GET 0x000200 // GET +#define SCB_AUTH 0x000400 // необходима авторизация +#define SCB_FINDCB 0x000800 // используется парсингом ~calback~ +#define SCB_RXDATA 0x001000 // прием данных (файла) +#define SCB_HEAD_OK 0x002000 // заголовок HTTP принят и обработан +#define SCB_BNDR 0x004000 // прилеплен Content-Type: multipart/form-data; boundary="..." +#define SCB_REDIR 0x008000 // Redirect 302 +#define SCB_WEBSOC 0x010000 // WebSocket +#define SCB_WSDATA 0x020000 // WebSocket data +#define SCB_SYSSAVE 0x040000 // по закрытию соединения вызвать sys_write_cfg() + + +#define SCB_OPEN 0 + +#define SetSCB(a) web_conn->webflag |= a +#define FreeSCB() web_conn->webflag = SCB_FREE +#define SetNextFunSCB(a) web_conn->func_web_cb = a +#define ClrSCB(a) web_conn->webflag &= ~(a) +#define CheckSCB(a) (web_conn->webflag & (a)) + +#define FreeSCB() web_conn->webflag = SCB_FREE +#define OpenSCB() web_conn->webflag = SCB_OPEN + +#define MAXLENBOUNDARY 64 +typedef struct s_http_upload +{ + uint16 status; + uint16 sizeboundary; + uint8 boundary[MAXLENBOUNDARY+1]; + uint8 name[VarNameSize]; + uint8 filename[VarNameSize]; +#ifdef USE_OVERLAY + uint32 segs; // кол-во сегментов оверлея // пока в web_conn->web_disc_par + uint32 start; // адрес запуска оверлея +#endif + uint32 fsize; + uint32 faddr; + uint8 *pbndr; + uint8 *pnext; +} HTTP_UPLOAD; + +typedef struct s_http_response +{ + uint32 status; + uint32 flag; + const char * headers; + const char * default_content; +} HTTP_RESPONSE; + +// HTTP_RESPONSE.flags: +#define HTTP_RESP_FLG_END 0x8000 +#define HTTP_RESP_FLG_NONE 0x0000 +#define HTTP_RESP_FLG_FINDFILE 0x0001 +#define HTTP_RESP_FLG_REDIRECT 0x0002 + +#define tcp_put(a) web_conn->msgbuf[web_conn->msgbuflen++] = a +#define tcp_htmlstrcpy(str, len) web_conn->msgbuflen += htmlcode(&web_conn->msgbuf[web_conn->msgbuflen], str, web_conn->msgbufsize - web_conn->msgbuflen - 1, len) +//#define tcp_urlstrcpy(str, len) web_conn->msgbuflen += urlencode(&web_conn->msgbuf[web_conn->msgbuflen], str, web_conn->msgbufsize - web_conn->msgbuflen - 1, len) +#define tcp_puts(...) web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], __VA_ARGS__) +#define tcp_puts_fd(...) web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], __VA_ARGS__) +/* +#define tcp_puts_fd(fmt, ...) do { \ + static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \ + web_conn->msgbuflen += rtl_sprintf((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)flash_str, ##__VA_ARGS__); \ + } while(0) +*/ +//#define tcp_strcpy(a) web_conn->msgbuflen += ets_strlen((char *)ets_strcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)a)) +#define tcp_strcpy(a) web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (const char *)a) +#define tcp_strcpy_fd(a) web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (const char *)a) +/* +#define tcp_strcpy_fd(fmt) do { \ + static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \ + web_conn->msgbuflen += rom_xstrcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], (char *)flash_str); \ + } while(0) +*/ +uint32 ahextoul(uint8 *s); +err_t webserver_init(uint16 portn); +err_t webserver_close(uint16 portn); +err_t webserver_reinit(uint16 portn); + +#endif /* _INCLUDE_WEB_SRV_H_ */ diff --git a/project/inc/web/web_srv_int.h b/project/inc/web/web_srv_int.h new file mode 100644 index 0000000..8606dc0 --- /dev/null +++ b/project/inc/web/web_srv_int.h @@ -0,0 +1,49 @@ +/* + * File: web_srv_int.h + * Description: The web server configration. + * Small WEB server ESP8266EX + * + * Author: PV` 12/2014 + */ + +#ifndef _INCLUDE_WEB_SRV_INT_H_ +#define _INCLUDE_WEB_SRV_INT_H_ + +#include "web_srv.h" + +#define WEB_NAME_VERSION "PVs/0.2" + +// #define WEBSOCKET_ENA 1 + +// lifetime (sec) of static responses as string 60*60*24*14=1209600" +#define FILE_CACHE_MAX_AGE_SEC 3600 // время для кеша файлов, ставить 0 пока тест! + +#define MAX_HTTP_HEAD_BUF 3070 // максимальный размер HTTP запроса (GET) + +#define RESCHKS_SEND_SIZE 16 +#define RESCHKE_SEND_SIZE 8 +#define RESCHK_SEND_SIZE (RESCHKS_SEND_SIZE + RESCHKE_SEND_SIZE) + +#define MIN_SEND_SIZE (256 + RESCHK_SEND_SIZE) // минимальный размер буфера для передачи файла +#define MAX_SEND_SIZE ((TCP_MSS*4) + RESCHK_SEND_SIZE) // максимальный размер буфера для передачи 4*MSS = 5840 (MSS=1460) + +#define HTTP_SEND_SIZE 384 // минимальный размер буфера для передачи заголовка HTTP +#define SCB_SEND_SIZE 128 // минимальный резерв в буфере для callback + +#define webfile bffiles[0] // File pointer for main file + +//----------------------------------------------------------------------------- + +void web_int_vars(TCP_SERV_CONN *ts_conn, uint8 *pcmd, uint8 *pvar); +void web_int_cookie(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn); +void web_int_callback(TCP_SERV_CONN *ts_conn, uint8 *cstr); + +void web_hexdump(TCP_SERV_CONN *ts_conn); +bool web_inc_fopen(TCP_SERV_CONN *ts_conn, uint8 *cFile); +bool web_inc_fclose(WEB_SRV_CONN *web_conn); + +bool web_trim_bufi(TCP_SERV_CONN *ts_conn, uint8 *pdata, uint32 data_len); +bool web_feee_bufi(TCP_SERV_CONN *ts_conn); +//uint8 * head_find_ctr(HTTP_CONN *CurHTTP, const uint8 * c, int clen, int dlen); + +#endif /* _INCLUDE_WEB_SRV_INT_H_ */ diff --git a/project/inc/web/web_utils.h b/project/inc/web/web_utils.h new file mode 100644 index 0000000..b96d1c1 --- /dev/null +++ b/project/inc/web/web_utils.h @@ -0,0 +1,33 @@ + /****************************************************************************** + * FileName: web_utils.h + * Alternate SDK + * Author: PV` + * (c) PV` 2015 +*******************************************************************************/ + +#ifndef _INCLUDE_WEB_UTILS_H_ +#define _INCLUDE_WEB_UTILS_H_ + +int rom_atoi(const char *s); +void copy_align4(void *ptrd, void *ptrs, uint32 len); +uint32 hextoul(uint8 *s); +uint32 ahextoul(uint8 *s); +uint8 * cmpcpystr(uint8 *pbuf, uint8 *pstr, uint8 a, uint8 b, uint16 len); +uint8 * web_strnstr(const uint8* buffer, const uint8* token, int n); +bool base64decode(const uint8 *in, int len, uint8_t *out, int *outlen); +size_t base64encode(char* target, size_t target_len, const char* source, size_t source_len); +void strtomac(uint8 *s, uint8 *macaddr); +//uint32 strtoip(uint8 *s); // ipaddr_addr(); +int urldecode(uint8 *d, uint8 *s, uint16 lend, uint16 lens); +//int urlencode(uint8 *d, uint8 *s, uint16 lend, uint16 lens); +int htmlcode(uint8 *d, uint8 *s, uint16 lend, uint16 lens); +void print_hex_dump(uint8 *buf, uint32 len, uint8 k); +// char* str_to_upper_case(char* text); +uint32 str_array(uint8 *s, uint32 *buf, uint32 max_buf); +uint32 str_array_w(uint8 *s, uint16 *buf, uint32 max_buf); +uint32 str_array_b(uint8 *s, uint8 *buf, uint32 max_buf); +char* word_to_lower_case(char* text); +int rom_xstrcmp(char * pd, const char * ps); +int rom_xstrcpy(char * pd, const char * ps); + +#endif /* _INCLUDE_WEB_UTILS_H_ */ diff --git a/project/inc/web/web_websocket.h b/project/inc/web/web_websocket.h new file mode 100644 index 0000000..bb4c4cc --- /dev/null +++ b/project/inc/web/web_websocket.h @@ -0,0 +1,17 @@ +#ifndef _WEB_WEBSOCKET_H_ +/****************************************************************************** + * FileName: web_websocket.h + * Description: websocket for web ESP8266 + * Author: PV` + * (c) PV` 2016 +*******************************************************************************/ +#define _WEB_WEBSOCKET_H_ +#include "user_config.h" +#ifdef WEBSOCKET_ENA +#include "websock.h" + +err_t websock_tx_close_err(TCP_SERV_CONN *ts_conn, uint32 err); +bool websock_rx_data(TCP_SERV_CONN *ts_conn); + +#endif // WEBSOCKET_ENA +#endif /* _WEB_WEBSOCKET_H_ */ diff --git a/project/inc/web/websock.h b/project/inc/web/websock.h new file mode 100644 index 0000000..969837e --- /dev/null +++ b/project/inc/web/websock.h @@ -0,0 +1,108 @@ +/* + * File: websock.h + * Small WEB server ESP8266EX + * Author: PV` + */ + +#ifndef _WEBSOCK_H_ +#define _WEBSOCK_H_ + +//#define WS_NONBLOCK 0x02 + +/* + 0 1 2 3 + 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 + +-+-+-+-+-------+-+-------------+-------------------------------+ + |F|R|R|R| опкод |М| Длина тела | Расширенная длина тела | + |I|S|S|S|(4бита)|А| (7бит) | (2 байта) | + |N|V|V|V| |С| |(если длина тела==126 или 127) | + | |1|2|3| |К| | | + | | | | | |А| | | + +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + |4 5 6 7 | + | Продолжение расширенной длины тела, если длина тела = 127 | + + - - - - - - - - - - - - - - - +-------------------------------+ + |8 9 10 11 | + | | Ключ маски, если МАСКА = 1 | + +-------------------------------+-------------------------------+ + |12 13 14 15 | + | Ключ маски (продолжение) | Данные фрейма ("тело") | + +-------------------------------- - - - - - - - - - - - - - - - + + |16 17 18 19 | + : Данные продолжаются ... : + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + | Данные продолжаются ... | + +---------------------------------------------------------------+ + +*/ + +#define WS_FRAGMENT_FIN 0x80 +//#define WS_RSVD_BITS (7 << 4) +#define WS_OPCODE_BITS 0x7F +#define WS_OPCODE_CONTINUE 0x0 // фрейм-продолжение для фрагментированного сообщения +#define WS_OPCODE_TEXT 0x1 // текстовый фрейм +#define WS_OPCODE_BINARY 0x2 // двоичный фрейм +#define WS_OPCODE_CLOSE 0x8 // закрытие соединения +#define WS_OPCODE_PING 0x9 +#define WS_OPCODE_PONG 0xa +#define WS_MASK_FLG (1 << 7) +#define WS_SIZE1_BITS 0x7F + + +#define WS_CLOSE_NORMAL 1000 +#define WS_CLOSE_GOING_AWAY 1001 +#define WS_CLOSE_PROTOCOL_ERROR 1002 +#define WS_CLOSE_NOT_ALLOWED 1003 +#define WS_CLOSE_RESERVED 1004 +#define WS_CLOSE_NO_CODE 1005 +#define WS_CLOSE_DIRTY 1006 +#define WS_CLOSE_WRONG_TYPE 1007 +#define WS_CLOSE_POLICY_VIOLATION 1008 +#define WS_CLOSE_MESSAGE_TOO_BIG 1009 +#define WS_CLOSE_UNEXPECTED_ERROR 1011 + +typedef struct _WS_FRSTAT +{ + uint32 frame_len; // размер данных в заголовке фрейма + uint32 cur_len; // счетчик обработанных данных + union { + unsigned char uc[4]; + unsigned int ud; + } mask; // маска принимаемых данных + uint8 status; + uint8 flg; + uint8 head_len; +} WS_FRSTAT; // __attribute__((packed)) + +#define WS_FLG_MASK 0x01 +#define WS_FLG_FIN 0x02 +#define WS_FLG_CLOSE 0x04 // уже передано WS_CLOSE + +enum WS_FRAME_STATE { + sw_frs_none = 0, + sw_frs_text, + sw_frs_binary, + sw_frs_close, + sw_frs_ping, + sw_frs_pong +}; + +extern const uint8 WebSocketHTTPOkKey[]; // ICACHE_RODATA_ATTR = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:%s\r\n\r\n" +extern const uint8 WebSocketAddKey[]; // ICACHE_RODATA_ATTR = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; +#define sizeWebSocketAddKey 36 +#define maxsizeWebSocketKey 64 +#define minsizeWebSocketKey 8 +extern const uint8 *HTTPUpgrade; // = "Upgrade:"; +#define sizeHTTPUpgrade 8 +extern const uint8 *HTTPwebsocket; // = "websocket"; +#define sizeHTTPwebsocket 9 +extern const uint8 *HTTPSecWebSocketKey; // = "Sec-WebSocket-Key:"; +#define sizeHTTPSecWebSocketKey 18 + + +bool WebSocketAcceptKey(uint8* dkey, uint8* skey); +void WebsocketMask(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len); +uint32 WebsocketHead(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len); +err_t WebsocketTxFrame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len); + +#endif /* _WEBSOCK_H_ */ diff --git a/project/inc/webfs/webfs.h b/project/inc/webfs/webfs.h new file mode 100644 index 0000000..d7c6c23 --- /dev/null +++ b/project/inc/webfs/webfs.h @@ -0,0 +1,116 @@ +/********************************************************************* + * + * FileName: WEBFS.h + * Basis of MPFS2 (Microchip File System). + * WEBFS has its differences Based. + * + ********************************************************************/ +#ifndef __WEBFS1_H +#define __WEBFS1_H + +#include "flash_eep.h" + +extern uint32 _irom0_text_end; + +#define WEBFS_DISK_FADDR 0x0D0000 + +#define WEBFS_DISK_ID 0x42455746 // заголовок WEBFiles.bin +#define WEBFS_DISK_VER 0x0001 // версия + +#define MAX_FILE_NAME_SIZE 64 + +#ifndef MAX_WEBFS_OPENFILES + #define MAX_WEBFS_OPENFILES 31 +#endif + + #define WEBFS_FLAG_ISZIPPED 0x0001 // Indicates a file is compressed with GZIP compression + #define WEBFS_FLAG_HASINDEX 0x0002 // Indicates a file has an associated index of dynamic variables + #define WEBFS_INVALID 0xffffffff // Indicates a position pointer is invalid + #define WEBFS_INVALID_FAT 0xffff // Indicates an invalid FAT cache + typedef uint32 WEBFS_PTR; // WEBFS Pointers are currently uint32s + typedef uint8 WEBFS_HANDLE; // WEBFS Handles are currently stored as uint8s + #define WEBFS_INVALID_HANDLE 0xff // Indicates that a handle is not valid + + + // Stores each file handle's information + // Handles are free when addr = WEBFS_INVALID + typedef struct + { + WEBFS_PTR addr; // Current address in the file system + uint32 bytesRem; // How many uint8s remain in this file +#ifdef USE_MAX_IRAM + uint32 fatID; // ID of which file in the FAT was accessed +#else + uint16 fatID; // ID of which file in the FAT was accessed +#endif + } WEBFS_STUB; + + // Indicates the method for WEBFSSeek + typedef enum + { + WEBFS_SEEK_START = 0, // Seek forwards from the front of the file + WEBFS_SEEK_END, // Seek backwards from the end of the file + WEBFS_SEEK_FORWARD, // Seek forward from the current position + WEBFS_SEEK_REWIND // See backwards from the current position + } WEBFS_SEEK_MODE; + + + typedef struct __attribute__((packed)) + { + uint32 id; + uint16 ver; + uint16 numFiles; + uint32 disksize; + } WEBFS_DISK_HEADER ; + + typedef struct __attribute__((packed)) + { + uint32 blksize; // Length of file data - headlen + uint16 headlen; // headlen (Length of File Name + 0) + uint16 flags; // Flags for this file + } WEBFS_FHEADER; + + // Stores the data for an WEBFS1 FAT record + typedef struct + { + uint32 string; // Pointer to the file name + uint32 data; // Address of the file data + uint32 len; // Length of file data +#ifdef USE_MAX_IRAM + uint32 flags; // Flags for this file +#else + uint16 flags; // Flags for this file +#endif + } WEBFS_FAT_RECORD ; + + +void WEBFSInit(void); +WEBFS_HANDLE WEBFSOpen(uint8* cFile); +void WEBFSClose(WEBFS_HANDLE hWEBFS); + +uint16 WEBFSGetArray(WEBFS_HANDLE hWEBFS, uint8* cData, uint16 wLen); + +uint16 WEBFSGetFlags(WEBFS_HANDLE hWEBFS); +uint32 WEBFSGetSize(WEBFS_HANDLE hWEBFS); +uint32 WEBFSGetBytesRem(WEBFS_HANDLE hWEBFS); +WEBFS_PTR WEBFSGetStartAddr(WEBFS_HANDLE hWEBFS); +WEBFS_PTR WEBFSGetEndAddr(WEBFS_HANDLE hWEBFS); +bool WEBFSGetFilename(WEBFS_HANDLE hWEBFS, uint8* cName, uint16 wLen); +uint32 WEBFSGetPosition(WEBFS_HANDLE hWEBFS); +uint32 WEBFS_max_size(void); +uint32 WEBFS_curent_size(void); +uint32 WEBFS_base_addr(void); + +#ifdef USE_MAX_IRAM +extern int isWEBFSLocked; // Lock WEBFS access during the upgrade +extern uint32 numFiles; +#else +extern volatile bool isWEBFSLocked; // Lock WEBFS access during the upgrade +extern uint16 numFiles; +#endif + +extern WEBFS_FAT_RECORD fatCache; +extern WEBFS_STUB WEBFSStubs[MAX_WEBFS_OPENFILES+1]; +extern uint32 disk_base_addr; + +#endif diff --git a/project/inc/wifi_user_set.h b/project/inc/wifi_user_set.h new file mode 100644 index 0000000..da9a4df --- /dev/null +++ b/project/inc/wifi_user_set.h @@ -0,0 +1,67 @@ +/* + * wifi_user_set.h + * + * Created on: 01/04/2017 + * Author: pvvx + */ + +#ifndef _WIFI_USER_SET_H_ +#define _WIFI_USER_SET_H_ + +//========================================= +//==== Wlan Config ======================== +#define DEF_WIFI_MODE RTW_MODE_STA // RTW_MODE_STA_AP, RTW_MODE_AP, RTW_MODE_STA +#define DEF_WIFI_AP_STATIONS 3 // Max number of STAs, should be 1..3, default is 3 +#define DEF_WIFI_COUNTRY RTW_COUNTRY_RU +#define DEF_WIFI_TX_PWR RTW_TX_PWR_PERCENTAGE_25 // RTW_TX_PWR_PERCENTAGE_75 // RTW_TX_PWR_PERCENTAGE_100 +#define DEF_WIFI_BGN RTW_NETWORK_BGN // rtw_network_mode_t +#define DEF_WIFI_ST_SLEEP 0 // 0 - none, 1 - on +//#define USE_NETBIOS 3 // 0 - off, 1 - ST, 2 - AP, 3 - AP+ST +#define DEF_LOAD_CFG ( 0 \ + | BID_WIFI_AP_CFG \ + | BID_WIFI_ST_CFG \ + | BID_AP_DHCP_CFG \ + | BID_ST_DHCP_CFG \ + | BID_WIFI_CFG \ +) +#define DEF_SAVE_CFG ( 0 \ + | BID_WIFI_AP_CFG \ + | BID_WIFI_ST_CFG \ + | BID_AP_DHCP_CFG \ + | BID_ST_DHCP_CFG \ + | BID_WIFI_CFG \ +) +//==== Interface 0 - wlan0 = AP =========== +#define DEF_AP_SSID "RTL871X" +#define DEF_AP_PASSWORD "0123456789" +#define DEF_AP_SECURITY RTW_SECURITY_WPA2_AES_PSK // RTW_SECURITY_OPEN, RTW_SECURITY_WEP_PSK +#define DEF_AP_BEACON 100 // 100...6000 ms +#define DEF_AP_CHANNEL 1 // 1..14 +#define DEF_AP_CHANNEL 1 // 1..14 +#define DEF_AP_DHCP_MODE 1 // =0 dhcp off, =1 - dhcp on +#define DEF_AP_IP IP4ADDR(192,168,4,1) +#define DEF_AP_MSK IP4ADDR(255,255,255,0) +#define DEF_AP_GW IP4ADDR(192,168,4,1) +#define DEF_AP_DHCP_START 2 +#define DEF_AP_DHCP_STOP 15 +//==== Interface 1 - wlan1 = STA ========== +#define DEF_ST_SSID "HOMEAP" +#define DEF_ST_PASSWORD "0123456789" +#define DEF_ST_SECURITY RTW_SECURITY_WPA_WPA2_MIXED +#define DEF_ST_BSSID { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } // If bssid set is not ff.ff.ff.ff.ff.ff, +// station will connect to the router with both ssid[] and bssid[] matched. +#define DEF_ST_CHANNEL 1 // 1..14 +#define DEF_ST_AUTORECONNECT 1 // 0 - none, 1..254 - count, 255 - all +#define DEF_ST_RECONNECT_PAUSE 1 // 5 sec +#define DEF_ST_DHCP_MODE 1 // =0 dhcp off, =1 - dhcp on, =2 Static ip, =3 - auto +#define DEF_ST_IP IP4ADDR(192,168,1,100) +#define DEF_ST_MSK IP4ADDR(255,255,255,0) +#define DEF_ST_GW IP4ADDR(192,168,1,1) +//==== Interface 2 - eth0 ================= +#define DEF_EH_DHCP_MODE 1 // =0 dhcp off, =1 - dhcp on +#define DEF_EH_IP IP4ADDR(192,168,7,200) +#define DEF_EH_MSK IP4ADDR(255,255,255,0) +#define DEF_EH_GW IP4ADDR(192,168,7,1) +//========================================= + +#endif /* _WIFI_USER_SET_H_ */ diff --git a/project/src/console/adc_tst.c b/project/src/console/adc_tst.c new file mode 100644 index 0000000..115ead1 --- /dev/null +++ b/project/src/console/adc_tst.c @@ -0,0 +1,258 @@ +/* + * adc_tst.c + * + * Created on: 04/04/2017. + * Author: pvvx + */ + +#include +#include "rtl8195a.h" +#include "FreeRTOS.h" +#include "rtl8195a/rtl_libc.h" + +//------------------------------------------------------------------------------ +#include "objects.h" +#include "PinNames.h" +#include "hal_adc.h" +#include "analogin_api.h" +#include "strproc.h" +//------------------------------------------------------------------------------ +analogin_t adc; + +LOCAL void fATADI(int argc, char *argv[]) { + + int count = 8; + int channel = 2; + union { + unsigned int ui[2]; + unsigned short us[4]; + }x; + uint16_t adcdat; + memset(&adc, 0, sizeof(adc)); + + + // ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_); + // ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_); + + if (argc > 1) { + channel = atoi(argv[1]); + channel &= 0x03; + if(!channel) channel = 2; + } + + if (argc > 2) { + count = atoi(argv[2]); + } + + analogin_init(&adc, (channel+1) | (PORT_V << 4)); + + PSAL_ADC_HND pSalADCHND = &((&(adc.SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv); + + uint32_t sum = 0; + for (uint32_t i = 1; i <= count; i++) { + RtkADCReceiveBuf(pSalADCHND, &x.ui); + adcdat = x.us[channel]; + if((i % 8) == 0 || (i == count)) { + printf("0x%04x\n", adcdat); + } else { + printf("0x%04x, ", adcdat); + } + sum += adcdat; + } + analogin_deinit(&adc); + printf("ADC%d = 0x%04x\n", channel, sum / count); + // sys_adc_calibration(0, &channel, &count); +} + +LOCAL void fATADD(int argc, char *argv[]) { + + int count = 64; + int channel = 2; + uint16_t adcdat; + memset(&adc, 0, sizeof(adc)); + + +// ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_); +// ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_); + + if (argc > 1) { + channel = atoi(argv[1]); + channel &= 0x03; + if(!channel) channel = 1; + } + + if (argc > 2) { + count = atoi(argv[2]); + if (count <= 2) { + count = 64; + } + }; + + analogin_init(&adc, (channel+1) | (PORT_V << 4)); + SAL_ADC_TRANSFER_BUF trbuf; + trbuf.pDataBuf = zalloc(count*4); + if(trbuf.pDataBuf) { + trbuf.DataLen = count/2; // x32 bit ? + trbuf.RSVD = 0; + adc.SalADCHndPriv.SalADCHndPriv.pRXBuf = &trbuf; + adc.SalADCHndPriv.SalADCHndPriv.OpType = ADC_DMA_TYPE; + + adc.HalADCInitData.ADCEndian = ADC_DATA_ENDIAN_LITTLE; //ADC endian selection, + //but actually it's for 32-bit ADC data swap control + //1'b0: no swap, + //1'b1: swap the upper 16-bit and the lower 16-bit +// adc.HalADCInitData.ADCCompOnly = ADC_FEATURE_DISABLED; //ADC compare mode only enable (without FIFO enable) +// adc.HalADCInitData.ADCEnManul = ADC_FEATURE_ENABLED; // ADC_FEATURE_DISABLED; //ADC enable manually +// adc.HalADCInitData.ADCIdx = channel+1; //ADC index used (1..3 ?) +// adc.HalADCInitData.ADCBurstSz = 8; //ADC DMA operation threshold +// adc.HalADCInitData.ADCOneShotTD = 8; //ADC one shot mode threshold +// adc.HalADCInitData.ADCDataRate = 0; // 0xff; // ADC down sample data rate ?? + adc.HalADCInitData.ADCAudioEn = ADC_FEATURE_ENABLED; //ADC audio mode enable // ADC_FEATURE_DISABLED +// adc.HalADCInitData.ADCOneShotEn = ADC_FEATURE_DISABLED; //ADC one shot mode threshold + adc.HalADCInitData.ADCInInput = ADC_FEATURE_ENABLED; //ADC Input is internal? +// adc.HalADCInitData.ADCEn = ADC_DISABLE; //ADC_ENABLE; + + HalADCInit8195a(&adc.HalADCInitData); + /* Read Content */ + HAL_ADC_READ32(REG_ADC_FIFO_READ); + HAL_ADC_READ32(REG_ADC_INTR_STS); + RtkADCReceive(&adc.SalADCHndPriv.SalADCHndPriv); + while(adc.SalADCHndPriv.SalADCHndPriv.DevSts != ADC_STS_IDLE); + uint16 * ptr = (uint16 *) trbuf.pDataBuf; + // RtkADCDMAInit(&adc.SalADCHndPriv.SalADCHndPriv); + for (uint32_t i = 1; i <= count; i++) { + if((i % 16) == 0 || (i == count)) { + printf("%04x\n", *ptr); + } else { + printf("%04x ", *ptr); + } + ptr++; + } + uint32_t sum = 0; + ptr = (uint16 *) trbuf.pDataBuf; + for (uint32_t i = 1; i <= count; i++) { + printf("%d\n", *ptr); + sum += *ptr; + ptr++; + if((i%512)==0) vTaskDelay(10); + } +/* + printf("OpType:\t\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.OpType); + printf("pRXBuf:\t\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf); + printf("pDataBuf:\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf->pDataBuf); + printf("DataLen:\t%p\n", adc.SalADCHndPriv.SalADCHndPriv.pRXBuf->DataLen); + printf("ADCDataRate:\t%p\n", adc.HalADCInitData.ADCDataRate); + printf("ADCData:\t%p\n", adc.HalADCInitData.ADCData); + printf("ADCIdx:\t\t%p\n", adc.HalADCInitData.ADCIdx); + printf("ADCPWCtrl:\t%p\n", adc.HalADCInitData.ADCPWCtrl); + printf("ADCAnaParAd3:\t%p\n", adc.HalADCInitData.ADCAnaParAd3); + printf("ADC%d = 0x%04x\n", channel, analogin_read_u16(&adc)); + printf("ADC%d = 0x%04x\n", channel, analogin_read_u16(&adc)); +*/ + analogin_deinit(&adc); + free(trbuf.pDataBuf); + printf("ADC%d = 0x%04x\n", channel, sum / count); + + } + else { + error_printf("%s: malloc failed!\n", __func__); + }; + +// sys_adc_calibration(0, &channel, &count); +} + +LOCAL void fATADC(int argc, char *argv[]) { + + int count = 8; + int channel = 2; + uint16_t adcdat; + memset(&adc, 0, sizeof(adc)); + + +// ConfigDebugErr |= (_DBG_ADC_|_DBG_GDMA_); +// ConfigDebugInfo |= (_DBG_ADC_|_DBG_GDMA_); + + if (argc > 1) { + channel = atoi(argv[1]); + channel &= 0x03; + if(!channel) channel = 1; + } + + if (argc > 2) { + count = atoi(argv[2]); + } + + analogin_init(&adc, (channel+1) | (PORT_V << 4)); + + uint32_t sum = 0; + for (uint32_t i = 1; i <= count; i++) { + adcdat = analogin_read_u16(&adc); + if((i % 8) == 0 || (i == count)) { + printf("0x%04x\n", adcdat); + } else { + printf("0x%04x, ", adcdat); + } + sum += adcdat; + } + analogin_deinit(&adc); + printf("ADC%d = 0x%04x\n", channel, sum / count); +// sys_adc_calibration(0, &channel, &count); +} + +LOCAL void fATSA(int argc, char *argv[]) { +// u32 tConfigDebugInfo = ConfigDebugInfo; + int channel; + char *ptmp; + u16 offset, gain, adcdat; + memset(&adc, 0, sizeof(adc)); + + if (argc < 2) { + printf("Usage: ATSA=CHANNEL(0~2)\n"); + printf("Usage: ATSA=k_get\n"); + printf("Usage: ATSA=k_set[offet(hex),gain(hex)]\n"); + return; + } + + if (strcmp(argv[1], "k_get") == 0) { + sys_adc_calibration(0, &offset, &gain); +// printf("[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain); + } else if (strcmp(argv[1], "k_set") == 0) { + if (argc != 4) { + printf("Usage: ATSA=k_set[offet(hex),gain(hex)]\n"); + return; + } + offset = strtoul(argv[2], &ptmp, 16); + gain = strtoul(argv[3], &ptmp, 16); + sys_adc_calibration(1, &offset, &gain); +// printf("[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain); + } else { + channel = atoi(argv[1]); + if (channel < 0 || channel > 2) { + printf("Usage: ATSA=CHANNEL(0~2)\n"); + return; + } + // Remove debug info massage +// ConfigDebugInfo = 0; + if (channel == 0) + analogin_init(&adc, AD_1); + else if (channel == 1) + analogin_init(&adc, AD_2); + else + analogin_init(&adc, AD_3); +// analogin_read_u16(&adc); + adcdat = analogin_read_u16(&adc) >> 4; + analogin_deinit(&adc); + // Recover debug info massage +// ConfigDebugInfo = tConfigDebugInfo; + + printf("A%d = 0x%04X\n", channel, adcdat); + } +} + +//------------------------------------------------------------------------------ +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_adc[] = { + { "ATADC", 0, fATADC, ": ADC Test" }, + { "ATADD", 0, fATADD, ": ADC DMA Test" }, + { "ATADI", 0, fATADI, ": ADC Irq Test" }, + { "ATSA" , 0, fATSA , ": ADC at" } +}; diff --git a/project/src/console/atcmd_user.c b/project/src/console/atcmd_user.c new file mode 100644 index 0000000..15b3ff2 --- /dev/null +++ b/project/src/console/atcmd_user.c @@ -0,0 +1,359 @@ +#include + +#ifdef CONFIG_AT_USR + +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "at_cmd/log_service.h" +#include "at_cmd/atcmd_wifi.h" +#include +#include "tcpip.h" +#include +#include +#include +#include "tcm_heap.h" +#include "rtl8195a/rtl_libc.h" + +#include "sleep_ex_api.h" + +#include "lwip/tcp_impl.h" + +extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57 + +#define printf rtl_printf // DiagPrintf + +/* RAM/TCM/Heaps info */ +extern void ShowMemInfo(void); +/* +void ShowMemInfo(void) +{ + printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n", + HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); +} + */ +//------------------------------------------------------------------------------ +// Mem, Tasks info +//------------------------------------------------------------------------------ +LOCAL void fATST(int argc, char *argv[]) { + ShowMemInfo(); +#if 0 //CONFIG_DEBUG_LOG > 1 + dump_mem_block_list(); + tcm_heap_dump(); +#endif; + printf("\n"); +#if (configGENERATE_RUN_TIME_STATS == 1) + char *cBuffer = pvPortMalloc(512); + if(cBuffer != NULL) { + vTaskGetRunTimeStats((char *)cBuffer); + printf("%s", cBuffer); + } + vPortFree(cBuffer); +#endif +#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1) + { + char * pcWriteBuffer = malloc(1024); + if(pcWriteBuffer) { + vTaskList((char*)pcWriteBuffer); + printf("\nTask List:\n"); + printf(&str_rom_57ch3Dch0A[7]); // "==========================================\n" + printf("Name\t Status Priority HighWaterMark TaskNumber\n%s\n", pcWriteBuffer); + free(pcWriteBuffer); + } + } +#endif +} +/*------------------------------------------------------------------------------------- + Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) +--------------------------------------------------------------------------------------*/ +extern void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len); +/* +static void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len) +{ + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; + unsigned int *p = (unsigned int *)((unsigned int)ps & (~3)); + unsigned int xlen = (unsigned int)ps & 3; + // unsigned int size = len; + + if(xlen) { + tmp.ud = *p++; + while (len) { + len--; + *pd++ = tmp.uc[xlen++]; + if(xlen & 4) break; + } + } + xlen = len >> 2; + while(xlen) { + tmp.ud = *p++; + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + } + if(len & 3) { + tmp.ud = *p; + pd[0] = tmp.uc[0]; + if(len & 2) { + pd[1] = tmp.uc[1]; + if(len & 1) { + pd[2] = tmp.uc[2]; + } + } + } + // return size; +} +*/ +int print_hex_dump(uint8_t *buf, int len, unsigned char k) { + uint32_t ss[2]; + ss[0] = 0x78323025; // "%02x" + ss[1] = k; // ","...'\0' + uint8_t * ptr = buf; + int result = 0; + while (len--) { + if (len == 0) + ss[1] = 0; + result += printf((uint8_t *) &ss, *ptr++); + } + return result; +} + +extern char str_rom_hex_addr[]; // in *.ld "[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F\n" +void dump_bytes(uint32 addr, int size) +{ + uint8 buf[17]; + u32 symbs_line = sizeof(buf)-1; + printf(str_rom_hex_addr); + while (size) { + if (symbs_line > size) symbs_line = size; + printf("%08X ", addr); + copy_align4_to_align1(buf, addr, symbs_line); + print_hex_dump(buf, symbs_line, ' '); + int i; + for(i = 0 ; i < symbs_line ; i++) { + if(buf[i] < 0x20 || buf[i] > 0x7E) { + buf[i] = '.'; + } + } + buf[symbs_line] = 0; + i = (sizeof(buf)-1) - symbs_line; + while(i--) printf(" "); + printf(" %s\r\n", buf); + addr += symbs_line; + size -= symbs_line; + } +} +//------------------------------------------------------------------------------ +// Dump byte register +//------------------------------------------------------------------------------ +LOCAL void fATSB(int argc, char *argv[]) +{ + int size = 16; + uint32 addr = Strtoul(argv[1],0,16); + if (argc > 2) { + size = Strtoul(argv[2],0,10); + if (size <= 0 || size > 16384) + size = 16; + } + if(addr + size > SPI_FLASH_BASE) { + flash_turnon(); + dump_bytes(addr, size); + SpicDisableRtl8195A(); + } + else { + dump_bytes(addr, size); + } +} + +//------------------------------------------------------------------------------ +// Dump dword register +//------------------------------------------------------------------------------ +LOCAL void fATSD(int argc, char *argv[]) +{ +/* + if (argc > 2) { + int size = Strtoul(argv[2],0,10); + if (size <= 0 || size > 16384) + argv[2] = "16"; + } +*/ + CmdDumpWord(argc-1, (unsigned char**)(argv+1)); +} +//------------------------------------------------------------------------------ +// Write dword register +//------------------------------------------------------------------------------ +LOCAL void fATSW(int argc, char *argv[]) +{ + CmdWriteWord(argc-1, (unsigned char**)(argv+1)); +} + +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ + ip4_addr2_16(ipaddr), \ + ip4_addr3_16(ipaddr), \ + ip4_addr4_16(ipaddr) + +#define IPSTR "%d.%d.%d.%d" + +extern const char * const tcp_state_str[]; +/* +static const char * const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; +*/ +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +void print_udp_pcb(void) +{ + struct udp_pcb *pcb; + bool prt_none = true; + rtl_printf("UDP pcbs:\n"); + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv ); + prt_none = false; + }; + if(prt_none) rtl_printf("none\n"); +} +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +void print_tcp_pcb(void) +{ + struct tcp_pcb *pcb; + rtl_printf("Active PCB states:\n"); + bool prt_none = true; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + }; + if(prt_none) rtl_printf("none\n"); + rtl_printf("Listen PCB states:\n"); + prt_none = true; + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + }; + if(prt_none) rtl_printf("none\n"); + rtl_printf("TIME-WAIT PCB states:\n"); + prt_none = true; + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p \t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + }; + if(prt_none) rtl_printf("none\n"); +} +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +LOCAL void fATLW(int argc, char *argv[]) // Info Lwip +{ + print_udp_pcb(); + print_tcp_pcb(); +} +//------------------------------------------------------------------------------ +// Deep sleep +//------------------------------------------------------------------------------ +LOCAL void fATDS(int argc, char *argv[]) +{ + uint32 sleep_ms = 10000; + if(argc > 1) sleep_ms = atoi(argv[1]); +#if 0 + if(argc > 2) { + printf("%u ms waiting low level on PB_1 before launching Deep-Sleep...\n", sleep_ms); + // turn off log uart + HalDeinitLogUart(); // sys_log_uart_off(); + + // initialize wakeup pin + gpio_t gpio_wake; + gpio_init(&gpio_wake, PB_1); + gpio_dir(&gpio_wake, PIN_INPUT); + gpio_mode(&gpio_wake, PullDown); + TickType_t sttime = xTaskGetTickCount(); + + do { + if(gpio_read(&gpio_wake) == 0) { + // Enter deep sleep... Wait give rising edge at PB_1 to wakeup system. + deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO, 0); + }; + vTaskDelay(1); + } while(xTaskGetTickCount() - sttime < sleep_ms); + HalInitLogUart(); // sys_log_uart_on(); + printf("No set pin low in deep sleep!\n"); + } + else { + printf("Deep-Sleep %u ms\n", sleep_ms); + HalLogUartWaitTxFifoEmpty(); + // Enter deep sleep... Wait timer ms + deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms); + } +#else + HalLogUartWaitTxFifoEmpty(); + deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms); +#endif +} +/*------------------------------------------------------------------------------ + * power saving mode + *----------------------------------------------------------------------------*/ +LOCAL void fATSP(int argc, char *argv[]) +{ + if(argc > 2) { + switch (argv[1][0]) { + case 'a': // acquire + { + acquire_wakelock(atoi(argv[2])); + break; + } + case 'r': // release + { + release_wakelock(atoi(argv[2])); + break; + } + }; + }; + printf("WakeLock Status %d\n", get_wakelock_status()); +} +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = { + {"ATST", 0, fATST, ": Memory info"}, + {"ATLW", 0, fATLW, ": LwIP Info"}, + {"ATSB", 1, fATSB, "=[,COUNT(dec)]: Dump byte register"}, + {"ATSD", 1, fATSD, "=[,COUNT(dec)]: Dump dword register"}, + {"ATSW", 2, fATSW, "=,: Set register"}, + {"ATDS", 0, fATDS, "=[TIME(ms)]: Deep sleep"}, + {"ATSP", 0, fATSP, "=,: Power"} +}; + +#endif //#ifdef CONFIG_AT_USR diff --git a/project/src/console/flash_tst.c b/project/src/console/flash_tst.c new file mode 100644 index 0000000..2499e0d --- /dev/null +++ b/project/src/console/flash_tst.c @@ -0,0 +1,38 @@ +/* + * flash_tst.c + * + * Created on: 10/04/2017 + * Author: pvvx + */ + +#include +#include "rtl8195a.h" +#include "flash_api.h" +#include "rtl8195a/rtl_libc.h" + +extern void dump_bytes(uint32 addr, int size); + +LOCAL void FlashDump(int argc, char *argv[]) { + if (argc > 1) { + int addr; + sscanf(argv[1], "%x", &addr); + int size = 16; + if (argc > 2) { + size = atoi(argv[2]); + if (size <= 0 || size > 16384) { + size = 16; + }; + }; + flash_turnon(); + dump_bytes(addr + SPI_FLASH_BASE, size); + SpicDisableRtl8195A(); + } +} + +MON_RAM_TAB_SECTION COMMAND_TABLE console_flash_tst[] = { + {"FLASHDB", 1, FlashDump, ": [,size]: Flash Dump"} +}; + + + + diff --git a/project/src/console/gpio_irq_test.c b/project/src/console/gpio_irq_test.c new file mode 100644 index 0000000..d67e0ec --- /dev/null +++ b/project/src/console/gpio_irq_test.c @@ -0,0 +1,99 @@ +/* + * test.c + * + * Created on: 12 марта 2017 г. + * Author: PVV + */ + +#include +#include "device.h" +#include "gpio_api.h" // mbed +#include "gpio_irq_api.h" // mbed +#include "gpio_irq_ex_api.h" // mbed +#include "timer_api.h" +#include "diag.h" +#include "main.h" + +#include "hal_diag.h" +#include "rtl8195a/rtl_libc.h" + +#define GPIO_LED_PIN PA_4 +#define GPIO_IRQ_PIN PC_4 + +gpio_irq_t gpio_btn; +gpio_t gpio_led; +gtimer_t my_timer; + +uint32_t lo_time_us, hi_time_us; +uint32_t lo_time_cnt, hi_time_cnt; +uint32_t old_tsf; +uint32_t lo, hi, fr; + +uint32_t io_irq_count; + +LOCAL void gpio_demo_irq_handler(uint32_t id, gpio_irq_event event) { + +// gpio_irq_disable(&gpio_btn); + io_irq_count++; + uint32_t new_tsf = get_tsf(); + uint32_t delta_us = (uint32_t) new_tsf - (uint32_t) old_tsf; + if (event & 1) { + lo_time_us += delta_us; + lo_time_cnt++; + gpio_irq_set(&gpio_btn, IRQ_LOW, 1); + } else { + hi_time_us += delta_us; + hi_time_cnt++; + gpio_irq_set(&gpio_btn, IRQ_HIGH, 1); + } + old_tsf = new_tsf; +// gpio_irq_enable(&gpio_btn); +} + +LOCAL void timer1_timeout_handler(uint32_t id) { + + if (lo_time_cnt && hi_time_cnt) { + lo = lo_time_us / lo_time_cnt; + hi = hi_time_us / hi_time_cnt; + fr = hi + lo; + lo_time_cnt = 0; + lo_time_us = 0; + hi_time_cnt = 0; + hi_time_us = 0; + printf("Period: %lu us, Lo: %lu us, Hi: %lu us\n", fr, lo, hi); + } +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +LOCAL void fATTT(int argc, char *argv[]) { + + lo_time_cnt = 0; + lo_time_us = 0; + hi_time_cnt = 0; + hi_time_us = 0; + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + gpio_write(&gpio_led, 0); + + // Initial Push Button pin as interrupt source + gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, + (uint32_t) (&gpio_led)); + gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_btn); + + // Initial a periodical timer + gtimer_init(&my_timer, TIMER1); + gtimer_start_periodical(&my_timer, 1000000, (void*) timer1_timeout_handler, + (uint32_t) &gpio_led); +} + +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_test[] = { { "ATTT", 0, + fATTT, ": Test" } }; + diff --git a/project/src/console/power_tst.c b/project/src/console/power_tst.c new file mode 100644 index 0000000..7445b6e --- /dev/null +++ b/project/src/console/power_tst.c @@ -0,0 +1,39 @@ +/* + * power_tst.c + * + * Created on: 04 апр. 2017 г. + * Author: PVV + */ + +#include "rtl8195a.h" +#include "freertos_pmu.h" +#include "rtl8195a/rtl_libc.h" +/*------------------------------------------------------------------------------ + * power saving mode + *----------------------------------------------------------------------------*/ +void fATSP(int argc, char *argv[]) +{ + if(argc > 2) { + switch (argv[1][0]) { + case 'a': // acquire + { + acquire_wakelock(atoi(argv[2])); + break; + } + case 'r': // release + { + release_wakelock(atoi(argv[2])); + break; + } + } + } + printf("WakeLock Status %d\n", get_wakelock_status()); +} + + +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_pwrs[] = { + {"ATSP", 0, fATSP, "=,: Power"} + +}; + + diff --git a/project/src/console/pwm_tst.c b/project/src/console/pwm_tst.c new file mode 100644 index 0000000..5e995c3 --- /dev/null +++ b/project/src/console/pwm_tst.c @@ -0,0 +1,59 @@ +/* + * pwm_tst.c + * + * Created on: 19/04/2017. + * Author: pvvx + */ + +#include +#include "rtl8195a.h" +#include "FreeRTOS.h" +#include "rtl8195a/rtl_libc.h" + +//#include "device.h" +#include "pwmout_api.h" // mbed +//#include "main.h" +#include "web_utils.h" +#include "objects.h" +#include "pinmap.h" + +extern const PinMap PinMap_PWM[]; +extern u32 gTimerRecord; + +HAL_PWM_ADAPTER pwm_hal_adp; + +LOCAL void fATPWM(int argc, char *argv[]) { + + uint8_t pin = ahextoul(argv[1]); + uint32_t period = ahextoul(argv[2]); + uint32_t pulse = ahextoul(argv[3]); + + uint32_t peripheral = pinmap_peripheral(pin, PinMap_PWM); + + if(pwm_hal_adp.enable) { + HAL_Pwm_Disable(&pwm_hal_adp); + gTimerRecord &= ~(1 << pwm_hal_adp.gtimer_id); + rtl_memset((void *)&pwm_hal_adp, 0, sizeof(HAL_PWM_ADAPTER)); + }; + if((period) && (unlikely(peripheral != NC)) + && (HAL_Pwm_Init(&pwm_hal_adp, RTL_GET_PERI_IDX(peripheral), RTL_GET_PERI_SEL(peripheral)) == HAL_OK)) { + HAL_Pwm_SetDuty(&pwm_hal_adp, period, pulse); + HAL_Pwm_Enable(&pwm_hal_adp); + } else { + printf("Error parameters!"); + }; +} + +LOCAL void fATWLED(int argc, char *argv[]) { + HalPinCtrlRtl8195A(WL_LED, 2, 1); + HalPinCtrlRtl8195A(EGTIM, ahextoul(argv[1]), 1); +} +//------------------------------------------------------------------------------ +// atpwm=34,1048575,524287 +// atpwm=34,122,61 (8.187kHz) +// atsw 40000368 85001002 (8.187kHz) +// atsd 40000360 6 +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_adc[] = { + { "ATWLED", 0, fATWLED, ": WLED Test" }, + { "ATPWM", 3, fATPWM, "=,,: PWM Test" } +}; diff --git a/project/src/console/spi_tst.c b/project/src/console/spi_tst.c new file mode 100644 index 0000000..7548065 --- /dev/null +++ b/project/src/console/spi_tst.c @@ -0,0 +1,83 @@ +/* + * spi_test.c + */ +#include +#include "rtl8195a.h" +#include "spi_api.h" +#include "spi_ex_api.h" +#include "rtl8195a/rtl_libc.h" + +#define SPI0_MOSI PC_2 +#define SPI0_MISO PC_3 +#define SPI0_SCLK PC_1 +#define SPI0_CS PC_0 + +spi_t spi_master; + +LOCAL void show_reg_spi(int i) { + rtl_printf("Regs SPI:\n"); + for(int x = 0; x < 64 ; x += 4) { + rtl_printf("0x%08x ", HAL_SSI_READ32(i, x)); + if((x & 0x0F) == 0x0C) rtl_printf("\n"); + } +} + + +LOCAL void fATSSI(int argc, char *argv[]) +{ + int len = 128; + int count = 32; + int clk = 1000000; + int ssn = 0; + if(argc > 1) { + len = atoi(argv[1]); + if(len > 32768 || len <= 0) { + len = 128; + error_printf("%s: len = %u!\n", __func__, len); + }; + }; + if(argc > 2) { + count = atoi(argv[2]); + if(count > 10000 || count <= 0) { + count = 32; + error_printf("%s: count = %u!\n", __func__, count); + }; + }; + if(argc > 3) { + clk = atoi(argv[3]); + if(clk <= 0) { + clk = 1000000; + error_printf("%s: clk = %u!\n", __func__, clk); + }; + }; + if(argc > 4) { + ssn = atoi(argv[4]); + if(ssn > 7 || ssn < 0) { + ssn = 0; + error_printf("%s: ssn = %u!\n", __func__, ssn); + }; + }; + char* buff = pvPortMalloc(len); + if(buff) { + spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); // CS заданный тут нигде не используется + spi_format(&spi_master, 16, 3, 0); + spi_frequency(&spi_master, clk); + spi_slave_select(&spi_master, ssn); // выбор CS + for(int i = 0; i < len; i++) buff[i] = (char)i; + while(count--) { + spi_master_write_stream(&spi_master, buff, len); + while(spi_busy(&spi_master)); + rtl_printf("Master write: %d\n", count); + }; +// show_reg_spi(spi_master.spi_adp.Index); + spi_free(&spi_master); + free(buff); + } + else { + error_printf("%s: error malloc!\n", __func__); + }; +} + +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_spitst[] = { + {"ATSSI", 0, fATSSI, "[len[,count[,clk[,ssn]]]]: Spi test"} +}; diff --git a/project/src/console/wifi_console.c b/project/src/console/wifi_console.c new file mode 100644 index 0000000..0f522fa --- /dev/null +++ b/project/src/console/wifi_console.c @@ -0,0 +1,338 @@ +/* + * wifi_console.c + * + * Created on: 03/04/2017 + * Author: pvvx + */ + +#include +#include "FreeRTOS.h" +#include "diag.h" +#include "wifi_api.h" +#include "wifi_conf.h" +#include "rtl8195a/rtl_libc.h" +#include "hal_platform.h" + +#include "section_config.h" +#include "hal_diag.h" +#include "lwip/netif.h" + + +extern struct netif xnetif[NET_IF_NUM]; + +//========================================================== +//--- CONSOLE -------------------------- + +// ATPN=[,password[,encryption[,auto reconnect[,reconnect pause]]]: WIFI Connect to AP +LOCAL void fATPN(int argc, char *argv[]){ + if(argc > 1) { + if(argv[1][0] == '?') { + show_wifi_st_cfg(); + } + else { + strncpy(wifi_st_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID); + if(argc > 2) { + strncpy(wifi_st_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID); + int i = strlen(wifi_st_cfg.password); + if(i > 7) { + wifi_st_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + else if(!i) { + wifi_st_cfg.security_type = RTW_SECURITY_OPEN; + } + else { + printf("password len < 8!\n"); + wifi_st_cfg.security_type = RTW_SECURITY_OPEN; + } + } + else { + wifi_st_cfg.password[0] = 0; + wifi_st_cfg.security_type = RTW_SECURITY_OPEN; + } + if(argc > 3) { + wifi_ap_cfg.security_type = translate_rtw_security(atoi(argv[3])); + } + if(argc > 4) { + wifi_st_cfg.autoreconnect = atoi(argv[3]); + } + else wifi_st_cfg.autoreconnect = 0; + if(argc > 5) { + wifi_st_cfg.reconnect_pause = atoi(argv[3]); + } + else wifi_st_cfg.reconnect_pause = 5; + show_wifi_st_cfg(); + wifi_run(wifi_run_mode | RTW_MODE_STA); + } + } +} + +// ATPA=[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP +LOCAL void fATPA(int argc, char *argv[]){ + if(argc > 1) { + if(argv[1][0] == '?') { + show_wifi_ap_cfg(); + } + else { + strncpy(wifi_ap_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID); + if(argc > 2) { + strncpy(wifi_ap_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID); + int i = strlen(wifi_ap_cfg.password); + if(i > 7) { + wifi_ap_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + else if(i == 0) { + wifi_ap_cfg.security_type = RTW_SECURITY_OPEN; + } + else { + printf("password len < 8!\n"); + wifi_ap_cfg.security_type = RTW_SECURITY_OPEN; + } + } + else { + wifi_ap_cfg.password[0] = 0; + wifi_ap_cfg.security_type = RTW_SECURITY_OPEN; + } + if(argc > 3) { + if(argv[3][0]=='0') wifi_st_cfg.security_type = RTW_SECURITY_OPEN; + else wifi_st_cfg.security_type = RTW_SECURITY_WEP_PSK; + } + if(argc > 4) { + wifi_ap_cfg.channel = atoi(argv[4]); + } + else wifi_ap_cfg.channel = 1; + if(argc > 5) { + wifi_ap_cfg.ssid_hidden = atoi(argv[5]); + } + else wifi_ap_cfg.ssid_hidden = 0; + + if(argc > 6) { + wifi_ap_cfg.max_sta = atoi(argv[6]); + } + else wifi_ap_cfg.max_sta = 3; + + show_wifi_ap_cfg(); + wifi_run(wifi_run_mode | RTW_MODE_AP); + } + } +} + +// WIFI Connect, Disconnect +LOCAL void fATWR(int argc, char *argv[]){ + rtw_mode_t mode = RTW_MODE_NONE; + if(argc > 1) mode = atoi(argv[1]); + wifi_run(mode); +} + +// Close connections +LOCAL void fATOF(int argc, char *argv[]){ + connect_close(); +} + +// Open connections +LOCAL void fATON(int argc, char *argv[]){ + connect_start(); +} + +LOCAL void fATWI(int argc, char *argv[]) { + rtw_wifi_setting_t Setting; + if((wifi_run_mode & RTW_MODE_AP) + && wifi_get_setting(wlan_ap_name, &Setting) == 0) { + wifi_show_setting(wlan_ap_name, &Setting); +// show_wifi_ap_ip(); + printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_AP_NETIF_NUM].ip_addr)); + } + if((wifi_run_mode & RTW_MODE_STA) + && wifi_get_setting(wlan_st_name, &Setting) == 0) { + wifi_show_setting(wlan_st_name, &Setting); +// show_wifi_st_ip(); + printf("\tIP: " IPSTR "\n", IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr)); + } + printf("\nWIFI config:\n"); + printf(&str_rom_57ch3Dch0A[25]); // "================================\n" + show_wifi_cfg(); + printf("\nWIFI AP config:\n"); + printf(&str_rom_57ch3Dch0A[25]); // "================================\n" + show_wifi_ap_cfg(); + printf("\nWIFI ST config:\n"); + printf(&str_rom_57ch3Dch0A[25]); // "================================\n" + show_wifi_st_cfg(); + printf("\n"); +#if 1 + if(argc > 2) { + uint8_t c = argv[1][0] | 0x20; + if(c == 's') { + int i = atoi(argv[2]); + printf("Save configs(%d)..\n", i); + write_wifi_cfg(atoi(argv[2])); + } + else if(c == 'l') { + wifi_cfg.load_flg = atoi(argv[2]); + } + else if(c == 'm') { + wifi_cfg.mode = atoi(argv[2]); + } + } +#endif +} + +extern uint8_t rtw_power_percentage_idx; + +LOCAL void fATWT(int argc, char *argv[]) { + if(argc > 1) { + int txpwr = atoi(argv[1]); + debug_printf("set tx power (%d)...\n", txpwr); + if(rltk_set_tx_power_percentage(txpwr) != RTW_SUCCESS) { + error_printf("Error set tx power (%d)!", wifi_cfg.tx_pwr); + } + } + printf("TX power = %d\n", rtw_power_percentage_idx); +} + +//-- Test tsf (64-bits counts, 1 us step) --- + +#include "hal_com_reg.h" + +#define ReadTSF_Lo32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR))) +#define ReadTSF_Hi32() (*((volatile unsigned int *)(WIFI_REG_BASE + REG_TSFTR1))) + +LOCAL uint64_t get_tsf(void) +{ + return *((uint64_t *)(WIFI_REG_BASE + REG_TSFTR)); +} + +LOCAL void fATSF(int argc, char *argv[]) +{ + uint64_t tsf = get_tsf(); + printf("\nTSF: %08x%08x\n", (uint32_t)(tsf>>32), (uint32_t)(tsf)); +} + +/* -------- WiFi Scan ------------------------------- */ +unsigned char *tab_txt_rtw_secyrity[] = { + "OPEN ", + "WEP ", + "WPA TKIP", + "WPA AES", + "WPA2 AES", + "WPA2 TKIP", + "WPA2 Mixed", + "WPA/WPA2 AES", + "Unknown" +}; +unsigned int *tab_code_rtw_secyrity[] = { + RTW_SECURITY_OPEN, + RTW_SECURITY_WEP_PSK, + RTW_SECURITY_WPA_TKIP_PSK, + RTW_SECURITY_WPA_AES_PSK, + RTW_SECURITY_WPA2_AES_PSK, + RTW_SECURITY_WPA2_TKIP_PSK, + RTW_SECURITY_WPA2_MIXED_PSK, + RTW_SECURITY_WPA_WPA2_MIXED, + RTW_SECURITY_UNKNOWN +}; + +volatile uint8_t scan_end; + +/* -------- WiFi Scan ------------------------------- */ +LOCAL rtw_result_t _scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) +{ + if (malloced_scan_result->scan_complete != RTW_TRUE) { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + if(scan_end == 1) { + printf("\nScan networks:\n\n"); + printf("N\tType\tMAC\t\t\tSignal\tCh\tWPS\tSecyrity\tSSID\n\n"); + }; + printf("%d\t", scan_end++); + printf("%s\t", (record->bss_type == RTW_BSS_TYPE_ADHOC)? "Adhoc": "Infra"); + printf(MAC_FMT, MAC_ARG(record->BSSID.octet)); + printf("\t%d\t", record->signal_strength); + printf("%d\t", record->channel); + printf("%d\t", record->wps_type); + int i = 0; + for(; record->security != tab_code_rtw_secyrity[i] && tab_code_rtw_secyrity[i] != RTW_SECURITY_UNKNOWN; i++); + printf("%s \t", tab_txt_rtw_secyrity[i]); + printf("%s\n", record->SSID.val); + } else { + scan_end = 0; + printf("\n"); + } + return RTW_SUCCESS; +} +/* -------- WiFi Scan ------------------------------- */ +#define scan_channels 14 +LOCAL void fATSN(int argc, char *argv[]) +{ + int i; + u8 *channel_list = (u8*)pvPortMalloc(scan_channels*2); + if(channel_list) { + scan_end = 1; + u8 * pscan_config = &channel_list[scan_channels]; + //parse command channel list + for(i = 1; i <= scan_channels; i++){ + *(channel_list + i - 1) = i; + *(pscan_config + i - 1) = PSCAN_ENABLE; + }; + if(wifi_set_pscan_chan(channel_list, pscan_config, scan_channels) < 0){ + printf("ERROR: wifi set partial scan channel fail\n"); + } else if(wifi_scan_networks(_scan_result_handler, NULL ) != RTW_SUCCESS){ + printf("ERROR: wifi scan failed\n"); + } else { + i = 300; + while(i-- && scan_end) { + vTaskDelay(10); + }; + }; + vPortFree(channel_list); + } else { + printf("ERROR: Can't malloc memory for channel list\n"); + }; +} + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +extern void cmd_ap_wps(int argc, char **argv); +extern void cmd_wps(int argc, char **argv); +//extern void cmd_wifi_on(int argc, char **argv); +#endif +#if CONFIG_ENABLE_P2P +extern void cmd_wifi_p2p_start(int argc, char **argv); +extern void cmd_wifi_p2p_stop(int argc, char **argv); +extern void cmd_p2p_listen(int argc, char **argv); +extern void cmd_p2p_find(int argc, char **argv); +extern void cmd_p2p_peers(int argc, char **argv); +extern void cmd_p2p_info(int argc, char **argv); +extern void cmd_p2p_disconnect(int argc, char **argv); +extern void cmd_p2p_connect(int argc, char **argv); +extern void cmd_wifi_p2p_auto_go_start(int argc, char **argv); +extern void cmd_p2p_peers(int argc, char **argv); +#endif //CONFIG_ENABLE_P2P + + +MON_RAM_TAB_SECTION COMMAND_TABLE console_cmd_wifi_api[] = { + {"ATPN", 1, fATPN, "=[,password[,encryption[,auto-reconnect[,reconnect pause]]]: WIFI Connect to AP"}, + {"ATPA", 1, fATPA, "=[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP"}, +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + {"WPS_AP", 1, cmd_ap_wps, "=[,pin]: WiFi AP WPS"}, + {"WPS_ST", 1, cmd_wps, "=[,pin]: WiFi Station WPS"}, +#endif +#if CONFIG_ENABLE_P2P + {"P2P_START", 0, cmd_wifi_p2p_start, ": p2p start" }, + {"P2P_ASTART", 0, cmd_wifi_p2p_auto_go_start, ": p2p auto go start" }, + {"P2P_STOP", 0, cmd_wifi_p2p_stop, ": p2p stop"}, + {"P2P_PEERS", 0, cmd_p2p_peers, ": p2p peers" }, + {"P2P_FIND", 0, cmd_p2p_find, ": p2p find"}, + {"P2P_INFO", 0, cmd_p2p_info, ": p2p info"}, + {"P2P_DISCCONNECT", 0, cmd_p2p_disconnect, ": p2p disconnect"}, + {"P2P_CONNECT", 0, cmd_p2p_connect, ": p2p connect"}, +#endif + {"ATWR", 0, fATWR, ": WIFI Connect, Disconnect"}, +// {"ATON", 0, fATON, ": Open connections"}, +// {"ATOF", 0, fATOF, ": Close connections"}, + {"ATWI", 0, fATWI, ": WiFi Info"}, +#if CONFIG_DEBUG_LOG > 3 + {"ATWT", 1, fATWT, "=: WiFi tx power: 0 - 100%, 1 - 75%, 2 - 50%, 3 - 25%, 4 - 12.5%"}, + {"ATSF", 0, fATSF, ": Test TSF value"}, +#endif + {"ATSN", 0, fATSN, ": Scan networks"} +}; + + diff --git a/project/src/console/wlan_tst.c b/project/src/console/wlan_tst.c new file mode 100644 index 0000000..5dfea23 --- /dev/null +++ b/project/src/console/wlan_tst.c @@ -0,0 +1,50 @@ +/* + * wlan_tst.c + * + * Created on: 10 апр. 2017 г. + * Author: PVV + */ +#include +#include "rtl8195a.h" +#include "drv_types.h" +//#include "section_config.h" +//#include "hal_diag.h" +#include "rtl8195a/rtl_libc.h" + +extern void dump_bytes(uint32 addr, int size); +extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h + +LOCAL void tst_wlan_struct(int argc, char *argv[]) +{ + printf("Test: sizeof(struct _ADAPTER) = %d\n", sizeof(struct _ADAPTER)); //6088 + printf("mlmeextpriv\t+%d\n", offsetof(struct _ADAPTER, mlmeextpriv)); //+1256 + printf("TSFValue\t+%d\n", offsetof(struct _ADAPTER, mlmeextpriv.TSFValue)); //+1992 + printf("stapriv\t\t+%d\n", offsetof(struct _ADAPTER, stapriv)); //+3024 [164] + printf("pwrctrlpriv.bInternalAutoSuspend +%d\n", offsetof(struct _ADAPTER, pwrctrlpriv.bInternalAutoSuspend)); //+5061 + printf("eeprompriv\t+%d\n", offsetof(struct _ADAPTER, eeprompriv)); // +5128 + printf("HalData\t\t+%d\n", offsetof(struct _ADAPTER, HalData)); //+5656 + printf("HalFunc\t\t+%d\n", offsetof(struct _ADAPTER, HalFunc)); //+5664 + printf("bDriverStopped\t+%d\n", offsetof(struct _ADAPTER, bDriverStopped)); //+5880 + printf("hw_init_completed +%d\n", offsetof(struct _ADAPTER, hw_init_completed)); //+5905 + printf("stats\t\t+%d\n", offsetof(struct _ADAPTER, stats)); //+6024 + printf("hw_init_mutex\t+%d\n", offsetof(struct _ADAPTER, hw_init_mutex)); //+6060 + printf("fix_rate\t+%d\n", offsetof(struct _ADAPTER, fix_rate)); //+6084 + + printf("rltk_wlan_info = %p\n", &rltk_wlan_info); + dump_bytes((u32)&rltk_wlan_info, sizeof(rltk_wlan_info)); + _adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv); + printf("adapter0 = %p, %p\n", ad, ad->pbuddy_adapter); + ad = *(_adapter **)((rltk_wlan_info[1].dev)->priv); + printf("adapter1 = %p, %p\n", ad, ad->pbuddy_adapter); + vTaskDelay(5); + dump_bytes((u32)ad,sizeof(struct _ADAPTER)); + vTaskDelay(5); + + if (sizeof(struct _ADAPTER) != 6088) { + printf("Error: Check WiFi adapter struct!\n"); + }; +} + +MON_RAM_TAB_SECTION COMMAND_TABLE console_wlan_tst[] = { + {"CHKWL", 0, tst_wlan_struct, ": Chk wlan struct"} +}; diff --git a/project/src/tcpsrv/tcp_srv_conn.c b/project/src/tcpsrv/tcp_srv_conn.c new file mode 100644 index 0000000..35760ee --- /dev/null +++ b/project/src/tcpsrv/tcp_srv_conn.c @@ -0,0 +1,1269 @@ +/****************************************************************************** + * FileName: tcp_srv_conn.c + * TCP сервачек для ESP8266 + * PV` ver1.0 20/12/2014 + ******************************************************************************/ +#include "user_config.h" +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +//#include "bios.h" +//#include "sdk/add_func.h" +//#include "osapi.h" +//#include "user_interface.h" +//#include +//#include "rtl8195a/rtl_common.h" +//#include "rtl_lib.h" +#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "flash_eep.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "rtl8195a/rtl_libc.h" +#include "esp_comp.h" +//#include "web_iohw.h" +//#include "wifi.h" + +#ifdef CONFIG_DEBUG_LOG +#define DEBUGSOO 2 // уровень вывода отладочной инфы по умолчанию = 2, =1 только error +#else +#define DEBUGSOO 0 +#endif +// Lwip funcs - http://www.ecoscentric.com/ecospro/doc/html/ref/lwip.html + +#define TCP_SRV_BSSDATA_ATTR +#define TCP_SRV_RODATA_ATTR +#define TCP_SRV_CODE_ATTR + +#define ts_printf(...) rtl_printf(__VA_ARGS__) +#define system_get_free_heap_size xPortGetFreeHeapSize + +#define os_free(p) vPortFree(p) +#define os_malloc(p) pvPortMalloc(p) +#define os_zalloc(p) pvPortZalloc(p) +#define os_realloc(p,s) pvPortReAlloc(p,s) +/* +extern __rtl_memsetw_v1_00(void *, uint32, size_t); + +void *pvPortZalloc( size_t xWantedSize ) +{ + void *pvReturn = pvPortMalloc(xWantedSize); + if(pvReturn != NULL) __rtl_memsetw_v1_00(pvReturn, 0, (xWantedSize + 3)>>2); + return pvReturn; +} +*/ + +TCP_SERV_CFG *phcfg TCP_SRV_BSSDATA_ATTR; // = NULL; // начальный указатель в памяти на структуры открытых сервачков + +#if DEBUGSOO > 0 +const uint8 txt_tcpsrv_NULL_pointer[] TCP_SRV_RODATA_ATTR = "tcpsrv: NULL pointer!\n"; +const uint8 txt_tcpsrv_already_initialized[] TCP_SRV_RODATA_ATTR = "tcpsrv: already initialized!\n"; +const uint8 txt_tcpsrv_out_of_mem[] TCP_SRV_RODATA_ATTR = "tcpsrv: out of mem!\n"; +#endif + +#define mMIN(a, b) ((a 2 +static const char srvContenErr00[] TCP_SRV_RODATA_ATTR = "Ok"; // ERR_OK 0 +static const char srvContenErr01[] TCP_SRV_RODATA_ATTR = "Out of memory error"; // ERR_MEM -1 +static const char srvContenErr02[] TCP_SRV_RODATA_ATTR = "Buffer error"; // ERR_BUF -2 +static const char srvContenErr03[] TCP_SRV_RODATA_ATTR = "Timeout"; // ERR_TIMEOUT -3 +static const char srvContenErr04[] TCP_SRV_RODATA_ATTR = "Routing problem"; // ERR_RTE -4 +static const char srvContenErr05[] TCP_SRV_RODATA_ATTR = "Operation in progress"; // ERR_INPROGRESS -5 +static const char srvContenErr06[] TCP_SRV_RODATA_ATTR = "Illegal value"; // ERR_VAL -6 +static const char srvContenErr07[] TCP_SRV_RODATA_ATTR = "Operation would block"; // ERR_WOULDBLOCK -7 +static const char srvContenErr08[] TCP_SRV_RODATA_ATTR = "Connection aborted"; // ERR_ABRT -8 +static const char srvContenErr09[] TCP_SRV_RODATA_ATTR = "Connection reset"; // ERR_RST -9 +static const char srvContenErr10[] TCP_SRV_RODATA_ATTR = "Connection closed"; // ERR_CLSD -10 +static const char srvContenErr11[] TCP_SRV_RODATA_ATTR = "Not connected"; // ERR_CONN -11 +static const char srvContenErr12[] TCP_SRV_RODATA_ATTR = "Illegal argument"; // ERR_ARG -12 +static const char srvContenErr13[] TCP_SRV_RODATA_ATTR = "Address in use"; // ERR_USE -13 +static const char srvContenErr14[] TCP_SRV_RODATA_ATTR = "Low-level netif error"; // ERR_IF -14 +static const char srvContenErr15[] TCP_SRV_RODATA_ATTR = "Already connected"; // ERR_ISCONN -15 +const char * srvContenErr[] = { + srvContenErr00, + srvContenErr01, + srvContenErr02, + srvContenErr03, + srvContenErr04, + srvContenErr05, + srvContenErr06, + srvContenErr07, + srvContenErr08, + srvContenErr09, + srvContenErr10, + srvContenErr11, + srvContenErr12, + srvContenErr13, + srvContenErr14, + srvContenErr15 +}; +#endif +static const char srvContenErrX[] TCP_SRV_RODATA_ATTR = "?"; +/****************************************************************************** + * FunctionName : tspsrv_error_msg + * Description : строка ошибки по номеру + * Parameters : LwIP err + * Returns : указатель на строку ошибки + *******************************************************************************/ +char * tspsrv_error_msg(err_t err) +{ + if((err > -16) && (err < 1)) { +#ifdef LWIP_DEBUG + return lwip_strerr(err); +#else + return srvContenErr[-err]; +#endif + } + else return srvContenErrX; +} + +extern const char * const tcp_state_str[]; +/****************************************************************************** + * FunctionName : tspsrv_tcp_state_msg + * Description : строка tcp_state по номеру + * Parameters : LwIP tcp_state + * Returns : указатель на строку + *******************************************************************************/ +char * tspsrv_tcp_state_msg(enum tcp_state state) +{ + if(state > TIME_WAIT && state < CLOSED) return srvContenErrX; + return tcp_state_str[state]; +} +/****************************************************************************** + * FunctionName : tspsrv_tcp_state_msg + * Description : строка tcp_state по номеру + * Parameters : LwIP tcp_state + * Returns : указатель на строку + *******************************************************************************/ +static char *msg_srvconn_state[] = { + "NONE", + "CLOSEWAIT", + "CLIENT", + "LISTEN", + "CONNECT", + "CLOSED" +}; +char * tspsrv_srvconn_state_msg(enum srvconn_state state) +{ + if(state > SRVCONN_CLOSED && state < SRVCONN_NONE) return srvContenErrX; + return msg_srvconn_state[state]; +} +//#endif +/****************************************************************************** + * FunctionName : tcpsrv_print_remote_info + * Description : выводит remote_ip:remote_port [conn_count] ts_printf("srv x.x.x.x:x [n] ") + * Parameters : TCP_SERV_CONN * ts_conn + * Returns : none + *******************************************************************************/ +void TCP_SRV_CODE_ATTR tcpsrv_print_remote_info(TCP_SERV_CONN *ts_conn) { +//#if DEBUGSOO > 0 + uint16 port; + if(ts_conn->pcb != NULL) port = ts_conn->pcb->local_port; + else port = ts_conn->pcfg->port; + ts_printf("srv[%u] %d.%d.%d.%d:%d [%d] ", port, + ts_conn->remote_ip.b[0], ts_conn->remote_ip.b[1], + ts_conn->remote_ip.b[2], ts_conn->remote_ip.b[3], + ts_conn->remote_port, ts_conn->pcfg->conn_count); +//#endif +} +/****************************************************************************** + * Default call back functions + ******************************************************************************/ +//------------------------------------------------------------------------------ +void TCP_SRV_CODE_ATTR tcpsrv_disconnect_calback_default(TCP_SERV_CONN *ts_conn) { + ts_conn->pcb = NULL; +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("disconnect\n"); +#endif +} +//------------------------------------------------------------------------------ +err_t TCP_SRV_CODE_ATTR tcpsrv_listen_default(TCP_SERV_CONN *ts_conn) { +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("listen\n"); +#endif + return ERR_OK; +} +//------------------------------------------------------------------------------ +err_t TCP_SRV_CODE_ATTR tcpsrv_connected_default(TCP_SERV_CONN *ts_conn) { +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("connected\n"); +#endif + return ERR_OK; +} +//------------------------------------------------------------------------------ +err_t TCP_SRV_CODE_ATTR tcpsrv_sent_callback_default(TCP_SERV_CONN *ts_conn) { +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("sent_cb\n"); +#endif + return ERR_OK; +} +//------------------------------------------------------------------------------ +err_t TCP_SRV_CODE_ATTR tcpsrv_received_data_default(TCP_SERV_CONN *ts_conn) { +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("received, buffer %d bytes\n", ts_conn->sizei); +#endif + return ERR_OK; +} +/****************************************************************************** + * FunctionName : tcpsrv_check_max_tm_tcp_pcb + * Description : Ограничение неактивных pcb в списках lwip до MAX_TIME_WAIT_PCB + * Parameters : none + * Returns : none + *******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_check_max_tm_tcp_pcb(void) +{ + struct tcp_pcb *pcb; + int i = 0; + for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) i++; +#if DEBUGSOO > 4 + ts_printf("tcpsrv: check %d tm pcb\n", i); +#endif + while(i-- > MAX_TIME_WAIT_PCB) { + struct tcp_pcb *inactive = NULL; + for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + inactive = pcb; + } +#if DEBUGSOO > 3 + ts_printf("tcpsrv: kill %d tm pcb\n", i); +#endif + if(inactive != NULL) { + tcp_pcb_remove(&tcp_tw_pcbs, inactive); + memp_free(MEMP_TCP_PCB, inactive); + } + } +} +/****************************************************************************** + * FunctionName : find_tcp_pcb + * Description : поиск pcb в списках lwip + * Parameters : TCP_SERV_CONN * ts_conn + * Returns : *pcb or NULL + *******************************************************************************/ +struct tcp_pcb * TCP_SRV_CODE_ATTR find_tcp_pcb(TCP_SERV_CONN * ts_conn) { + struct tcp_pcb *pcb = ts_conn->pcb; + if (pcb) { + uint16 remote_port = ts_conn->remote_port; + uint16 local_port = ts_conn->pcfg->port; + uint32 ip = ts_conn->remote_ip.dw; + if ((pcb->remote_port == remote_port) && (pcb->local_port == local_port) + && (pcb->remote_ip.addr == ip)) + return pcb; + for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if ((pcb->remote_port == remote_port) && (pcb->local_port == local_port) + && (pcb->remote_ip.addr == ip)) + return pcb; + }; + for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if ((pcb->remote_port == remote_port) && (pcb->local_port == local_port) + && (pcb->remote_ip.addr == ip)) + return pcb; + }; + } + return NULL; +} +/****************************************************************************** + * FunctionName : tcpsrv_disconnect + * Description : disconnect + * Parameters : TCP_SERV_CONN * ts_conn + * Returns : none + *******************************************************************************/ +void TCP_SRV_CODE_ATTR tcpsrv_disconnect(TCP_SERV_CONN * ts_conn) { + if (ts_conn == NULL || ts_conn->state == SRVCONN_CLOSEWAIT) return; // уже закрывается + ts_conn->pcb = find_tcp_pcb(ts_conn); // ещё жива данная pcb ? + if (ts_conn->pcb != NULL) tcpsrv_server_close(ts_conn); +} +/****************************************************************************** + * FunctionName : internal fun: tcpsrv_int_sent_data + * Description : передача данных (не буферизированная! только передача в tcp Lwip-у) + * вызывать только из call back с текущим pcb! + * Parameters : TCP_SERV_CONN * ts_conn + * uint8* psent - буфер с данными + * uint16 length - кол-во передаваемых байт + * Returns : tcp error + ******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_int_sent_data(TCP_SERV_CONN * ts_conn, uint8 *psent, uint16 length) { + err_t err = ERR_ARG; + if(ts_conn == NULL) return err; + ts_conn->pcb = find_tcp_pcb(ts_conn); // ещё жива данная pcb ? + struct tcp_pcb *pcb = ts_conn->pcb; + if(pcb == NULL || ts_conn->state == SRVCONN_CLOSEWAIT) return ERR_CONN; + ts_conn->flag.busy_bufo = 1; // буфер bufo занят + if(tcp_sndbuf(pcb) < length) { +#if DEBUGSOO > 1 + ts_printf("sent_data length (%u) > sndbuf (%u)!\n", length, tcp_sndbuf(pcb)); +#endif + return err; + } + if (length) { + if(ts_conn->flag.nagle_disabled) tcp_nagle_disable(pcb); + err = tcp_write(pcb, psent, length, 1); + if (err == ERR_OK) { + ts_conn->ptrtx = psent + length; + ts_conn->cntro -= length; + ts_conn->flag.wait_sent = 1; // ожидать завершения передачи (sent_cb) + err = tcp_output(pcb); // передать что влезло + } else { // ts_conn->state = SRVCONN_CLOSE; +#if DEBUGSOO > 1 + ts_printf("tcp_write(%p, %p, %u) = %d! pbuf = %u\n", pcb, psent, length, err, tcp_sndbuf(pcb)); +#endif + ts_conn->flag.wait_sent = 0; + tcpsrv_server_close(ts_conn); + }; + } else { // создать вызов tcpsrv_server_sent() + tcp_nagle_enable(pcb); + err = tcp_output(pcb); // передать пустое + } + ts_conn->flag.busy_bufo = 0; // буфер bufo свободен + return err; +} +/****************************************************************************** + * FunctionName : tcpsrv_server_sent + * Description : Data has been sent and acknowledged by the remote host. + * This means that more data can be sent. + * Parameters : arg -- Additional argument to pass to the callback function + * pcb -- The connection pcb for which data has been acknowledged + * len -- The amount of bytes acknowledged + * Returns : ERR_OK: try to send some data by calling tcp_output + * ERR_ABRT: if you have called tcp_abort from within the function! + ******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { + sint8 ret_err = ERR_OK; + TCP_SERV_CONN * ts_conn = arg; + if (ts_conn == NULL || pcb == NULL) return ERR_ARG; + ts_conn->state = SRVCONN_CONNECT; + ts_conn->recv_check = 0; + ts_conn->flag.wait_sent = 0; // блок передан + if ((ts_conn->flag.tx_null == 0) + && (ts_conn->pcfg->func_sent_cb != NULL)) { + ret_err = ts_conn->pcfg->func_sent_cb(ts_conn); + } + return ret_err; +} +/****************************************************************************** + * FunctionName : recv_trim_bufi + * Description : увеличение размера буфера приема на newadd + * Parameters : ts_conn, newadd - требуемое дополнение размера буфера + * Returns : err_t + ******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR recv_trim_bufi(TCP_SERV_CONN * ts_conn, uint32 newadd) +{ + uint32 len = 0; +// while(ts_conn->flag.busy_bufi) vTaskDelay(1); + ts_conn->flag.busy_bufi = 1; // идет обработка bufi + if(newadd) { + // требуется дополнение размера буфера + if(ts_conn->pbufi != NULL) { // уже есть какой-то буфер + if ((ts_conn->flag.rx_buf) && ts_conn->cntri < ts_conn->sizei) { // буфер не пуст + len = ts_conn->sizei - ts_conn->cntri; // размер необработанных данных + if(ts_conn->cntri >= newadd) { // кол-во обработанных байт (пустого места в буфере) больше чем дополнение + os_memcpy(ts_conn->pbufi, &ts_conn->pbufi[ts_conn->cntri], len ); // скопировать необработанную часть в начало буфера + ts_conn->sizei = len; + if(ts_conn->cntri != newadd) { // кол-во обработанных байт (пустого места в буфере) равно требуемому дополнению + // уменьшение занимаемого буфера в памяти + len += newadd; // + ts_conn->pbufi = (uint8 *)os_realloc(ts_conn->pbufi, len + 1); //mem_trim(ts_conn->pbufi, len); + if(ts_conn->pbufi == NULL) { +#if DEBUGSOO > 2 + ts_printf("memtrim err %p[%d] ", ts_conn->pbufi, len + 1); +#endif + return ERR_MEM; + } +#if DEBUGSOO > 2 + ts_printf("memi%p[%d] ", ts_conn->pbufi, len); +#endif + } + ts_conn->pbufi[len] = '\0'; // вместо os_zalloc; + ts_conn->cntri = 0; + ts_conn->flag.busy_bufi = 0; // обработка bufi окончена + return ERR_OK; + } + } + else { // буфер пуст или не тот режим + // удалить буфер + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + } + } + // подготовка нового буфера, если его нет или не лезет дополнение + uint8 * newbufi = (uint8 *) os_malloc(len + newadd + 1); + if (newbufi == NULL) { +#if DEBUGSOO > 2 + ts_printf("memerr %p[%d] ", newbufi, len + newadd); +#endif + ts_conn->flag.busy_bufi = 0; // обработка bufi окончена + return ERR_MEM; + } +#if DEBUGSOO > 2 + ts_printf("memi%p[%d] ", newbufi, len + newadd); +#endif + newbufi[len + newadd] = '\0'; // вместо os_zalloc + if(len) { + os_memcpy(newbufi, &ts_conn->pbufi[ts_conn->cntri], len); + os_free(ts_conn->pbufi); + }; + ts_conn->pbufi = newbufi; + ts_conn->sizei = len; + } + else { + // оптимизация буфера (уменьшение занимаемого размера) + if((!ts_conn->flag.rx_buf) || ts_conn->cntri >= ts_conn->sizei) { // буфер обработан + ts_conn->sizei = 0; + if (ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); // освободить буфер. + ts_conn->pbufi = NULL; + }; + } + else if(ts_conn->cntri) { // есть обработанные данные + // уменьшение занимаемого размера на обработанные данные + len = ts_conn->sizei - ts_conn->cntri; + os_memcpy(ts_conn->pbufi, &ts_conn->pbufi[ts_conn->cntri], len ); + ts_conn->sizei = len; + ts_conn->pbufi = (uint8 *)os_realloc(ts_conn->pbufi, len + 1); //mem_trim(ts_conn->pbufi, len); + if(ts_conn->pbufi == NULL) { +#if DEBUGSOO > 2 + ts_printf("memtrim err %p[%d] ", ts_conn->pbufi, len + 1); +#endif + ts_conn->flag.busy_bufi = 0; // обработка bufi окончена + return ERR_MEM; + } + ts_conn->pbufi[len] = '\0'; // вместо os_zalloc; + } + } + ts_conn->cntri = 0; + ts_conn->flag.busy_bufi = 0; // обработка bufi окончена + return ERR_OK; +} +/****************************************************************************** + * FunctionName : tcpsrv_server_recv + * Description : Data has been received on this pcb. + * Parameters : arg -- Additional argument to pass to the callback function + * pcb -- The connection pcb which received data + * p -- The received data (or NULL when the connection has been closed!) + * err -- An error code if there has been an error receiving + * Returns : ERR_ABRT: if you have called tcp_abort from within the function! + ******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { + // Sets the callback function that will be called when new data arrives on the connection associated with pcb. + // The callback function will be passed a NULL pbuf to indicate that the remote host has closed the connection. + TCP_SERV_CONN * ts_conn = arg; + if (ts_conn == NULL || pcb == NULL) return ERR_ARG; + +// if(syscfg.cfg.b.hi_speed_enable) set_cpu_clk(); + + if (p == NULL || err != ERR_OK) { // the remote host has closed the connection. + tcpsrv_server_close(ts_conn); + return err; + }; + // если нет функции обработки или ожидаем закрытия соединения, то принимаем данные в трубу + if ((ts_conn->flag.rx_null != 0) || (ts_conn->pcfg->func_recv == NULL) + || (ts_conn->state == SRVCONN_CLOSEWAIT)) { // соединение закрыто? нет. + tcp_recved(pcb, p->tot_len + ts_conn->unrecved_bytes); // сообщает стеку, что съели len и можно посылать ACK и принимать новые данные. + ts_conn->unrecved_bytes = 0; +#if DEBUGSOO > 3 + ts_printf("rec_null %d of %d\n", ts_conn->cntri, p->tot_len); +#endif + pbuf_free(p); // данные выели + return ERR_OK; + }; + ts_conn->state = SRVCONN_CONNECT; // был прием + ts_conn->recv_check = 0; // счет времени до авто-закрытия с нуля + if(p->tot_len) { + err = recv_trim_bufi(ts_conn, p->tot_len); // увеличить буфер + if(err != ERR_OK) return err; + // добавление всего что отдал Lwip в буфер + uint32 len = pbuf_copy_partial(p, &ts_conn->pbufi[ts_conn->sizei], p->tot_len, 0); + ts_conn->sizei += len; + pbuf_free(p); // все данные выели + if(!ts_conn->flag.rx_buf) { + tcp_recved(pcb, len); // сообщает стеку, что съели len и можно посылать ACK и принимать новые данные. + } + else ts_conn->unrecved_bytes += len; +#if DEBUGSOO > 3 + ts_printf("rec %d of %d :\n", p->tot_len, ts_conn->sizei); +#endif + err = ts_conn->pcfg->func_recv(ts_conn); + err_t err2 = recv_trim_bufi(ts_conn, 0); // оптимизировать размер занимаемый буфером + if(err2 != ERR_OK) return err2; + } + return err; +} +/****************************************************************************** + * FunctionName : tcpsrv_unrecved_win + * Description : Update the TCP window. + * This can be used to throttle data reception (e.g. when received data is + * programmed to flash and data is received faster than programmed). + * Parameters : TCP_SERV_CONN * ts_conn + * Returns : none + * После включения throttle, будет принято до 5840 (MAX WIN) + 1460 (MSS) байт? + ******************************************************************************/ +void TCP_SRV_CODE_ATTR tcpsrv_unrecved_win(TCP_SERV_CONN *ts_conn) { + if (ts_conn->unrecved_bytes) { + // update the TCP window +#if DEBUGSOO > 3 + ts_printf("recved_bytes=%d\n", ts_conn->unrecved_bytes); +#endif +#if 1 + if(ts_conn->pcb != NULL) tcp_recved(ts_conn->pcb, ts_conn->unrecved_bytes); +#else + struct tcp_pcb *pcb = find_tcp_pcb(ts_conn); // уже закрыто? + if(pcb != NULL) tcp_recved(ts_conn->pcb, ts_conn->unrecved_bytes); +#endif + } + ts_conn->unrecved_bytes = 0; +} +/****************************************************************************** + * FunctionName : tcpsrv_disconnect + * Description : disconnect with host + * Parameters : ts_conn + * Returns : none + ******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_disconnect_successful(TCP_SERV_CONN * ts_conn) { + ts_conn->pcb = NULL; + if(ts_conn->flag.client && ts_conn->flag.client_reconnect) + tcpsrv_client_reconnect(ts_conn); + else + tcpsrv_list_delete(ts_conn); // remove the node from the server's connection list +} +/****************************************************************************** + * FunctionName : tcpsrv_server_close + * Description : The connection shall be actively closed. + * Parameters : ts_conn + * Returns : none + ******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_server_close(TCP_SERV_CONN * ts_conn) { + + struct tcp_pcb *pcb = ts_conn->pcb; + if(pcb == NULL) { +#if DEBUGSOO > 3 + ts_printf("tcpsrv_server_close, state: %s, pcb = NULL!\n", tspsrv_srvconn_state_msg(ts_conn->state)); +#endif + return; + } +#if DEBUGSOO > 3 + ts_printf("tcpsrv_server_close[%d], state: %s\n", pcb->local_port, tspsrv_srvconn_state_msg(ts_conn->state)); +#endif + if(ts_conn->state != SRVCONN_CLOSEWAIT && ts_conn->state != SRVCONN_CLOSED) { +#if DEBUGSOO > 2 + tcpsrv_print_remote_info(ts_conn); + ts_printf("start close...\n"); +#endif + ts_conn->state = SRVCONN_CLOSEWAIT; + ts_conn->recv_check = 0; + ts_conn->flag.wait_sent = 0; // блок передан + ts_conn->flag.rx_null = 1; // отключение вызова func_received_data() и прием в null + ts_conn->flag.tx_null = 1; // отключение вызова func_sent_callback() и передача в null + // отключение функций приема, передачи и poll + tcp_recv(pcb, NULL); // отключение приема + tcp_sent(pcb, NULL); // отключение передачи + tcp_poll(pcb, NULL, 0); // отключение poll + tcp_err(pcb, NULL); + // + if(ts_conn->unrecved_bytes) { + tcp_recved(pcb, TCP_WND); + ts_conn->unrecved_bytes = 0; + } + // освободить буфера + if (ts_conn->pbufo != NULL) { + os_free(ts_conn->pbufo); + ts_conn->pbufo = NULL; + } + ts_conn->sizeo = 0; + ts_conn->cntro = 0; + if (ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + } + ts_conn->sizei = 0; + ts_conn->cntri = 0; + } + if(ts_conn->state == SRVCONN_CLOSEWAIT || ts_conn->state == SRVCONN_CLOSED) { + if (pcb->state == CLOSED || pcb->state == TIME_WAIT) { + /*remove the node from the server's active connection list*/ +#if DEBUGSOO > 3 + ts_printf("close[%d]\n", pcb->local_port); +#endif + tcpsrv_disconnect_successful(ts_conn); + } else { + if (ts_conn->recv_check > 3) { // счет до принудительного закрытия 3 раза по TCP_SRV_CLOSE_WAIT +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("tcp_abandon!\n"); +#endif + tcp_poll(pcb, NULL, 0); +/// tcp_err(pcb, NULL); + tcp_abandon(pcb, 0); +// ts_conn->pcb = NULL; + // remove the node from the server's active connection list + tcpsrv_disconnect_successful(ts_conn); + } + else if (tcp_close(pcb) != ERR_OK) { // послать закрытие соединения, closing failed +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("+ncls+[%d]\n", pcb->local_port); +#endif + // closing failed, try again later + tcp_poll(pcb, tcpsrv_poll, 2*(TCP_SRV_CLOSE_WAIT)); + } + else { +#if DEBUGSOO > 3 + ts_printf("tcp_close[%d] ok.\n", pcb->local_port); +#endif + tcpsrv_disconnect_successful(ts_conn); + } + } + } +#if DEBUGSOO > 2 + else { + tcpsrv_print_remote_info(ts_conn); + ts_printf("already close!\n"); + } +#endif +} +/****************************************************************************** + * FunctionName : tcpsrv_poll (server and client) + * Description : The poll function is called every 1 second. + * This could be increased, but we don't want to waste resources for bad connections. + * Parameters : arg -- Additional argument to pass to the callback function + * pcb -- The connection pcb for which data has been acknowledged + * Returns : ERR_OK: try to send some data by calling tcp_output + * ERR_ABRT: if you have called tcp_abort from within the function! + *******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_poll(void *arg, struct tcp_pcb *pcb) { + TCP_SERV_CONN * ts_conn = arg; + if (ts_conn == NULL) { +#if DEBUGSOO > 3 + ts_printf("poll, ts_conn = NULL! - abandon\n"); +#endif + tcp_poll(pcb, NULL, 0); + tcp_abandon(pcb, 0); + return ERR_ABRT; + } +#if DEBUGSOO > 3 + tcpsrv_print_remote_info(ts_conn); + ts_printf("poll: %d %s#%s, %d,%d, pcb:%p\n", ts_conn->recv_check, tspsrv_srvconn_state_msg(ts_conn->state), tspsrv_tcp_state_msg(pcb->state), ts_conn->pcfg->time_wait_rec, ts_conn->pcfg->time_wait_cls), pcb; +#endif + if (ts_conn->pcb != NULL && ts_conn->state != SRVCONN_CLOSEWAIT) { + ts_conn->recv_check++; + if (pcb->state == ESTABLISHED) { + if ((ts_conn->state == SRVCONN_LISTEN + && (ts_conn->pcfg->time_wait_rec) + && ts_conn->recv_check > ts_conn->pcfg->time_wait_rec) + || (ts_conn->state == SRVCONN_CONNECT + && (ts_conn->pcfg->time_wait_cls) + && ts_conn->recv_check > ts_conn->pcfg->time_wait_cls)) { + if(ts_conn->flag.client) tcpsrv_client_reconnect(ts_conn); + else tcpsrv_server_close(ts_conn); + } +// else tcpsrv_server_close(ts_conn); + } + else if(ts_conn->state == SRVCONN_CLIENT) { + if(ts_conn->pcfg->time_wait_rec == 0) { + if(ts_conn->recv_check > TCP_CLIENT_MAX_CONNECT_RETRY) + tcpsrv_client_reconnect(ts_conn); + } + else if(ts_conn->recv_check > ts_conn->pcfg->time_wait_rec) { + tcpsrv_client_reconnect(ts_conn); + } + } + else tcpsrv_server_close(ts_conn); + } + else tcpsrv_server_close(ts_conn); + return ERR_OK; +} +/****************************************************************************** + * FunctionName : tcpsrv_list_delete + * Description : remove the node from the connection list + * Parameters : ts_conn + * Returns : none + *******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_list_delete(TCP_SERV_CONN * ts_conn) { +// if (ts_conn == NULL) return; + if(ts_conn->state != SRVCONN_CLOSED) { + ts_conn->state = SRVCONN_CLOSED; // исключить повторное вхождение из запросов в func_discon_cb() + if (ts_conn->pcfg->func_discon_cb != NULL) + ts_conn->pcfg->func_discon_cb(ts_conn); + if(phcfg == NULL || ts_conn->pcfg == NULL) return; // если в func_discon_cb() было вызвано tcpsrv_close_all() и т.д. + } +#if DEBUGSOO > 3 + ts_printf("tcpsrv_list_delete (%p)\n", ts_conn->pcb); +#endif + TCP_SERV_CONN ** p = &ts_conn->pcfg->conn_links; + TCP_SERV_CONN *tcpsrv_cmp = ts_conn->pcfg->conn_links; + while (tcpsrv_cmp != NULL) { + if (tcpsrv_cmp == ts_conn) { + *p = ts_conn->next; + ts_conn->next = NULL; + ts_conn->pcfg->conn_count--; + if (ts_conn->linkd != NULL) { + os_free(ts_conn->linkd); + ts_conn->linkd = NULL; + } + if (ts_conn->pbufo != NULL) { + os_free(ts_conn->pbufo); + ts_conn->pbufo = NULL; + } + if (ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + } + os_free(ts_conn); + return; // break; + } + p = &tcpsrv_cmp->next; + tcpsrv_cmp = tcpsrv_cmp->next; + }; +} +/****************************************************************************** + * FunctionName : tcpsrv_client_reconnect (client) + * Description : освобождение занимаемых ресурсов и + * включение задержки до следующего tcpsrv_client_connect + * Parameters : ts_conn + * Returns : none + *******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_client_reconnect(TCP_SERV_CONN * ts_conn) +{ + if (ts_conn != NULL) { + if(ts_conn->state != SRVCONN_CLIENT) { // не установка соединения (клиент)? +#if DEBUGSOO > 3 + ts_printf("Client free\n"); +#endif + if(ts_conn->state != SRVCONN_CLOSED) { + ts_conn->state = SRVCONN_CLOSED; // исключить повторное вхождение из запросов в func_discon_cb() + if (ts_conn->pcfg->func_discon_cb != NULL) ts_conn->pcfg->func_discon_cb(ts_conn); + } + if (ts_conn->linkd != NULL) { + os_free(ts_conn->linkd); + ts_conn->linkd = NULL; + } + if (ts_conn->pbufo != NULL) { + os_free(ts_conn->pbufo); + ts_conn->pbufo = NULL; + } + if (ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + } + ts_conn->cntri = 0; + ts_conn->cntro = 0; + ts_conn->sizei = 0; + ts_conn->sizeo = 0; + ts_conn->unrecved_bytes = 0; + ts_conn->ptrtx = NULL; + ts_conn->flag = ts_conn->pcfg->flag; + } + if(++ts_conn->pcfg->conn_count == 0) ts_conn->pcfg->conn_count = 0xffff; + if(ts_conn->pcfg->conn_count < ts_conn->pcfg->max_conn || ts_conn->pcfg->max_conn == 0) { +#if DEBUGSOO > 1 + ts_printf("Waiting next connection %u sec...\n", TCP_CLIENT_NEXT_CONNECT_S); +#endif + tcpsrv_client_connect(ts_conn); + } + else tcpsrv_server_close(ts_conn); //tcpsrv_disconnect(ts_conn); + } +} +//----------------------------------------------------------------------------- +static void tspsrv_delete_pcb(TCP_SERV_CONN * ts_conn) +{ + struct tcp_pcb *pcb = find_tcp_pcb(ts_conn); + if(pcb) { + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_err(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_sent(pcb, NULL); + tcp_recved(pcb, TCP_WND); + tcp_close(pcb); + ts_conn->pcb = NULL; + } + tcpsrv_list_delete(ts_conn); +} +/****************************************************************************** + * FunctionName : tcpsrv_error (server and client) + * Description : The pcb had an error and is already deallocated. + * The argument might still be valid (if != NULL). + * Parameters : arg -- Additional argument to pass to the callback function + * err -- Error code to indicate why the pcb has been closed + * Returns : none + *******************************************************************************/ +static void TCP_SRV_CODE_ATTR tcpsrv_error(void *arg, err_t err) { + TCP_SERV_CONN * ts_conn = arg; +// struct tcp_pcb *pcb = NULL; + if (ts_conn != NULL) { +#if DEBUGSOO > 2 + tcpsrv_print_remote_info(ts_conn); + ts_printf("error %d (%s)\n", err, tspsrv_error_msg(err)); +#elif DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); +#ifdef LWIP_DEBUG + ts_printf("error %d (%s)\n", err, tspsrv_error_msg(err)); +#else + ts_printf("error %d\n", err); +#endif +#endif + if (ts_conn->state != SRVCONN_CLOSEWAIT) { + if(ts_conn->flag.client && // если данное соединение клиент + (ts_conn->flag.client_reconnect // вечный реконнект + || (ts_conn->state == SRVCONN_CLIENT // установка соединения + && (ts_conn->pcfg->max_conn == 0 // максимальное кол-во одновременных соединений + || ts_conn->recv_check < ts_conn->pcfg->max_conn)))) { + ts_conn->recv_check++; +#if DEBUGSOO > 3 + ts_printf("go_reconnect\n"); +#endif + tcpsrv_client_reconnect(ts_conn); + } + else if(ts_conn->pcb != NULL) { +// && ts_conn->state != SRVCONN_CLOSED) { +// && (ts_conn->state != SRVCONN_CONNECT || ts_conn->state == SRVCONN_LISTEN)) { +#if DEBUGSOO > 1 + ts_printf("eclose[%d]\n", ts_conn->pcfg->port); +#endif + tcpsrv_list_delete(ts_conn); // remove the node from the server's connection list + }; + }; + } +} +/****************************************************************************** + * FunctionName : tcpsrv_client_connect + * Returns : err + *******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_client_connect(TCP_SERV_CONN * ts_conn) +{ + err_t err = ERR_ARG; + if (ts_conn != NULL) { +#if DEBUGSOO > 3 + ts_printf("tcpsrv_client_connect()\n"); +#endif + struct tcp_pcb *pcb = ts_conn->pcb; + if(pcb != NULL) { // повторный? + pcb = find_tcp_pcb(ts_conn); // ещё жива pcb? + if(pcb != NULL) { + tcp_abandon(pcb, 0); +// ts_conn->pcb = NULL; + } + } + pcb = tcp_new(); + if(pcb != NULL) { + ts_conn->pcb = pcb; + ts_conn->state = SRVCONN_CLIENT; // установка соединения (клиент) +// ts_conn->recv_check = 0; + err_t err = tcp_bind(pcb, IP_ADDR_ANY, 0); // Binds pcb to a local IP address and new port number. // &netif_default->ip_addr +#if DEBUGSOO > 2 + ts_printf("tcp_bind() = %s, port = %d\n", tspsrv_error_msg(err), ts_conn->pcb->local_port); +#endif + if (err == ERR_OK) { // If another connection is bound to the same port, the function will return ERR_USE, otherwise ERR_OK is returned. + ts_conn->pcfg->port = ts_conn->pcb->local_port; + tcp_arg(pcb, ts_conn); // Allocate client-specific session structure, set as callback argument + // Set up the various callback functions + tcp_err(pcb, tcpsrv_error); + tcp_poll(pcb, tcpsrv_poll, 2); // every 1/2 seconds + err = tcp_connect(pcb, (ip_addr_t *)&ts_conn->remote_ip, ts_conn->remote_port, tcpsrv_connected); +#if DEBUGSOO > 2 + ts_printf("tcp_connect() = %s\n", tspsrv_error_msg(err)); +#endif + if(err == ERR_OK) { +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("start client - Ok\n"); +#endif + return err; + } + } + tcp_abandon(pcb, 0); + } + else err = ERR_MEM; // ERR_CONN; + ts_conn->pcb = NULL; +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("start client - error!\n"); +#endif + } + return err; +} +/****************************************************************************** + tcpsrv_connected_fn (client) + *******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_connected(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + TCP_SERV_CONN * ts_conn = arg; + err_t merr = ERR_OK; + if (ts_conn != NULL) { +// os_timer_disarm(&ts_conn->ptimer); + tcp_err(tpcb, tcpsrv_error); + ts_conn->state = SRVCONN_LISTEN; + ts_conn->recv_check = 0; + tcp_sent(tpcb, tcpsrv_server_sent); + tcp_recv(tpcb, tcpsrv_server_recv); + tcp_poll(tpcb, tcpsrv_poll, 2); // every 1/2 seconds + if(ts_conn->pcfg->func_listen != NULL) merr = ts_conn->pcfg->func_listen(ts_conn); + else { +#if DEBUGSOO > 2 + tcpsrv_print_remote_info(ts_conn); + char serr[24]; + if((err > -16) && (err < 1)) { + os_memcpy(serr, srvContenErr[-err], 24); + } + else { + serr[0] = '?'; + serr[1] = '\0'; + } + ts_printf("error %d (%s)\n", err, serr); +#elif DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + ts_printf("connected, error %d\n", err); +#endif + // test + // tcpsrv_int_sent_data(ts_conn, wificonfig.st.config.password, os_strlen(wificonfig.st.config.password)); + } + } + return merr; +} +/****************************************************************************** + * FunctionName : tcpsrv_tcp_accept + * Description : A new incoming connection has been accepted. + * Parameters : arg -- Additional argument to pass to the callback function + * pcb -- The connection pcb which is accepted + * err -- An unused error code, always ERR_OK currently + * Returns : acception result + *******************************************************************************/ +static err_t TCP_SRV_CODE_ATTR tcpsrv_server_accept(void *arg, struct tcp_pcb *pcb, err_t err) { + struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*) arg; + TCP_SERV_CFG *p = tcpsrv_server_port2pcfg(pcb->local_port); + TCP_SERV_CONN * ts_conn; + if (p == NULL) return ERR_ARG; + if (system_get_free_heap_size() < p->min_heap) { +#if DEBUGSOO > 1 + ts_printf("srv[%u] new listen - low heap size!\n", p->port); +#endif + return ERR_MEM; + } + if (p->conn_count >= p->max_conn) { + if(p->flag.srv_reopen) { +#if DEBUGSOO > 1 + ts_printf("srv[%u] reconnect!\n", p->port); +#endif + if (p->conn_links != NULL) { + tspsrv_delete_pcb(p->conn_links); + }; + } + else { +#if DEBUGSOO > 1 + ts_printf("srv[%u] new listen - max connection!\n", p->port); +#endif + return ERR_CONN; + } + } + ts_conn = (TCP_SERV_CONN *) os_zalloc(sizeof(TCP_SERV_CONN)); + if (ts_conn == NULL) { +#if DEBUGSOO > 1 + ts_printf("srv[%u] new listen - out of mem!\n", ts_conn->pcfg->port); +#endif + return ERR_MEM; + } + ts_conn->pcfg = p; + // перенести флаги по умолчанию на данное соединение + ts_conn->flag = p->flag; + tcp_accepted(lpcb); // Decrease the listen backlog counter + // tcp_setprio(pcb, TCP_PRIO_MIN); // Set priority ? + // init/copy data ts_conn + ts_conn->pcb = pcb; + ts_conn->remote_port = pcb->remote_port; + ts_conn->remote_ip.dw = pcb->remote_ip.addr; +// *(uint16 *) &ts_conn->flag = 0; //zalloc +// ts_conn->recv_check = 0; //zalloc +// ts_conn->linkd = NULL; //zalloc + // Insert new ts_conn + ts_conn->next = ts_conn->pcfg->conn_links; + ts_conn->pcfg->conn_links = ts_conn; + ts_conn->pcfg->conn_count++; + ts_conn->state = SRVCONN_LISTEN; + // Tell TCP that this is the structure we wish to be passed for our callbacks. + tcp_arg(pcb, ts_conn); + // Set up the various callback functions + tcp_err(pcb, tcpsrv_error); + tcp_sent(pcb, tcpsrv_server_sent); + tcp_recv(pcb, tcpsrv_server_recv); + tcp_poll(pcb, tcpsrv_poll, 2); /* every 1/2 seconds */ +#if MEMP_MEM_MALLOC // tcp_alloc() уже управляет убийством TIME_WAIT если MEMP_MEM_MALLOC == 0 + if(ts_conn->flag.pcb_time_wait_free) tcpsrv_check_max_tm_tcp_pcb(); + // http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html +#endif + if (p->func_listen != NULL) + return p->func_listen(ts_conn); + return ERR_OK; +} +/****************************************************************************** + * FunctionName : tcpsrv_server_port2pcfg + * Description : поиск конфига servera по порту + * Parameters : номер порта + * Returns : указатель на TCP_SERV_CFG или NULL + *******************************************************************************/ +TCP_SERV_CFG * TCP_SRV_CODE_ATTR tcpsrv_server_port2pcfg(uint16 portn) { + TCP_SERV_CFG * p; + for (p = phcfg; p != NULL; p = p->next) + if (p->port == portn + && (!(p->flag.client))) + return p; + return NULL; +} +/****************************************************************************** + * FunctionName : tcpsrv_client_ip_port2conn + * Description : поиск конфига clienta по ip + порту + * Parameters : номер порта + * Returns : указатель на TCP_SERV_CFG или NULL + *******************************************************************************/ +TCP_SERV_CFG * TCP_SRV_CODE_ATTR tcpsrv_client_ip_port2conn(uint32 ip, uint16 portn) { + TCP_SERV_CFG * p; + for (p = phcfg; p != NULL; p = p->next) + if (p->flag.client + && p->conn_links != NULL + && p->conn_links->remote_ip.dw == ip + && p->conn_links->remote_port == portn) + return p; + return NULL; +} +/****************************************************************************** + tcpsrv_init server or client. + client -> port = 1 ? + *******************************************************************************/ +TCP_SERV_CFG * TCP_SRV_CODE_ATTR tcpsrv_init(uint16 portn) { + // if (portn == 0) portn = 80; + if (portn == 0) return NULL; + TCP_SERV_CFG * p; + for (p = phcfg; p != NULL; p = p->next) { + if (p->port == portn) { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_already_initialized); +#endif + return NULL; + } + } + p = (TCP_SERV_CFG *) os_zalloc(sizeof(TCP_SERV_CFG)); + if (p == NULL) { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_out_of_mem); +#endif + return NULL; + } + p->port = portn; + p->conn_count = 0; + p->min_heap = TCP_SRV_MIN_HEAP_SIZE; + p->time_wait_rec = TCP_SRV_RECV_WAIT; + p->time_wait_cls = TCP_SRV_END_WAIT; + // p->phcfg->conn_links = NULL; // zalloc + // p->pcb = NULL; // zalloc + // p->lnk = NULL; // zalloc + if(portn > ID_CLIENTS_PORT) { + p->max_conn = TCP_SRV_MAX_CONNECTIONS; + p->func_listen = tcpsrv_listen_default; + } + else { + p->max_conn = TCP_CLIENT_MAX_CONNECT_RETRY; + p->flag.client = 1; // данное соединение не сервер, а клиент! + // insert new tcpsrv_config + p->next = phcfg; + phcfg = p; + } + p->func_discon_cb = tcpsrv_disconnect_calback_default; + p->func_sent_cb = tcpsrv_sent_callback_default; + p->func_recv = tcpsrv_received_data_default; + return p; +} +/****************************************************************************** + tcpsrv_start + *******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_start(TCP_SERV_CFG *p) { + err_t err = ERR_OK; + if (p == NULL) { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_NULL_pointer); +#endif + return ERR_ARG; + } + if (p->pcb != NULL) { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_already_initialized); +#endif + return ERR_USE; + } + p->pcb = tcp_new(); + + if (p->pcb != NULL) { + tcp_setprio(p->pcb, TCP_SRV_PRIO); + err = tcp_bind(p->pcb, IP_ADDR_ANY, p->port); // Binds pcb to a local IP address and port number. + if (err == ERR_OK) { // If another connection is bound to the same port, the function will return ERR_USE, otherwise ERR_OK is returned. + p->pcb = tcp_listen(p->pcb); // Commands pcb to start listening for incoming connections. + // When an incoming connection is accepted, the function specified with the tcp_accept() function + // will be called. pcb must have been bound to a local port with the tcp_bind() function. + // The tcp_listen() function returns a new connection identifier, and the one passed as an + // argument to the function will be deallocated. The reason for this behavior is that less + // memory is needed for a connection that is listening, so tcp_listen() will reclaim the memory + // needed for the original connection and allocate a new smaller memory block for the listening connection. + // tcp_listen() may return NULL if no memory was available for the listening connection. + // If so, the memory associated with pcb will not be deallocated. + if (p->pcb != NULL) { + tcp_arg(p->pcb, p->pcb); + // insert new tcpsrv_config + p->next = phcfg; + phcfg = p; + // initialize callback arg and accept callback + tcp_accept(p->pcb, tcpsrv_server_accept); + return err; + } + } + tcp_abandon(p->pcb, 0); + p->pcb = NULL; + } else + err = ERR_MEM; +#if DEBUGSOO > 0 + ts_printf("tcpsrv: not new tcp!\n"); +#endif + return err; +} +/****************************************************************************** + tcpsrv_start_client + TCP_SERV_CFG * p = tcpsrv_init(ID_CLIENTS_PORT); + // insert new tcpsrv_config + p->next = phcfg; + phcfg = p; + *******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_client_start(TCP_SERV_CFG * p, uint32 remote_ip, uint16 remote_port) { + err_t err = ERR_ARG; + if (p == NULL) return err; + if (system_get_free_heap_size() >= p->min_heap) { + TCP_SERV_CONN * ts_conn = (TCP_SERV_CONN *) os_zalloc(sizeof(TCP_SERV_CONN)); + if (ts_conn != NULL) { + ts_conn->flag = p->flag; // перенести флаги по умолчанию на данное соединение + ts_conn->pcfg = p; + ts_conn->state = SRVCONN_CLIENT; // установка соединения (клиент) + ts_conn->remote_port = remote_port; + ts_conn->remote_ip.dw = remote_ip; + err = tcpsrv_client_connect(ts_conn); +// if(ts_conn->pcb != NULL) { + if(err == ERR_OK) { + // Insert new ts_conn + ts_conn->next = p->conn_links; + p->conn_links = ts_conn; + p->conn_count++; +// err = ERR_OK; + } else { +#if DEBUGSOO > 0 + tcpsrv_print_remote_info(ts_conn); + ts_printf("tcpsrv: connect error = %s\n", tspsrv_error_msg(err)); +#endif + os_free(ts_conn); +// err = ERR_CONN; + }; + } + else { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_out_of_mem); +#endif + err = ERR_MEM; + }; + } else { +#if DEBUGSOO > 0 + ts_printf("tcpsrv: low heap size!\n"); +#endif + err = ERR_MEM; + }; + return err; +} +/****************************************************************************** + tcpsrv_close + *******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_close(TCP_SERV_CFG *p) { + if (p == NULL) { +#if DEBUGSOO > 0 + ts_printf(txt_tcpsrv_NULL_pointer); +#endif + return ERR_ARG; + }; + TCP_SERV_CFG **pwr = &phcfg; + TCP_SERV_CFG *pcmp = phcfg; + while (pcmp != NULL) { + if (pcmp == p) { + *pwr = p->next; + while (p->conn_links != NULL) { + tspsrv_delete_pcb(p->conn_links); + }; + if(p->pcb != NULL) tcp_close(p->pcb); + os_free(p); + p = NULL; + return ERR_OK; // break; + } + pwr = &pcmp->next; + pcmp = pcmp->next; + }; +#if DEBUGSOO > 2 + ts_printf("tcpsrv: srv_cfg not find!\n"); +#endif + return ERR_CONN; +} +/****************************************************************************** + tcpsrv_close_port + *******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_close_port(uint16 portn) +{ + if(portn) return tcpsrv_close(tcpsrv_server_port2pcfg(portn)); + else return ERR_ARG; +} +/****************************************************************************** + tcpsrv_close_all_tcp_pcb + *******************************************************************************/ +int TCP_SRV_CODE_ATTR tcpsrv_close_all_tcp_pcb(void) +{ + struct tcp_pcb *pcb; + int ret = 0; + for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { +#if DEBUGSOO > 3 + ts_printf("tcpsrv: abort %p pcb\n", pcb); +#endif + tcp_abort(pcb); + ret = 1; + } + return ret; +} +/****************************************************************************** + tcpsrv_delete_all_tm_tcp_pcb + *******************************************************************************/ +void TCP_SRV_CODE_ATTR tcpsrv_delete_all_tm_tcp_pcb(void) +{ + struct tcp_pcb *pcb; + for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { +#if DEBUGSOO > 3 + ts_printf("tcpsrv: del tm %p pcb\n", pcb); +#endif + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } +} +/****************************************************************************** + tcpsrv_close_all + *******************************************************************************/ +err_t TCP_SRV_CODE_ATTR tcpsrv_close_all(void) +{ + err_t err = ERR_OK; + while(phcfg != NULL && err == ERR_OK) err = tcpsrv_close(phcfg); + if(tcpsrv_close_all_tcp_pcb()) vTaskDelay(50); + tcpsrv_delete_all_tm_tcp_pcb(); + return err; +} + diff --git a/project/src/user/main.c b/project/src/user/main.c new file mode 100644 index 0000000..3cd3427 --- /dev/null +++ b/project/src/user/main.c @@ -0,0 +1,97 @@ +/* + * + */ + +#include "platform_autoconf.h" +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "hal_crypto.h" +#include "hal_log_uart.h" +#include "hal_misc.h" +#include "diag.h" +//#include "wdt_api.h" +//#include +#include "hal_platform.h" +#include "rtl8195a_sys_on.h" + +#ifdef CONFIG_WDG_ON_IDLE +#include "hal_peri_on.h" +#include "rtl8195a_peri_on.h" +#endif + +/* --------------------------------------------------- + * Customized Signature (Image Name) + * ---------------------------------------------------*/ +#include "section_config.h" +SECTION(".custom.validate.rodata") +const unsigned char cus_sig[32] = "WEB Sample"; + +#ifdef CONFIG_DEBUG_LOG +#define DEBUG_MAIN_LEVEL CONFIG_DEBUG_LOG +#else +#define DEBUG_MAIN_LEVEL 0 +#endif + +#ifndef CONFIG_INIT_NET +#define CONFIG_INIT_NET 1 +#endif +#ifndef CONFIG_INTERACTIVE_MODE +#define CONFIG_INTERACTIVE_MODE 1 +#endif + +extern void user_init_thrd(void); + +/* RAM/TCM/Heaps info */ +void ShowMemInfo(void) +{ + DiagPrintf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n", + HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); +} + +/* main */ +void main(void) +{ +#if DEBUG_MAIN_LEVEL > 3 + ConfigDebugErr = -1; + ConfigDebugInfo = ~(_DBG_SPI_FLASH_);//|_DBG_TCM_HEAP_); + ConfigDebugWarn = -1; + CfgSysDebugErr = -1; + CfgSysDebugInfo = -1; + CfgSysDebugWarn = -1; +#endif + +#ifdef CONFIG_WDG_ON_IDLE + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & 0x1FFFFF); +#if CONFIG_DEBUG_LOG > 3 + WDGInitial(CONFIG_WDG_ON_IDLE * 3000); // 30 s +#else + WDGInitial(CONFIG_WDG_ON_IDLE * 1000); // 10 s +#endif + WDGStart(); +#endif + +#if (defined(CONFIG_CRYPTO_STARTUP) && (CONFIG_CRYPTO_STARTUP)) + if(rtl_cryptoEngine_init() != 0 ) { + DBG_8195A("Crypto engine init failed!\n"); + } +#endif + +#if DEBUG_MAIN_LEVEL > 1 + vPortFree(pvPortMalloc(4)); // Init RAM heap + ShowMemInfo(); // RAM/TCM/Heaps info +#endif + + /* wlan & user_start intialization */ + xTaskCreate(user_init_thrd, "user_init", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, NULL); + + /*Enable Schedule, Start Kernel*/ +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED +#ifdef PLATFORM_FREERTOS + vTaskStartScheduler(); +#endif +#else + RtlConsolTaskRom(NULL); +#endif +} diff --git a/project/src/user/user_start.c b/project/src/user/user_start.c new file mode 100644 index 0000000..06a0ef7 --- /dev/null +++ b/project/src/user/user_start.c @@ -0,0 +1,77 @@ +/* + * user_start.c + * + * Created on: 26/03/2017 + * Author: pvvx + */ +#include "user_config.h" +#include "platform_autoconf.h" +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "netbios/netbios.h" +#include "user/sys_cfg.h" +#include "web/web_srv.h" +#include "webfs/webfs.h" + +struct SystemCfg syscfg = { + .cfg.w = SYS_CFG_DEBUG_ENA | SYS_CFG_NETBIOS_ENA, +#if defined(USE_WEB) + .web_port = USE_WEB, +#else + .web_port = 0, +#endif + .web_twrec = 5, + .web_twcls = 5 +}; + +void connect_start(void) +{ + info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount()); +} + +void connect_close(void) +{ + info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount()); +} + +void user_start(void) +{ + info_printf("\%s: Time at start %d ms.\n", __func__, xTaskGetTickCount()); + +} + +void sys_write_cfg(void) +{ + flash_write_cfg(&syscfg, FEEP_ID_SYS_CFG, sizeof(syscfg)); +} + + +void user_init_thrd(void) { + + flash_read_cfg(&syscfg, FEEP_ID_SYS_CFG, sizeof(syscfg)); + + if(!syscfg.cfg.b.debug_print_enable) print_off = 1; + + /* Initilaize the console stack */ + + console_init(); + + /* Web Disk Init */ + WEBFSInit(); + + /* Load cfg, init WiFi + LwIP init, WiFi start if wifi_cfg.mode != RTW_MODE_NONE */ + wifi_init(); + + if(syscfg.cfg.b.netbios_ena) netbios_init(); + + // webstuff_init(); // httpd_init(); + webserver_init(syscfg.web_port); + + // xTaskCreate(x_init_thrd, "wifi_init", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, NULL); + + /* Kill init thread after all init tasks done */ + vTaskDelete(NULL); +} + diff --git a/project/src/web/web_int_callbacks.c b/project/src/web/web_int_callbacks.c new file mode 100644 index 0000000..aa26a07 --- /dev/null +++ b/project/src/web/web_int_callbacks.c @@ -0,0 +1,688 @@ +/****************************************************************************** + * FileName: web_int_callbacks.c + * Description: The web server inernal callbacks. +*******************************************************************************/ + +#include "user_config.h" +#ifdef USE_WEB +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "lwip/tcp.h" +#include "flash_eep.h" +#include "device_lock.h" +#include "ethernetif.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "web_srv_int.h" +#include "web_utils.h" +#include "webfs/webfs.h" +#include "rtl8195a/rtl_libc.h" +#include "user/sys_cfg.h" +#include "wifi_api.h" +#include "sys_api.h" +#include "esp_comp.h" + +#ifdef USE_NETBIOS +#include "netbios.h" +#endif + +#ifdef USE_SNTP +#include "sntp.h" +#endif + +#ifdef USE_CAPTDNS +#include "captdns.h" +#endif + +#ifdef USE_MODBUS +#include "modbustcp.h" +#include "mdbtab.h" +#endif + +#ifdef USE_RS485DRV +#include "driver/rs485drv.h" +#endif + +#ifdef USE_OVERLAY +#include "overlay.h" +#endif + +#define atoi rom_atoi + +#define mMIN(a, b) ((alinkd; + unsigned int len = web_conn->msgbufsize - web_conn->msgbuflen; + if(len > WAV_HEADER_SIZE + 10) { + len -= WAV_HEADER_SIZE; + WAV_HEADER * ptr = (WAV_HEADER *) &web_conn->msgbuf[web_conn->msgbuflen]; + os_memcpy(ptr, &wav_header, WAV_HEADER_SIZE); + ptr->dsize = len; + web_conn->msgbuflen += WAV_HEADER_SIZE; + len >>= 1; + read_adcs((uint16 *)(web_conn->msgbuf + web_conn->msgbuflen), len, 0x0808); + web_conn->msgbuflen += len << 1; + } + SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close +} +#endif // TEST_SEND_WAVE +#if 0 +//=============================================================================== +// WiFi Saved Aps XML +//------------------------------------------------------------------------------- +void ICACHE_FLASH_ATTR wifi_aps_xml(TCP_SERV_CONN *ts_conn) +{ + struct buf_html_string { + uint8 ssid[32*6 + 1]; + uint8 psw[64*6 + 1]; + }; + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd; + struct station_config config[5]; + struct buf_html_string * buf = (struct buf_html_string *)os_malloc(sizeof(struct buf_html_string)); + if(buf == NULL) return; + int total_aps = wifi_station_get_ap_info(config); + // Check if this is a first round call + if(CheckSCB(SCB_RETRYCB)==0) { + tcp_puts_fd("%u%u", total_aps, wifi_station_get_current_ap_id()); + if(total_aps == 0) return; + web_conn->udata_start = 0; + } + while(web_conn->msgbuflen + 74 + 32 <= web_conn->msgbufsize) { + if(web_conn->udata_start < total_aps) { + struct station_config *p = (struct station_config *)&config[web_conn->udata_start]; + if(web_conn->msgbuflen + 74 + htmlcode(buf->ssid, p->ssid, 32*6, 32) + htmlcode(buf->psw, p->password, 64*6, 64) > web_conn->msgbufsize) break; + tcp_puts_fd("%s%s" MACSTR "%d", + web_conn->udata_start, buf->ssid, buf->psw, MAC2STR(p->bssid), p->bssid_set); + web_conn->udata_start++; + if(web_conn->udata_start >= total_aps) { + ClrSCB(SCB_RETRYCB); + os_free(buf); + return; + } + } + else { + ClrSCB(SCB_RETRYCB); + os_free(buf); + return; + } + } + // repeat in the next call ... + SetSCB(SCB_RETRYCB); + SetNextFunSCB(wifi_aps_xml); + os_free(buf); + return; +} +//=============================================================================== +// WiFi Scan XML +//------------------------------------------------------------------------------- +void ICACHE_FLASH_ATTR web_wscan_xml(TCP_SERV_CONN *ts_conn) +{ + struct bss_scan_info si; + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd; + // Check if this is a first round call + if(CheckSCB(SCB_RETRYCB)==0) { + tcp_puts_fd("%d", total_scan_infos); + if(total_scan_infos == 0) return; + web_conn->udata_start = 0; + } + while(web_conn->msgbuflen + 96 + 32 <= web_conn->msgbufsize) { + if(web_conn->udata_start < total_scan_infos) { + struct bss_scan_info *p = (struct bss_scan_info *)buf_scan_infos; + p += web_conn->udata_start; + ets_memcpy(&si, p, sizeof(si)); +/* + uint8 ssid[33]; + ssid[32] = '\0'; + ets_memcpy(ssid, si.ssid, 32); */ + uint8 ssid[32*6 + 1]; + if(web_conn->msgbuflen + 96 + htmlcode(ssid, si.ssid, 32*6, 32) > web_conn->msgbufsize) break; + tcp_puts_fd("%d%d" MACSTR "%s%d%d", web_conn->udata_start, si.channel, si.authmode, MAC2STR(si.bssid), ssid, si.rssi, si.is_hidden); + web_conn->udata_start++; + if(web_conn->udata_start >= total_scan_infos) { + ClrSCB(SCB_RETRYCB); + return; + } + } + else { + ClrSCB(SCB_RETRYCB); + return; + } + } + // repeat in the next call ... + SetSCB(SCB_RETRYCB); + SetNextFunSCB(web_wscan_xml); + return; +} +//=============================================================================== +// WiFi Probe Request XML +//------------------------------------------------------------------------------- +void ICACHE_FLASH_ATTR web_ProbeRequest_xml(TCP_SERV_CONN *ts_conn) +{ + struct s_probe_requests pr; + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd; + // Check if this is a first round call + uint32 cnt = (probe_requests_count < MAX_COUNT_BUF_PROBEREQS)? probe_requests_count : MAX_COUNT_BUF_PROBEREQS; + if(CheckSCB(SCB_RETRYCB)==0) { + if(cnt == 0) { + tcp_strcpy_fd("0"); + return; + } + web_conn->udata_start = 0; + } + while(web_conn->msgbuflen + 92 <= web_conn->msgbufsize) { + if(web_conn->udata_start < cnt) { + struct s_probe_requests *p = (struct s_probe_requests *)&buf_probe_requests; + p += web_conn->udata_start; + ets_memcpy(&pr, p, sizeof(struct s_probe_requests)); + tcp_puts_fd("" MACSTR "%d%d", web_conn->udata_start, MAC2STR(pr.mac), pr.rssi_min, pr.rssi_max); + web_conn->udata_start++; + if(web_conn->udata_start >= cnt) { + tcp_puts_fd("%d", cnt); + ClrSCB(SCB_RETRYCB); + return; + } + } + else { + ClrSCB(SCB_RETRYCB); + return; + } + } + // repeat in the next call ... + SetSCB(SCB_RETRYCB); + SetNextFunSCB(web_ProbeRequest_xml); + return; +} +#endif +#ifdef USE_MODBUS +//=============================================================================== +// Mdb XML +//------------------------------------------------------------------------------- +void ICACHE_FLASH_ATTR web_modbus_xml(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd; + while(web_conn->msgbuflen + 24 <= web_conn->msgbufsize) { + if(web_conn->udata_start < web_conn->udata_stop) { + uint16 val16; + if(RdMdbData((uint8 *)&val16, web_conn->udata_start, 1) != 0) tcp_puts_fd("?", web_conn->udata_start, web_conn->udata_start); + else { + if(ts_conn->flag.user_option2) { + if(ts_conn->flag.user_option1) { + tcp_puts_fd("0x%04x", web_conn->udata_start, val16, web_conn->udata_start); + } + else { + tcp_puts_fd("%04x", web_conn->udata_start, val16, web_conn->udata_start); + }; + } + else { + if(ts_conn->flag.user_option1) { + tcp_puts_fd("%d", web_conn->udata_start, (sint32)((sint16)val16), web_conn->udata_start); + } + else { + tcp_puts_fd("%u", web_conn->udata_start, val16, web_conn->udata_start); + }; + }; + }; + web_conn->udata_start++; + } + else { + ClrSCB(SCB_RETRYCB); + return; + } + } + // repeat in the next call ... + SetSCB(SCB_RETRYCB); + SetNextFunSCB(web_modbus_xml); + return; +} +#endif +//=============================================================================== +// RAM hexdump +//------------------------------------------------------------------------------- +void ICACHE_FLASH_ATTR web_hexdump(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *) ts_conn->linkd; + union { + uint32 dw[4]; + uint8 b[16]; + }data; + web_conn->udata_start &= 0xfffffff0; + uint32 *addr = (uint32 *)web_conn->udata_start; + int i; + web_conn->udata_stop &= 0xfffffff0; + while(web_conn->msgbuflen + (9+3*16+17+2) <= web_conn->msgbufsize) { + if((uint32)addr < 0x9A000000) { + tcp_puts("%08x", addr); + for(i=0 ; i < 4 ; i++) data.dw[i] = *addr++; + web_conn->udata_start = (uint32)addr; + if(ts_conn->flag.user_option1) { + for(i=0 ; i < 4 ; i++) tcp_puts(" %08x", data.dw[i]); + } + else { + for(i=0 ; i < 16 ; i++) tcp_puts(" %02x", data.b[i]); + } + tcp_put(' '); tcp_put(' '); + for(i=0 ; i < 16 ; i++) tcp_put((data.b[i] >=' ' && data.b[i] != 0x7F)? data.b[i] : '.'); + tcp_puts("\r\n"); + if((uint32)addr >= web_conn->udata_stop) { + ClrSCB(SCB_RETRYCB); + SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close + return; + } + } + else { + tcp_puts("%p = Bad address!\r\n", addr); + ClrSCB(SCB_RETRYCB); + SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // connection close + return; + }; + } + // repeat in the next call ... + SetSCB(SCB_RETRYCB); + SetNextFunSCB(web_hexdump); + return; +} +/****************************************************************************** + * FunctionName : web saved flash + * Description : Processing the flash data send + * Parameters : none (Calback) + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR web_get_flash(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + // Check if this is a first round call + if(CheckSCB(SCB_RETRYCB)==0) { + if(web_conn->udata_start == web_conn->udata_stop) return; +#if DEBUGSOO > 2 + os_printf("file_size:%08x ", web_conn->udata_stop - web_conn->udata_start ); +#endif + } + // Get/put as many bytes as possible + unsigned int len = mMIN(web_conn->msgbufsize - web_conn->msgbuflen, web_conn->udata_stop - web_conn->udata_start); + // Read Flash addr = web_conn->webfinc_offsets, len = x, buf = sendbuf +#if DEBUGSOO > 2 + os_printf("%08x..%08x ",web_conn->udata_start, web_conn->udata_start + len ); +#endif +// device_mutex_lock(RT_DEV_LOCK_FLASH); + if(spi_flash_read(web_conn->udata_start, web_conn->msgbuf, len)) { + web_conn->udata_start += len; + web_conn->msgbuflen += len; + if(web_conn->udata_start < web_conn->udata_stop) { + SetNextFunSCB(web_get_flash); +// device_mutex_unlock(RT_DEV_LOCK_FLASH); + SetSCB(SCB_RETRYCB); + return; + }; + }; +// device_mutex_unlock(RT_DEV_LOCK_FLASH); + ClrSCB(SCB_RETRYCB); +// SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + return; +} +/****************************************************************************** + * FunctionName : web saved flash + * Description : Processing the flash data send + * Parameters : none (Calback) + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR web_get_ram(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + // Check if this is a first round call + if(CheckSCB(SCB_RETRYCB)==0) { // On initial call, проверка параметров + if(web_conn->udata_start == web_conn->udata_stop) { +// SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + return; + } +#if DEBUGSOO > 2 + os_printf("file_size:%08x ", web_conn->udata_stop - web_conn->udata_start ); +#endif + } + // Get/put as many bytes as possible + uint32 len = mMIN(web_conn->msgbufsize - web_conn->msgbuflen, web_conn->udata_stop - web_conn->udata_start); + copy_align4(web_conn->msgbuf, (void *)(web_conn->udata_start), len); + web_conn->msgbuflen += len; + web_conn->udata_start += len; +#if DEBUGSOO > 2 + os_printf("%08x-%08x ",web_conn->udata_start, web_conn->udata_start + len ); +#endif + if(web_conn->udata_start != web_conn->udata_stop) { + SetSCB(SCB_RETRYCB); + SetNextFunSCB(web_get_ram); + return; + }; + ClrSCB(SCB_RETRYCB); +// SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + return; +} +/****************************************************************************** + * FunctionName : web_callback + * Description : callback + * Parameters : struct TCP_SERV_CONN + * Returns : none + ******************************************************************************/ +void ICACHE_FLASH_ATTR web_int_callback(TCP_SERV_CONN *ts_conn, uint8 *cstr) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; +// uint8 *cstr = &web_conn->msgbuf[web_conn->msgbuflen]; + { + uint8 *vstr = os_strchr(cstr, '='); + if(vstr != NULL) { + *vstr++ = '\0'; + web_int_vars(ts_conn, cstr, vstr); + return; + } + } +#if DEBUGSOO > 3 + os_printf("[%s]\n", cstr); +#endif + ifcmp("start") tcp_puts("0x%08x", web_conn->udata_start); + else ifcmp("stop") tcp_puts("0x%08x", web_conn->udata_stop); + else ifcmp("xml_") { + cstr+=4; + web_conn->udata_start&=~3; + ifcmp("ram") tcp_puts("0x%08x", *((uint32*)web_conn->udata_start)); + else tcp_put('?'); + web_conn->udata_start += 4; + } + else ifcmp("sys_") { + cstr+=4; + ifcmp("cid") tcp_puts("%08x", HalGetChipId()); + else ifcmp("fid") tcp_puts("%08x", spi_flash_get_id()); + else ifcmp("fsize") tcp_puts("%u", spi_flash_real_size()); // flashchip->chip_size + else ifcmp("sdkver") tcp_strcpy_fd(SDK_VERSION); + else ifcmp("sysver") tcp_strcpy_fd(SYS_VERSION); + else ifcmp("webver") tcp_strcpy_fd(WEB_SVERSION); + else ifcmp("heap") tcp_puts("%u", xPortGetFreeHeapSize()); + else ifcmp("heapm") tcp_puts("%u", xPortGetMinimumEverFreeHeapSize()); + else ifcmp("tcmh") tcp_puts("%u", tcm_heap_freeSpace()); + else ifcmp("time") tcp_puts("%u", xTaskGetTickCount()); + else ifcmp("mactime") { + if(wifi_mode) { + union { + uint32 dw[2]; + uint64 dd; + }ux; + ux.dd = *((uint64_t *)(WIFI_REG_BASE + 0x0560)); // REG_TSFTR -> #include "hal_com_reg.h" + tcp_puts("0x%08x%08x", ux.dw[1], ux.dw[0]); + } + } + else ifcmp("clkcpu") tcp_puts("%u", HalGetCpuClk()); + else ifcmp("debug") tcp_put('1' - (print_off & 1)); // rtl_print on/off + else ifcmp("restart") web_conn->web_disc_cb = (web_func_disc_cb)sys_reset; + else ifcmp("ram") tcp_puts("0x%08x", *((uint32 *)(ahextoul(cstr+3)&(~3)))); + else ifcmp("rdec") tcp_puts("%d", *((uint32 *)(ahextoul(cstr+4)&(~3)))); + else ifcmp("ip") { + uint32 cur_ip; + if(netif_default != NULL) cur_ip = netif_default->ip_addr.addr; + tcp_puts(IPSTR, IP2STR(&cur_ip)); + } +#ifdef USE_NETBIOS + else ifcmp("netbios") { + if(syscfg.cfg.b.netbios_ena) tcp_strcpy(netbios_name); + } +#endif + else tcp_put('?'); + } + else ifcmp("cfg_") { + cstr += 4; + ifcmp("web_") { + cstr += 4; + ifcmp("port") tcp_puts("%u", syscfg.web_port); + else ifcmp("twrec") tcp_puts("%u", syscfg.web_twrec); + else ifcmp("twcls") tcp_puts("%u", syscfg.web_twcls); + else ifcmp("twd") tcp_put((syscfg.cfg.b.web_time_wait_delete)? '1' : '0'); + else tcp_put('?'); + } + else ifcmp("pinclr") tcp_put((syscfg.cfg.b.pin_clear_cfg_enable)? '1' : '0'); + else ifcmp("debug") tcp_put((syscfg.cfg.b.debug_print_enable)? '1' : '0'); +#ifdef USE_NETBIOS + else ifcmp("netbios") tcp_put((syscfg.cfg.b.netbios_ena)? '1' : '0'); +#endif +#ifdef USE_SNTP + else ifcmp("sntp") tcp_put((syscfg.cfg.b.sntp_ena)? '1' : '0'); +#endif +#ifdef USE_CAPTDNS + else ifcmp("cdns") tcp_put((syscfg.cfg.b.cdns_ena)? '1' : '0'); +#endif + else tcp_put('?'); + } + else ifcmp("wifi_") { + cstr+=5; + ifcmp("rdcfg") read_wifi_cfg(-1); + else ifcmp("newcfg") { + web_conn->web_disc_cb = (web_func_disc_cb)wifi_run; + web_conn->web_disc_par = wifi_cfg.mode; + } + else ifcmp("cmode") tcp_puts("%d", wifi_mode); + else ifcmp("mode") tcp_puts("%d", wifi_cfg.mode); + else ifcmp("bgn") tcp_puts("%d", wifi_cfg.bgn); + else ifcmp("sleep") tcp_puts("%d", wifi_cfg.sleep); + else ifcmp("txpow") tcp_puts("%u", wifi_cfg.tx_pwr); + else ifcmp("lflg") tcp_puts("%u", wifi_cfg.load_flg); + else ifcmp("sflg") tcp_puts("%u", wifi_cfg.save_flg); + else ifcmp("country") tcp_puts("%u", wifi_cfg.country_code); + else ifcmp("ap_") { + cstr+=3; + ifcmp("ssid") { + int len = os_strlen(wifi_ap_cfg.ssid); + if(len > sizeof(wifi_ap_cfg.ssid)) { + len = sizeof(wifi_ap_cfg.ssid); + } + os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_ap_cfg.ssid, len); + web_conn->msgbuflen += len; + } + else ifcmp("psw") { + int len = os_strlen(wifi_ap_cfg.password); + if(len > sizeof(wifi_ap_cfg.password)) { + len = sizeof(wifi_ap_cfg.password); + } + os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_ap_cfg.password, len); + web_conn->msgbuflen += len; + } + else ifcmp("chl") tcp_puts("%u", wifi_ap_cfg.channel); + else ifcmp("mcns") tcp_puts("%u", wifi_ap_cfg.max_sta); + else ifcmp("auth") tcp_put((wifi_ap_cfg.security_type == RTW_SECURITY_OPEN) ? '0' : '1'); + else ifcmp("hssid") tcp_put((wifi_ap_cfg.ssid_hidden & 1) + '0'); + else ifcmp("bint") tcp_puts("%u", wifi_ap_cfg.beacon_interval); + else ifcmp("mac") tcp_puts(MACSTR, MAC2STR(xnetif[wlan_ap_netifn].hwaddr)); + else ifcmp("hostname") tcp_strcpy(lwip_host_name[wlan_ap_netifn]); + else ifcmp("dhcp") tcp_puts("%u", wifi_ap_dhcp.mode); + else ifcmp("ip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.ip)); + else ifcmp("gw") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.gw)); + else ifcmp("msk") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.mask)); + else ifcmp("cip") tcp_puts(IPSTR, IP2STR(&xnetif[wlan_st_netifn].ip_addr.addr)); + + // else ifcmp("mac") strtomac(pvar, wifi_ap_cfg.macaddr); + // else ifcmp("sip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.start_ip)); + // else ifcmp("eip") tcp_puts(IPSTR, IP2STR(&wifi_ap_dhcp.end_ip)); + #if DEBUGSOO > 2 + else os_printf(" - none! "); + #endif + } + else ifcmp("st_") { + cstr+=3; + ifcmp("rssi") { + int rssi; + wifi_get_rssi(&rssi); + tcp_puts("%d", rssi); + } + else ifcmp("arec") tcp_puts("%u", wifi_st_cfg.autoreconnect); + else ifcmp("rect") tcp_puts("%u", wifi_st_cfg.reconnect_pause); + else ifcmp("ssid") { + int len = os_strlen(wifi_st_cfg.ssid); + if(len > sizeof(wifi_st_cfg.ssid)) { + len = sizeof(wifi_st_cfg.ssid); + } + os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_st_cfg.ssid, len); + web_conn->msgbuflen += len; + } + else ifcmp("psw") { + int len = os_strlen(wifi_st_cfg.password); + if(len > sizeof(wifi_st_cfg.password)) { + len = sizeof(wifi_st_cfg.password); + } + os_memcpy((char *)&web_conn->msgbuf[web_conn->msgbuflen], wifi_st_cfg.password, len); + web_conn->msgbuflen += len; + } + else ifcmp("mac") tcp_puts(MACSTR, MAC2STR(xnetif[wlan_st_netifn].hwaddr)); + else ifcmp("bssid") tcp_puts(MACSTR, MAC2STR(wifi_st_cfg.bssid)); + else ifcmp("sbss") tcp_puts("%u", wifi_st_cfg.flg); +#if LWIP_NETIF_HOSTNAME + else ifcmp("hostname") tcp_strcpy(lwip_host_name[wlan_st_netifn]); +#endif + else ifcmp("auth") tcp_puts("%u", wifi_st_cfg.security_type); + else ifcmp("dhcp") tcp_puts("%u", wifi_st_dhcp.mode); + else ifcmp("ip") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.ip)); + else ifcmp("gw") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.gw)); + else ifcmp("msk") tcp_puts(IPSTR, IP2STR(&wifi_st_dhcp.mask)); + #if DEBUGSOO > 5 + else os_printf(" - none!\n"); + #endif + } +#if DEBUGSOO > 5 + else os_printf(" - none!\n"); +#endif + } + else ifcmp("bin_") { + cstr+=4; + ifcmp("flash") { + cstr+=5; + if(*cstr == '_') { + cstr++; + ifcmp("all") { + web_conn->udata_start = 0; + web_conn->udata_stop = spi_flash_real_size(); + web_get_flash(ts_conn); + } + else ifcmp("sec_") { + web_conn->udata_start = ahextoul(cstr+4) << 12; + web_conn->udata_stop = web_conn->udata_start + FLASH_SECTOR_SIZE; + web_get_flash(ts_conn); + } + else ifcmp("disk") { + web_conn->udata_start = WEBFS_base_addr(); + web_conn->udata_stop = web_conn->udata_start + WEBFS_curent_size(); + web_get_flash(ts_conn); + } + else tcp_put('?'); + } + else web_get_flash(ts_conn); + } + else ifcmp("ram") web_get_ram(ts_conn); + else tcp_put('?'); + } + else ifcmp("hexdmp") { + if(cstr[6]=='d') ts_conn->flag.user_option1 = 1; + else ts_conn->flag.user_option1 = 0; + web_hexdump(ts_conn); + } + else ifcmp("web_") { + cstr+=4; + ifcmp("port") tcp_puts("%u", ts_conn->pcfg->port); + else ifcmp("host") tcp_puts(IPSTR ":%d", IP2STR(&(ts_conn->pcb->local_ip.addr)), ts_conn->pcb->local_port); + else ifcmp("remote") tcp_puts(IPSTR ":%d", IP2STR(&(ts_conn->remote_ip.dw)), ts_conn->remote_port); + else ifcmp("twrec") tcp_puts("%u", ts_conn->pcfg->time_wait_rec); + else ifcmp("twcls") tcp_puts("%u", ts_conn->pcfg->time_wait_cls); + else tcp_put('?'); + } + else ifcmp("wfs_") { + cstr+=4; + ifcmp("files") tcp_puts("%u", numFiles); + else ifcmp("addr") tcp_puts("0x%08x", WEBFS_base_addr()); + else ifcmp("size") tcp_puts("%u", WEBFS_curent_size()); + else ifcmp("max_size") tcp_puts("%u", WEBFS_max_size()); + else tcp_put('?'); + } +#ifdef USE_OVERLAY + else ifcmp("ovl") { + cstr += 3; + if(*cstr == ':') { + int i = ovl_loader(cstr + 1); + if (i == 0) { + if(CheckSCB(SCB_WEBSOC)) { + tcp_puts("%d", ovl_call(1)); + } + else { + web_conn->web_disc_cb = (web_func_disc_cb)ovl_call; // адрес старта оверлея + web_conn->web_disc_par = 1; // параметр функции - инициализация + } + } + tcp_puts("%d", i); + } + else if(*cstr == '$') { + if(ovl_call != NULL) tcp_puts("%d", ovl_call(ahextoul(cstr + 1))); + else tcp_put('?'); + } + else if(*cstr == '@') { + if(ovl_call != NULL) tcp_puts("%d", ovl_call((int) cstr + 1)); + else tcp_put('?'); + } + else tcp_put('?'); + } +#endif +#ifdef USE_SNTP + else ifcmp("sntp_") { + cstr += 5; + ifcmp("time") tcp_puts("%u", get_sntp_time()); + else tcp_put('?'); + } +#endif +#ifdef TEST_SEND_WAVE + else ifcmp("test_adc") web_test_adc(ts_conn); +#endif + else ifcmp("hellomsg") tcp_puts_fd("Web on RTL871x!"); + else tcp_put('?'); +} + + +#endif // USE_WEB diff --git a/project/src/web/web_int_vars.c b/project/src/web/web_int_vars.c new file mode 100644 index 0000000..947eb52 --- /dev/null +++ b/project/src/web/web_int_vars.c @@ -0,0 +1,356 @@ +/****************************************************************************** + * FileName: webserver.c + * Description: The web server mode configuration. +*******************************************************************************/ + +#include "user_config.h" +#ifdef USE_WEB +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "lwip/ip.h" +#include "lwip/ip_addr.h" +#include "lwip/tcp.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "ethernetif.h" +#include "web_srv_int.h" +#include "web_utils.h" +#include "flash_eep.h" +#include "device_lock.h" +#include "rtl8195a/rtl_libc.h" +#include "user/sys_cfg.h" +#include "wifi_api.h" +#include "sys_api.h" +#include "esp_comp.h" + +#ifdef USE_NETBIOS +#include "netbios.h" +#endif + +#ifdef USE_SNTP +#include "sntp.h" +#endif + +#ifdef USE_LWIP_PING +#include "lwip/app/ping.h" +struct ping_option pingopt; // for test +#endif + +#ifdef USE_CAPTDNS +#include "captdns.h" +#endif + +#ifdef USE_MODBUS +#include "modbustcp.h" +#include "mdbtab.h" +#endif + +#ifdef USE_RS485DRV +#include "driver/rs485drv.h" +#include "mdbrs485.h" +#endif + +#ifdef USE_OVERLAY +#include "overlay.h" +#endif + +extern void web_get_ram(TCP_SERV_CONN *ts_conn); +extern void web_get_flash(TCP_SERV_CONN *ts_conn); +extern void web_hexdump(TCP_SERV_CONN *ts_conn); + +#define ifcmp(a) if(rom_xstrcmp(cstr, a)) + +extern int rom_atoi(const char *); +#define atoi rom_atoi + +typedef uint32 (* call_func)(uint32 a, uint32 b, uint32 c); + +/****************************************************************************** + * FunctionName : parse_url + * Description : parse the received data from the server + * Parameters : CurHTTP -- the result of parsing the url + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR web_int_vars(TCP_SERV_CONN *ts_conn, uint8 *pcmd, uint8 *pvar) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + uint32 val = ahextoul(pvar); + char *cstr = pcmd; +#if DEBUGSOO > 1 + os_printf("[%s=%s]\n", pcmd, pvar); +#endif + ifcmp("start") web_conn->udata_start = val; + else ifcmp("stop") web_conn->udata_stop = val; + else ifcmp("sys_") { + cstr+=4; + ifcmp("restart") { + if(val == 12345) web_conn->web_disc_cb = (web_func_disc_cb)sys_reset; + } + else ifcmp("ram") { uint32 *ptr = (uint32 *)(ahextoul(cstr+3)&(~3)); str_array(pvar, ptr, 32); } + else ifcmp("debug") print_off = (!val) & 1; // rtl_print on/off +#ifdef USE_LWIP_PING + else ifcmp("ping") { +// struct ping_option *pingopt = (struct ping_option *)UartDev.rcv_buff.pRcvMsgBuff; + pingopt.ip = ipaddr_addr(pvar); + pingopt.count = 3; + pingopt.recv_function=NULL; + pingopt.sent_function=NULL; + ping_start(&pingopt); + } +#endif + } + else ifcmp("cfg_") { + cstr += 4; + ifcmp("web_") { + cstr += 4; + ifcmp("port") { + if(syscfg.web_port != val) { + web_conn->web_disc_par = syscfg.web_port; // ts_conn->pcfg->port + syscfg.web_port = val; + web_conn->web_disc_cb = (web_func_disc_cb)webserver_reinit; + } + } + else ifcmp("twd") { + if(val) { + syscfg.cfg.b.web_time_wait_delete = 1; + ts_conn->pcfg->flag.pcb_time_wait_free = 1; + } + else { + syscfg.cfg.b.web_time_wait_delete = 0; + ts_conn->pcfg->flag.pcb_time_wait_free = 0; + } + } + else ifcmp("twrec") { + syscfg.web_twrec = val; + ts_conn->pcfg->time_wait_rec = val; + } + else ifcmp("twcls") { + syscfg.web_twcls = val; + ts_conn->pcfg->time_wait_cls = val; + } +#if DEBUGSOO > 5 + else os_printf(" - none!\n"); +#endif + } + else ifcmp("pinclr") syscfg.cfg.b.pin_clear_cfg_enable = (val)? 1 : 0; + else ifcmp("debug") { + syscfg.cfg.b.debug_print_enable = val; + print_off = (!val) & 1; // rtl_print on/off + } + else ifcmp("save") { + if(val == 2) SetSCB(SCB_SYSSAVE); // по закрытию соединения вызвать sys_write_cfg() + else if(val == 1) sys_write_cfg(); + } +#ifdef USE_NETBIOS + else ifcmp("netbios") { + syscfg.cfg.b.netbios_ena = (val)? 1 : 0; + if(syscfg.cfg.b.netbios_ena) netbios_init(); + else netbios_off(); + } +#endif +#ifdef USE_SNTP + else ifcmp("sntp") { + syscfg.cfg.b.sntp_ena = (val)? 1 : 0; + if(syscfg.cfg.b.sntp_ena) sntp_inits(); + else sntp_close(); + } +#endif +#ifdef USE_CAPTDNS + else ifcmp("cdns") { + syscfg.cfg.b.cdns_ena = (val)? 1 : 0; + if(syscfg.cfg.b.cdns_ena && wifi_softap_get_station_num()) captdns_init(); + else captdns_close(); + } +#endif +#if DEBUGSOO > 5 + else os_printf(" - none!\n"); +#endif + // sys_write_cfg(); + } + else ifcmp("wifi_") { + cstr+=5; + ifcmp("rdcfg") web_conn->udata_stop = read_wifi_cfg(val); + else ifcmp("newcfg") { + web_conn->web_disc_cb = (web_func_disc_cb)wifi_run; + web_conn->web_disc_par = wifi_cfg.mode; + } + else ifcmp("mode") wifi_cfg.mode = val; + else ifcmp("bgn") wifi_cfg.bgn = val; + else ifcmp("lflg") wifi_cfg.load_flg = val; + else ifcmp("sflg") wifi_cfg.save_flg = val; + else ifcmp("sleep") wifi_cfg.sleep = val; + else ifcmp("txpow") wifi_cfg.tx_pwr = val; + else ifcmp("country") wifi_cfg.country_code = val; +// else ifcmp("scan") { +// web_conn->web_disc_par = val; +// web_conn->web_disc_cb = (web_func_disc_cb)wifi_start_scan; +// } + else ifcmp("save") { write_wifi_cfg(val); } + else ifcmp("ap_") { + cstr+=3; + ifcmp("ssid") { + if(pvar[0]!='\0') { + int len = os_strlen(pvar); + if(len > sizeof(wifi_ap_cfg.ssid)) { + len = sizeof(wifi_ap_cfg.ssid); + } + else os_memset(wifi_ap_cfg.ssid, 0, sizeof(wifi_ap_cfg.ssid)); + os_memcpy(wifi_ap_cfg.ssid, pvar, len); +#ifdef USE_NETBIOS + netbios_set_name(wifi_ap_cfg.ssid); +#endif + } + } + else ifcmp("psw") { + int len = os_strlen(pvar); + if(len > sizeof(wifi_ap_cfg.password)) { + len = sizeof(wifi_ap_cfg.password); + } + else os_memset(wifi_ap_cfg.password, 0, sizeof(wifi_ap_cfg.password)); + os_memcpy(wifi_ap_cfg.password, pvar, len); + } + else ifcmp("chl") wifi_ap_cfg.channel = val; + else ifcmp("mcns") wifi_ap_cfg.max_sta = val; + else ifcmp("auth") wifi_ap_cfg.security_type = (val)? RTW_SECURITY_WEP_PSK : RTW_SECURITY_OPEN; + else ifcmp("hssid") wifi_ap_cfg.ssid_hidden = val; + else ifcmp("bint") wifi_ap_cfg.beacon_interval = val; +#if LWIP_NETIF_HOSTNAME + else ifcmp("hostname") { + int len = os_strlen(pvar); + if(len >= LWIP_NETIF_HOSTNAME_SIZE) { + len = LWIP_NETIF_HOSTNAME_SIZE-1; + } + os_memcpy(lwip_host_name[wlan_ap_netifn], pvar, len); + lwip_host_name[wlan_ap_netifn][len] = 0; + netbios_set_name(wlan_ap_netifn, pvar); + } +#endif + else ifcmp("dhcp") wifi_ap_dhcp.mode = val; + else ifcmp("ip") wifi_ap_dhcp.ip = ipaddr_addr(pvar); + else ifcmp("gw") wifi_ap_dhcp.gw = ipaddr_addr(pvar); + else ifcmp("msk") wifi_ap_dhcp.mask = ipaddr_addr(pvar); +// else ifcmp("mac") strtomac(pvar, wifi_ap_cfg.macaddr); +// else ifcmp("sip") wifi_ap_dhcp.start_ip = ipaddr_addr(pvar); +// else ifcmp("eip") wifi_ap_dhcp.end_ip = ipaddr_addr(pvar); +#if DEBUGSOO > 2 + else os_printf(" - none! "); +#endif + } + else ifcmp("st_") { + cstr+=3; + ifcmp("arec") wifi_st_cfg.autoreconnect = val; + else ifcmp("rect") wifi_st_cfg.reconnect_pause = val; + else ifcmp("ssid") { + if(pvar[0]!='\0') { + int len = os_strlen(pvar); + if(len > sizeof(wifi_st_cfg.ssid)) { + len = sizeof(wifi_st_cfg.ssid); + } + else os_memset(wifi_st_cfg.ssid, 0, sizeof(wifi_st_cfg.ssid)); + os_memcpy(wifi_st_cfg.ssid, pvar, len); + } + } + else ifcmp("psw") { + int len = os_strlen(pvar); + if(len > sizeof(wifi_st_cfg.password)) { + len = sizeof(wifi_st_cfg.password); + } + else os_memset(wifi_st_cfg.password, 0, sizeof(wifi_st_cfg.password)); + os_memcpy(wifi_st_cfg.password, pvar, len); + } + else ifcmp("auth") wifi_st_cfg.security_type = val; + else ifcmp("bssid") strtomac(pvar, wifi_st_cfg.bssid); + else ifcmp("sbss") wifi_st_cfg.flg = val; +#if LWIP_NETIF_HOSTNAME + else ifcmp("hostname") { + int len = os_strlen(pvar); + if(len >= LWIP_NETIF_HOSTNAME_SIZE) { + len = LWIP_NETIF_HOSTNAME_SIZE-1; + } + os_memcpy(lwip_host_name[wlan_st_netifn], pvar, len); + lwip_host_name[wlan_st_netifn][len] = 0; + netbios_set_name(wlan_st_netifn, pvar); + } +#endif + else ifcmp("dhcp") wifi_st_dhcp.mode = val; + else ifcmp("ip") wifi_st_dhcp.ip = ipaddr_addr(pvar); + else ifcmp("gw") wifi_st_dhcp.gw = ipaddr_addr(pvar); + else ifcmp("msk") wifi_st_dhcp.mask = ipaddr_addr(pvar); +// else ifcmp("mac") strtomac(pvar, wifi_st_cfg.mac); +// else ifcmp("sbss") wifi_st_cfg.bssidx = val; +#if DEBUGSOO > 5 + else os_printf(" - none!\n"); +#endif + } +#if DEBUGSOO > 5 + else os_printf(" - none!\n"); +#endif + } + else if(web_conn->bffiles[0]==WEBFS_WEBCGI_HANDLE && CheckSCB(SCB_GET)) { + ifcmp("hexdmp") { +#if DEBUGSOO > 5 + os_printf("hexdmp(%p)\n", val); +#endif + if(val > 0) { + if(cstr[6]=='d') ts_conn->flag.user_option1 = 1; + else ts_conn->flag.user_option1 = 0; + uint32 x = ahextoul(cstr+7); + web_conn->udata_start = x; + web_conn->udata_stop = val + web_conn->udata_start; +#if DEBUGSOO > 5 + os_printf("start=%p, stop=%p\n", web_conn->udata_start, web_conn->udata_stop); +#endif + web_conn->fileType = HTTP_TXT; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_hexdump); + }; + } + else ifcmp("flash") { + cstr+=5; + if(*cstr == '_') { + cstr++; + ifcmp("all") { + web_conn->udata_start = 0; + web_conn->udata_stop = spi_flash_real_size(); + web_conn->fileType = HTTP_BIN; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_get_flash); + } + else ifcmp("sec_") { + web_conn->udata_start = ahextoul(cstr+4) << 12; + web_conn->udata_stop = web_conn->udata_start + FLASH_SECTOR_SIZE*val; + web_conn->fileType = HTTP_BIN; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_get_flash); + } + else ifcmp("disk") { + web_conn->udata_start = WEBFS_base_addr(); + web_conn->udata_stop = web_conn->udata_start + WEBFS_curent_size(); + web_conn->fileType = HTTP_BIN; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_get_flash); + } + else tcp_put('?'); + } + else { + web_conn->fileType = HTTP_BIN; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_get_flash); + } + } + else ifcmp("bin_ram") { + web_conn->fileType = HTTP_BIN; + SetSCB(SCB_RETRYCB | SCB_FCALBACK); + SetNextFunSCB(web_get_ram); + } +#if DEBUGSOO > 5 + else os_printf(" - none! "); +#endif + } +#if DEBUGSOO > 5 + else os_printf(" - none! "); +#endif +} + +#endif // USE_WEB diff --git a/project/src/web/web_srv.c b/project/src/web/web_srv.c new file mode 100644 index 0000000..93154e0 --- /dev/null +++ b/project/src/web/web_srv.c @@ -0,0 +1,2073 @@ +/****************************************************************************** + * FileName: webserver.c + * Description: Small WEB server + WebSocket + * Author: pvvx + * ver1.0 25/12/2014 SDK 0.9.4 + * ver1.1 02/04/2015 SDK 1.0.0 + * ver2.0 14/14/2017 RTL871x +*******************************************************************************/ +#include "user_config.h" +#ifdef USE_WEB +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "lwip/tcp.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "web_srv_int.h" +#include "web_utils.h" +#include "flash_eep.h" +#include "device_lock.h" +#include "webfs/webfs.h" +#include "user/sys_cfg.h" +#include "wifi_api.h" +#include "rtl8195a/rtl_libc.h" +#include "esp_comp.h" + +#ifdef WEBSOCKET_ENA +#include "web_websocket.h" +#endif + +#ifdef USE_CAPTDNS +#include "captdns.h" +#endif + +#ifdef USE_OVERLAY +#include "overlay.h" +#endif + +#define USE_WEB_NAGLE // https://en.wikipedia.org/wiki/Nagle%27s_algorithm +#define MIN_REQ_LEN 7 // Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes +#define CRLF "\r\n" + +#define max_len_buf_write_flash 2048 // размер буфера при записи flash. Увеличение/уменньшение размера (до сектора 4096) ускорения не дает (1..2%) + +#define mMIN(a, b) ((ab)?a:b) + +#define atoi(s) rom_atoi(s) + +LOCAL void web_print_headers(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) ICACHE_FLASH_ATTR ; + +//LOCAL void webserver_discon(void *arg) ICACHE_FLASH_ATTR; +//LOCAL void webserver_recon(void *arg, sint8 err) ICACHE_FLASH_ATTR; +LOCAL void webserver_send_fdata(TCP_SERV_CONN *ts_conn) ICACHE_FLASH_ATTR; +LOCAL void web_int_disconnect(TCP_SERV_CONN *ts_conn) ICACHE_FLASH_ATTR; +LOCAL bool webserver_open_file(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) ICACHE_FLASH_ATTR; +LOCAL void webserver_file_ext(HTTP_CONN *CurHTTP, uint8 *pfname) ICACHE_FLASH_ATTR; + +const char http_default_file[] ICACHE_RODATA_ATTR = "index.htm"; +const char web_cgi_fname[] ICACHE_RODATA_ATTR = "web.cgi"; +const char fsupload_fname[] ICACHE_RODATA_ATTR = "fsupload"; +#ifdef USE_CAPTDNS +const char ncsi_txt_fname[] ICACHE_RODATA_ATTR = "ncsi.txt"; +//const char generate_204_fname[] ICACHE_RODATA_ATTR = "generate_204"; +const char *HTTPHost ="Host:"; +#define sizeHTTPHost 5 +#endif +#define ProtectedFilesName "protect" + +#define MAX_NO_DATA_BUF_SIZE (8192) // if(ts_conn->sizei > MAX_NO_DATA_BUF_SIZE) CurHTTP->httpStatus = 418; // 418: Out of Coffee + +QueueHandle_t xQueueWebSrv; + +/**************************************************************************** + Section: + File and Content Type Settings + ***************************************************************************/ + // File type extensions corresponding to HTTP_FILE_TYPE +static const char *httpFileExtensions[] = { + "txt", // HTTP_TXT + "htm", // HTTP_HTML + "cgi", // HTTP_CGI + "xml", // HTTP_XML + "css", // HTTP_CSS + "ico", // HTTP_ICO + "gif", // HTTP_GIF + "png", // HTTP_PNG + "jpg", // HTTP_JPG + "svg", // HTTP_SVG + "js", // HTTP_JAVA + "swf", // HTTP_SWF + "wav", // HTTP_WAV + "pdf", // HTTP_PDF + "zip", // HTTP_ZIP + "bin", // HTTP_BIN + "\0\0\0" // HTTP_UNKNOWN +}; + +// Content-type strings corresponding to HTTP_FILE_TYPE +static const char *httpContentTypes[] = { + "text/plain", // HTTP_TXT "txt", + "text/html", // HTTP_HTM "htm", + "magnus-internal/cgi", // HTTP_CGI "cgi", + "text/xml", // HTTP_XML "xml", + "text/css", // HTTP_CSS "css", + "image/vnd.microsoft.icon", // HTTP_ICO "ico", + "image/gif", // HTTP_GIF "gif", + "image/png", // HTTP_PNG "png", + "image/jpeg", // HTTP_JPG "jpg", + "image/svg+xml", // HTTP_SVG "svg", + "text/javascript", // HTTP_JAVA "js", + "application/x-shockwave-flash", // HTTP_SWF "swf", + "audio/x-wave", // HTTP_WAV "wav", + "application/pdf", // HTTP_PDF "pdf", + "application/zip", // HTTP_ZIP "zip", + "application/octet-stream", // HTTP_BIN "bin", + "" // HTTP_UNKNOWN +}; +/**************************************************************************** + Section: + Commands and Server Responses + ***************************************************************************/ +const char HTTPresponse_200_head[] ICACHE_RODATA_ATTR = "OK"; +const char HTTPresponse_302_head[] ICACHE_RODATA_ATTR = "Found"; +const char HTTPresponse_304_head[] ICACHE_RODATA_ATTR = "Not Modified"; +const char HTTPresponse_400_head[] ICACHE_RODATA_ATTR = "Bad Request"; +const char HTTPresponse_401_head[] ICACHE_RODATA_ATTR = "Unauthorized\r\nWWW-Authenticate: Basic realm=\"Protected\""; +const char HTTPresponse_404_head[] ICACHE_RODATA_ATTR = "Not found"; +const char HTTPresponse_411_head[] ICACHE_RODATA_ATTR = "Length Required"; +const char HTTPresponse_413_head[] ICACHE_RODATA_ATTR = "Request Entity Too Large"; +const char HTTPresponse_414_head[] ICACHE_RODATA_ATTR = "Request-URI Too Long"; +const char HTTPresponse_418_head[] ICACHE_RODATA_ATTR = "I'm a teapot"; +const char HTTPresponse_429_head[] ICACHE_RODATA_ATTR = "Too Many Requests\r\nRetry-After: 30"; +const char HTTPresponse_500_head[] ICACHE_RODATA_ATTR = "Internal Server Error"; +const char HTTPresponse_501_head[] ICACHE_RODATA_ATTR = "Not Implemented\r\nAllow: GET, POST"; + +const char HTTPresponse_401_content[] ICACHE_RODATA_ATTR = "401 Unauthorized: Password required\r\n"; +const char HTTPresponse_404_content[] ICACHE_RODATA_ATTR = "404: File not found\r\n"; +const char HTTPresponse_411_content[] ICACHE_RODATA_ATTR = "411 The request must have a content length\r\n"; +const char HTTPresponse_413_content[] ICACHE_RODATA_ATTR = "413 Request Entity Too Large: There's too many letters :)\r\n"; +const char HTTPresponse_414_content[] ICACHE_RODATA_ATTR = "414 Request-URI Too Long: Buffer overflow detected\r\n"; +const char HTTPresponse_418_content[] ICACHE_RODATA_ATTR = "418: Out of Coffee\r\n"; +const char HTTPresponse_500_content[] ICACHE_RODATA_ATTR = "500 Internal Server Error\r\n"; +const char HTTPresponse_501_content[] ICACHE_RODATA_ATTR = "501 Not Implemented: Only GET and POST supported\r\n"; + +// Initial response strings (Corresponding to HTTP_STATUS) +static const HTTP_RESPONSE ICACHE_RODATA_ATTR HTTPResponse[] ICACHE_RODATA_ATTR = { + { 200, HTTP_RESP_FLG_NONE, + HTTPresponse_200_head, + NULL }, + // успешный запрос. Если клиентом были запрошены какие-либо данные, то они находятся в заголовке и/или теле сообщения. + { 302, HTTP_RESP_FLG_NONE | HTTP_RESP_FLG_REDIRECT, + HTTPresponse_302_head, + NULL }, +// "HTTP/1.1 302 Found\r\nConnection: close\r\nLocation: ", + // 302 Found, 302 Moved Temporarily - запрошенный документ временно + // доступен по другому URI, указанному в заголовке в поле Location. + // Этот код может быть использован, например, при управляемом сервером + // согласовании содержимого. Некоторые клиенты некорректно ведут себя + // при обработке данного кода. + { 304, HTTP_RESP_FLG_NONE, + HTTPresponse_304_head, + NULL }, +///"304 Redirect: ", // If-Modified-Since If-None-Match + // сервер возвращает такой код, если клиент запросил документ методом GET, + // использовал заголовок If-Modified-Since или If-None-Match и документ + // не изменился с указанного момента. При этом сообщение сервера не должно содержать тела. + { 400, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_400_head, + NULL} , + // сервер обнаружил в запросе клиента синтаксическую ошибку. + { 401, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_401_head, + HTTPresponse_401_content }, + // для доступа к запрашиваемому ресурсу требуется аутентификация. + // В заголовке ответ должен содержать поле WWW-Authenticate с перечнем + // условий аутентификации. Клиент может повторить запрос, + // включив в заголовок сообщения поле Authorization с требуемыми для аутентификации данными. +//"HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n403 Forbidden: SSL Required - use HTTPS\r\n" + { 404, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_404_head, + HTTPresponse_404_content }, + // Сервер понял запрос, но не нашёл соответствующего ресурса по указанному URI. + { 411, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_411_head, + HTTPresponse_411_content }, + // для указанного ресурса клиент должен указать Content-Length в заголовке запроса. + // Без указания этого поля не стоит делать повторную попытку запроса к серверу по данному URI. + // Такой ответ естественен для запросов типа POST и PUT. + // Например, если по указанному URI производится загрузка файлов, а на сервере стоит + // ограничение на их объём. Тогда разумней будет проверить в самом начале заголовок + // Content-Length и сразу отказать в загрузке, чем провоцировать бессмысленную нагрузку, + // разрывая соединение, когда клиент действительно пришлёт слишком объёмное сообщение. + { 413, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_413_head, + HTTPresponse_413_content }, + // возвращается в случае, если сервер отказывается обработать запрос + // по причине слишком большого размера тела запроса. Сервер может закрыть соединение, + // чтобы прекратить дальнейшую передачу запроса. + { 414, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_414_head, + HTTPresponse_414_content }, + // сервер не может обработать запрос из-за слишком длинного указанного URL. + // Такую ошибку можно спровоцировать, например, когда клиент пытается передать длинные + // параметры через метод GET, а не POST. + { 429, HTTP_RESP_FLG_NONE, + HTTPresponse_429_head, + NULL }, + // клиент попытался отправить слишком много запросов за короткое время, что может указывать, + // например, на попытку DoS-атаки. Может сопровождаться заголовком Retry-After, указывающим, + // через какое время можно повторить запрос. + { 501, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_501_head, + HTTPresponse_501_content }, + // сервер не поддерживает возможностей, необходимых для обработки запроса. + // Типичный ответ для случаев, когда сервер не понимает указанный в запросе метод. + см 405 + { 418, HTTP_RESP_FLG_FINDFILE, + HTTPresponse_418_head, + HTTPresponse_418_content }, + // http://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol + { 500, HTTP_RESP_FLG_END, + HTTPresponse_500_head, + HTTPresponse_500_content } + // любая внутренняя ошибка сервера, которая не входит в рамки остальных ошибок класса. +}; +const char HTTPfsupload[] ICACHE_RODATA_ATTR = "
File Upload

"; +#define sizeHTTPfsupload 220 +const char HTTPdefault[] ICACHE_RODATA_ATTR = "

RTL871X Built-in Web server ©

"; +#define sizeHTTPdefault 73 +const char HTTPfserror[] ICACHE_RODATA_ATTR = "

Web-disk error. Upload the WEBFiles.bin!

"; +#define sizeHTTPfserror 62 + +const char HTTPAccessControlAllowOrigin[] ICACHE_RODATA_ATTR = "Access-Control-Allow-Origin: *\r\n"; +// const uint8 *HTTPCacheControl = "Cache-Control:"; +const char *HTTPContentLength = "Content-Length:"; +#define sizeHTTPContentLength 15 +// const uint8 *HTTPConnection = "Connection: "; +// #define sizeHTTPConnection 12 +// const uint8 *HTTPkeepalive = "keep-alive"; +// #define sizeHTTPkeepalive 10 +// const uint8 *HTTPIfNoneMatch = "If-None-Match:" +// #define sizeHTTPIfNoneMatch 14 +const char *HTTPContentType = "Content-Type:"; +#define sizeHTTPContentType 13 +const char *HTTPmultipartformdata = "multipart/form-data"; +#define sizeHTTPmultipartformdata 19 +const char *HTTPboundary = "boundary="; +#define sizeHTTPboundary 9 +const char *HTTPAuthorization = "Authorization:"; +#define sizeHTTPAuthorization 14 +const char *HTTPCookie = "Cookie:"; +#define sizeHTTPCookie 7 + +/****************************************************************************** + * FunctionName : Close_web_conn + * Description : Free ts_conn + * Parameters : struct TCP_SERV_CONN + * Returns : none +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR Close_web_conn(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + int i = 0; + do { + if(web_conn->bffiles[i] != WEBFS_INVALID_HANDLE) { +#if DEBUGSOO > 1 + os_printf("cf%d ", web_conn->bffiles[i]); +#endif + if(web_conn->bffiles[i] <= WEBFS_MAX_HANDLE) WEBFSClose(web_conn->bffiles[i]); + web_conn->bffiles[i] = WEBFS_INVALID_HANDLE; + }; + i++; + }while(i < 4); + ClrSCB(SCB_FOPEN | SCB_FGZIP | SCB_FCALBACK); +} +/****************************************************************************** + * FunctionName : ReNew_web_conn + * Description : + * Parameters : struct TCP_SERV_CONN + * Returns : none +*******************************************************************************/ +LOCAL WEB_SRV_CONN * ICACHE_FLASH_ATTR ReNew_web_conn(TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(web_conn == NULL) { + web_conn = (WEB_SRV_CONN *)os_zalloc(sizeof(WEB_SRV_CONN)); + if(web_conn != NULL) { + web_conn->bffiles[0] = WEBFS_INVALID_HANDLE; + web_conn->bffiles[1] = WEBFS_INVALID_HANDLE; + web_conn->bffiles[2] = WEBFS_INVALID_HANDLE; + web_conn->bffiles[3] = WEBFS_INVALID_HANDLE; + // web_conn->webflag = 0; //zalloc + // web_conn->func_web_cb = NULL; //zalloc + OpenSCB(); // сбросить флаги + ts_conn->linkd = (void *)web_conn; + }; + } + return web_conn; +} +//============================================================================= +// Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n" +// The resulting string is then encoded using the RFC2045-MIME variant of Base64, +// except not limited to 76 uint8/line +// /ssl/crypto/ssl_crypto_misc.c: +// EXP_FUNC int STDCALL base64_decode(const uint8 *in, int len, uint8_t *out, int *outlen); +// Username and password are combined into a string "username:password" +LOCAL bool ICACHE_FLASH_ATTR CheckAuthorization(uint8* base64str) +{ + uint8 *pcmp = base64str; + int len = 0; + while(*pcmp++ >= '+') len++; +// struct softap_config apcfg; + uint8 pbuf[77]; + int declen = 76; + if((len >= 4)&&(len <= 128) + &&(base64decode(base64str, len, pbuf, &declen))) { + pbuf[declen]='\0'; + uint8 ppsw[32+64+1]; + cmpcpystr(ppsw, wifi_ap_cfg.ssid, '\0','\0', 32); + len = rtl_strlen((char*)ppsw); + ppsw[len++] = ':'; + cmpcpystr(&ppsw[len], wifi_ap_cfg.password, '\0','\0', 64); +#if DEBUGSOO > 1 + os_printf("'%s' ", pbuf); +#endif +#if DEBUGSOO > 2 + os_printf("<%s>[%u] ", ppsw, declen); +#endif + if(os_strncmp(pbuf, (char *)ppsw , declen) == 0) return true; + }; + return false; +} +//============================================================================= + +//============================================================================= +LOCAL void ICACHE_FLASH_ATTR +web_parse_cookie(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + if((CurHTTP->pcookie == NULL)||(CurHTTP->cookie_len == 0)) return; + uint8 pcmd[CmdNameSize]; + uint8 pvar[VarNameSize*3]; + uint8 *pcmp = CurHTTP->pcookie - 1; + do { + pcmp = cmpcpystr(pvar, ++pcmp, '\0', '=', sizeof(pvar)-1); + if(pcmp == NULL) return; + urldecode(pcmd, pvar, CmdNameSize - 1, sizeof(pvar)); + pcmp = cmpcpystr(pvar, pcmp, '=', ';', sizeof(pvar)-1); + if(pcmd[0]!='\0') { + urldecode(pvar, pvar, VarNameSize - 1, sizeof(pvar)); + web_int_vars(ts_conn, pcmd, pvar); + } + } while(pcmp != NULL); +} +//============================================================================= +LOCAL void ICACHE_FLASH_ATTR +web_parse_uri_vars(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + if((CurHTTP->puri == NULL)||(CurHTTP->uri_len == 0)) return; + uint8 pcmd[CmdNameSize]; + uint8 pvar[VarNameSize*3]; + uint8 *pcmp = CurHTTP->puri; + uint8 c = '?'; + pcmp = cmpcpystr(NULL, pcmp, '\0', c, CurHTTP->uri_len); + while(pcmp != NULL) { + pcmp = cmpcpystr(pvar, pcmp, c, '=', sizeof(pvar)-1); + if(pcmp == NULL) return; + urldecode(pcmd, pvar, CmdNameSize - 1, sizeof(pvar)); + c = '&'; + pcmp = cmpcpystr(pvar, pcmp, '=', c, sizeof(pvar)-1); + if(pcmd[0]!='\0') { + urldecode(pvar, pvar, VarNameSize - 1, sizeof(pvar)); + web_int_vars(ts_conn, pcmd, pvar); + } + }; +} +//============================================================================= +LOCAL void ICACHE_FLASH_ATTR +web_parse_content(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + if((CurHTTP->pcontent == NULL)||(CurHTTP->content_len == 0)) return; + uint8 pcmd[CmdNameSize]; + uint8 pvar[VarNameSize*3]; + uint8 *pcmp = CurHTTP->pcontent; + uint8 c = '\0'; + do { + pcmp = cmpcpystr(pvar, pcmp, c, '=', sizeof(pvar)-1); + if(pcmp == NULL) return; + urldecode(pcmd, pvar, CmdNameSize - 1, sizeof(pvar)); + c = '&'; + pcmp = cmpcpystr(pvar, pcmp, '=', c, sizeof(pvar)-1); + if(pcmd[0]!='\0') { + urldecode(pvar, pvar, VarNameSize - 1, sizeof(pvar)); + web_int_vars(ts_conn, pcmd, pvar); + } + } while(pcmp != NULL); +} +//============================================================================= +// Разбор имени файла и перевод в вид относительного URI. +// (выкидывание HTTP://Host) +// Проверка на обращение в папку или имя файла требующее пароль +//============================================================================= +LOCAL void ICACHE_FLASH_ATTR +web_parse_fname(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + if(CurHTTP->puri == NULL) return; + if(CurHTTP->uri_len < 2) { // = "/"? + CurHTTP->pFilename[0] = CurHTTP->puri[0]; + return; + } + { + uint8 cbuf[FileNameSize+16]; + uint8 *pcbuf = cbuf; + urldecode(pcbuf, CurHTTP->puri, sizeof(cbuf) - 1, CurHTTP->uri_len); + if((os_strncmp((char *)pcbuf, "HTTP://", 7) == 0)||(os_strncmp((char *)pcbuf, "http://", 7) == 0)) { + pcbuf += 7; + uint8 *pcmp = os_strchr((char *)pcbuf, '/'); + if(pcmp != NULL) pcbuf = pcmp; + }; + cmpcpystr(CurHTTP->pFilename, pcbuf, '\0', '?', FileNameSize); + }; + { // Проверка на обращение в папку или имя файла требующее пароль + uint8 *pcmp = web_strnstr(CurHTTP->pFilename, ProtectedFilesName, os_strlen(CurHTTP->pFilename)); + if(pcmp != NULL) { + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + SetSCB(SCB_AUTH); + } + }; +} +//============================================================================= +//============================================================================= +uint8 * ICACHE_FLASH_ATTR head_find_ctr(HTTP_CONN *CurHTTP, const uint8 * c, int clen, int dlen) +{ + if(CurHTTP->head_len < clen + dlen + 2) return NULL; // + "\r\n" + uint8 * pstr = web_strnstr((char *)CurHTTP->phead, c, CurHTTP->head_len); + if(pstr != NULL) { + pstr += clen; + uint8 *pend = web_strnstr(pstr, CRLF, CurHTTP->phead + CurHTTP->head_len - pstr); + if(pend == NULL) { + CurHTTP->httpStatus = 400; // 400 Bad Request + return NULL; + } + while(*pstr == ' ' && pstr < pend) pstr++; + if(pend - pstr < dlen) { + CurHTTP->httpStatus = 400; // 400 Bad Request + return NULL; + } + } + return pstr; +} +//============================================================================= +// Func: parse_header +// Разбирает докачан или нет заголовок HTTP, что там принято, GET или POST, +// открывает файл и проверяет content, если это POST и не прием файла. +//============================================================================= +LOCAL bool ICACHE_FLASH_ATTR +parse_header(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + CurHTTP->httpStatus = 501; // 501 Not Implemented (not a GET or POST command) + + uint8 *pstr = ts_conn->pbufi; + uint8 *pend = &ts_conn->pbufi[ts_conn->sizei]; + CurHTTP->pcontent = pend; + + if(pstr == NULL) { + CurHTTP->httpStatus = 500; // 500 Internal Server Error + return false; + }; + if(ts_conn->sizei < MIN_REQ_LEN) return false; // 501 Not Implemented (not a GET or POST command) + uint8 *pnext = web_strnstr(pstr, CRLF, ts_conn->sizei); // "\r\n" +// if(pnext != NULL) *pnext = '\0'; + if(pnext == NULL) { + CurHTTP->httpStatus = 400; // 400 Bad Request + return false; + }; + pnext += 2; + if(pnext - pstr < MIN_REQ_LEN) return false; // 501 размер строки запроса менее "GET /" + if(os_strncmp(pstr, "GET ", 4) == 0) { + SetSCB(SCB_GET); + CurHTTP->httpStatus = 200; + pstr += 4; + } + else if(os_strncmp(pstr, "POST ", 5) == 0) { + SetSCB(SCB_POST); + CurHTTP->httpStatus = 200; + pstr += 5; + } + else return false; // 501 Not Implemented (not a GET or POST command) + CurHTTP->puri = pstr; + CurHTTP->uri_len = pnext - pstr; + + if(CurHTTP->uri_len > 10) { // "/ HTTP/1.0\r\n" + pstr = web_strnstr(CurHTTP->puri, " HTTP/", CurHTTP->uri_len); + if(pstr != NULL) { + if((pstr[7] == '.')&&(pstr[6] <= '9')&&(pstr[6] >= '0')&&(pstr[8] >= '0')&&(pstr[8] <= '9')) + CurHTTP->httpver = ((pstr[6]-'0')<<4) + pstr[8]-'0'; + // else CurHTTP->ver = 0x00; + }; + }; +#if DEBUGSOO > 3 + os_printf("http_ver=%02x ", CurHTTP->httpver); +#endif + if(CurHTTP->httpver < 0x10) { // HTTP/0.9 ? + if(CheckSCB(SCB_POST)) { + CurHTTP->httpStatus = 400; // 400 HTTP/0.9 does not support POST + return false; // HTTP/0.9 + }; + }; + // здесь уже надо глядеть - следует или нет докачивать данные + pstr = web_strnstr(pnext-2, CRLF CRLF, pend - pnext + 2 ); // find "\r\n\r\n" + if(pstr == NULL) return true; // докачивать! + // разбираем дальше Header, раз уже скачан + pstr += 2; + if(pstr != pnext) { // есть Headers + CurHTTP->phead = pnext; + CurHTTP->head_len = pstr - pnext; + if(CheckSCB(SCB_POST)){ + pstr += 2; + CurHTTP->pcontent = pstr; + CurHTTP->content_len = pend - pstr; + }; + }; + if(!CheckSCB(SCB_FOPEN)) { // файл уже открыт? нет + web_parse_fname(CurHTTP, ts_conn); + if(!webserver_open_file(CurHTTP, ts_conn)) { + CurHTTP->httpStatus = 404; // "404: File not found" + return false; // + }; + }; + if((CurHTTP->phead == NULL)||(CurHTTP->head_len == 0)) { + // если требуется авторизация, но нет передачи пароля... + if(CheckSCB(SCB_AUTH)) CurHTTP->httpStatus = 401; // 401 Unauthorized + return false; // нет Header + }; + if(CheckSCB(SCB_POST)) { + pstr = head_find_ctr(CurHTTP, HTTPContentLength, sizeHTTPContentLength, 1); + if(pstr == NULL || CurHTTP->httpStatus != 200) { + CurHTTP->httpStatus = 411; // no "Content Length:", 411 Length Required + return false; + } + uint32 cnlen = atoi(pstr); +#if DEBUGSOO > 1 + os_printf("content_len = %d of %d ", cnlen, CurHTTP->content_len); +#endif + if(cnlen) { + web_conn->content_len = cnlen; // запомнить размер, для приема файла + if(!CheckSCB(SCB_BNDR) && (CurHTTP->head_len > sizeHTTPContentType + sizeHTTPmultipartformdata + sizeHTTPboundary + 2 + 2)) { //"x\r\n" + pstr = head_find_ctr(CurHTTP, HTTPContentType, sizeHTTPContentType, sizeHTTPmultipartformdata + sizeHTTPboundary + 2); + if(CurHTTP->httpStatus != 200) return false; + if(pstr != NULL) { + pend = web_strnstr(pstr, CRLF, CurHTTP->phead + CurHTTP->head_len - pstr); + pstr = web_strnstr(pstr, HTTPmultipartformdata, pend - pstr); + if(pstr != NULL) { + pstr += sizeHTTPmultipartformdata; + pstr = web_strnstr(pstr, HTTPboundary, pend - pstr); + if(pstr != NULL) { + // сохраним этот "мультипаспорт" (с) 5-ый элемент :) + pstr += sizeHTTPboundary; + HTTP_UPLOAD *pupload = (HTTP_UPLOAD *)os_zalloc(sizeof(HTTP_UPLOAD)); + if(pupload == NULL) { + CurHTTP->httpStatus = 500; // 500 Internal Server Error + return false; + } + uint8 x = *pend; + *pend = '\0'; +#if DEBUGSOO > 4 + os_printf("[%s] ", pstr); +#endif + rtl_memcpy(pupload->boundary, pstr, MAXLENBOUNDARY); + *pend = x; + pupload->sizeboundary = os_strlen(pupload->boundary); + ts_conn->pbufo = (uint8 *)pupload; + SetSCB(SCB_BNDR); +// if(cnlen > ((pupload->sizeboundary * 2) + 18)) { + SetSCB(SCB_RXDATA); +// } + }; + }; + }; + }; + if((!CheckSCB(SCB_BNDR)) && cnlen > CurHTTP->content_len) { // обычный контент и недокачан заголовок? да. + CurHTTP->content_len = cnlen; +#if DEBUGSOO > 2 + os_printf("wait content "); +#endif + CurHTTP->httpStatus = 413; // 413 Request Entity Too Large // пока так + return true; // докачивать + }; + } + else CurHTTP->content_len = cnlen; // уточнить, что Content Length = 0 + }; + if(CheckSCB(SCB_AUTH)) { + pstr = head_find_ctr(CurHTTP, HTTPAuthorization, sizeHTTPAuthorization, 5 + 3); // "Authorization: Basic 1234\r\n" + if(pstr == NULL || CurHTTP->httpStatus != 200) { + CurHTTP->httpStatus = 401; // 401 Unauthorized + return false; + } + if(os_strncmp(pstr, "Basic", 5) == 0) { // The authorization method and a space i.e. "Basic" is then put before the encoded string. + pstr += 5; + while(*pstr == ' ') pstr++; + if(CheckAuthorization(pstr)) ClrSCB(SCB_AUTH); + else { + CurHTTP->httpStatus = 401; // 401 Unauthorized + return false; + }; + } + else { + CurHTTP->httpStatus = 401; // 401 Unauthorized + return false; + }; + }; + + if(CurHTTP->head_len > sizeHTTPCookie + 4) { // "Cookie: a=\r\n" + pstr = head_find_ctr(CurHTTP, HTTPCookie, sizeHTTPCookie, 2); + if(pstr != NULL) { + pend = web_strnstr(pstr, CRLF, CurHTTP->phead + CurHTTP->head_len - pstr); + if(pend != NULL) { + CurHTTP->pcookie = pstr; + CurHTTP->cookie_len = pend - pstr; +#if DEBUGSOO > 3 + *pend = '\0'; + os_printf("cookie:[%s] ", pstr); + *pend = '\r'; +#endif + } +#if DEBUGSOO > 3 + else os_printf("cookie not crlf! "); +#endif + }; + }; +#ifdef WEBSOCKET_ENA + if(CheckSCB(SCB_GET) && web_conn->bffiles[0] == WEBFS_WEBCGI_HANDLE) { +#if DEBUGSOO > 3 + os_printf("hdlen=%d ", CurHTTP->head_len); +#endif + if(CurHTTP->head_len > sizeHTTPUpgrade + sizeHTTPwebsocket + 2 + sizeHTTPSecWebSocketKey + minsizeWebSocketKey + 2) { // + "\r\n" + pstr = head_find_ctr(CurHTTP, HTTPUpgrade, sizeHTTPUpgrade, sizeHTTPwebsocket); + if(CurHTTP->httpStatus != 200) return false; + if(pstr != NULL) { + if(!rom_xstrcmp(word_to_lower_case(pstr), HTTPwebsocket)) { + CurHTTP->httpStatus = 400; // 400 Bad Request + return false; + } + pstr = head_find_ctr(CurHTTP, HTTPSecWebSocketKey, sizeHTTPSecWebSocketKey, minsizeWebSocketKey); + if(pstr == NULL || CurHTTP->httpStatus != 200) return false; + { + if(WebSocketAcceptKey(CurHTTP->pFilename, pstr)) SetSCB(SCB_WEBSOC); + } + } + } + } +#endif + return false; +} +/****************************************************************************** + * FunctionName : web_inc_fp + * Parameters : fp +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR web_inc_fp(WEB_SRV_CONN *web_conn, WEBFS_HANDLE fp) +{ + if(web_conn->bffiles[3] != WEBFS_INVALID_HANDLE) { + #if DEBUGSOO > 1 + os_printf("cf%d ", web_conn->bffiles[3]); + #endif + if(web_conn->bffiles[3] <= WEBFS_MAX_HANDLE) { + web_conn->content_len -= WEBFSGetBytesRem(web_conn->bffiles[3]); + WEBFSClose(web_conn->bffiles[3]); + } + }; + web_conn->bffiles[3] = web_conn->bffiles[2]; + web_conn->bffiles[2] = web_conn->bffiles[1]; + web_conn->bffiles[1] = web_conn->bffiles[0]; + web_conn->bffiles[0] = fp; + SetSCB(SCB_FOPEN); // файл открыт +} +/****************************************************************************** + * FunctionName : web_inc_fopen + * Description : web include file open + * Parameters : struct + * Returns : true - open OK +*******************************************************************************/ +bool ICACHE_FLASH_ATTR web_inc_fopen(TCP_SERV_CONN *ts_conn, uint8 *cFile) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(CheckSCB(SCB_FOPEN) && (!CheckSCB(SCB_FCALBACK))) { // файл уже открыт и он не парсится? + return false; // такое не поддерживается в "~inc:filename~" + }; + WEBFS_HANDLE fp = WEBFSOpen(cFile); +#if DEBUGSOO > 1 + os_printf("of%d[%s] ", fp, cFile); +#endif + if(fp != WEBFS_INVALID_HANDLE) { + if(fatCache.flags & WEBFS_FLAG_HASINDEX) SetSCB(SCB_FCALBACK); // файл надо парсить + web_conn->content_len += WEBFSGetBytesRem(fp); // указать размер файла для вывода + if(fatCache.flags & WEBFS_FLAG_ISZIPPED) { + if(CheckSCB(SCB_FOPEN)) { // файл уже открыт и "~inc:filename~" не поддерживает GZIP! + WEBFSClose(fp); +#if DEBUGSOO > 1 + os_printf("Not inc GZIP! "); +#endif + return false; + }; + SetSCB(SCB_FGZIP); // файл сжат GZIP + } + } + else { // File not found + return false; + }; + web_inc_fp(web_conn, fp); + return true; +}; +/****************************************************************************** + * FunctionName : web_inc_file + * Description : web include file close + * Parameters : struct + * Returns : true - все файлы закрыты +*******************************************************************************/ +bool ICACHE_FLASH_ATTR web_inc_fclose(WEB_SRV_CONN *web_conn) +{ + if(web_conn->bffiles[0] != WEBFS_INVALID_HANDLE) { +#if DEBUGSOO > 1 + os_printf("cf%d ", web_conn->bffiles[0]); +#endif + if(web_conn->bffiles[0] <= WEBFS_MAX_HANDLE) { + WEBFSClose(web_conn->bffiles[0]); + ClrSCB(SCB_FGZIP); + } + web_conn->bffiles[0] = web_conn->bffiles[1]; + web_conn->bffiles[1] = web_conn->bffiles[2]; + web_conn->bffiles[2] = web_conn->bffiles[3]; + web_conn->bffiles[3] = WEBFS_INVALID_HANDLE; + if(web_conn->bffiles[0] != WEBFS_INVALID_HANDLE) return false; + }; + ClrSCB(SCB_FOPEN | SCB_FGZIP | SCB_FCALBACK); + return true; // больше нет файлов +}; +/****************************************************************************** + * FunctionName : webserver_open_file + * Description : Compare to known extensions to determine Content-Type + * Parameters : filename -- file name + * Returns : 1 - open, 0 - no +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR webserver_file_ext(HTTP_CONN *CurHTTP, uint8 *pfname) +{ + uint8 *pfext = NULL; + while(*pfname >= ' ') if(*pfname++ == '.') pfext = pfname; + if(pfext != NULL) { + for(CurHTTP->fileType = HTTP_TXT; CurHTTP->fileType < HTTP_UNKNOWN; CurHTTP->fileType++) + if(rom_xstrcmp(pfext, httpFileExtensions[CurHTTP->fileType])) break; + }; +} +/*----------------------------------------------------------------------*/ +#ifdef USE_CAPTDNS +/* = flase, если включен redirect, и запрос от ip адреса из подсети AP, + * и Host name не равен aesp8266 или ip AP. */ +LOCAL bool ICACHE_FLASH_ATTR web_cdns_no_redir(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + if(syscfg.cfg.b.cdns_ena + && pcb_cdns != NULL + &&((ts_conn->pcb->remote_ip.addr ^ info.ap_ip) & info.ap_mask) == 0 + && CurHTTP->phead != NULL + && CurHTTP->head_len != 0) { + uint8 * ps = head_find_ctr(CurHTTP, HTTPHost, sizeHTTPHost, 7); + if(ps != NULL) { +#if DEBUGSOO > 1 + os_printf("Host: '%s' ", ps); +#endif + uint8 strip[4*4]; + os_sprintf_fd(strip, IPSTR, IP2STR(&info.ap_ip)); + if((rom_xstrcmp(ps, HostNameLocal) == 0) && (rom_xstrcmp(ps, strip) == 0)) { + rtl_sprintf(CurHTTP->pFilename, httpHostNameLocal, HostNameLocal); // "http://esp8266/" + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + SetSCB(SCB_REDIR); + return false; + } + } + } + return true; +} +#endif +/****************************************************************************** + * FunctionName : webserver_open_file + * Description : Open file + * Parameters : filename -- file name + * Returns : 1 - open, 0 - no +*******************************************************************************/ +LOCAL bool ICACHE_FLASH_ATTR webserver_open_file(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + uint8 pbuf[MAX_FILE_NAME_SIZE]; + uint8 *pstr = pbuf; + if(CurHTTP->pFilename[0] == '/') { + if(CurHTTP->pFilename[1] == '\0') { + if(isWEBFSLocked) { + web_inc_fp(web_conn, WEBFS_NODISK_HANDLE); // желательно дописать ответ, что нет диска. + web_conn->content_len = sizeHTTPfserror; + CurHTTP->fileType = HTTP_HTML; +#if DEBUGSOO > 1 + os_printf("of%d[%s] ", web_conn->webfile, CurHTTP->pFilename); +#endif + return true; + } + else { +#ifdef USE_CAPTDNS + if(web_cdns_no_redir(CurHTTP, ts_conn)) rom_xstrcpy(pstr, http_default_file); + else return false; +#else + rom_xstrcpy(pstr, http_default_file); +#endif + } + } + else { + rtl_memcpy(pstr, &CurHTTP->pFilename[1], MAX_FILE_NAME_SIZE-1); + if(rom_xstrcmp(pstr, web_cgi_fname)) { + web_inc_fp(web_conn, WEBFS_WEBCGI_HANDLE); + web_conn->content_len = sizeHTTPdefault; + CurHTTP->fileType = HTTP_HTML; +#if DEBUGSOO > 1 + os_printf("of%d[%s] ", web_conn->webfile, CurHTTP->pFilename); +#endif + return true; + } + else if(rom_xstrcmp(pstr, fsupload_fname)) { + SetSCB(SCB_AUTH); + web_inc_fp(web_conn, WEBFS_UPLOAD_HANDLE); + web_conn->content_len = sizeHTTPfsupload; + CurHTTP->fileType = HTTP_HTML; +#if DEBUGSOO > 1 + os_printf("of%d[%s] ", web_conn->webfile, CurHTTP->pFilename); +#endif + return true; + } + } + if(isWEBFSLocked) return false; + // поиск файла на диске + if(!web_inc_fopen(ts_conn, pstr)) { + uint32 i = os_strlen(pbuf); + if(i + sizeof(http_default_file) < MAX_FILE_NAME_SIZE - 1) { + // добавить к имени папки "/index.htm" + pbuf[i] = '/'; + rom_xstrcpy(&pbuf[i+1], http_default_file); + if(!web_inc_fopen(ts_conn, pstr)) { +#ifdef USE_CAPTDNS + web_cdns_no_redir(CurHTTP, ts_conn); +#endif + return false; + } + }; + }; + // Compare to known extensions to determine Content-Type + webserver_file_ext(CurHTTP, pstr); + return true; + }; + return false; // файл не открыт +} +/****************************************************************************** +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR web_send_fnohanle(TCP_SERV_CONN *ts_conn) { + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + uint32 pdata = 0; +// uint8 pbuf[mMAX(mMAX(sizeHTTPdefault,sizeHTTPfserror), sizeHTTPfsupload)]; + uint32 size = 0; + switch(web_conn->webfile) { + case WEBFS_WEBCGI_HANDLE: + pdata = (uint32)((void *)HTTPdefault); + size = sizeHTTPdefault; + break; + case WEBFS_UPLOAD_HANDLE: + pdata = (uint32)((void *)HTTPfsupload); + size = sizeHTTPfsupload; + break; + case WEBFS_NODISK_HANDLE: + pdata = (uint32)((void *)HTTPfserror); + size = sizeHTTPfserror; + break; + } + if(pdata != 0 && size != 0) { +// spi_flash_read(pdata & MASK_ADDR_FLASH_ICACHE_DATA, pbuf, size); + tcpsrv_int_sent_data(ts_conn, pdata, size); + } +#if DEBUGSOO > 1 + os_printf("%u ", size); +#endif + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); +} +/****************************************************************************** +*******************************************************************************/ +LOCAL int ICACHE_FLASH_ATTR web_find_cbs(uint8 * chrbuf, uint32 len) { + int i; + for(i = 0; i < len; i++) if(chrbuf[i] == '~') return i; + return -1; +} +/****************************************************************************** + * FunctionName : webserver_send_fdata + * Description : Sent callback function to call for this espconn when data + * is successfully sent + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR webserver_send_fdata(TCP_SERV_CONN *ts_conn) { + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(web_conn->webfile == WEBFS_INVALID_HANDLE) { + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + return; + } +#if DEBUGSOO > 1 + os_printf("send: "); +#endif +#ifdef SET_CPU_CLK_SPEED +// set_cpu_clk(); +#endif + web_conn->msgbufsize = tcp_sndbuf(ts_conn->pcb); + +#if DEBUGSOO > 5 + os_printf("sndbuf=%u ", web_conn->msgbufsize); +#endif + + if (web_conn->msgbufsize < MIN_SEND_SIZE) { +#if DEBUGSOO > 1 + os_printf("sndbuf=%u! ", web_conn->msgbufsize); + if(ts_conn->flag.wait_sent) os_printf("wait_sent! "); // блок передан? +#endif + ts_conn->pcb->flags &= ~TF_NODELAY; + tcpsrv_int_sent_data(ts_conn, (uint8 *)ts_conn, 0); + return; + } + if((web_conn->webfile > WEBFS_MAX_HANDLE)&&(!CheckSCB(SCB_RETRYCB))) { + web_send_fnohanle(ts_conn); + return; + } + web_conn->msgbufsize = mMIN(MAX_SEND_SIZE, web_conn->msgbufsize); + uint8 *pbuf = (uint8 *) os_malloc(web_conn->msgbufsize); + if (pbuf == NULL) { +#if DEBUGSOO > 0 + os_printf("out of memory - disconnect!\n"); +#endif + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + return; + }; + web_conn->msgbuf = pbuf; + web_conn->msgbuflen = 0; + if (CheckSCB(SCB_CHUNKED)) { // is chunked + web_conn->msgbuf += RESCHKS_SEND_SIZE; + web_conn->msgbufsize -= RESCHK_SEND_SIZE; + }; + if(CheckSCB(SCB_FCALBACK) == 0) { // передача файла без парсинга + // Get/put as many bytes as possible + web_conn->msgbuflen = WEBFSGetArray(web_conn->webfile, web_conn->msgbuf, web_conn->msgbufsize); + if(web_conn->msgbuflen < web_conn->msgbufsize ) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + } + else { // парсинг потока передачи + do { // начинаем с пустого буфера + if(CheckSCB(SCB_RETRYCB)) { // повторный callback? да +#if DEBUGSOO > 2 + os_printf("rcb "); +#endif + if(web_conn->func_web_cb != NULL) web_conn->func_web_cb(ts_conn); + if(CheckSCB(SCB_RETRYCB)) break; // повторить ещё раз? да. + } + else { + uint8 *pstr = &web_conn->msgbuf[web_conn->msgbuflen]; // указатель в буфере + // запомнить указатель в файле. ftell(fp) + uint32 max = mMIN(web_conn->msgbufsize - web_conn->msgbuflen, SCB_SEND_SIZE); // читаем по 128 байт ? + uint32 len = WEBFSGetArray(web_conn->webfile, pstr, max); + // прочитано len байт в буфер по указателю &sendbuf[msgbuflen] + if(len) { // есть байты для передачи, ищем string "~calback~" + int cmp = web_find_cbs(pstr, len); + if(cmp >= 0) { // найден calback + // откат файла + WEBFSStubs[web_conn->webfile].addr -= len; + WEBFSStubs[web_conn->webfile].bytesRem += len; + // передвинуть указатель в файле на считанные байты с учетом маркера, без добавки длины для передачи + WEBFSStubs[web_conn->webfile].addr += cmp+1; + WEBFSStubs[web_conn->webfile].bytesRem -= cmp+1; + // это второй маркер? + if(CheckSCB(SCB_FINDCB)) { // в файле найден закрывающий маркер calback + ClrSCB(SCB_FINDCB); // прочитали string calback-а + if(cmp != 0) { // это дубль маркера ? нет. + // запустить calback + pstr[cmp] = '\0'; // закрыть string calback-а + if(!os_memcmp((void*)pstr, "inc:", 4)) { // "inc:file_name" + if(!web_inc_fopen(ts_conn, &pstr[4])) { + tcp_strcpy_fd("file not found!"); + }; + } + else web_int_callback(ts_conn, pstr); + } + else { // Дубль маркера. + web_conn->msgbuflen++; // передать только маркер ('~') + }; + } + else { + SetSCB(SCB_FINDCB); // в файле найден стартовый маркер calback + web_conn->msgbuflen += cmp; // передать до стартового маркера calback + }; + } + else { // просто данные + ClrSCB(SCB_FINDCB); + if(len < max) { + if(web_inc_fclose(web_conn)) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // файл(ы) закончилсь совсем? да. + }; + web_conn->msgbuflen += len; // добавить кол-во считанных байт для передачи. + }; + } + else if(web_inc_fclose(web_conn)) SetSCB(SCB_FCLOSE | SCB_DISCONNECT); // файл(ы) закончилсь совсем? да. + }; // not SCB_RETRYCB + } // набираем буфер + while((web_conn->msgbufsize - web_conn->msgbuflen >= SCB_SEND_SIZE)&&(!CheckSCB(SCB_FCLOSE | SCB_RETRYCB | SCB_DISCONNECT))); + }; +#if DEBUGSOO > 3 + os_printf("#%04x %d ", web_conn->webflag, web_conn->msgbuflen); +#elif DEBUGSOO > 1 + os_printf("%u ", web_conn->msgbuflen); +#endif + if(web_conn->msgbuflen) { + web_conn->content_len -= web_conn->msgbuflen; // пока только для инфы + if(CheckSCB(SCB_CHUNKED)) { // greate chunked + uint8 cbuf[16]; + static const char chunks[] ICACHE_RODATA_ATTR = "\r\n%X\r\n"; + unsigned int len = rtl_sprintf(cbuf, chunks, web_conn->msgbuflen); + web_conn->msgbuf -= len; + rtl_memcpy(web_conn->msgbuf, cbuf, len); + web_conn->msgbuflen += len; + if(CheckSCB(SCB_FCLOSE)) { // close file? -> add 'end chunked' + tcp_strcpy_fd("\r\n0\r\n\r\n"); + }; + }; + ts_conn->pcb->flags |= TF_NODELAY; + tcpsrv_int_sent_data(ts_conn, web_conn->msgbuf, web_conn->msgbuflen); + }; + os_free(pbuf); + web_conn->msgbuf = NULL; +} +/****************************************************************************** + * FunctionName : web_print_headers + * Description : Print HTTP Response Header + * Parameters : * + * Returns : none +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR +web_print_headers(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + HTTP_RESPONSE *CurResp = (HTTP_RESPONSE *)HTTPResponse; +#if DEBUGSOO > 3 + os_printf("prh#%04x,%d,%d ", web_conn->webflag, CurHTTP->httpStatus, CurHTTP->fileType); +#endif + web_conn->msgbuf = (uint8 *)os_malloc(HTTP_SEND_SIZE); + if(web_conn->msgbuf == NULL) + { +#if DEBUGSOO == 1 + os_printf("web: out of memory!\n"); +#elif DEBUGSOO > 1 + os_printf("out of memory! "); +#endif + SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + return; + } + web_conn->msgbufsize = HTTP_SEND_SIZE; + web_conn->msgbuflen = 0; + if(CheckSCB(SCB_REDIR)) { + CurHTTP->httpStatus = 302; // редирект + } +#ifdef WEBSOCKET_ENA + if(CheckSCB(SCB_WEBSOC) && CurHTTP->httpStatus == 200) { +#if DEBUGSOO > 1 + CurHTTP->httpStatus = 101; +#endif + tcp_puts(WebSocketHTTPOkKey, CurHTTP->pFilename); + } + else { +#endif + while(!(CurResp->flag & HTTP_RESP_FLG_END)) { + if(CurResp->status == CurHTTP->httpStatus) break; + CurResp++; + }; + tcp_puts_fd("HTTP/1.1 %u ", CurResp->status); + tcp_strcpy(CurResp->headers); + tcp_strcpy_fd("\r\nServer: " WEB_NAME_VERSION "\r\nConnection: close\r\n"); + if(CheckSCB(SCB_REDIR)) { + tcp_puts_fd("Location: %s\r\n\r\n", CurHTTP->pFilename); + ts_conn->flag.pcb_time_wait_free = 1; // закрыть соединение + SetSCB(SCB_DISCONNECT); + } + else { + if(CurResp->status != 200) { + web_inc_fclose(web_conn); + ClrSCB(SCB_FCALBACK | SCB_FGZIP | SCB_CHUNKED | SCB_RXDATA | SCB_FCLOSE); + if(CurResp->flag & HTTP_RESP_FLG_FINDFILE) { + os_sprintf_fd(CurHTTP->pFilename, "/%u.htm", CurResp->status); + webserver_open_file(CurHTTP, ts_conn); + // CurHTTP->httpStatus = CurResp->status; // вернуть статус! + }; + } + if((!CheckSCB(SCB_FOPEN)) && (CurResp->default_content != NULL) ) { + tcp_puts_fd("%s %u\r\n%s %s\r\n\r\n", HTTPContentLength, rtl_strlen(CurResp->default_content), + HTTPContentType, httpContentTypes[HTTP_TXT]); + tcp_strcpy(CurResp->default_content); + SetSCB(SCB_DISCONNECT); + } + else if(CheckSCB(SCB_FOPEN)) { + if(web_conn->content_len) { + // Указать, что данные могут пользовать все (очень актуально для XML, ...) + tcp_strcpy_fd("Access-Control-Allow-Origin: *\r\n"); + if(CurHTTP->fileType != HTTP_UNKNOWN) { + if(web_conn->bffiles[0] == WEBFS_WEBCGI_HANDLE && CheckSCB(SCB_FCALBACK)) CurHTTP->fileType = web_conn->fileType; + tcp_puts_fd("Content-Type: %s\r\n", httpContentTypes[CurHTTP->fileType]); + }; + // Output the cache-control + ContentLength + if(CheckSCB(SCB_FCALBACK)) { // длина неизветсна + // file is callback index + tcp_strcpy_fd("Cache-Control: no-store, no-cache, must-revalidate, max-age=0\r\n"); + if(CurHTTP->httpver >= 0x11) SetSCB(SCB_CHUNKED); + } + else { // длина изветсна + tcp_puts_fd("%s %d\r\n", HTTPContentLength, web_conn->content_len); + if(CurResp->status == 200 && (!isWEBFSLocked) && web_conn->bffiles[0] != WEBFS_WEBCGI_HANDLE) { + // lifetime (sec) of static responses as string 60*60*24*14=1209600" + tcp_puts_fd("Cache-Control: smax-age=%d\r\n", FILE_CACHE_MAX_AGE_SEC); + } + else { + tcp_strcpy_fd("Cache-Control: no-store, no-cache, must-revalidate, max-age=0\r\n"); + } + }; + if(CheckSCB(SCB_FGZIP)) { + // Output the gzip encoding header if needed + tcp_strcpy_fd("Content-Encoding: gzip\r\n"); + } + else if(CheckSCB(SCB_CHUNKED)) { + tcp_strcpy_fd("Transfer-Encoding: chunked\r\n"); + } + if(!CheckSCB(SCB_CHUNKED)) tcp_strcpy_fd(CRLF); + } + else { + tcp_puts_fd("%s 0\r\n\r\n", HTTPContentLength); + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + } + } + else SetSCB(SCB_DISCONNECT); + } // CheckSCB(SCB_REDIR) +#ifdef WEBSOCKET_ENA + } +#endif +#if DEBUGSOO > 3 + os_printf("#%04x (%d) %d ", web_conn->webflag, web_conn->msgbuflen, CurHTTP->httpStatus); + web_conn->msgbuf[web_conn->msgbuflen] = 0; + os_printf("\n2?%d[%s]\n", web_conn->msgbuflen, web_conn->msgbuf); +#elif DEBUGSOO > 1 + os_printf("head[%d]:%d ", web_conn->msgbuflen, CurHTTP->httpStatus); +#endif + if(web_conn->msgbuflen) { + if(CheckSCB(SCB_DISCONNECT)) SetSCB(SCB_CLOSED); + tcpsrv_int_sent_data(ts_conn, web_conn->msgbuf, web_conn->msgbuflen); +#ifdef USE_WEB_NAGLE + ts_conn->flag.nagle_disabled = 1; +#endif + }; + os_free(web_conn->msgbuf); + web_conn->msgbuf = NULL; +} +/******************************************************************************/ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// поиск boundary +// 0 - разделитель (boundary) не найден, докачивать или ... +// 1 - boundary найден +// 200 - найден завершаюший boundary +// 400 - неверный формат +// ... +//----------------------------------------------------------------------------- +/* Пример M-Explorer: Load blk len: 399 +-----------------------------7df22f37711be\r\n +Content-Disposition: form-data; name="test"; filename="readme.txt"\r\n +Content-Type: text/plain\r\n\r\n +1234567890\r\n +-----------------------------7df22f37711be\r\n +Content-Disposition: form-data; name="start"\r\n\r\n +0x1B000\r\n +-----------------------------7df22f37711be\r\n +Content-Disposition: form-data; name="stop"\r\n\r\n +0x1B000\r\n +-----------------------------7df22f37711be--\r\n */ +/* Пример Google Chrome: Load blk len: 391 +------WebKitFormBoundaryugGNBVFOk6qxfe22\r\n +Content-Disposition: form-data; name="test"; filename="readme.txt"\r\n +Content-Type: text/plain\r\n\r\n +1234567890\r\n +------WebKitFormBoundaryugGNBVFOk6qxfe22\r\n +Content-Disposition: form-data; name="start"\r\n\r\n +0x1B000\r\n +------WebKitFormBoundaryugGNBVFOk6qxfe22\r\n +Content-Disposition: form-data; name="stop"\r\n\r\n +0x1B000\r\n +------WebKitFormBoundaryugGNBVFOk6qxfe22--\r\n */ +//----------------------------------------------------------------------------- +const char crlf_end_boundary[] ICACHE_RODATA_ATTR = "--" CRLF; +LOCAL int ICACHE_FLASH_ATTR find_boundary(HTTP_UPLOAD *pupload, uint8 *pstr, uint32 len) +{ + int x = len - 6 - pupload->sizeboundary; + if(x <= 0) return 0; // разделитель (boundary) не найден - докачивать буфер + int i; + uint8 *pcmp; + for(i = 0; i <= x; i++) { + if(pstr[i] == '-' && pstr[i+1] == '-') { + pcmp = pstr + i; +// if((pstr + len - pcmp) < pupload->sizeboundary + 6) return 0; // разделитель (boundary) не найден - докачивать буфер + pupload->pbndr = pcmp; // указатель на заголовок boundary (конец блока данных); + pcmp += 2; + if(os_memcmp(pcmp, pupload->boundary, pupload->sizeboundary)) return 0; // разделитель (boundary) не найден + pcmp += pupload->sizeboundary; + if(rom_xstrcmp(pcmp, crlf_end_boundary)) { + pcmp += 4; + pupload->pnext = pcmp; // указатель в заголовке boundary (описание новых данных); + return 200; // найден завершающий разделитель + } + if(pcmp[0] != '\r' || pcmp[1] != '\n') return 400; // неверный формат + pcmp += 2; + pupload->pnext = pcmp; // указатель в заголовке boundary (описание новых данных); + return 1; + }; + }; + return 0; // разделитель (boundary) не найден - докачивать буфер +} +//----------------------------------------------------------------------------- +// Function: cmp_next_boundary +// return: +// 0 - разделитель (boundary) не найден, докачивать +// 1 - далее обработка данных +// 200 - найден завершающий разделитель: "\r\n--boundary--" +// 400 - неизвестный формат content-а +//----------------------------------------------------------------------------- +const char disk_ok_filename[] ICACHE_RODATA_ATTR = "/disk_ok.htm"; +const char disk_err1_filename[] ICACHE_RODATA_ATTR = "/disk_er1.htm"; +const char disk_err2_filename[] ICACHE_RODATA_ATTR = "/disk_er2.htm"; +const char disk_err3_filename[] ICACHE_RODATA_ATTR = "/disk_er3.htm"; +const char sysconst_filename[] ICACHE_RODATA_ATTR = "sysconst"; +#ifdef USE_OVERLAY +const char overlay_filename[] ICACHE_RODATA_ATTR = "overlay"; +#endif +const char sector_filename[] ICACHE_RODATA_ATTR = "fsec_"; +#define sector_filename_size 5 +const char file_label[] ICACHE_RODATA_ATTR = "file"; + +LOCAL int ICACHE_FLASH_ATTR upload_boundary(TCP_SERV_CONN *ts_conn) // HTTP_UPLOAD pupload, uint8 pstr, uint16 len) +{ + HTTP_UPLOAD *pupload = (HTTP_UPLOAD *)ts_conn->pbufo; + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(pupload == NULL) return 500; // ошибка сервера + uint32 ret; + uint32 len; + uint8 *pnext; + uint8 *pstr; + while(web_conn->content_len && ts_conn->pbufi != NULL) { + pstr = ts_conn->pbufi; + len = ts_conn->sizei; +#if DEBUGSOO > 4 + os_printf("bufi[%u]%u, cont:%u ", ts_conn->sizei, ts_conn->cntri, web_conn->content_len); +#endif + if(len < (8 + pupload->sizeboundary)) return 0; // разделитель (boundary) не влезет - докачивать буфер + switch(pupload->status) { + case 0: // поиск boundary + { +#if DEBUGSOO > 4 + os_printf("find_bndr "); +#endif + pnext = web_strnstr(pstr, CRLF CRLF , len); + if(pnext == NULL) return 0; // докачивать + len = pnext - pstr; + ret = find_boundary(pupload, pstr, len); +#if DEBUGSOO > 4 + os_printf("len=%u,ret=%u ", len, ret ); +#endif + if(ret != 1) return ret; + pstr = pupload->pnext; // +"\r\n" адрес за заголовком boundary + pupload->name[0] = '\0'; + pupload->filename[0] = '\0'; + pstr = web_strnstr(pstr, "name=", pnext - pstr); + if(pstr == NULL) return 400; // неизвестный формат content-а + pstr += 5; + if(pstr >= pnext) return 400; // неизвестный формат content-а + uint8 *pcmp = cmpcpystr(pupload->name, pstr, '"', '"', VarNameSize); + if(pcmp == NULL) { + pcmp = cmpcpystr(pupload->name, pstr, 0x22, 0x22, VarNameSize); + if(pcmp == NULL) return 400; // неизвестный формат content-а + }; + pstr = pcmp; +#if DEBUGSOO > 4 + os_printf("name:'%s' ", pupload->name); +#endif + if(pstr >= pnext) return 400; // неизвестный формат content-а + pcmp = web_strnstr(pstr, "filename=", pnext - pstr); + if(pcmp != NULL) { + pcmp += 9; + if(pcmp < pnext) { + if(cmpcpystr(pupload->filename, pcmp, '"', '"', VarNameSize) == NULL) + cmpcpystr(pupload->filename, pcmp, 0x22, 0x22, VarNameSize); + }; +#if DEBUGSOO > 1 + if(pupload->filename[0]!= '\0') os_printf("filename:'%s' ", pupload->filename); +#endif + }; + len += 4; + pupload->status++; +#if DEBUGSOO > 4 + os_printf("trim#%u\n", len ); +#endif + ts_conn->cntri += len; // далее идут данные + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[len], ts_conn->sizei - len)) return 500; + web_conn->content_len -= len; + break; + } + case 1: // прием данных, первый заход, проверка форматов и т.д. + { +#if DEBUGSOO > 4 + os_printf("tst,fn='%s' ", pupload->filename); +#endif + if(pupload->filename[0]!='\0') { // загрузка файла? + if(rom_xstrcmp(pupload->name, file_label)) { // !os_memcmp((void*)pupload->name, "file", 4) + if(len < sizeof(WEBFS_DISK_HEADER)) return 0; // докачивать + WEBFS_DISK_HEADER *dhead = (WEBFS_DISK_HEADER *)pstr; + if(dhead->id != WEBFS_DISK_ID || dhead->ver != WEBFS_DISK_VER + || (web_conn->content_len - pupload->sizeboundary - 8 < dhead->disksize)) { + if(isWEBFSLocked) return 400; + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err1_filename); // rtl_memcpy(pupload->filename,"/disk_er1.htm\0",14); // неверный формат + return 200; + }; + if(dhead->disksize > WEBFS_max_size()) { + if(isWEBFSLocked) return 400; + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err2_filename); // rtl_memcpy(pupload->filename,"/disk_er2.htm\0",14); // не влезет + return 200; + }; + pupload->fsize = dhead->disksize; + pupload->faddr = WEBFS_base_addr(); +#if DEBUGSOO > 4 + os_printf("updisk[%u]=ok ", dhead->disksize); +#endif + pupload->status = 3; // = 3 загрузка WebFileSystem во flash + isWEBFSLocked = true; + break; + } +#ifdef USE_OVERLAY + else if(rom_xstrcmp(pupload->name, overlay_filename)) { + if(len < sizeof(struct SPIFlashHeader)) return 0; // докачивать + struct SPIFlashHeader *fhead = (struct SPIFlashHeader *)pstr; + if(web_conn->content_len - pupload->sizeboundary < sizeof(fhead) + || fhead->head.id != LOADER_HEAD_ID) { + if(isWEBFSLocked) return 400; + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err1_filename); // rtl_memcpy(pupload->filename,"/disk_er1.htm\0",14); // неверный формат + return 200; + }; + if(fhead->entry_point >= IRAM_BASE && ovl_call != NULL) { + ovl_call(0); // close прошлый оверлей + ovl_call = NULL; + } + pupload->start = fhead->entry_point; + pupload->segs = fhead->head.number_segs; + if(pupload->segs) { + pupload->fsize = sizeof(struct SPIFlashHeadSegment); + pupload->status = 5; // = 5 загрузка файла оверлея, начать с загрузки заголовка сегмента + } + else { + pupload->fsize = 0; + pupload->status = 4; // = 4 загрузка файла оверлея, запуск entry_point + } + // + len = sizeof(struct SPIFlashHeader); + ts_conn->cntri += len; + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[len], ts_conn->sizei - len)) return 500; + web_conn->content_len -= len; + // + break; + } +#endif + else if(rom_xstrcmp(pupload->name, sysconst_filename)) { + pupload->fsize = FLASH_SECTOR_SIZE; + pupload->faddr = FLASH_RESERVED_DATA_BASE; // FLASH_SYSTEM_DATA_ADDR + pupload->status = 2; // = 2 загрузка файла во flash + break; + } + else if(rom_xstrcmp(pupload->name, sector_filename)) { + pupload->fsize = FLASH_SECTOR_SIZE; + pupload->faddr = ahextoul(&pupload->name[sector_filename_size]) << 12; + pupload->status = 2; // = 2 загрузка файла сектора во flash + break; + }; + if(isWEBFSLocked) return 400; + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err3_filename); // rtl_memcpy(pupload->filename,"/disk_er3.htm\0",14); // неизвестный тип + return 200; + } + else { + uint8 *pcmp = web_strnstr(pstr, CRLF, len); + if(pcmp == NULL) return 0; // докачивать + ret = find_boundary(pupload, pstr, len); +#if DEBUGSOO > 4 + os_printf("ret=%u ", ret ); +#endif + if((ret != 1 && ret != 200)) { // не найден конец или новый boundary? + return ret; // догружать + } + *pcmp = '\0'; + web_int_vars(ts_conn, pupload->name, pstr); + if(ret == 200) return ret; + // найден следующий boundary + len = pupload->pbndr - ts_conn->pbufi; + pupload->status = 0; // = 0 найден следующий boundary +#if DEBUGSOO > 4 + os_printf("trim#%u\n", len ); +#endif + ts_conn->cntri += len; // далее идут данные + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[len], ts_conn->sizei - len)) return 500; + web_conn->content_len -= len; + break; + } +// return 400; + } +// default: + case 2: // загрузка файла во flash + case 3: // загрузка WebFileSystem во flash (скорость записи W25Q128 ~175 килобайт в сек, полный диск на 15,5МБ пишется 90..100 сек ) + { +#if DEBUGSOO > 4 + os_printf("fdata "); +#endif + uint32 block_size = mMIN(max_len_buf_write_flash + 8 + pupload->sizeboundary, web_conn->content_len); + if(ts_conn->sizei < block_size) return 0; // докачивать + ret = find_boundary(pupload, pstr, block_size); +#if DEBUGSOO > 4 + os_printf("ret=%u ", ret); +#endif + if((ret == 1 || ret == 200)) { // найден конец или новый boundary? + len = mMIN(block_size, pupload->pbndr - 2 - ts_conn->pbufi); + } + else { + len = mMIN(max_len_buf_write_flash, web_conn->content_len - 8 - pupload->sizeboundary); + } +#if DEBUGSOO > 4 + os_printf("\nlen=%d, block_size=%d, content_len=%d, sizeboundary= %d, ret=%d, data = %d, load=%d", len, block_size, web_conn->content_len, pupload->sizeboundary, ret, pupload->pbndr - ts_conn->pbufi, ts_conn->sizei); +#endif + if(pupload->fsize < len) block_size = pupload->fsize; + else block_size = len; + if(block_size) { // идут данные файла +// tcpsrv_unrecved_win(ts_conn); // для ускорения, пока стрирается-пишется уже обновит окно (включено в web_rx_buf) + + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(pupload->faddr >= flash_get_size(&flashobj) && pupload->status == 3) { + if((pupload->faddr & 0x0000FFFF)==0) { + +#if DEBUGSOO > 2 + os_printf("Clear flash page addr %p... ", pupload->faddr); +#endif + flash_erase_block(&flashobj, pupload->faddr); + } + } + else if((pupload->faddr & 0x00000FFF) == 0) { +#if DEBUGSOO > 2 + os_printf("Clear flash sector addr %p... ", pupload->faddr); +#endif + flash_erase_sector(&flashobj, pupload->faddr); + } +#if DEBUGSOO > 2 + os_printf("Write flash addr:%p[0x%04x]\n", pupload->faddr, block_size); +#endif + flash_stream_write(&flashobj, pupload->faddr, (block_size + 3)&(~3), (uint32 *)pstr); + + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + pupload->fsize -= block_size; + pupload->faddr += block_size; + } +#if DEBUGSOO > 4 + os_printf("trim#%u\n", len); +#endif + if(len) { + ts_conn->cntri += len; + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[len], ts_conn->sizei - len)) return 500; + web_conn->content_len -= len; + } +#ifdef SET_CPU_CLK_SPEED +// if(syscfg.cfg.b.hi_speed_enable) set_cpu_clk(); +#endif + if((ret == 1 || ret == 200)) { // найден конец или новый boundary? + if(pupload->status == 3) WEBFSInit(); + if(pupload->fsize != 0) { + if(!isWEBFSLocked) { + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err1_filename); // rtl_memcpy(pupload->filename,"/disk_er1.htm\0",14); // не всё передано или неверный формат + return 200; + } + return 400; // не всё передано или неверный формат + } + else { + if(!isWEBFSLocked) { + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_ok_filename); // rtl_memcpy(pupload->filename,"/disk_ok.htm\0",13); + }; + }; + if(ret == 1) pupload->status = 0; // = 0 найден следующий boundary + if(ret == 200) return ret; + } + break; + } +#ifdef USE_OVERLAY + case 4: // загрузка данных/кода оверлея + case 5: // загрузка заголовка данных оверлея + { + uint32 block_size = mMIN(max_len_buf_write_flash + 8 + pupload->sizeboundary, web_conn->content_len); + if(ts_conn->sizei < block_size) return 0; // докачивать + ret = find_boundary(pupload, pstr, block_size); + if((ret == 1 || ret == 200)) { // найден конец или новый boundary? + len = mMIN(block_size, pupload->pbndr - 2 - ts_conn->pbufi); + } + else { + len = mMIN(max_len_buf_write_flash, web_conn->content_len - 8 - pupload->sizeboundary); + } + block_size = len; + while(block_size) { +#if DEBUGSOO > 5 + os_printf("blk:%d,st:%d,fs:%d,%d ", block_size, pupload->status, pupload->fsize, pupload->segs); +#endif + if(pupload->status == 5) { + if(block_size >= sizeof(struct SPIFlashHeadSegment)) { // размер данных + if(pupload->segs) { // + rtl_memcpy(&pupload->faddr, pstr, 4); + rtl_memcpy(&pupload->fsize, &pstr[4], 4); +#if DEBUGSOO > 4 + os_printf("New seg ovl addr:%p[%p] ", pupload->faddr, pupload->fsize); +#endif + } + } + else if(ret != 1 && ret != 200) { // не найден конец или boundary? + return 0; // докачивать + } + else { +#if DEBUGSOO > 5 + os_printf("err_load_fseg "); +#endif +// if(block_size < sizeof(struct SPIFlashHeadSegment) +// || pupload->segs == 0 // +// || pupload->fsize > USE_OVERLAY) { + if(!isWEBFSLocked) { + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err1_filename); // rtl_memcpy(pupload->filename,"/disk_er1.htm\0",14); // не всё передано или неверный формат + return 200; + } + return 400; // не всё передано или неверный формат + } + pupload->segs--; // счет сегментов + pupload->status = 4; // загрузка данных/кода оверлея + pstr += sizeof(struct SPIFlashHeadSegment); + block_size -= sizeof(struct SPIFlashHeadSegment); + }; + uint32 i = mMIN(pupload->fsize, block_size); + if(i) { +#if DEBUGSOO > 1 + os_printf("Wr:%p[%p] ", pupload->faddr, i); +#endif + copy_s1d4((void *)pupload->faddr, pstr, i); + block_size -= i; + pupload->faddr += i; + pstr += i; + pupload->fsize -= i; + }; + if(pupload->fsize == 0) { + if(pupload->segs) { // все сегменты загружены? + pupload->status = 5; // загрузка заголовка данных оверлея + } + else { // все сегменты загружены + block_size = 0; + break; // break while(block_size) + } + }; + }; // while(block_size) + if(len) { + ts_conn->cntri += len; + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[len], ts_conn->sizei - len)) return 500; + web_conn->content_len -= len; + }; + if((ret == 1 || ret == 200)) { // найден конец или новый boundary? +#if DEBUGSOO > 5 + os_printf("fs:%d,%d ", pupload->fsize, pupload->segs); +#endif + if(pupload->fsize != 0 || pupload->segs != 0) { // + if(!isWEBFSLocked) { + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_err1_filename); // rtl_memcpy(pupload->filename,"/disk_er1.htm\0",14); // не всё передано или неверный формат + return 200; + } + return 400; // не всё передано или неверный формат + } + else { +#if DEBUGSOO > 1 + os_printf("Run%p ", pupload->start); +#endif + if(pupload->start >= IRAM_BASE) { + ovl_call = (tovl_call *)pupload->start; + web_conn->web_disc_cb = (web_func_disc_cb)pupload->start; // адрес старта оверлея + web_conn->web_disc_par = 1; // параметр функции - инициализация + } + if(!isWEBFSLocked) { + SetSCB(SCB_REDIR); + rom_xstrcpy(pupload->filename, disk_ok_filename); // rtl_memcpy(pupload->filename,"/disk_ok.htm\0",13); + }; + }; + if(ret == 1) pupload->status = 0; // = 0 найден следующий boundary + if(ret == 200) return ret; + }; + break; + }; +#endif + }; + }; + return 0; // +} +//----------------------------------------------------------------------------- +// web_rx_buf +// +//----------------------------------------------------------------------------- +LOCAL bool ICACHE_FLASH_ATTR web_rx_buf(HTTP_CONN *CurHTTP, TCP_SERV_CONN *ts_conn) +{ + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + ts_conn->flag.rx_buf = 1; // указать, что всегда в режиме докачивать +// CurHTTP->fileType = HTTP_UNKNOWN; +// ts_conn->pbufi, ts_conn->cntri; +#if DEBUGSOO > 3 + os_printf("rx:%u[%u] ", web_conn->content_len, ts_conn->sizei); +#endif + if(ts_conn->sizei == 0) return true; // докачивать + tcpsrv_unrecved_win(ts_conn); + int ret = upload_boundary(ts_conn); + if(ret > 1) { + CurHTTP->httpStatus = ret; + web_conn->content_len = 0; + if(ret == 200) { + if(CheckSCB(SCB_REDIR)) { + HTTP_UPLOAD *pupload = (HTTP_UPLOAD *)ts_conn->pbufo; + if(pupload != NULL) { + rtl_memcpy(CurHTTP->pFilename, pupload->filename, VarNameSize); +// SetSCB(SCB_DISCONNECT); + } + } + else if((!isWEBFSLocked) && CheckSCB(SCB_FOPEN) + && web_conn->webfile <= WEBFS_MAX_HANDLE + && WEBFSGetFilename(web_conn->webfile, CurHTTP->pFilename, FileNameSize)) { + SetSCB(SCB_REDIR); +// web_conn->content_len = WEBFSGetBytesRem(web_conn->webfile); // WEBFSGetSize(web_conn->webfile); +// webserver_file_ext(CurHTTP, CurHTTP->pFilename); +// return false; // ok 200 + file + } + } + SetSCB(SCB_DISCONNECT); + return false; // неизвестный content или end + } + else { +#if DEBUGSOO > 2 + os_printf("no boundary "); +#endif + if(ts_conn->sizei > MAX_NO_DATA_BUF_SIZE) { + CurHTTP->httpStatus = 418; // 418: Out of Coffee + SetSCB(SCB_DISCONNECT); + return false; // неизвестный content или end + } + }; + if(web_conn->content_len > ts_conn->cntri) return true; // докачивать + CurHTTP->httpStatus = 400; + SetSCB(SCB_DISCONNECT); + web_conn->content_len = 0; + return false; // неизвестный content +} +//----------------------------------------------------------------------------- +//--- web_trim_bufi ----------------------------------------------------------- +//----------------------------------------------------------------------------- +bool ICACHE_FLASH_ATTR web_trim_bufi(TCP_SERV_CONN *ts_conn, uint8 *pdata, uint32 data_len) +{ + if(pdata != NULL && data_len != 0 && ts_conn->sizei > data_len) { + rtl_memcpy(ts_conn->pbufi, pdata, data_len); // переместим кусок в начало буфера + ts_conn->pbufi = (uint8 *)os_realloc(ts_conn->pbufi, data_len + 1); // mem_trim(ts_conn->pbufi, data_len + 1); + if(ts_conn->pbufi != NULL) { + ts_conn->sizei = data_len; // размер куска + ts_conn->cntri = 0; + } + else return false; // CurHTTP.httpStatus = 500; // 500 Internal Server Error + } + else if(ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + ts_conn->sizei = 0; + ts_conn->cntri = 0; + }; + return true; +} +/****************************************************************************** + * web_feee_bufi + * освободить приемный буфер +*******************************************************************************/ +bool ICACHE_FLASH_ATTR web_feee_bufi(TCP_SERV_CONN *ts_conn) +{ + if(ts_conn->pbufi != NULL) { + os_free(ts_conn->pbufi); + ts_conn->pbufi = NULL; + ts_conn->sizei = 0; + ts_conn->cntri = 0; + return true; + } + return false; +} +/****************************************************************************** + * FunctionName : webserver_recv + * Description : Processing the received data from the server + * Parameters : arg -- Additional argument to pass to the callback function + * pusrdata -- The received data (or NULL when the connection has been closed!) + * length -- The length of received data + * Returns : none + * + * For HTTP 1.0, this should normally only happen once (if the request fits in one packet). + * +*******************************************************************************/ +LOCAL err_t ICACHE_FLASH_ATTR webserver_received_data(TCP_SERV_CONN *ts_conn) +{ +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); + os_printf("read: %d ", ts_conn->sizei); +#endif + HTTP_CONN CurHTTP; // Current HTTP connection state + WEB_SRV_CONN *web_conn = ReNew_web_conn(ts_conn); + if(web_conn == NULL) { +#if DEBUGSOO > 1 + os_printf("err mem!\n"); +#endif + return ERR_MEM; + } + if(CheckSCB(SCB_CLOSED | SCB_DISCONNECT | SCB_FCLOSE )) // обрабатывать нечего + return ERR_OK; + if(!CheckSCB(SCB_WEBSOC)) { + web_conn->udata_start = 0; + web_conn->udata_stop = 0; + } + os_memset(&CurHTTP, 0, sizeof(CurHTTP)); + CurHTTP.httpStatus = 200; // OK + CurHTTP.fileType = HTTP_UNKNOWN; + // прием и обработка заголовка HHTP + if(!CheckSCB(SCB_HEAD_OK)) { // заголовок уже принят и обработан? нет + ts_conn->flag.rx_buf = 1; // докачивать буфер + tcpsrv_unrecved_win(ts_conn); + // разбираем докачан или нет заголовок HTTP, что там принято GET или POST и открываем файл и прием content, если это POST и не прием файла. + if(parse_header(&CurHTTP, ts_conn)) { // заголовок полный? нет + if(ts_conn->sizei < MAX_HTTP_HEAD_BUF) { +#if DEBUGSOO > 4 + os_printf("buf"); +#endif +#if DEBUGSOO > 1 + os_printf("...\n"); +#endif + return ERR_OK; // будем принимать ещё. + }; + CurHTTP.httpStatus = 413; // 413 Request Entity Too Large // пока так + }; + // разбор заголовка +#if DEBUGSOO > 1 +#ifdef WEBSOCKET_ENA + os_printf("%s f[%s] ", (CheckSCB(SCB_POST))? "POST" : (CheckSCB(SCB_WEBSOC))? "WEBSOC" : "GET", CurHTTP.pFilename); +#else + os_printf("%s f[%s] ", (CheckSCB(SCB_POST))? "POST" : "GET", CurHTTP.pFilename); +#endif +#endif +#if DEBUGSOO > 3 + os_printf("hcn:%p[%d],wcn:%d ", CurHTTP.pcontent, CurHTTP.content_len, web_conn->content_len); +#endif + if(CurHTTP.httpStatus == 200) { // && CheckSCB(SCB_FOPEN)) { // если файл открыт и всё OK + if(CurHTTP.cookie_len != 0) web_parse_cookie(&CurHTTP, ts_conn); + web_parse_uri_vars(&CurHTTP, ts_conn); + if(CurHTTP.pcontent != NULL) { + if(CheckSCB(SCB_RXDATA)) { + if(web_conn->content_len) { // с заголовком приняли кусок данных файла? +#if DEBUGSOO > 3 + os_printf("trim:%u[%u] ", web_conn->content_len, CurHTTP.content_len); +#endif + if(!web_trim_bufi(ts_conn, CurHTTP.pcontent, CurHTTP.content_len)) { +#if DEBUGSOO > 1 + os_printf("trim error!\n"); +#endif + CurHTTP.httpStatus = 500; + }; + }; + } + else { + if(CurHTTP.content_len != 0) web_parse_content(&CurHTTP, ts_conn); + }; + }; + }; + SetSCB(SCB_HEAD_OK); // заголовок принят и обработан + }; +#if DEBUGSOO > 3 + os_printf("tst_rx: %u, %u, %u ", CurHTTP.httpStatus, (CheckSCB(SCB_RXDATA) != 0), web_conn->content_len ); +#endif + // проверка на прием данных (content) + if(CurHTTP.httpStatus == 200 && CheckSCB(SCB_RXDATA) && (web_conn->content_len) && web_rx_buf(&CurHTTP, ts_conn)) { +#if DEBUGSOO > 1 + os_printf("...\n"); +#endif + return ERR_OK; // докачивать content + }; +#ifdef WEBSOCKET_ENA + if(CheckSCB(SCB_WEBSOC) && CurHTTP.httpStatus == 200 && (!CheckSCB(SCB_REDIR))) { + if(!CheckSCB(SCB_WSDATA)) { + // создание и вывод заголовка ответа websock + ClrSCB(SCB_RXDATA); + Close_web_conn(ts_conn); // закрыть все файлы + web_print_headers(&CurHTTP, ts_conn); + if(CheckSCB(SCB_DISCONNECT)) { + ts_conn->flag.rx_null = 1; // всё - больше не принимаем! + ts_conn->flag.rx_buf = 0; // не докачивать буфер + if(web_feee_bufi(ts_conn)) tcpsrv_unrecved_win(ts_conn); // уничтожим буфер + } + else { + SetSCB(SCB_WSDATA); + ts_conn->flag.rx_buf = 1; // указать, что всегда в режиме докачивать + tcpsrv_unrecved_win(ts_conn); + tcp_output(ts_conn->pcb); + + if(web_feee_bufi(ts_conn)) tcpsrv_unrecved_win(ts_conn); // уничтожим буфер +/* + if(ts_conn->pbufi != NULL && ts_conn->sizei != 0) { // что-то ещё есть в буфере? +#if DEBUGSOO > 1 + os_printf("ws_rx[%u]? ", ts_conn->sizei); +#endif + websock_rx_data(ts_conn); + } +*/ + } + } + else { + websock_rx_data(ts_conn); + } + } + else +#endif + { + ts_conn->flag.rx_null = 1; // всё - больше не принимаем! + ts_conn->flag.rx_buf = 0; // не докачивать буфер + if(web_feee_bufi(ts_conn)) tcpsrv_unrecved_win(ts_conn); // уничтожим буфер + if(tcp_sndbuf(ts_conn->pcb) >= HTTP_SEND_SIZE) { // возможна втавка ответа? + // создание и вывод заголовка ответа. + web_print_headers(&CurHTTP, ts_conn); + // начало предачи файла, если есть + if((!CheckSCB(SCB_CLOSED | SCB_DISCONNECT | SCB_FCLOSE))&&CheckSCB(SCB_FOPEN)) webserver_send_fdata(ts_conn); + } + else { +#if DEBUGSOO > 1 + os_printf("sndbuf=%u! ", tcp_sndbuf(ts_conn->pcb)); +#endif + SetSCB(SCB_FCLOSE | SCB_DISCONNECT); + }; + } + if(CheckSCB(SCB_FCLOSE)) { + tcp_output(ts_conn->pcb); + Close_web_conn(ts_conn); + SetSCB(SCB_DISCONNECT); + } + if(CheckSCB(SCB_DISCONNECT)) web_int_disconnect(ts_conn); +#if DEBUGSOO > 1 + else os_printf("...\n"); +#endif + return ERR_OK; +} +/****************************************************************************** + * web_int_disconnect +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR web_int_disconnect(TCP_SERV_CONN *ts_conn) +{ +#if DEBUGSOO > 1 + os_printf("dis\n"); +#endif + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + ts_conn->flag.tx_null = 1; + ts_conn->flag.rx_null = 1; + tcpsrv_unrecved_win(ts_conn); + if(ts_conn->flag.pcb_time_wait_free) tcpsrv_disconnect(ts_conn); + SetSCB(SCB_CLOSED); +} +/****************************************************************************** + * FunctionName : webserver_sent_cb + * Description : Sent callback function to call for this espconn when data + * is successfully sent + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +LOCAL err_t ICACHE_FLASH_ATTR webserver_sent_callback(TCP_SERV_CONN *ts_conn) +{ +#if DEBUGSOO > 1 + tcpsrv_print_remote_info(ts_conn); +#endif + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(web_conn == NULL) return ERR_ARG; + if(CheckSCB(SCB_CLOSED) == 0) { // No SCB_CLOSED + if(!CheckSCB(SCB_DISCONNECT)) { +#ifdef WEBSOCKET_ENA + if(CheckSCB(SCB_WSDATA)) { + websock_rx_data(ts_conn); + } + else +#endif + if((!CheckSCB(SCB_FCLOSE))&&CheckSCB(SCB_FOPEN)) webserver_send_fdata(ts_conn); + } + if(CheckSCB(SCB_FCLOSE)) { + Close_web_conn(ts_conn); + SetSCB(SCB_DISCONNECT); + } + if(CheckSCB(SCB_DISCONNECT)) web_int_disconnect(ts_conn); + #if DEBUGSOO > 1 + else os_printf("...\n"); + #endif + } + else { // SCB_CLOSED +#if DEBUGSOO > 1 + os_printf("#%04x ?\n", web_conn->webflag); +#endif + ts_conn->flag.tx_null = 1; + ts_conn->flag.rx_null = 1; + }; + return ERR_OK; +} +/****************************************************************************** + * FunctionName : webserver_disconnect + * Description : calback disconnect + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR webserver_disconnect(TCP_SERV_CONN *ts_conn) +{ +#if DEBUGSOO > 1 + tcpsrv_disconnect_calback_default(ts_conn); +#endif + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(web_conn == NULL) return; + Close_web_conn(ts_conn); + if(CheckSCB(SCB_SYSSAVE)) { + ClrSCB(SCB_SYSSAVE); + sys_write_cfg(); + } + if(web_conn->web_disc_cb != NULL) { + if(xQueueSendToBack(xQueueWebSrv, &web_conn->web_disc_cb, 0) != pdPASS) { +#if DEBUGSOO > 1 + os_printf("\nWEB: Queue QFn full!\n"); +#endif + } +// web_conn->web_disc_cb(web_conn->web_disc_par); + }; +} + +/****************************************************************************** +******************************************************************************/ +void qfnk_task(void) +{ + WEB_SRV_QFNK qfn; + while(1) { + if(xQueueReceive(xQueueWebSrv, &qfn, portMAX_DELAY ) == pdPASS) { + if(qfn.fnk) { +#if DEBUGSOO > 2 + os_printf("qfn: %p(%p)\n", qfn.fnk, qfn.param); +#endif + qfn.fnk(qfn.param); + } +// else { +// vTaskDelete(NULL); +// } + } + } +} +/****************************************************************************** + * FunctionName : webserver_init + * Description : Открытие сервера + * Parameters : arg -- port N + * Returns : none +*******************************************************************************/ +//TaskHandle_t xHandleQfn; +err_t ICACHE_FLASH_ATTR webserver_init(uint16 portn) +{ +// WEBFSInit(); // файловая система + + err_t err = ERR_MEM; + xQueueWebSrv = xQueueCreate(5, sizeof( WEB_SRV_QFNK )); // Create a queue... + if(xQueueWebSrv) { +// if(xTaskCreate(qfnk_task, "web_qfn", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &xHandleQfn) == pdPASS) + if(xTaskCreate(qfnk_task, "web_qfn", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, NULL) == pdPASS) + { + TCP_SERV_CFG *p = tcpsrv_init(portn); + if (p != NULL) { + // изменим конфиг на наше усмотрение: + if(syscfg.cfg.b.web_time_wait_delete) p->flag.pcb_time_wait_free = 1; // пусть убивает, для теста и проксей + p->max_conn = 256; // сработает по heap_size +#if DEBUGSOO > 3 + os_printf("Max connection %d, time waits %d & %d, min heap size %d\n", + p->max_conn, p->time_wait_rec, p->time_wait_cls, p->min_heap); +#endif + p->time_wait_rec = syscfg.web_twrec; // =0 -> вечное ожидание + p->time_wait_cls = syscfg.web_twcls; // =0 -> вечное ожидание + // слинкуем с желаемыми процедурами: + p->func_discon_cb = webserver_disconnect; + // p->func_listen = webserver_listen; // не требуется + p->func_sent_cb = webserver_sent_callback; + p->func_recv = webserver_received_data; + err = tcpsrv_start(p); + if (err != ERR_OK) { + tcpsrv_close(p); + p = NULL; + } + else { +#if DEBUGSOO > 1 + os_printf("WEB: init port %u\n", portn); +#endif + } + + } +// else err = ERR_MEM; + } +// else err = ERR_MEM; + } +// else err = ERR_MEM; + return err; +} + +/****************************************************************************** + * FunctionName : webserver_close + * Description : закрытие сервера + * Parameters : arg -- port N + * Returns : none +*******************************************************************************/ +err_t ICACHE_FLASH_ATTR webserver_close(uint16 portn) +{ + err_t err = ERR_ARG; + if(portn != 0) err = tcpsrv_close(tcpsrv_server_port2pcfg(portn)); +#if DEBUGSOO > 1 + if(err == ERR_OK) os_printf("WEB: close\n"); +#endif + if(xQueueWebSrv) { + WEB_SRV_QFNK qfn; + qfn.fnk = vTaskDelete; + qfn.param = NULL; + if(xQueueSendToBack(xQueueWebSrv, &qfn, 1000) == pdPASS) { + while(uxQueueMessagesWaiting(xQueueWebSrv)) { + vTaskDelay(10); + }; + } +/* + else if(xHandleQfn) { + vTaskDelete(xHandleQfn); + } + vQueueDelete(xQueueWebSrv); + xHandleQfn = NULL; +*/ + xQueueWebSrv = NULL; + }; + return err; +} +/****************************************************************************** + * FunctionName : webserver_reinit + * Description : закрытие сервера и открытие нового + * Parameters : arg -- port N открытого порта + * Returns : none +*******************************************************************************/ +err_t ICACHE_FLASH_ATTR webserver_reinit(uint16 portn) +{ + err_t err = ERR_OK; +// if(portn == syscfg.web_port) return err; + if(portn) err = tcpsrv_close(tcpsrv_server_port2pcfg(portn)); // закрыть старый порт + if(syscfg.web_port) err = webserver_init(syscfg.web_port); // открыть новый + return err; +} + +#endif // USE_WEB diff --git a/project/src/web/web_utils.c b/project/src/web/web_utils.c new file mode 100644 index 0000000..020e98a --- /dev/null +++ b/project/src/web/web_utils.c @@ -0,0 +1,640 @@ +/* + * web_utils.c + * + * Created on: 25 дек. 2014 г. + * Author: PV` + */ +#include "user_config.h" +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +//#include "bios.h" +//#include "sdk/add_func.h" +//#include "ets_sys.h" +//#include "os_type.h" +//#include "osapi.h" +//#include "user_interface.h" +#include "web_utils.h" +#include "esp_comp.h" + +#define mMIN(a, b) ((a= '0' && *s <= '9') + n = 10*n - (*s++ - '0'); + return neg ? n : -n; +} +/****************************************************************************** + * copy_align4 + * копирует данные из области кеширования flash и т.д. +*******************************************************************************/ +void ICACHE_FLASH_ATTR copy_align4(void *ptrd, void *ptrs, uint32 len) +{ + union { + uint8 uc[4]; + uint32 ud; + }tmp; + uint8 *pd = ptrd; + uint32 *p = (uint32 *)((uint32)ptrs & (~3)); + uint32 xlen = ((uint32)ptrs) & 3; + if(xlen) { + if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p++; + else { + tmp.ud = 0; + p++; + } + while (len) { + *pd++ = tmp.uc[xlen++]; + len--; + if(xlen >= 4) break; + } + } + xlen = len >> 2; + while(xlen) { + if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p++; + else { + tmp.ud = 0; + p++; + } + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + } + len &= 3; + if(len) { + if(((uint32)p >= 0x10000000)&&((uint32)p < 0x9A002000)) tmp.ud = *p; + else tmp.ud = 0; + uint8 * ptmp = tmp.uc; + while (len--) *pd++ = *ptmp++; + } +} +/****************************************************************************** + * FunctionName : hextoul +*******************************************************************************/ +// bool conv_str_hex(uint32 * dest, uint8 *s); +uint32 ICACHE_FLASH_ATTR hextoul(uint8 *s) +{ +/* + uint32 val; + if(!conv_str_hex(&val, s)) return 0; + return val; +*/ + uint32 val = 0; + while (*s) + { + if (*s >= '0' && *s <= '9') + { + val <<= 4; + val |= *s - '0'; + } + else if (*s >= 'A' && *s <= 'F') + { + val <<= 4; + val |= *s - 'A' + 10; + } + else if (*s >= 'a' && *s <= 'f') + { + val <<= 4; + val |= *s - 'a' + 10; + } + else break; + s++; + }; + return val; +} +/****************************************************************************** + * FunctionName : ahextoul +*******************************************************************************/ +// bool convert_para_str(uint32 * dest, uint8 *s); +uint32 ICACHE_FLASH_ATTR ahextoul(uint8 *s) +{ +/* + uint32 ret; + if(!convert_para_str(&ret, s)) return 0; + return ret; +*/ + if((s[0]=='0') && ((s[1] | 0x20) =='x')) return hextoul(s+2); + return rom_atoi(s); +} +/****************************************************************************** + * FunctionName : cmpcpystr + * Description : выбирает слово из строки текста с заданными начальным символом + * и конечным терминатором. Терминатор и стартовый символ не копирует, если заданы. + * Parameters : При задании начального символа = '\0' берется любой символ (>' '). + Копирует до символа <' ' или терминатора. + Задается ограничение размера буфера для копируемого слова (с дописыванием в буфер '\0'!). + * Returns : Зависит от значения терминатора, указывает на терминатор в строке, + если терминатор найден. + Если NULL, то начальный или конечный терминатор не найден. +*******************************************************************************/ +uint8 * ICACHE_FLASH_ATTR cmpcpystr(uint8 *pbuf, uint8 *pstr, uint8 a, uint8 b, uint16 len) +{ + if(len == 0) pbuf = NULL; + if(pstr == NULL) { + if(pbuf != NULL) *pbuf='\0'; + return NULL; + }; + uint8 c; + do { + c = *pstr; + if(c < ' ') { // строка кончилась + if(pbuf != NULL) *pbuf='\0'; + return NULL; // id не найден + }; + if((a == '\0')&&(c > ' ')) break; // не задан -> любой символ + pstr++; + if(c == a) break; // нашли стартовый символ (некопируемый в буфер) + }while(1); + if(pbuf != NULL) { + while(len--) { + c = *pstr; + if(c == b) { // нашли терминирующий символ (некопируемый в буфер) + *pbuf='\0'; + return pstr; // конечный терминатор найден + }; +// if(c <= ' ') { // строка кончилась или пробел + if(c < ' ') { // строка кончилась или пробел + *pbuf='\0'; + return NULL; // конечный терминатор не найден + }; + pstr++; + *pbuf++ = c; + }; + *--pbuf='\0'; // закрыть буфер + }; + do { + c = *pstr; + if(c == b) return pstr; // нашли терминирующий символ +// if(c <= ' ') return NULL; // строка кончилась + if(c < ' ') return NULL; // строка кончилась + pstr++; + }while(1); +} +/****************************************************************************** + * FunctionName : str_array + * Набирает из строки s массив слов в buf в кол-ве до max_buf + * возврат - кол-во переменных в строке + * Разделитель переменных в строке ',' + * Если нет переменной, то пропускает изменение в buf + * Примеры: + * Строка "1,2,3,4" -> buf = 0x01 0x02 0x03 0x04 + * Строка "1,,3," -> buf = 0x01 (не изменено) 0x03 (не изменено) +*******************************************************************************/ +uint32 ICACHE_FLASH_ATTR str_array(uint8 *s, uint32 *buf, uint32 max_buf) +{ + uint32 ret = 0; + uint8 *sval = NULL; + while(max_buf > ret) { + if(sval == NULL) { + if (*s == '-' && s[1] >= '0' && s[1] <= '9') { + sval = s; + s++; + } + else if (*s >= '0' && *s <= '9') sval = s; + } + if(*s == ',' || *s <= ')') { + if(sval != NULL) { + *buf = ahextoul(sval); + sval = NULL; + } + buf++; + ret++; + if(*s < ')') return ret; + } + s++; + } + return ret; +} +uint32 ICACHE_FLASH_ATTR str_array_w(uint8 *s, uint16 *buf, uint32 max_buf) +{ + uint32 ret = 0; + uint8 *sval = NULL; + while(max_buf > ret) { + if(sval == NULL) { + if (*s == '-' && s[1] >= '0' && s[1] <= '9') { + sval = s; + s++; + } + else if (*s >= '0' && *s <= '9') sval = s; + } + if(*s == ',' || *s <= ')') { + if(sval != NULL) { + *buf = ahextoul(sval); + sval = NULL; + } + buf++; + ret++; + if(*s < ')') return ret; + } + s++; + } + return ret; +} +uint32 ICACHE_FLASH_ATTR str_array_b(uint8 *s, uint8 *buf, uint32 max_buf) +{ + uint32 ret = 0; + uint8 *sval = NULL; + while(max_buf > ret) { + if(sval == NULL) { + if (*s == '-' && s[1] >= '0' && s[1] <= '9') { + sval = s; + s++; + } + else if (*s >= '0' && *s <= '9') sval = s; + } + if(*s == ',' || *s == '.' || *s <= ')') { + if(sval != NULL) { + *buf = ahextoul(sval); + sval = NULL; + } + buf++; + ret++; + if(*s < ')') return ret; + } + s++; + } + return ret; +} +/****************************************************************************** + * FunctionName : strtmac +*******************************************************************************/ +void ICACHE_FLASH_ATTR strtomac(uint8 *s, uint8 *macaddr) +{ + uint8 pbuf[4]; + s = cmpcpystr(pbuf, s, 0, ':', 3); + *macaddr++ = hextoul(pbuf); + int i = 4; + while(i--) { + s = cmpcpystr(pbuf, s, ':', ':', 3); + *macaddr++ = hextoul(pbuf); + } + s = cmpcpystr(pbuf, s, ':', ' ', 3); + *macaddr++ = hextoul(pbuf); +} +/****************************************************************************** + * FunctionName : urldecode +*******************************************************************************/ +int ICACHE_FLASH_ATTR urldecode(uint8 *d, uint8 *s, uint16 lend, uint16 lens) +{ + uint16 ret = 0; + if(s != NULL) while ((lens--) && (lend--) && (*s > ' ')) { + if ((*s == '%')&&(lens > 1)) { + s++; + int i = 2; + uint8 val = 0; + while(i--) { + if (*s >= '0' && *s <= '9') { + val <<= 4; + val |= *s - '0'; + } else if (*s >= 'A' && *s <= 'F') { + val <<= 4; + val |= *s - 'A' + 10; + } else if (*s >= 'a' && *s <= 'f') { + val <<= 4; + val |= *s - 'a' + 10; + } else + break; + s++; + lens--; + }; + s--; + *d++ = val; + } else if (*s == '+') + *d++ = ' '; + else + *d++ = *s; + ret++; + s++; + } + *d = '\0'; + return ret; +} +/****************************************************************************** + * FunctionName : urlencode +*******************************************************************************/ +/*int ICACHE_FLASH_ATTR urlencode(uint8 *d, uint8 *s, uint16 lend, uint16 lens) +{ + uint16 ret = 0; + if(s != NULL) while ((lens--) && (lend--) && (*s != '\0')) { + if ( (48 <= *s && *s <= 57) //0-9 + || (65 <= *s && *s <= 90) //abc...xyz + || (97 <= *s && *s <= 122) //ABC...XYZ + || (*s == '~' || *s == '!' || *s == '*' || *s == '(' || *s == ')' || *s == '\'')) { + *d++ = *s++; + ret++; + } else { + if(lend >= 3) { + ret += 3; + lend -= 3; + *d++ = '%'; + uint8 val = *s >> 4; + if(val <= 9) val += '0'; + else val += 0x41 - 10; + *d++ = val; + val = *s++ & 0x0F; + if(val <= 9) val += '0'; + else val += 0x41 - 10; + *d++ = val; + } + else break; + } + } + *d = '\0'; + return ret; +}*/ +/****************************************************************************** + * FunctionName : htmlcode +*******************************************************************************/ +int ICACHE_FLASH_ATTR htmlcode(uint8 *d, uint8 *s, uint16 lend, uint16 lens) +{ + uint16 ret = 0; + if(s != NULL) while ((lens--) && (lend--) && (*s != '\0')) { + if ( *s == 0x27 ) { // "'" ' + if(lend >= 6) { + ret += 6; + lend -= 6; + s++; + *d++ = '&'; + *d++ = 'a'; + *d++ = 'p'; + *d++ = 'o'; + *d++ = 's'; + *d++ = ';'; + } + else break; + } else if ( *s == '"' ) { // " + if(lend >= 6) { + ret += 6; + lend -= 6; + s++; + *d++ = '&'; + *d++ = 'q'; + *d++ = 'u'; + *d++ = 'o'; + *d++ = 't'; + *d++ = ';'; + } + else break; + } else if ( *s == '&' ) { // & + if(lend >= 5) { + ret += 5; + lend -= 5; + s++; + *d++ = '&'; + *d++ = 'a'; + *d++ = 'm'; + *d++ = 'p'; + *d++ = ';'; + } + else break; + } else if ( *s == '<' ) { // < + if(lend >= 4) { + ret += 4; + lend -= 4; + s++; + *d++ = '&'; + *d++ = 'l'; + *d++ = 't'; + *d++ = ';'; + } + else break; + } else if ( *s == '>' ) { // > + if(lend >= 4) { + ret += 4; + lend -= 4; + s++; + *d++ = '&'; + *d++ = 'g'; + *d++ = 't'; + *d++ = ';'; + } + else break; + } else { + *d++ = *s++; + ret++; + } + } + *d = '\0'; + return ret; +} +//============================================================================= +uint8* ICACHE_FLASH_ATTR +web_strnstr(const uint8* buffer, const uint8* token, int len) +{ + const uint8* p; + int tokenlen = rtl_strlen(token); + if (tokenlen == 0) { + return (uint8 *)buffer; + }; + for (p = buffer; *p && (p + tokenlen <= buffer + len); p++) { + if ((*p == *token) && (rtl_strncmp(p, token, tokenlen) == 0)) { + return (uint8 *)p; + }; + }; + return NULL; +} +//============================================================================= +static const uint8_t base64map[128] ICACHE_RODATA_ATTR = +{ + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255 +}; +//============================================================================= +bool ICACHE_FLASH_ATTR base64decode(const uint8 *in, int len, uint8_t *out, int *outlen) +{ +// uint8 *map = (uint8 *)UartDev.rcv_buff.pRcvMsgBuff; +// ets_memcpy(map, base64map, 128); + uint8 *map = base64map; + int g, t, x, y, z; + uint8_t c; + g = 3; + for (x = y = z = t = 0; x < len; x++) { + if ((c = map[in[x]&0x7F]) == 0xff) continue; + if (c == 254) { /* this is the end... */ + c = 0; + if (--g < 0) return false; + } + else if (g != 3) return false; /* only allow = at end */ + t = (t<<6) | c; + if (++y == 4) { + out[z++] = (uint8_t)((t>>16)&255); + if (g > 1) out[z++] = (uint8_t)((t>>8)&255); + if (g > 2) out[z++] = (uint8_t)(t&255); + y = t = 0; + } + /* check that we don't go past the output buffer */ + if (z > *outlen) return false; + } + if (y != 0) return false; + *outlen = z; + return true; +} +//============================================================================= +/* Table 6-bit-index-to-ASCII used for base64-encoding */ +const uint8_t base64_table[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/' +}; +// ld: PROVIDE ( base64_table = 0x3FFFD600 ); +//extern const uint8_t base64_table[]; +//============================================================================= +/** Base64 encoding */ +size_t ICACHE_FLASH_ATTR base64encode(char* target, size_t target_len, const char* source, size_t source_len) +{ + size_t i; + sint8 j; + size_t target_idx = 0; + size_t longer = 3 - (source_len % 3); + size_t source_len_b64 = source_len + longer; + size_t len = (((source_len_b64) * 4) / 3); + uint8 x = 5; + uint8 current = 0; + + if(target == NULL || target_len < len) return 0; + + for (i = 0; i < source_len_b64; i++) { + uint8 b = (i < source_len ? source[i] : 0); + for (j = 7; j >= 0; j--, x--) { + uint8 shift = ((b & (1 << j)) != 0) ? 1 : 0; + current |= shift << x; + if (x == 0) { + target[target_idx++] = base64_table[current]; + x = 6; + current = 0; + } + } + } + for (i = len - longer; i < len; i++) { + target[i] = '='; + } + return len; +} +/* +//============================================================================= +void ICACHE_FLASH_ATTR print_hex_dump(uint8 *buf, uint32 len, uint8 k) +{ + if(!system_get_os_print()) return; // if(*((uint8 *)(0x3FFE8000)) == 0) return; + uint32 ss[2]; + ss[0] = 0x78323025; // "%02x" + ss[1] = k; // ","...'\0' + uint8* ptr = buf; + while(len--) { + if(len == 0) ss[1] = 0; + ets_printf((uint8 *)&ss[0], *ptr++); + } +} +*/ +//============================================================================= +#define LowerCase(a) ((('A' <= a) && (a <= 'Z')) ? a + 32 : a) + +char* ICACHE_FLASH_ATTR word_to_lower_case(char* text) { + for(; *text ==' '; text++); + char* p = text; + for (; *p >= ' '; p++) { + *p = LowerCase(*p); + } + return text; +} +#if 0 +//============================================================================= +/* char UpperCase(char ch) { + return (('a' <= ch) && (ch <= 'z')) ? ch - 32 : ch; }*/ +#define UpperCase(a) ((('a' <= a) && (a <= 'z')) ? a - 32 : a) + +char* ICACHE_FLASH_ATTR str_to_upper_case(char* text) { + char* p = text; + for (; *p; ++p) { + *p = UpperCase(*p); + } + return text; +} +#endif + diff --git a/project/src/web/web_websocket.c b/project/src/web/web_websocket.c new file mode 100644 index 0000000..8af34e3 --- /dev/null +++ b/project/src/web/web_websocket.c @@ -0,0 +1,347 @@ +/****************************************************************************** + * FileName: web_websocket.c + * Description: websocket for web + * Author: pvvx + * 2016 +*******************************************************************************/ +#include "user_config.h" +#ifdef WEBSOCKET_ENA +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +//#include "bios.h" +//#include "osapi.h" +//#include "sdk/rom2ram.h" +#include "lwip/tcp.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "web_srv_int.h" +#include "web_utils.h" +#include "web_websocket.h" +#include "rtl8195a/rtl_libc.h" +#include "esp_comp.h" + +#if 0 +#undef DEBUGSOO +#define DEBUGSOO 4 +#endif + +#define copy_s4d1 rtl_memcpy + +#define mMIN(a, b) ((a 3 + os_printf("ws%utx[%u] error %d!\n", opcode, raw_len, err); +#endif + ((WEB_SRV_CONN *)ts_conn->linkd)->webflag |= SCB_DISCONNECT; + } + else { + if((opcode & WS_OPCODE_BITS) == WS_OPCODE_CLOSE) { + ((WEB_SRV_CONN *)ts_conn->linkd)->ws.flg |= WS_FLG_CLOSE; + } + } + return err; +} +//============================================================================= +// websock_tx_close_err() - вывод сообщения закрытия или ошибки +//============================================================================= +err_t ICACHE_FLASH_ATTR +websock_tx_close_err(TCP_SERV_CONN *ts_conn, uint32 err) +{ + uint8 uc[2]; + uc[1] = err; + uc[0] = err>>8; + return websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, uc, 2); +} +//============================================================================= +// websock_rx_data() прием данных +//============================================================================= +#define MAX_WS_DATA_BLK_SIZE (tcp_sndbuf(ts_conn->pcb)-8) // (TCP_MSS - 8) +//============================================================================= +bool ICACHE_FLASH_ATTR +websock_rx_data(TCP_SERV_CONN *ts_conn) +{ +// HTTP_CONN *CurHTTP; + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + if(web_conn == NULL) return false; + WS_FRSTAT *ws = &web_conn->ws; + uint16 len; + uint8 *pstr; + +#if DEBUGSOO > 3 + os_printf("ws_rx[%u]%u ", ts_conn->sizei, ts_conn->cntri); +#endif + if(ts_conn->sizei == 0) return true; // докачивать + tcpsrv_unrecved_win(ts_conn); + if((ws->flg & WS_FLG_CLOSE) != 0) { + // убить буфер ts_conn->pbufi, конец давно :) + web_feee_bufi(ts_conn); + SetSCB(SCB_DISCONNECT); + return false; + } + if(ts_conn->sizei > MAX_RX_BUF_SIZE) { +#if DEBUGSOO > 0 + os_printf("ws:rxbuf_full! "); +#endif + // убить буфер ts_conn->pbufi и ответить ошибкой WS_CLOSE_UNEXPECTED_ERROR + web_feee_bufi(ts_conn); + websock_tx_close_err(ts_conn, WS_CLOSE_MESSAGE_TOO_BIG); // WS_CLOSE_UNEXPECTED_ERROR); + SetSCB(SCB_DISCONNECT); + return false; + } + pstr = ts_conn->pbufi;// + ts_conn->cntri; + len = ts_conn->sizei;// - ts_conn->cntri; + while(ts_conn->cntri < ts_conn->sizei || (ws->flg & WS_FLG_FIN) != 0) { + pstr = ts_conn->pbufi;// + ts_conn->cntri; + len = ts_conn->sizei;// - ts_conn->cntri; + if((ws->flg & WS_FLG_FIN) != 0 // обработка + || ws->frame_len > ws->cur_len) { + ws->flg &= ~WS_FLG_FIN; + len = mMIN(ws->frame_len - ws->cur_len, mMIN(MAX_WS_DATA_BLK_SIZE, len)); + // размаскировать + if((ws->flg & WS_FLG_MASK) != 0) WebsocketMask(ws, pstr, len); +#if DEBUGSOO > 3 + os_printf("wsfr[%u]blk[%u]at:%u ", ws->frame_len, len, ws->cur_len); +#endif + switch(ws->status) { + case sw_frs_binary: +#if DEBUGSOO > 1 + os_printf("ws:bin "); +#endif + if(ws->frame_len != 0) { + // пока просто эхо + uint32 opcode = WS_OPCODE_BINARY; + if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE; + if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN; + if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) { + return false; // не докачивать, ошибка или закрытие + } + } + ws->cur_len += len; + ts_conn->cntri += len; + break; + case sw_frs_text: +#if DEBUGSOO > 1 + os_printf("ws:txt "); +#if DEBUGSOO > 2 + if(ws->frame_len != 0) { + uint8 tt = pstr[len]; + pstr[len] = 0; + os_printf("'%s' ", pstr); + pstr[len] = tt; + } +#endif +#endif + if(ws->frame_len == ws->cur_len + len && ws->frame_len != 0) { // полное соо + web_conn->msgbufsize = tcp_sndbuf(ts_conn->pcb); // сколько можем выввести сейчас? + if (web_conn->msgbufsize < MIN_SEND_SIZE) { +#if DEBUGSOO > 0 + os_printf("ws:sndbuf=%u! ", web_conn->msgbufsize); +#endif + websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR); + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + return false; + } + if(ws->frame_len == (sizeof(txt_wsping)-1) && rom_xstrcmp(pstr, txt_wsping) != 0){ + copy_s4d1(pstr, (void *)txt_wspong, sizeof(txt_wspong) - 1); + if(websock_tx_frame(ts_conn, WS_OPCODE_TEXT | WS_FRAGMENT_FIN, pstr, sizeof(txt_wspong) - 1) != ERR_OK) { + return false; // не докачивать, ошибка или закрытие + } + } + else { + web_conn->msgbuf = (uint8 *) os_malloc(web_conn->msgbufsize); + if (web_conn->msgbuf == NULL) { +#if DEBUGSOO > 0 + os_printf("ws:mem!\n"); +#endif + websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR); + SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + return false; + }; + web_conn->msgbuflen = 0; + uint32 opcode; + if(CheckSCB(SCB_RETRYCB)) { // повторный callback? да + if(web_conn->func_web_cb != NULL) web_conn->func_web_cb(ts_conn); + if(!CheckSCB(SCB_RETRYCB)) { + ClrSCB(SCB_FCLOSE | SCB_DISCONNECT); + opcode = WS_OPCODE_CONTINUE | WS_FRAGMENT_FIN; + } + else opcode = WS_OPCODE_CONTINUE; + } + else { + pstr[len] = '\0'; + uint8 *vstr = os_strchr(pstr, '='); + if(vstr != NULL) { + *vstr++ = '\0'; + web_int_vars(ts_conn, pstr, vstr); + } + else { + web_conn->msgbuf[0] = 0; + web_int_callback(ts_conn, pstr); + } + if(CheckSCB(SCB_RETRYCB)) opcode = WS_OPCODE_TEXT; + else { + ClrSCB(SCB_FCLOSE | SCB_DISCONNECT); + opcode = WS_OPCODE_TEXT | WS_FRAGMENT_FIN; + } + } + if(web_conn->msgbuflen != 0) { + if(websock_tx_frame(ts_conn, opcode, web_conn->msgbuf, web_conn->msgbuflen) != ERR_OK) { + os_free(web_conn->msgbuf); + web_conn->msgbuf = NULL; + return false; // не докачивать, ошибка или закрытие + } + } + os_free(web_conn->msgbuf); + web_conn->msgbuf = NULL; + if(CheckSCB(SCB_RETRYCB)) return false; + } + } +/* + if(0) { + uint32 opcode = WS_OPCODE_TEXT; + if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE; + if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN; + if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) { + return false; // не докачивать, ошибка или закрытие + } + } +*/ + ws->cur_len += len; + ts_conn->cntri += len; + return true; // докачивать +// break; +// break; + case sw_frs_ping: +#if DEBUGSOO > 1 + os_printf("ws:ping "); +#endif + { + uint32 opcode = WS_OPCODE_PONG; + if(ws->cur_len != 0) opcode = WS_OPCODE_CONTINUE; + if(ws->frame_len == ws->cur_len + len) opcode |= WS_FRAGMENT_FIN; + if(websock_tx_frame(ts_conn, opcode, pstr, len) != ERR_OK) { + return false; // не докачивать, ошибка или закрытие + } + } + ws->cur_len += len; + ts_conn->cntri += len; + return true; // докачивать +// break; + case sw_frs_pong: +#if DEBUGSOO > 1 + os_printf("ws:pong "); +#endif + ws->cur_len += len; + ts_conn->cntri += len; + break; +// return true; + case sw_frs_close: +#if DEBUGSOO > 1 + os_printf("ws:close "); +#endif +// if((ws->flg & WS_FLG_CLOSE) == 0) { + { + if(len >= 2) { + uint32 close_code = (pstr[0]<<8) | pstr[1]; +#if DEBUGSOO > 1 + os_printf("code:%d ", close_code); +#endif + if(close_code == WS_CLOSE_NORMAL) websock_tx_close_err(ts_conn, WS_CLOSE_NORMAL); + // else websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, NULL, 0); + } + else + { + websock_tx_close_err(ts_conn, WS_CLOSE_NORMAL); + // websock_tx_frame(ts_conn, WS_OPCODE_CLOSE | WS_FRAGMENT_FIN, NULL, 0); + } + } + ts_conn->flag.pcb_time_wait_free = 1; + SetSCB(SCB_DISCONNECT); +// ts_conn->cntri = ts_conn->sizei; +/* ws->cur_len += len; + ts_conn->cntri += len; */ + return false; + default: +#if DEBUGSOO > 0 + os_printf("ws:f?! "); +#endif + websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR); + SetSCB(SCB_DISCONNECT); + // ts_conn->cntri = ts_conn->sizei; + return false; + } + } + else + if(ws->cur_len >= ws->frame_len) { // прием и разбор нового фрейма + if((ws->flg & WS_FLG_FIN) != 0) { // обработка +#if DEBUGSOO > 3 + os_printf("ws_rx:fin=%u ", ws->cur_len); +#endif + } + else { + uint32 ret = WebsocketHead(ws, pstr, len); + if(ret >= WS_CLOSE_NORMAL) { // error или close + +#if DEBUGSOO > 0 + os_printf("ws:txerr=%u ", ret); +#endif + websock_tx_close_err(ts_conn, ret); +// ts_conn->cntri = ts_conn->sizei; // убить буфер ts_conn->pbufi + return false; // error + } + else if(ret == 0) { +#if DEBUGSOO > 3 + os_printf("ws_rx... "); +#endif + return true; // докачивать + } + ts_conn->cntri += ws->head_len; // вычесть заголовок +/* + switch(ws->status) { + case sw_frs_binary: + break; + case sw_frs_text: + if(ws->frame_len > MAX_RX_BUF_SIZE) { + websock_tx_close_err(ts_conn, WS_CLOSE_MESSAGE_TOO_BIG); + return false; + } + break; + } +*/ + } + } +#if DEBUGSOO > 3 + os_printf("trim%u-%u ", ts_conn->sizei, ts_conn->sizei - ts_conn->cntri ); +#endif + if(!web_trim_bufi(ts_conn, &ts_conn->pbufi[ts_conn->cntri], ts_conn->sizei - ts_conn->cntri)) { +#if DEBUGSOO > 0 + os_printf("ws:trim_err! "); +#endif + // убить буфер ts_conn->pbufi и ответить ошибкой WS_CLOSE_UNEXPECTED_ERROR + websock_tx_close_err(ts_conn, WS_CLOSE_UNEXPECTED_ERROR); + SetSCB(SCB_DISCONNECT); +// ts_conn->cntri = ts_conn->sizei; + return false; + }; + } + return false; // не докачивать, ошибка или закрытие +} +//============================================================================= +//============================================================================= +#endif // WEBSOCKET_ENA + + diff --git a/project/src/web/websock.c b/project/src/web/websock.c new file mode 100644 index 0000000..d9e2efc --- /dev/null +++ b/project/src/web/websock.c @@ -0,0 +1,245 @@ +/****************************************************************************** + * FileName: websock.c + * Description: websocket for web ESP8266 + * Author: PV` + * (c) PV` 2016 +*******************************************************************************/ +#include "user_config.h" +#ifdef WEBSOCKET_ENA +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "tcpsrv/tcp_srv_conn.h" +#include "web_utils.h" // base64encode() +#include "web_srv.h" +//#include "phy/phy.h" +#include "device_lock.h" +#include "lwip/tcp.h" +#include "websock.h" +#include "rtl8195a/rtl_libc.h" +#include "esp_comp.h" +#include "hal_crypto.h" + +// HTTP/1.1 101 Web Socket Protocol Handshake\r\n +const uint8 WebSocketHTTPOkKey[] ICACHE_RODATA_ATTR = "HTTP/1.1 101 Switching Protocols\r\nAccess-Control-Allow-Origin: *\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\n\r\n"; +const uint8 WebSocketAddKey[] ICACHE_RODATA_ATTR = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; +const uint8 *HTTPUpgrade = "Upgrade:"; +const uint8 *HTTPwebsocket = "websocket"; +const uint8 *HTTPSecWebSocketKey = "Sec-WebSocket-Key:"; + +//============================================================================= +// WebSocketAcceptKey() +// 1) взять строковое значение из заголовка Sec-WebSocket-Key и объединить со +// строкой 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 +// 2) вычислить бинарный хеш SHA-1 (бинарная строка из 20 символов) от полученной +// в первом пункте строки +// 3) закодировать хеш в Base64 +// skey[24+36]:'dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11' +// cha:'b37a4f2cc0624f1690f64606cf385945b2bec4ea' +// key[28]:'s3pPLMBiTxaQ9kYGzzhZRbK+xOo=' +//============================================================================= +uint8 buff[maxsizeWebSocketKey + sizeWebSocketAddKey]; // [68] +bool ICACHE_FLASH_ATTR WebSocketAcceptKey(uint8* dkey, uint8* skey) +{ + int len = 0; + bool ret = false; + uint8 keybuf[CRYPTO_SHA1_DIGEST_LENGTH]; + uint8 * buff = os_malloc(maxsizeWebSocketKey + sizeWebSocketAddKey); + if(buff) { + while(skey[len] >= '+' && len < maxsizeWebSocketKey) { + buff[len] = skey[len]; + len++; + }; + if(len > minsizeWebSocketKey) { + rtl_memcpy(&buff[len], WebSocketAddKey, sizeWebSocketAddKey+1); + device_mutex_lock(RT_DEV_LOCK_CRYPTO); + rtl_crypto_sha1(buff, len + sizeWebSocketAddKey, keybuf); + device_mutex_unlock(RT_DEV_LOCK_CRYPTO); +// rtl_cryptoEngine_info(); + len = base64encode(dkey, FileNameSize, keybuf, CRYPTO_SHA1_DIGEST_LENGTH); +#if DEBUGSOO > 2 + os_printf("\ncha:'"); + print_hex_dump(keybuf, CRYPTO_SHA1_DIGEST_LENGTH, '\0'); + os_printf("'\n"); + os_printf("key[%u]:'%s'\n", len, dkey); +#endif + ret = true; + } + os_free(buff); + } + return ret; + +} +//============================================================================= +// websock_mask() размаскирование блока +//============================================================================= +void ICACHE_FLASH_ATTR +WebsocketMask(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len) +{ + uint32 i, x = ws->cur_len; +#if DEBUGSOO > 3 + os_printf("mask[%u]%u ", raw_len, x); +#endif + for (i = 0; i < raw_len; i++) { + raw_data[i] ^= ws->mask.uc[x++ & 3]; + } +} +//============================================================================= +// websock_head() разбор заголовка +//============================================================================= +uint32 ICACHE_FLASH_ATTR +WebsocketHead(WS_FRSTAT *ws, uint8 *raw_data, uint32 raw_len) +{ + // определить размер заголовка фрейма + uint32 head_len = 2; + if(raw_len < head_len) return 0; // докачивать + uint32 data_len = raw_data[1] & WS_SIZE1_BITS; + if(data_len == 127) head_len = 10; + else if(data_len == 126) head_len = 4; + if(raw_data[1] & WS_MASK_FLG) head_len += 4; + if(raw_len < head_len) return 0; // докачивать + ws->head_len = head_len; + ws->cur_len = 0; + ws->flg = 0; + data_len = raw_data[1] & WS_SIZE1_BITS; + if(data_len >= 126) { + if(data_len == 127) { + uint32 i; + for(i = 3; i < 6; i++) { + if(raw_data[i] != 0) { + ws->status = sw_frs_close; + ws->frame_len = 0; + return WS_CLOSE_MESSAGE_TOO_BIG; + } + } + data_len = (raw_data[6] << 24) | (raw_data[7] << 16) | (raw_data[8] << 8) | raw_data[9]; + } + else { + data_len = (raw_data[2] << 8) | raw_data[3]; + } + } + if(raw_data[1] & WS_MASK_FLG) { + ws->flg |= WS_FLG_MASK; + ws->mask.uc[0] = raw_data[head_len-4]; + ws->mask.uc[1] = raw_data[head_len-3]; + ws->mask.uc[2] = raw_data[head_len-2]; + ws->mask.uc[3] = raw_data[head_len-1]; + } +// else ws->mask = 0; + uint8 opcode = raw_data[0] & WS_OPCODE_BITS; + switch(opcode) { + case WS_OPCODE_PING: // эхо - дублировать прием + raw_data[0] &= ~WS_FRAGMENT_FIN; + raw_data[0] |= WS_OPCODE_PONG; + ws->status = sw_frs_pong; + ws->frame_len = data_len; + break; + case WS_OPCODE_PONG: // эхо - дублировать прием + ws->status = sw_frs_ping; + ws->frame_len = data_len; + break; + case WS_OPCODE_CONTINUE: // продолжить + if(ws->status == sw_frs_pong) { + ws->frame_len = data_len; + break; + } + else ws->frame_len += data_len; + break; + case WS_OPCODE_CLOSE: // + ws->status = sw_frs_close; + ws->frame_len = data_len; + break; + case WS_OPCODE_TEXT: + ws->status = sw_frs_text; + ws->frame_len = data_len; + break; + case WS_OPCODE_BINARY: + ws->status = sw_frs_binary; + ws->frame_len = data_len; + break; + default: + ws->status = sw_frs_close; + ws->frame_len = 0; + return WS_CLOSE_WRONG_TYPE; + } +// uint32 len = mMIN(raw_len - head_len, data_len); +// if((ws->flg & WS_FLG_MASK) != 0) websock_mask(ws, &raw_data[head_len], mMIN(raw_len - head_len, len)); +// ws->cur_len += len; + if((raw_data[0] & WS_FRAGMENT_FIN) != 0) { // конец - данные на обработку + ws->flg |= WS_FLG_FIN; + } +#if DEBUGSOO > 1 + os_printf("ws#%02xrx[%u] ", raw_data[0], data_len); +#endif + return 1; +/* + if(data_len + head_len <= raw_len) { // весь пакет уже в буфере? + return 1; + } + return 0; // докачивать */ +} +//============================================================================= +// websock_tx_frame() - передача фрейма +//============================================================================= +err_t ICACHE_FLASH_ATTR +WebsocketTxFrame(TCP_SERV_CONN *ts_conn, uint32 opcode, uint8 *raw_data, uint32 raw_len) +{ + union { + uint8 uc[8]; + uint16 uw[4]; + uint32 ud[2]; + }head; + union { + uint8 uc[4]; + uint16 uw[2]; + uint32 ud; + }mask; + if(raw_data == NULL) raw_len = 0; + head.ud[0] = opcode; + uint32 head_len; + if(raw_len > 126) { + head.uc[1] = 126; + head.uc[2] = raw_len>>8; + head.uc[3] = raw_len; + head_len = 4; + } + else { + head.uc[1] = raw_len; + head_len = 2; + }; + if(opcode & (WS_MASK_FLG << 8)) { + mask.ud ^= rand(); + head.uc[1] |= WS_MASK_FLG; + head.uc[head_len] = mask.uc[0]; + head.uc[head_len+1] = mask.uc[1]; + head.uc[head_len+2] = mask.uc[2]; + head.uc[head_len+3] = mask.uc[3]; + head_len += 4; + } + uint32 len = tcp_sndbuf(ts_conn->pcb); + err_t err = 1; // ERR_BUF; + if(len >= raw_len + head_len) { +#if DEBUGSOO > 1 + os_printf("ws#%02xtx[%u] ", head.uc[0], raw_len); +#endif + ts_conn->flag.nagle_disabled = 0; + tcp_nagle_disable(ts_conn->pcb); + err = tcpsrv_int_sent_data(ts_conn, head.uc, head_len); + ts_conn->flag.nagle_disabled = 1; + if(err == ERR_OK && raw_len != 0) { + if(opcode & (WS_MASK_FLG << 8)) { + uint32 i; + for (i = 0; i < raw_len; i++) { + raw_data[i] ^= mask.uc[i & 3]; + } + } + err = tcpsrv_int_sent_data(ts_conn, raw_data, raw_len); + } + } + return err; +} + + +#endif // WEBSOCKET_ENA + diff --git a/project/src/webfs/webfs.c b/project/src/webfs/webfs.c new file mode 100644 index 0000000..bec3a38 --- /dev/null +++ b/project/src/webfs/webfs.c @@ -0,0 +1,483 @@ +/********************************************************************* + * WEBFS.c + * RTL871x Flash WEB File System v1.0 + ********************************************************************/ +#include "autoconf.h" +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include +#include +#include "device_lock.h" +#include "flash_api.h" +//#include "flash_eep.h" + +#include "webfs/webfs.h" +#include "rtl8195a/rtl_libc.h" +#include "esp_comp.h" + + +#define WEBFS_CODE_ATTR +#define WEBFS_DATA_ATTR + +#define web_mutex_lock() device_mutex_lock(RT_DEV_LOCK_FLASH) +#define web_mutex_unlock() device_mutex_unlock(RT_DEV_LOCK_FLASH) + +// Supports long file names to 64 characters +#define MAX_FILE_NAME_LEN 64 // VarNameSize +uint32 disk_base_addr WEBFS_DATA_ATTR; +#define WEBFS_HEAD_ADDR disk_base_addr +/* + * + * Structure: + * + * [F][W][E][B][uint8 Ver Hi][uint8 Ver Lo] // заголовок диска + * [uint16 Number of Files] // кол-во файлов на диске + * [Name Hash 0]...[Name Hash N] // uint16 типа хеш на каждое имя файла + * [File Record 0]...[File Record N] // uint32 указатели на адреса структур файлов, относительно начала диска + * + * File Record Structure: + * [uint32 Len] размер файла с заголовком + * [uint16 HeadLen] длина заголовка, включая размер, флаг, имя (адрес данных - адрес позиции len) + * [uint16 Flags] бит 0 =1 - файл сжат GZIP, бит 1 = 1 - парсится - имеет динамические переменные + * [File Name, 0] Имя файла с "СИ" терминатором + * [File Data] данные файла + * + * Name hash (2 uint8s) is calculated as follows: + * hash = 0 + * for each(uint8 in name) + * hash += uint8 + * hash <<= 1 + * + * Technically this means the hash only includes the + * final 15 characters of a name. + * + * String FileNmae Structure (1 to 64 uint8s): + * ["path/to/file.ext"][0x00] + * + * + * Current version is 1.0 + */ +// Lock WEBFS access during the upgrade +volatile bool isWEBFSLocked WEBFS_DATA_ATTR; +// Track the WEBFS File Handles +// WEBFSStubs[0] is reserved for internal use (FAT access) +WEBFS_STUB WEBFSStubs[MAX_WEBFS_OPENFILES+1] WEBFS_DATA_ATTR; // + HANDLE = 0 +// FAT record cache +WEBFS_FAT_RECORD fatCache WEBFS_DATA_ATTR; +// ID of currently loaded fatCache +static uint32 fatCacheID WEBFS_DATA_ATTR; +// Number of files in this WEBFS image +uint16 numFiles WEBFS_DATA_ATTR; + +LOCAL void GetFATRecord(uint16 fatID); +LOCAL void WEBFS_Update(void); + +/***************************************************************************** + Function: + void WEBFSInit(void) + Description: + Web Disk Init + *****************************************************************************/ +void WEBFS_CODE_ATTR WEBFSInit(void) +{ + disk_base_addr = WEBFS_base_addr(); + os_memset((char *) &WEBFSStubs, 0xff, sizeof(WEBFSStubs)); + // Validate the image and load numFiles + WEBFS_Update(); +#if DEBUGSOO > 0 + os_printf("\nDisk init: %d files, addr = %p\n", numFiles, disk_base_addr); +#endif + // тут надо расчет контрольки тела диска или другой контроль... + if(numFiles == 0) isWEBFSLocked = true; + else isWEBFSLocked = false; +} +/***************************************************************************** + Function: + WEBFS_HANDLE WEBFSOpen(uint8* cFile) + + Description: + Opens a file in the WEBFS2 file system. + + Precondition: + None + + Parameters: + cFile - a null terminated file name to open + + Returns: + An WEBFS_HANDLE to the opened file if found, or WEBFS_INVALID_HANDLE + if the file could not be found or no free handles exist. + ***************************************************************************/ +WEBFS_HANDLE WEBFS_CODE_ATTR WEBFSOpen(uint8* cFile) +{ + WEBFS_HANDLE hWEBFS; + uint16 nameHash; + int i, len = 0; + uint16 hashCache[16]; + uint8 bufname[MAX_FILE_NAME_LEN]; + uint8 *ptr; + + // Make sure WEBFS is unlocked and we got a filename + if(*cFile == '\0' || isWEBFSLocked == true) + return WEBFS_INVALID_HANDLE; + + // Calculate the name hash to speed up searching + for(nameHash = 0, ptr = cFile; *ptr != '\0'; ptr++) + { + nameHash += *ptr; + nameHash <<= 1; + len++; + } + // Find a free file handle to use + for(hWEBFS = 1; hWEBFS <= MAX_WEBFS_OPENFILES; hWEBFS++) + if(WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) break; + if(hWEBFS == MAX_WEBFS_OPENFILES) + return WEBFS_INVALID_HANDLE; + // Read in hashes, and check remainder on a match. Store 8 in cache for performance + for(i = 0; i < numFiles; i++) { + // For new block of 8, read in data + if((i & 0x0F) == 0) { + WEBFSStubs[0].addr = 12 + i*2; + WEBFSStubs[0].bytesRem = 32; + WEBFSGetArray(0, (uint8*)hashCache, 32); + } + // If the hash matches, compare the full filename + if(hashCache[i&0x0F] == nameHash) + { + GetFATRecord(i); + // filename comparison + WEBFSStubs[0].addr = fatCache.string; + WEBFSStubs[0].bytesRem = MAX_FILE_NAME_LEN; + WEBFSGetArray(0, bufname, MAX_FILE_NAME_LEN); + if(os_strncmp(cFile, bufname, len) == 0) { // Filename matches, so return true + WEBFSStubs[hWEBFS].addr = fatCache.data; + WEBFSStubs[hWEBFS].bytesRem = fatCache.len; + WEBFSStubs[hWEBFS].fatID = i; + return hWEBFS; + } + } + } + // No file name matched, so return nothing + return WEBFS_INVALID_HANDLE; +} +/***************************************************************************** + Function: void WEBFSClose(WEBFS_HANDLE hWEBFS) + Summary: Closes a file. + Returns: None + ***************************************************************************/ +void WEBFS_CODE_ATTR WEBFSClose(WEBFS_HANDLE hWEBFS) +{ + if(hWEBFS != 0 && hWEBFS <= MAX_WEBFS_OPENFILES) + WEBFSStubs[hWEBFS].addr = WEBFS_INVALID; +} +/***************************************************************************** + Function: uint16 WEBFSGetArray(WEBFS_HANDLE hWEBFS, uint8* cData, uint16 wLen) + Description: Reads a series of uint8s from a file. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: + hWEBFS - the file handle from which to read + cData - where to store the uint8s that were read + wLen - how many uint8s to read + Returns: + The number of uint8s successfully read. If this is less than wLen, + an EOF occurred while attempting to read. + ***************************************************************************/ +uint16 WEBFS_CODE_ATTR WEBFSGetArray(WEBFS_HANDLE hWEBFS, uint8* cData, uint16 wLen) +{ + // Make sure we're reading a valid address + if(hWEBFS > MAX_WEBFS_OPENFILES) return 0; + + // Determine how many we can actually read + if(wLen > WEBFSStubs[hWEBFS].bytesRem) wLen = WEBFSStubs[hWEBFS].bytesRem; + // Make sure we're reading a valid address + if(WEBFSStubs[hWEBFS].addr == WEBFS_INVALID || wLen == 0) return 0; + + if(cData != NULL) { + + // Read the data + web_mutex_lock(); +// if(wLen < 16) + flash_stream_read(&flashobj, WEBFSStubs[hWEBFS].addr + WEBFS_HEAD_ADDR, wLen, cData); +// else flash_burst_read(&flashobj, WEBFSStubs[hWEBFS].addr + WEBFS_HEAD_ADDR, wLen, cData); + web_mutex_unlock(); + +// if(spi_flash_read(WEBFSStubs[hWEBFS].addr+WEBFS_HEAD_ADDR, cData, wLen) != SPI_FLASH_RESULT_OK) +// return 0; + }; + WEBFSStubs[hWEBFS].addr += wLen; + WEBFSStubs[hWEBFS].bytesRem -= wLen; + return wLen; +} +/***************************************************************************** + Function: + bool WEBFSSeek(WEBFS_HANDLE hWEBFS, uint32 dwOffset, WEBFS_SEEK_MODE tMode) + Description: Moves the current read pointer to a new location. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: + hWEBFS - the file handle to seek with + dwOffset - offset from the specified position in the specified direction + tMode - one of the WEBFS_SEEK_MODE constants + Returns: + true - the seek was successful + false - either the new location or the handle itself was invalid + ***************************************************************************/ +bool WEBFS_CODE_ATTR WEBFSSeek(WEBFS_HANDLE hWEBFS, uint32 dwOffset, WEBFS_SEEK_MODE tMode) +{ + uint32 temp; + + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return false; + + switch(tMode) + { + // Seek offset uint8s from start + case WEBFS_SEEK_START: + temp = WEBFSGetSize(hWEBFS); + if(dwOffset > temp) + return false; + + WEBFSStubs[hWEBFS].addr = WEBFSGetStartAddr(hWEBFS) + dwOffset; + WEBFSStubs[hWEBFS].bytesRem = temp - dwOffset; + return true; + + // Seek forwards offset uint8s + case WEBFS_SEEK_FORWARD: + if(dwOffset > WEBFSStubs[hWEBFS].bytesRem) + return false; + + WEBFSStubs[hWEBFS].addr += dwOffset; + WEBFSStubs[hWEBFS].bytesRem -= dwOffset; + return true; + + // Seek backwards offset uint8s + case WEBFS_SEEK_REWIND: + temp = WEBFSGetStartAddr(hWEBFS); + if(WEBFSStubs[hWEBFS].addr < temp + dwOffset) + return false; + + WEBFSStubs[hWEBFS].addr -= dwOffset; + WEBFSStubs[hWEBFS].bytesRem += dwOffset; + return true; + + // Seek so that offset uint8s remain in file + case WEBFS_SEEK_END: + temp = WEBFSGetSize(hWEBFS); + if(dwOffset > temp) + return false; + + WEBFSStubs[hWEBFS].addr = WEBFSGetEndAddr(hWEBFS) - dwOffset; + WEBFSStubs[hWEBFS].bytesRem = dwOffset; + return true; + + default: + return false; + } +} +/***************************************************************************** + Function: static void GetFATRecord(uint16 fatID) + Description: Loads the FAT record for a specified handle. + Precondition: None + Parameters: fatID - the ID of the file whose FAT is to be loaded + Returns: None + Remarks: The FAT record will be stored in fatCache. + ***************************************************************************/ +LOCAL void WEBFS_CODE_ATTR GetFATRecord(uint16 fatID) +{ + WEBFS_FHEADER fhead; + if(fatID == fatCacheID || fatID >= numFiles) return; + // Read the FAT record to the cache + WEBFSStubs[0].bytesRem = sizeof(fhead) + 4; + WEBFSStubs[0].addr = 12 + numFiles*2 + fatID *4; + WEBFSGetArray(0, (uint8 *)&fatCache.data, 4); + WEBFSStubs[0].addr = fatCache.data; + WEBFSGetArray(0, (uint8 *)&fhead, sizeof(fhead)); + fatCache.len = fhead.blksize - fhead.headlen; + fatCache.string = fatCache.data + 8; + fatCache.flags = fhead.flags; + fatCache.data = fatCache.data + fhead.headlen; + fatCacheID = fatID; +} +/***************************************************************************** + Function: uint16 WEBFSGetFlags(WEBFS_HANDLE hWEBFS) + Description: Reads a file's flags. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle from which to read the metadata + Returns: The flags that were associated with the file + ***************************************************************************/ +uint16 WEBFS_CODE_ATTR WEBFSGetFlags(WEBFS_HANDLE hWEBFS) +{ + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return 0; + + //move to the point for reading + GetFATRecord(WEBFSStubs[hWEBFS].fatID); + return fatCache.flags; +} +/***************************************************************************** + Function: uint32 WEBFSGetSize(WEBFS_HANDLE hWEBFS) + Description: Reads the size of a file. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle from which to read the metadata + Returns: The size that was read as a uint32 + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFSGetSize(WEBFS_HANDLE hWEBFS) +{ + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return 0; + + // Move to the point for reading + GetFATRecord(WEBFSStubs[hWEBFS].fatID); + return fatCache.len; +} +/***************************************************************************** + Function: uint32 WEBFSGetBytesRem(WEBFS_HANDLE hWEBFS) + Description: Determines how many uint8s remain to be read. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle from which to read the metadata + Returns: The number of uint8s remaining in the file as a uint32 + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFSGetBytesRem(WEBFS_HANDLE hWEBFS) +{ + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return 0; + return WEBFSStubs[hWEBFS].bytesRem; +} +/***************************************************************************** + Function: WEBFS_PTR WEBFSGetStartAddr(WEBFS_HANDLE hWEBFS) + Description: Reads the starting address of a file. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle from which to read the metadata + Returns: The starting address of the file in the WEBFS image + ***************************************************************************/ +WEBFS_PTR WEBFS_CODE_ATTR WEBFSGetStartAddr(WEBFS_HANDLE hWEBFS) +{ + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return 0; + // Move to the point for reading + GetFATRecord(WEBFSStubs[hWEBFS].fatID); + return fatCache.data; +} +/***************************************************************************** + Function: WEBFS_PTR WEBFSGetEndAddr(WEBFS_HANDLE hWEBFS) + Description: Determines the ending address of a file. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle from which to read the metadata + Returns: The address just after the file ends (start address of next file) + ***************************************************************************/ +WEBFS_PTR WEBFS_CODE_ATTR WEBFSGetEndAddr(WEBFS_HANDLE hWEBFS) +{ + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return WEBFS_INVALID; + // Move to the point for reading + GetFATRecord(WEBFSStubs[hWEBFS].fatID); + return fatCache.data + fatCache.len; +} +/***************************************************************************** + Function: bool WEBFSGetFilename(WEBFS_HANDLE hWEBFS, uint8* cName, uint16 wLen) + Description: Reads the file name of a file that is already open. + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: + hWEBFS - the file handle from which to determine the file name + cName - where to store the name of the file + wLen - the maximum length of data to store in cName + Returns: + true - the file name was successfully located + false - the file handle provided is not currently open + ***************************************************************************/ +bool WEBFS_CODE_ATTR WEBFSGetFilename(WEBFS_HANDLE hWEBFS, uint8* cName, uint16 wLen) +{ + uint32 addr; + + // Make sure a valid file is open + if(hWEBFS > MAX_WEBFS_OPENFILES || WEBFSStubs[hWEBFS].addr == WEBFS_INVALID) + return false; + + // Move to the point for reading + GetFATRecord(WEBFSStubs[hWEBFS].fatID); + addr = fatCache.string; + WEBFSStubs[0].addr = addr; + WEBFSStubs[0].bytesRem = 255; + + // Read the value and return + WEBFSGetArray(0, cName, wLen); + return true; +} +/***************************************************************************** + Function: uint32 WEBFSGetPosition(WEBFS_HANDLE hWEBFS) + Description: Determines the current position in the file + Precondition: The file handle referenced by hWEBFS is already open. + Parameters: hWEBFS - the file handle for which to determine position + Returns: The position in the file as a uint32 (or WEBFS_PTR) + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFSGetPosition(WEBFS_HANDLE hWEBFS) +{ + return WEBFSStubs[hWEBFS].addr - WEBFSGetStartAddr(hWEBFS); +} +/***************************************************************************** + Function: void WEBFS_Update(void) + Summary: Validates the WEBFS Image + Description: Verifies that the WEBFS image is valid, and reads the number of + available files from the image header. This function is called on + boot, and again after any image is written. + Parameters: None + Returns: None + ***************************************************************************/ +LOCAL void WEBFS_CODE_ATTR WEBFS_Update(void) +{ + // Update numFiles + WEBFS_DISK_HEADER dhead; + WEBFSStubs[0].addr = 0; + WEBFSStubs[0].bytesRem = sizeof(dhead); + WEBFSGetArray(0, (uint8*)&dhead, sizeof(dhead)); + if(dhead.id == WEBFS_DISK_ID && dhead.ver == WEBFS_DISK_VER) { //"FWEB"1,0 ? + numFiles = dhead.numFiles; + } + else numFiles = 0; + fatCacheID = WEBFS_INVALID_FAT; +} +/**************************************************************************** + * WEBFS_max_size() + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFS_max_size(void) +{ +/* + uint32 size = spi_flash_real_size(); + if(size > WEBFS_DISK_ADDR_BIGFLASH) size -= WEBFS_DISK_ADDR_BIGFLASH; + else { + size = WEBFS_DISK_ADDR_MINFLASH_END - WEBFS_DISK_ADDR_MINFLASH_START; + } + return size; +*/ + return spi_flash_real_size() - WEBFS_DISK_FADDR; +} +/**************************************************************************** + * WEBFS_size() + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFS_curent_size(void) +{ + uint32 size = 0; + web_mutex_lock(); + if(numFiles) flash_read_word(&flashobj, disk_base_addr + 8, &size); + web_mutex_unlock(); + return size; +} +/**************************************************************************** + * WEBFS_size() + ***************************************************************************/ +uint32 WEBFS_CODE_ATTR WEBFS_base_addr(void) +{ +/* + uint32 webfs_faddr; + if(flash_get_size(&flashobj) <= WEBFS_DISK_ADDR_BIGFLASH) webfs_faddr = WEBFS_DISK_ADDR_MINFLASH_START; + else webfs_faddr = WEBFS_DISK_ADDR_BIGFLASH; + return webfs_faddr; +*/ + return WEBFS_DISK_FADDR; +} diff --git a/project_set.xml b/project_set.xml new file mode 100644 index 0000000..665f2d5 --- /dev/null +++ b/project_set.xml @@ -0,0 +1,177 @@ + + +
+ + + + +/${ProjName}/project/inc +/${ProjName}/project/inc/rtl8195a +/${ProjName}/project/src/include +/${ProjSDK}/component/soc/realtek/common/bsp +/${ProjSDK}/component/os/freertos +/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include +/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3 +/${ProjSDK}/component/os/os_dep/include +/${ProjSDK}/component/soc/realtek/8195a/misc/driver +/${ProjSDK}/component/common/api/network/include +/${ProjSDK}/component/common/api +/${ProjSDK}/component/common/api/platform +/${ProjSDK}/component/common/api/wifi +/${ProjSDK}/component/common/api/wifi/rtw_wpa_supplicant/src +/${ProjSDK}/component/common/application +/${ProjSDK}/component/common/application/iotdemokit +/${ProjSDK}/component/common/application/google +/${ProjSDK}/component/common/media/framework +/${ProjSDK}/component/common/example +/${ProjSDK}/component/common/example/wlan_fast_connect +/${ProjSDK}/component/common/mbed/api +/${ProjSDK}/component/common/mbed/hal +/${ProjSDK}/component/common/mbed/hal_ext +/${ProjSDK}/component/common/mbed/targets/hal/rtl8195a +/${ProjSDK}/component/common/network +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include/lwip +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4 +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/port/realtek +/${ProjSDK}/component/common/test +/${ProjSDK}/component/soc/realtek/8195a/cmsis +/${ProjSDK}/component/soc/realtek/8195a/cmsis/device +/${ProjSDK}/component/soc/realtek/8195a/fwlib +/${ProjSDK}/component/soc/realtek/8195a/fwlib/rtl8195a +/${ProjSDK}/component/soc/realtek/8195a/misc/rtl_std_lib/include +/${ProjSDK}/component/common/drivers/wlan/realtek/include +/${ProjSDK}/component/common/drivers/wlan/realtek/src/osdep +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hci +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hal +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hal/OUTSRC +/${ProjSDK}/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom +/${ProjSDK}/component/common/network/ssl/polarssl-1.3.8/include +/${ProjSDK}/component/common/network/ssl/ssl_ram_map/rom +/${ProjSDK}/component/common/utilities +/${ProjSDK}/component/common/application/apple/WACServer/External/Curve25519 +/${ProjSDK}/component/common/application/apple/WACServer/External/GladmanAES +/${ProjSDK}/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include +/${ProjSDK}/component/common/media/codec +/${ProjSDK}/component/common/drivers/usb_class/host/uvc/inc +/${ProjSDK}/component/common/drivers/usb_class/device +/${ProjSDK}/component/common/drivers/usb_class/device/class +/${ProjSDK}/component/common/file_system/fatfs +/${ProjSDK}/component/common/file_system/fatfs/r0.10c/include +/${ProjSDK}/component/common/drivers/sdio/realtek/sdio_host/inc +/${ProjSDK}/component/common/audio +/${ProjSDK}/component/common/drivers/i2s +/${ProjSDK}/component/common/application/xmodem + + + +/${ProjName}/project/inc +/${ProjName}/project/inc/rtl8195a +/${ProjName}/project/src/include +/${ProjSDK}/component/soc/realtek/common/bsp +/${ProjSDK}/component/os/freertos +/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include +/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3 +/${ProjSDK}/component/os/os_dep/include +/${ProjSDK}/component/soc/realtek/8195a/misc/driver +/${ProjSDK}/component/common/api/network/include +/${ProjSDK}/component/common/api +/${ProjSDK}/component/common/api/platform +/${ProjSDK}/component/common/api/wifi +/${ProjSDK}/component/common/api/wifi/rtw_wpa_supplicant/src +/${ProjSDK}/component/common/application +/${ProjSDK}/component/common/application/iotdemokit +/${ProjSDK}/component/common/application/google +/${ProjSDK}/component/common/media/framework +/${ProjSDK}/component/common/example +/${ProjSDK}/component/common/example/wlan_fast_connect +/${ProjSDK}/component/common/mbed/api +/${ProjSDK}/component/common/mbed/hal +/${ProjSDK}/component/common/mbed/hal_ext +/${ProjSDK}/component/common/mbed/targets/hal/rtl8195a +/${ProjSDK}/component/common/network +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include/lwip +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4 +/${ProjSDK}/component/common/network/lwip/lwip_v1.4.1/port/realtek +/${ProjSDK}/component/common/test +/${ProjSDK}/component/soc/realtek/8195a/cmsis +/${ProjSDK}/component/soc/realtek/8195a/cmsis/device +/${ProjSDK}/component/soc/realtek/8195a/fwlib +/${ProjSDK}/component/soc/realtek/8195a/fwlib/rtl8195a +/${ProjSDK}/component/soc/realtek/8195a/misc/rtl_std_lib/include +/${ProjSDK}/component/common/drivers/wlan/realtek/include +/${ProjSDK}/component/common/drivers/wlan/realtek/src/osdep +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hci +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hal +/${ProjSDK}/component/common/drivers/wlan/realtek/src/hal/OUTSRC +/${ProjSDK}/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom +/${ProjSDK}/component/common/network/ssl/polarssl-1.3.8/include +/${ProjSDK}/component/common/network/ssl/ssl_ram_map/rom +/${ProjSDK}/component/common/utilities +/${ProjSDK}/component/common/application/apple/WACServer/External/Curve25519 +/${ProjSDK}/component/common/application/apple/WACServer/External/GladmanAES +/${ProjSDK}/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include +/${ProjSDK}/component/common/media/codec +/${ProjSDK}/component/common/drivers/usb_class/host/uvc/inc +/${ProjSDK}/component/common/drivers/usb_class/device +/${ProjSDK}/component/common/drivers/usb_class/device/class +/${ProjSDK}/component/common/file_system/fatfs +/${ProjSDK}/component/common/file_system/fatfs/r0.10c/include +/${ProjSDK}/component/common/drivers/sdio/realtek/sdio_host/inc +/${ProjSDK}/component/common/audio +/${ProjSDK}/component/common/drivers/i2s +/${ProjSDK}/component/common/application/xmodem + + + + + +
+
+ + + + + +CONFIG_PLATFORM_8195A + + +GCC_ARMCM3 + + +ARDUINO_SDK + + +M3 + + +F_CPU166666666L + + + + + +CONFIG_PLATFORM_8195A + + +GCC_ARMCM3 + + +ARDUINO_SDK + + +M3 + + +F_CPU166666666L + + + + + + +
+
diff --git a/sdkbuild.mk b/sdkbuild.mk new file mode 100644 index 0000000..5291d37 --- /dev/null +++ b/sdkbuild.mk @@ -0,0 +1,93 @@ + +include sdkset.mk +include paths.mk + +INCFLAGS = $(patsubst %,-I%,$(patsubst sdk/%,$(SDK_PATH)%,$(INCLUDES))) + +LIBFLAGS = $(addprefix -L,$(patsubst sdk/%,$(SDK_PATH)%,$(PATHLIBS))) $(addprefix -l,$(LIBS)) + +LFLAGS += -Wl,-Map=$(OBJ_DIR)/$(TARGET).map + +CFLAGS += $(INCFLAGS) + +SRC_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(ADD_SRC_C))) $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(SRC_C))) +DRAM_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(DRAM_C))) +BOOT_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(BOOT_C))) + +SRC_C_LIST = $(patsubst sdk/%,$(SDK_PATH)%,$(ADD_SRC_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(SRC_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(DRAM_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(BOOT_C)) +OBJ_LIST = $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(SRC_C_LIST))) +DEPENDENCY_LIST = $(patsubst %.c,$(OBJ_DIR)/%.d,$(SRC_C_LIST)) + +TARGET ?= build +OBJ_DIR ?= $(TARGET)/obj +BIN_DIR ?= $(TARGET)/bin +ELFFILE ?= $(OBJ_DIR)/$(TARGET).axf + +all: prerequirement application +mp: prerequirement application + +.PHONY: build_info +build_info: + @echo \#define UTS_VERSION \"`date +%Y/%m/%d-%T`\" > .ver + @echo \#define RTL8195AFW_COMPILE_TIME \"`date +%Y/%m/%d-%T`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_DATE \"`date +%Y%m%d`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_BY \"`id -u -n`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_HOST \"`$(HOSTNAME_APP)`\" >> .ver + @if [ -x /bin/dnsdomainname ]; then \ + echo \#define RTL8195AFW_COMPILE_DOMAIN \"`dnsdomainname`\"; \ + elif [ -x /bin/domainname ]; then \ + echo \#define RTL8195AFW_COMPILE_DOMAIN \"`domainname`\"; \ + else \ + echo \#define RTL8195AFW_COMPILE_DOMAIN ; \ + fi >> .ver + @echo \#define RTL195AFW_COMPILER \"gcc `$(CC) $(CFLAGS) -dumpversion | tr --delete '\r'`\" >> .ver + @mv -f .ver project/inc/$@.h + +.PHONY: application +application: build_info $(SRC_O) $(DRAM_O) $(BOOT_O) + @echo "===========================================================" + @echo "Link ($(TARGET))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) $(OBJ_DIR) + @$(file > $(OBJ_DIR)/obj_list.lst,$(OBJ_LIST)) + @$(LD) $(LFLAGS) -o $(ELFFILE) @$(OBJ_DIR)/obj_list.lst $(LIBFLAGS) -T$(LDFILE) + @$(OBJDUMP) -d $(ELFFILE) > $(OBJ_DIR)/$(TARGET).asm + +.PHONY: prerequirement +#.NOTPARALLEL: prerequirement +prerequirement: +# @$(file >DEPENDENCY_LIST.txt,$(DEPENDENCY_LIST)) + @echo "===========================================================" + @echo "Compile ($(TARGET))" +# @echo "===========================================================" + @mkdir -p $(OBJ_DIR) + +$(SRC_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +$(DRAM_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(OBJCOPY) --prefix-alloc-sections .sdram $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +$(BOOT_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(OBJCOPY) --prefix-alloc-sections .boot $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +-include $(DEPENDENCY_LIST) + +VPATH:=$(OBJ_DIR) $(SDK_PATH) + +#.PHONY: clean +clean: + rm -rf $(OBJ_DIR) $(BIN_DIR) $(OBJ_DIR)/$(SDK_PATH) + + \ No newline at end of file diff --git a/sdkset.mk b/sdkset.mk new file mode 100644 index 0000000..c5543c2 --- /dev/null +++ b/sdkset.mk @@ -0,0 +1,433 @@ +#USE_FATFS = 1 +#USE_POLARSSL = 1 + +# FLAGS +# ------------------------------------------------------------------- +CFLAGS = -DM3 -DCONFIG_PLATFORM_8195A -DGCC_ARMCM3 -DARDUINO_SDK -DF_CPU=166666666L -DNDEBUG +CFLAGS += -mcpu=cortex-m3 -mthumb -g2 -Os -std=gnu99 -Wall -Werror +CFLAGS += -fno-common -fmessage-length=0 -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-short-enums -fsigned-char +CFLAGS += -w -Wno-pointer-sign +LFLAGS = -mcpu=cortex-m3 -mthumb -g -Os -nostartfiles -nostdlib +#--specs=nano.specs +LFLAGS += -Wl,--gc-sections -Wl,--cref -Wl,--entry=Reset_Handler -Wl,--no-enum-size-warning -Wl,--no-wchar-size-warning -Wl,-nostdlib + +# LIBS +# ------------------------------------------------------------------- +LIBS = +all: LIBS +=_platform_new _wlan _wps _p2p _websocket _sdcard _xmodem +# _mdns m c nosys gcc _wps _p2p _websocket _sdcard _xmodem +mp: LIBS +=_platform_new _wlan_mp _wps _p2p _websocket _sdcard _xmodem +PATHLIBS = sdk/component/soc/realtek/8195a/misc/bsp/lib/common/gcc +LDFILE = rlx8195A-symbol-v04-img2.ld +BOOTS = sdk/component/soc/realtek/8195a/misc/bsp/image + +# Include folder list +# ------------------------------------------------------------------- +INCLUDES = ../inc +INCLUDES += project/inc +INCLUDES += sdk/component/soc/realtek/common/bsp +INCLUDES += sdk/component/os/freertos +INCLUDES += sdk/component/os/freertos/freertos_v8.1.2/Source/include +INCLUDES += sdk/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3 +INCLUDES += sdk/component/os/os_dep/include sdk/component/soc/realtek/8195a/misc/driver +INCLUDES += sdk/component/common/api/network/include +INCLUDES += sdk/component/common/api +INCLUDES += sdk/component/common/api/platform +INCLUDES += sdk/component/common/api/wifi +INCLUDES += sdk/component/common/api/wifi/rtw_wpa_supplicant/src +INCLUDES += sdk/component/common/application +#INCLUDES += sdk/component/common/application/iotdemokit +#INCLUDES += sdk/component/common/application/google +#INCLUDES += sdk/component/common/media/framework +#INCLUDES += sdk/component/common/example +#INCLUDES += sdk/component/common/example/wlan_fast_connect +INCLUDES += sdk/component/common/mbed/api +INCLUDES += sdk/component/common/mbed/hal +INCLUDES += sdk/component/common/mbed/hal_ext +INCLUDES += sdk/component/common/mbed/targets/hal/rtl8195a +INCLUDES += sdk/component/common/network +INCLUDES += sdk/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos +INCLUDES += sdk/component/common/network/lwip/lwip_v1.4.1/src/include +INCLUDES += sdk/component/common/network/lwip/lwip_v1.4.1/src/include/lwip +INCLUDES += sdk/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4 +INCLUDES += sdk/component/common/network/lwip/lwip_v1.4.1/port/realtek +INCLUDES += sdk/component/common/test +INCLUDES += sdk/component/soc/realtek/8195a/cmsis +INCLUDES += sdk/component/soc/realtek/8195a/cmsis/device +INCLUDES += sdk/component/soc/realtek/8195a/fwlib +INCLUDES += sdk/component/soc/realtek/8195a/fwlib/rtl8195a +INCLUDES += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/ +INCLUDES += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/include +INCLUDES += sdk/component/common/drivers +INCLUDES += sdk/component/common/drivers/i2s +INCLUDES += sdk/component/common/drivers/wlan/realtek/include +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/osdep +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hci +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hal +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hal/OUTSRC +INCLUDES += sdk/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom +INCLUDES += sdk/component/common/network/ssl/ssl_ram_map/rom +INCLUDES += sdk/component/common/utilities +INCLUDES += sdk/component/common/application/apple/WACServer/External/Curve25519 +INCLUDES += sdk/component/common/application/apple/WACServer/External/GladmanAES +INCLUDES += sdk/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include +#INCLUDES += sdk/component/common/media/codec +#INCLUDES += sdk/component/common/drivers/usb_class/host/uvc/inc +#INCLUDES += sdk/component/common/drivers/usb_class/device +#INCLUDES += sdk/component/common/drivers/usb_class/device/class sdk/component/common/file_system/fatfs +INCLUDES += sdk/component/common/file_system/fatfs/r0.10c/include +INCLUDES += sdk/component/common/drivers/sdio/realtek/sdio_host/inc +INCLUDES += sdk/component/common/audio +INCLUDES += sdk/component/common/application/xmodem + +# Source file list +# ------------------------------------------------------------------- +SRC_C = +DRAM_C = +BOOT_C = + +#bootloader +SRC_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/rtl_bios_data.c +BOOT_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot.c + +#cmsis +SRC_C += sdk/component/soc/realtek/8195a/cmsis/device/system_8195a.c + +#console +#DRAM_C += sdk/component/common/api/at_cmd/atcmd_ethernet.c +#DRAM_C += sdk/component/common/api/at_cmd/atcmd_lwip.c +#DRAM_C += sdk/component/common/api/at_cmd/atcmd_sys.c +#DRAM_C += sdk/component/common/api/at_cmd/atcmd_wifi.c +#SRC_C += sdk/component/common/api/at_cmd/log_service.c +#SRC_C += sdk/component/soc/realtek/8195a/misc/driver/low_level_io.c +#console new/old +SRC_C += sdk/component/soc/realtek/8195a/misc/driver/rtl_console_new.c +#SRC_C += sdk/component/soc/realtek/8195a/misc/driver/rtl_consol.c + +#network - api +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_p2p_config.c +SRC_C += sdk/component/common/api/wifi/wifi_conf.c +SRC_C += sdk/component/common/api/wifi/wifi_ind.c +SRC_C += sdk/component/common/api/wifi/wifi_promisc.c +SRC_C += sdk/component/common/api/wifi/wifi_simple_config.c +SRC_C += sdk/component/common/api/wifi/wifi_util.c +SRC_C += sdk/component/common/api/lwip_netconf.c + +#network - app +#SRC_C += sdk/component/common/utilities/ssl_client.c +#SRC_C += sdk/component/common/utilities/ssl_client_ext.c +#SRC_C += sdk/component/common/utilities/tcptest.c +#SRC_C += sdk/component/common/utilities/uart_ymodem.c +#SRC_C += sdk/component/common/utilities/update.c +#SRC_C += sdk/component/common/application/uart_adapter/uart_adapter.c +SRC_C += sdk/component/common/api/network/src/wlan_network.c +SRC_C += sdk/component/common/api/wifi_interactive_mode.c +#SRC_C += sdk/component/common/api/network/src/ping_test.c + +#network - lwip +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/api_lib.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/api_msg.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/err.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/netbuf.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/netdb.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/netifapi.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/sockets.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/api/tcpip.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/autoip.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/icmp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/igmp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet_chksum.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_addr.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_frag.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/def.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/dhcp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/dns.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/init.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/lwip_timers.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/mem.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/memp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/netif.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/pbuf.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/raw.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/stats.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/sys.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/tcp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_in.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_out.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/core/udp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/src/netif/etharp.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.c +SRC_C += sdk/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.c +SRC_C += sdk/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.c +SRC_C += sdk/component/common/network/dhcp/dhcps.c +SRC_C += sdk/component/common/network/sntp/sntp.c +SRC_C += sdk/component/common/network/netbios/netbios.c + +#network - mdns +#SRC_C += sdk/component/common/network/mDNS/mDNSPlatform.c + +#os - freertos +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_5.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/port.c +SRC_C += sdk/component/os/freertos/cmsis_os.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/croutine.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/event_groups.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/list.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/queue.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/tasks.c +SRC_C += sdk/component/os/freertos/freertos_v8.1.2/Source/timers.c + +#os - osdep +SRC_C += sdk/component/os/os_dep/device_lock.c +SRC_C += sdk/component/os/freertos/freertos_service.c +SRC_C += sdk/component/os/os_dep/mailbox.c +SRC_C += sdk/component/os/os_dep/osdep_api.c +SRC_C += sdk/component/os/os_dep/osdep_service.c +SRC_C += sdk/component/os/os_dep/tcm_heap.c + +#peripheral - api +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/analogin_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/dma_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/efuse_api.c +#SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/ethernet_api.c +#SRC_C += sdk/component/common/drivers/ethernet_mii/ethernet_mii.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/flash_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/gpio_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/gpio_irq_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/i2c_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/i2s_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/nfc_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pinmap.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pinmap_common.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/port_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pwmout_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/rtc_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/serial_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/sleep.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/spdio_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/spi_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/sys_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/timer_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/us_ticker.c +SRC_C += sdk/component/common/mbed/common/us_ticker_api.c +SRC_C += sdk/component/common/mbed/common/wait_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/wdt_api.c + +#peripheral - hal +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_32k.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_adc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_gdma.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_gpio.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_i2c.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_i2s.c +#SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_mii.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_nfc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pcm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pwm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_sdr_controller.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_ssi.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_timer.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_uart.c + +#peripheral - osdep +SRC_C += sdk/component/os/freertos/freertos_pmu.c + +#peripheral - rtl8195a +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_adc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gdma.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gpio.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2c.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2s.c +#SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_mii.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_nfc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pwm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_timer.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_uart.c + +#peripheral - wlan +#SRC_C += sdk/component/common/drivers/wlan/realtek/src/core/option/rtw_opt_skbuf.c + +#SDRAM +#DRAM_C += sdk/component/common/api/platform/stdlib_patch.c +#SDRAM - polarssl +ifdef USE_POLARSSL +INCLUDES += sdk/component/common/network/ssl/polarssl-1.3.8/include + +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_wps_config.c +SRC_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/bignum.c + +DRAM_C += sdk/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.c +DRAM_C += sdk/component/common/network/ssl/ssl_ram_map/ssl_ram_map.c + +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/aes.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/aesni.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/arc4.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/asn1parse.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/asn1write.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/base64.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/blowfish.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/camellia.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ccm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/certs.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/cipher.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/cipher_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ctr_drbg.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/debug.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/des.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/dhm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecp.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecp_curves.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecdh.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecdsa.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/entropy.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/entropy_poll.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/error.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/gcm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/havege.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/hmac_drbg.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md2.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md4.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md5.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/memory_buffer_alloc.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/net.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/oid.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/padlock.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pbkdf2.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pem.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs5.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs11.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs12.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pk.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pk_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkparse.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkwrite.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/platform.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ripemd160.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/rsa.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha1.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha256.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha512.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_cache.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_ciphersuites.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_cli.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_srv.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_tls.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/threading.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/timing.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/version.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/version_features.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_crt.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_crl.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_csr.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_create.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509write_crt.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509write_csr.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/xtea.c +endif + + +#SDRAM - wigadget +#DRAM_C += sdk/component/common/application/wigadget/cloud_link.c +#DRAM_C += sdk/component/common/application/wigadget/shtc1.c +#DRAM_C += sdk/component/common/application/wigadget/wigadget.c + +#utilities +#SRC_C += sdk/component/common/utilities/cJSON.c +#SRC_C += sdk/component/common/utilities/http_client.c +#SRC_C += sdk/component/common/utilities/uart_socket.c +#SRC_C += sdk/component/common/utilities/webserver.c +#SRC_C += sdk/component/common/utilities/xml.c + +#utilities - FatFS +ifdef USE_FATFS +SRC_C += sdk/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/diskio.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/ff.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c +SRC_C += sdk/component/common/file_system/fatfs/disk_if/src/sdcard.c +endif + +#utilities - xmodem update +#SRC_C += sdk/component/common/application/xmodem/uart_fw_update.c +# ------------------------------------------------------------------- +# My Source file list +# ------------------------------------------------------------------- +ADD_SRC_C = +# REVERSED +#ADD_SRC_C += sdk/component/soc/realtek/8195a/cmsis/device/app_start.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_dac.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_common.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_soc_ps_monitor.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_efuse.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_log_uart.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pinmux.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_misc.c +#ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c +# COMPONENTS +ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/startup.c +ADD_SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/flash_eep.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libc.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libgloss_retarget.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_eabi_cast_ram.c +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_math_ram.c +#if +- nostdlib.. +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_pvvx_libc.c +#if c_printf() float +ADD_SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c +# ------------------------------------------------------------------- +# SAMPLES +# ------------------------------------------------------------------- +#ADD_SRC_C += sdk/component/common/example/cJSON/cJSON_example.c +#ADD_SRC_C += sdk/component/common/example/googlenest/example_google.c +#ADD_SRC_C += sdk/component/common/example/mdns/example_mdns.c +#ADD_SRC_C += sdk/component/common/example/socket_select/example_socket_select.c +#ADD_SRC_C += sdk/component/common/example/wlan_fast_connect/example_wlan_fast_connect.c +#ADD_SRC_C += sdk/component/common/example/uart_atcmd/example_uart_atcmd.c +#ADD_SRC_C += sdk/component/common/example/xml/example_xml.c +#ADD_SRC_C += sdk/component/common/example/example_entry.c +#ADD_SRC_C += sdk/component/common/drivers/sdio/realtek/sdio_host/src/sd.c +#ADD_SRC_C += sdk/component/common/drivers/sdio/realtek/sdio_host/src/sdio_host.c +#ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_sdio_host.c +#ADD_SRC_C += sdk/component/common/file_system/fatfs/disk_if/src/sdcard.c +ADD_SRC_C += sdk/component/common/api/wifi_api.c +#============================================= +# PROGECT +#============================================= +#user main +ADD_SRC_C += project/src/user/main.c +ADD_SRC_C += project/src/user/user_start.c +# components +ADD_SRC_C += project/src/console/atcmd_user.c +ADD_SRC_C += project/src/console/wifi_console.c +ADD_SRC_C += project/src/console/pwm_tst.c + +#Web-свалка +INCLUDES += project/inc/web +ADD_SRC_C += project/src/tcpsrv/tcp_srv_conn.c +ADD_SRC_C += project/src/webfs/webfs.c +ADD_SRC_C += project/src/web/web_srv.c +ADD_SRC_C += project/src/web/web_utils.c +ADD_SRC_C += project/src/web/web_websocket.c +ADD_SRC_C += project/src/web/websock.c +ADD_SRC_C += project/src/web/web_int_callbacks.c +ADD_SRC_C += project/src/web/web_int_vars.c + +#CFLAGS += -DDEFAULT_BAUDRATE=1562500 +#if CONFIG_ENABLE_P2P and ...: +CFLAGS += -DLOGUART_STACK_SIZE=1024 + +#LwIP HTTPd +#include project/src/LwHTTPd/LwHTTPd.mk + +#WebSocket Client +#ADD_SRC_C += project/src/console/ws_test.c +#include websocket/module.mk +#============================================= diff --git a/tools/webfs/WEBFS22.exe b/tools/webfs/WEBFS22.exe new file mode 100644 index 0000000..c7b4776 Binary files /dev/null and b/tools/webfs/WEBFS22.exe differ diff --git a/tools/webfs/py/README.md b/tools/webfs/py/README.md new file mode 100644 index 0000000..fe8cd1c --- /dev/null +++ b/tools/webfs/py/README.md @@ -0,0 +1,7 @@ +# webfs + +Программа для формирования и обслуживания web-диска на Python v2.7.
+Проект не закончен и находится в начальной стадии.
+Пока содержит два варианта примера загрузчика бинарного диска по HTTP.
+ + \ No newline at end of file diff --git a/tools/webfs/py/webfs_upload1.py b/tools/webfs/py/webfs_upload1.py new file mode 100644 index 0000000..41d16e6 --- /dev/null +++ b/tools/webfs/py/webfs_upload1.py @@ -0,0 +1,157 @@ +#-*- coding: utf-8 -*- +# +# test webfs_upload.py +# PV` Created on 26/09/2015. +# +# Bases: +#--------------------------------------------------- +# 2006/02 Will Holcomb +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# 2007/07/26 Slightly modified by Brian Schneider +# +# in order to support unicode files ( multipart_encode function ) +# From http://peerit.blogspot.com/2007/07/multipartposthandler-doesnt-work-for.html +# +# 2013/07 Ken Olum +# +# Removed one of \r\n and send Content-Length +# +# 2014/05 Applied Fedora rpm patch +# +# https://bugzilla.redhat.com/show_bug.cgi?id=920778 +# http://pkgs.fedoraproject.org/cgit/python-MultipartPostHandler2.git/diff/python-MultipartPostHandler2-cut-out-main.patch?id=c1638bb3e45596232b4d02f1e69901db0c28cfdb +# +# 2014/05/09 Sergio Basto +# +# Better deal with None values, don't throw an exception and just send an empty string. +# +#--------------------------------------------------- +import sys +import urllib +import urllib2 +import mimetools #, mimetypes +import os +import stat +from base64 import standard_b64encode + +from cStringIO import StringIO + +class Callable: + def __init__(self, anycallable): + self.__call__ = anycallable + +class MultipartPostHandler(urllib2.BaseHandler): + handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first + + + def http_request(self, request): + data = request.get_data() + if data is not None and type(data) != str: + v_files = [] + v_vars = [] + try: + for(key, value) in data.items(): + if type(value) == file: + v_files.append((key, value)) + else: + v_vars.append((key, value)) + except TypeError: + systype, value, traceback = sys.exc_info() + raise TypeError, "not a valid non-string sequence or mapping object", traceback + if len(v_files) == 0: + data = urllib.urlencode(v_vars, 1) + else: + boundary, data = self.multipart_encode(v_vars, v_files) + contenttype = 'multipart/form-data; boundary=%s' % boundary + + if(request.has_header('Content-Type') + and request.get_header('Content-Type').find('multipart/form-data') != 0): + print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data') + + request.add_unredirected_header('Content-Type', contenttype) +# authstr = 'Basic ' + standard_b64encode('ESP8266' + ':' + '0123456789') +# if(request.has_header('Authorization')): +# print "Replacing %s with %s" % (request.get_header('Authorization'), authstr) +# request.add_unredirected_header('Authorization', authstr) + request.add_data(data) + return request + + def multipart_encode(vars, files, boundary = None, buffer = None): + if boundary is None: + boundary = mimetools.choose_boundary() + if buffer is None: + buffer = StringIO() + for(key, value) in vars: + buffer.write('--%s\r\n' % boundary) + buffer.write('Content-Disposition: form-data; name="%s"' % key) + if value is None: + value = "" + # if type(value) is not str, we need str(value) to not error with cannot concatenate 'str' + # and 'dict' or 'tuple' or somethingelse objects + buffer.write('\r\n\r\n' + str(value) + '\r\n') + for(key, fd) in files: + file_size = os.fstat(fd.fileno())[stat.ST_SIZE] + filename = fd.name.split('/')[-1] +# contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' + contenttype = 'application/octet-stream' + buffer.write('--%s\r\n' % boundary) + buffer.write('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)) + buffer.write('Content-Type: %s\r\n' % contenttype) + buffer.write('Content-Length: %s\r\n' % file_size) + fd.seek(0) + buffer.write('\r\n' + fd.read() + '\r\n') + buffer.write('--' + boundary + '--\r\n') + buffer = buffer.getvalue() + return boundary, buffer + multipart_encode = Callable(multipart_encode) + + https_request = http_request + +if __name__ == '__main__': + if len(sys.argv) == 2: + if sys.argv[1] == '-h': + print 'Usage: filename rtlurl username password' + sys.exit(0) + + filename = '../webbin/WEBFiles.bin' + rtlurl = 'http://rtl871x0/fsupload' + username = 'RTL871X' + password = '0123456789' + + if len(sys.argv) > 1: + if sys.argv[1]: + filename = sys.argv[1] + if len(sys.argv) > 2: + if sys.argv[2]: + rtlurl = sys.argv[2] + if len(sys.argv) > 3: + if sys.argv[3]: + username = sys.argv[3] + if len(sys.argv) > 4: + if sys.argv[4]: + password = sys.argv[4] + + print('Start send %s to %s' % (filename, rtlurl)) + opener = urllib2.build_opener(MultipartPostHandler) + authstr = 'Basic ' + standard_b64encode(username + ':' + password) + opener.addheaders.append(['Authorization', authstr]) + params = { 'overlay' : open(filename, 'rb') } + try: + resp = opener.open(rtlurl, params) + print('End, response code: %s\n' % resp.code) + sys.exit(0) + except Exception as e: + print('Failed open (%s) %s\n' % (str(e).decode('cp1251'), rtlurl)) + sys.exit(1) + + \ No newline at end of file diff --git a/tools/webfs/py/webfs_upload2.py b/tools/webfs/py/webfs_upload2.py new file mode 100644 index 0000000..c064788 --- /dev/null +++ b/tools/webfs/py/webfs_upload2.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# -*- coding: cp1251 -*- +''' +test webfs_upload.py +Created on 27/09/2015. + +@author: PVV +''' +# +# Use module 'requests' - http://docs.python-requests.org/ +# + +import requests +from requests.auth import HTTPBasicAuth + + +if __name__ == '__main__': + rtlurl = 'http://rtl871x0/fsupload' + username = 'RTL871X' + password = '0123456789' + filename = '../webbin/WEBFiles.bin' + + files = {'file': (filename, open(filename, 'rb'), 'application/octet-stream')} +# postdata = {'':''} +# headers = {'Connection' : 'keep-alive'} + + s = requests.Session() +# q = s.post(theurl, auth=HTTPBasicAuth(username, password), headers=headers, data=postdata, files=files) + q = s.post(rtlurl, auth=HTTPBasicAuth(username, password), files=files) + print(q.status_code) diff --git a/tools/webfs/src/WEBFS22.zip b/tools/webfs/src/WEBFS22.zip new file mode 100644 index 0000000..85de8f7 Binary files /dev/null and b/tools/webfs/src/WEBFS22.zip differ diff --git a/webfs.mk b/webfs.mk new file mode 100644 index 0000000..e8a6656 --- /dev/null +++ b/webfs.mk @@ -0,0 +1,7 @@ +include paths.mk + +all: + @mkdir -p $(BIN_DIR) + ./tools/webfs/WEBFS22.exe -h "*.htm, *.html, *.cgi, *.xml, *.bin, *.txt, *.wav" -z "mdbini.bin, *.inc, *.ini, snmp.bib, *.ovl" ./WEBFiles $(BIN_DIR) WEBFiles.bin + +clean: