diff --git a/grblHAL_Teensy4/src/T41BB5X_Pro_map.h b/grblHAL_Teensy4/src/T41BB5X_Pro_map.h
new file mode 100644
index 0000000..4d7cb94
--- /dev/null
+++ b/grblHAL_Teensy4/src/T41BB5X_Pro_map.h
@@ -0,0 +1,164 @@
+/*
+ T41BB5X_Pro_map.h - driver code for IMXRT1062 processor (on Teensy 4.1 board)
+
+ Part of grblHAL
+
+ Board by Phil Barrett: https://github.com/phil-barrett/grblHAL-teensy-4.x
+
+ Copyright (c) 2021 Terje Io
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+*/
+
+#define BOARD_NAME "T41BB5X Pro"
+#define HAS_BOARD_INIT
+
+#if N_AXIS > 5
+#error Max number of axes is 5 for T41U5XBB
+#endif
+
+#if QEI_ENABLE && SPINDLE_SYNC_ENABLE
+#error Quadrature encoder and spindle sync cannot be enabled at the same time
+#endif
+
+// Board has 2K FRAM
+#undef EEPROM_ENABLE
+#undef EEPROM_IS_FRAM
+#define EEPROM_ENABLE 1
+#define EEPROM_IS_FRAM 1
+
+// Default pin assignments allow only one axis to be ganged or auto squared.
+// B axis pin numbers are used for the ganged/auto squared axis.
+// If a second axis is to be ganged/auto squared pin assignments needs to be changed!
+// Set to 1 to enable, 0 to disable.
+#define X_GANGED 0
+#define X_AUTO_SQUARE 0
+#define Y_GANGED 0
+#define Y_AUTO_SQUARE 0
+#define Z_GANGED 0
+#define Z_AUTO_SQUARE 0
+//
+
+#define X_STEP_PIN (2u)
+#define X_DIRECTION_PIN (3u)
+#define X_ENABLE_PIN (10u)
+#define X_LIMIT_PIN (20u)
+
+#if X_GANGED || X_AUTO_SQUARE
+#define X2_STEP_PIN (26u)
+#define X2_DIRECTION_PIN (27u)
+#define X2_ENABLE_PIN (37u)
+#if X_AUTO_SQUARE
+ #define X2_LIMIT_PIN (28u)
+#endif
+#endif
+
+#define Y_STEP_PIN (4u)
+#define Y_DIRECTION_PIN (5u)
+#define Y_ENABLE_PIN (35u)
+#define Y_LIMIT_PIN (21u)
+
+#if Y_GANGED || Y_AUTO_SQUARE
+#define Y2_STEP_PIN (26u)
+#define Y2_DIRECTION_PIN (27u)
+#define Y2_ENABLE_PIN (37u)
+#if Y_AUTO_SQUARE
+ #define Y2_LIMIT_PIN (28u)
+#endif
+#endif
+
+#define Z_STEP_PIN (6u)
+#define Z_DIRECTION_PIN (7u)
+#define Z_ENABLE_PIN (39u)
+#define Z_LIMIT_PIN (22u)
+
+#if Z_GANGED || Z_AUTO_SQUARE
+#define Z2_STEP_PIN (26u)
+#define Z2_DIRECTION_PIN (27u)
+#define Z2_ENABLE_PIN (37u)
+#if Z_AUTO_SQUARE
+ #define Z2_LIMIT_PIN (28u)
+#endif
+#endif
+
+#if N_AXIS > 3
+#define A_STEP_PIN (8u)
+#define A_DIRECTION_PIN (9u)
+#define A_ENABLE_PIN (38u)
+#define A_LIMIT_PIN (23u)
+#endif
+
+#if N_AXIS > 4
+#define B_STEP_PIN (26u)
+#define B_DIRECTION_PIN (27u)
+#define B_ENABLE_PIN (37u)
+#define B_LIMIT_PIN (28u)
+#endif
+
+// Define spindle enable and spindle direction output pins.
+#define SPINDLE_ENABLE_PIN (12u)
+#define SPINDLE_DIRECTION_PIN (11u)
+#define SPINDLEPWMPIN (13u) // NOTE: only pin 12 or pin 13 can be assigned!
+
+// Define flood and mist coolant enable output pins.
+#define COOLANT_FLOOD_PIN (19u)
+#define COOLANT_MIST_PIN (18u)
+
+// Define user-control CONTROLs (cycle start, reset, feed hold, door) input pins.
+#define RESET_PIN (40u)
+#define FEED_HOLD_PIN (16u)
+#define CYCLE_START_PIN (17u)
+#define SAFETY_DOOR_PIN (29u)
+
+// Define probe switch input pin.
+#define PROBE_PIN (15u)
+
+#if QEI_ENABLE
+#define QEI_A_PIN (36u)
+#define QEI_B_PIN (30u)
+//#define QEI_INDEX_PIN (36u)
+#define QEI_SELECT_PIN (31u)
+#endif
+
+#if SPINDLE_SYNC_ENABLE
+#define SPINDLE_INDEX_PIN (31u) // ST2
+#define SPINDLE_PULSE_PIN (14u) // ST3
+#endif
+
+// Define auxillary input pins
+#define AUXINPUT0_PIN (36u) // ST0
+#if !QEI_ENABLE
+#define AUXINPUT1_PIN (30u) // ST1
+#if !SPINDLE_SYNC_ENABLE
+#define AUXINPUT2_PIN (31u) // ST2
+#define AUXINPUT3_PIN (14u) // ST3
+#endif
+#endif
+
+// Define auxillary output pins
+#define AUXOUTPUT0_PIN (32U)
+#define AUXOUTPUT1_PIN (33U)
+#define AUXOUTPUT2_PIN (34U)
+#define AUX_N_OUT 3
+#define AUX_OUT_MASK 0b111
+
+#if KEYPAD_ENABLE
+#define KEYPAD_STROBE_PIN (41U)
+#endif
+
+#if EEPROM_ENABLE || KEYPAD_ENABLE
+#define I2C_PORT 4
+#define I2C_SCL4 (24u) // Not used, for info only
+#define I2C_SDA4 (25u) // Not used, for info only
+#endif
diff --git a/grblHAL_Teensy4/src/T41U5XBB.c b/grblHAL_Teensy4/src/T41U5XBB.c
index 9543b53..0ce25b5 100644
--- a/grblHAL_Teensy4/src/T41U5XBB.c
+++ b/grblHAL_Teensy4/src/T41U5XBB.c
@@ -23,7 +23,7 @@
#include "driver.h"
-#if defined(BOARD_T41U5XBB) || defined(BOARD_T41U5XBB_SS)
+#if defined(BOARD_T41U5XBB) || defined(BOARD_T41U5XBB_SS) || defined(BOARD_T41BB5X_PRO)
//#include "Arduino.h"
#include
diff --git a/grblHAL_Teensy4/src/driver.c b/grblHAL_Teensy4/src/driver.c
index a47e9e5..90f31a3 100644
--- a/grblHAL_Teensy4/src/driver.c
+++ b/grblHAL_Teensy4/src/driver.c
@@ -63,6 +63,10 @@ static void ppi_timeout_isr (void);
#include "odometer/odometer.h"
#endif
+#if OPENPNP_ENABLE
+#include "openpnp/openpnp.h"
+#endif
+
#if ETHERNET_ENABLE
#include "enet.h"
#if TELNET_ENABLE
@@ -2102,7 +2106,7 @@ bool driver_init (void)
options[strlen(options) - 1] = '\0';
hal.info = "iMXRT1062";
- hal.driver_version = "210423";
+ hal.driver_version = "210509";
#ifdef BOARD_NAME
hal.board = BOARD_NAME;
#endif
@@ -2290,7 +2294,9 @@ bool driver_init (void)
plasma_init();
#endif
- my_plugin_init();
+#if OPENPNP_ENABLE
+ openpnp_init();
+#endif
#if ODOMETER_ENABLE
odometer_init(); // NOTE: this *must* be last plugin to be initialized as it claims storage at the end of NVS.
diff --git a/grblHAL_Teensy4/src/driver.h b/grblHAL_Teensy4/src/driver.h
index 9ea8cbe..e45f7da 100644
--- a/grblHAL_Teensy4/src/driver.h
+++ b/grblHAL_Teensy4/src/driver.h
@@ -66,6 +66,9 @@
#ifndef ODOMETER_ENABLE
#define ODOMETER_ENABLE 0
#endif
+#ifndef OPENPNP_ENABLE
+#define OPENPNP_ENABLE 0
+#endif
#ifndef ETHERNET_ENABLE
#define ETHERNET_ENABLE 0
@@ -165,8 +168,8 @@
#include "T41U5XBB_map.h"
#elif defined(BOARD_T41U5XBB_SS)
#include "T41U5XBB_ss_map.h"
-#elif defined(BOARD_T41PROBB)
- #include "T41ProBB_map.h"
+#elif defined(BOARD_T41BB5X_PRO)
+ #include "T41BB5X_Pro_map.h"
#elif defined(BOARD_MY_MACHINE)
#include "my_machine_map.h"
#else // default board
diff --git a/grblHAL_Teensy4/src/my_machine.h b/grblHAL_Teensy4/src/my_machine.h
index 1d33c87..16c5861 100644
--- a/grblHAL_Teensy4/src/my_machine.h
+++ b/grblHAL_Teensy4/src/my_machine.h
@@ -26,6 +26,7 @@
//#define BOARD_T40X101
#define BOARD_T41U5XBB
//#define BOARD_T41U5XBB_SS // For a modified T41U5XBB board, allows spindle sync to be enabled.
+//#define BOARD_T41BB5X_PRO
//#define BOARD_CNC_BOOSTERPACK
//#define BOARD_MY_MACHINE // Add my_machine_map.h before enabling this!
@@ -37,6 +38,7 @@
----------------------|-----------|---------|--------|--------|--------|
BOARD_T40X101 | no | no | yes | yes³ | max 4 |
BOARD_T41U5XBB | yes | yes | yes | yes³ | max 5 |
+BOARD_T41BB5X_PRO | yes | yes | yes | yes | max 5 |
BOARD_CNC_BOOSTERPACK | yes² | yes | yes | yes | max 3 |
¹ Teensy 4.1 only
@@ -52,15 +54,16 @@ N_AXIS has a default value of 3, edit grbl\config.h to increase.
//#define SPINDLE_HUANYANG 1 // Set to 1 or 2 for Huanyang VFD spindle. Requires spindle plugin.
//#define QEI_ENABLE 1 // Enable quadrature encoder interfaces. Max value is 1. Requires encoder plugin.
//#define ETHERNET_ENABLE 1 // Ethernet streaming. Requires networking plugin.
-//#define SDCARD_ENABLE 1 // Run gcode programs from SD card, requires sdcard plugin.
+//#define SDCARD_ENABLE 2 // Run gcode programs from SD card, requires sdcard plugin.
//#define KEYPAD_ENABLE 1 // I2C keypad for jogging etc., requires keypad plugin.
//#define PLASMA_ENABLE 1 // Plasma/THC plugin. To be completed.
//#define PPI_ENABLE 1 // Laser PPI plugin. To be completed.
-//#define ODOMETER_ENABLE 1 // Odometer plugin. To be completed.
+//#define ODOMETER_ENABLE 1 // Odometer plugin.
+//#define OPENPNP_ENABLE 1 // OpenPNP plugin. To be completed.
//#define EEPROM_ENABLE 1 // I2C EEPROM support. Set to 1 for 24LC16(2K), 2 for larger sizes. Requires eeprom plugin.
//#define EEPROM_IS_FRAM 1 // Uncomment when EEPROM is enabled and chip is FRAM, this to remove write delay.
//#define SPINDLE_SYNC_ENABLE 1 // Enable spindle sync support (G33, G76). !! NOTE: Alpha quality - enable only for test or verification.
- // Currently only available for BOARD_T41U5XBB_SS.
+ // Currently only available for BOARD_T41BB5X_PRO and BOARD_T41U5XBB_SS.
//#define ESTOP_ENABLE 0 // When enabled only real-time report requests will be executed when the reset pin is asserted.
// Note: if left commented out the default setting is determined from COMPATIBILITY_LEVEL.
diff --git a/grblHAL_Teensy4/src/openpnp/openpnp.c b/grblHAL_Teensy4/src/openpnp/openpnp.c
new file mode 100644
index 0000000..53cae8f
--- /dev/null
+++ b/grblHAL_Teensy4/src/openpnp/openpnp.c
@@ -0,0 +1,186 @@
+/*
+
+ openpnp.c - plugin for for OpenPNP required M-codes
+
+ Part of grblHAL
+
+ Copyright (c) 2021 Terje Io
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+
+*/
+
+#include "driver.h"
+
+#if OPENPNP_ENABLE
+
+#include
+
+#include "grbl/hal.h"
+#include "grbl/protocol.h"
+
+static user_mcode_ptrs_t user_mcode;
+static on_report_options_ptr on_report_options;
+
+static user_mcode_t userMCodeCheck (user_mcode_t mcode)
+{
+ return (uint32_t)mcode == 42 || (uint32_t)mcode == 114 || (uint32_t)mcode == 115 || (uint32_t)mcode == 204 || mcode == (uint32_t)400
+ ? mcode
+ : (user_mcode.check ? user_mcode.check(mcode) : UserMCode_Ignore);
+}
+
+static status_code_t userMCodeValidate (parser_block_t *gc_block, parameter_words_t *value_words)
+{
+ status_code_t state = Status_GcodeValueWordMissing;
+
+ switch((uint32_t)gc_block->user_mcode) {
+
+ case 42:
+ if((*value_words).p && (*value_words).s) {
+
+ if((*value_words).p && isnan(gc_block->values.p))
+ state = Status_BadNumberFormat;
+
+ if((*value_words).s && isnan(gc_block->values.s))
+ state = Status_BadNumberFormat;
+
+ if(state != Status_BadNumberFormat) {
+ if(gc_block->values.p <= 255.0f && (uint8_t)gc_block->values.p < hal.port.num_digital_out) {
+ (*value_words).p = (*value_words).s = Off;
+ state = Status_OK;
+ } else
+ state = Status_InvalidStatement;
+ }
+ }
+ break;
+
+ case 114:
+ (*value_words).d = Off;
+ // check if d value is 0 or 1?
+ state = Status_OK;
+ break;
+
+ case 204:
+ if((*value_words).p && isnan(gc_block->values.p))
+ state = Status_BadNumberFormat;
+
+ if((*value_words).r && isnan(gc_block->values.r))
+ state = Status_BadNumberFormat;
+
+ if((*value_words).s && isnan(gc_block->values.s))
+ state = Status_BadNumberFormat;
+
+ if(state != Status_BadNumberFormat) {
+ (*value_words).p = (*value_words).r = (*value_words).s = (*value_words).t = Off;
+ // TODO: add validation
+ state = Status_OK;
+ }
+ break;
+
+ case 115:
+ case 400:
+ state = Status_OK;
+ break;
+
+ default:
+ state = Status_Unhandled;
+ break;
+ }
+
+ return state == Status_Unhandled && user_mcode.validate ? user_mcode.validate(gc_block, value_words) : state;
+}
+
+static void report_position (void)
+{
+ uint_fast8_t idx;
+ int32_t current_position[N_AXIS];
+ float print_position[N_AXIS];
+ char buf[(STRLEN_COORDVALUE + 4) * N_AXIS];
+
+ memcpy(current_position, sys.position, sizeof(sys.position));
+ system_convert_array_steps_to_mpos(print_position, current_position);
+
+ *buf = '\0';
+ for (idx = 0; idx < N_AXIS; idx++) {
+ print_position[idx] -= gc_get_offset(idx);
+ strcat(buf, axis_letter[idx]);
+ strcat(buf, ":");
+ strcat(buf, ftoa(print_position[idx], N_DECIMAL_COORDVALUE_MM)); // always mm and 4 decimals?
+ strcat(buf, idx == N_AXIS - 1 ? ASCII_EOL : " ");
+ }
+
+ hal.stream.write(buf);
+}
+
+static void userMCodeExecute (uint_fast16_t state, parser_block_t *gc_block)
+{
+ bool handled = true;
+
+ if (state != STATE_CHECK_MODE)
+ switch((uint32_t)gc_block->user_mcode) {
+
+ case 42:
+ hal.port.digital_out(gc_block->values.p, gc_block->values.s != 0.0f);
+ break;
+
+ case 114:
+ report_position();
+ break;
+
+ case 115:
+ hal.stream.write("FIRMWARE_NAME:grblHAL ");
+ hal.stream.write("FIRMWARE_URL:https%3A//github.com/grblHAL ");
+ hal.stream.write("FIRMWARE_VERSION:" GRBL_VERSION " ");
+ hal.stream.write("FIRMWARE_BUILD:" GRBL_VERSION_BUILD ASCII_EOL);
+ break;
+
+ case 204:
+ protocol_buffer_synchronize();
+ // TODO: set acceleration - needs core modification
+ break;
+
+ case 400:
+ protocol_buffer_synchronize();
+ break;
+
+ default:
+ handled = false;
+ break;
+ }
+
+ if(!handled && user_mcode.execute)
+ user_mcode.execute(state, gc_block);
+}
+
+static void onReportOptions (bool newopt)
+{
+ on_report_options(newopt);
+
+ if(!newopt)
+ hal.stream.write("[PLUGIN:OpenPNP v0.01]" ASCII_EOL);
+}
+
+void openpnp_init (void)
+{
+ memcpy(&user_mcode, &hal.user_mcode, sizeof(user_mcode_ptrs_t));
+
+ hal.user_mcode.check = userMCodeCheck;
+ hal.user_mcode.validate = userMCodeValidate;
+ hal.user_mcode.execute = userMCodeExecute;
+
+ on_report_options = grbl.on_report_options;
+ grbl.on_report_options = onReportOptions;
+}
+
+#endif
diff --git a/grblHAL_Teensy4/src/openpnp/openpnp.h b/grblHAL_Teensy4/src/openpnp/openpnp.h
new file mode 100644
index 0000000..72c87bb
--- /dev/null
+++ b/grblHAL_Teensy4/src/openpnp/openpnp.h
@@ -0,0 +1,29 @@
+/*
+
+ openpnp.h - plugin for for OpenPNP required M-codes
+
+ Part of grblHAL
+
+ Copyright (c) 2021 Terje Io
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+
+*/
+
+#ifndef _OPENPNP_H_
+#define _OPENPNP_H_
+
+void openpnp_init (void);
+
+#endif