Added some HAL entry points and properties for pin handling, $pins system command (not all drivers) and some minor bug fixes.

This commit is contained in:
Terje Io
2021-06-06 22:27:47 +02:00
parent edd243ac8a
commit 3a84b58d30
22 changed files with 786 additions and 64 deletions

View File

@@ -11,7 +11,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
Latest build date is 20210223, see the [changelog](https://github.com/terjeio/grblHAL/blob/master/changelog.md) for details.
Latest build date is 20210604, see the [changelog](changelog.md) for details.
---
@@ -20,7 +20,7 @@ __NOTE:__ Arduino drivers has now been converted to Arduino libraries, [installa
---
grblHAL is a no-compromise, high performance, low cost alternative to parallel-port-based motion control for CNC milling and is based on the [Arduino version of grbl](https://github.com/gnea/grbl). It is mainly aimed at ARM processors \(or other 32-bit MCUs\) with ample amounts of RAM and flash \(compared to AVR 328p\) and requires a [hardware driver](https://github.com/grblHAL/drivers) to be functional.
Currently drivers are available for 13 different processors/processor families all of which share the same core.
Currently drivers are available for more than 15 different processors/processor families all of which share the same core codebase.
grblHAL has an open architecture allowing [plugins](https://github.com/grblHAL/plugins) to extend functionality.
User made plugins can be added to grblHAL without changing a single file in the source<sup>1</sup>, and allows for a wide range extensions to be added.
@@ -34,7 +34,7 @@ It is able to maintain up to 300kHz<sup>3</sup> of stable, jitter free control p
It accepts standards-compliant g-code and has been tested with the output of several CAM tools with no problems. Arcs, circles and helical motion are fully supported, as well as, all other primary g-code commands. Macro functions, variables, and some canned cycles are not supported, but we think GUIs can do a much better job at translating them into straight g-code anyhow.
Grbl includes full acceleration management with look ahead. That means the controller will look up to 16 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering.
Grbl includes full acceleration management with look ahead. That means the controller will look up motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering.
This is a port/rewrite of [grbl 1.1f](https://github.com/gnea/grbl) and should be compatible with GCode senders compliant with the specifications for that version. It should be possible to change default compile-time configurations if problems arise, eg. the default serial buffer sizes has been increased in some of the [drivers](https://github.com/grblHAL/drivers) provided.
@@ -77,4 +77,4 @@ List of Supported G-Codes:
```
---
2021-04-05
2021-06-06

305
changelog.md Normal file
View File

@@ -0,0 +1,305 @@
## grblHAL changelog
Build 20210604:
* Added some HAL entry points and properties, shared file for mapped step and dir output.
* Added `$pins` system command, for listing current pin assignments. Work in progress, only supported by a couple of drivers.
* Some minor bugs fixed.
Build 20210515:
* Fixed G43 "bug" by changing to LinuxCNC specification. NIST specification is ambiguous.
* Added acceleration override handling, to be used by OpenPNP plugin M-code.
Build 20210505:
* Some bug fixes: relative canned cycles repeat error, comment handling...
* Check mode changes to allow use with SD card streaming.
* Internal buffer changes for reducing RAM footprint. Some HAL extensions.
Build 20210314:
* Added support for tool change protocol to networking protocols using shared stream buffer.
* Added `$S` system command for toggling single step mode, when enabled cycle start has to be issued after each block.
* Some bug fixes.
Build 20210207:
* Added `#define BOARD_MY_MACHINE` option in _my_machine.h_ for building using _my_machine-map.c_, this for simpler handling of user defined pin mappings.
_my_machine-map.c_ is __*not*__ part of the distributed source and must by added to the project by the user before enabled, typically by copying an existing map file.
* Added HAL layer on top of Trinamic driver low-level code. Unified Triniamic plugins into single plugin.
This is still work in progress, testers wanted.
* Added core support for up to four limit switches per axis.
Added `$LEV` command for outputting report containing which limit or control switch(es) caused the last event.
Report format:
`[LASTEVENTS:<control signals>,<min>,<max>,<min2>,<max2)]`
Where `<control signals>` field may contain controls signal letters (`H`, `S` etc.) and the rest axis letters for the corresponding limit switches inputs.
* More settings susbsystem changes and refactored $-system commands parser.
There are some API changes related to this that may affect user defined plugins.
* Added $7 setting for option "Spindle off with zero speed".
* Added `|FW:grblHAL` element to full real-time report requested by sending `0x87`.
* Simplified settings handling.
* No longer sends any messages to networking streams on connect.
* Added [driver](drivers/STM32F3xx) for STM32F303 based Blackpills.
* Updated support for Trinamic TMC5160 drivers, currently for the SKR 1.x boards \(LPC176x driver\) - testing i progress.
* Initial support for Trinamic TMC5160 drivers added, currently for the SKR 1.x boards \(LPC176x driver\) - not yet tested.
* Added handling for motor fault signal to the core, similar to E-stop handling. Added new alarm and error code for this.
* Changed to clear homed status on a soft reset only if machine was in motion. Added setting flag for always keeping homed status on soft reset to `$22` setting.
__NOTE:__ This change is experimental and might be changed or reverted. Please report any problems related to this.
* Updated gcode parser \(grbl/gcode.c\) to use bitfields structs instead of bitfield variables.
Done to improve readability and for easier debugging.
Note that this is a major change and there is a non-zero risk that mistakes has been made.
* Changed signature of user mcode validation function to use a bitfield union for value words available.
Removed the need for user mcode parameter words to have an associated value. This means that [user mcode](https://github.com/terjeio/grblHAL/tree/test/templates) implementations now must check this locally.
If no associated value is provided the corresponding value in the value struct is set to `NAN` (Not A Number) for floats and all bits set to 1 for integers.
* Refactored Trinamic driver code, added initial support for TMC2209. Work in progress.
* Removed the need to copy the core grbl and plugin code to the driver chosen, this is now kept in sync with the master Subversion repository automatically.
* Added initial support for RADDS 1.6 board to SAM3X8E driver \(Arduino Due\). Untested!
* Added C-axis support to iMXRT1062 driver \(Teensy 4.x\).
Untested and none of the current board maps has the needed pins defined.
* Added alarm and error message for power on self-test \(POS\) failure.
If POS fails only $-commands are accepted.
* Work in good progress for Trinamic TMC2209 driver support \(UART mode\).
Processor/board specific driver code has to be added for this, currently testing with STM32F446 and Nucleo-64 breakout board.
* Renumbered setting groups for more logical sorting (by id).
* Harmonized probing code across drivers for planned future extensions.
* Added additional I/O support for the [Teensy 4.1 T41U5XBB board](https://github.com/phil-barrett/grbl-teensy-4) \(iMXRT1062 driver\), 3 outputs and 4 inputs available via `M62` - `M66`.
Not that the result from reading inputs with `M66` cannot be used in a gcode program in any meaningful way.
* Fixed excessive step pulse jitter in STM32F4xx driver.
* Added [more options](https://github.com/terjeio/grblHAL/wiki/Report-extensions#controller-information-extensions) to the `NEWOPT` tag in the extended `$I` report.
* Error 7 is no longer issued on startup if non-volatile storage \(Flash/EEPROM/FRAM\) for settings is not available.
* [Alarm substate](https://github.com/terjeio/grblHAL/wiki/Report-extensions#realtime-report) \(if available\) is always added to the real-time report if a [complete report](https://github.com/terjeio/grblHAL/wiki/For-sender-developers#single-character-real-time-commands) is requested by sending `0x87`.
* Added input signal and handling for limit switches override.
The pin is pulled high and requires a normally open \(NO\) push switch for operation. When closed limit pins are excluded from the status report and alarm 12 will not be raised if a limit switch is asserted _on a soft reset_ when "Hard limits" and "Strict mode" is enabled with `$21`.
This allows normal operation so that a manual pull-off can be done before e.g. homing the machine.
Currently only the iMXRT1062 \(Teensy 4.x\) driver has support for this, for now by reassigning the safety door input when this is not used for its intended purpose.
__NOTE:__ A override will _not_ affect handling of homing and limit switch events elsewhere.
* Now adds `ODO` to `NEWOPT` tag values if odometer data is available.
* Updated _[my_plugin.c](templates/my_plugin.c)_ [template](templates/README.md) with settings details for `$HELP` and `$ES`/`$EG` enumerations.
* Settings/setting groups handling enhanced, moved some to plugins and added sorting (requres enough heap).
* Removed external dependecies by adding driver source/USB blob to LPC176x driver.
* Enhanced and improved ModBus support code for VFD spindle, added settings for baud rate and receive timeout.
* Added support for enumeration of and help for driver and plugin provided settings and setting groups.
* Moved board selection etc. to [CMakeLists.txt](drivers/ESP32/CMakeLists.txt) for [ESP32 driver](drivers/ESP32/README.md) for simpler configuration.
* Fixed regression for VFD spindle code, should now be able to run tests.
* Added build configurations for processor variants and Nucleo-64 boards for the [STM32F4xx driver](drivers/STM32F4xx/README.md).
* Added initial board map file for [BTT SKR 1.4 Turbo board](https://www.bigtree-tech.com/products/btt-skr-v1-4-skr-v1-4-turbo-32-bit-control-board.html) to the [LPC176x driver](drivers/LPC1769/README.md) including build configuration for bootloader compatible executable.
* Added polling of limit switches to the LPC176x driver, enabling hard limits is now possible.
* Added `$` commands for getting details about alarm codes, error codes, settings and settings groups.
`$EA` - enumerate alarm codes.
`$EE` - enumerate error codes.
`$ES` - enumerate settings.
`$EG` - enumerate setting groups.
`$E*` - enumerate all above.
The output from these is intended for sender developers and can be used instead of loading this information from .csv files.
The settings enumeration contains additional information such as group assignment, datatype and format, value list for bitfields, min allowed value and max allowed value.
For now descriptions of the settings are not included.
__NOTE:__ This is a preview version, format and group codes may change for settings and setting groups.
* Added `$HELP` command and `$$<n>` command for listing information about a specific setting.
`$HELP` on its own prints arguments that can be used with `$HELP`.
`$HELP Commands` - print `$` commands available with a short description.
`$HELP Settings` - print information about all available settings.
`$HELP <argument>` print information about settings from the setting group provided in `<argument>`. E.g. `$HELP Spindle` will print information about spindle settings.
__NOTE:__ do _NOT_ issue these commands from a sender MDI as the output may crash it, output is in plaintext and thus intended for use from a terminal only.
__NOTE:__ Settings data format has been changed and settings will be reset to default on update. Backup and restore.
* Moved `#define` values to settings for auto square failure distances:
`$347` - default value from `DUAL_AXIS_HOMING_FAIL_AXIS_LENGTH_PERCENT` \(5%\) in grbl/config.h.
`$348` - default value from `DUAL_AXIS_HOMING_FAIL_DISTANCE_MIN` \(2.5mm\) in grbl/config.h.
`$349` - default value from `DUAL_AXIS_HOMING_FAIL_DISTANCE_MAX` \(25mm\) in grbl/config.h.
* Added settings and functionality for moving the second axis up to &plusmn;2mm after successful auto squaring to compensate for any switch alignment error.
The settings is per axis, `$17n` where `n` is the axis index: `n` = `0` -> X axis, `1` -> Y axis, ...
Note that settings values will only be reported for axes with dual motors installed and configured for auto squaring.
* Added setting `$345` for pull-off rate from tool length sensor used for tool change. Default value is 100mm/min.
* Added setting flag to `$10` for enabling override of _Homing on startup required_ \(if enabled\) by a soft reset.
* Blocked loophole where machine could be unlocked by issuing a single axis homing command when _Homing on startup required_ is enabled.
Alarm 11 will now be reissued until all axes configured for homing are homed.
* Added software debounce for the safety door switch to STM32 drivers.
* "Hardened" parking functionality. It should now tolerate a bouncy door switch and multiple closing/reopenings of the door during retract/restore.
__NOTE:__ Not extensively tested. Use with care!
* Added `$I+` system command. This can be used when [compatibility level](https://github.com/terjeio/grblHAL/wiki/Compatibility-level) is > 0 to get the extended version including the current compatibility setting.
* Added basic support for separating limit switches from homing switches in the core. If a driver does not handle separate inputs for these the core "connects" the homing switches to the limit switches in code.
* Improved auto squaring. If a limit switch is engaged when homing starts the axis will be moved pull-off distance * 5 away from them. If still engaged homing will fail.
__NOTE:__ Auto squaring is currently only tested with a simulator. Use with care!
Build 20201103:
* Added data structures for spindle encoder/spindle sync to the core. Used by drivers supporting spindle sync.
* Updated spindle sync code for MSP432 and added spindle sync capability to iMXRT1060 and STM32F4xx drivers.
__NOTE:__ Spindle sync support is still in alpha stage! The current code has only been tested with a simulator.
* Fixed bug that could lead to settings storage area fail to reinitialize properly when corrupted.
* Moved some symbols in preparation for adding $-settings for them.
* Improved rewind capability (on `M2`) of SD card plugin. Added `$` command for dumping SD card file contents to output stream.
Build 20201020:
__NOTE:__ Settings data format has been changed and settings will be reset to default on update. Backup and restore.
* Added support for STM32F446 based Nucleo-64 boards to STM32F4xx driver.
* Fix for regression that set laser mode as default - `$32=1`. Check that this is correct after restoring settings from backup.
* Added new settings option `$341=4` for ignoring `M6` tool change command.
* Bug fix for `M61Q0` - returned error previously.
* Changed clearing of tool length offset reference on homing to be done only if relevant axis is/axes are homed.
* Fixed check for running startup scripts on homing to check that all axes configured for homing are actually homed.
* Changes to message display from `(MSG,..)` comments in gcode.
`(MSG,..)` strings will be sent back to the sender in sync with gcode execution.
* Added `*` prefix to NVS storage type in `$I` report if buffered, e.g: `[NEWOPT:*EEPROM,ES,TC]`
* Increased heap allocation for nearly all drivers.
Memory from heap is used for the NVS buffer and for temporary storage of `(MSG,..)` strings.
* Added option for adding substates to the `Run` state in the real time report to `$11` setting \(bit 11\).
If enabled `Run:2` will be reported when a probing motion is ongoing, this can be used by senders to provide a simple probe protection scheme.
* Another refactoring of the settings subsystem, this time for handling plugin settings.
Plugins settings storage space is now dynamically allocated and handled locally by the plugin code, this allows user defined plugins to add settings too!
Ten setting codes are reserved for user defined plugins.
* Added template for [basic plugin with two settings](templates/README.md).
* HAL pointers refactored for code readability, many moved to separate structures for each subsystem. Added typedefs.
* Some minor bug fixes and other code readability improvements. Prepared for switch to 16-bit CRC for settings data validation.
Build 20200923:
* Added support for STM32F411 based Blackpill boards to STM32F4xx driver.
* Initial changes to ESP32 driver to allow compilation with PlatformIO, added my_machine.h for this. Note that my_machine.h is not used if compiling with idf.py.
* Added home position to `$#` ngc report, e.g. `[HOME,0.000,0.000,0.000:7]` - means all axes are homed. Position is reported in machine coordinates. `:7` in the example is an axis bitfield, the reported value is for which axes are homed: bit 0 is Z, 1 is X etc. `:0` = no axes homed.
* "Hardened" the new tool change functionality even more. Initial changes for multi-axis tool reference offset made.
An empy message will now be sent when tool change is complete, this to clear any tool change related message in the sender.
* Added call to [weak](https://en.wikipedia.org/wiki/Weak_symbol) `my_plugin_init()` function at startup, name your [plugin](https://github.com/terjeio/grblHAL/tree/master/plugins) init function `void my_plugin_init (void)` and there is no need to change any grblHAL source files to bring it alive.
Use this feature for your private plugin only, multiple public plugins using this name cannot coexist!
* Some changes to improve code readability and added strict check for `G59.x` gcodes.
Build 20200911:
* Core refactored for better support for non-volatile storage. Some HAL entry points renamed for readability and moved to a new data structure.
* Added plugin for axis odometers. This logs total distance traveled and machining time to EEPROM/FRAM.
[FRAM](https://www.electronics-notes.com/articles/electronic_components/semiconductor-ic-memory/fram-ferroelectric-ram-memory.php) is recommended for storage as it is faster and can sustain a larger number of write cycles. FRAM chips are sold in packages that is pin compatible with EEPROM.
__NOTE:__ Currently for review and for now only for the iMRXT1061 \(Teensy 4.x\) driver. It will _not_ be available in configurations that stores non-volatile data to flash.
* "Hardening" of new [manual tool change](https://github.com/terjeio/grblHAL/wiki/Manual,-semi-automatic-and-automatic-tool-change) functionality.
* Improved auto squaring algorithm in core.
* Enhanced some plugins so they can coexist.
---
Build 20200830:
* Improved tool change functionality, a status report is forced on end of tool change to inform change is completed.
* Fix for iMRXT1062 homing failure when serial over USB is used.
* Standardized serial over USB `#define` macro across drivers to `USB_SERIAL_CDC`.
---
Build 20200818:
* Part two of large overhaul of configuration system.
Driver configuration has been moved from _driver.h_ to _my_machine.h_ and options has been made available to be defined as compiler defined symbols/macros with the `-D` compiler command line option. In order to allow compiler defined symbols to override _my_machine.h_ settings the symbol `OVERRIDE_MY_MACHINE` should always be added to the command line. See [compiling grblHAL](https://github.com/terjeio/grblHAL/wiki/Compiling-GrblHAL) for more information. Available driver options in _my_machine.h_ can now be listed from the driver ReadMe page.
---
Build 20200813:
* "Hardened" step pulse generation when delay is enabled. The delay will now only be added on direction changes.
The minimum possible delay is dependent on many factors and will be adjusted to match what the processor is capable of.
By default driver code is calibrated for a 2.5 &micro;s delay and may deviate a bit for other settings and configurations. The actual delay should be checked with an oscilloscope when high step rates are used.
__NOTE:__ A delay is only added if AMASS is disabled, when AMASS is enabled \(it is by default\) there is always a implicit delay on direction changes.
---
Build 20200811:
* Part one of large overhaul of configuration system.
This has been done to allow a global configuration file and/or setting compile time options as compiler symbols/macros with the `-D` compiler command line option.
* Networking \(cabled ethernet\), SD Card and I2C keypad plugin support added to [Teensy 4.x driver.](drivers/IMXRT1062) A Teensy 4.1 is required for networking.
* Tool number range changed from 8-bit \(0-255\) to 32-bit \(0-4294967294\). Note that if the optional tool table is enabled the max tool number is limited by number of entries in the tool table.
* M60 and corresponding pallet shuttle HAL entry point added. No driver support for this yet.
_Configuration system changes:_
Symbols \(#define macros\) that are unlikely to be changed or is used for conditional compilation has been moved from [grbl/config.h](grbl/config.h) to [grbl/grbl.h](grbl/grbl.h).
Symbols used for conditional compilation can be overridden by `-D` compiler command line options or by editing [grbl/config.h](grbl/config.h).
[grbl/defaults.h](grbl/defaults.h) is now used for default values for settings that can be changed at run-time with the `$$` command. __Important:__ grbl/defaults.h should only be changed when adding new settings.
[grbl/config.h](grbl/config.h) is now used for overriding default values in grbl/grbl.h or grbl/defaults.h. Out of the box all overridable symbols are commented out, uncomment and change as needed to override default definitions in grbl/grbl.h or grbl/defaults.h.
These changes are part of a long term plan to create a user friendly front end for configuring and building grblHAL.
---
Build 20200805:
* **Important:** settings has been changed again and settings will be restored to defaults after updating. Backup & restore!
* Added tool change handler for [manual tool change](https://github.com/terjeio/grblHAL/wiki/Manual,-semi-automatic-and-automatic-tool-change) on M6. Four different modes available, selectable with [`$341` setting](https://github.com/terjeio/grblHAL/wiki/Additional-or-extended-settings#manual-tool-change-settings).
* STMF4xx driver updated for optional I2C EEPROM plugin support.
---
Build 20200722:
* **Important:** settings version has been changed again and settings will be restored to defaults after updating. Backup & restore!
* Changed step pulse width and delay settings from int to float and reduced minimum allowed value to 2 microseconds<sup>1</sup>. Useful for very high step rates.
* New plugin for [quadrature encoder input](https://github.com/terjeio/grblHAL/issues/73#issuecomment-659222664) for up to 5 encoders \(driver dependent\). Can be used to adjust overrides and has rudimentary support for MPG functionality. Work in progress and the iMXRT1062 \(Teensy 4\) driver is currently the only driver with low-level support for this (one encoder).
* New plugin for [ModBus VFD](https://github.com/terjeio/grblHAL/issues/68) spindle controllers. Untested and with limited driver support in this build.
* Added setting, `$340` for spindle at speed tolerance \(percent\). If spindle fails to reach speed within limits in 4 seconds alarm 14 will be raised. Set to 0 to disable. Availability driver dependent.
* All [new settings](https://github.com/terjeio/grblHAL/wiki/Additional-or-extended-settings) are now possibly to set independent of the [compatibility level](https://github.com/terjeio/grblHAL/wiki/Changes-from-grbl-1.1#workaround) except some settings that has flags added to them. The added flags will not be available at all compatibilty levels. A new command, `$+`, can be used to list all settings independent of compatibilty level.
* Internal changes to settings data in order to simplify automatic migration on changes. Automatic migration is on the roadmap.
<sup>1</sup> Note that several factors may affect the accuracy of these settings such as step output mode, number of axes defined and compiler optimization settings.
A new #define, `STEP_PULSE_LATENCY`, has been added to driver.h for those drivers that requires it so that fine tuning can be done. I may move this to a setting later.
In setups where very high step rates are used the actual step pulse width should be confirmed with an oscilloscope.
The step pulse delay has not been fine tuned yet as setting this to a value > 0 is not normally needed as there seems to be a implicit delay on direction changes when AMASS is enabled.
__Note:__ high step rates \(e.g. above 80 kHz\) cannot be achieved with the step pulse setting set to the default 10 microseconds. This has to be reduced so that both the on and off time is within specifications of the stepper driver. At 100 kHz the time available for a pulse \(on + off\) is 10 microseconds.
__Note:__ The SAMD21 \(MKRZERO\) driver needs updating in for it to allow short step pulses. My mistake was to use some Arduino code so that the Arduino pin numbers could be used for pin mappings. This adds around 500 ns per axis of overhead... To be fixed later.
For the curious: I have managed to achieve a 400 kHz step rate with the iMXRT1062 before everything breaks down, this with a command entered from MDI. I have not tested this with a running program, but I am pretty sure that a step rate at or above 200 kHz is sustainable.
---
2020/06/18: Added driver for STM32F4xx [Black Pill](https://www.cnx-software.com/2019/12/24/stm32-black-pill-board-features-stm32f4-cortex-m4-mcu-optional-spi-flash/), code modified by @shaise from the STM32F1xx driver. This is the first driver provided by someone else than me, thanks for that.
This driver is a candidate along with the IMXRT1062 \(Teensy 4.x\) driver to get spindle sync support. I have a [NucleoF411RE development board](https://www.st.com/en/evaluation-tools/nucleo-f411re.html) on order and will look into adding a pin mapping for that when it arrives.
---
Build 20200603:
* **Important:** settings version has been changed and settings will be restored to defaults after updating. Backup & restore!
* Optimizations for ring buffer handling in planner and step generator.
* New optional input signal for probe connected status, driver support will be added later to selected drivers.
* Automatic reporting of tool length offset \(`[TLO:...]`\) when changed.
* Support for [G5](http://www.linuxcnc.org/docs/2.5/html/gcode/gcode.html#sec:G5-Cubic-Spline) \(cubic spline\) added.
* `G43.x`, `G49` and `G92` added to parser state report.
* `G76` [threading cycle](https://hackaday.io/project/165248-mini-lathe-emco-compact-5-cnc-conversion) refactored.
* \(Re\)added `REPORT_PROBE_COORDINATES` and `TOOL_LENGTH_OFFSET_AXIS` [configuration](grbl/config.h) options, the latter available when `COMPATIBILITY_LEVEL` > 2.
* Improved backwards compatibility with vanilla grbl, e.g. G92 and tool offset\(s\) will be lost on a soft reset. Dependent on `COMPATIBILITY_LEVEL` setting.
* Board name added to `$I` report if provided by driver.
* [Grbl-Sim](https://github.com/grbl/grbl-sim) ported to grblHAL as a [driver](drivers/Simulator). Added telnet support++. Can be used to test senders. Note: currently only compiled/tested for Linux.
* Some minor bug fixes.
---
Build 20200503: Added configuration flag for manual homing. \(Re\)added compile time option `ENABLE_SAFETY_DOOR_INPUT_PIN` for [safety door switch](https://github.com/terjeio/grblHAL/blob/master/grbl/config.h), default is now disabled. Some bug fixes and "hardening" of code.
---
Added some [template code](./templates/README.md) to aid customizations such as driver support for M62 - M68 M-codes mentioned below.
---
Build 20191222: Added digital and analog output support to the core \(and HAL\) as per [linuxcnc specifications for M62 - M68](http://linuxcnc.org/docs/html/gcode/m-code.html#mcode:m62-m65), number of outputs available \(if any\) is driver dependent. Adding support for these M-commands makes it fairly easy to add driver code \(for up to 256 outputs\) as parsing and synchronization is taken care of by the core.
---
Build 20191215: Moved spindle RPM linearization to $-settings, option needs to be enabled in config.h - driver support required. Optimized EEPROM allocation handling. WebUI support for ESP32 driver improved.
MSP432 driver enhanced for spindle linearization app in the pipeline \(for Windows only - needs input from spindle encoder\), more work done on closed loop spindle RPM control and spindle synchronized motion - still at experimental stage.
__NOTE:__ settings version number has been increased so settings will be reset to default after update, make a backup first!
---
Added [#define COMPATIBILITY_LEVEL to config.h](grbl/config.h) for backwards compatibility with Grbl v1.1 protocol definition, this for enabling the use of more GCode senders. Please raise an issue if your sender still does not behave well after setting this as the current implementation does not yet disable all extensions, notably [new $xx settings](doc/markdown/grblHAL%20extensions.md#settings).
G76 threading support added to grblHAL in combination with the [MSP432 driver](drivers/MSP432/README.md). Extensive testing is required before it can be regarded as safe.
**WARNING!** This is a potentially dangerous addition. Do NOT use if you do not understand the risks. A proper E-Stop is a must, it should cut power to the steppers and if possible engage any spindle brake. The implementation is based on the [linuxcnc specification](http://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G76-Threading-Canned). Please note that I am not a machinist so my interpretation and implementation may be wrong!
G76 availablity requires a spindle encoder with index pulse, grblHAL configured to [lathe mode](doc/markdown/settings.md#opmode) and tuning of the spindle sync PID loop.
__NOTE:__ Feed hold is delayed until spindle synced cut is complete, spindle RPM overrides and CSS mode disabled through the whole cycle.

View File

@@ -1,8 +1,6 @@
/*
crossbar.h - signal crossbar definitions
Not used by the core.
Part of grblHAL
Copyright (c) 2021 Terje Io
@@ -34,10 +32,13 @@ typedef enum {
Input_EStop,
Input_ModeSelect,
Input_LimitX,
Input_LimitX_2,
Input_LimitX_Max,
Input_LimitY,
Input_LimitY_2,
Input_LimitY_Max,
Input_LimitZ,
Input_LimitZ_2,
Input_LimitZ_Max,
Input_LimitA,
Input_LimitA_Max,
@@ -45,6 +46,12 @@ typedef enum {
Input_LimitB_Max,
Input_LimitC,
Input_LimitC_Max,
Input_LimitU,
Input_LimitU_Max,
Input_LimitV,
Input_LimitV_Max,
Input_MISO,
Input_RX,
Input_KeypadStrobe,
Input_QEI_A,
Input_QEI_B,
@@ -59,24 +66,31 @@ typedef enum {
Input_Aux5,
Input_Aux6,
Input_Aux7,
Output_StepX,
Outputs,
Output_StepX = Outputs,
Output_StepY,
Output_StepZ,
Output_StepA,
Output_StepB,
Output_StepC,
Output_StepU,
Output_StepV,
Output_DirX,
Output_DirY,
Output_DirZ,
Output_DirA,
Output_DirB,
Output_DirC,
Output_DirU,
Output_DirV,
Output_StepperEnable,
Output_StepperEnableX,
Output_StepperEnableY,
Output_StepperEnableZ,
Output_StepperEnableA,
Output_StepperEnableB,
Output_StepperEnableU,
Output_StepperEnableV,
Output_StepperEnableC,
Output_StepperEnableXY,
Output_StepperEnableAB,
@@ -85,6 +99,9 @@ typedef enum {
Output_SpindlePWM,
Output_CoolantMist,
Output_CoolantFlood,
Output_TX,
Output_SCK,
Output_MOSI,
Output_SdCardCS,
Output_Aux0,
Output_Aux1,
@@ -93,9 +110,132 @@ typedef enum {
Output_Aux4,
Output_Aux5,
Output_Aux6,
Output_Aux7
Output_Aux7,
Bidirectional,
Bidirectional_SDA = Bidirectional
} pin_function_t;
#define PIN_ISINPUT(pin) (pin < Outputs)
#define PIN_ISOUTPUT(pin) (pin >= Outputs && pin < Bidirectional)
#define PIN_ISBIDIRECTIONAL(pin) (pin >= Bidirectional)
typedef struct {
pin_function_t function;
const char *name;
} pin_name_t;
PROGMEM static const pin_name_t pin_names[] = {
{ .function = Input_Probe, .name = "Probe" },
{ .function = Input_Reset, .name = "Reset" },
{ .function = Input_FeedHold, .name = "Feed hold" },
{ .function = Input_CycleStart, .name = "Cycle start" },
{ .function = Input_SafetyDoor, .name = "Safety door" },
{ .function = Input_LimitsOverride, .name = "Limits override" },
{ .function = Input_EStop, .name = "Emergency stop" },
{ .function = Input_ModeSelect, .name = "MPG mode select" },
{ .function = Input_LimitX, .name = "X limit min" },
{ .function = Input_LimitX_2, .name = "X limit min 2" },
{ .function = Input_LimitX_Max, .name = "X limit max" },
{ .function = Input_LimitY, .name = "Y limit min" },
{ .function = Input_LimitY_2, .name = "Y limit min 2" },
{ .function = Input_LimitY_Max, .name = "Y limit max" },
{ .function = Input_LimitZ, .name = "Z limit min" },
{ .function = Input_LimitZ_2, .name = "Z limit min 2" },
{ .function = Input_LimitZ_Max, .name = "Z limit max" },
{ .function = Input_LimitA, .name = "A limit min" },
{ .function = Input_LimitA_Max, .name = "A limit max" },
{ .function = Input_LimitB, .name = "B limit min" },
{ .function = Input_LimitB_Max, .name = "B limit max" },
{ .function = Input_LimitC, .name = "C limit min" },
{ .function = Input_LimitC_Max, .name = "C limit max" },
{ .function = Input_LimitU, .name = "U limit min" },
{ .function = Input_LimitU_Max, .name = "U limit max" },
{ .function = Input_LimitV, .name = "V limit min" },
{ .function = Input_LimitV_Max, .name = "V limit max" },
{ .function = Input_MISO, .name = "MISO" },
{ .function = Input_RX, .name = "RX" },
{ .function = Input_KeypadStrobe, .name = "Keypad strobe" },
{ .function = Input_QEI_A, .name = "QEI A" },
{ .function = Input_QEI_B, .name = "QEI B" },
{ .function = Input_QEI_Select, .name = "QEI select" },
{ .function = Input_QEI_Index, .name = "QEI index" },
{ .function = Input_SpindleIndex, .name = "Spindle index" },
{ .function = Input_Aux0, .name = "Aux input 0" },
{ .function = Input_Aux1, .name = "Aux input 1" },
{ .function = Input_Aux2, .name = "Aux input 2" },
{ .function = Input_Aux3, .name = "Aux input 3" },
{ .function = Input_Aux4, .name = "Aux input 4" },
{ .function = Input_Aux5, .name = "Aux input 5" },
{ .function = Input_Aux6, .name = "Aux input 6" },
{ .function = Input_Aux7, .name = "Aux input 7" },
{ .function = Output_StepX, .name = "X step" },
{ .function = Output_StepY, .name = "Y step" },
{ .function = Output_StepZ, .name = "Z step" },
{ .function = Output_StepA, .name = "A step" },
{ .function = Output_StepB, .name = "B step" },
{ .function = Output_StepC, .name = "C step" },
{ .function = Output_DirX, .name = "X dir" },
{ .function = Output_DirY, .name = "Y dir" },
{ .function = Output_DirZ, .name = "Z dir" },
{ .function = Output_DirA, .name = "A dir" },
{ .function = Output_DirB, .name = "B dir" },
{ .function = Output_DirC, .name = "C dir" },
{ .function = Output_StepperEnable, .name = "Steppers enable" },
{ .function = Output_StepperEnableX, .name = "X enable" },
{ .function = Output_StepperEnableY, .name = "Y enable" },
{ .function = Output_StepperEnableZ, .name = "Z enable" },
{ .function = Output_StepperEnableA, .name = "A enable" },
{ .function = Output_StepperEnableB, .name = "B enable" },
{ .function = Output_StepperEnableC, .name = "C enable" },
{ .function = Output_StepperEnableXY, .name = "XY enable" },
{ .function = Output_StepperEnableAB, .name = "AB enable" },
{ .function = Output_SpindleOn, .name = "Spindle on" },
{ .function = Output_SpindleDir, .name = "Spindle direction" },
{ .function = Output_SpindlePWM, .name = "Spindle PWM" },
{ .function = Output_CoolantMist, .name = "Mist" },
{ .function = Output_CoolantFlood, .name = "Flood" },
{ .function = Output_TX, .name = "TX" },
{ .function = Output_SCK, .name = "SCK" },
{ .function = Output_MOSI, .name = "MOSI" },
{ .function = Output_SdCardCS, .name = "SD card CS" },
{ .function = Output_Aux0, .name = "Aux out 0" },
{ .function = Output_Aux1, .name = "Aux out 1" },
{ .function = Output_Aux2, .name = "Aux out 2" },
{ .function = Output_Aux3, .name = "Aux out 3" },
{ .function = Output_Aux4, .name = "Aux out 4" },
{ .function = Output_Aux5, .name = "Aux out 5" },
{ .function = Output_Aux6, .name = "Aux out 6" },
{ .function = Output_Aux7, .name = "Aux out 7" },
{ .function = Bidirectional_SDA, .name = "SDA" }
};
typedef enum {
PinGroup_SpindleControl = 0,
PinGroup_SpindlePWM,
PinGroup_Coolant,
PinGroup_SpindlePulse,
PinGroup_SpindleIndex,
PinGroup_StepperEnable,
PinGroup_StepperStep,
PinGroup_StepperDir,
PinGroup_AuxOutput,
PinGroup_SdCard,
PinGroup_I2C,
PinGroup_SPI,
PinGroup_UART,
PinGroup_UART2,
PinGroup_USB,
// Interrupt capable pins that may have debounce processing enabled
PinGroup_Control = (1<<8),
PinGroup_Limit = (1<<9),
PinGroup_Probe = (1<<10),
PinGroup_Keypad = (1<<11),
PinGroup_MPG = (1<<12),
PinGroup_QEI = (1<<13),
PinGroup_QEI_Select = (1<<14),
PinGroup_AuxInput = (1<<15),
} pin_group_t;
typedef enum {
IRQ_Mode_None = 0b00,
IRQ_Mode_Change = 0b01,
@@ -104,27 +244,32 @@ typedef enum {
} pin_irq_mode_t;
typedef enum {
PinGroup_Control = (1<<0),
PinGroup_Limit = (1<<1),
PinGroup_Probe = (1<<2),
PinGroup_Keypad = (1<<3),
PinGroup_MPG = (1<<4),
PinGroup_QEI = (1<<5),
PinGroup_QEI_Select = (1<<6),
PinGroup_SpindleControl = (1<<7),
PinGroup_SpindlePWM = (1<<8),
PinGroup_Coolant = (1<<9),
PinGroup_SpindlePulse = (1<<10),
PinGroup_SpindleIndex = (1<<11),
PinGroup_StepperEnable = (1<<12),
PinGroup_StepperStep = (1<<13),
PinGroup_StepperDir = (1<<14),
PinGroup_AuxInput = (1<<15),
PinGroup_AuxOutput = (1<<16),
PinGroup_SdCard = (1<<17),
PinGroup_I2C = (1<<18),
PinGroup_SPI = (1<<19)
} pin_group_t;
PullMode_None = 0b00,
PullMode_Up = 0b01,
PullMode_Down = 0b10
} pull_mode_t;
#define PINMODE_NONE (0)
#define PINMODE_OUTPUT (1U<<1)
#define PINMODE_OD (1U<<2)
#define PINMODE_PULLUP (PullMode_Up<<3)
#define PINMODE_PULLDOWN (PullMode_Down<<3)
#define PINMODE_REMAP (1U<<10)
typedef union {
uint16_t mask;
struct {
uint16_t input :1,
output :1,
open_drain :1,
pull_mode :2,
irq_mode :2,
pwm :1,
analog :1,
peripheral :1,
can_remap :1;
};
} pin_mode_t;
typedef bool (*xbar_get_value_ptr)(void);
typedef void (*xbar_set_value_ptr)(bool on);
@@ -132,9 +277,13 @@ typedef void (*xbar_event_ptr)(bool on);
typedef void (*xbar_config_ptr)(void *cfg_data);
typedef struct {
uint32_t function;
pin_function_t function;
pin_group_t group;
void *port;
uint8_t bit;
uint_fast8_t pin;
uint32_t bit;
pin_mode_t mode;
pin_mode_t cap;
xbar_config_ptr config;
xbar_get_value_ptr get_value;
xbar_set_value_ptr set_value;

View File

@@ -287,6 +287,32 @@
#define DEFAULT_C_MAX_TRAVEL 200.0f
#endif
#ifndef DEFAULT_U_STEPS_PER_MM
#define DEFAULT_U_STEPS_PER_MM 250.0f
#endif
#ifndef DEFAULT_U_MAX_RATE
#define DEFAULT_U_MAX_RATE 500.0f
#endif
#ifndef DEFAULT_U_ACCELERATION
#define DEFAULT_U_ACCELERATION DEFAULT_ACCELERATION
#endif
#ifndef DEFAULT_U_MAX_TRAVEL
#define DEFAULT_U_MAX_TRAVEL 200.0f
#endif
#ifndef DEFAULT_V_STEPS_PER_MM
#define DEFAULT_V_STEPS_PER_MM 250.0f
#endif
#ifndef DEFAULT_V_MAX_RATE
#define DEFAULT_V_MAX_RATE 500.0f
#endif
#ifndef DEFAULT_V_ACCELERATION
#define DEFAULT_V_ACCELERATION DEFAULT_ACCELERATION
#endif
#ifndef DEFAULT_V_MAX_TRAVEL
#define DEFAULT_V_MAX_TRAVEL 200.0f
#endif
#ifndef DEFAULT_G73_RETRACT
#define DEFAULT_G73_RETRACT 0.1f
#endif

55
gcode.c
View File

@@ -127,6 +127,12 @@ static scale_factor_t scale_factor = {
#ifdef C_AXIS
, .ijk[C_AXIS] = 1.0f
#endif
#ifdef U_AXIS
, .ijk[U_AXIS] = 1.0f
#endif
#ifdef V_AXIS
, .ijk[V_AXIS] = 1.0f
#endif
};
// Simple hypotenuse computation function.
@@ -376,11 +382,17 @@ status_code_t gc_execute_block(char *block, char *message)
#ifdef A_AXIS
, .a = On
#endif
#ifdef A_AXIS
#ifdef B_AXIS
, .b = On
#endif
#ifdef A_AXIS
#ifdef C_AXIS
, .c = On
#endif
#ifdef U_AXIS
, .u = On
#endif
#ifdef V_AXIS
, .v = On
#endif
};
@@ -671,9 +683,20 @@ status_code_t gc_execute_block(char *block, char *message)
word_bit.modal_group.G13 = On;
if (mantissa != 0) // [G61.1 not supported]
FAIL(Status_GcodeUnsupportedCommand);
// gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61
break;
/*
case 61:
word_bit.modal_group.G13 = On;
if (mantissa != 0 || mantissa != 10)
FAIL(Status_GcodeUnsupportedCommand);
gc_block.modal.control = mantissa == 0 ? ControlMode_ExactPath : ControlMode_ExactStop;
break;
case 64:
word_bit.modal_group.G13 = On;
gc_block.modal.control = ControlMode_PathBlending; // G64
break;
*/
case 96: case 97:
if(settings.mode == Mode_Lathe && hal.driver_cap.variable_spindle) {
word_bit.modal_group.G14 = On;
@@ -967,7 +990,23 @@ status_code_t gc_execute_block(char *block, char *message)
gc_block.values.t = isnan(value) ? 0xFFFFFFFF : int_value;
break;
case 'X':
#ifdef U_AXIS
case 'U':
axis_words.u = On;
word_bit.parameter.u = On;
gc_block.values.xyz[U_AXIS] = value;
break;
#endif
#ifdef V_AXIS
case 'V':
axis_words.v = On;
word_bit.parameter.v = On;
gc_block.values.xyz[V_AXIS] = value;
break;
#endif
case 'X':
axis_words.x = On;
word_bit.parameter.x = On;
gc_block.values.xyz[X_AXIS] = value;
@@ -1470,6 +1509,14 @@ status_code_t gc_execute_block(char *block, char *message)
}
// [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED.
/*
if (command_words.G13) { // Check if called in block
if(gc_block.modal.control == ControlMode_PathBlending) {
gc_state.blending_tolerance = value_words.p ? gc_block.values.p : 0.0f;
value_words.p = Off;
}
}
*/
// [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED.
// [18. Set retract mode ]: N/A.

19
gcode.h
View File

@@ -112,7 +112,11 @@ typedef enum {
//#define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero)
// Modal Group G13: Control mode
//#define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero)
typedef enum {
ControlMode_ExactPath = 0, // G61 (Default: Must be zero)
ControlMode_ExactStop = 1, // G61.1
ControlMode_PathBlending = 2 // G64
} control_mode_t;
// Modal Group G8: Tool length offset
typedef enum {
@@ -224,6 +228,10 @@ typedef union {
a :1,
b :1,
c :1,
#endif
#if N_AXIS > 6
u :1,
v :1,
#endif
d :1;
};
@@ -274,6 +282,12 @@ typedef union {
#endif
#ifdef C_AXIS
float c;
#endif
#ifdef U_AXIS
float u;
#endif
#ifdef V_AXIS
float v;
#endif
};
} coord_data_t;
@@ -320,7 +334,7 @@ typedef struct {
// uint8_t cutter_comp; // {G40} NOTE: Don't track. Only default supported.
tool_offset_mode_t tool_offset_mode; // {G43,G43.1,G49}
coord_system_t coord_system; // {G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3}
// uint8_t control; // {G61} NOTE: Don't track. Only default supported.
// control_mode_t control; // {G61} NOTE: Don't track. Only default supported.
program_flow_t program_flow; // {M0,M1,M2,M30,M60}
coolant_state_t coolant; // {M7,M8,M9}
spindle_state_t spindle; // {M3,M4,M5}
@@ -412,6 +426,7 @@ typedef struct {
float feed_rate; // Millimeters/min
float distance_per_rev; // Millimeters/rev
float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code
// float blending_tolerance; // Motion blending tolerance
int32_t line_number; // Last line number sent
uint32_t tool_pending; // Tool to be selected on next M6
bool file_run; // Tracks % command

2
grbl.h
View File

@@ -34,7 +34,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_VERSION_BUILD "20210517"
#define GRBL_VERSION_BUILD "20210604"
// The following symbols are set here if not already set by the compiler or in config.h
// Do NOT change here!

25
hal.h
View File

@@ -27,6 +27,7 @@
#include "system.h"
#include "coolant_control.h"
#include "spindle_control.h"
#include "crossbar.h"
#include "stepper.h"
#include "nvs.h"
#include "stream.h"
@@ -80,6 +81,7 @@ typedef bool (*enqueue_realtime_command_ptr)(char data);
typedef struct {
stream_type_t type;
bool connected;
uint16_t (*get_rx_buffer_available)(void);
stream_write_ptr write; // write string to current I/O stream only.
stream_write_ptr write_all; // write string to all active output streams.
@@ -91,16 +93,31 @@ typedef struct {
enqueue_realtime_command_ptr enqueue_realtime_command; // NOTE: set by grbl at startup.
} io_stream_t;
typedef bool (*stream_select_ptr)(const io_stream_t *stream);
// Aux I/O
typedef void (*digital_out_ptr)(uint8_t port, bool on);
typedef bool (*analog_out_ptr)(uint8_t port, float value);
typedef int32_t (*wait_on_input_ptr)(bool digital, uint8_t port, wait_mode_t wait_mode, float timeout);
typedef xbar_t *(*get_pin_info_ptr)(bool digital, uint8_t port);
typedef struct {
uint8_t num_digital_in;
uint8_t num_digital_out;
uint8_t num_analog_in;
uint8_t num_analog_out;
void (*digital_out)(uint8_t port, bool on);
bool (*analog_out)(uint8_t port, float value);
int32_t (*wait_on_input)(bool digital, uint8_t port, wait_mode_t wait_mode, float timeout);
digital_out_ptr digital_out;
analog_out_ptr analog_out;
wait_on_input_ptr wait_on_input;
get_pin_info_ptr get_pin_info;
} io_port_t;
// Pins
typedef void (*pin_info_ptr)(xbar_t *pin);
typedef void (*enumerate_pins_ptr)(bool low_level, pin_info_ptr callback);
// Spindle
typedef void (*spindle_set_state_ptr)(spindle_state_t state, float rpm);
@@ -277,6 +294,7 @@ typedef struct {
stepper_ptrs_t stepper;
control_signals_ptrs_t control;
io_stream_t stream;
stream_select_ptr stream_select;
settings_changed_ptr settings_changed;
//
@@ -298,6 +316,7 @@ typedef struct {
encoder_ptrs_t encoder;
nvs_io_t nvs;
io_port_t port;
enumerate_pins_ptr enumerate_pins;
bool (*stream_blocking_callback)(void); // set up by core before driver_init() is called.

View File

@@ -66,6 +66,12 @@ char const *const axis_letter[N_AXIS] = {
#if N_AXIS > 5
,"C"
#endif
#if N_AXIS > 6
,"U"
#endif
#if N_AXIS > 7
,"V"
#endif
};
// Converts an uint32 variable to string.

View File

@@ -68,10 +68,17 @@
#define B_AXIS 4
#define B_AXIS_BIT bit(B_AXIS)
#endif
#if N_AXIS == 6
#if N_AXIS > 5
#define C_AXIS 5
#define C_AXIS_BIT bit(C_AXIS)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT)
#endif
#if N_AXIS > 6
#define U_AXIS 6
#define U_AXIS_BIT bit(U_AXIS)
#endif
#if N_AXIS == 8
#define V_AXIS 7
#define V_AXIS_BIT bit(V_AXIS)
#endif
#if N_AXIS == 3
@@ -80,6 +87,12 @@
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT)
#elif N_AXIS == 5
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT)
#elif N_AXIS == 6
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT)
#elif N_AXIS == 7
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT|U_AXIS_BIT)
#else
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT|U_AXIS_BIT|V_AXIS_BIT)
#endif
extern char const *const axis_letter[];
@@ -93,7 +106,9 @@ typedef union {
z :1,
a :1,
b :1,
c :1;
c :1,
u :1,
v :1;
};
} axes_signals_t;

View File

@@ -100,7 +100,9 @@ inline static uint8_t ram_get_byte (uint32_t addr)
inline static void ram_put_byte (uint32_t addr, uint8_t new_value)
{
dirty = dirty || nvsbuffer[addr] != new_value;
if(addr == 0)
settings_dirty.version = true;
dirty = dirty || nvsbuffer[addr] != new_value || addr == 0;
nvsbuffer[addr] = new_value;
}
@@ -122,7 +124,7 @@ static nvs_transfer_result_t memcpy_to_ram (uint32_t destination, uint8_t *sourc
if(with_checksum)
ram_put_byte(dest, checksum);
if(source == hal.nvs.driver_area.mem_address)
if(settings_dirty.version || source == hal.nvs.driver_area.mem_address)
dirty = true;
if(dirty && physical_nvs.type != NVS_None) {
@@ -280,12 +282,15 @@ void nvs_buffer_sync_physical (void)
if(physical_nvs.memcpy_to_nvs) {
if(settings_dirty.build_info)
settings_dirty.build_info = physical_nvs.memcpy_to_nvs(NVS_ADDR_BUILD_INFO, (uint8_t *)(nvsbuffer + NVS_ADDR_BUILD_INFO), sizeof(stored_line_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
if(settings_dirty.version)
settings_dirty.version = physical_nvs.memcpy_to_nvs(0, nvsbuffer, 1, false) != NVS_TransferResult_OK;
if(settings_dirty.global_settings)
settings_dirty.global_settings = physical_nvs.memcpy_to_nvs(NVS_ADDR_GLOBAL, (uint8_t *)(nvsbuffer + NVS_ADDR_GLOBAL), sizeof(settings_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
if(settings_dirty.build_info)
settings_dirty.build_info = physical_nvs.memcpy_to_nvs(NVS_ADDR_BUILD_INFO, (uint8_t *)(nvsbuffer + NVS_ADDR_BUILD_INFO), sizeof(stored_line_t) + NVS_CRC_BYTES, false) != NVS_TransferResult_OK;
uint_fast8_t idx = N_STARTUP_LINE, offset;
if(settings_dirty.startup_lines) do {
idx--;
@@ -344,7 +349,7 @@ nvs_io_t *nvs_buffer_get_physical (void)
return hal.nvs.type == NVS_Emulated ? &physical_nvs : &hal.nvs;
}
#ifndef DEBUGOUT
#ifdef DEBUGOUT
#include "report.h"

View File

@@ -27,6 +27,7 @@ typedef uint32_t nvs_address_t;
typedef struct {
bool is_dirty;
bool version;
bool global_settings;
bool build_info;
bool driver_settings;

View File

@@ -41,7 +41,7 @@
#endif
static plan_block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions
static plan_block_t *block_buffer_tail; // Pointer to the block to process now
static plan_block_t *block_buffer_tail = NULL; // Pointer to the block to process now
static plan_block_t *block_buffer_head; // Pointer to the next block to be pushed
static plan_block_t *next_buffer_head; // Pointer to the next buffer head
static plan_block_t *block_buffer_planned; // Pointer to the optimally planned block
@@ -203,9 +203,9 @@ inline static void plan_cleanup (plan_block_t *block)
}
inline static void plan_reset_buffer (bool soft_reset)
inline static void plan_reset_buffer ()
{
if(soft_reset) {
if(block_buffer_tail) {
// Free memory for any pending messages and output commands after soft reset
while(block_buffer_tail != block_buffer_head) {
plan_cleanup(block_buffer_tail);
@@ -221,7 +221,14 @@ inline static void plan_reset_buffer (bool soft_reset)
void plan_reset ()
{
static bool soft_reset = false;
if(block_buffer_tail) {
// Free memory for any pending messages and output commands after soft reset
while(block_buffer_tail != block_buffer_head) {
plan_cleanup(block_buffer_tail);
block_buffer_tail = block_buffer_tail->next;
}
block_buffer_tail = NULL;
}
memset(&pl, 0, sizeof(planner_t)); // Clear planner struct
@@ -232,8 +239,7 @@ void plan_reset ()
block_buffer[idx].next = &block_buffer[idx == BLOCK_BUFFER_SIZE - 1 ? 0 : idx + 1];
}
plan_reset_buffer(soft_reset);
soft_reset = true;
plan_reset_buffer();
}

View File

@@ -87,6 +87,7 @@ typedef struct plan_block {
// Planner data prototype. Must be used when passing new motions to the planner.
typedef struct {
float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion.
// float blending_tolerance; // Motion blending tolerance
spindle_t spindle; // Desired spindle speed through line motion.
planner_cond_t condition; // Bitfield variable to indicate planner conditions. See defines above.
gc_override_flags_t overrides; // Block bitfield variable for overrides

View File

@@ -21,12 +21,12 @@
#pragma once
#if defined(STM32F103xB) || defined(STM32F401xC) || defined(STM32F407xx) || defined(STM32F411xE) || defined(STM32F446xx)
#if defined(STM32F103xB) || defined(STM32F401xC) || defined(STM32F407xx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F756xx)
#define STM32_PLATFORM
#endif
#if defined(STM32_PLATFORM) || defined(__LPC17XX__) || defined(__IMXRT1062__)
#define UINT32FMT "lu"
#define UINT32FMT "%lu"
#else
#define UINT32FMT "u"
#define UINT32FMT "%u"
#endif

View File

@@ -1841,6 +1841,38 @@ status_code_t report_spindle_data (sys_state_t state, char *args)
return hal.spindle.get_data ? Status_OK : Status_InvalidStatement;
}
static const char *get_pinname (pin_function_t function)
{
const char *name = NULL;
uint_fast8_t idx = sizeof(pin_names) / sizeof(pin_name_t);
do {
if(pin_names[--idx].function == function)
name = pin_names[idx].name;
} while(idx && !name);
return name ? name : "N/A";
}
static void report_pin (xbar_t *pin)
{
hal.stream.write("[PIN:");
if(pin->port)
hal.stream.write((char *)pin->port);
hal.stream.write(uitoa(pin->pin));
hal.stream.write(",");
hal.stream.write(get_pinname(pin->function));
hal.stream.write("]" ASCII_EOL);
}
status_code_t report_pins (sys_state_t state, char *args)
{
if(hal.enumerate_pins)
hal.enumerate_pins(false, report_pin);
return Status_OK;
}
void report_pid_log (void)
{
#ifdef PID_LOG

View File

@@ -97,6 +97,9 @@ status_code_t report_current_limit_state (sys_state_t state, char *args);
// Prints spindle data (encoder pulse and index count, angular position).
status_code_t report_spindle_data (sys_state_t state, char *args);
// Prints pin assignments
status_code_t report_pins (sys_state_t state, char *args);
// Prints current PID log.
void report_pid_log (void);

View File

@@ -242,6 +242,28 @@ PROGMEM const settings_t defaults = {
.homing.cycle[5].mask = HOMING_CYCLE_5,
#endif
#ifdef U_AXIS
.axis[U_AXIS].steps_per_mm = DEFAULT_U_STEPS_PER_MM,
.axis[U_AXIS].acceleration = DEFAULT_U_ACCELERATION,
.axis[U_AXIS].max_rate = DEFAULT_U_MAX_RATE,
.axis[U_AXIS].max_travel = (-DEFAULT_U_MAX_TRAVEL),
.axis[U_AXIS].dual_axis_offset = 0.0f,
#ifdef ENABLE_BACKLASH_COMPENSATION
.axis[U_AXIS].backlash = 0.0f,
#endif
#endif
#ifdef V_AXIS
.axis[V_AXIS].steps_per_mm = DEFAULT_V_STEPS_PER_MM,
.axis[V_AXIS].acceleration = DEFAULT_V_ACCELERATION,
.axis[V_AXIS].max_rate = DEFAULT_V_MAX_RATE,
.axis[V_AXIS].max_travel = (-DEFAULT_V_MAX_TRAVEL),
.axis[V_AXIS].dual_axis_offset = 0.0f,
#ifdef ENABLE_BACKLASH_COMPENSATION
.axis[V_AXIS].backlash = 0.0f,
#endif
#endif
.tool_change.mode = (toolchange_mode_t)DEFAULT_TOOLCHANGE_MODE,
.tool_change.probing_distance = DEFAULT_TOOLCHANGE_PROBING_DISTANCE,
.tool_change.feed_rate = DEFAULT_TOOLCHANGE_FEED_RATE,
@@ -285,7 +307,13 @@ PROGMEM static const setting_group_detail_t setting_group_detail [] = {
{ Group_Axis, Group_BAxis, "B-axis"},
#endif
#ifdef C_AXIS
{ Group_Axis, Group_CAxis, "C-axis"}
{ Group_Axis, Group_CAxis, "C-axis"},
#endif
#ifdef U_AXIS
{ Group_Axis, Group_UAxis, "U-axis"},
#endif
#ifdef V_AXIS
{ Group_Axis, Group_VAxis, "V-axis"}
#endif
};
@@ -1282,16 +1310,14 @@ bool read_global_settings ()
}
// Write Grbl global settings and version number to persistent storage
// Write Grbl global settings to persistent storage
void settings_write_global (void)
{
if(override_backup.valid)
restore_override_backup();
if(hal.nvs.type != NVS_None) {
hal.nvs.put_byte(0, SETTINGS_VERSION);
if(hal.nvs.type != NVS_None)
hal.nvs.memcpy_to_nvs(NVS_ADDR_GLOBAL, (uint8_t *)&settings, sizeof(settings_t), true);
}
}
@@ -1304,6 +1330,8 @@ void settings_restore (settings_restore_t restore)
memset(empty_line, 0xFF, sizeof(stored_line_t));
*empty_line = '\0';
hal.nvs.put_byte(0, SETTINGS_VERSION); // Forces write to physical storage
if (restore.defaults) {
memcpy(&settings, &defaults, sizeof(settings_t));
@@ -1404,6 +1432,12 @@ bool settings_is_group_available (setting_group_t group)
#endif
#ifdef C_AXIS
case Group_CAxis:
#endif
#ifdef U_AXIS
case Group_UAxis:
#endif
#ifdef V_AXIS
case Group_VAxis:
#endif
available = true;
break;

View File

@@ -590,6 +590,12 @@ typedef enum {
#endif
#ifdef C_AXIS
Group_CAxis,
#endif
#ifdef U_AXIS
Group_UAxis,
#endif
#ifdef V_AXIS
Group_VAxis,
#endif
Group_All = Group_Root
} setting_group_t;

View File

@@ -349,6 +349,12 @@ ISR_CODE void stepper_driver_interrupt_handler (void)
#endif
#ifdef C_AXIS
= st.counter_c
#endif
#ifdef U_AXIS
= st.counter_u
#endif
#ifdef V_AXIS
= st.counter_v
#endif
= st.step_event_count >> 1;
@@ -372,6 +378,12 @@ ISR_CODE void stepper_driver_interrupt_handler (void)
#ifdef C_AXIS
st.steps[C_AXIS] = st.exec_block->steps[C_AXIS] >> st.amass_level;
#endif
#ifdef U_AXIS
st.steps[U_AXIS] = st.exec_block->steps[U_AXIS] >> st.amass_level;
#endif
#ifdef V_AXIS
st.steps[V_AXIS] = st.exec_block->steps[V_AXIS] >> st.amass_level;
#endif
#endif
if(st.exec_segment->update_rpm) {
@@ -474,6 +486,30 @@ ISR_CODE void stepper_driver_interrupt_handler (void)
}
#endif
#ifdef U_AXIS
st.counter_u += st.steps[U_AXIS];
if (st.counter_u > st.step_event_count) {
step_outbits.u = On;
st.counter_u -= st.step_event_count;
#ifdef ENABLE_BACKLASH_COMPENSATION
if(!backlash_motion)
#endif
sys.position[U_AXIS] = sys.position[U_AXIS] + (st.dir_outbits.u ? -1 : 1);
}
#endif
#ifdef V_AXIS
st.counter_v += st.steps[V_AXIS];
if (st.counter_v > st.step_event_count) {
step_outbits.v = On;
st.counter_v -= st.step_event_count;
#ifdef ENABLE_BACKLASH_COMPENSATION
if(!backlash_motion)
#endif
sys.position[V_AXIS] = sys.position[V_AXIS] + (st.dir_outbits.v ? -1 : 1);
}
#endif
st.step_outbits.value = step_outbits.value;
// During a homing cycle, lock out and prevent desired axes from moving.

View File

@@ -90,6 +90,12 @@ typedef struct {
#ifdef C_AXIS
, counter_c
#endif
#ifdef C_AXIS
, counter_u
#endif
#ifdef C_AXIS
, counter_v
#endif
;
bool new_block; // Set to true when a new block is started, might be used by driver for advanced functionality
bool dir_change; // Set to true on direction changes, might be used by driver for advanced functionality

View File

@@ -39,6 +39,7 @@ static status_code_t enumerate_errors (sys_state_t state, char *args);
static status_code_t enumerate_groups (sys_state_t state, char *args);
static status_code_t enumerate_settings (sys_state_t state, char *args);
static status_code_t enumerate_all (sys_state_t state, char *args);
static status_code_t enumerate_pins (sys_state_t state, char *args);
static status_code_t output_settings (sys_state_t state, char *args);
static status_code_t output_all_settings (sys_state_t state, char *args);
static status_code_t output_parser_state (sys_state_t state, char *args);
@@ -205,6 +206,7 @@ const sys_command_t sys_commands[] = {
{"EG", true, enumerate_groups},
{"ES", true, enumerate_settings},
{"E*", true, enumerate_all},
{"PINS", true, enumerate_pins},
{"RST", false, settings_reset},
{"LEV", true, report_last_signals_event},
{"LIM", true, report_current_limit_state},
@@ -354,6 +356,11 @@ static status_code_t enumerate_all (sys_state_t state, char *args)
return report_settings_details(false, Setting_SettingsAll, Group_All);
}
static status_code_t enumerate_pins (sys_state_t state, char *args)
{
return report_pins(state, args);
}
static status_code_t output_settings (sys_state_t state, char *args)
{
status_code_t retval = Status_OK;
@@ -743,9 +750,12 @@ static status_code_t set_startup_line1 (sys_state_t state, char *args)
}
#ifdef DEBUGOUT
#include "nvs_buffer.h"
static status_code_t output_memmap (sys_state_t state, char *args)
{
nvs_output_memmap();
nvs_memmap();
return Status_OK;
}