From cb7f1a450b4f461c12b236ed671e357e30f9823b Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Sun, 9 Jan 2022 12:36:16 +0700 Subject: [PATCH 1/7] strncasecmp did not work corectly --- X86TestSupport/TestSupport/WString.cpp | 13 ++----------- X86TestSupport/TestSupport/WString.h | 1 + 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/X86TestSupport/TestSupport/WString.cpp b/X86TestSupport/TestSupport/WString.cpp index b3d9d4f8f..aec1f3dcf 100644 --- a/X86TestSupport/TestSupport/WString.cpp +++ b/X86TestSupport/TestSupport/WString.cpp @@ -96,19 +96,10 @@ StringAppender& operator+(const StringAppender& lhs, double num) { #ifdef _MSC_VER int strcasecmp(const char* lhs, const char* rhs) { - while (*lhs && *rhs && tolower(*lhs) == tolower(*rhs)) { - ++lhs; - ++rhs; - } - return (*lhs) == '\0' && (*rhs) == '\0'; + return ::_stricmp(lhs, rhs); } int strncasecmp(const char* lhs, const char* rhs, size_t count) { - while (*lhs && *rhs && tolower(*lhs) == tolower(*rhs) && count > 0) { - ++lhs; - ++rhs; - --count; - } - return count == 0 || ((*lhs) == '\0' && (*rhs) == '\0'); + return ::_strnicmp(lhs,rhs , count); } #endif diff --git a/X86TestSupport/TestSupport/WString.h b/X86TestSupport/TestSupport/WString.h index 76fcaeb0f..b8da84fd6 100644 --- a/X86TestSupport/TestSupport/WString.h +++ b/X86TestSupport/TestSupport/WString.h @@ -6,6 +6,7 @@ #include #include #include +#include class StringAppender; From 3b41c2883e8dd59815b8da2cce03f0653de75de1 Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Sun, 9 Jan 2022 21:27:22 +0700 Subject: [PATCH 2/7] Added the FluidConsole project Added the FluidConsole project. The project is a win32 console application that allows you to debug and emulate Fluidnc code on Windows. File "config.yaml" should be placed on the working directory. Use COM# in command line to connect via com port --- FluidNC.sln | 14 +- FluidNC/src/FileStream.cpp | 11 + FluidNC/src/Main.cpp | 53 +- FluidNC/src/Protocol.cpp | 5 +- FluidNC/src/Report.cpp | 7 + FluidNCConsole.vcxproj | 493 +++++++++ FluidNCConsole.vcxproj.filters | 988 ++++++++++++++++++ X86TestSupport/TestSupport/ComPortX86.cpp | 115 ++ X86TestSupport/TestSupport/ComPortX86.h | 21 + X86TestSupport/TestSupport/SPIFFS.h | 2 +- X86TestSupport/TestSupport/StdTimer.cpp | 76 ++ X86TestSupport/TestSupport/StdTimer.h | 44 + X86TestSupport/TestSupport/driver/uart.h | 2 + .../TestSupport/esp32-hal-timer.cpp | 52 +- config.yaml | 95 ++ screenshots/2022-01-07_12-25-20.png | Bin 0 -> 30747 bytes screenshots/2022-01-07_12-31-21.png | Bin 0 -> 81569 bytes 17 files changed, 1955 insertions(+), 23 deletions(-) create mode 100644 FluidNCConsole.vcxproj create mode 100644 FluidNCConsole.vcxproj.filters create mode 100644 X86TestSupport/TestSupport/ComPortX86.cpp create mode 100644 X86TestSupport/TestSupport/ComPortX86.h create mode 100644 X86TestSupport/TestSupport/StdTimer.cpp create mode 100644 X86TestSupport/TestSupport/StdTimer.h create mode 100644 config.yaml create mode 100644 screenshots/2022-01-07_12-25-20.png create mode 100644 screenshots/2022-01-07_12-31-21.png diff --git a/FluidNC.sln b/FluidNC.sln index 7c2c2a590..5eef9045b 100644 --- a/FluidNC.sln +++ b/FluidNC.sln @@ -1,12 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29306.81 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1738 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FluidNC", "FluidNC.vcxproj", "{11C8A44F-A303-4885-B5AD-5B65F7FE41C0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests", "UnitTests.vcxproj", "{33ECE513-60D1-4949-A4A9-C95D353C2CF0}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FluidNCConsole", "FluidNCConsole.vcxproj", "{8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -29,6 +31,14 @@ Global {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Release|x64.Build.0 = Release|x64 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Release|x86.ActiveCfg = Release|Win32 {33ECE513-60D1-4949-A4A9-C95D353C2CF0}.Release|x86.Build.0 = Release|Win32 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Debug|x64.ActiveCfg = Debug|x64 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Debug|x64.Build.0 = Debug|x64 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Debug|x86.ActiveCfg = Debug|Win32 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Debug|x86.Build.0 = Debug|Win32 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Release|x64.ActiveCfg = Release|x64 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Release|x64.Build.0 = Release|x64 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Release|x86.ActiveCfg = Release|Win32 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/FluidNC/src/FileStream.cpp b/FluidNC/src/FileStream.cpp index e1b7ecb4c..f5d6f7a9f 100644 --- a/FluidNC/src/FileStream.cpp +++ b/FluidNC/src/FileStream.cpp @@ -6,6 +6,9 @@ #include "SDCard.h" #include "Logging.h" #include +#ifdef FLUIDNC_CONSOLE +#include +#endif int FileStream::available() { return 1; @@ -45,7 +48,15 @@ size_t FileStream::position() { FileStream::FileStream(String filename, const char* mode, const char* defaultFs) : FileStream(filename.c_str(), mode, defaultFs) {} FileStream::FileStream(const char* filename, const char* mode, const char* defaultFs) : Channel("file") { +#ifdef FLUIDNC_CONSOLE + std::string cur_path = std::filesystem::current_path().string(); + if (cur_path.back() != '\\') + cur_path += '\\'; + + const char* actualLocalFs = cur_path.c_str(); +#else const char* actualLocalFs = "/spiffs/"; +#endif const char* sdPrefix = "/sd/"; const char* localFsPrefix = "/localfs/"; diff --git a/FluidNC/src/Main.cpp b/FluidNC/src/Main.cpp index 932b3b1d9..64070624b 100644 --- a/FluidNC/src/Main.cpp +++ b/FluidNC/src/Main.cpp @@ -197,14 +197,55 @@ void loop() { void WEAK_LINK machine_init() {} -# if 0 -int main() { - setup(); // setup() - while (1) { // loop() - loop(); +#ifdef FLUIDNC_CONSOLE +#include "ComPortX86.h" +#include "InputFile.h" + + +int main(int argc, char *argv[]){ + + setup(); + + allChannels.deregistration(&Uart0); // USB Serial + allChannels.deregistration(&WebUI::inputBuffer); // Macros + + Channel *pin = nullptr; + Channel *pout = nullptr; + + if (argc == 1) { //console input + pin = new ComPortX86(nullptr); } + else if (strncasecmp(argv[1], "COM", 3) == 0) { //com port + pin = new ComPortX86(argv[1]); + } + else { + pout = new ComPortX86(nullptr); // run file from command line, ouput to console + infile = new InputFile("/localfs", argv[1], WebUI::AuthenticationLevel::LEVEL_GUEST, *pout); + readyNext = true; + } + + if (pin) + allChannels.registration(pin); + if (pout) + allChannels.registration(pout); + + if ( config ) + config->_verboseErrors = true; + +// unlock GRBL to easy debugging + do_command_or_setting("X", nullptr, WebUI::AuthenticationLevel::LEVEL_ADMIN, pout != nullptr ? *pout : *pin); + + loop(); + + if (pin) + delete pin; + if ( pout ) + delete pout; + if ( infile ) + delete infile; + return 0; } -# endif +#endif #endif diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index ce1ac73cd..cf16f8bf3 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -199,7 +199,7 @@ void protocol_main_loop() { break; } #ifdef DEBUG_REPORT_ECHO_RAW_LINE_RECEIVED - report_echo_line_received(line, *chan); + report_echo_line_received(line, *chan); #endif display("GCODE", line); // auth_level can be upgraded by supplying a password on the command line @@ -742,7 +742,8 @@ void protocol_exec_rt_system() { if (rtSeq) { rtSeq = false; log_error("planner " << pl_seq0 << " stepper " << st_seq0); - rtReset = true; + rtReset = true; //rtReset = true; comment this becouse this appear if G0 instruction does not chenge the position + } if (rtCrash) { rtCrash = false; diff --git a/FluidNC/src/Report.cpp b/FluidNC/src/Report.cpp index 233f20b3a..28e696716 100644 --- a/FluidNC/src/Report.cpp +++ b/FluidNC/src/Report.cpp @@ -39,6 +39,9 @@ #include #include #include +#ifdef FLUIDNC_CONSOLE +#include +#endif #ifdef DEBUG_REPORT_HEAP EspClass esp; @@ -412,7 +415,11 @@ void report_build_info(const char* line, Print& channel) { // Prints the character string line that was received, which has been pre-parsed, // and has been sent into protocol_execute_line() routine to be executed. void report_echo_line_received(char* line, Print& channel) { +#ifdef FLUIDNC_CONSOLE + std::cout << "[echo: " << line << "]\n"; +#else channel << "[echo: " << line << "]\n"; +#endif } // Calculate the position for status reports. diff --git a/FluidNCConsole.vcxproj b/FluidNCConsole.vcxproj new file mode 100644 index 000000000..10fd12bea --- /dev/null +++ b/FluidNCConsole.vcxproj @@ -0,0 +1,493 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {8CE82A5A-3357-4179-8E8B-5D5B5B52B37B} + Win32Proj + FluidNCConsole + 10.0.17763.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(Configuration)\$(ProjectName)\ + + + true + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(Configuration)\$(ProjectName)\ + + + false + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + + + Level3 + Disabled + true + FLUIDNC_CONSOLE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(MSBuildThisFileDirectory)X86TestSupport\TestSupport;$(MSBuildThisFileDirectory)FluidNC;%(AdditionalIncludeDirectories) + 4996;%(DisableSpecificWarnings) + stdcpp17 + + + Console + true + + + + + + + Level3 + Disabled + true + FLUIDNC_CONSOLE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(MSBuildThisFileDirectory)X86TestSupport\TestSupport;$(MSBuildThisFileDirectory)FluidNC;%(AdditionalIncludeDirectories) + stdcpp17 + 4996;%(DisableSpecificWarnings) + + + Console + true + + + + + + + Level3 + MaxSpeed + true + true + true + FLUIDNC_CONSOLE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996;%(DisableSpecificWarnings) + stdcpp17 + $(MSBuildThisFileDirectory)X86TestSupport\TestSupport;$(MSBuildThisFileDirectory)FluidNC;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + Level3 + MaxSpeed + true + true + true + FLUIDNC_CONSOLE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996;%(DisableSpecificWarnings) + stdcpp17 + $(MSBuildThisFileDirectory)X86TestSupport\TestSupport;$(MSBuildThisFileDirectory)FluidNC;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FluidNCConsole.vcxproj.filters b/FluidNCConsole.vcxproj.filters new file mode 100644 index 000000000..7231911e0 --- /dev/null +++ b/FluidNCConsole.vcxproj.filters @@ -0,0 +1,988 @@ + + + + + {0b908af9-f859-4c7e-afeb-8b986c16a2dd} + + + {0af7da47-d437-4dfb-ba91-df1fedaad27e} + + + {86c3d48f-4f1d-4573-9da1-0b0185a5d10f} + + + {d4d90279-db45-456d-b8e4-d15cc120cf91} + + + {eb2b6d4b-b39e-4654-bc63-ce803dc0d8b8} + + + {9cca02dd-d718-4e0a-9564-502000cee56f} + + + {41ab1e58-9e2a-4ad7-978f-b87201140aac} + + + {1c639553-4d87-4b44-9370-5c54ed9d4eb0} + + + {65d8580e-d3bc-48c5-ad7d-da8fe776bbe1} + + + {34428cb7-aed3-4e27-8ad1-360ab644361b} + + + {4cfbecfd-14fa-412f-89b5-1ce3a08e6c31} + + + {ddda5f9e-d343-4e28-b20a-b2a07484f22c} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\StackTrace + + + src\StackTrace + + + src\PinUsers + + + src\Custom + + + src\Custom + + + src\Custom + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\StackTrace + + + src\StackTrace + + + src\PinUsers + + + src\Custom + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\WebUI + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Machine + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Pins + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Spindles + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Motors + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + src\Kinematics + + + X86TestSupport + + + X86TestSupport + + + X86TestSupport + + + + + X86TestSupport + + + + + src + + + src + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Configuration + + + src\Spindles + + + src\Motors + + + + + \ No newline at end of file diff --git a/X86TestSupport/TestSupport/ComPortX86.cpp b/X86TestSupport/TestSupport/ComPortX86.cpp new file mode 100644 index 000000000..acaa5e58d --- /dev/null +++ b/X86TestSupport/TestSupport/ComPortX86.cpp @@ -0,0 +1,115 @@ +#include "ComPortX86.h" +#include +#include +#include "StdTimer.h" + + +#define MAX_DEVPATH_LENGTH 1024 +//#define LOCAL_ECHO +extern StdTimer g_timer; + +ComPortX86::ComPortX86(const char *pPort ) : + hSerial(INVALID_HANDLE_VALUE), Channel("com_win32") +{ + DCB dcb; + BOOL fSuccess; + TCHAR devicePath[MAX_DEVPATH_LENGTH]; + COMMTIMEOUTS commTimeout; + + if (pPort != NULL) + { + mbstowcs_s(NULL, devicePath, MAX_DEVPATH_LENGTH, pPort, strlen(pPort)); + hSerial = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, NULL); + } + if (hSerial != INVALID_HANDLE_VALUE) + { + // Initialize the DCB structure. + SecureZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + fSuccess = GetCommState(hSerial, &dcb); + if (!fSuccess) + { + CloseHandle(hSerial); + hSerial = INVALID_HANDLE_VALUE; + return; + } + + GetCommState(hSerial, &dcb); + dcb.BaudRate = CBR_115200; // baud rate + dcb.ByteSize = 8; // data size, xmit and rcv + dcb.Parity = NOPARITY; // parity bit + dcb.StopBits = ONESTOPBIT; // stop bit + dcb.fBinary = TRUE; + dcb.fParity = TRUE; + + fSuccess = SetCommState(hSerial, &dcb); + if (!fSuccess) + { + CloseHandle(hSerial); + hSerial = INVALID_HANDLE_VALUE; + return; + } + + GetCommTimeouts(hSerial, &commTimeout); + commTimeout.ReadIntervalTimeout = 1; + commTimeout.ReadTotalTimeoutConstant = 1; + commTimeout.ReadTotalTimeoutMultiplier = 1; + commTimeout.WriteTotalTimeoutConstant = 1; + commTimeout.WriteTotalTimeoutMultiplier = 1; + SetCommTimeouts(hSerial, &commTimeout); + } +} + +ComPortX86::ComPortX86() : + Channel("com_win32"), hSerial(INVALID_HANDLE_VALUE) +{ } + +ComPortX86::~ComPortX86() +{ + +} + +int ComPortX86::read() +{ +DWORD dwBytesRead; +uint8_t data; +int ret =-1; + +if (hSerial != INVALID_HANDLE_VALUE ) +{ + if (ReadFile(hSerial, &data, 1, &dwBytesRead, NULL) && dwBytesRead == 1) + { + ret = static_cast(data); + } +} +else +{ + if (_kbhit()) + { + ret = _getch(); + char c = static_cast(ret); + std::cout << c; + if ( c== 10 || c == 13 ) + std::cout << "\n"; + } +} + return ret; +} + +size_t ComPortX86::write(uint8_t c) +{ + DWORD dwBytesWritten = 1; + if (hSerial != INVALID_HANDLE_VALUE) + { + WriteFile(hSerial, &c, 1, &dwBytesWritten, NULL); + } + else + { + std::cout << c; + + } + return dwBytesWritten; +} + + diff --git a/X86TestSupport/TestSupport/ComPortX86.h b/X86TestSupport/TestSupport/ComPortX86.h new file mode 100644 index 000000000..24e8a12da --- /dev/null +++ b/X86TestSupport/TestSupport/ComPortX86.h @@ -0,0 +1,21 @@ +#pragma once +#include "src/Channel.h" +#include + +class ComPortX86 : public Channel +{ +public: + ComPortX86(const char *pPort); + ComPortX86(); + ~ComPortX86(); + virtual size_t write(uint8_t c) override; + virtual int read() override; + virtual int available() { return true; } + virtual int peek() { return 0; } + virtual void flush() { return; } + virtual int rx_buffer_available() { return 0; } +private: + + HANDLE hSerial; +}; + diff --git a/X86TestSupport/TestSupport/SPIFFS.h b/X86TestSupport/TestSupport/SPIFFS.h index a6691b2aa..1fc2872a0 100644 --- a/X86TestSupport/TestSupport/SPIFFS.h +++ b/X86TestSupport/TestSupport/SPIFFS.h @@ -29,7 +29,7 @@ namespace fs { void end(); private: - char* partitionLabel_; + String partitionLabel_; }; } diff --git a/X86TestSupport/TestSupport/StdTimer.cpp b/X86TestSupport/TestSupport/StdTimer.cpp new file mode 100644 index 000000000..003bb9042 --- /dev/null +++ b/X86TestSupport/TestSupport/StdTimer.cpp @@ -0,0 +1,76 @@ +#include "StdTimer.h" +#include + + + +void tic_processor(StdTimer &pt, int microsec) +{ + int tmp_rubs_for_move = 0; + uint64_t cur_period = 0; + + for (;;) { + if (pt.is_stop()) { + break; + } + if (cur_period >= pt.get_timer_tic()) { + cur_period = 0; + if (pt.is_enabled()) + { + pt.do_action(); + } + } + cur_period++; + std::this_thread::sleep_for(std::chrono::microseconds(microsec)); + } +} + + +StdTimer::StdTimer(uint32_t microsec, uint8_t timer, uint16_t divider, bool countUp) : + _microsec(microsec), _timer(timer), _divider(divider), _countUp(countUp), _action(0), _is_stop(true), + _enable(false),_interrupt(0) { + /* Create the queue. */ +} +StdTimer::~StdTimer(){ + stop(); +} + +void StdTimer::start() { + if (!_is_stop) + return; + _is_stop = false; + set_enable(false); + std::thread(tic_processor, std::ref(*this), _microsec).detach(); +} + + +void StdTimer::do_action() +{ +#ifdef FLUIDNC_CONSOLE_DEBUG_TIMER + static int pulse_count = 0; + std::cout << pulse_count << " puls\n"; + pulse_count++; +#endif + if ( _action ) + _action(); +} + +void StdTimer::set_enable(bool enable) { + _enable = enable; +} + +bool StdTimer::is_enabled() { + return _enable; +} + +void StdTimer::set_action(void (*fn)(void)) { + _action = fn; +} +void StdTimer::set_pulse_tic(uint64_t interruptAt) +{ + // interruptAt pulses in a second + //It's a big question now + _interrupt = interruptAt/(_microsec*240); + +} + + diff --git a/X86TestSupport/TestSupport/StdTimer.h b/X86TestSupport/TestSupport/StdTimer.h new file mode 100644 index 000000000..573952c74 --- /dev/null +++ b/X86TestSupport/TestSupport/StdTimer.h @@ -0,0 +1,44 @@ +#pragma once + +/* Kernel includes. */ +#include +#include +#include +#include + +//typedef Concurrency::concurrent_queue WorkQueue; +typedef std::queue WorkQueue; + +struct hw_timer_s { + virtual ~hw_timer_s() {} +}; +class StdTimer; +void tic_processor(StdTimer &pt, int microsec); + +class StdTimer : public hw_timer_s +{ +public: + StdTimer(uint32_t microsec, uint8_t timer=0, uint16_t divider=1, bool countUp=false); + ~StdTimer(); + void start(); + void set_enable( bool enable); + bool is_enabled(); + void set_pulse_tic(uint64_t interruptAt); + bool is_stop() { return _is_stop; } + uint8_t get_timer_id() { return _timer; } + void set_action(void(*fn)(void)); + void stop() { _is_stop = true; } + uint64_t get_timer_tic() { return _interrupt; } + void do_action(); +public: + bool _is_stop; +private: + uint8_t _timer; + bool _enable; + uint16_t _divider; + bool _countUp; + void (*_action)(void); + uint64_t _interrupt; + int _microsec; +}; + diff --git a/X86TestSupport/TestSupport/driver/uart.h b/X86TestSupport/TestSupport/driver/uart.h index 9b7192685..51c428f4d 100644 --- a/X86TestSupport/TestSupport/driver/uart.h +++ b/X86TestSupport/TestSupport/driver/uart.h @@ -5,6 +5,8 @@ #include "freertos/FreeRTOS.h" #include "esp_err.h" +#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */ + /** * @brief UART mode selection */ diff --git a/X86TestSupport/TestSupport/esp32-hal-timer.cpp b/X86TestSupport/TestSupport/esp32-hal-timer.cpp index e5f491fa6..969bb479f 100644 --- a/X86TestSupport/TestSupport/esp32-hal-timer.cpp +++ b/X86TestSupport/TestSupport/esp32-hal-timer.cpp @@ -1,31 +1,59 @@ #include "esp32-hal-timer.h" +#include "StdTimer.h" + uint32_t g_ticks_per_us_pro = 240 * 1000 * 1000; // For CPU 0 - typically 240 MHz uint32_t g_ticks_per_us_app = 240 * 1000 * 1000; // For CPU 1 - typically 240 MHz -struct hw_timer_s {}; +StdTimer g_timer(10); + -// TODO: These are just stubs. +hw_timer_s* timerBegin(uint8_t timer, uint16_t divider, bool countUp) { + return &g_timer; +} -void timerAlarmEnable(hw_timer_t* timer) {} -void timerAlarmDisable(hw_timer_t* timer) {} -void timerWrite(hw_timer_t* timer, uint64_t val) {} -void timerAlarmWrite(hw_timer_t* timer, uint64_t interruptAt, bool autoreload) {} +void timerEnd(hw_timer_s* timer) +{ + g_timer.stop(); +} -hw_timer_t* timerBegin(uint8_t timer, uint16_t divider, bool countUp) { - return new hw_timer_t(); +void timerAttachInterrupt(hw_timer_s* timer, void (*fn)(void), bool edge) +{ + g_timer.set_action(fn); + g_timer.start(); } -void timerEnd(hw_timer_t* timer) { - delete timer; + + +// TODO: These are just stubs. + +void timerAlarmEnable(hw_timer_t* timer) +{ + g_timer.set_enable(true); +} +void timerAlarmDisable(hw_timer_t* timer) +{ + g_timer.set_enable(false); +} + +void timerWrite(hw_timer_t* timer, uint64_t val) +{ + // timerTicks/sec * 60 sec/minute * minutes = timerTicks +} +void timerAlarmWrite(hw_timer_t* timer, uint64_t interruptAt, bool autoreload) +{ + g_timer.set_pulse_tic(interruptAt); } -void timerAttachInterrupt(hw_timer_t* timer, void (*fn)(void), bool edge) {} -void timerDetachInterrupt(hw_timer_t* timer) {} // Figure this out: extern "C" { esp_err_t esp_task_wdt_reset(void) { return ESP_OK; } + +void vAssertCalled( unsigned long ulLine, const char * const pcFileName ) +{ + +} } diff --git a/config.yaml b/config.yaml new file mode 100644 index 000000000..d859a2f5c --- /dev/null +++ b/config.yaml @@ -0,0 +1,95 @@ +name: "ESP32 Dev Controller V4" +board: "ESP32 Dev Controller V4" + +stepping: + engine: RMT + idle_ms: 250 + dir_delay_us: 1 + pulse_us: 2 + disable_delay_us: 0 + +axes: + shared_stepper_disable_pin: gpio.13:low + + x: + steps_per_mm: 800 + max_rate_mm_per_min: 2000 + acceleration_mm_per_sec2: 25 + max_travel_mm: 1000 + homing: + cycle: 2 + mpos_mm: 10 + positive_direction: false + + motor0: + limit_all_pin: gpio.17:low:pu + stepstick: + direction_pin: gpio.14 + step_pin: gpio.12 + motor1: + null_motor: + + y: + steps_per_mm: 800 + max_rate_mm_per_min: 2000 + acceleration_mm_per_sec2: 25 + max_travel_mm: 1000 + homing: + cycle: 2 + mpos_mm: 10 + positive_direction: false + + motor0: + limit_all_pin: gpio.4:low:pu + stepstick: + direction_pin: gpio.15 + step_pin: gpio.26 + motor1: + null_motor: + + z: + steps_per_mm: 800 + max_rate_mm_per_min: 2000 + acceleration_mm_per_sec2: 25 + max_travel_mm: 1000 + homing: + cycle: 1 + mpos_mm: 10 + positive_direction: true + + motor0: + limit_all_pin: gpio.16:low:pu + stepstick: + direction_pin: gpio.33 + step_pin: gpio.27 + motor1: + null_motor: + +spi: + miso_pin: gpio.19 + mosi_pin: gpio.23 + sck_pin: gpio.18 + +sdcard: + cs_pin: gpio.5 + card_detect_pin: NO_PIN + +coolant: + flood_pin: gpio.25 + mist_pin: gpio.21 + + +probe: + pin: gpio.32:low:pu + +PWM: + pwm_hz: 5000 + output_pin: gpio.2 + enable_pin: gpio.22 + direction_pin: NO_PIN + disable_with_s0: false + s0_with_disable: true + spinup_ms: 0 + spindown_ms: 0 + tool_num: 0 + speed_map: 0=0% 10000=100% diff --git a/screenshots/2022-01-07_12-25-20.png b/screenshots/2022-01-07_12-25-20.png new file mode 100644 index 0000000000000000000000000000000000000000..5a66ad4ffe9daa9802a31cc41cb7e10d9cf33fe4 GIT binary patch literal 30747 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 literal 0 HcmV?d00001 From f7e922f57eedcaab645dff5168b6d4f56c77618f Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:31:48 +0700 Subject: [PATCH 3/7] Move "main" function to separate file and fix code style using clang-format --- FluidNC/src/Main.cpp | 53 +------- FluidNC/src/Protocol.cpp | 4 +- FluidNCConsole.vcxproj | 1 + FluidNCConsole.vcxproj.filters | 3 + X86TestSupport/TestSupport/ComPortX86.cpp | 115 +++++++----------- .../TestSupport/FluidConsoleMain.cpp | 45 +++++++ X86TestSupport/TestSupport/StdTimer.cpp | 46 +++---- config.yaml | 95 --------------- 8 files changed, 119 insertions(+), 243 deletions(-) create mode 100644 X86TestSupport/TestSupport/FluidConsoleMain.cpp delete mode 100644 config.yaml diff --git a/FluidNC/src/Main.cpp b/FluidNC/src/Main.cpp index 64070624b..932b3b1d9 100644 --- a/FluidNC/src/Main.cpp +++ b/FluidNC/src/Main.cpp @@ -197,55 +197,14 @@ void loop() { void WEAK_LINK machine_init() {} -#ifdef FLUIDNC_CONSOLE -#include "ComPortX86.h" -#include "InputFile.h" - - -int main(int argc, char *argv[]){ - - setup(); - - allChannels.deregistration(&Uart0); // USB Serial - allChannels.deregistration(&WebUI::inputBuffer); // Macros - - Channel *pin = nullptr; - Channel *pout = nullptr; - - if (argc == 1) { //console input - pin = new ComPortX86(nullptr); +# if 0 +int main() { + setup(); // setup() + while (1) { // loop() + loop(); } - else if (strncasecmp(argv[1], "COM", 3) == 0) { //com port - pin = new ComPortX86(argv[1]); - } - else { - pout = new ComPortX86(nullptr); // run file from command line, ouput to console - infile = new InputFile("/localfs", argv[1], WebUI::AuthenticationLevel::LEVEL_GUEST, *pout); - readyNext = true; - } - - if (pin) - allChannels.registration(pin); - if (pout) - allChannels.registration(pout); - - if ( config ) - config->_verboseErrors = true; - -// unlock GRBL to easy debugging - do_command_or_setting("X", nullptr, WebUI::AuthenticationLevel::LEVEL_ADMIN, pout != nullptr ? *pout : *pin); - - loop(); - - if (pin) - delete pin; - if ( pout ) - delete pout; - if ( infile ) - delete infile; - return 0; } -#endif +# endif #endif diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index cf16f8bf3..d4878000d 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -199,7 +199,7 @@ void protocol_main_loop() { break; } #ifdef DEBUG_REPORT_ECHO_RAW_LINE_RECEIVED - report_echo_line_received(line, *chan); + report_echo_line_received(line, *chan); #endif display("GCODE", line); // auth_level can be upgraded by supplying a password on the command line @@ -742,7 +742,7 @@ void protocol_exec_rt_system() { if (rtSeq) { rtSeq = false; log_error("planner " << pl_seq0 << " stepper " << st_seq0); - rtReset = true; //rtReset = true; comment this becouse this appear if G0 instruction does not chenge the position + rtReset = true; } if (rtCrash) { diff --git a/FluidNCConsole.vcxproj b/FluidNCConsole.vcxproj index 10fd12bea..494b4cf0e 100644 --- a/FluidNCConsole.vcxproj +++ b/FluidNCConsole.vcxproj @@ -282,6 +282,7 @@ + diff --git a/FluidNCConsole.vcxproj.filters b/FluidNCConsole.vcxproj.filters index 7231911e0..e9b7fca18 100644 --- a/FluidNCConsole.vcxproj.filters +++ b/FluidNCConsole.vcxproj.filters @@ -427,6 +427,9 @@ X86TestSupport + + X86TestSupport + diff --git a/X86TestSupport/TestSupport/ComPortX86.cpp b/X86TestSupport/TestSupport/ComPortX86.cpp index acaa5e58d..a2fa8d761 100644 --- a/X86TestSupport/TestSupport/ComPortX86.cpp +++ b/X86TestSupport/TestSupport/ComPortX86.cpp @@ -3,113 +3,86 @@ #include #include "StdTimer.h" - #define MAX_DEVPATH_LENGTH 1024 -//#define LOCAL_ECHO extern StdTimer g_timer; -ComPortX86::ComPortX86(const char *pPort ) : - hSerial(INVALID_HANDLE_VALUE), Channel("com_win32") -{ - DCB dcb; - BOOL fSuccess; - TCHAR devicePath[MAX_DEVPATH_LENGTH]; +ComPortX86::ComPortX86(const char* pPort) : hSerial(INVALID_HANDLE_VALUE), Channel("com_win32") { + DCB dcb; + BOOL fSuccess; + TCHAR devicePath[MAX_DEVPATH_LENGTH]; COMMTIMEOUTS commTimeout; - if (pPort != NULL) - { + if (pPort != NULL) { mbstowcs_s(NULL, devicePath, MAX_DEVPATH_LENGTH, pPort, strlen(pPort)); - hSerial = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, NULL); + hSerial = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); } - if (hSerial != INVALID_HANDLE_VALUE) - { + if (hSerial != INVALID_HANDLE_VALUE) { // Initialize the DCB structure. SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); - fSuccess = GetCommState(hSerial, &dcb); - if (!fSuccess) - { + fSuccess = GetCommState(hSerial, &dcb); + if (!fSuccess) { CloseHandle(hSerial); hSerial = INVALID_HANDLE_VALUE; return; } GetCommState(hSerial, &dcb); - dcb.BaudRate = CBR_115200; // baud rate - dcb.ByteSize = 8; // data size, xmit and rcv - dcb.Parity = NOPARITY; // parity bit - dcb.StopBits = ONESTOPBIT; // stop bit - dcb.fBinary = TRUE; - dcb.fParity = TRUE; + dcb.BaudRate = CBR_115200; // baud rate + dcb.ByteSize = 8; // data size, xmit and rcv + dcb.Parity = NOPARITY; // parity bit + dcb.StopBits = ONESTOPBIT; // stop bit + dcb.fBinary = TRUE; + dcb.fParity = TRUE; fSuccess = SetCommState(hSerial, &dcb); - if (!fSuccess) - { + if (!fSuccess) { CloseHandle(hSerial); hSerial = INVALID_HANDLE_VALUE; return; } GetCommTimeouts(hSerial, &commTimeout); - commTimeout.ReadIntervalTimeout = 1; - commTimeout.ReadTotalTimeoutConstant = 1; - commTimeout.ReadTotalTimeoutMultiplier = 1; - commTimeout.WriteTotalTimeoutConstant = 1; + commTimeout.ReadIntervalTimeout = 1; + commTimeout.ReadTotalTimeoutConstant = 1; + commTimeout.ReadTotalTimeoutMultiplier = 1; + commTimeout.WriteTotalTimeoutConstant = 1; commTimeout.WriteTotalTimeoutMultiplier = 1; SetCommTimeouts(hSerial, &commTimeout); } } -ComPortX86::ComPortX86() : - Channel("com_win32"), hSerial(INVALID_HANDLE_VALUE) -{ } - -ComPortX86::~ComPortX86() -{ +ComPortX86::ComPortX86() : Channel("com_win32"), hSerial(INVALID_HANDLE_VALUE) {} -} +ComPortX86::~ComPortX86() {} -int ComPortX86::read() -{ -DWORD dwBytesRead; -uint8_t data; -int ret =-1; +int ComPortX86::read() { + DWORD dwBytesRead; + uint8_t data; + int ret = -1; -if (hSerial != INVALID_HANDLE_VALUE ) -{ - if (ReadFile(hSerial, &data, 1, &dwBytesRead, NULL) && dwBytesRead == 1) - { - ret = static_cast(data); - } -} -else -{ - if (_kbhit()) - { - ret = _getch(); - char c = static_cast(ret); - std::cout << c; - if ( c== 10 || c == 13 ) - std::cout << "\n"; + if (hSerial != INVALID_HANDLE_VALUE) { + if (ReadFile(hSerial, &data, 1, &dwBytesRead, NULL) && dwBytesRead == 1) { + ret = static_cast(data); + } + } else { + if (_kbhit()) { + ret = _getch(); + char c = static_cast(ret); + std::cout << c; + if (c == 10 || c == 13) + std::cout << "\n"; + } } -} - return ret; + return ret; } -size_t ComPortX86::write(uint8_t c) -{ - DWORD dwBytesWritten = 1; - if (hSerial != INVALID_HANDLE_VALUE) - { +size_t ComPortX86::write(uint8_t c) { + DWORD dwBytesWritten = 1; + if (hSerial != INVALID_HANDLE_VALUE) { WriteFile(hSerial, &c, 1, &dwBytesWritten, NULL); - } - else - { - std::cout << c; - + } else { + std::cout << c; } return dwBytesWritten; } - - diff --git a/X86TestSupport/TestSupport/FluidConsoleMain.cpp b/X86TestSupport/TestSupport/FluidConsoleMain.cpp new file mode 100644 index 000000000..8a72f3756 --- /dev/null +++ b/X86TestSupport/TestSupport/FluidConsoleMain.cpp @@ -0,0 +1,45 @@ +#include "src/Serial.h" +#include "src/Settings.h" +#include "src/InputFile.h" +#include "src/Uart.h" +#include "src/Machine/MachineConfig.h" +#include "ComPortX86.h" + +extern void setup(); +extern void loop(); + +int main(int argc, char* argv[]) { + setup(); + + // Remove Uart and Web chanalls + allChannels.deregistration(&Uart0); + allChannels.deregistration(&WebUI::inputBuffer); + + std::unique_ptr pin; + std::unique_ptr pout; + + if (argc == 1) { //console input + pin = std::make_unique(nullptr); + } else if (strncasecmp(argv[1], "COM", 3) == 0) { // com port + pin = std::make_unique(argv[1]); + } else { + pout = std::make_unique(nullptr); // run file from command line, ouput to console + infile = new InputFile("/localfs", argv[1], WebUI::AuthenticationLevel::LEVEL_GUEST, *pout); + readyNext = true; + } + + if (pin) + allChannels.registration(pin.get()); + if (pout) + allChannels.registration(pout.get()); + + if (config) + config->_verboseErrors = true; + + // Unlock GRBL for easy debugging + do_command_or_setting("X", nullptr, WebUI::AuthenticationLevel::LEVEL_ADMIN, pout != nullptr ? *pout : *pin); + + loop(); + + return 0; +} diff --git a/X86TestSupport/TestSupport/StdTimer.cpp b/X86TestSupport/TestSupport/StdTimer.cpp index 003bb9042..d2ad6897c 100644 --- a/X86TestSupport/TestSupport/StdTimer.cpp +++ b/X86TestSupport/TestSupport/StdTimer.cpp @@ -1,12 +1,9 @@ #include "StdTimer.h" #include - - -void tic_processor(StdTimer &pt, int microsec) -{ - int tmp_rubs_for_move = 0; - uint64_t cur_period = 0; +void tic_processor(StdTimer& pt, int microsec) { + int tmp_rubs_for_move = 0; + uint64_t cur_period = 0; for (;;) { if (pt.is_stop()) { @@ -14,23 +11,20 @@ void tic_processor(StdTimer &pt, int microsec) } if (cur_period >= pt.get_timer_tic()) { cur_period = 0; - if (pt.is_enabled()) - { + if (pt.is_enabled()) { pt.do_action(); } } cur_period++; std::this_thread::sleep_for(std::chrono::microseconds(microsec)); - } + } } - StdTimer::StdTimer(uint32_t microsec, uint8_t timer, uint16_t divider, bool countUp) : - _microsec(microsec), _timer(timer), _divider(divider), _countUp(countUp), _action(0), _is_stop(true), - _enable(false),_interrupt(0) { + _microsec(microsec), _timer(timer), _divider(divider), _countUp(countUp), _action(0), _is_stop(true), _enable(false), _interrupt(0) { /* Create the queue. */ } -StdTimer::~StdTimer(){ +StdTimer::~StdTimer() { stop(); } @@ -42,35 +36,31 @@ void StdTimer::start() { std::thread(tic_processor, std::ref(*this), _microsec).detach(); } - -void StdTimer::do_action() -{ +void StdTimer::do_action() { #ifdef FLUIDNC_CONSOLE_DEBUG_TIMER static int pulse_count = 0; std::cout << pulse_count << " puls\n"; pulse_count++; #endif - if ( _action ) - _action(); + if (_action) + _action(); } void StdTimer::set_enable(bool enable) { - _enable = enable; + _enable = enable; } bool StdTimer::is_enabled() { - return _enable; + return _enable; } void StdTimer::set_action(void (*fn)(void)) { - _action = fn; -} -void StdTimer::set_pulse_tic(uint64_t interruptAt) -{ - // interruptAt pulses in a second - //It's a big question now - _interrupt = interruptAt/(_microsec*240); - + _action = fn; } +// interruptAt pulses in a second +// It's a big question now +void StdTimer::set_pulse_tic(uint64_t interruptAt) { + _interrupt = interruptAt / (_microsec * 240); +} diff --git a/config.yaml b/config.yaml deleted file mode 100644 index d859a2f5c..000000000 --- a/config.yaml +++ /dev/null @@ -1,95 +0,0 @@ -name: "ESP32 Dev Controller V4" -board: "ESP32 Dev Controller V4" - -stepping: - engine: RMT - idle_ms: 250 - dir_delay_us: 1 - pulse_us: 2 - disable_delay_us: 0 - -axes: - shared_stepper_disable_pin: gpio.13:low - - x: - steps_per_mm: 800 - max_rate_mm_per_min: 2000 - acceleration_mm_per_sec2: 25 - max_travel_mm: 1000 - homing: - cycle: 2 - mpos_mm: 10 - positive_direction: false - - motor0: - limit_all_pin: gpio.17:low:pu - stepstick: - direction_pin: gpio.14 - step_pin: gpio.12 - motor1: - null_motor: - - y: - steps_per_mm: 800 - max_rate_mm_per_min: 2000 - acceleration_mm_per_sec2: 25 - max_travel_mm: 1000 - homing: - cycle: 2 - mpos_mm: 10 - positive_direction: false - - motor0: - limit_all_pin: gpio.4:low:pu - stepstick: - direction_pin: gpio.15 - step_pin: gpio.26 - motor1: - null_motor: - - z: - steps_per_mm: 800 - max_rate_mm_per_min: 2000 - acceleration_mm_per_sec2: 25 - max_travel_mm: 1000 - homing: - cycle: 1 - mpos_mm: 10 - positive_direction: true - - motor0: - limit_all_pin: gpio.16:low:pu - stepstick: - direction_pin: gpio.33 - step_pin: gpio.27 - motor1: - null_motor: - -spi: - miso_pin: gpio.19 - mosi_pin: gpio.23 - sck_pin: gpio.18 - -sdcard: - cs_pin: gpio.5 - card_detect_pin: NO_PIN - -coolant: - flood_pin: gpio.25 - mist_pin: gpio.21 - - -probe: - pin: gpio.32:low:pu - -PWM: - pwm_hz: 5000 - output_pin: gpio.2 - enable_pin: gpio.22 - direction_pin: NO_PIN - disable_with_s0: false - s0_with_disable: true - spinup_ms: 0 - spindown_ms: 0 - tool_num: 0 - speed_map: 0=0% 10000=100% From 1caa93ada7bfafef5b7ab783251af9acebd7b3f1 Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:45:56 +0700 Subject: [PATCH 4/7] small formatting fix --- FluidNC/src/Protocol.cpp | 1 - X86TestSupport/TestSupport/ComPortX86.h | 18 +++++----- X86TestSupport/TestSupport/StdTimer.cpp | 2 +- X86TestSupport/TestSupport/StdTimer.h | 44 ++++++++++--------------- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/FluidNC/src/Protocol.cpp b/FluidNC/src/Protocol.cpp index d4878000d..ce1ac73cd 100644 --- a/FluidNC/src/Protocol.cpp +++ b/FluidNC/src/Protocol.cpp @@ -743,7 +743,6 @@ void protocol_exec_rt_system() { rtSeq = false; log_error("planner " << pl_seq0 << " stepper " << st_seq0); rtReset = true; - } if (rtCrash) { rtCrash = false; diff --git a/X86TestSupport/TestSupport/ComPortX86.h b/X86TestSupport/TestSupport/ComPortX86.h index 24e8a12da..e5fc1e44f 100644 --- a/X86TestSupport/TestSupport/ComPortX86.h +++ b/X86TestSupport/TestSupport/ComPortX86.h @@ -2,20 +2,18 @@ #include "src/Channel.h" #include -class ComPortX86 : public Channel -{ +class ComPortX86 : public Channel { public: - ComPortX86(const char *pPort); + ComPortX86(const char* pPort); ComPortX86(); ~ComPortX86(); virtual size_t write(uint8_t c) override; - virtual int read() override; - virtual int available() { return true; } - virtual int peek() { return 0; } - virtual void flush() { return; } - virtual int rx_buffer_available() { return 0; } -private: + virtual int read() override; + virtual int available() { return true; } + virtual int peek() { return 0; } + virtual void flush() { return; } + virtual int rx_buffer_available() { return 0; } +private: HANDLE hSerial; }; - diff --git a/X86TestSupport/TestSupport/StdTimer.cpp b/X86TestSupport/TestSupport/StdTimer.cpp index d2ad6897c..b5865178a 100644 --- a/X86TestSupport/TestSupport/StdTimer.cpp +++ b/X86TestSupport/TestSupport/StdTimer.cpp @@ -1,4 +1,5 @@ #include "StdTimer.h" +#include #include void tic_processor(StdTimer& pt, int microsec) { @@ -60,7 +61,6 @@ void StdTimer::set_action(void (*fn)(void)) { // interruptAt pulses in a second // It's a big question now - void StdTimer::set_pulse_tic(uint64_t interruptAt) { _interrupt = interruptAt / (_microsec * 240); } diff --git a/X86TestSupport/TestSupport/StdTimer.h b/X86TestSupport/TestSupport/StdTimer.h index 573952c74..fa874c372 100644 --- a/X86TestSupport/TestSupport/StdTimer.h +++ b/X86TestSupport/TestSupport/StdTimer.h @@ -2,43 +2,35 @@ /* Kernel includes. */ #include -#include -#include -#include - -//typedef Concurrency::concurrent_queue WorkQueue; -typedef std::queue WorkQueue; struct hw_timer_s { - virtual ~hw_timer_s() {} + virtual ~hw_timer_s() {} }; -class StdTimer; -void tic_processor(StdTimer &pt, int microsec); -class StdTimer : public hw_timer_s -{ +class StdTimer : public hw_timer_s { public: - StdTimer(uint32_t microsec, uint8_t timer=0, uint16_t divider=1, bool countUp=false); + StdTimer(uint32_t microsec, uint8_t timer = 0, uint16_t divider = 1, bool countUp = false); ~StdTimer(); - void start(); - void set_enable( bool enable); - bool is_enabled(); - void set_pulse_tic(uint64_t interruptAt); - bool is_stop() { return _is_stop; } - uint8_t get_timer_id() { return _timer; } - void set_action(void(*fn)(void)); - void stop() { _is_stop = true; } + void start(); + void set_enable(bool enable); + bool is_enabled(); + void set_pulse_tic(uint64_t interruptAt); + bool is_stop() { return _is_stop; } + uint8_t get_timer_id() { return _timer; } + void set_action(void (*fn)(void)); + void stop() { _is_stop = true; } uint64_t get_timer_tic() { return _interrupt; } - void do_action(); + void do_action(); + public: bool _is_stop; + private: - uint8_t _timer; - bool _enable; + uint8_t _timer; + bool _enable; uint16_t _divider; - bool _countUp; + bool _countUp; void (*_action)(void); uint64_t _interrupt; - int _microsec; + int _microsec; }; - From 85f51612ab4c0ffa173a599385238849e1e982da Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Mon, 10 Jan 2022 13:01:03 +0700 Subject: [PATCH 5/7] small formating fixes --- .../TestSupport/esp32-hal-timer.cpp | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/X86TestSupport/TestSupport/esp32-hal-timer.cpp b/X86TestSupport/TestSupport/esp32-hal-timer.cpp index 969bb479f..cbf6911cd 100644 --- a/X86TestSupport/TestSupport/esp32-hal-timer.cpp +++ b/X86TestSupport/TestSupport/esp32-hal-timer.cpp @@ -1,59 +1,43 @@ #include "esp32-hal-timer.h" #include "StdTimer.h" - uint32_t g_ticks_per_us_pro = 240 * 1000 * 1000; // For CPU 0 - typically 240 MHz uint32_t g_ticks_per_us_app = 240 * 1000 * 1000; // For CPU 1 - typically 240 MHz StdTimer g_timer(10); - hw_timer_s* timerBegin(uint8_t timer, uint16_t divider, bool countUp) { return &g_timer; } -void timerEnd(hw_timer_s* timer) -{ - g_timer.stop(); +void timerEnd(hw_timer_s* timer) { + g_timer.stop(); } -void timerAttachInterrupt(hw_timer_s* timer, void (*fn)(void), bool edge) -{ - g_timer.set_action(fn); - g_timer.start(); +void timerAttachInterrupt(hw_timer_s* timer, void (*fn)(void), bool edge) { + g_timer.set_action(fn); + g_timer.start(); } - - -// TODO: These are just stubs. - -void timerAlarmEnable(hw_timer_t* timer) -{ +void timerAlarmEnable(hw_timer_t* timer) { g_timer.set_enable(true); } -void timerAlarmDisable(hw_timer_t* timer) -{ +void timerAlarmDisable(hw_timer_t* timer) { g_timer.set_enable(false); } -void timerWrite(hw_timer_t* timer, uint64_t val) -{ - // timerTicks/sec * 60 sec/minute * minutes = timerTicks +void timerWrite(hw_timer_t* timer, uint64_t val) { + // timerTicks/sec * 60 sec/minute * minutes = timerTicks } -void timerAlarmWrite(hw_timer_t* timer, uint64_t interruptAt, bool autoreload) -{ +void timerAlarmWrite(hw_timer_t* timer, uint64_t interruptAt, bool autoreload) { g_timer.set_pulse_tic(interruptAt); } - // Figure this out: extern "C" { esp_err_t esp_task_wdt_reset(void) { return ESP_OK; } -void vAssertCalled( unsigned long ulLine, const char * const pcFileName ) -{ - -} +void vAssertCalled(unsigned long ulLine, const char* const pcFileName) {} } From b7e109027fe5ec105ceb0bf56ab00fe348335344 Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Mon, 10 Jan 2022 13:11:46 +0700 Subject: [PATCH 6/7] small style changes --- X86TestSupport/TestSupport/esp32-hal-timer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/X86TestSupport/TestSupport/esp32-hal-timer.cpp b/X86TestSupport/TestSupport/esp32-hal-timer.cpp index cbf6911cd..06f7d33ca 100644 --- a/X86TestSupport/TestSupport/esp32-hal-timer.cpp +++ b/X86TestSupport/TestSupport/esp32-hal-timer.cpp @@ -3,8 +3,9 @@ uint32_t g_ticks_per_us_pro = 240 * 1000 * 1000; // For CPU 0 - typically 240 MHz uint32_t g_ticks_per_us_app = 240 * 1000 * 1000; // For CPU 1 - typically 240 MHz +uint32_t g_internal_timer_ticks_in_us = 10; -StdTimer g_timer(10); +StdTimer g_timer(g_internal_timer_ticks_in_us); hw_timer_s* timerBegin(uint8_t timer, uint16_t divider, bool countUp) { return &g_timer; From 016eb5460e358ebf6e9e31064b056a1ee9c72682 Mon Sep 17 00:00:00 2001 From: Boris Berkhin <46570216+bberkhin@users.noreply.github.com> Date: Mon, 10 Jan 2022 16:32:40 +0700 Subject: [PATCH 7/7] fix period of stepper timer --- X86TestSupport/TestSupport/StdTimer.cpp | 11 ++++------- X86TestSupport/TestSupport/esp32-hal-timer.cpp | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/X86TestSupport/TestSupport/StdTimer.cpp b/X86TestSupport/TestSupport/StdTimer.cpp index b5865178a..19ffa2fd3 100644 --- a/X86TestSupport/TestSupport/StdTimer.cpp +++ b/X86TestSupport/TestSupport/StdTimer.cpp @@ -17,14 +17,13 @@ void tic_processor(StdTimer& pt, int microsec) { } } cur_period++; - std::this_thread::sleep_for(std::chrono::microseconds(microsec)); + std::this_thread::sleep_for(std::chrono::nanoseconds(microsec)); } } StdTimer::StdTimer(uint32_t microsec, uint8_t timer, uint16_t divider, bool countUp) : - _microsec(microsec), _timer(timer), _divider(divider), _countUp(countUp), _action(0), _is_stop(true), _enable(false), _interrupt(0) { - /* Create the queue. */ -} + _microsec(microsec), _timer(timer), _divider(divider), _countUp(countUp), _action(0), _is_stop(true), _enable(false), _interrupt(0) {} + StdTimer::~StdTimer() { stop(); } @@ -59,8 +58,6 @@ void StdTimer::set_action(void (*fn)(void)) { _action = fn; } -// interruptAt pulses in a second -// It's a big question now void StdTimer::set_pulse_tic(uint64_t interruptAt) { - _interrupt = interruptAt / (_microsec * 240); + _interrupt = interruptAt; // interruptAt / (_microsec * 100); } diff --git a/X86TestSupport/TestSupport/esp32-hal-timer.cpp b/X86TestSupport/TestSupport/esp32-hal-timer.cpp index 06f7d33ca..ac9489c33 100644 --- a/X86TestSupport/TestSupport/esp32-hal-timer.cpp +++ b/X86TestSupport/TestSupport/esp32-hal-timer.cpp @@ -1,11 +1,12 @@ #include "esp32-hal-timer.h" #include "StdTimer.h" +#include "src/Stepping.h" -uint32_t g_ticks_per_us_pro = 240 * 1000 * 1000; // For CPU 0 - typically 240 MHz -uint32_t g_ticks_per_us_app = 240 * 1000 * 1000; // For CPU 1 - typically 240 MHz -uint32_t g_internal_timer_ticks_in_us = 10; +uint32_t g_ticks_per_us_pro = 240 * 1000 * 1000; // For CPU 0 - typically 240 MHz +uint32_t g_ticks_per_us_app = 240 * 1000 * 1000; // For CPU 1 - typically 240 MHz +uint32_t g_internal_timer_us = 1000000000L / Machine::Stepping::fStepperTimer; -StdTimer g_timer(g_internal_timer_ticks_in_us); +StdTimer g_timer(g_internal_timer_us); hw_timer_s* timerBegin(uint8_t timer, uint16_t divider, bool countUp) { return &g_timer; @@ -27,11 +28,12 @@ void timerAlarmDisable(hw_timer_t* timer) { g_timer.set_enable(false); } -void timerWrite(hw_timer_t* timer, uint64_t val) { - // timerTicks/sec * 60 sec/minute * minutes = timerTicks -} +void timerWrite(hw_timer_t* timer, uint64_t val) {} + +// interruptAt timerTicks/step or ticks between steps +// Machine::fStepperTimer/interruptAt void timerAlarmWrite(hw_timer_t* timer, uint64_t interruptAt, bool autoreload) { - g_timer.set_pulse_tic(interruptAt); + g_timer.set_pulse_tic(interruptAt / 100); } // Figure this out: