diff --git a/CMakeLists.txt b/CMakeLists.txt
index c98583d..230010f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,7 @@ target_sources(grbl INTERFACE
${CMAKE_CURRENT_LIST_DIR}/sleep.c
${CMAKE_CURRENT_LIST_DIR}/spindle_control.c
${CMAKE_CURRENT_LIST_DIR}/state_machine.c
+ ${CMAKE_CURRENT_LIST_DIR}/stream.c
${CMAKE_CURRENT_LIST_DIR}/stepper.c
${CMAKE_CURRENT_LIST_DIR}/system.c
${CMAKE_CURRENT_LIST_DIR}/tool_change.c
diff --git a/grbl.h b/grbl.h
index ebc5fae..46556f3 100644
--- a/grbl.h
+++ b/grbl.h
@@ -34,7 +34,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
-#define GRBL_VERSION_BUILD "20210223"
+#define GRBL_VERSION_BUILD "20210313"
// The following symbols are set here if not already set by the compiler or in config.h
// Do NOT change here!
diff --git a/nvs_buffer.c b/nvs_buffer.c
index 2903644..0cf7cb7 100644
--- a/nvs_buffer.c
+++ b/nvs_buffer.c
@@ -199,9 +199,11 @@ bool nvs_buffer_alloc (void)
//
// Switch over to RAM based copy.
-// Changes to RAM based copy will be written to physical storage when Grbl is in IDLE state.
+// Changes to RAM based copy will be written to physical storage when grblHAL is in IDLE state.
bool nvs_buffer_init (void)
{
+ hal.nvs.size = ((hal.nvs.size - 1) | 0x03) + 1; // Ensure NVS area ends on a word boundary
+
if(nvsbuffer) {
memcpy(&physical_nvs, &hal.nvs, sizeof(nvs_io_t)); // save pointers to physical storage handler functions
diff --git a/stream.c b/stream.c
new file mode 100644
index 0000000..ba9b604
--- /dev/null
+++ b/stream.c
@@ -0,0 +1,49 @@
+/*
+ stream.h - shared stream rx buffer copy for tool change protocol
+
+ Part of grblHAL
+
+ Copyright (c) 2021 Terje Io
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+*/
+
+#include
+
+#include "hal.h"
+
+static stream_rx_buffer_t rxbackup;
+
+// "dummy" version of serialGetC
+static int16_t stream_get_null (void)
+{
+ return SERIAL_NO_DATA;
+}
+
+bool stream_rx_suspend (stream_rx_buffer_t *rxbuffer, bool suspend)
+{
+ if(suspend)
+ hal.stream.read = stream_get_null;
+ else if(rxbuffer->backup)
+ memcpy(rxbuffer, &rxbackup, sizeof(stream_rx_buffer_t));
+
+ return rxbuffer->tail != rxbuffer->head;
+}
+
+ISR_CODE void stream_rx_backup (stream_rx_buffer_t *rxbuffer)
+{
+ memcpy(&rxbackup, rxbuffer, sizeof(stream_rx_buffer_t));
+ rxbuffer->backup = true;
+ rxbuffer->tail = rxbuffer->head;
+}
diff --git a/stream.h b/stream.h
index 7e0af6e..07e62c0 100644
--- a/stream.h
+++ b/stream.h
@@ -104,4 +104,7 @@ typedef struct {
char data[BLOCK_TX_BUFFER_SIZE];
} stream_block_tx_buffer_t;
+bool stream_rx_suspend (stream_rx_buffer_t *rxbuffer, bool suspend);
+void stream_rx_backup (stream_rx_buffer_t *rxbuffer);
+
#endif