Updated to use encapsulated stream code and stadardized motor allocations.

Added support for Bluetooth plugin.
This commit is contained in:
Terje Io 2021-06-27 21:02:38 +02:00
parent 0d7d05c656
commit f0e1c4dd1b
18 changed files with 824 additions and 837 deletions

View File

@ -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)

View File

@ -21,8 +21,12 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#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.

View File

@ -21,84 +21,48 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#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.

View File

@ -23,84 +23,48 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -19,38 +19,46 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#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.

View File

@ -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 <math.h>
@ -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;

View File

@ -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

View File

@ -0,0 +1,75 @@
/*
my_plugin.c - plugin template for setting auxillary output on feed hold
Part of grblHAL
Public domain.
*/
#include <string.h>
#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.
}
}

View File

@ -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;

View File

@ -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 <stdbool.h>
#include <stdint.h>
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

View File

@ -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

View File

@ -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 <stdbool.h>
#include <stdint.h>
#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

View File

@ -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

View File

@ -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 <stdbool.h>
#include <stdint.h>
#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