mirror of
https://github.com/synthetos/g2.git
synced 2026-09-26 09:03:37 +08:00
Work in process
This commit is contained in:
@@ -261,9 +261,9 @@ void cm_set_motion_state(const cmMotionState motion_state)
|
||||
cm->motion_state = motion_state;
|
||||
|
||||
switch (motion_state) {
|
||||
case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; }
|
||||
case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; }
|
||||
case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; }
|
||||
case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; }
|
||||
case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; }
|
||||
case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,11 +285,11 @@ cmProbeState cm_get_probe_state() { return cm->probe_state[0];}
|
||||
/*
|
||||
* cm_get_combined_state() - combines raw states into something a user might want to see
|
||||
*
|
||||
* Note:
|
||||
* On issuing a gcode command we call cm_cycle_start() before the motion gets queued. We don't go
|
||||
* to MOTION_RUN until the command is executed by mp_exec_aline(), planned, queued, and started.
|
||||
* So MOTION_STOP must actually return COMBINED_RUN to address this case, even though under some
|
||||
* circumstances it might actually ne an exception case. Therefore this assertion isn't valid:
|
||||
* NOTE: On issuing a gcode command we call cm_cycle_start() before the motion gets queued.
|
||||
* We don't go to MOTION_RUN until the command is executed by mp_exec_aline(), planned,
|
||||
* queued, and started. So MOTION_STOP must actually return COMBINED_RUN to address this
|
||||
* case, even though under some circumstances it might actually be an exception case.
|
||||
* Therefore this assertion isn't valid:
|
||||
* cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "mots2"));//"mots is stop but machine is in cycle"
|
||||
* return (COMBINED_PANIC);
|
||||
*/
|
||||
@@ -309,7 +309,7 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm)
|
||||
case CYCLE_JOG: { return (COMBINED_JOG); }
|
||||
case CYCLE_MACHINING: case CYCLE_NONE: {
|
||||
switch(_cm->motion_state) {
|
||||
case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above
|
||||
case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE, above
|
||||
case MOTION_RUN: { return (COMBINED_RUN); }
|
||||
case MOTION_HOLD: { return (COMBINED_HOLD); }
|
||||
default: {
|
||||
|
||||
+24
-24
@@ -81,7 +81,7 @@ typedef enum { // check alignment with messages in config.c / m
|
||||
} cmCombinedState;
|
||||
//### END CRITICAL REGION ###
|
||||
|
||||
typedef enum {
|
||||
typedef enum { // Note: MachineState signals if the machine is in cycle (5) or some other non-cycle state
|
||||
MACHINE_INITIALIZING = 0, // machine is initializing
|
||||
MACHINE_READY, // machine is ready for use but idle
|
||||
MACHINE_ALARM, // machine is in alarm state
|
||||
@@ -109,27 +109,27 @@ typedef enum {
|
||||
// ...
|
||||
} cmCycleType;
|
||||
|
||||
typedef enum { // feedhold requests
|
||||
FEEDHOLD_NO_REQUEST = 0, // no pending request; reverts here when complete (read-only; cannot be set)
|
||||
FEEDHOLD_HOLD_P1, // enter p1 feedhold, enter HOLD state in p1
|
||||
FEEDHOLD_HOLD_P2, // (!) enter p1 feedhold, enter p2 with entry actions
|
||||
FEEDHOLD_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion
|
||||
FEEDHOLD_EXIT_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP
|
||||
|
||||
// Feedholds with specialized exits
|
||||
// If not in hold, perform hold (or halt), then perform the exit immediately
|
||||
// If already in hold just perform the exit
|
||||
FEEDHOLD_HOLD_SKIP, // enter p1 feedhold, skip remainder of block, resume from next block (for homing & probes)
|
||||
FEEDHOLD_HOLD_STOP, // enter p1 feedhold, enter PROGRAM_STOP state
|
||||
FEEDHOLD_HOLD_FAST_STOP, // enter p1 feedhold, perform FAST_STOP, enter STOP state
|
||||
FEEDHOLD_HOLD_HALT, // enter p1 feedhold, enter PROGRAM_STOP state
|
||||
FEEDHOLD_HOLD_END, // enter p1 feedhold, flush queue, perform PROGRAM_END
|
||||
FEEDHOLD_HOLD_END_ALARM, // enter p1 feedhold, flush queue, perform PROGRAM_END, trigger ALARM
|
||||
FEEDHOLD_HOLD_ALARM, // enter p1 feedhold, flush queue, trigger ALARM
|
||||
FEEDHOLD_HOLD_SHUTDOWN, // enter p1 feedhold, flush queue, trigger SHUTDOWN
|
||||
FEEDHOLD_HOLD_PANIC, // perform HALT, trigger PANIC
|
||||
FEEDHOLD_HOLD_INTERLOCK // enter p1 feedhold, trigger and release INTERLOCK
|
||||
} cmFeedholdRequest;
|
||||
typedef enum { // cycle start and feedhold requests
|
||||
OPERATION_NULL = 0, // no operation; reverts here when complete
|
||||
OPERATION_CYCLE_START, // perform a cycle start with no other actions
|
||||
OPERATION_HOLD_TO_P2, // feedhold into p2 with p2 entry actions
|
||||
OPERATION_P1_FAST_HOLD, // perform a fast hold in p1
|
||||
OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner
|
||||
OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner
|
||||
OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush
|
||||
OPERATION_JOB_KILL, // fast hold followed by queue flush and program end
|
||||
OPERATION_END_JOG, // fast hold followed by program stop
|
||||
OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit
|
||||
OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit
|
||||
OPERATION_SHUTDOWN, // actions to run when a shutdown is received
|
||||
OPERATION_PANIC, // actions to run when a panic is received
|
||||
OPERATION_INTERLOCK_START, // enter an interlock state
|
||||
OPERATION_INTERLOCK_END, // exit interlocked state
|
||||
OPERATION_DI_FUNC_STOP, // run digital input STOP function
|
||||
OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function
|
||||
OPERATION_DI_FUNC_HALT, // run digital input HALT function
|
||||
OPERATION_TOOL_CHANGE // run a tool change sequence
|
||||
} cmOperationType;
|
||||
|
||||
typedef enum { // feedhold state machine
|
||||
FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit
|
||||
@@ -272,8 +272,6 @@ typedef struct cmMachine { // struct to manage canonical machin
|
||||
cmMotionState motion_state; // momo
|
||||
|
||||
cmFeedholdState hold_state; // hold: feedhold state machine
|
||||
cmFeedholdRequest hold_request; // hold: pending feedhold request
|
||||
cmFeedholdRequest hold_exit; // hold: pending feedhold exit request
|
||||
cmFlushState flush_state; // hold: queue flush state machine
|
||||
bool hold_exit_requested; // request normal exit from feedhold
|
||||
bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill)
|
||||
@@ -469,6 +467,8 @@ stat_t cm_json_wait(char *json_string); // M102
|
||||
void cm_request_feedhold(void);
|
||||
void cm_request_exit_hold(void);
|
||||
void cm_request_queue_flush(void);
|
||||
stat_t cm_request_operation(cmOperationType operation); // request a new operation
|
||||
stat_t cm_operation_callback(void); // operation action runner
|
||||
stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests
|
||||
stat_t cm_feedhold_command_blocker(void);
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ static void _controller_HSM()
|
||||
DISPATCH(qr_queue_report_callback()); // conditionally send queue report
|
||||
|
||||
DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner
|
||||
DISPATCH(cm_operation_callback()); // operation action runner
|
||||
DISPATCH(mp_planner_callback()); // motion planner
|
||||
DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines
|
||||
DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2)
|
||||
|
||||
+211
-26
@@ -47,6 +47,198 @@ static void _feedhold_p1_exit(void);
|
||||
static void _feedhold_p2_exit(void);
|
||||
static void _feedhold_abort(void);
|
||||
|
||||
static stat_t action_hold(float* value, bool* flag);
|
||||
static stat_t action_halt(float* value, bool* flag);
|
||||
static stat_t action_p2_entry(float* value, bool* flag);
|
||||
static stat_t action_p2_exit(float* value, bool* flag);
|
||||
static stat_t action_parking_move(float* value, bool* flag);
|
||||
static stat_t action_return_move(float* value, bool* flag);
|
||||
static stat_t action_spindle_control(float* value, bool* flag);
|
||||
static stat_t action_coolant_control(float* value, bool* flag);
|
||||
static stat_t action_heater_control(float* value, bool* flag);
|
||||
static stat_t action_output_control(float* value, bool* flag);
|
||||
static stat_t action_cycle_start(float* value, bool* flag);
|
||||
static stat_t action_queue_flush(float* value, bool* flag);
|
||||
static stat_t action_input_function(float* value, bool* flag);
|
||||
static stat_t action_finalize_program(float* value, bool* flag);
|
||||
static stat_t action_trigger_alarm(float* value, bool* flag);
|
||||
|
||||
typedef enum { // Operation Actions
|
||||
// Initiation actions
|
||||
ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set)
|
||||
ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1
|
||||
ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used)
|
||||
ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1
|
||||
ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2
|
||||
ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2)
|
||||
|
||||
// Hold Entry Actions - run when motion has stopped
|
||||
ACTION_P2_ENTRY, // Z lift, spindle and coolant actions (bundled)
|
||||
ACTION_PARKING_MOVE, // perform a pre-defined toolhead parking move
|
||||
ACTION_PAUSE_SPINDLE,
|
||||
ACTION_PAUSE_COOLANT,
|
||||
ACTION_PAUSE_HEATERS,
|
||||
ACTION_PAUSE_OUTPUTS, // programmed special purpose outputs
|
||||
ACTION_STOP_SPINDLE,
|
||||
ACTION_STOP_COOLANT,
|
||||
ACTION_STOP_HEATERS,
|
||||
ACTION_STOP_OUTPUTS,
|
||||
|
||||
// In-Hold actions
|
||||
ACTION_TOOL_CHANGE,
|
||||
|
||||
// Feedhold Exit Actions // This set is kept in a separate vector, so the bit shifts start over.
|
||||
ACTION_P2_EXIT, // coolant, spindle, return move actions (bundled)
|
||||
ACTION_RESUME_HEATERS,
|
||||
ACTION_RESUME_COOLANT,
|
||||
ACTION_RESUME_SPINDLE,
|
||||
ACTION_RESUME_OUTPUTS, // programmed special purpose outputs
|
||||
ACTION_RETURN_MOVE, // returns to hold pint an re-enters p1
|
||||
|
||||
// Cycle start, restart, exit hold
|
||||
ACTION_SKIP_TO_SYNC, // discard remaining length, execute next block if SYNC command, otherwise flush buffer
|
||||
ACTION_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion
|
||||
ACTION_QUEUE_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP
|
||||
|
||||
// Finalization actions
|
||||
ACTION_DI_FUNCTION, // function as assigned by digital input configuration (TBD)
|
||||
ACTION_PROGRAM_STOP, // invoke PROGRAM_STOP
|
||||
ACTION_PROGRAM_END, // invoke PROGRAM_END
|
||||
ACTION_TRIGGER_ALARM, // trigger ALARM
|
||||
ACTION_TRIGGER_SHUTDOWN, // trigger SHUTDOWN
|
||||
ACTION_TRIGGER_PANIC, // trigger PANIC state
|
||||
ACTION_PERFORM_RESET, // defined, but not implemented
|
||||
} cmOpAction;
|
||||
|
||||
|
||||
/*** Object Definitions ***/
|
||||
|
||||
#define ACTION_MAX 12
|
||||
typedef stat_t (*action_exec_t)(float[], bool[]); // callback to operation action execution function
|
||||
|
||||
typedef struct cmAction { // struct to manage execution of operations
|
||||
struct cmAction *nx; // static pointer to next buffer
|
||||
|
||||
action_exec_t func; // callback to operation action function. NULL == disabled
|
||||
float value[AXES]; // parameters for the function
|
||||
bool flag[AXES];
|
||||
|
||||
// clears this structure (except the pointer)
|
||||
void reset() {
|
||||
func = NULL;
|
||||
}
|
||||
} cmAction_t;
|
||||
|
||||
typedef struct cmOperation { // struct to manage execution of operations
|
||||
cmAction action[ACTION_MAX]; // singly linked list of action control structures
|
||||
|
||||
cmAction *current_action; // current action being worked
|
||||
|
||||
void add_action(stat_t(*action_exec)(float[], bool[]), float* value, bool* flag) {
|
||||
if (action_exec == NULL) {
|
||||
return;
|
||||
}
|
||||
current_action->func = action_exec;
|
||||
|
||||
for (uint8_t i = 0; i < AXES; i++) {
|
||||
current_action->value[i] = value[i];
|
||||
current_action->flag[i] = flag[i];
|
||||
}
|
||||
};
|
||||
|
||||
stat_t run_action(void) {
|
||||
stat_t status;
|
||||
status = current_action->func(current_action->value, current_action->flag);
|
||||
if (status == STAT_OK) {
|
||||
current_action = current_action->nx;
|
||||
}
|
||||
return (status);
|
||||
};
|
||||
|
||||
void reset(void) {
|
||||
for (uint8_t i=0; i < ACTION_MAX; i++) {
|
||||
action[i].reset();
|
||||
action[i].nx = &action[i+1];
|
||||
}
|
||||
action[ACTION_MAX-1].nx = &action[0];
|
||||
current_action = &action[0];
|
||||
};
|
||||
|
||||
} cmOperation_t;
|
||||
|
||||
cmOperation_t op; // operations runner
|
||||
|
||||
/****************************************************************************************
|
||||
**** Operations ************************************************************************
|
||||
****************************************************************************************/
|
||||
|
||||
/****************************************************************************************
|
||||
* cm_request_operation()
|
||||
* cm_operation_callback()
|
||||
*/
|
||||
|
||||
stat_t cm_request_operation(cmOperationType operation)
|
||||
{
|
||||
op.reset(); // start with a fresh operation controller
|
||||
|
||||
switch (operation) {
|
||||
|
||||
case OP_CYCLE_START: {
|
||||
op.add_action(action_cycle_start, nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
|
||||
}
|
||||
}
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
stat_t cm_operation_callback()
|
||||
{
|
||||
stat_t status = STAT_OK;
|
||||
while ((status = op.run_action()) == STAT_OK);
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* cm_action_functions
|
||||
*
|
||||
* Coding an action:
|
||||
*
|
||||
* Actions can complete in one call or take multiple calls (continuations).
|
||||
* In the latter case they will be called multiple times by the action runner.
|
||||
* The returned status defines this:
|
||||
*
|
||||
* STAT_OK - signals completion of the action. Runner will run the next action
|
||||
* STAT_EAGAIN - signals that the action needs to be called again later to complete
|
||||
* STAT_(anything else) - aborts the operation
|
||||
*/
|
||||
|
||||
static stat_t action_hold(float* value, bool* flag) { return (STAT_OK); } // p1, p2, regular and fast holds
|
||||
static stat_t action_halt(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_p2_entry(float* value, bool* flag) { return (STAT_OK); } // p2 entry actions, bundled
|
||||
static stat_t action_p2_exit(float* value, bool* flag) { return (STAT_OK); } // p2 exit actions, bundled
|
||||
static stat_t action_parking_move(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_return_move(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_spindle_control(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_coolant_control(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_heater_control(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_output_control(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_queue_flush(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_input_function(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_finalize_program(float* value, bool* flag) { return (STAT_OK); }
|
||||
static stat_t action_trigger_alarm(float* value, bool* flag) { return (STAT_OK); }
|
||||
|
||||
static stat_t action_cycle_start(float* value, bool* flag)
|
||||
{
|
||||
cm_set_motion_state(MOTION_RUN);
|
||||
cm_cycle_start();
|
||||
st_request_exec_move();
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
**** Feedholds *************************************************************************
|
||||
@@ -181,10 +373,11 @@ bool cm_has_hold()
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* cm_start_hold() - start a feedhhold external to feedhold request equencing
|
||||
* cm_request_feedhold() - reqeust a feedhold
|
||||
* cm_request_exit_hold() - reqeust feedhold exit with resume motion
|
||||
* cm_request_queue_flush() - request feedhold exit with queue flush
|
||||
* cm_start_hold() - start a feedhhold external to feedhold request equencing
|
||||
* cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner
|
||||
*
|
||||
* p1 is the primary planner, p2 is the secondary planner, which is active if the
|
||||
* primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one.
|
||||
@@ -210,21 +403,10 @@ bool cm_has_hold()
|
||||
* Any executing or pending "in-hold" moves are stopped prior to the exit actions
|
||||
*/
|
||||
|
||||
void cm_start_hold()
|
||||
{
|
||||
// Can only request a feedhold if the machine is in motion and there not one is not already in progress
|
||||
if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) {
|
||||
cm_set_motion_state(MOTION_HOLD);
|
||||
cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution
|
||||
}
|
||||
}
|
||||
|
||||
void cm_request_feedhold(void) // !
|
||||
{
|
||||
// Only generate request if not already in a feedhold and the machine is in motion
|
||||
if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) {
|
||||
cm1.hold_request = FEEDHOLD_HOLD_P2; // request a hold to p2
|
||||
cm1.hold_exit = FEEDHOLD_NO_REQUEST; // no exit specified
|
||||
cm1.hold_state = FEEDHOLD_REQUESTED; // signal request to state machine
|
||||
} else
|
||||
if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) {
|
||||
@@ -235,7 +417,6 @@ void cm_request_feedhold(void) // !
|
||||
void cm_request_exit_hold(void) // ~
|
||||
{
|
||||
if (cm1.hold_state != FEEDHOLD_OFF) {
|
||||
cm1.hold_exit = FEEDHOLD_CYCLE_START; // signal a normal feedhold resume as exit
|
||||
cm1.hold_exit_requested = true;
|
||||
}
|
||||
}
|
||||
@@ -245,11 +426,27 @@ void cm_request_queue_flush() // %
|
||||
// NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now
|
||||
if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold
|
||||
(cm1.flush_state == FLUSH_OFF)) { // ...and only once
|
||||
cm1.hold_exit = FEEDHOLD_EXIT_FLUSH; // signal a flush exit
|
||||
cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped
|
||||
}
|
||||
}
|
||||
|
||||
void cm_start_hold()
|
||||
{
|
||||
// Can only request a feedhold if the machine is in motion and there not one is not already in progress
|
||||
if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) {
|
||||
cm_set_motion_state(MOTION_HOLD);
|
||||
cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution
|
||||
}
|
||||
}
|
||||
|
||||
stat_t cm_feedhold_command_blocker()
|
||||
{
|
||||
if (cm1.hold_state != FEEDHOLD_OFF) {
|
||||
return (STAT_EAGAIN);
|
||||
}
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests
|
||||
*
|
||||
@@ -323,18 +520,6 @@ stat_t cm_feedhold_sequencing_callback()
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner
|
||||
*/
|
||||
|
||||
stat_t cm_feedhold_command_blocker()
|
||||
{
|
||||
if (cm1.hold_state != FEEDHOLD_OFF) {
|
||||
return (STAT_EAGAIN);
|
||||
}
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
* _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold
|
||||
* _sync_to_p1_hold_entry_actions_done() - final state change occurs here
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<com_atmel_avrdbg_tool_atmelice>
|
||||
<ToolOptions>
|
||||
<InterfaceProperties>
|
||||
<SwdClock>10000000</SwdClock>
|
||||
<SwdClock>2000000</SwdClock>
|
||||
</InterfaceProperties>
|
||||
<InterfaceName>SWD</InterfaceName>
|
||||
</ToolOptions>
|
||||
@@ -102,7 +102,7 @@
|
||||
<preserveEEPROM>true</preserveEEPROM>
|
||||
<avrtoolserialnumber>J41800019454</avrtoolserialnumber>
|
||||
<avrdeviceexpectedsignature>0x284E0A60</avrdeviceexpectedsignature>
|
||||
<avrtoolinterfaceclock>10000000</avrtoolinterfaceclock>
|
||||
<avrtoolinterfaceclock>2000000</avrtoolinterfaceclock>
|
||||
<custom>
|
||||
<ToolOptions xmlns="">
|
||||
<InterfaceProperties>
|
||||
|
||||
@@ -407,6 +407,12 @@ stat_t mp_exec_move()
|
||||
|
||||
stat_t mp_exec_aline(mpBuf_t *bf)
|
||||
{
|
||||
// don't run the block if the machine is not in cycle
|
||||
if (cm_get_machine_state() != MACHINE_CYCLE) {
|
||||
return (STAT_NOOP);
|
||||
}
|
||||
|
||||
// don't run the block if the block is inactive
|
||||
if (bf->block_state == BLOCK_INACTIVE) {
|
||||
return (STAT_NOOP);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user