From 24d802e57369f55be54fd657f6dc23baa0dedb47 Mon Sep 17 00:00:00 2001 From: Terje Io Date: Thu, 4 Sep 2025 08:36:48 +0200 Subject: [PATCH] Fix for bug preventing disabling of AMASS, changed the ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING symbol so it can be overridden via compiler argument. For developers: added output function parameter to signature of report_realtime_status() call to allow routing output to a given stream (or streams). --- changelog.md | 20 ++++++++- core_handlers.h | 2 +- grbl.h | 8 ++-- grbllib.c | 2 +- machine_limits.c | 2 +- protocol.c | 4 +- report.c | 112 +++++++++++++++++++++++------------------------ report.h | 2 +- stepper.c | 36 ++++++++------- stream.c | 5 +++ stream.h | 10 ++++- 11 files changed, 118 insertions(+), 85 deletions(-) diff --git a/changelog.md b/changelog.md index 4febd34..569b699 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,21 @@ ## grblHAL changelog +Build 20250902 + +Core: + +* Fix for bug preventing disabling of AMASS, changed the `ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING` symbol so it can be overridden via compiler argument. + +* For developers: added output function parameter to signature of `report_realtime_status()` call to allow routing output to a given stream \(or streams\). + +Drivers: + +* ESP32, TM4C123: updated for changed `ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING` symbol. + +* RP2040: updated BTT SKR Pico v1 map to use _Servo_ port for reset/estop in four motor configurations. Ref discussion [#110](https://github.com/grblHAL/RP2040/discussions/110). + +--- + 20250831 Drivers: @@ -22,7 +38,7 @@ Plugins: * Plasma: added support for VAD lock \(Velcoity Anti Dive\) to THC up/down mode and tentative support for puddle jumping. Puddle jump parameters can only be set via LinuxCNC style material data. -Moved THC on delay to delayed task so cutting can start before THC is enabled and fixed non-responsive up/down mode when the undelying step injection code is run via polling. +Moved THC on delay to delayed task so cutting can start before THC is enabled and fixed non-responsive up/down mode when the underlying step injection code is run via polling. Ref. issue [#24](https://github.com/grblHAL/Plugin_plasma/issues/24). --- @@ -33,7 +49,7 @@ Core: * Fix for laser enable not restored after feedhold. Ref. issue [#798](https://github.com/grblHAL/core/issues/798). -* Fix for incorrect direction of motion via second stepper driver used for step injection /(plasma THC/) and stepper spindle. +* Fix for incorrect direction of motion via second stepper driver used for step injection \(plasma THC\) and stepper spindle. Plugins: diff --git a/core_handlers.h b/core_handlers.h index f1255a9..8ddbf56 100644 --- a/core_handlers.h +++ b/core_handlers.h @@ -47,7 +47,7 @@ typedef enum { /* TODO: add to grbl pointers so that a different formatting (xml, json etc) of reports may be implemented by a plugin? typedef struct { void (*report_echo_line_received)(char *line); - void (*report_realtime_status)(void); + void (*report_realtime_status)(stream_write_ptr stream_write); void (*report_probe_parameters)(void); void (*report_ngc_parameters)(void); void (*report_gcode_modes)(void); diff --git a/grbl.h b/grbl.h index b5841aa..a05c2c0 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 2020829 +#define GRBL_BUILD 20250902 #define GRBL_URL "https://github.com/grblHAL" @@ -213,7 +213,9 @@ // frequencies below 10kHz, where the aliasing between axes of multi-axis motions can cause audible // noise and shake your machine. At even lower step frequencies, AMASS adapts and provides even better // step smoothing. See stepper.c for more details on the AMASS system works. -#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +#ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING 1 // Default enabled. Set to 0 to disable. +#endif // Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level // frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin @@ -224,7 +226,7 @@ // NOTE: AMASS cutoff frequency multiplied by ISR overdrive factor must not exceed maximum step frequency. // NOTE: Current settings are set to overdrive the ISR to no more than 16kHz, balancing CPU overhead // and timer accuracy. Do not alter these settings unless you know what you are doing. -#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING #ifndef MAX_AMASS_LEVEL #define MAX_AMASS_LEVEL 3 #endif diff --git a/grbllib.c b/grbllib.c index 9d7d30b..5d2bf9d 100644 --- a/grbllib.c +++ b/grbllib.c @@ -319,7 +319,7 @@ int grbl_enter (void) // check and configure driver -#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING driver.amass = hal.driver_cap.amass_level >= MAX_AMASS_LEVEL; hal.driver_cap.amass_level = MAX_AMASS_LEVEL; #else diff --git a/machine_limits.c b/machine_limits.c index 6770911..d23b8a0 100644 --- a/machine_limits.c +++ b/machine_limits.c @@ -438,7 +438,7 @@ static bool homing_cycle (axes_signals_t cycle, axes_signals_t auto_square) if(rt_exec == EXEC_STATUS_REPORT) { system_clear_exec_state_flag(EXEC_STATUS_REPORT); - report_realtime_status(); + report_realtime_status(hal.stream.write_all); } else { // Homing failure condition: Reset issued during cycle. diff --git a/protocol.c b/protocol.c index 91830e8..9339458 100644 --- a/protocol.c +++ b/protocol.c @@ -504,7 +504,7 @@ bool protocol_exec_rt_system (void) if(bit_istrue(sys.rt_exec_state, EXEC_STATUS_REPORT)) { system_clear_exec_state_flag(EXEC_STATUS_REPORT); - report_realtime_status(); + report_realtime_status(hal.stream.write_all); } protocol_poll_cmd(); @@ -604,7 +604,7 @@ bool protocol_exec_rt_system (void) // Execute and print status to output stream if (rt_exec & EXEC_STATUS_REPORT) - report_realtime_status(); + report_realtime_status(hal.stream.write_all); if(rt_exec & EXEC_GCODE_REPORT) report_gcode_modes(); diff --git a/report.c b/report.c index c9a19c5..6974887 100644 --- a/report.c +++ b/report.c @@ -1147,9 +1147,9 @@ static bool report_spindle_num (spindle_info_t *spindle, void *data) // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram // and the actual location of the CNC machine. Users may change the following function to their // specific needs, but the desired real-time data report must be as short as possible. This is - // requires as it minimizes the computational overhead and allows grbl to keep running smoothly, + // requires as it minimizes the computational overhead and allows grblHAL to keep running smoothly, // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz). -void report_realtime_status (void) +void report_realtime_status (stream_write_ptr stream_write) { static bool probing = false; @@ -1167,62 +1167,62 @@ void report_realtime_status (void) probe_state = hal.probe.get_state(); // Report current machine state and sub-states - hal.stream.write_all("<"); + stream_write("<"); sys_state_t state = state_get(); switch (gc_state.tool_change && state == STATE_CYCLE ? STATE_TOOL_CHANGE : state) { case STATE_IDLE: - hal.stream.write_all("Idle"); + stream_write("Idle"); break; case STATE_CYCLE: - hal.stream.write_all("Run"); + stream_write("Run"); if(sys.probing_state == Probing_Active && settings.status_report.run_substate) probing = true; else if (probing) probing = probe_state.triggered; if(sys.flags.feed_hold_pending) - hal.stream.write_all(":1"); + stream_write(":1"); else if(probing) - hal.stream.write_all(":2"); + stream_write(":2"); break; case STATE_HOLD: - hal.stream.write_all(appendbuf(2, "Hold:", uitoa((uint32_t)(sys.holding_state - 1)))); + stream_write(appendbuf(2, "Hold:", uitoa((uint32_t)(sys.holding_state - 1)))); break; case STATE_JOG: - hal.stream.write_all("Jog"); + stream_write("Jog"); break; case STATE_HOMING: - hal.stream.write_all("Home"); + stream_write("Home"); break; case STATE_ESTOP: case STATE_ALARM: if((report.all || settings.status_report.alarm_substate) && sys.alarm) - hal.stream.write_all(appendbuf(2, "Alarm:", uitoa((uint32_t)sys.alarm))); + stream_write(appendbuf(2, "Alarm:", uitoa((uint32_t)sys.alarm))); else - hal.stream.write_all("Alarm"); + stream_write("Alarm"); break; case STATE_CHECK_MODE: - hal.stream.write_all("Check"); + stream_write("Check"); break; case STATE_SAFETY_DOOR: - hal.stream.write_all(appendbuf(2, "Door:", uitoa((uint32_t)sys.parking_state))); + stream_write(appendbuf(2, "Door:", uitoa((uint32_t)sys.parking_state))); break; case STATE_SLEEP: - hal.stream.write_all("Sleep"); + stream_write("Sleep"); break; case STATE_TOOL_CHANGE: - hal.stream.write_all("Tool"); + stream_write("Tool"); break; } @@ -1235,23 +1235,23 @@ void report_realtime_status (void) } // Report position - hal.stream.write_all(settings.status_report.machine_position ? "|MPos:" : "|WPos:"); - hal.stream.write_all(get_axis_values(print_position)); + stream_write(settings.status_report.machine_position ? "|MPos:" : "|WPos:"); + stream_write(get_axis_values(print_position)); // Returns planner and output stream buffer states. if (settings.status_report.buffer_state) { - hal.stream.write_all("|Bf:"); - hal.stream.write_all(uitoa((uint32_t)plan_get_block_buffer_available())); - hal.stream.write_all(","); - hal.stream.write_all(uitoa(hal.stream.get_rx_buffer_free())); + stream_write("|Bf:"); + stream_write(uitoa((uint32_t)plan_get_block_buffer_available())); + stream_write(","); + stream_write(uitoa(hal.stream.get_rx_buffer_free())); } if(settings.status_report.line_numbers) { // Report current line number plan_block_t *cur_block = plan_get_current_block(); if (cur_block != NULL && cur_block->line_number > 0) - hal.stream.write_all(appendbuf(2, "|Ln:", uitoa((uint32_t)cur_block->line_number))); + stream_write(appendbuf(2, "|Ln:", uitoa((uint32_t)cur_block->line_number))); } spindle_ptrs_t *spindle_0; @@ -1263,12 +1263,12 @@ void report_realtime_status (void) // Report realtime feed speed if(settings.status_report.feed_speed) { if(spindle_0->cap.variable) { - hal.stream.write_all(appendbuf(2, "|FS:", get_rate_value(st_get_realtime_rate()))); - hal.stream.write_all(appendbuf(2, ",", uitoa(spindle_0_state.on ? lroundf(spindle_0->param->rpm_overridden) : 0))); + stream_write(appendbuf(2, "|FS:", get_rate_value(st_get_realtime_rate()))); + stream_write(appendbuf(2, ",", uitoa(spindle_0_state.on ? lroundf(spindle_0->param->rpm_overridden) : 0))); if(spindle_0->get_data /* && sys.mpg_mode */) - hal.stream.write_all(appendbuf(2, ",", uitoa(lroundf(spindle_0->get_data(SpindleData_RPM)->rpm)))); + stream_write(appendbuf(2, ",", uitoa(lroundf(spindle_0->get_data(SpindleData_RPM)->rpm)))); } else - hal.stream.write_all(appendbuf(2, "|F:", get_rate_value(st_get_realtime_rate()))); + stream_write(appendbuf(2, "|F:", get_rate_value(st_get_realtime_rate()))); } #if N_SYS_SPINDLE > 1 @@ -1280,10 +1280,10 @@ void report_realtime_status (void) if((spindle_n = spindle_get(idx))) { spindle_n_state = spindle_n->get_state(spindle_n); - hal.stream.write_all(appendbuf(3, "|SP", uitoa(idx), ":")); - hal.stream.write_all(appendbuf(3, uitoa(spindle_n_state.on ? lroundf(spindle_n->param->rpm_overridden) : 0), ",,", spindle_n_state.on ? (spindle_n_state.ccw ? "C" : "S") : "")); + stream_write(appendbuf(3, "|SP", uitoa(idx), ":")); + stream_write(appendbuf(3, uitoa(spindle_n_state.on ? lroundf(spindle_n->param->rpm_overridden) : 0), ",,", spindle_n_state.on ? (spindle_n_state.ccw ? "C" : "S") : "")); if(settings.status_report.overrides) - hal.stream.write_all(appendbuf(2, ",", uitoa(spindle_n->param->override_pct))); + stream_write(appendbuf(2, ",", uitoa(spindle_n->param->override_pct))); } } @@ -1328,7 +1328,7 @@ void report_realtime_status (void) append = control_signals_tostring(append, ctrl_pin_state); *append = '\0'; - hal.stream.write_all(buf); + stream_write(buf); } } @@ -1382,19 +1382,19 @@ void report_realtime_status (void) for(idx = 0; idx < N_AXIS; idx++) wco[idx] = gc_get_offset(idx, true); } - hal.stream.write_all("|WCO:"); - hal.stream.write_all(get_axis_values(wco)); + stream_write("|WCO:"); + stream_write(get_axis_values(wco)); } if(report.gwco) { - hal.stream.write_all("|WCS:"); - hal.stream.write_all(gc_coord_system_to_str(gc_state.modal.coord_system.id)); + stream_write("|WCS:"); + stream_write(gc_coord_system_to_str(gc_state.modal.coord_system.id)); } if(report.overrides) { - hal.stream.write_all(appendbuf(2, "|Ov:", uitoa((uint32_t)sys.override.feed_rate))); - hal.stream.write_all(appendbuf(2, ",", uitoa((uint32_t)sys.override.rapid_rate))); - hal.stream.write_all(appendbuf(2, ",", uitoa((uint32_t)spindle_0->param->override_pct))); + stream_write(appendbuf(2, "|Ov:", uitoa((uint32_t)sys.override.feed_rate))); + stream_write(appendbuf(2, ",", uitoa((uint32_t)sys.override.rapid_rate))); + stream_write(appendbuf(2, ",", uitoa((uint32_t)spindle_0->param->override_pct))); } if(report.spindle || report.coolant || report.tool || gc_state.tool_change) { @@ -1424,61 +1424,61 @@ void report_realtime_status (void) *append++ = 'T'; *append = '\0'; - hal.stream.write_all(buf); + stream_write(buf); } if(report.scaling) { axis_signals_tostring(buf, gc_get_g51_state()); - hal.stream.write_all("|Sc:"); - hal.stream.write_all(buf); + stream_write("|Sc:"); + stream_write(buf); } #if COMPATIBILITY_LEVEL <= 1 if((report.all || report.mpg_mode) && settings.report_interval) { - hal.stream.write_all(sys.flags.auto_reporting ? "|AR:" : "|AR"); + stream_write(sys.flags.auto_reporting ? "|AR:" : "|AR"); if(sys.flags.auto_reporting) - hal.stream.write_all(uitoa(settings.report_interval)); + stream_write(uitoa(settings.report_interval)); } #endif if(report.mpg_mode) - hal.stream.write_all(sys.mpg_mode ? "|MPG:1" : "|MPG:0"); + stream_write(sys.mpg_mode ? "|MPG:1" : "|MPG:0"); if(report.homed && (sys.homing.mask || settings.homing.flags.single_axis_commands || settings.homing.flags.manual)) { axes_signals_t homing = {sys.homing.mask ? sys.homing.mask : AXES_BITMASK}; - hal.stream.write_all(appendbuf(2, "|H:", (homing.mask & sys.homed.mask) == homing.mask ? "1" : "0")); + stream_write(appendbuf(2, "|H:", (homing.mask & sys.homed.mask) == homing.mask ? "1" : "0")); if(settings.homing.flags.single_axis_commands) - hal.stream.write_all(appendbuf(2, ",", uitoa(sys.homed.mask))); + stream_write(appendbuf(2, ",", uitoa(sys.homed.mask))); } if(report.xmode && settings.mode == Mode_Lathe) - hal.stream.write_all(gc_state.modal.diameter_mode ? "|D:1" : "|D:0"); + stream_write(gc_state.modal.diameter_mode ? "|D:1" : "|D:0"); if(report.tool) - hal.stream.write_all(appendbuf(2, "|T:", uitoa((uint32_t)gc_state.tool->tool_id))); + stream_write(appendbuf(2, "|T:", uitoa((uint32_t)gc_state.tool->tool_id))); if(report.probe_id) - hal.stream.write_all(appendbuf(2, "|P:", uitoa((uint32_t)probe_state.probe_id))); + stream_write(appendbuf(2, "|P:", uitoa((uint32_t)probe_state.probe_id))); if(report.tlo_reference) - hal.stream.write_all(appendbuf(2, "|TLR:", uitoa(sys.tlo_reference_set.mask != 0))); + stream_write(appendbuf(2, "|TLR:", uitoa(sys.tlo_reference_set.mask != 0))); if(report.m66result && sys.var5399 > -2) { // M66 result if(sys.var5399 >= 0) - hal.stream.write_all(appendbuf(2, "|In:", uitoa(sys.var5399))); + stream_write(appendbuf(2, "|In:", uitoa(sys.var5399))); else - hal.stream.write_all("|In:-1"); + stream_write("|In:-1"); } } if(grbl.on_realtime_report) - grbl.on_realtime_report(hal.stream.write_all, sys.report); + grbl.on_realtime_report(stream_write, sys.report); #if COMPATIBILITY_LEVEL <= 1 if(report.all) { - hal.stream.write_all("|FW:grblHAL"); + stream_write("|FW:grblHAL"); if(sys.blocking_event) - hal.stream.write_all("|$C:1"); + stream_write("|$C:1"); } else #endif @@ -1510,7 +1510,7 @@ void report_realtime_status (void) system_set_exec_state_flag(EXEC_TLO_REPORT); } - hal.stream.write_all(">" ASCII_EOL); + stream_write(">" ASCII_EOL); system_add_rt_report(Report_ClearAll); diff --git a/report.h b/report.h index 820fc33..0fcf18d 100644 --- a/report.h +++ b/report.h @@ -64,7 +64,7 @@ status_code_t report_grbl_setting (setting_id_t id, void *data); void report_echo_line_received (char *line); // Prints realtime status report. -void report_realtime_status (void); +void report_realtime_status (stream_write_ptr stream_write); // Prints recorded probe position. void report_probe_parameters (void); diff --git a/stepper.c b/stepper.c index 56ddc88..b9cd78c 100644 --- a/stepper.c +++ b/stepper.c @@ -69,7 +69,7 @@ DCRAM static segment_t segment_buffer[SEGMENT_BUFFER_SIZE]; // Stepper ISR data struct. Contains the running data for the main stepper ISR. static stepper_t st = {}; -#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING typedef struct { uint32_t level_1; uint32_t level_2; @@ -495,12 +495,12 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void) #endif = st.step_event_count >> 1; - #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING - memcpy(st.steps, st.exec_block->steps, sizeof(st.steps)); + #if !ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING + memcpy(&st.steps, &st.exec_block->steps, sizeof(st.steps)); #endif } -#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // With AMASS enabled, adjust Bresenham axis increment counters according to AMASS level. st.amass_level = st.exec_segment->amass_level; @@ -572,6 +572,7 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void) sys.position[Y_AXIS] = sys.position[Y_AXIS] + (st.dir_out.y ? -1 : 1); } + if(st.steps.value[Z_AXIS]) { st.counter.z += st.steps.value[Z_AXIS]; if (st.counter.z > st.step_event_count) { step_out.z = On; @@ -581,6 +582,7 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void) #endif sys.position[Z_AXIS] = sys.position[Z_AXIS] + (st.dir_out.z ? -1 : 1); } + } #ifdef A_AXIS st.counter.a += st.steps.value[A_AXIS]; @@ -695,13 +697,13 @@ void st_reset (void) memset(&prep, 0, sizeof(st_prep_t)); memset(&st, 0, sizeof(stepper_t)); -#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // TODO: move to driver? // AMASS_LEVEL0: Normal operation. No AMASS. No upper cutoff frequency. Starts at LEVEL1 cutoff frequency. // Defined as step timer frequency / Cutoff frequency in Hz amass.level_1 = hal.f_step_timer / 8000; - amass.level_2 = hal.f_step_timer / 4000; - amass.level_3 = hal.f_step_timer / 2000; + amass.level_2 = amass.level_1 << 1; + amass.level_3 = amass.level_2 << 1; #endif cycles_per_min = (float)hal.f_step_timer * 60.0f; @@ -829,13 +831,7 @@ void st_prep_buffer (void) st_prep_block = st_prep_block->next; uint_fast8_t idx = N_AXIS; - #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING - do { - idx--; - st_prep_block->steps[idx] = (pl_block->steps[idx] << 1); - } while(idx); - st_prep_block->step_event_count = (pl_block->step_event_count << 1); - #else +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // With AMASS enabled, simply bit-shift multiply all Bresenham data by the max AMASS // level, such that we never divide beyond the original data anywhere in the algorithm. // If the original data is divided, we can lose a step from integer roundoff. @@ -844,7 +840,13 @@ void st_prep_buffer (void) st_prep_block->steps.value[idx] = pl_block->steps.value[idx] << MAX_AMASS_LEVEL; } while(idx); st_prep_block->step_event_count = pl_block->step_event_count << MAX_AMASS_LEVEL; - #endif +#else + do { + idx--; + st_prep_block->steps.value[idx] = pl_block->steps.value[idx] << 1; + } while(idx); + st_prep_block->step_event_count = pl_block->step_event_count << 1; +#endif st_prep_block->direction = pl_block->direction; st_prep_block->programmed_rate = pl_block->programmed_rate; @@ -1224,7 +1226,7 @@ void st_prep_buffer (void) prep_segment->target_position = prep.target_position; //st_prep_block->millimeters - pl_block->millimeters; } - #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING +#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Compute step timing and multi-axis smoothing level. // NOTE: AMASS overdrives the timer with each level, so only one prescalar is required. if (cycles < amass.level_1) @@ -1234,7 +1236,7 @@ void st_prep_buffer (void) cycles >>= prep_segment->amass_level; prep_segment->n_step <<= prep_segment->amass_level; } - #endif +#endif prep_segment->cycles_per_tick = cycles; prep_segment->current_rate = prep.current_speed; diff --git a/stream.c b/stream.c index 2e8c145..5d6da7f 100644 --- a/stream.c +++ b/stream.c @@ -138,6 +138,11 @@ ISR_CODE static bool ISR_FUNC(await_toolchange_ack)(char c) return true; } +stream_suspend_state_t stream_is_rx_suspended (void) +{ + return stream.rxbuffer ? (stream.rxbuffer->backup ? StreamSuspend_Active : StreamSuspend_Pending) : StreamSuspend_Off; +} + bool stream_rx_suspend (stream_rx_buffer_t *rxbuffer, bool suspend) { if(suspend) { diff --git a/stream.h b/stream.h index df27cb5..aa2d67f 100644 --- a/stream.h +++ b/stream.h @@ -91,6 +91,12 @@ typedef enum { StreamType_Null } stream_type_t; +typedef enum { + StreamSuspend_Off = 0, + StreamSuspend_Pending, + StreamSuspend_Active +} stream_suspend_state_t; + typedef enum { Serial_8bit = 0, Serial_7bit @@ -367,7 +373,9 @@ int16_t stream_get_null (void); \param suspend when true _hal.stream.read_ is changed to stream_get_null(), if false it is restored if already saved. \returns true if there is data in the buffer, false otherwise. */ -bool stream_rx_suspend (stream_rx_buffer_t *rxbuffer, bool suspend); + bool stream_rx_suspend (stream_rx_buffer_t *rxbuffer, bool suspend); + + stream_suspend_state_t stream_is_rx_suspended (void); bool stream_mpg_register (const io_stream_t *stream, bool rx_only, stream_write_char_ptr write_char);