diff --git a/grblHAL_Teensy4/src/T40X101_map.h b/grblHAL_Teensy4/src/T40X101_map.h
index 45a0320..fa5faa9 100644
--- a/grblHAL_Teensy4/src/T40X101_map.h
+++ b/grblHAL_Teensy4/src/T40X101_map.h
@@ -23,81 +23,49 @@
#define BOARD_NAME "T40X101"
-#if N_AXIS > 4
-#error Max number of axes is 4 for T40X101
+#if N_ABC_MOTORS > 2
+#error "Axis configuration is not supported!"
#endif
#if QEI_ENABLE
-#error No pins available for encoder input!
+#error "No pins available for encoder input!"
#endif
#if SPINDLE_SYNC_ENABLE
-#error Spindle sync is not supported for T40X101
+#error "Spindle sync is not supported for T40X101!"
#endif
-// Default pin assignments allow only one axis to be ganged or auto squared.
-// A 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_LIMIT_PIN (20u)
-#define X_STEP_PIN (2u)
-#define X_DIRECTION_PIN (3u)
-#define X_LIMIT_PIN (20u)
+#define Y_STEP_PIN (4u)
+#define Y_DIRECTION_PIN (5u)
+#define Y_LIMIT_PIN (21u)
-#if X_GANGED || X_AUTO_SQUARE
-#define X2_STEP_PIN (8u)
-#define X2_DIRECTION_PIN (9u)
-#if X_AUTO_SQUARE
- #define X2_LIMIT_PIN (23u)
-#endif
+#define Z_STEP_PIN (6u)
+#define Z_DIRECTION_PIN (7u)
+#define Z_LIMIT_PIN (22u)
+
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN (8u)
+#define M3_DIRECTION_PIN (9u)
+#define M3_LIMIT_PIN (23u)
#endif
-#define Y_STEP_PIN (4u)
-#define Y_DIRECTION_PIN (5u)
-#define Y_LIMIT_PIN (21u)
-
-#if Y_GANGED || Y_AUTO_SQUARE
-#define Y2_STEP_PIN (8u)
-#define Y2_DIRECTION_PIN (9u)
-#if Y_AUTO_SQUARE
- #define Y2_LIMIT_PIN (23u)
-#endif
-#endif
-
-#define Z_STEP_PIN (6u)
-#define Z_DIRECTION_PIN (7u)
-#define Z_LIMIT_PIN (22u)
-
-#if Z_GANGED || Z_AUTO_SQUARE
-#define Z2_STEP_PIN (8u)
-#define Z2_DIRECTION_PIN (9u)
-#if Z_AUTO_SQUARE
- #define Z2_LIMIT_PIN (23u)
-#endif
-#endif
-
-#if N_AXIS > 3
-#define A_STEP_PIN (8u)
-#define A_DIRECTION_PIN (9u)
-#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)
+// Define ganged axis or B axis step pulse and step direction output pins.
+#if N_ABC_MOTORS == 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN (26u)
+#define M4_DIRECTION_PIN (27u)
+#define M4_LIMIT_PIN (28u)
+#define M4_ENABLE_PIN (37u)
#endif
// Define stepper driver enable/disable output pin(s).
-#define STEPPERS_ENABLE_PIN (10u)
+#define STEPPERS_ENABLE_PIN (10u)
// Define spindle enable and spindle direction output pins.
#define SPINDLE_ENABLE_PIN (12u)
diff --git a/grblHAL_Teensy4/src/T41BB5X_Pro_map.h b/grblHAL_Teensy4/src/T41BB5X_Pro_map.h
index b528197..8d2bae5 100644
--- a/grblHAL_Teensy4/src/T41BB5X_Pro_map.h
+++ b/grblHAL_Teensy4/src/T41BB5X_Pro_map.h
@@ -21,8 +21,12 @@
along with Grbl. If not, see .
*/
+#if N_ABC_MOTORS > 2
+#error "Axis configuration is not supported!"
+#endif
+
#define BOARD_NAME "T41BB5X Pro"
-#define HAS_BOARD_INIT
+#define HAS_IOPORTS
#if N_AXIS > 5
#error Max number of axes is 5 for T41U5XBB
@@ -38,72 +42,37 @@
#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 1
-#define X_AUTO_SQUARE 1
-#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)
-#define X_STEP_PIN (2u)
-#define X_DIRECTION_PIN (3u)
-#define X_ENABLE_PIN (10u)
-#define X_LIMIT_PIN (20u)
+#define Y_STEP_PIN (4u)
+#define Y_DIRECTION_PIN (5u)
+#define Y_ENABLE_PIN (35u)
+#define Y_LIMIT_PIN (21u)
-#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
+#define Z_STEP_PIN (6u)
+#define Z_DIRECTION_PIN (7u)
+#define Z_ENABLE_PIN (39u)
+#define Z_LIMIT_PIN (22u)
+
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN (8u)
+#define M3_DIRECTION_PIN (9u)
+#define M3_LIMIT_PIN (23u)
+#define M3_ENABLE_PIN (38u)
#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)
+// Define ganged axis or B axis step pulse and step direction output pins.
+#if N_ABC_MOTORS == 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN (26u)
+#define M4_DIRECTION_PIN (27u)
+#define M4_LIMIT_PIN (28u)
+#define M4_ENABLE_PIN (37u)
#endif
// Define spindle enable and spindle direction output pins.
diff --git a/grblHAL_Teensy4/src/T41U5XBB_map.h b/grblHAL_Teensy4/src/T41U5XBB_map.h
index f16a2c2..5014a3a 100644
--- a/grblHAL_Teensy4/src/T41U5XBB_map.h
+++ b/grblHAL_Teensy4/src/T41U5XBB_map.h
@@ -21,84 +21,48 @@
along with Grbl. If not, see .
*/
-#define BOARD_NAME "T41U5XBB"
-#define HAS_BOARD_INIT
-
-#if N_AXIS > 5
-#error Max number of axes is 5 for T41U5XBB
+#if N_ABC_MOTORS > 2
+#error "Axis configuration is not supported!"
#endif
#if SPINDLE_SYNC_ENABLE
-#error Spindle sync is not supported for T41U5XBB
+#error "Spindle sync is not supported for T41U5XBB!"
#endif
-// 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 BOARD_NAME "T41U5XBB"
+#define HAS_IOPORTS
-#define X_STEP_PIN (2u)
-#define X_DIRECTION_PIN (3u)
-#define X_ENABLE_PIN (10u)
-#define X_LIMIT_PIN (20u)
+#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
+#define Y_STEP_PIN (4u)
+#define Y_DIRECTION_PIN (5u)
+#define Y_ENABLE_PIN (40u)
+#define Y_LIMIT_PIN (21u)
+
+#define Z_STEP_PIN (6u)
+#define Z_DIRECTION_PIN (7u)
+#define Z_ENABLE_PIN (39u)
+#define Z_LIMIT_PIN (22u)
+
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN (8u)
+#define M3_DIRECTION_PIN (9u)
+#define M3_LIMIT_PIN (23u)
+#define M3_ENABLE_PIN (38u)
#endif
-#define Y_STEP_PIN (4u)
-#define Y_DIRECTION_PIN (5u)
-#define Y_ENABLE_PIN (40u)
-#define Y_LIMIT_PIN (21u)
-
-// Changed to use A pins rather than B pins
-#if Y_GANGED || Y_AUTO_SQUARE
-#define Y2_STEP_PIN (8u)
-#define Y2_DIRECTION_PIN (9u)
-#define Y2_ENABLE_PIN (38u)
-#if Y_AUTO_SQUARE
- #define Y2_LIMIT_PIN (23u)
-#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)
+// Define ganged axis or B axis step pulse and step direction output pins.
+#if N_ABC_MOTORS == 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN (26u)
+#define M4_DIRECTION_PIN (27u)
+#define M4_LIMIT_PIN (28u)
+#define M4_ENABLE_PIN (37u)
#endif
// Define spindle enable and spindle direction output pins.
diff --git a/grblHAL_Teensy4/src/T41U5XBB_ss_map.h b/grblHAL_Teensy4/src/T41U5XBB_ss_map.h
index 3fd2506..5c62312 100644
--- a/grblHAL_Teensy4/src/T41U5XBB_ss_map.h
+++ b/grblHAL_Teensy4/src/T41U5XBB_ss_map.h
@@ -23,84 +23,48 @@
along with Grbl. If not, see .
*/
-#define BOARD_NAME "T41U5XBB"
-#define HAS_BOARD_INIT
-
-#if N_AXIS > 5
-#error Max number of axes is 5 for T41U5XBB
+#if N_ABC_MOTORS > 2
+#error "Axis configuration is not supported!"
#endif
#if QEI_ENABLE && SPINDLE_SYNC_ENABLE
-#error Quadrature encoder and spindle sync cannot be enabled at the same time
+#error "Quadrature encoder and spindle sync cannot be enabled at the same time!"
#endif
-// 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 BOARD_NAME "T41U5XBB"
+#define HAS_IOPORTS
-#define X_STEP_PIN (2u)
-#define X_DIRECTION_PIN (3u)
-#define X_ENABLE_PIN (10u)
-#define X_LIMIT_PIN (20u)
+#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
+#define Y_STEP_PIN (4u)
+#define Y_DIRECTION_PIN (5u)
+#define Y_ENABLE_PIN (40u)
+#define Y_LIMIT_PIN (21u)
+
+#define Z_STEP_PIN (6u)
+#define Z_DIRECTION_PIN (7u)
+#define Z_ENABLE_PIN (39u)
+#define Z_LIMIT_PIN (22u)
+
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN (8u)
+#define M3_DIRECTION_PIN (9u)
+#define M3_LIMIT_PIN (23u)
+#define M3_ENABLE_PIN (38u)
#endif
-#define Y_STEP_PIN (4u)
-#define Y_DIRECTION_PIN (5u)
-#define Y_ENABLE_PIN (40u)
-#define Y_LIMIT_PIN (21u)
-
-// Changed to use A pins rather than B pins
-#if Y_GANGED || Y_AUTO_SQUARE
-#define Y2_STEP_PIN (8u)
-#define Y2_DIRECTION_PIN (9u)
-#define Y2_ENABLE_PIN (38u)
-#if Y_AUTO_SQUARE
- #define Y2_LIMIT_PIN (23u)
-#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)
+// Define ganged axis or B axis step pulse and step direction output pins.
+#if N_ABC_MOTORS == 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN (26u)
+#define M4_DIRECTION_PIN (27u)
+#define M4_LIMIT_PIN (28u)
+#define M4_ENABLE_PIN (37u)
#endif
// Define spindle enable and spindle direction output pins.
diff --git a/grblHAL_Teensy4/src/cnc_boosterpack_map.h b/grblHAL_Teensy4/src/cnc_boosterpack_map.h
index c94254a..31a6854 100644
--- a/grblHAL_Teensy4/src/cnc_boosterpack_map.h
+++ b/grblHAL_Teensy4/src/cnc_boosterpack_map.h
@@ -21,12 +21,12 @@
#define BOARD_NAME "CNC BoosterPack"
-#if N_AXIS > 3
-#error Max number of axes is 3 for CNC BoosterPack
+#if N_ABC_MOTORS
+#error "Axis configuration is not supported!"
#endif
#if SPINDLE_SYNC_ENABLE
-#error Spindle sync is not supported for CNC BoosterPack
+#error "Spindle sync is not supported for CNC BoosterPack"
#endif
#ifdef EEPROM_ENABLE
diff --git a/grblHAL_Teensy4/src/driver.c b/grblHAL_Teensy4/src/driver.c
index b88f1c1..ff041f8 100644
--- a/grblHAL_Teensy4/src/driver.c
+++ b/grblHAL_Teensy4/src/driver.c
@@ -67,6 +67,10 @@ static void ppi_timeout_isr (void);
#include "openpnp/openpnp.h"
#endif
+#if BLUETOOTH_ENABLE
+#include "bluetooth/bluetooth.h"
+#endif
+
#if ETHERNET_ENABLE
#include "enet.h"
#if TELNET_ENABLE
@@ -96,17 +100,7 @@ static void ppi_timeout_isr (void);
#define F_BUS_MHZ (F_BUS_ACTUAL / 1000000)
-#if X_AUTO_SQUARE || Y_AUTO_SQUARE || Z_AUTO_SQUARE
-#define SQUARING_ENABLED
-#endif
-
-#if defined(X2_LIMIT_PIN) || defined(Y2_LIMIT_PIN) || defined(Z2_LIMIT_PIN) || defined(A2_LIMIT_PIN) || defined(B2_LIMIT_PIN)
-#define DUAL_LIMIT_SWITCHES
-#else
- #ifdef SQUARING_ENABLED
- #error "Squaring requires at least one axis with dual switch inputs!"
- #endif
-#endif
+#include "grbl/motor_pins.h"
typedef struct {
volatile uint_fast8_t head;
@@ -224,6 +218,9 @@ static gpio_t QEI_A, QEI_B;
#ifdef X2_LIMIT_PIN
static gpio_t LimitX2;
#endif
+#ifdef X_LIMIT_PIN_MAX
+ static gpio_t LimitXMax;
+#endif
#ifdef Y2_STEP_PIN
static gpio_t stepY2;
@@ -237,6 +234,9 @@ static gpio_t QEI_A, QEI_B;
#ifdef Y2_LIMIT_PIN
static gpio_t LimitY2;
#endif
+#ifdef Y_LIMIT_PIN_MAX
+ static gpio_t LimitYMax;
+#endif
#ifdef Z2_STEP_PIN
static gpio_t stepZ2;
@@ -250,6 +250,10 @@ static gpio_t QEI_A, QEI_B;
#ifdef Z2_LIMIT_PIN
static gpio_t LimitZ2;
#endif
+#ifdef Z_LIMIT_PIN_MAX
+ static gpio_t LimitZMax;
+#endif
+
#ifdef SPINDLE_INDEX_PIN
static gpio_t SpindleIndex;
#endif
@@ -295,15 +299,24 @@ input_signal_t inputpin[] = {
// Limit input pins must be consecutive
{ .id = Input_LimitX, .port = &LimitX, .pin = X_LIMIT_PIN, .group = PinGroup_Limit },
#ifdef X2_LIMIT_PIN
- { .id = Input_LimitX_Max, .port = &LimitX2, .pin = X2_LIMIT_PIN, .group = PinGroup_Limit },
+ { .id = Input_LimitX_2, .port = &LimitX2, .pin = X2_LIMIT_PIN, .group = PinGroup_Limit },
+#endif
+#ifdef X_LIMIT_PIN_MAX
+ { .id = Input_LimitX_Max, .port = &LimitXMax, .pin = X_LIMIT_PIN_MAX, .group = PinGroup_Limit },
#endif
{ .id = Input_LimitY, .port = &LimitY, .pin = Y_LIMIT_PIN, .group = PinGroup_Limit },
#ifdef Y2_LIMIT_PIN
- { .id = Input_LimitY_Max, .port = &LimitY2, .pin = Y2_LIMIT_PIN, .group = PinGroup_Limit },
+ { .id = Input_LimitY_2, .port = &LimitY2, .pin = Y2_LIMIT_PIN, .group = PinGroup_Limit },
+#endif
+#ifdef Y_LIMIT_PIN_MAX
+ { .id = Input_LimitY_Max, .port = &LimitYMax, .pin = Y_LIMIT_PIN_MAX, .group = PinGroup_Limit },
#endif
{ .id = Input_LimitZ, .port = &LimitZ, .pin = Z_LIMIT_PIN, .group = PinGroup_Limit }
#ifdef Z2_LIMIT_PIN
- , { .id = Input_LimitZ_Max, .port = &LimitZ2, .pin = Z2_LIMIT_PIN, .group = PinGroup_Limit }
+ , { .id = Input_LimitZ_2, .port = &LimitZ2, .pin = Z2_LIMIT_PIN, .group = PinGroup_Limit }
+#endif
+#ifdef Z_LIMIT_PIN_MAX
+ , { .id = Input_LimitZ_Max, .port = &LimitZMax, .pin = Z_LIMIT_PIN_MAX, .group = PinGroup_Limit }
#endif
#ifdef A_LIMIT_PIN
, { .id = Input_LimitA, .port = &LimitA, .pin = A_LIMIT_PIN, .group = PinGroup_Limit }
@@ -471,10 +484,6 @@ static spindle_pwm_t spindle_pwm;
static void spindle_set_speed (uint_fast16_t pwm_value);
#endif
-#if MODBUS_ENABLE
-static modbus_stream_t modbus_stream = {0};
-#endif
-
#if SPINDLE_SYNC_ENABLE
#include "grbl/spindle_sync.h"
@@ -493,8 +502,11 @@ static void spindle_pulse_isr (void);
#endif
+static const io_stream_t *serial_stream;
+
#if ETHERNET_ENABLE
static network_services_t services = {0};
+static stream_write_ptr write_serial;
static void enetStreamWriteS (const char *data)
{
@@ -506,50 +518,11 @@ static void enetStreamWriteS (const char *data)
if(services.websocket)
WsStreamWriteS(data);
#endif
-#if USB_SERIAL_CDC
- usb_serialWriteS(data);
-#else
- serialWriteS(data);
-#endif
+ if(write_serial)
+ write_serial(data);
}
#endif // ETHERNET_ENABLE
-#if USB_SERIAL_CDC
- const io_stream_t serial_stream = {
- .type = StreamType_Serial,
- .read = usb_serialGetC,
- .write = usb_serialWriteS,
- .write_char = usb_serialPutC,
- #if ETHERNET_ENABLE
- .write_all = enetStreamWriteS,
- #else
- .write_all = usb_serialWriteS,
- #endif
- .get_rx_buffer_available = usb_serialRxFree,
- .reset_read_buffer = usb_serialRxFlush,
- .cancel_read_buffer = usb_serialRxCancel,
- .suspend_read = usb_serialSuspendInput,
- .enqueue_realtime_command = protocol_enqueue_realtime_command
- };
-#else
-const io_stream_t serial_stream = {
- .type = StreamType_Serial,
- .read = serialGetC,
- .write = serialWriteS,
- .write_char = serialPutC,
-#if ETHERNET_ENABLE
- .write_all = enetStreamWriteS,
-#else
- .write_all = serialWriteS,
-#endif
- .get_rx_buffer_available = serialRxFree,
- .reset_read_buffer = serialRxFlush,
- .cancel_read_buffer = serialRxCancel,
- .suspend_read = serialSuspendInput,
- .enqueue_realtime_command = protocol_enqueue_realtime_command
-};
-#endif
-
// Interrupt handler prototypes
// Interrupt handlers needs to be registered, possibly by modifying a system specific startup file.
// It is possible to relocate the interrupt dispatch table from flash to RAM and programatically attach handlers.
@@ -587,12 +560,13 @@ static bool selectStream (const io_stream_t *stream)
{
static bool serial_connected = false;
static stream_type_t active_stream = StreamType_Serial;
+ static const io_stream_t *last_serial_stream;
- if(hal.stream.type == StreamType_Serial)
+ if(hal.stream.type == StreamType_Serial || hal.stream.type == StreamType_Bluetooth)
serial_connected = hal.stream.connected;
if(!stream)
- stream = &serial_stream;
+ stream = active_stream == StreamType_Bluetooth ? serial_stream : last_serial_stream;
memcpy(&hal.stream, stream, sizeof(io_stream_t));
@@ -607,6 +581,9 @@ static bool selectStream (const io_stream_t *stream)
if(!hal.stream.enqueue_realtime_command)
hal.stream.enqueue_realtime_command = protocol_enqueue_realtime_command;
+ if(hal.stream.disable)
+ hal.stream.disable(false);
+
switch(stream->type) {
#if TELNET_ENABLE
@@ -624,12 +601,21 @@ static bool selectStream (const io_stream_t *stream)
case StreamType_Serial:
#if ETHERNET_ENABLE
services.mask = 0;
+ write_serial = serial_connected ? hal.stream.write : NULL;
#endif
hal.stream.connected = serial_connected;
+ last_serial_stream = stream;
if(active_stream != StreamType_Serial && hal.stream.connected)
hal.stream.write_all("[MSG:SERIAL STREAM ACTIVE]" ASCII_EOL);
break;
+ case StreamType_Bluetooth:
+#if ETHERNET_ENABLE
+ services.mask = 0;
+ write_serial = hal.stream.write;
+#endif
+ last_serial_stream = stream;
+ break;
default:
break;
}
@@ -643,6 +629,7 @@ static bool selectStream (const io_stream_t *stream)
// step_outbits.value (or step_outbits.mask) are: bit0 -> X, bit1 -> Y...
// Individual step bits can be accessed by step_outbits.x, step_outbits.y, ...
#ifdef SQUARING_ENABLED
+
inline static __attribute__((always_inline)) void set_step_outputs (axes_signals_t step_outbits_1)
{
axes_signals_t step_outbits_2;
@@ -672,7 +659,33 @@ inline static __attribute__((always_inline)) void set_step_outputs (axes_signals
DIGITAL_OUT(stepB, step_outbits_1.b);
#endif
}
+
+static axes_signals_t getAutoSquaredAxes (void)
+{
+ axes_signals_t ganged = {0};
+
+#if X_AUTO_SQUARE
+ ganged.x = On;
+#endif
+#if Y_AUTO_SQUARE
+ ganged.y = On;
+#endif
+#if Z_AUTO_SQUARE
+ ganged.z = On;
+#endif
+
+ return ganged;
+}
+
+// Enable/disable motors for auto squaring of ganged axes
+static void StepperDisableMotors (axes_signals_t axes, squaring_mode_t mode)
+{
+ motors_1.mask = (mode == SquaringMode_A || mode == SquaringMode_Both ? axes.mask : 0) ^ AXES_BITMASK;
+ motors_2.mask = (mode == SquaringMode_B || mode == SquaringMode_Both ? axes.mask : 0) ^ AXES_BITMASK;
+}
+
#else
+
inline static __attribute__((always_inline)) void set_step_outputs (axes_signals_t step_outbits)
{
step_outbits.value ^= settings.steppers.step_invert.mask;
@@ -702,7 +715,8 @@ inline static __attribute__((always_inline)) void set_step_outputs (axes_signals
DIGITAL_OUT(stepC, step_outbits.c);
#endif
}
-#endif
+
+#endif // SQUARING_ENABLED
// Set stepper direction ouput pins.
// dir_outbits.value (or dir_outbits.mask) are: bit0 -> X, bit1 -> Y...
@@ -988,8 +1002,6 @@ void stepperOutputStep (axes_signals_t step_outbits, axes_signals_t dir_outbits)
#endif
-#ifdef DUAL_LIMIT_SWITCHES
-
// Returns limit state as an axes_signals_t variable.
// Each bitfield bit indicates an axis limit, where triggered is 1 and not triggered is 0.
// Dual limit switch inputs per axis version. Only one needs to be dual input!
@@ -998,100 +1010,59 @@ inline static limit_signals_t limitsGetState()
limit_signals_t signals = {0};
signals.min.mask = signals.min2.mask = settings.limits.invert.mask;
+#ifdef DUAL_LIMIT_SWITCHES
+ signals.min2.mask = settings.limits.invert.mask;
+#endif
+#ifdef MAX_LIMIT_SWITCHES
+ signals.max.mask = settings.limits.invert.mask;
+#endif
- signals.min.x = (LimitX.reg->DR & LimitX.bit) != 0;
+ signals.min.x = DIGITAL_IN(LimitX);
#ifdef X2_LIMIT_PIN
- signals.min2.x = (LimitX2.reg->DR & LimitX2.bit) != 0;
+ signals.min2.x = DIGITAL_IN(LimitX2);
+#endif
+#ifdef X_LIMIT_PIN_MAX
+ signals.max.x = DIGITAL_IN(LimitXMax);
#endif
- signals.min.y = (LimitY.reg->DR & LimitY.bit) != 0;
+ signals.min.y = DIGITAL_IN(LimitY);
#ifdef Y2_LIMIT_PIN
- signals.min2.y = (LimitY2.reg->DR & LimitY2.bit) != 0;
+ signals.min2.y = DIGITAL_IN(LimitY2);
+#endif
+#ifdef Y_LIMIT_PIN_MAX
+ signals.max.y = DIGITAL_IN(LimitYMax);
#endif
- signals.min.z = (LimitZ.reg->DR & LimitZ.bit) != 0;
+ signals.min.z = DIGITAL_IN(LimitZ);
#ifdef Z2_LIMIT_PIN
- signals.min2.z = (LimitZ2.reg->DR & LimitZ2.bit) != 0;
+ signals.min2.z = DIGITAL_IN(LimitZ2);
+#endif
+#ifdef Z_LIMIT_PIN_MAX
+ signals.max.z = DIGITAL_IN(LimitZMax);
#endif
#ifdef A_LIMIT_PIN
- signals.min.a = (LimitA.reg->DR & LimitA.bit) != 0;
+ signals.min.a = DIGITAL_IN(LimitA);
#endif
#ifdef B_LIMIT_PIN
- signals.min.b = (LimitB.reg->DR & LimitB.bit) != 0;
+ signals.min.b = DIGITAL_IN(LimitB);
#endif
#ifdef C_LIMIT_PIN
- signals.min.c = (LimitC.reg->DR & LimitC.bit) != 0;
+ signals.min.c = DIGITAL_IN(LimitC);
#endif
if(settings.limits.invert.mask) {
signals.min.value ^= settings.limits.invert.mask;
- signals.min2.value ^= settings.limits.invert.mask;
+#ifdef DUAL_LIMIT_SWITCHES
+ signals.min2.mask ^= settings.limits.invert.mask;
+#endif
+#ifdef MAX_LIMIT_SWITCHES
+ signals.max.value ^= settings.limits.invert.mask;
+#endif
}
return signals;
}
-#else // SINGLE INPUT LIMIT SWITCHES
-
-// Returns limit state as an axes_signals_t bitmap variable.
-// signals.value (or signals.mask) are: bit0 -> X, bit1 -> Y...
-// Individual signals bits can be accessed by signals.x, signals.y, ...
-// Each bit indicates a limit signal, where triggered is 1 and not triggered is 0.
-// axes_signals_t is defined in grbl/nuts_bolts.h.
-inline static limit_signals_t limitsGetState()
-{
- limit_signals_t signals = {0};
-
- signals.min.mask = settings.limits.invert.mask;
-
- signals.min.x = (LimitX.reg->DR & LimitX.bit) != 0;
- signals.min.y = (LimitY.reg->DR & LimitY.bit) != 0;
- signals.min.z = (LimitZ.reg->DR & LimitZ.bit) != 0;
-#ifdef A_LIMIT_PIN
- signals.min.a = (LimitA.reg->DR & LimitA.bit) != 0;
-#endif
-#ifdef B_LIMIT_PIN
- signals.min.b = (LimitB.reg->DR & LimitB.bit) != 0;
-#endif
-#ifdef C_LIMIT_PIN
- signals.min.c = (LimitC.reg->DR & LimitC.bit) != 0;
-#endif
-
- if (settings.limits.invert.mask)
- signals.min.value ^= settings.limits.invert.mask;
-
- return signals;
-}
-
-#endif
-
-#ifdef SQUARING_ENABLED
-
-static axes_signals_t getAutoSquaredAxes (void)
-{
- axes_signals_t ganged = {0};
-
- #if X_AUTO_SQUARE
- ganged.x = On;
-#endif
-#if Y_AUTO_SQUARE
- ganged.y = On;
-#endif
-#if Z_AUTO_SQUARE
- ganged.z = On;
-#endif
-
- return ganged;
-}
-
-// Enable/disable motors for auto squaring of ganged axes
-static void StepperDisableMotors (axes_signals_t axes, squaring_mode_t mode)
-{
- motors_1.mask = (mode == SquaringMode_A || mode == SquaringMode_Both ? axes.mask : 0) ^ AXES_BITMASK;
- motors_2.mask = (mode == SquaringMode_B || mode == SquaringMode_Both ? axes.mask : 0) ^ AXES_BITMASK;
-}
-
-#endif
// Enable/disable limit pins interrupt.
// NOTE: the homing parameter is indended for configuring advanced
@@ -1633,6 +1604,7 @@ static void settings_changed (settings_t *settings)
break;
case Input_LimitX:
+ case Input_LimitX_2:
case Input_LimitX_Max:
pullup = !settings->limits.disable_pullup.x;
signal->debounce = hal.driver_cap.software_debounce;
@@ -1640,12 +1612,14 @@ static void settings_changed (settings_t *settings)
break;
case Input_LimitY:
+ case Input_LimitY_2:
case Input_LimitY_Max:
pullup = !settings->limits.disable_pullup.y;
signal->irq_mode = limit_fei.y ? IRQ_Mode_Falling : IRQ_Mode_Rising;
break;
case Input_LimitZ:
+ case Input_LimitZ_2:
case Input_LimitZ_Max:
pullup = !settings->limits.disable_pullup.z;
signal->irq_mode = limit_fei.z ? IRQ_Mode_Falling : IRQ_Mode_Rising;
@@ -1718,42 +1692,30 @@ static void settings_changed (settings_t *settings)
break;
}
+ if(signal->group == PinGroup_AuxInput) {
+ signal->cap.pull_mode = (PullMode_Up|PullMode_Down);
+ signal->cap.irq_mode = (IRQ_Mode_Rising|IRQ_Mode_Falling);
+ }
+
pinMode(signal->pin, pullup ? INPUT_PULLUP : INPUT_PULLDOWN);
signal->gpio.reg = (gpio_reg_t *)digital_pin_to_info_PGM[signal->pin].reg;
signal->gpio.bit = digital_pin_to_info_PGM[signal->pin].mask;
+ if(signal->gpio.reg == (gpio_reg_t *)&GPIO6_DR)
+ signal->offset = 0;
+ else if(signal->gpio.reg == (gpio_reg_t *)&GPIO7_DR)
+ signal->offset = 1;
+ else if(signal->gpio.reg == (gpio_reg_t *)&GPIO8_DR)
+ signal->offset = 2;
+ else
+ signal->offset = 3;
+
if(signal->port != NULL)
memcpy(signal->port, &signal->gpio, sizeof(gpio_t));
if(signal->irq_mode != IRQ_Mode_None) {
- if(signal->gpio.reg == (gpio_reg_t *)&GPIO6_DR)
- signal->offset = 0;
- else if(signal->gpio.reg == (gpio_reg_t *)&GPIO7_DR)
- signal->offset = 1;
- else if(signal->gpio.reg == (gpio_reg_t *)&GPIO8_DR)
- signal->offset = 2;
- else
- signal->offset = 3;
-
- if(signal->irq_mode == IRQ_Mode_Change)
- signal->gpio.reg->EDGE_SEL |= signal->gpio.bit;
- else {
- signal->gpio.reg->EDGE_SEL &= ~signal->gpio.bit;
- uint32_t iopin = __builtin_ctz(signal->gpio.bit);
- if(iopin < 16) {
- uint32_t shift = iopin << 1;
- signal->gpio.reg->ICR1 = (signal->gpio.reg->ICR1 & ~(0b11 << shift)) | (signal->irq_mode << shift);
- } else {
- uint32_t shift = (iopin - 16) << 1;
- signal->gpio.reg->ICR2 = (signal->gpio.reg->ICR2 & ~(0b11 << shift)) | (signal->irq_mode << shift);
- }
- }
-
- signal->gpio.reg->ISR = signal->gpio.bit; // Clear interrupt.
-
- if(signal->group != PinGroup_Limit) // If pin is not a limit pin
- signal->gpio.reg->IMR |= signal->gpio.bit; // enable interrupt
+ pinEnableIRQ(signal, signal->irq_mode);
signal->active = (signal->gpio.reg->DR & signal->gpio.bit) != 0;
@@ -1803,6 +1765,45 @@ void pinModeOutput (gpio_t *gpio, uint8_t pin)
gpio->bit = digital_pin_to_info_PGM[pin].mask;
}
+void pinEnableIRQ (const input_signal_t *signal, pin_irq_mode_t irq_mode)
+{
+ if(irq_mode == IRQ_Mode_None)
+ signal->gpio.reg->IMR &= ~signal->gpio.bit; // Disable interrupt
+ else if(irq_mode == IRQ_Mode_Change)
+ signal->gpio.reg->EDGE_SEL |= signal->gpio.bit;
+ else {
+ uint32_t iopin = __builtin_ctz(signal->gpio.bit), shift, mode = 0;
+
+ switch(irq_mode) {
+ case IRQ_Mode_Rising:
+ mode = 0b10;
+ break;
+ case IRQ_Mode_Falling:
+ mode = 0b11;
+ break;
+ case IRQ_Mode_High:
+ mode = 0b10;
+ break;
+ default: // Low
+ mode = 0b00;
+ break;
+ }
+ signal->gpio.reg->EDGE_SEL &= ~signal->gpio.bit;
+ if(iopin < 16) {
+ shift = iopin << 1;
+ signal->gpio.reg->ICR1 = (signal->gpio.reg->ICR1 & ~(0b11 << shift)) | (mode << shift);
+ } else {
+ shift = (iopin - 16) << 1;
+ signal->gpio.reg->ICR2 = (signal->gpio.reg->ICR2 & ~(0b11 << shift)) | (mode << shift);
+ }
+ }
+
+ signal->gpio.reg->ISR = signal->gpio.bit; // Clear interrupt.
+
+ if(!(irq_mode == IRQ_Mode_None || signal->group == PinGroup_Limit)) // If pin is not a limit pin
+ signal->gpio.reg->IMR |= signal->gpio.bit; // enable interrupt
+}
+
#if QEI_ENABLE
static void qei_update (void)
@@ -2165,7 +2166,7 @@ bool driver_init (void)
options[strlen(options) - 1] = '\0';
hal.info = "iMXRT1062";
- hal.driver_version = "210605";
+ hal.driver_version = "210617";
#ifdef BOARD_NAME
hal.board = BOARD_NAME;
#endif
@@ -2219,15 +2220,15 @@ bool driver_init (void)
grbl.on_report_options = reportIP;
#endif
- hal.stream_select = selectStream;
- hal.stream_select(&serial_stream);
-
#if USB_SERIAL_CDC
- usb_serialInit();
+ serial_stream = usb_serialInit();
#else
- serialInit(115200);
+ serial_stream = serialInit(115200);
#endif
+ hal.stream_select = selectStream;
+ hal.stream_select(serial_stream);
+
#ifdef I2C_PORT
i2c_init();
#endif
@@ -2257,30 +2258,13 @@ bool driver_init (void)
#if QEI_ENABLE
hal.encoder.reset = qei_reset;
hal.encoder.on_event = encoder_event;
-#endif
-
-#if MODBUS_ENABLE
- modbus_stream.write = serialWrite;
- modbus_stream.read = serialGetC;
- modbus_stream.flush_rx_buffer = serialRxFlush;
- modbus_stream.flush_tx_buffer = serialTxFlush;
- modbus_stream.get_rx_buffer_count = serialRxCount;
- modbus_stream.get_tx_buffer_count = serialTxCount;
- modbus_stream.set_baud_rate = serialSetBaudRate;
-
- bool modbus = modbus_init(&modbus_stream);
-
-#if SPINDLE_HUANYANG
- if(modbus)
- huanyang_init(&modbus_stream);
-#endif
-
#endif
// Driver capabilities, used for announcing and negotiating (with Grbl) driver functionality.
// See driver_cap_t union i grbl/hal.h for available flags.
#if ESTOP_ENABLE
+ hal.signals_cap.reset = Off;
hal.signals_cap.e_stop = On;
#endif
#if SAFETY_DOOR_ENABLE
@@ -2321,13 +2305,13 @@ bool driver_init (void)
for(i = 0 ; i < sizeof(inputpin) / sizeof(input_signal_t); i++) {
signal = &inputpin[i];
-
+#ifdef HAS_IOPORTS
if(signal->group == PinGroup_AuxInput) {
if(aux_inputs.pins.inputs == NULL)
aux_inputs.pins.inputs = signal;
aux_inputs.n_pins++;
}
-
+#endif
if(signal->group == PinGroup_Limit) {
if(limit_inputs.pins.inputs == NULL)
limit_inputs.pins.inputs = signal;
@@ -2335,6 +2319,7 @@ bool driver_init (void)
}
}
+#ifdef HAS_IOPORTS
output_signal_t *output;
for(i = 0 ; i < sizeof(outputpin) / sizeof(output_signal_t); i++) {
output = &outputpin[i];
@@ -2345,14 +2330,17 @@ bool driver_init (void)
}
}
-#ifdef HAS_BOARD_INIT
- board_init(&aux_inputs, &aux_outputs);
+ ioports_init(&aux_inputs, &aux_outputs);
#endif
#if ETHERNET_ENABLE
grbl_enet_init();
#endif
+#if SPINDLE_HUANYANG
+ huanyang_init(modbus_init(serialInit(115200), NULL));
+#endif
+
#if KEYPAD_ENABLE
keypad_init();
#endif
@@ -2370,6 +2358,10 @@ bool driver_init (void)
openpnp_init();
#endif
+#if BLUETOOTH_ENABLE
+ bluetooth_init(serialInit(115200));
+#endif
+
#if ODOMETER_ENABLE
odometer_init(); // NOTE: this *must* be last plugin to be initialized as it claims storage at the end of NVS.
#endif
@@ -2548,16 +2540,17 @@ static void gpio_isr (void)
uint32_t i = sizeof(inputpin) / sizeof(input_signal_t);
do {
- if(inputpin[--i].irq_mode != IRQ_Mode_None) {
+ if(inputpin[--i].irq_mode != IRQ_Mode_None || inputpin[i].group == PinGroup_AuxInput) {
if(intr_status[inputpin[i].offset] & inputpin[i].gpio.bit) {
inputpin[i].active = true;
+
if(inputpin[i].debounce && enqueue_debounce(&inputpin[i])) {
inputpin[i].gpio.reg->IMR &= ~inputpin[i].gpio.bit;
debounce = true;
- } else {
+ } else switch(inputpin[i].group) {
#if QEI_ENABLE
- if(inputpin[i].group & PinGroup_QEI) {
+ casePinGroup_QEI:
qei_update();
/*
QEI_A.reg->IMR &= ~QEI_A.bit; // Switch off
@@ -2567,19 +2560,33 @@ static void gpio_isr (void)
qei.debounce = QEI_DEBOUNCE;
qei.initial_debounce = true;
*/
- } else
+ break;
#endif
#if SPINDLE_SYNC_ENABLE && defined(SPINDLE_INDEX_PIN)
- if(inputpin[i].group & PinGroup_SpindleIndex) {
+ case PinGroup_SpindleIndex:
spindleLock = true;
spindle_encoder.counter.index_count++;
spindle_encoder.counter.last_index = GPT2_CNT;
spindle_encoder.timer.last_index = GPT1_CNT;
spindleLock = false;
- } else
+ break;
#endif
+
+#if KEYPAD_ENABLE
+ case PinGroup_Keypad:
+ keypad_keyclick_handler(!(KeypadStrobe.reg->DR & KeypadStrobe.bit));
+ break;
+#endif
+
+#ifdef HAS_IOPORTS
+ case PinGroup_AuxInput:
+ ioports_event(&inputpin[i]);
+ break;
+#endif
+ default:
grp |= inputpin[i].group;
+ break;
}
}
}
@@ -2622,11 +2629,6 @@ static void gpio_isr (void)
mpg_mutex = false;
}
#endif
-
-#if KEYPAD_ENABLE
- if(grp & PinGroup_Keypad)
- keypad_keyclick_handler(!(KeypadStrobe.reg->DR & KeypadStrobe.bit));
-#endif
}
// Interrupt handler for 1 ms interval timer
diff --git a/grblHAL_Teensy4/src/driver.h b/grblHAL_Teensy4/src/driver.h
index ffac504..68b54e4 100644
--- a/grblHAL_Teensy4/src/driver.h
+++ b/grblHAL_Teensy4/src/driver.h
@@ -34,9 +34,7 @@
#include "my_machine.h"
#endif
-#include "grbl/hal.h"
-#include "grbl/nuts_bolts.h"
-#include "grbl/crossbar.h"
+#include "grbl/driver_opts.h"
#define DIGITAL_IN(gpio) (!!(gpio.reg->DR & gpio.bit))
#define DIGITAL_OUT(gpio, on) { if(on) gpio.reg->DR_SET = gpio.bit; else gpio.reg->DR_CLEAR = gpio.bit; }
@@ -45,111 +43,6 @@
//#define UART_DEBUG // For development only - enable only with USB_SERIAL_CDC enabled and SPINDLE_HUANYANG disabled
#endif
-#ifndef USB_SERIAL_CDC
-#define USB_SERIAL_CDC 0 // for UART comms
-#endif
-#ifndef USB_SERIAL_WAIT
-#define USB_SERIAL_WAIT 0
-#endif
-#ifndef SDCARD_ENABLE
-#define SDCARD_ENABLE 0
-#endif
-#ifndef KEYPAD_ENABLE
-#define KEYPAD_ENABLE 0
-#endif
-#ifndef EEPROM_ENABLE
-#define EEPROM_ENABLE 0
-#endif
-#ifndef EEPROM_IS_FRAM
-#define EEPROM_IS_FRAM 0
-#endif
-#ifndef SPINDLE_SYNC_ENABLE
-#define SPINDLE_SYNC_ENABLE 0
-#endif
-#ifndef TRINAMIC_ENABLE
-#define TRINAMIC_ENABLE 0
-#endif
-#ifndef TRINAMIC_I2C
-#define TRINAMIC_I2C 0
-#endif
-#ifndef TRINAMIC_DEV
-#define TRINAMIC_DEV 0
-#endif
-#ifndef PLASMA_ENABLE
-#define PLASMA_ENABLE 0
-#endif
-#ifndef PPI_ENABLE
-#define PPI_ENABLE 0
-#endif
-#ifndef SPINDLE_HUANYANG
-#define SPINDLE_HUANYANG 0
-#endif
-#ifndef QEI_ENABLE
-#define QEI_ENABLE 0
-#endif
-#ifndef ODOMETER_ENABLE
-#define ODOMETER_ENABLE 0
-#endif
-#ifndef OPENPNP_ENABLE
-#define OPENPNP_ENABLE 0
-#endif
-
-#ifndef ESTOP_ENABLE
- #if COMPATIBILITY_LEVEL <= 1
- #define ESTOP_ENABLE 1
- #else
- #define ESTOP_ENABLE 0
- #endif
-#elif ESTOP_ENABLE && COMPATIBILITY_LEVEL > 1
- #warning "Enabling ESTOP may not work with all senders!"
-#endif
-
-#ifndef ETHERNET_ENABLE
-#define ETHERNET_ENABLE 0
-#endif
-#ifndef TELNET_ENABLE
-#define TELNET_ENABLE 0
-#endif
-#ifndef WEBSOCKET_ENABLE
-#define WEBSOCKET_ENABLE 0
-#endif
-#ifndef FTP_ENABLE
-#define FTP_ENABLE 0
-#elif !SDCARD_ENABLE
-#undef FTP_ENABLE
-#define FTP_ENABLE 0
-#endif
-
-#if ETHERNET_ENABLE
-#ifndef NETWORK_HOSTNAME
-#define NETWORK_HOSTNAME "GRBL"
-#endif
-#ifndef NETWORK_IPMODE
-#define NETWORK_IPMODE 1 // 0 = static, 1 = DHCP, 2 = AutoIP
-#endif
-#ifndef NETWORK_IP
-#define NETWORK_IP "192.168.5.1"
-#endif
-#ifndef NETWORK_GATEWAY
-#define NETWORK_GATEWAY "192.168.5.1"
-#endif
-#ifndef NETWORK_MASK
-#define NETWORK_MASK "255.255.255.0"
-#endif
-#ifndef NETWORK_TELNET_PORT
-#define NETWORK_TELNET_PORT 23
-#endif
-#ifndef NETWORK_WEBSOCKET_PORT
-#define NETWORK_WEBSOCKET_PORT 80
-#endif
-#ifndef NETWORK_HTTP_PORT
-#define NETWORK_HTTP_PORT 80
-#endif
-#if NETWORK_IPMODE < 0 || NETWORK_IPMODE > 2
-#error "Invalid IP mode selected!"
-#endif
-#endif
-
// Timer assignments (for reference, Arduino libs does not follow the CMSIS style...)
//#define STEPPER_TIMER PIT0 (32 bit)
@@ -163,8 +56,6 @@
//#define RPM_TIMER GPT1
//#define RPM_COUNTER GPT2
-// End configuration
-
#ifdef BOARD_CNC_BOOSTERPACK
#include "cnc_boosterpack_map.h"
#elif defined(BOARD_T40X101)
@@ -212,6 +103,10 @@
#include "encoder/encoder.h"
#endif
+#if BLUETOOTH_ENABLE && USB_SERIAL_CDC == 0
+#error "Bluetooth cannot be used with UART communications enabled!"
+#endif
+
#if SPINDLE_HUANYANG
#if USB_SERIAL_CDC == 0
#error "Huanyang VFD cannot be used with UART communications enabled!"
@@ -286,6 +181,8 @@ typedef struct {
uint8_t offset;
volatile bool active;
volatile bool debounce;
+ pin_mode_t cap;
+ ioport_interrupt_callback_ptr interrupt_callback;
} input_signal_t;
typedef struct {
@@ -312,13 +209,13 @@ typedef struct {
const uint32_t select_val; // Value for that selection
} pin_info_t;
-//
-
void pinModeOutput (gpio_t *gpio, uint8_t pin);
+void pinEnableIRQ (const input_signal_t *signal, pin_irq_mode_t irq_mode);
uint32_t xTaskGetTickCount();
-#ifdef HAS_BOARD_INIT
-void board_init(pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs);
+#ifdef HAS_IOPORTS
+void ioports_init (pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs);
+void ioports_event (input_signal_t *input);
#endif
#ifdef UART_DEBUG
diff --git a/grblHAL_Teensy4/src/enet.c b/grblHAL_Teensy4/src/enet.c
index e6ac89f..107adff 100644
--- a/grblHAL_Teensy4/src/enet.c
+++ b/grblHAL_Teensy4/src/enet.c
@@ -38,13 +38,14 @@
#include "networking/networking.h"
+static bool enet_started = false;
static volatile bool linkUp = false;
static char IPAddress[IP4ADDR_STRLEN_MAX];
static network_services_t services = {0}, allowed_services;
static nvs_address_t nvs_address;
static network_settings_t ethernet, network;
static on_report_options_ptr on_report_options;;
-static char netservices[30] = ""; // must be large enough to hold all service names
+static char netservices[40] = ""; // must be large enough to hold all service names
static void report_options (bool newopt)
{
@@ -105,6 +106,9 @@ void grbl_enet_poll (void)
static uint32_t last_ms0, last_ms1;
uint32_t ms;
+ if(!enet_started)
+ return;
+
enet_proc_input();
ms = millis();
@@ -154,6 +158,8 @@ bool grbl_enet_start (void)
#endif
if(network.ip_mode == IpMode_DHCP)
dhcp_start(netif_default);
+
+ enet_started = true;
}
return nvs_address != 0;
diff --git a/grblHAL_Teensy4/src/generic_map.h b/grblHAL_Teensy4/src/generic_map.h
index ce6f844..ae22554 100644
--- a/grblHAL_Teensy4/src/generic_map.h
+++ b/grblHAL_Teensy4/src/generic_map.h
@@ -19,38 +19,46 @@
along with Grbl. If not, see .
*/
+#if N_ABC_MOTORS > 2
+#error "Axis configuration is not supported!"
+#endif
+
#if SPINDLE_SYNC_ENABLE
-#error Spindle sync is not supported
+#error "Spindle sync is not supported"
#endif
// Define step pulse output pins.
-#define X_STEP_PIN (2u)
-#define Y_STEP_PIN (4u)
-#define Z_STEP_PIN (6u)
+#define X_STEP_PIN (2u)
+#define Y_STEP_PIN (4u)
+#define Z_STEP_PIN (6u)
// Define step direction output pins.
-#define X_DIRECTION_PIN (3u)
-#define Y_DIRECTION_PIN (5u)
-#define Z_DIRECTION_PIN (7u)
+#define X_DIRECTION_PIN (3u)
+#define Y_DIRECTION_PIN (5u)
+#define Z_DIRECTION_PIN (7u)
// Define stepper driver enable/disable output pin(s).
#define STEPPERS_ENABLE_PIN (10u)
// Define homing/hard limit switch input pins.
-#define X_LIMIT_PIN (20u)
-#define Y_LIMIT_PIN (21u)
-#define Z_LIMIT_PIN (22u)
+#define X_LIMIT_PIN (20u)
+#define Y_LIMIT_PIN (21u)
+#define Z_LIMIT_PIN (22u)
-#if N_AXIS > 3
-#define A_STEP_PIN (8u)
-#define A_DIRECTION_PIN (9u)
-#define A_LIMIT_PIN (23u)
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN (8u)
+#define M3_DIRECTION_PIN (9u)
+#define M3_LIMIT_PIN (23u)
#endif
-#if N_AXIS > 4
-#define B_STEP_PIN (26u)
-#define B_DIRECTION_PIN (27u)
-#define B_LIMIT_PIN (28u)
+// Define ganged axis or B axis step pulse and step direction output pins.
+#if N_ABC_MOTORS == 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN (26u)
+#define M4_DIRECTION_PIN (27u)
+#define M4_LIMIT_PIN (28u)
#endif
// Define spindle enable and spindle direction output pins.
diff --git a/grblHAL_Teensy4/src/T41U5XBB.c b/grblHAL_Teensy4/src/ioports.c
similarity index 52%
rename from grblHAL_Teensy4/src/T41U5XBB.c
rename to grblHAL_Teensy4/src/ioports.c
index 3a82951..938b418 100644
--- a/grblHAL_Teensy4/src/T41U5XBB.c
+++ b/grblHAL_Teensy4/src/ioports.c
@@ -1,5 +1,5 @@
/*
- T41U5XBB.c - driver code for IMXRT1062 processor (on Teensy 4.1 board)
+ ioports.c - driver code for IMXRT1062 processor (on Teensy 4.1 board)
Part of grblHAL
@@ -23,7 +23,7 @@
#include "driver.h"
-#if defined(BOARD_T41U5XBB) || defined(BOARD_T41U5XBB_SS) || defined(BOARD_T41BB5X_PRO)
+#ifdef HAS_IOPORTS
//#include "Arduino.h"
#include
@@ -32,6 +32,8 @@
#include "grbl/protocol.h"
static uint_fast8_t aux_n_in, aux_n_out;
+static volatile uint32_t event_bits;
+static volatile bool spin_lock = false;
static input_signal_t *aux_in;
static output_signal_t *aux_out;
static ioport_bus_t out = {0};
@@ -40,14 +42,15 @@ static char input_ports[56] = "", output_ports[56] = "";
static void aux_settings_load (void);
static status_code_t aux_set_invert_out (setting_id_t id, uint_fast16_t int_value);
static uint32_t aux_get_invert_out (setting_id_t setting);
+static bool is_setting_available (const setting_detail_t *setting);
static const setting_group_detail_t aux_groups[] = {
{ Group_Root, Group_AuxPorts, "Aux ports"}
};
static const setting_detail_t aux_settings[] = {
- { Settings_IoPort_InvertIn, Group_AuxPorts, "Invert I/O Port inputs", NULL, Format_Bitfield, input_ports, NULL, NULL, Setting_NonCore, &settings.ioport.invert_in.mask },
- { Settings_IoPort_InvertOut, Group_AuxPorts, "Invert I/O Port outputs", NULL, Format_Bitfield, output_ports, NULL, NULL, Setting_NonCoreFn, aux_set_invert_out, aux_get_invert_out },
+ { Settings_IoPort_InvertIn, Group_AuxPorts, "Invert I/O Port inputs", NULL, Format_Bitfield, input_ports, NULL, NULL, Setting_NonCore, &settings.ioport.invert_in.mask, NULL, is_setting_available },
+ { Settings_IoPort_InvertOut, Group_AuxPorts, "Invert I/O Port outputs", NULL, Format_Bitfield, output_ports, NULL, NULL, Setting_NonCoreFn, aux_set_invert_out, aux_get_invert_out, is_setting_available },
};
static setting_details_t details = {
@@ -59,6 +62,29 @@ static setting_details_t details = {
.save = settings_write_global
};
+static bool is_setting_available (const setting_detail_t *setting)
+{
+ bool available = false;
+
+ switch(setting->id) {
+
+ case Settings_IoPort_InvertIn:
+ case Settings_IoPort_Pullup_Disable:
+ available = aux_n_in > 0;
+ break;
+
+ case Settings_IoPort_InvertOut:
+ case Settings_IoPort_OD_Enable:
+ available = aux_n_out > 0;
+ break;
+
+ default:
+ break;
+ }
+
+ return available;
+}
+
static setting_details_t *on_get_settings (void)
{
return &details;
@@ -70,6 +96,7 @@ static void aux_settings_load (void)
do {
idx--;
+ pinModeOutput(aux_out[idx].port, aux_out[idx].pin);
DIGITAL_OUT((*(aux_out[idx].port)), (settings.ioport.invert_out.mask >> idx) & 0x01);
} while(idx);
}
@@ -104,27 +131,67 @@ static void digital_out (uint8_t port, bool on)
DIGITAL_OUT((*(aux_out[port].port)), ((settings.ioport.invert_out.mask >> port) & 0x01) ? !on : on);
}
-inline static __attribute__((always_inline)) int32_t get_input (gpio_t *gpio, bool invert, wait_mode_t wait_mode, float timeout)
+inline static __attribute__((always_inline)) int32_t get_input (const input_signal_t *input, bool invert, wait_mode_t wait_mode, float timeout)
{
if(wait_mode == WaitMode_Immediate)
- return !!(gpio->reg->DR & gpio->bit) ^ invert;
+ return DIGITAL_IN(input->gpio) ^ invert;
+ int32_t value = -1;
uint_fast16_t delay = (uint_fast16_t)ceilf((1000.0f / 50.0f) * timeout) + 1;
- bool wait_for = wait_mode != WaitMode_Low;
+ if(wait_mode == WaitMode_Rise || wait_mode == WaitMode_Fall) {
- do {
- if((!!(gpio->reg->DR & gpio->bit) ^ invert) == wait_for)
- return !!(gpio->reg->DR & gpio->bit);
+ pin_irq_mode_t irq_mode = wait_mode == WaitMode_Rise ? IRQ_Mode_Rising : IRQ_Mode_Falling;
- if(delay) {
- protocol_execute_realtime();
- hal.delay_ms(50, NULL);
- } else
- break;
- } while(--delay && !sys.abort);
+ if(input->cap.irq_mode & irq_mode) {
- return -1;
+ event_bits &= ~input->gpio.bit;
+ pinEnableIRQ(input, irq_mode);
+
+ do {
+ if(event_bits & input->gpio.bit) {
+ value = DIGITAL_IN(input->gpio) ^ invert;
+ break;
+ }
+ if(delay) {
+ protocol_execute_realtime();
+ hal.delay_ms(50, NULL);
+ } else
+ break;
+ } while(--delay && !sys.abort);
+
+ pinEnableIRQ(input, IRQ_Mode_None); // Restore pin interrupt status
+ }
+
+ } else {
+
+ bool wait_for = wait_mode != WaitMode_Low;
+
+ do {
+ if((DIGITAL_IN(input->gpio) ^ invert) == wait_for) {
+ value = DIGITAL_IN(input->gpio);
+ break;
+ }
+ if(delay) {
+ protocol_execute_realtime();
+ hal.delay_ms(50, NULL);
+ } else
+ break;
+ } while(--delay && !sys.abort);
+ }
+
+ return value;
+}
+
+void ioports_event (input_signal_t *input)
+{
+ spin_lock = true;
+ event_bits |= input->gpio.bit;
+
+ if(input->interrupt_callback)
+ input->interrupt_callback(input->id - Output_Aux0, !!(input->port->reg->DR & input->port->bit));
+
+ spin_lock = false;
}
static int32_t wait_on_input (bool digital, uint8_t port, wait_mode_t wait_mode, float timeout)
@@ -133,29 +200,51 @@ static int32_t wait_on_input (bool digital, uint8_t port, wait_mode_t wait_mode,
if(digital) {
if(port < aux_n_in)
- value = get_input(aux_in[port].port, (settings.ioport.invert_in.mask << port) & 0x01, wait_mode, timeout);
+ value = get_input(&aux_in[port], (settings.ioport.invert_in.mask << port) & 0x01, wait_mode, timeout);
}
// else if(port == 0)
// value = analogRead(41);
-/*
- hal.stream.write("[MSG:AUX");
- hal.stream.write(uitoa(port));
- hal.stream.write("=");
- hal.stream.write(value == -1 ? "fail" : uitoa(value));
- hal.stream.write("]" ASCII_EOL);
-*/
+
return value;
}
-void board_init (pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs)
+static bool register_interrupt_handler (uint8_t port, pin_irq_mode_t irq_mode, ioport_interrupt_callback_ptr interrupt_callback)
+{
+ bool ok;
+
+ if((ok = port < aux_n_in && aux_in[port].cap.irq_mode != IRQ_Mode_None)) {
+
+ input_signal_t *input = &aux_in[port];
+
+ if(irq_mode != IRQ_Mode_None && (ok = interrupt_callback != NULL)) {
+ input->irq_mode = irq_mode;
+ input->interrupt_callback = interrupt_callback;
+ pinEnableIRQ(input, irq_mode);
+ }
+
+ if(irq_mode == IRQ_Mode_None || !ok) {
+ while(spin_lock);
+ pinEnableIRQ(input, IRQ_Mode_None);
+ input->irq_mode = IRQ_Mode_None;
+ input->interrupt_callback = NULL;
+ }
+ }
+
+ return ok;
+}
+
+void ioports_init (pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs)
{
aux_in = aux_inputs->pins.inputs;
aux_out = aux_outputs->pins.outputs;
- hal.port.wait_on_input = wait_on_input;
- hal.port.digital_out = digital_out;
- hal.port.num_digital_in = aux_n_in = aux_inputs->n_pins;
- hal.port.num_digital_out = aux_n_out = aux_outputs->n_pins;
+ if((hal.port.num_digital_in = aux_n_in = aux_inputs->n_pins)) {
+ hal.port.wait_on_input = wait_on_input;
+ hal.port.register_interrupt_handler = register_interrupt_handler;
+ }
+
+ if((hal.port.num_digital_out = aux_n_out = aux_outputs->n_pins))
+ hal.port.digital_out = digital_out;
details.on_get_settings = grbl.on_get_settings;
grbl.on_get_settings = on_get_settings;
diff --git a/grblHAL_Teensy4/src/my_machine.h b/grblHAL_Teensy4/src/my_machine.h
index ceb78e5..f46a475 100644
--- a/grblHAL_Teensy4/src/my_machine.h
+++ b/grblHAL_Teensy4/src/my_machine.h
@@ -51,10 +51,11 @@ N_AXIS has a default value of 3, edit grbl\config.h to increase.
#define USB_SERIAL_CDC 2 // 1 for Arduino class library and 2 for PJRC C library. Comment out to use UART communication.
//#define USB_SERIAL_WAIT 1 // Wait for USB connection before starting grblHAL.
+//#define BLUETOOTH_ENABLE 1 // Set to 1 for HC-05 module. Requires Bluetooth plugin.
//#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 2 // Run gcode programs from SD card, requires sdcard plugin.
+//#define SDCARD_ENABLE 1 // 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.
@@ -67,9 +68,24 @@ N_AXIS has a default value of 3, edit grbl\config.h to increase.
//#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.
+// If the selected board map supports more than three motors ganging and/or auto-squaring
+// of axes can be enabled here.
+//#define X_GANGED 1
+//#define X_AUTO_SQUARE 1
+//#define Y_GANGED 1
+//#define Y_AUTO_SQUARE 1
+//#define Z_GANGED 1
+//#define Z_AUTO_SQUARE 1
+// For ganged axes the limit switch input (if available) can be configured to act as a max travel limit switch.
+// NOTE: If board map already has max limit inputs defined this configuration will be ignored.
+//#define X_GANGED_LIM_MAX 1
+//#define Y_GANGED_LIM_MAX 1
+//#define Z_GANGED_LIM_MAX 1
+//
+
#if ETHERNET_ENABLE > 0
#define TELNET_ENABLE 1 // Telnet daemon - requires Ethernet streaming enabled.
-#define FTP_ENABLE 0 // Ftp daemon - requires SD card enabled. !!DO NOT ENABLE - there is a bug in the FatFS library that has to be fixed first!!
+#define FTP_ENABLE 1 // Ftp daemon - requires SD card enabled.
#define WEBSOCKET_ENABLE 1 // Websocket daemon - requires Ethernet streaming enabled.
#define NETWORK_HOSTNAME "GRBL"
#define NETWORK_IPMODE 1 // 0 = static, 1 = DHCP, 2 = AutoIP
diff --git a/grblHAL_Teensy4/src/my_plugin.c b/grblHAL_Teensy4/src/my_plugin.c
new file mode 100644
index 0000000..d65987b
--- /dev/null
+++ b/grblHAL_Teensy4/src/my_plugin.c
@@ -0,0 +1,75 @@
+/*
+
+ my_plugin.c - plugin template for setting auxillary output on feed hold
+
+ Part of grblHAL
+
+ Public domain.
+
+*/
+
+#include
+
+#include "driver.h"
+#include "grbl/protocol.h"
+
+static uint8_t port;
+
+static on_state_change_ptr on_state_change;
+static on_report_options_ptr on_report_options;
+
+static void onStateChanged (sys_state_t state)
+{
+ static sys_state_t last_state = STATE_IDLE;
+
+ if(state != last_state) {
+ last_state = state;
+ hal.port.digital_out(port, state == STATE_HOLD);
+ }
+
+ if(on_state_change) // Call previous function in the chain.
+ on_state_change(state);
+}
+
+static void onReportOptions (bool newopt)
+{
+ on_report_options(newopt); // Call previous function in the chain.
+
+ if(!newopt) // Add info about us to the $I report.
+ hal.stream.write("[PLUGIN:MY PLUGIN Template 2]" ASCII_EOL);
+}
+
+static void output_warning (uint_fast16_t state)
+{
+ report_message("An output port is required for my_plugin!", Message_Warning);
+}
+
+// Tell the user about which port is used for the output
+static void output_port (uint_fast16_t state)
+{
+ char msg[30];
+
+ strcpy(msg, "My plugin port: ");
+ strcat(msg, uitoa(port));
+
+ report_message(msg, Message_Info);
+}
+
+void xmy_plugin_init()
+{
+ if(hal.port.num_digital_out == 0) // This plugin requires one digital output port,
+ protocol_enqueue_rt_command(output_warning); // complain if not available.
+
+ else {
+ port = hal.port.num_digital_out - 1; // Claim the
+ hal.port.num_digital_out--; // last free port.
+
+ on_state_change = grbl.on_state_change; // Subscribe to the state changed event by saving away the original
+ grbl.on_state_change = onStateChanged; // function pointer and adding ours to the chain.
+
+ on_report_options = grbl.on_report_options; // Add our plugin to to the options report chain
+ grbl.on_report_options = onReportOptions; // to tell the user we are active.
+
+ protocol_enqueue_rt_command(output_port); // Tell the user about which port is used for the output after startup is complete.
+ }
+}
diff --git a/grblHAL_Teensy4/src/uart.c b/grblHAL_Teensy4/src/uart.c
index 82f69d0..ecf9a93 100644
--- a/grblHAL_Teensy4/src/uart.c
+++ b/grblHAL_Teensy4/src/uart.c
@@ -143,113 +143,10 @@ static uint16_t tx_fifo_size;
static stream_tx_buffer_t txbuffer = {0};
static stream_rx_buffer_t rxbuffer = {0};
-void serialInit (uint32_t baud_rate)
-{
-// uart_hardware_t *hardware = &UART;
- float base = (float)UART_CLOCK / (float)baud_rate;
- float besterr = 1e20;
- int bestdiv = 1;
- int bestosr = 4;
- for (int osr = 4; osr <= 32; osr++) {
- float div = base / (float)osr;
- int divint = (int)(div + 0.5f);
- if (divint < 1)
- divint = 1;
- else if (divint > 8191)
- divint = 8191;
- float err = ((float)divint - div) / div;
- if (err < 0.0f)
- err = -err;
- if (err <= besterr) {
- besterr = err;
- bestdiv = divint;
- bestosr = osr;
- }
- }
-
- *UART.ccm_register |= UART.ccm_value;
-
- *(portControlRegister(UART.rx_pin.pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
- *(portConfigRegister(UART.rx_pin.pin)) = UART.rx_pin.mux_val;
- if (UART.rx_pin.select_reg)
- *(UART.rx_pin.select_reg) = UART.rx_pin.select_val;
-
- *(portControlRegister(UART.tx_pin.pin)) = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
- *(portConfigRegister(UART.tx_pin.pin)) = UART.tx_pin.mux_val;
- if (UART.tx_pin.select_reg)
- *(UART.tx_pin.select_reg) = UART.tx_pin.select_val;
-
- UART.port->BAUD = LPUART_BAUD_OSR(bestosr - 1) | LPUART_BAUD_SBR(bestdiv) | (bestosr <= 8 ? LPUART_BAUD_BOTHEDGE : 0);
- UART.port->PINCFG = 0;
-
- // Enable the transmitter, receiver and enable receiver interrupt
- NVIC_DISABLE_IRQ(UART.irq);
- attachInterruptVector(UART.irq, UART.irq_handler);
- NVIC_SET_PRIORITY(UART.irq, 0);
- NVIC_ENABLE_IRQ(UART.irq);
-
- tx_fifo_size = (UART.port->FIFO >> 4) & 0x7;
- tx_fifo_size = tx_fifo_size ? (2 << tx_fifo_size) : 1;
-
- uint8_t tx_water = (tx_fifo_size < 16) ? tx_fifo_size >> 1 : 7;
- uint16_t rx_fifo_size = (((UART.port->FIFO >> 0) & 0x7) << 2);
- uint8_t rx_water = (rx_fifo_size < 16) ? rx_fifo_size >> 1 : 7;
- /*
- Serial.printf("SerialX::begin stat:%x ctrl:%x fifo:%x water:%x\n", UART.port->STAT, UART.port->CTRL, UART.port->FIFO, UART.port->WATER );
- Serial.printf(" FIFO sizes: tx:%d rx:%d\n",tx_fifo_size, rx_fifo_size);
- Serial.printf(" Watermark tx:%d, rx: %d\n", tx_water, rx_water);
- */
- UART.port->WATER = LPUART_WATER_RXWATER(rx_water) | LPUART_WATER_TXWATER(tx_water);
- UART.port->FIFO |= LPUART_FIFO_TXFE | LPUART_FIFO_RXFE;
- // lets configure up our CTRL register value
- uint32_t ctrl = CTRL_TX_INACTIVE;
-
-uint16_t format = 0;
-
- // Now process the bits in the Format value passed in
- // Bits 0-2 - Parity plus 9 bit.
- ctrl |= (format & (LPUART_CTRL_PT | LPUART_CTRL_PE) ); // configure parity - turn off PT, PE, M and configure PT, PE
- if (format & 0x04) ctrl |= LPUART_CTRL_M; // 9 bits (might include parity)
- if ((format & 0x0F) == 0x04) ctrl |= LPUART_CTRL_R9T8; // 8N2 is 9 bit with 9th bit always 1
-
- // Bit 5 TXINVERT
- if (format & 0x20) ctrl |= LPUART_CTRL_TXINV; // tx invert
-
- // write out computed CTRL
- UART.port->CTRL = ctrl;
-
- // Bit 3 10 bit - Will assume that begin already cleared it.
- // process some other bits which change other registers.
- if (format & 0x08) UART.port->BAUD |= LPUART_BAUD_M10;
-
- // Bit 4 RXINVERT
- uint32_t c = UART.port->STAT & ~LPUART_STAT_RXINV;
- if (format & 0x10) c |= LPUART_STAT_RXINV; // rx invert
- UART.port->STAT = c;
-
- // bit 8 can turn on 2 stop bit mote
- if ( format & 0x100) UART.port->BAUD |= LPUART_BAUD_SBNS;
-
-//transmitterEnable(1);
- hal.stream.connected = true;
-}
-
-bool serialSetBaudRate (uint32_t baud_rate)
-{
- static bool init_ok = false;
-
- if(!init_ok) {
- serialInit(baud_rate);
- init_ok = true;
- }
-
- return true;
-}
-
//
// serialGetC - returns -1 if no data available
//
-int16_t serialGetC (void)
+static int16_t serialGetC (void)
{
int16_t data;
uint_fast16_t bptr = rxbuffer.tail;
@@ -263,37 +160,37 @@ int16_t serialGetC (void)
return data;
}
-void serialTxFlush (void)
+static void serialTxFlush (void)
{
txbuffer.tail = txbuffer.head;
}
-uint16_t serialRxCount (void)
+static uint16_t serialRxCount (void)
{
uint_fast16_t head = rxbuffer.head, tail = rxbuffer.tail;
return BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}
-uint16_t serialRxFree (void)
+static uint16_t serialRxFree (void)
{
return (RX_BUFFER_SIZE - 1) - serialRxCount();
}
-void serialRxFlush (void)
+static void serialRxFlush (void)
{
rxbuffer.tail = rxbuffer.head;
rxbuffer.overflow = false;
}
-void serialRxCancel (void)
+static void serialRxCancel (void)
{
serialRxFlush();
rxbuffer.data[rxbuffer.head] = ASCII_CAN;
rxbuffer.head = (rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
}
-bool serialPutC (const char c)
+static bool serialPutC (const char c)
{
uint_fast16_t next_head;
@@ -324,7 +221,7 @@ bool serialPutC (const char c)
return true;
}
-void serialWriteS (const char *data)
+static void serialWriteS (const char *data)
{
char c, *ptr = (char *)data;
@@ -332,7 +229,7 @@ void serialWriteS (const char *data)
serialPutC(c);
}
-void serialWrite(const char *s, uint16_t length)
+static void serialWrite(const char *s, uint16_t length)
{
char *ptr = (char *)s;
@@ -340,18 +237,150 @@ void serialWrite(const char *s, uint16_t length)
serialPutC(*ptr++);
}
-bool serialSuspendInput (bool suspend)
+static bool serialSuspendInput (bool suspend)
{
return stream_rx_suspend(&rxbuffer, suspend);
}
-uint16_t serialTxCount(void) {
+static uint16_t serialTxCount(void) {
uint_fast16_t head = txbuffer.head, tail = txbuffer.tail;
return BUFCOUNT(head, tail, TX_BUFFER_SIZE) + ((UART.port->WATER >> 8) & 0x7) + ((UART.port->STAT & LPUART_STAT_TC) ? 0 : 1);
}
+static bool serialSetBaudRate (uint32_t baud_rate)
+{
+ float base = (float)UART_CLOCK / (float)baud_rate;
+ float besterr = 1e20;
+ int bestdiv = 1;
+ int bestosr = 4;
+ for (int osr = 4; osr <= 32; osr++) {
+ float div = base / (float)osr;
+ int divint = (int)(div + 0.5f);
+ if (divint < 1)
+ divint = 1;
+ else if (divint > 8191)
+ divint = 8191;
+ float err = ((float)divint - div) / div;
+ if (err < 0.0f)
+ err = -err;
+ if (err <= besterr) {
+ besterr = err;
+ bestdiv = divint;
+ bestosr = osr;
+ }
+ }
+
+ UART.port->BAUD = LPUART_BAUD_OSR(bestosr - 1) | LPUART_BAUD_SBR(bestdiv) | (bestosr <= 8 ? LPUART_BAUD_BOTHEDGE : 0);
+
+ return true;
+}
+
+static bool serialDisable (bool disable)
+{
+ if(disable)
+ NVIC_DISABLE_IRQ(UART.irq);
+ else
+ NVIC_ENABLE_IRQ(UART.irq);
+
+ return true;
+}
+
+const io_stream_t *serialInit (uint32_t baud_rate)
+{
+ PROGMEM static const io_stream_t stream = {
+ .type = StreamType_Serial,
+ .connected = true,
+ .read = serialGetC,
+ .write = serialWriteS,
+ .write_n = serialWrite,
+ .write_char = serialPutC,
+ .write_all = serialWriteS,
+ .get_rx_buffer_free = serialRxFree,
+ .get_rx_buffer_count = serialRxCount,
+ .get_tx_buffer_count = serialTxCount,
+ .reset_write_buffer = serialTxFlush,
+ .reset_read_buffer = serialRxFlush,
+ .cancel_read_buffer = serialRxCancel,
+ .suspend_read = serialSuspendInput,
+ .disable = serialDisable,
+ .set_baud_rate = serialSetBaudRate
+ };
+
+ *UART.ccm_register |= UART.ccm_value;
+
+ *(portControlRegister(UART.rx_pin.pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
+ *(portConfigRegister(UART.rx_pin.pin)) = UART.rx_pin.mux_val;
+ if (UART.rx_pin.select_reg)
+ *(UART.rx_pin.select_reg) = UART.rx_pin.select_val;
+
+ *(portControlRegister(UART.tx_pin.pin)) = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
+ *(portConfigRegister(UART.tx_pin.pin)) = UART.tx_pin.mux_val;
+ if (UART.tx_pin.select_reg)
+ *(UART.tx_pin.select_reg) = UART.tx_pin.select_val;
+
+ serialSetBaudRate(baud_rate);
+
+ UART.port->PINCFG = 0;
+
+ // Enable the transmitter, receiver and enable receiver interrupt
+ NVIC_DISABLE_IRQ(UART.irq);
+ attachInterruptVector(UART.irq, UART.irq_handler);
+ NVIC_SET_PRIORITY(UART.irq, 0);
+ NVIC_ENABLE_IRQ(UART.irq);
+
+ tx_fifo_size = (UART.port->FIFO >> 4) & 0x7;
+ tx_fifo_size = tx_fifo_size ? (2 << tx_fifo_size) : 1;
+
+ uint8_t tx_water = (tx_fifo_size < 16) ? tx_fifo_size >> 1 : 7;
+ uint16_t rx_fifo_size = (((UART.port->FIFO >> 0) & 0x7) << 2);
+ uint8_t rx_water = (rx_fifo_size < 16) ? rx_fifo_size >> 1 : 7;
+ /*
+ Serial.printf("SerialX::begin stat:%x ctrl:%x fifo:%x water:%x\n", UART.port->STAT, UART.port->CTRL, UART.port->FIFO, UART.port->WATER );
+ Serial.printf(" FIFO sizes: tx:%d rx:%d\n",tx_fifo_size, rx_fifo_size);
+ Serial.printf(" Watermark tx:%d, rx: %d\n", tx_water, rx_water);
+ */
+ UART.port->WATER = LPUART_WATER_RXWATER(rx_water) | LPUART_WATER_TXWATER(tx_water);
+ UART.port->FIFO |= LPUART_FIFO_TXFE | LPUART_FIFO_RXFE;
+ // lets configure up our CTRL register value
+ uint32_t ctrl = CTRL_TX_INACTIVE;
+
+uint16_t format = 0;
+
+ // Now process the bits in the Format value passed in
+ // Bits 0-2 - Parity plus 9 bit.
+ ctrl |= (format & (LPUART_CTRL_PT | LPUART_CTRL_PE) ); // configure parity - turn off PT, PE, M and configure PT, PE
+ if (format & 0x04)
+ ctrl |= LPUART_CTRL_M; // 9 bits (might include parity)
+ if ((format & 0x0F) == 0x04)
+ ctrl |= LPUART_CTRL_R9T8; // 8N2 is 9 bit with 9th bit always 1
+
+ // Bit 5 TXINVERT
+ if (format & 0x20)
+ ctrl |= LPUART_CTRL_TXINV; // tx invert
+
+ // write out computed CTRL
+ UART.port->CTRL = ctrl;
+
+ // Bit 3 10 bit - Will assume that begin already cleared it.
+ // process some other bits which change other registers.
+ if (format & 0x08) UART.port->BAUD |= LPUART_BAUD_M10;
+
+ // Bit 4 RXINVERT
+ uint32_t c = UART.port->STAT & ~LPUART_STAT_RXINV;
+ if (format & 0x10) c |= LPUART_STAT_RXINV; // rx invert
+ UART.port->STAT = c;
+
+ // bit 8 can turn on 2 stop bit mode
+ if (format & 0x100)
+ UART.port->BAUD |= LPUART_BAUD_SBNS;
+
+//transmitterEnable(1);
+
+ return &stream;
+}
+
static void uart_interrupt_handler (void)
{
uint_fast16_t bptr;
diff --git a/grblHAL_Teensy4/src/uart.h b/grblHAL_Teensy4/src/uart.h
index 1847bf4..2bf05ca 100644
--- a/grblHAL_Teensy4/src/uart.h
+++ b/grblHAL_Teensy4/src/uart.h
@@ -4,7 +4,7 @@
Part of grblHAL
- Copyright (c) 2020 Terje Io
+ Copyright (c) 2020-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
@@ -26,18 +26,8 @@
#include
#include
-void serialInit (uint32_t baud_rate);
-bool serialSetBaudRate (uint32_t baud_rate);
-int16_t serialGetC (void);
-bool serialPutC (const char c);
-void serialWrite(const char *s, uint16_t length);
-void serialWriteS (const char *data);
-bool serialSuspendInput (bool suspend);
-uint16_t serialRxFree (void);
-uint16_t serialRxCount (void);
-uint16_t serialTxCount (void);
-void serialRxFlush (void);
-void serialTxFlush (void);
-void serialRxCancel (void);
+#include "grbl/hal.h"
+
+const io_stream_t *serialInit (uint32_t baud_rate);
#endif
diff --git a/grblHAL_Teensy4/src/usb_serial_ard.cpp b/grblHAL_Teensy4/src/usb_serial_ard.cpp
index 118222f..0749d7f 100644
--- a/grblHAL_Teensy4/src/usb_serial_ard.cpp
+++ b/grblHAL_Teensy4/src/usb_serial_ard.cpp
@@ -39,36 +39,20 @@ extern "C" {
static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer;
-
-void usb_serialInit(void)
-{
- txbuf.s = txbuf.data;
-
- SerialUSB.begin(BAUD_RATE);
-
-#if USB_SERIAL_WAIT
- while(!SerialUSB); // Wait for connection
-
- hal.stream.connected = true;
-#endif
-
- txbuf.max_length = SerialUSB.availableForWrite(); // 6144 bytes
- txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
-}
-
+/*
//
// Returns number of characters in serial input buffer
//
-uint16_t usb_serialRxCount (void)
+static uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}
-
+*/
//
// Returns number of free characters in serial input buffer
//
-uint16_t usb_serialRxFree (void)
+static uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
@@ -86,7 +70,7 @@ void usb_serialRxFlush (void)
//
// Flushes and adds a CAN character to the serial input buffer
//
-void usb_serialRxCancel (void)
+static void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
@@ -96,7 +80,7 @@ void usb_serialRxCancel (void)
//
// Writes a character to the serial output stream
//
-bool usb_serialPutC (const char c)
+static bool usb_serialPutC (const char c)
{
SerialUSB.write(c);
@@ -108,7 +92,7 @@ bool usb_serialPutC (const char c)
// Buffers locally up to 40 characters or until the string is terminated with a ASCII_LF character.
// NOTE: grbl always sends ASCII_LF terminated strings!
//
-void usb_serialWriteS (const char *s)
+static void usb_serialWriteS (const char *s)
{
if(*s == '\0')
return;
@@ -148,11 +132,11 @@ void usb_serialWriteS (const char *s)
}
}
}
-
+/*
//
// Writes a null terminated string to the serial output stream followed by EOL, blocks if buffer full
//
-void usb_serialWriteLn (const char *s)
+static void usb_serialWriteLn (const char *s)
{
usb_serialWriteS(s);
usb_serialWriteS(ASCII_EOL);
@@ -161,18 +145,18 @@ void usb_serialWriteLn (const char *s)
//
// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full
//
-void usb_serialWrite (const char *s, uint16_t length)
+static void usb_serialWrite (const char *s, uint16_t length)
{
char *ptr = (char *)s;
while(length--)
usb_serialPutC(*ptr++);
}
-
+*/
//
// serialGetC - returns -1 if no data available
//
-int16_t usb_serialGetC (void)
+static int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;
@@ -185,11 +169,43 @@ int16_t usb_serialGetC (void)
return (int16_t)data;
}
-bool usb_serialSuspendInput (bool suspend)
+static bool usb_serialSuspendInput (bool suspend)
{
return stream_rx_suspend(&usb_rxbuffer, suspend);
}
+const io_stream_t *usb_serialInit (void)
+{
+ PROGMEM static const io_stream_t stream = {
+ .type = StreamType_Serial,
+ .connected = false,
+ .get_rx_buffer_free = usb_serialRxFree,
+ .write = usb_serialWriteS,
+ .write_all = usb_serialWriteS,
+ .write_char = usb_serialPutC,
+ .read = usb_serialGetC,
+ .reset_read_buffer = usb_serialRxFlush,
+ .cancel_read_buffer = usb_serialRxCancel,
+ .suspend_read = usb_serialSuspendInput
+ };
+
+ txbuf.s = txbuf.data;
+
+ SerialUSB.begin(BAUD_RATE);
+
+#if USB_SERIAL_WAIT
+ while(!SerialUSB); // Wait for connection
+
+ hal.stream.connected = true;
+#endif
+
+ txbuf.max_length = SerialUSB.availableForWrite(); // 6144 bytes
+ txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
+
+ return &stream;
+}
+
+
//
// This function get called from the systick interrupt handler,
// used here to get characters off the USB serial input stream and buffer
diff --git a/grblHAL_Teensy4/src/usb_serial_ard.h b/grblHAL_Teensy4/src/usb_serial_ard.h
index 71f6285..53b7766 100644
--- a/grblHAL_Teensy4/src/usb_serial_ard.h
+++ b/grblHAL_Teensy4/src/usb_serial_ard.h
@@ -4,7 +4,7 @@
Part of grblHAL
- Copyright (c) 2018-2020 Terje Io
+ Copyright (c) 2018-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
@@ -27,22 +27,12 @@
#include
#include
+#include "grbl/hal.h"
+
extern void usb_execute_realtime (uint_fast16_t state);
#define usb_serial_poll() usb_execute_realtime(0)
-void usb_serialInit(void);
-int16_t usb_serialGetC(void);
-bool usb_serialPutC(const char c);
-void usb_serialWriteS(const char *s);
-void usb_serialWriteLn(const char *s);
-void usb_serialWrite(const char *s, uint16_t length);
-bool usb_serialSuspendInput (bool suspend);
-
-uint16_t usb_serialTxCount(void);
-uint16_t usb_serialRxCount(void);
-uint16_t usb_serialRxFree(void);
-void usb_serialRxFlush(void);
-void usb_serialRxCancel(void);
+const io_stream_t *usb_serialInit(void);
#endif
diff --git a/grblHAL_Teensy4/src/usb_serial_pjrc.c b/grblHAL_Teensy4/src/usb_serial_pjrc.c
index 1ce4b74..e59c76d 100644
--- a/grblHAL_Teensy4/src/usb_serial_pjrc.c
+++ b/grblHAL_Teensy4/src/usb_serial_pjrc.c
@@ -35,28 +35,20 @@
static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer;
-
-void usb_serialInit(void)
-{
-// usb_serial_configure(); // Done somewhere already - do not call again
- txbuf.s = txbuf.data;
- txbuf.max_length = usb_serial_write_buffer_free(); // 6144
- txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
-}
-
+/*
//
// Returns number of characters in serial input buffer
//
-uint16_t usb_serialRxCount (void)
+static uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}
-
+*/
//
// Returns number of free characters in serial input buffer
//
-uint16_t usb_serialRxFree (void)
+static uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
@@ -65,7 +57,7 @@ uint16_t usb_serialRxFree (void)
//
// Flushes the serial input buffer (including the USB buffer)
//
-void usb_serialRxFlush (void)
+static void usb_serialRxFlush (void)
{
usb_serial_flush_input();
usb_rxbuffer.tail = usb_rxbuffer.head;
@@ -74,7 +66,7 @@ void usb_serialRxFlush (void)
//
// Flushes and adds a CAN character to the serial input buffer
//
-void usb_serialRxCancel (void)
+static void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
@@ -84,7 +76,7 @@ void usb_serialRxCancel (void)
//
// Writes a character to the serial output stream
//
-bool usb_serialPutC (const char c)
+static bool usb_serialPutC (const char c)
{
usb_serial_putchar(c);
@@ -94,7 +86,7 @@ bool usb_serialPutC (const char c)
//
// Writes a null terminated string to the serial output stream, blocks if buffer full
//
-void usb_serialWriteS (const char *s)
+static void usb_serialWriteS (const char *s)
{
if(*s == '\0')
return;
@@ -134,11 +126,11 @@ void usb_serialWriteS (const char *s)
}
}
}
-
+/*
//
// Writes a null terminated string to the serial output stream followed by EOL, blocks if buffer full
//
-void usb_serialWriteLn (const char *s)
+static void usb_serialWriteLn (const char *s)
{
usb_serialWriteS(s);
usb_serialWriteS(ASCII_EOL);
@@ -147,18 +139,18 @@ void usb_serialWriteLn (const char *s)
//
// Writes a number of characters from string to the serial output stream followed by EOL, blocks if buffer full
//
-void usb_serialWrite (const char *s, uint16_t length)
+static void usb_serialWrite (const char *s, uint16_t length)
{
char *ptr = (char *)s;
while(length--)
usb_serialPutC(*ptr++);
}
-
+*/
//
// serialGetC - returns -1 if no data available
//
-int16_t usb_serialGetC (void)
+static int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;
@@ -171,11 +163,33 @@ int16_t usb_serialGetC (void)
return (int16_t)data;
}
-bool usb_serialSuspendInput (bool suspend)
+static bool usb_serialSuspendInput (bool suspend)
{
return stream_rx_suspend(&usb_rxbuffer, suspend);
}
+const io_stream_t *usb_serialInit(void)
+{
+ PROGMEM static const io_stream_t stream = {
+ .type = StreamType_Serial,
+ .read = usb_serialGetC,
+ .write = usb_serialWriteS,
+ .write_char = usb_serialPutC,
+ .write_all = usb_serialWriteS,
+ .get_rx_buffer_free = usb_serialRxFree,
+ .reset_read_buffer = usb_serialRxFlush,
+ .cancel_read_buffer = usb_serialRxCancel,
+ .suspend_read = usb_serialSuspendInput
+ };
+
+// usb_serial_configure(); // Done somewhere already - do not call again
+ txbuf.s = txbuf.data;
+ txbuf.max_length = usb_serial_write_buffer_free(); // 6144
+ txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
+
+ return &stream;
+}
+
//
// This function get called from the systick interrupt handler,
// used here to get characters off the USB serial input stream and buffer
diff --git a/grblHAL_Teensy4/src/usb_serial_pjrc.h b/grblHAL_Teensy4/src/usb_serial_pjrc.h
index ea7d675..ec7b58e 100644
--- a/grblHAL_Teensy4/src/usb_serial_pjrc.h
+++ b/grblHAL_Teensy4/src/usb_serial_pjrc.h
@@ -4,7 +4,7 @@
Part of grblHAL
- Copyright (c) 2018-2020 Terje Io
+ Copyright (c) 2020-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
@@ -27,22 +27,12 @@
#include
#include
+#include "grbl/hal.h"
+
extern void usb_execute_realtime (uint_fast16_t state);
#define usb_serial_poll() usb_execute_realtime(0)
-void usb_serialInit(void);
-int16_t usb_serialGetC(void);
-bool usb_serialPutC(const char c);
-void usb_serialWriteS(const char *s);
-void usb_serialWriteLn(const char *s);
-void usb_serialWrite(const char *s, uint16_t length);
-bool usb_serialSuspendInput (bool suspend);
-
-uint16_t usb_serialTxCount(void);
-uint16_t usb_serialRxCount(void);
-uint16_t usb_serialRxFree(void);
-void usb_serialRxFlush(void);
-void usb_serialRxCancel(void);
+const io_stream_t *usb_serialInit(void);
#endif