diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp old mode 100755 new mode 100644 index ec7a3cb8..01152b35 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1248,7 +1248,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm.gm); // send the move to the planner cm_finalize_move(); - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { cm_cycle_end(); return (STAT_OK); } @@ -1277,7 +1277,7 @@ stat_t _goto_stored_position(float target2[], const float target[], const bool f target2[i] -= target[i]; } } - while (mp_planner_is_full()); // Make sure you have available buffers + while (mp_planner_is_full(ACTIVE_Q)); // Make sure you have available buffers bool flags2[] = { 1,1,1,1,1,1 }; return (cm_straight_traverse(target2, flags2)); // Go to programmed endpoint @@ -1395,7 +1395,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_finalize_move(); // <-- ONLY safe because we don't care about status... - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { cm_cycle_end(); return (STAT_OK); } @@ -1720,7 +1720,7 @@ bool cm_has_hold() void cm_start_hold() { - if (mp_has_runnable_buffer()) { // meaning there's something running + if (mp_has_runnable_buffer(ACTIVE_Q)) { // meaning there's something running cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); diff --git a/g2core/controller.cpp b/g2core/controller.cpp old mode 100755 new mode 100644 index b92b029f..aa4df6e4 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -201,7 +201,7 @@ static stat_t _dispatch_command() { if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_BOTH; - if ((!mp_planner_is_full()) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { + if ((!mp_planner_is_full(ACTIVE_Q)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { _dispatch_kernel(); } } @@ -350,7 +350,7 @@ static stat_t _sync_to_tx_buffer() static stat_t _sync_to_planner() { - if (mp_planner_is_full()) { // allow up to N planner buffers for this line + if (mp_planner_is_full(ACTIVE_Q)) { // allow up to N planner buffers for this line return (STAT_EAGAIN); } return (STAT_OK); diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp old mode 100755 new mode 100644 index fa2c3e2b..43d8ddd2 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -130,7 +130,7 @@ stat_t cm_jogging_cycle_callback(void) { return (STAT_EAGAIN); // sync to planner move ends } // if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) { - if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full()) { + if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(ACTIVE_Q)) { return (STAT_EAGAIN); // prevent flooding the queue with jog moves } return (jog.func(jog.axis)); // execute the current jogging move @@ -142,7 +142,7 @@ static stat_t _set_jogging_func(stat_t (*func)(int8_t axis)) { } static stat_t _jogging_axis_start(int8_t axis) { - // cm_end_hold(); // ends hold if one is in effect +// cm_end_hold(); // ends hold if one is in effect return (_set_jogging_func(_jogging_axis_ramp_jog)); } diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 052a6871..8698c231 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -78,7 +78,7 @@ stat_t cm_arc_callback() if (arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } - if (mp_planner_is_full()) { + if (mp_planner_is_full(ACTIVE_Q)) { return (STAT_EAGAIN); } arc.theta += arc.segment_theta; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 6882ad9f..8ea3fef7 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -419,8 +419,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm.hold_state == FEEDHOLD_DECEL_END) { - mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr.target, mr.position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point @@ -431,7 +431,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) mp_free_run_buffer(); } - mp_replan_queue(mb.r); // make it replan all the blocks + mp_replan_queue(mp_get_r(ACTIVE_Q)); // make it replan all the blocks +// mp_replan_queue(mb.r); // make it replan all the blocks return (STAT_OK); } @@ -560,7 +561,7 @@ stat_t mp_plan_feedhold_move() void mp_exit_hold_state() { cm.hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer()) { + if (mp_has_runnable_buffer(ACTIVE_Q)) { cm_set_motion_state(MOTION_RUN); sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 8a5c5031..27637acd 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -112,7 +112,9 @@ bool mp_get_runtime_busy() if (cm.cycle_state == CYCLE_OFF) { return (false); } - if ((st_runtime_isbusy() == true) || (mr.block_state == BLOCK_ACTIVE) || (mb.r->buffer_state > MP_BUFFER_EMPTY)) { + if ((st_runtime_isbusy() == true) || + (mr.block_state == BLOCK_ACTIVE) || + (mp_get_r(ACTIVE_Q)->buffer_state > MP_BUFFER_EMPTY)) { return (true); } return (false); diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 662d3fd8..7ef79bb4 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,8 +65,9 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -mpBufferPool_t mb; // buffer pool management -mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for pool #1 buffers +mpBufferQueue_t mb; // buffer pool management +mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mb_pool1[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers mpMotionPlannerSingleton_t mp; // context for block planning mpMotionRuntimeSingleton_t mr; // context for block runtime @@ -168,11 +169,13 @@ void planner_init_assertions() stat_t planner_test_assertions() { +/* +++++ Fix this if ((BAD_MAGIC(mb.magic_start)) || (BAD_MAGIC(mb.magic_end)) || (BAD_MAGIC(mp.magic_start)) || (BAD_MAGIC(mp.magic_end)) || (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } +*/ return (STAT_OK); } @@ -433,22 +436,27 @@ stat_t mp_exec_out_of_band_dwell(void) * mp_has_runnable_buffer() - true if next buffer is runnable, indicating motion has not stopped. * mp_is_it_phat_city_time() - test if there is time for non-essential processes */ -uint8_t mp_get_planner_buffers() +uint8_t mp_get_planner_buffers(int8_t q) // which queue are you interested in? { - return (mb.buffers_available); + if (q == ACTIVE_Q) { q = mb.active_q; }; + return (mb.q[q].buffers_available); } -bool mp_planner_is_full() +bool mp_planner_is_full(int8_t q) // which queue are you interested in? { - // We also need to ensure we have room for another JSON command - return ((mb.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); + if (q == ACTIVE_Q) { q = mb.active_q; }; + return ((mb.q[q].buffers_available < PLANNER_BUFFER_HEADROOM) + || (jc.available == 0)); // We also need to ensure we have room for another JSON command } -bool mp_has_runnable_buffer() +bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) { - return (mb.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true + if (q == ACTIVE_Q) { q = mb.active_q; }; + return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } + + bool mp_is_phat_city_time() { if(cm.hold_state == FEEDHOLD_HOLD) { @@ -494,7 +502,8 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state - if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state +//+++ if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state + if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state (cm.motion_state == MOTION_STOP) && (cm.hold_state == FEEDHOLD_OFF)) { mp.planner_state = PLANNER_IDLE; @@ -512,11 +521,12 @@ stat_t mp_planner_callback() // Process a planner request or timeout if (mp.planner_state == PLANNER_IDLE) { - mp.p = mb.r; // initialize planner pointer to run buffer +//++++ mp.p = mb.r; // initialize planner pointer to run buffer + mp.p = mp_get_r(ACTIVE_Q); // initialize planner pointer to run buffer mp.planner_state = PLANNER_STARTUP; } if (mp.planner_state == PLANNER_STARTUP) { - if (!mp_planner_is_full() && !_timed_out) { + if (!mp_planner_is_full(ACTIVE_Q) && !_timed_out) { return (STAT_OK); // remain in STARTUP } mp.planner_state = PLANNER_PRIMING; @@ -534,15 +544,13 @@ stat_t mp_planner_callback() void mp_replan_queue(mpBuf_t *bf) { do { - if (bf->buffer_state >= MP_BUFFER_PLANNED) { - // revert from PLANNED state + if (bf->buffer_state >= MP_BUFFER_PLANNED) { // revert from PLANNED state bf->buffer_state = MP_BUFFER_PREPPED; - } else { - // If it's not "planned" then it's either PREPPED or earlier. - // We don't need to adjust it. - break; + } else { // If it's not "planned" then it's either PREPPED or earlier. + break; // We don't need to adjust it. } - } while ((bf = mp_get_next_buffer(bf)) != mb.r); + } while ((bf = mp_get_next_buffer(bf)) != mp_get_r(ACTIVE_Q)); +//+++ } while ((bf = mp_get_next_buffer(bf)) != mb.r); mp.request_planning = true; } @@ -599,14 +607,16 @@ void mp_end_feed_override(const float ramp_time) void mp_planner_time_accounting() { - mpBuf_t *bf = mb.r; // start with run buffer +//+++ mpBuf_t *bf = mb.r; // start with run buffer + mpBuf_t *bf = mp_get_r(ACTIVE_Q); // start with run buffer // check the run buffer to see if anything is running. Might not be if (bf->buffer_state != MP_BUFFER_RUNNING) { // this is not an error condition return; } mp.plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ - while ((bf = bf->nx) != mb.r) { +//+++ while ((bf = bf->nx) != mb.r) { + while ((bf = bf->nx) != mp_get_r(ACTIVE_Q)) { if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) { break; } @@ -701,53 +711,71 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->clear(); } -void _init_buffer_pool(mpBuf_t *base, uint8_t size) +void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; + + memset(&mb.q[q], 0, sizeof(mpQueue_t)); // clear values, pointers and status + mb.q[q].magic_start = MAGICNUM; + mb.q[q].magic_end = MAGICNUM; - memset(base, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool - mb.bf = base; // link the buffer pool first - mb.w = mb.bf; // init all buffer pointers - mb.r = mb.bf; - mb.queue_size = size-1; - mb.buffers_available = size; + memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool + mb.q[q].bf = pool; // link the buffer pool first + mb.q[q].w = pool; // init all buffer pointers + mb.q[q].r = pool; + mb.q[q].queue_size = size-1; + mb.q[q].buffers_available = size; - pv = &mb.bf[size-1]; + pv = &mb.q[q].bf[size-1]; for (i=0; i < size-1; i++) { - mb.bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) + mb.q[q].bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) nx_i = ((ipv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } -*/ + */ + +mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); } +mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); } mpBuf_t * mp_get_write_buffer() // get & clear a buffer { + mpBuf_t *w = mb.q[mb.active_q].w; + mpQueue_t *q = &mb.q[mb.active_q]; + + if (q->w->buffer_state == MP_BUFFER_EMPTY) { + _clear_buffer(w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer + w->buffer_state = MP_BUFFER_INITIALIZING; + mb.q[mb.active_q].buffers_available--; + + return (mp_get_w(ACTIVE_Q)); + } + // The no buffer condition always causes a panic - invoked by the caller + rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); + return (NULL); +/* if (mb.w->buffer_state == MP_BUFFER_EMPTY) { _clear_buffer(mb.w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer mb.w->buffer_state = MP_BUFFER_INITIALIZING; @@ -758,14 +786,23 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer // The no buffer condition always causes a panic - invoked by the caller rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); return (NULL); +*/ } void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count { + mpBuf_t *w = mb.q[mb.active_q].w; + + if (w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer + w->buffer_state = MP_BUFFER_EMPTY; + mb.q[mb.active_q].buffers_available++; + } +/* if (mb.w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer mb.w->buffer_state = MP_BUFFER_EMPTY; mb.buffers_available++; } +*/ } /*** WARNING *** @@ -775,6 +812,28 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff void mp_commit_write_buffer(const blockType block_type) { + mpBuf_t *w = mb.q[mb.active_q].w; + + w->block_type = block_type; + w->block_state = BLOCK_INITIAL_ACTION; + + if (block_type == BLOCK_TYPE_ALINE) { + if (cm.motion_state == MOTION_STOP) { + cm_set_motion_state(MOTION_PLANNING); + } + } else { + if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { + // NB: BEWARE! the exec may result in the planner buffer being + // processed IMMEDIATELY and then freed - invalidating the contents + st_request_plan_move(); // request an exec if the runtime is not busy + } + } + w->plannable = true; // enable block for planning + mp.request_planning = true; + mb.q[mb.active_q].w = w->nx; // advance write buffer pointer + mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer + qr_request_queue_report(+1); // request QR and add to "added buffers" count +/* mb.w->block_type = block_type; mb.w->block_state = BLOCK_INITIAL_ACTION; @@ -782,7 +841,7 @@ void mp_commit_write_buffer(const blockType block_type) if (cm.motion_state == MOTION_STOP) { cm_set_motion_state(MOTION_PLANNING); } - } else { + } else { if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents @@ -794,11 +853,25 @@ void mp_commit_write_buffer(const blockType block_type) mb.w = mb.w->nx; // advance write buffer pointer mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count + +*/ } // Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt mpBuf_t * mp_get_run_buffer() { + mpBuf_t *r = mb.q[mb.active_q].r; + + // EMPTY is the one case where nothing is returned. This is not an error + if (r->buffer_state == MP_BUFFER_EMPTY) { + return (NULL); + } + // Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out: + // (1) is the the first time the run buffer has been retrieved? + // (2) is the buffer in error - i.e. not yet ready for running? + return (r); +} +/* // EMPTY is the one case where nothing is returned. This is not an error if (mb.r->buffer_state == MP_BUFFER_EMPTY) { return (NULL); @@ -808,12 +881,23 @@ mpBuf_t * mp_get_run_buffer() // (2) is the buffer in error - i.e. not yet ready for running? return (mb.r); } - +*/ // Note: mp_free_run_buffer() is only called from mp_exec_XXX, which are within an interrupt bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { - _audit_buffers(); // diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + mpBuf_t *r = mb.q[mb.active_q].r; +// _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + + mb.q[mb.active_q].r = r->nx; // advance to next run buffer + _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) + + mb.q[mb.active_q].buffers_available++; + qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count + return (mb.q[mb.active_q].w == mb.q[mb.active_q].r); // return true if the queue emptied + +/* + return (mb.w == mb.r); // return true if the queue emptied mpBuf_t *r = mb.r; mb.r = mb.r->nx; // advance to next run buffer _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) @@ -821,6 +905,7 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the mb.buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (mb.w == mb.r); // return true if the queue emptied +*/ } /* UNUSED FUNCTIONS - left in for completeness and for reference diff --git a/g2core/planner.h b/g2core/planner.h index f817480c..40035985 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -124,8 +124,8 @@ typedef enum { /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 -#define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)4) // Secondary planner queue for feedhold operations +#define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million #define JUNCTION_INTEGRATION_MIN (0.05) // minimum allowable setting @@ -172,6 +172,11 @@ typedef enum { //#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } #define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; } +// Define which queue you are interested in for input args +#define PRIMARY_Q 0 +#define SECONDARY_Q 1 +#define ACTIVE_Q -1 + /* * Planner structures */ @@ -243,17 +248,20 @@ typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging } mpBuf_t; -typedef struct mpBufferPool { // one or more planner buffer queues +typedef struct mpQueue { // a planner buffer queue magic_t magic_start; // magic number to test memory integrity - mpBuf_t *r; // run buffer pointer mpBuf_t *w; // write buffer pointer uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48) - uint8_t buffers_available; // running count of available buffers + uint8_t buffers_available; // running count of available buffers in queue mpBuf_t *bf; // pointer to buffer storage array - magic_t magic_end; -} mpBufferPool_t; +} mpQueue_t; + +typedef struct mpBufferQueue { // one or more planner buffer queues + uint8_t active_q; // index of currently active queue + mpQueue_t q[2]; // number of queues +} mpBufferQueue_t; typedef struct mpMotionPlannerSingleton { // common variables for planning (move master) magic_t magic_start; // magic number to test memory integrity @@ -350,7 +358,7 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables } mpMotionRuntimeSingleton_t; // Reference global scope structures -extern mpBufferPool_t mb; // buffer pool management +extern mpBufferQueue_t mb; // planner buffer queue management extern mpMotionPlannerSingleton_t mp; // context for block planning extern mpMotionRuntimeSingleton_t mr; // context for block runtime @@ -383,9 +391,9 @@ void mp_request_out_of_band_dwell(float seconds); stat_t mp_exec_out_of_band_dwell(void); // planner functions and helpers -uint8_t mp_get_planner_buffers(void); -bool mp_planner_is_full(void); -bool mp_has_runnable_buffer(void); +uint8_t mp_get_planner_buffers(int8_t q); +bool mp_planner_is_full(int8_t q); +bool mp_has_runnable_buffer(int8_t q); bool mp_is_phat_city_time(void); stat_t mp_planner_callback(); @@ -396,6 +404,8 @@ void mp_planner_time_accounting(void); // planner buffer primitives void mp_init_buffers(void); +mpBuf_t * mp_get_w(int8_t q); +mpBuf_t * mp_get_r(int8_t q); //mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf); // Use the following macro instead //mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf); // Use the following macro instead diff --git a/g2core/report.cpp b/g2core/report.cpp index e7fca4eb..7b42cb59 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -491,7 +491,7 @@ void qr_init_queue_report() void qr_request_queue_report(int8_t buffers) { // get buffer depth and added/removed count - qr.buffers_available = mp_get_planner_buffers(); + qr.buffers_available = mp_get_planner_buffers(ACTIVE_Q); if (buffers > 0) { qr.buffers_added += buffers; } else { @@ -574,7 +574,7 @@ stat_t qr_queue_report_callback() // called by controller dispatcher */ stat_t qr_get(nvObj_t *nv) { - nv->value = (float)mp_get_planner_buffers(); // ensure that manually requested QR count is always up to date + nv->value = (float)mp_get_planner_buffers(ACTIVE_Q); // ensure that manually requested QR count is always up to date nv->valuetype = TYPE_INT; return (STAT_OK); }