Extended handling of legacy printable real-time commands due to ESP32 RTOS issue.

Internal changes to crossbar definitions, improved stream handling and sleep handling.
This commit is contained in:
Terje Io
2023-05-19 19:17:32 +02:00
parent af2a922915
commit 44e4dc4ea3
11 changed files with 273 additions and 162 deletions

View File

@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
Latest build date is 20230501 see the [changelog](changelog.md) for details.
Latest build date is 20230507 see the [changelog](changelog.md) for details.
__NOTE:__ A settings reset will be performed on an update of builds earlier than 20230125. Backup and restore of settings is recommended.
__IMPORTANT!__ A new setting has been introduced for ganged axes motors in build 20211121.
I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured.
@@ -86,7 +86,9 @@ List of Supported G-Codes:
***** requires keypad macros plugin or SD card plugin. Nesting is not allowed.
```
G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are documented [here](https://github.com/grblHAL/core/wiki/Additional-G--and-M-codes).
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
---
2023-05-07
2023-05-11

View File

@@ -1,5 +1,29 @@
## grblHAL changelog
<a name="20230519"/>20230519
Core:
* Extended handling of legacy printable real-time commands due to ESP32 RTOS issue.
* Internal to changes for crossbar definitions, improved stream handling and sleep handling.
Plugins:
* Networking: added support for some WIZnet SPI based ethernet breakout boards, currently only W5100S and W5500 based. Updated for core changes.
Drivers:
* STM32F4xx: added low level driver support for WIZnet SPI based ethernet breakout boards, updated SPI interface for DMA transfer.
* RP2040: added low level driver support for WIZnet SPI based ethernet breakout boards, updated SPI interface for DMA transfer.
__NOTE:__ Build support for ethernet is not yet ready!
Web Builder:
Added options for spindle sync and WIZnet networking for relevant drivers and boards.
---
<a name="20230507"/>20230507
Core:

View File

@@ -58,6 +58,7 @@ typedef enum {
Input_LimitV,
Input_LimitV_Max,
Input_MISO,
Input_SPIIRQ,
Input_RX,
Input_KeypadStrobe, // To be deprecated? Use Input_I2CStrobe instead.
Input_I2CStrobe,
@@ -75,6 +76,14 @@ typedef enum {
Input_Aux5,
Input_Aux6,
Input_Aux7,
Input_Analog_Aux0,
Input_Analog_Aux1,
Input_Analog_Aux2,
Input_Analog_Aux3,
Input_Analog_Aux4,
Input_Analog_Aux5,
Input_Analog_Aux6,
Input_Analog_Aux7,
Input_MotorWarning,
Input_MotorFault,
Outputs,
@@ -130,6 +139,8 @@ typedef enum {
Output_RTS,
Output_SCK,
Output_MOSI,
Output_SPIRST,
Output_SPICS,
Output_SdCardCS,
Output_Aux0,
Output_Aux1,
@@ -139,6 +150,14 @@ typedef enum {
Output_Aux5,
Output_Aux6,
Output_Aux7,
Output_Analog_Aux0,
Output_Analog_Aux1,
Output_Analog_Aux2,
Output_Analog_Aux3,
Output_Analog_Aux4,
Output_Analog_Aux5,
Output_Analog_Aux6,
Output_Analog_Aux7,
Bidirectional,
Bidirectional_SDA = Bidirectional,
Bidirectional_MotorUARTX,
@@ -161,137 +180,156 @@ typedef struct {
} pin_name_t;
PROGMEM static const pin_name_t pin_names[] = {
{ .function = Input_Probe, .name = "Probe" },
{ .function = Input_Reset, .name = "Reset" },
{ .function = Input_FeedHold, .name = "Feed hold" },
{ .function = Input_CycleStart, .name = "Cycle start" },
{ .function = Input_SafetyDoor, .name = "Safety door" },
{ .function = Input_LimitsOverride, .name = "Limits override" },
{ .function = Input_EStop, .name = "Emergency stop" },
{ .function = Input_BlockDelete, .name = "Block delete" },
{ .function = Input_SingleBlock, .name = "Single block" },
{ .function = Input_StopDisable, .name = "Stop disable" },
{ .function = Input_ProbeDisconnect, .name = "Probe disconnect" },
{ .function = Input_MPGSelect, .name = "MPG mode select" },
{ .function = Input_LimitX, .name = "X limit min" },
{ .function = Input_LimitX_2, .name = "X limit min 2" },
{ .function = Input_LimitX_Max, .name = "X limit max" },
{ .function = Input_LimitY, .name = "Y limit min" },
{ .function = Input_LimitY_2, .name = "Y limit min 2" },
{ .function = Input_LimitY_Max, .name = "Y limit max" },
{ .function = Input_LimitZ, .name = "Z limit min" },
{ .function = Input_LimitZ_2, .name = "Z limit min 2" },
{ .function = Input_LimitZ_Max, .name = "Z limit max" },
{ .function = Input_MISO, .name = "MISO" },
{ .function = Input_RX, .name = "RX" },
{ .function = Input_KeypadStrobe, .name = "Keypad strobe" },
{ .function = Input_I2CStrobe, .name = "I2C strobe" },
{ .function = Input_QEI_A, .name = "QEI A" },
{ .function = Input_QEI_B, .name = "QEI B" },
{ .function = Input_QEI_Select, .name = "QEI select" },
{ .function = Input_QEI_Index, .name = "QEI index" },
{ .function = Input_SpindleIndex, .name = "Spindle index" },
{ .function = Input_SpindlePulse, .name = "Spindle pulse" },
{ .function = Input_MotorWarning, .name = "Motor warning" },
{ .function = Input_MotorFault, .name = "Motor fault" },
{ .function = Input_Aux0, .name = "Aux input 0" },
{ .function = Input_Aux1, .name = "Aux input 1" },
{ .function = Input_Aux2, .name = "Aux input 2" },
{ .function = Input_Aux3, .name = "Aux input 3" },
{ .function = Input_Aux4, .name = "Aux input 4" },
{ .function = Input_Aux5, .name = "Aux input 5" },
{ .function = Input_Aux6, .name = "Aux input 6" },
{ .function = Input_Aux7, .name = "Aux input 7" },
{ .function = Output_StepX, .name = "X step" },
{ .function = Output_StepX_2, .name = "X2 step" },
{ .function = Output_StepY, .name = "Y step" },
{ .function = Output_StepY_2, .name = "Y2 step" },
{ .function = Output_StepZ, .name = "Z step" },
{ .function = Output_StepZ_2, .name = "Z2 step" },
{ .function = Output_DirX, .name = "X dir" },
{ .function = Output_DirX_2, .name = "X2 dir" },
{ .function = Output_DirY, .name = "Y dir" },
{ .function = Output_DirY_2, .name = "Y2 dir" },
{ .function = Output_DirZ, .name = "Z dir" },
{ .function = Output_DirZ_2, .name = "Z2 dir" },
{ .function = Output_StepperPower, .name = "Stepper power" },
{ .function = Output_StepperEnable, .name = "Steppers enable" },
{ .function = Output_StepperEnableX, .name = "X enable" },
{ .function = Output_StepperEnableY, .name = "Y enable" },
{ .function = Output_StepperEnableZ, .name = "Z enable" },
{ .function = Output_StepperEnableXY, .name = "XY enable" },
{ .function = Input_Probe, .name = "Probe" },
{ .function = Input_Reset, .name = "Reset" },
{ .function = Input_FeedHold, .name = "Feed hold" },
{ .function = Input_CycleStart, .name = "Cycle start" },
{ .function = Input_SafetyDoor, .name = "Safety door" },
{ .function = Input_LimitsOverride, .name = "Limits override" },
{ .function = Input_EStop, .name = "Emergency stop" },
{ .function = Input_BlockDelete, .name = "Block delete" },
{ .function = Input_SingleBlock, .name = "Single block" },
{ .function = Input_StopDisable, .name = "Stop disable" },
{ .function = Input_ProbeDisconnect, .name = "Probe disconnect" },
{ .function = Input_MPGSelect, .name = "MPG mode select" },
{ .function = Input_LimitX, .name = "X limit min" },
{ .function = Input_LimitX_2, .name = "X limit min 2" },
{ .function = Input_LimitX_Max, .name = "X limit max" },
{ .function = Input_LimitY, .name = "Y limit min" },
{ .function = Input_LimitY_2, .name = "Y limit min 2" },
{ .function = Input_LimitY_Max, .name = "Y limit max" },
{ .function = Input_LimitZ, .name = "Z limit min" },
{ .function = Input_LimitZ_2, .name = "Z limit min 2" },
{ .function = Input_LimitZ_Max, .name = "Z limit max" },
{ .function = Input_MISO, .name = "MISO" },
{ .function = Input_SPIIRQ, .name = "SPI IRQ" },
{ .function = Input_RX, .name = "RX" },
{ .function = Input_KeypadStrobe, .name = "Keypad strobe" },
{ .function = Input_I2CStrobe, .name = "I2C strobe" },
{ .function = Input_QEI_A, .name = "QEI A" },
{ .function = Input_QEI_B, .name = "QEI B" },
{ .function = Input_QEI_Select, .name = "QEI select" },
{ .function = Input_QEI_Index, .name = "QEI index" },
{ .function = Input_SpindleIndex, .name = "Spindle index" },
{ .function = Input_SpindlePulse, .name = "Spindle pulse" },
{ .function = Input_MotorWarning, .name = "Motor warning" },
{ .function = Input_MotorFault, .name = "Motor fault" },
{ .function = Input_Aux0, .name = "Aux input 0" },
{ .function = Input_Aux1, .name = "Aux input 1" },
{ .function = Input_Aux2, .name = "Aux input 2" },
{ .function = Input_Aux3, .name = "Aux input 3" },
{ .function = Input_Aux4, .name = "Aux input 4" },
{ .function = Input_Aux5, .name = "Aux input 5" },
{ .function = Input_Aux6, .name = "Aux input 6" },
{ .function = Input_Aux7, .name = "Aux input 7" },
{ .function = Input_Analog_Aux0, .name = "Aux analog input 0" },
{ .function = Input_Analog_Aux1, .name = "Aux analog input 1" },
{ .function = Input_Analog_Aux2, .name = "Aux analog input 2" },
{ .function = Input_Analog_Aux3, .name = "Aux analog input 3" },
{ .function = Input_Analog_Aux4, .name = "Aux analog input 4" },
{ .function = Input_Analog_Aux5, .name = "Aux analog input 5" },
{ .function = Input_Analog_Aux6, .name = "Aux analog input 6" },
{ .function = Input_Analog_Aux7, .name = "Aux analog input 7" },
{ .function = Output_StepX, .name = "X step" },
{ .function = Output_StepX_2, .name = "X2 step" },
{ .function = Output_StepY, .name = "Y step" },
{ .function = Output_StepY_2, .name = "Y2 step" },
{ .function = Output_StepZ, .name = "Z step" },
{ .function = Output_StepZ_2, .name = "Z2 step" },
{ .function = Output_DirX, .name = "X dir" },
{ .function = Output_DirX_2, .name = "X2 dir" },
{ .function = Output_DirY, .name = "Y dir" },
{ .function = Output_DirY_2, .name = "Y2 dir" },
{ .function = Output_DirZ, .name = "Z dir" },
{ .function = Output_DirZ_2, .name = "Z2 dir" },
{ .function = Output_StepperPower, .name = "Stepper power" },
{ .function = Output_StepperEnable, .name = "Steppers enable" },
{ .function = Output_StepperEnableX, .name = "X enable" },
{ .function = Output_StepperEnableY, .name = "Y enable" },
{ .function = Output_StepperEnableZ, .name = "Z enable" },
{ .function = Output_StepperEnableXY, .name = "XY enable" },
#ifdef A_AXIS
{ .function = Output_StepA, .name = "A step" },
{ .function = Output_DirA, .name = "A dir" },
{ .function = Output_StepperEnableA, .name = "A enable" },
{ .function = Input_LimitA, .name = "A limit min" },
{ .function = Input_LimitA_Max, .name = "A limit max" },
{ .function = Output_StepA, .name = "A step" },
{ .function = Output_DirA, .name = "A dir" },
{ .function = Output_StepperEnableA, .name = "A enable" },
{ .function = Input_LimitA, .name = "A limit min" },
{ .function = Input_LimitA_Max, .name = "A limit max" },
#endif
#ifdef B_AXIS
{ .function = Output_StepB, .name = "B step" },
{ .function = Output_DirB, .name = "B dir" },
{ .function = Output_StepperEnableB, .name = "B enable" },
{ .function = Output_StepperEnableAB, .name = "AB enable" },
{ .function = Input_LimitB, .name = "B limit min" },
{ .function = Input_LimitB_Max, .name = "B limit max" },
{ .function = Output_StepB, .name = "B step" },
{ .function = Output_DirB, .name = "B dir" },
{ .function = Output_StepperEnableB, .name = "B enable" },
{ .function = Output_StepperEnableAB, .name = "AB enable" },
{ .function = Input_LimitB, .name = "B limit min" },
{ .function = Input_LimitB_Max, .name = "B limit max" },
#endif
#ifdef C_AXIS
{ .function = Output_StepC, .name = "C step" },
{ .function = Output_DirC, .name = "C dir" },
{ .function = Output_StepperEnableC, .name = "C enable" },
{ .function = Input_LimitC, .name = "C limit min" },
{ .function = Input_LimitC_Max, .name = "C limit max" },
{ .function = Output_StepC, .name = "C step" },
{ .function = Output_DirC, .name = "C dir" },
{ .function = Output_StepperEnableC, .name = "C enable" },
{ .function = Input_LimitC, .name = "C limit min" },
{ .function = Input_LimitC_Max, .name = "C limit max" },
#endif
#ifdef U_AXIS
{ .function = Output_StepU, .name = "U step" },
{ .function = Output_DirU, .name = "U dir" },
{ .function = Output_StepperEnableU, .name = "U enable" },
{ .function = Input_LimitU, .name = "U limit min" },
{ .function = Input_LimitU_Max, .name = "U limit max" },
{ .function = Output_StepU, .name = "U step" },
{ .function = Output_DirU, .name = "U dir" },
{ .function = Output_StepperEnableU, .name = "U enable" },
{ .function = Input_LimitU, .name = "U limit min" },
{ .function = Input_LimitU_Max, .name = "U limit max" },
#endif
#ifdef V_AXIS
{ .function = Output_StepV, .name = "V step" },
{ .function = Output_DirV, .name = "V dir" },
{ .function = Output_StepperEnableV, .name = "V enable" },
{ .function = Input_LimitV, .name = "V limit min" },
{ .function = Input_LimitV_Max, .name = "V limit max" },
{ .function = Output_StepV, .name = "V step" },
{ .function = Output_DirV, .name = "V dir" },
{ .function = Output_StepperEnableV, .name = "V enable" },
{ .function = Input_LimitV, .name = "V limit min" },
{ .function = Input_LimitV_Max, .name = "V limit max" },
#endif
{ .function = Output_MotorChipSelect, .name = "Motor CS" },
{ .function = Output_MotorChipSelectX, .name = "Motor CSX" },
{ .function = Output_MotorChipSelectY, .name = "Motor CSY" },
{ .function = Output_MotorChipSelectZ, .name = "Motor CSZ" },
{ .function = Output_MotorChipSelectM3, .name = "Motor CSM3" },
{ .function = Output_MotorChipSelectM4, .name = "Motor CSM4" },
{ .function = Output_MotorChipSelectM5, .name = "Motor CSM5" },
{ .function = Output_MotorChipSelectM6, .name = "Motor CSM6" },
{ .function = Output_MotorChipSelectM7, .name = "Motor CSM7" },
{ .function = Output_SpindleOn, .name = "Spindle on" },
{ .function = Output_SpindleDir, .name = "Spindle direction" },
{ .function = Output_SpindlePWM, .name = "Spindle PWM" },
{ .function = Output_CoolantMist, .name = "Mist" },
{ .function = Output_CoolantFlood, .name = "Flood" },
{ .function = Output_TX, .name = "TX" },
{ .function = Output_RTS, .name = "RTS" },
{ .function = Output_SCK, .name = "SCK" },
{ .function = Output_MOSI, .name = "MOSI" },
{ .function = Output_SdCardCS, .name = "SD card CS" },
{ .function = Output_Aux0, .name = "Aux out 0" },
{ .function = Output_Aux1, .name = "Aux out 1" },
{ .function = Output_Aux2, .name = "Aux out 2" },
{ .function = Output_Aux3, .name = "Aux out 3" },
{ .function = Output_Aux4, .name = "Aux out 4" },
{ .function = Output_Aux5, .name = "Aux out 5" },
{ .function = Output_Aux6, .name = "Aux out 6" },
{ .function = Output_Aux7, .name = "Aux out 7" },
{ .function = Bidirectional_SDA, .name = "SDA" },
{ .function = Bidirectional_MotorUARTX, .name = "UART X" },
{ .function = Bidirectional_MotorUARTY, .name = "UART Y" },
{ .function = Bidirectional_MotorUARTZ, .name = "UART Z" },
{ .function = Bidirectional_MotorUARTM3, .name = "UART M3" },
{ .function = Bidirectional_MotorUARTM4, .name = "UART M4" },
{ .function = Bidirectional_MotorUARTM5, .name = "UART M5" },
{ .function = Bidirectional_MotorUARTM6, .name = "UART M6" },
{ .function = Bidirectional_MotorUARTM7, .name = "UART M7" }
{ .function = Output_MotorChipSelect, .name = "Motor CS" },
{ .function = Output_MotorChipSelectX, .name = "Motor CSX" },
{ .function = Output_MotorChipSelectY, .name = "Motor CSY" },
{ .function = Output_MotorChipSelectZ, .name = "Motor CSZ" },
{ .function = Output_MotorChipSelectM3, .name = "Motor CSM3" },
{ .function = Output_MotorChipSelectM4, .name = "Motor CSM4" },
{ .function = Output_MotorChipSelectM5, .name = "Motor CSM5" },
{ .function = Output_MotorChipSelectM6, .name = "Motor CSM6" },
{ .function = Output_MotorChipSelectM7, .name = "Motor CSM7" },
{ .function = Output_SpindleOn, .name = "Spindle on" },
{ .function = Output_SpindleDir, .name = "Spindle direction" },
{ .function = Output_SpindlePWM, .name = "Spindle PWM" },
{ .function = Output_CoolantMist, .name = "Mist" },
{ .function = Output_CoolantFlood, .name = "Flood" },
{ .function = Output_TX, .name = "TX" },
{ .function = Output_RTS, .name = "RTS" },
{ .function = Output_SCK, .name = "SCK" },
{ .function = Output_MOSI, .name = "MOSI" },
{ .function = Output_SPIRST, .name = "SPI reset" },
{ .function = Output_SPICS, .name = "SPI CS" },
{ .function = Output_SdCardCS, .name = "SD card CS" },
{ .function = Output_Aux0, .name = "Aux out 0" },
{ .function = Output_Aux1, .name = "Aux out 1" },
{ .function = Output_Aux2, .name = "Aux out 2" },
{ .function = Output_Aux3, .name = "Aux out 3" },
{ .function = Output_Aux4, .name = "Aux out 4" },
{ .function = Output_Aux5, .name = "Aux out 5" },
{ .function = Output_Aux6, .name = "Aux out 6" },
{ .function = Output_Aux7, .name = "Aux out 7" },
{ .function = Output_Analog_Aux0, .name = "Aux analog out 0" },
{ .function = Output_Analog_Aux1, .name = "Aux analog out 1" },
{ .function = Output_Analog_Aux2, .name = "Aux analog out 2" },
{ .function = Output_Analog_Aux3, .name = "Aux analog out 3" },
{ .function = Output_Analog_Aux4, .name = "Aux analog out 4" },
{ .function = Output_Analog_Aux5, .name = "Aux analog out 5" },
{ .function = Output_Analog_Aux6, .name = "Aux analog out 6" },
{ .function = Output_Analog_Aux7, .name = "Aux analog out 7" },
{ .function = Bidirectional_SDA, .name = "SDA" },
{ .function = Bidirectional_MotorUARTX, .name = "UART X" },
{ .function = Bidirectional_MotorUARTY, .name = "UART Y" },
{ .function = Bidirectional_MotorUARTZ, .name = "UART Z" },
{ .function = Bidirectional_MotorUARTM3, .name = "UART M3" },
{ .function = Bidirectional_MotorUARTM4, .name = "UART M4" },
{ .function = Bidirectional_MotorUARTM5, .name = "UART M5" },
{ .function = Bidirectional_MotorUARTM6, .name = "UART M6" },
{ .function = Bidirectional_MotorUARTM7, .name = "UART M7" }
};
typedef enum {
@@ -344,7 +382,8 @@ typedef enum {
} pin_irq_mode_t;
typedef enum {
IRQ_I2C_Strobe = 0
IRQ_I2C_Strobe = 0,
IRQ_SPI
} irq_type_t;
typedef bool (*irq_callback_ptr)(uint_fast8_t id, bool level);
@@ -371,6 +410,8 @@ typedef enum {
#define PINMODE_PULLUP (PullMode_Up<<3)
#define PINMODE_PULLDOWN (PullMode_Down<<3)
#define PINMODE_REMAP (1U<<10)
#define PINMODE_PWM (1U<<11)
#define PINMODE_ANALOG (1U<<12)
typedef union {
uint16_t mask;
@@ -389,12 +430,23 @@ typedef union {
};
} pin_mode_t;
typedef bool (*xbar_get_value_ptr)(void);
typedef void (*xbar_set_value_ptr)(bool on);
typedef void (*xbar_event_ptr)(bool on);
typedef void (*xbar_config_ptr)(void *cfg_data);
//! /a cfg_data argument to /a xbar_config_ptr for PWM pins
typedef struct {
float freq_hz; //
float off_value; // percent of period
float min_value; // percent of period
float max_value; // percent of period
bool invert;
} pwm_config_t;
struct xbar;
typedef float (*xbar_get_value_ptr)(struct xbar *pin);
typedef void (*xbar_set_value_ptr)(struct xbar *pin, float value);
typedef void (*xbar_event_ptr)(bool on);
typedef void (*xbar_config_ptr)(struct xbar *pin, void *cfg_data);
typedef struct xbar {
pin_function_t function;
pin_group_t group;
void *port;
@@ -406,7 +458,7 @@ typedef struct {
xbar_config_ptr config;
xbar_get_value_ptr get_value;
xbar_set_value_ptr set_value;
xbar_event_ptr on_event;
xbar_event_ptr on_event; // ?? - remove?
} xbar_t;
typedef struct {

2
grbl.h
View File

@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20230507
#define GRBL_BUILD 20230519
#define GRBL_URL "https://github.com/grblHAL"

9
hal.h
View File

@@ -79,14 +79,6 @@ typedef void (*driver_reset_ptr)(void);
/*! \brief Pointer to function for getting free memory (as sum of all free blocks in the heap). */
typedef uint32_t (*get_free_mem_ptr)(void);
/*! \brief Optional pointer to function for switching between I/O streams.
\param stream pointer to io_stream_t
\returns true if switch was successful
__NOTE:__ required if the networking plugin is to be supported.
*/
typedef bool (*stream_select_ptr)(const io_stream_t *stream);
/*! \brief Pointer to function for registering information about a peripheral pin.
\param pin as periph_pin_t struct containing pin information.
*/
@@ -585,7 +577,6 @@ typedef struct {
spindle_data_ptrs_t spindle_data; //!< Handlers for getting/resetting spindle data (RPM, angular position, ...).
stepper_ptrs_t stepper; //!< Handlers for stepper motors.
io_stream_t stream; //!< Handlers for stream I/O.
stream_select_ptr stream_select; //!< Optional handler for switching between I/O streams.
settings_changed_ptr settings_changed; //!< Callback handler to be called on settings loaded or settings changed events.
probe_ptrs_t probe; //!< Optional handlers for probe input(s).
tool_ptrs_t tool; //!< Optional handlers for tool changes.

View File

@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2021 Terje Io
Copyright (c) 2021-2023 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
@@ -90,7 +90,7 @@ bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port,
uint8_t n_ports = ioports_available(type, dir);
uint8_t base = type == Port_Digital
? (dir == Port_Input ? Input_Aux0 : Output_Aux0)
: (dir == Port_Input ? Input_Aux0 : Output_Aux0); // TODO add analog ports?
: (dir == Port_Input ? Input_Analog_Aux0 : Output_Analog_Aux0);
if(hal.port.claim != NULL) {

View File

@@ -197,6 +197,10 @@
#define I2C_STROBE_BIT (1<<I2C_STROBE_PIN)
#endif
#if defined(SPI_IRQ_PIN) && !defined(SPI_IRQ_BIT)
#define SPI_IRQ_BIT (1<<SPI_IRQ_PIN)
#endif
#if defined(RTS_PIN) && !defined(RTS_BIT)
#define RTS_BIT (1<<RTS_PIN)
#endif

View File

@@ -813,6 +813,11 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
case '\r':
break;
case '$':
if(char_counter == 0)
keep_rt_commands = !settings.flags.legacy_rt_commands;
break;
case CMD_STOP:
system_set_exec_state_flag(EXEC_STOP);
char_counter = 0;

View File

@@ -41,6 +41,7 @@ static void sleep_execute()
uint16_t rx_initial = hal.stream.get_rx_buffer_free();
do {
grbl.on_execute_realtime(state_get());
// Monitor for any new input stream data or external events (queries, buttons, alarms) to exit.
if ((hal.stream.get_rx_buffer_free() != rx_initial) || sys.rt_exec_state || sys.rt_exec_alarm ) {
// Disable sleep timeout and return to normal operation.

View File

@@ -37,15 +37,15 @@ typedef struct {
typedef union {
uint8_t value;
struct {
uint8_t is_up :1,
is_mpg :1,
uint8_t is_mpg :1,
is_mpg_tx :1,
unused :5;
unused :6;
};
} stream_connection_flags_t;
typedef struct stream_connection {
const io_stream_t *stream;
stream_is_connected_ptr is_up;
stream_connection_flags_t flags;
struct stream_connection *next;
} stream_connection_t;
@@ -162,28 +162,54 @@ ISR_CODE bool ISR_FUNC(stream_enqueue_realtime_command)(char c)
return hal.stream.enqueue_rt_command ? hal.stream.enqueue_rt_command(c) : protocol_enqueue_realtime_command(c);
}
static bool connection_is_up (io_stream_t *stream)
{
if(stream->is_connected)
return stream->is_connected();
stream_connection_t *connection = connections;
while(connection) {
if(connection->stream->type == stream->type &&
connection->stream->instance == stream->instance &&
connection->stream->state.is_usb == stream->state.is_usb)
return connection->is_up();
connection = connection->next;
}
return false;
}
static void stream_write_all (const char *s)
{
stream_connection_t *connection = connections;
while(connection) {
if(connection->flags.is_up)
if(connection->is_up())
connection->stream->write(s);
connection = connection->next;
}
}
static bool is_connected (void)
{
return true;
}
static bool is_not_connected (void)
{
return false;
}
static stream_connection_t *add_connection (const io_stream_t *stream)
{
stream_connection_t *connection, *last = connections;
if(base.stream == NULL) {
base.stream = stream;
base.flags.is_up = stream->state.connected == On;
connection = &base;
} else if((connection = malloc(sizeof(stream_connection_t)))) {
connection->stream = stream;
connection->flags.is_up = stream->state.connected == On || stream->state.is_usb == On; // TODO: add connect/disconnect event to driver code
connection->next = NULL;
while(last->next) {
last = last->next;
@@ -195,6 +221,8 @@ static stream_connection_t *add_connection (const io_stream_t *stream)
last->next = connection;
}
connection->is_up = stream->is_connected ? stream->is_connected : (stream->state.is_usb ? is_not_connected : is_connected);
return connection;
}
@@ -203,7 +231,7 @@ static bool stream_select (const io_stream_t *stream, bool add)
static const io_stream_t *active_stream = NULL;
if(stream == base.stream) {
base.flags.is_up = add;
base.is_up = add ? (stream->is_connected ? stream->is_connected : is_connected) : is_not_connected;
return true;
}
@@ -237,14 +265,14 @@ static bool stream_select (const io_stream_t *stream, bool add)
switch(stream->type) {
case StreamType_Serial:
if(active_stream && active_stream->type != StreamType_Serial && stream->state.connected) {
if(active_stream && active_stream->type != StreamType_Serial && connection_is_up((io_stream_t *)stream)) {
hal.stream.write = stream->write;
report_message("SERIAL STREAM ACTIVE", Message_Plain);
}
break;
case StreamType_Telnet:
if(hal.stream.state.connected)
if(connection_is_up(&hal.stream))
report_message("TELNET STREAM ACTIVE", Message_Plain);
if(add && sys.driver_started) {
hal.stream.write_all = stream->write;
@@ -253,7 +281,7 @@ static bool stream_select (const io_stream_t *stream, bool add)
break;
case StreamType_WebSocket:
if(hal.stream.state.connected)
if(connection_is_up(&hal.stream))
report_message("WEBSOCKET STREAM ACTIVE", Message_Plain);
if(add && sys.driver_started && !hal.stream.state.webui_connected) {
hal.stream.write_all = stream->write;
@@ -262,7 +290,7 @@ static bool stream_select (const io_stream_t *stream, bool add)
break;
case StreamType_Bluetooth:
if(hal.stream.state.connected)
if(connection_is_up(&hal.stream))
report_message("BLUETOOTH STREAM ACTIVE", Message_Plain);
if(add && sys.driver_started) {
hal.stream.write_all = stream->write;
@@ -321,9 +349,9 @@ io_stream_flags_t stream_get_flags (io_stream_t stream)
bool stream_connect (const io_stream_t *stream)
{
bool ok = hal.stream_select ? hal.stream_select(stream) : stream_select(stream, true);
bool ok;
if(ok && stream->type == StreamType_Serial && hal.periph_port.set_pin_description) {
if((ok = stream_select(stream, true)) && stream->type == StreamType_Serial && !stream->state.is_usb && hal.periph_port.set_pin_description) {
hal.periph_port.set_pin_description(Input_RX, (pin_group_t)(PinGroup_UART + stream->instance), "Primary UART");
hal.periph_port.set_pin_description(Output_TX, (pin_group_t)(PinGroup_UART + stream->instance), "Primary UART");
}
@@ -356,9 +384,7 @@ bool stream_connect_instance (uint8_t instance, uint32_t baud_rate)
void stream_disconnect (const io_stream_t *stream)
{
if(hal.stream_select)
hal.stream_select(NULL);
else if(stream)
if(stream)
stream_select(stream, false);
}
@@ -381,14 +407,14 @@ bool stream_mpg_register (const io_stream_t *stream, bool rx_only, stream_write_
if(stream == NULL || stream->type != StreamType_Serial || stream->disable_rx == NULL)
return false;
base.flags.is_up = On;
// base.flags.is_up = On;
mpg_write_char = write_char;
if(stream->write == NULL || rx_only) {
mpg.stream = stream;
mpg.flags.is_up = stream->state.connected;
mpg.is_up = is_connected;
return true;
}
@@ -527,7 +553,7 @@ const io_stream_t *stream_null_init (uint32_t baud_rate)
{
static const io_stream_t stream = {
.type = StreamType_Null,
.state.connected = On,
.is_connected = is_connected,
.read = stream_get_null,
.write = null_write_string,
.write_n = null_write,

View File

@@ -89,6 +89,11 @@ typedef enum {
StreamType_Null
} stream_type_t;
/*! \brief Pointer to function for getting stream connected status.
\returns \a true connected, \a false otherwise.
*/
typedef bool (*stream_is_connected_ptr)(void);
/*! \brief Pointer to function for getting number of characters available or free in a stream buffer.
\returns number of characters available or free.
*/
@@ -197,7 +202,7 @@ typedef bool (*disable_rx_stream_ptr)(bool disable);
typedef union {
uint8_t value;
struct {
uint8_t connected :1,
uint8_t connected :1, //!< deprecated
claimable :1,
claimed :1,
can_set_baud :1,
@@ -223,6 +228,7 @@ typedef struct {
stream_type_t type; //!< Type of stream.
uint8_t instance; //!< Instance of stream type, starts from 0.
io_stream_state_t state; //!< Optional status flags such as connected status.
stream_is_connected_ptr is_connected; //!< Handler for getting stream connected status.
get_stream_buffer_count_ptr get_rx_buffer_free; //!< Handler for getting number of free characters in the input buffer.
stream_write_ptr write; //!< Handler for writing string to current output stream only.
stream_write_ptr write_all; //!< Handler for writing string to all active output streams.