rt_public void failure(void) { /* A fatal Eiffel exception has occurred. The stack of exceptions is dumped * and the memory is cleaned up, if possible. */ GTCX /* When we arrive at this location, the Eiffel call stack is theoratically * empty, but `loc_set' still points to the location where the last Eiffel * call has been made. Since now `loc_set' records address of C local variable * which are usually located on the C call stack. Any addition to the C call * stack (like the call to `trapsig' below) will corrupt the information * stored in `loc_set' since it will replace a location by another. * * To prevent this, we have to manually empty `loc_set'. It does not matter * at this point that the GC forgets about all objects referenced through * a local variable since all Eiffel calls have been executed. * Doing so, enables a safe `reclaim' that will not traverse `loc_set' * objects. * We then create an empty `loc_set' as most of the run-time macros for stack * management expect `loc_set' to have at least one chunk. */ #ifdef ISE_GC st_reset (&loc_set); st_alloc (&loc_set, eif_stack_chunk); #endif trapsig(emergency); /* Weird signals are trapped */ esfail(MTC_NOARG); /* Dump the execution stack trace */ reclaim(); /* Reclaim all the objects */ exit(1); /* Abnormal termination */ /* NOTREACHED */ }
int main(void) { motor_init(); //while(1) // rotazione1(); // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts /*while(true) { serial_write('A'); serial_write('B'); serial_write('C'); }*/ //settings_init(); // Load grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt memset(&sys, 0, sizeof(sys)); // Clear all system variables sys.abort = true; // Set abort to complete initialization //sei(); // Enable interrupts // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Grbl initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. for(;;) { // TODO: Separate configure task that require interrupts to be disabled, especially upon // a system abort and ensuring any active interrupts are cleanly reset. // Reset Grbl primary systems. serial_reset_read_buffer(); // Clear serial read buffer //spindle_init(); //coolant_init(); //limits_init(); //probe_init(); st_reset(); // Clear stepper subsystem variables. // Reset system variables. sys.abort = false; sys.execute = 0; // Start Grbl main loop. Processes program inputs and executes them. protocol_main_loop(); } return 0; /* Never reached */ }
void umcwriter_planner_set_position(double X, double Y, double A) { umcwriter_planner_sync(); double pos[3]; pos[settings.x_axes] = X * settings.x_dir; pos[settings.y_axes] = Y * settings.y_dir; pos[2] = A; plan_set_position(pos); st_reset(); }
void tg_application_reset(void) { cli(); // disable global interrupts st_reset(); // reset stepper subsystem mp_init(); // motion planning subsystem cm_init(); // canonical machine gc_init(); // gcode-parser PMIC_SetVectorLocationToApplication(); // as opposed to boot ROM PMIC_EnableHighLevel(); // all levels are used, so don't bother to abstract them PMIC_EnableMediumLevel(); PMIC_EnableLowLevel(); sei(); // enable global interrupts tg_ready(); // (LAST) announce app is online }
int startGrbl(void) { // Initialize system serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load grbl settings from EEPROM st_init(); // Setup stepper pins and interrupt timers sei(); // Enable interrupts memset(&sys, 0, sizeof(sys)); // Clear all system variables sys.abort = true; // Set abort to complete initialization sys.state = STATE_INIT; // Set alarm state to indicate unknown initial position // Wire.begin(); for(;;) { // Execute system reset upon a system abort, where the main program will return to this loop. // Once here, it is safe to re-initialize the system. At startup, the system will automatically // reset to finish the initialization process. if (sys.abort) { // Reset system. serial_reset_read_buffer(); // Clear serial read buffer plan_init(); // Clear block buffer and planner variables gc_init(); // Set g-code parser to default state protocol_init(); // Clear incoming line data and execute startup lines spindle_init(); coolant_init(); limits_init(); st_reset(); // Clear stepper subsystem variables. syspos(&encdr_x,&encdr_y,&encdr_z); ofst_x=encdr_x; ofst_y=encdr_y; ofst_z=encdr_z; // Sync cleared gcode and planner positions to current system position, which is only // cleared upon startup, not a reset/abort. sys_sync_current_position(); // Reset system variables. sys.abort = false; sys.execute = 0; if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) { sys.auto_start = true; } // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (sys.state == STATE_INIT && bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Check for and report alarm state after a reset, error, or an initial power up. if (sys.state == STATE_ALARM) { report_feedback_message(MESSAGE_ALARM_LOCK); } else { // All systems go. Set system to ready and execute startup script. sys.state = STATE_IDLE; protocol_execute_startup(); } } protocol_execute_runtime(); // syspos(&encdr_x,&encdr_y); protocol_process(); // ... process the serial protocol } return 0; /* never reached */ }
void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, uint8_t is_no_error) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. if (sys.state == STATE_CHECK_MODE) { return; } // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); // Initialize probing control variables sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. probe_configure_invert_mask(is_probe_away); // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); protocol_execute_realtime(); } if (sys.abort) { return; } // Return if system reset has been issued. // Setup and queue probing motion. Auto cycle-start should not start the cycle. #ifdef USE_LINE_NUMBERS mc_line(target, feed_rate, invert_feed_rate, line_number); #else mc_line(target, feed_rate, invert_feed_rate); #endif // Activate the probing state monitor in the stepper module. sys_probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); do { protocol_execute_realtime(); if (sys.abort) { return; } // Check for system abort } while (sys.state != STATE_IDLE); // Probing cycle complete! // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys_probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. protocol_execute_realtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort // Reset the stepper and planner buffers to remove the remainder of the probe motion. st_reset(); // Reest step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. // TODO: Update the g-code parser code to not require this target calculation but uses a gc_sync_position() call. // NOTE: The target[] variable updated here will be sent back and synced with the g-code parser. system_convert_array_steps_to_mpos(target, sys.position); #ifdef MESSAGE_PROBE_COORDINATES // All done! Output the probe position as message. report_probe_parameters(); #endif }
int main(void) { // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load Grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt memset(sys_position,0,sizeof(sys_position)); // Clear machine position. sei(); // Enable interrupts // Initialize system state. #ifdef FORCE_INITIALIZATION_ALARM // Force Grbl into an ALARM state upon a power-cycle or hard reset. sys.state = STATE_ALARM; #else sys.state = STATE_IDLE; #endif // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Grbl initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. for(;;) { // Reset system variables. uint8_t prior_state = sys.state; memset(&sys, 0, sizeof(system_t)); // Clear system struct variable. sys.state = prior_state; sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100% sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100% sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100% memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position. sys_probe_state = 0; sys_rt_exec_state = 0; sys_rt_exec_alarm = 0; sys_rt_exec_motion_override = 0; sys_rt_exec_accessory_override = 0; // Reset Grbl primary systems. serial_reset_read_buffer(); // Clear serial read buffer gc_init(); // Set g-code parser to default state spindle_init(); coolant_init(); limits_init(); probe_init(); plan_reset(); // Clear block buffer and planner variables st_reset(); // Clear stepper subsystem variables. // Sync cleared gcode and planner positions to current system position. plan_sync_position(); gc_sync_position(); // Print welcome message. Indicates an initialization has occured at power-up or with a reset. report_init_message(); // Start Grbl main loop. Processes program inputs and executes them. protocol_main_loop(); } return 0; /* Never reached */ }
// Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags) { // TODO: Need to update this cycle so it obeys a non-auto cycle start. if (sys.state == STATE_CHECK_MODE) { return(GC_PROBE_CHECK_MODE); } // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); if (sys.abort) { return(GC_PROBE_ABORT); } // Return if system reset has been issued. // Initialize probing control variables uint8_t is_probe_away = bit_istrue(parser_flags,GC_PARSER_PROBE_IS_AWAY); uint8_t is_no_error = bit_istrue(parser_flags,GC_PARSER_PROBE_IS_NO_ERROR); sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. probe_configure_invert_mask(is_probe_away); // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_INITIAL); protocol_execute_realtime(); probe_configure_invert_mask(false); // Re-initialize invert mask before returning. return(GC_PROBE_FAIL_INIT); // Nothing else to do but bail. } // Setup and queue probing motion. Auto cycle-start should not start the cycle. mc_line(target, pl_data); // Activate the probing state monitor in the stepper module. sys_probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. system_set_exec_state_flag(EXEC_CYCLE_START); do { protocol_execute_realtime(); if (sys.abort) { return(GC_PROBE_ABORT); } // Check for system abort } while (sys.state != STATE_IDLE); // Probing cycle complete! // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys_probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys_probe_position, sys_position, sizeof(sys_position)); } else { system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_CONTACT); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. probe_configure_invert_mask(false); // Re-initialize invert mask. protocol_execute_realtime(); // Check and execute run-time commands // Reset the stepper and planner buffers to remove the remainder of the probe motion. st_reset(); // Reset step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. #ifdef MESSAGE_PROBE_COORDINATES // All done! Output the probe position as message. report_probe_parameters(); #endif if (sys.probe_succeeded) { return(GC_PROBE_FOUND); } // Successful probe cycle. else { return(GC_PROBE_FAIL_END); } // Failed to trigger probe within travel. With or without error. }
int main(void) { // Initialize system serial_init(BAUD_RATE); // Setup serial baud rate and interrupts st_init(); // Setup stepper pins and interrupt timers sei(); // Enable interrupts memset(&sys, 0, sizeof(sys)); // Clear all system variables sys.abort = true; // Set abort to complete initialization for(;;) { // Execute system reset upon a system abort, where the main program will return to this loop. // Once here, it is safe to re-initialize the system. At startup, the system will automatically // reset to finish the initialization process. if (sys.abort) { // Retain last known machine position and work coordinate offset(s). If the system abort // occurred while in motion, machine position is not guaranteed, since a hard stop can cause // the steppers to lose steps. Always perform a feedhold before an abort, if maintaining // accurate machine position is required. // TODO: Report last position and coordinate offset to users to help relocate origins. Future // releases will auto-reset the machine position back to [0,0,0] if an abort is used while // grbl is moving the machine. /// by LETARTARE 3-> 4 int32_t last_position[4]; double last_coord_system[N_COORDINATE_SYSTEM][3]; memcpy(last_position, sys.position, sizeof(sys.position)); // last_position[] = sys.position[] memcpy(last_coord_system, sys.coord_system, sizeof(sys.coord_system)); // last_coord_system[] = sys.coord_system[] // Reset system. memset(&sys, 0, sizeof(sys)); // Clear all system variables serial_reset_read_buffer(); // Clear serial read buffer settings_init(); // Load grbl settings from EEPROM protocol_init(); // Clear incoming line data plan_init(); // Clear block buffer and planner variables gc_init(); // Set g-code parser to default state spindle_init(); limits_init(); coolant_init(); st_reset(); // Clear stepper subsystem variables. // Reload last known machine position and work systems. G92 coordinate offsets are reset. memcpy(sys.position, last_position, sizeof(last_position)); // sys.position[] = last_position[] memcpy(sys.coord_system, last_coord_system, sizeof(last_coord_system)); // sys.coord_system[] = last_coord_system[] gc_set_current_position(last_position[X_AXIS],last_position[Y_AXIS],last_position[Z_AXIS],last_position[C_AXIS]); plan_set_current_position(last_position[X_AXIS],last_position[Y_AXIS],last_position[Z_AXIS],last_position[C_AXIS]); // Set system runtime defaults // TODO: Eventual move to EEPROM from config.h when all of the new settings are worked out. // Mainly to avoid having to maintain several different versions. #ifdef CYCLE_AUTO_START sys.auto_start = true; #endif // TODO: Install G20/G21 unit default into settings and load appropriate settings. } protocol_execute_runtime(); protocol_process(); // ... process the serial protocol } return 0; /* never reached */ }
// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after // completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate // the trigger point of the limit switches. The rapid stops are handled by a system level axis lock // mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically // circumvent the processes for executing motions in normal operation. // NOTE: Only the abort realtime command can interrupt this process. // TODO: Move limit pin-specific calls to a general function for portability. void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. // Initialize uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); uint8_t step_pin[N_AXIS]; float target[N_AXIS]; float max_travel = 0.0; uint8_t idx; for (idx=0; idx<N_AXIS; idx++) { // Initialize step pin masks step_pin[idx] = get_step_pin_mask(idx); #ifdef COREXY if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (get_step_pin_mask(X_AXIS)|get_step_pin_mask(Y_AXIS)); } #endif if (bit_istrue(cycle_mask,bit(idx))) { // Set target based on max_travel setting. Ensure homing switches engaged with search scalar. // NOTE: settings.max_travel[] is stored as a negative value. max_travel = max(max_travel,(-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]); } } // Set search mode with approach at seek rate to quickly engage the specified cycle_mask limit switches. bool approach = true; float homing_rate = settings.homing_seek_rate; uint8_t limit_state, axislock, n_active_axis; do { system_convert_array_steps_to_mpos(target,sys.position); // Initialize and declare variables needed for homing routine. axislock = 0; n_active_axis = 0; for (idx=0; idx<N_AXIS; idx++) { // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; sys.position[idx] = 0; // Set target direction based on cycle mask and homing cycle approach state. // NOTE: This happens to compile smaller than any other implementation tried. if (bit_istrue(settings.homing_dir_mask,bit(idx))) { if (approach) { target[idx] = -max_travel; } else { target[idx] = max_travel; } } else { if (approach) { target[idx] = max_travel; } else { target[idx] = -max_travel; } } // Apply axislock to the step port pins active in this cycle. axislock |= step_pin[idx]; } } homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate. sys.homing_axis_lock = axislock; plan_sync_position(); // Sync planner position to current machine position. // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle. #ifdef USE_LINE_NUMBERS plan_buffer_line(target, homing_rate, false, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion. #else plan_buffer_line(target, homing_rate, false, false); // Bypass mc_line(). Directly plan homing motion. #endif st_prep_buffer(); // Prep and fill segment buffer from newly planned block. st_wake_up(); // Initiate motion do { if (approach) { // Check limit state. Lock out cycle axes when they change. limit_state = limits_get_state(); for (idx=0; idx<N_AXIS; idx++) { if (axislock & step_pin[idx]) { if (limit_state & (1 << idx)) { axislock &= ~(step_pin[idx]); } } } sys.homing_axis_lock = axislock; } st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // Exit routines: No time to run protocol_execute_realtime() in this loop. if (sys_rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { // Homing failure: Limit switches are still engaged after pull-off motion if ( (sys_rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) || // Safety door or reset issued (!approach && (limits_get_state() & cycle_mask)) || // Limit switch still engaged after pull-off motion ( approach && (sys_rt_exec_state & EXEC_CYCLE_STOP)) ) { // Limit switch not found during approach. mc_reset(); // Stop motors, if they are running. protocol_execute_realtime(); return; } else { // Pull-off motion complete. Disable CYCLE_STOP from executing. system_clear_exec_state_flag(EXEC_CYCLE_STOP); break; } } } while (STEP_MASK & axislock); st_reset(); // Immediately force kill steppers and reset step segment buffer. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. // Reverse direction and reset homing rate for locate cycle(s). approach = !approach; // After first cycle, homing enters locating phase. Shorten search to pull-off distance. if (approach) { max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR; homing_rate = settings.homing_feed_rate; } else { max_travel = settings.homing_pulloff; homing_rate = settings.homing_seek_rate; } } while (n_cycle-- > 0); // The active cycle axes should now be homed and machine limits have been located. By // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, // set up pull-off maneuver from axes limit switches that have been homed. This provides // some initial clearance off the switches and should also help prevent them from falsely // triggering when hard limits are enabled or when more than one axes shares a limit pin. #ifdef COREXY int32_t off_axis_position = 0; #endif int32_t set_axis_position; // Set machine positions for homed limit switches. Don't update non-homed axes. for (idx=0; idx<N_AXIS; idx++) { // NOTE: settings.max_travel[] is stored as a negative value. if (cycle_mask & bit(idx)) { #ifdef HOMING_FORCE_SET_ORIGIN set_axis_position = 0; #else if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) { set_axis_position = lround((settings.max_travel[idx]+settings.homing_pulloff)*settings.steps_per_mm[idx]); } else { set_axis_position = lround(-settings.homing_pulloff*settings.steps_per_mm[idx]); } #endif #ifdef COREXY if (idx==X_AXIS) { off_axis_position = (sys.position[B_MOTOR] - sys.position[A_MOTOR])/2; sys.position[A_MOTOR] = set_axis_position - off_axis_position; sys.position[B_MOTOR] = set_axis_position + off_axis_position; } else if (idx==Y_AXIS) { off_axis_position = (sys.position[A_MOTOR] + sys.position[B_MOTOR])/2; sys.position[A_MOTOR] = off_axis_position - set_axis_position; sys.position[B_MOTOR] = off_axis_position + set_axis_position; } else { sys.position[idx] = set_axis_position; } #else sys.position[idx] = set_axis_position; #endif } } plan_sync_position(); // Sync planner position to homed machine position. // sys.state = STATE_HOMING; // Ensure system state set as homing before returning. }
// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after // completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate // the trigger point of the limit switches. The rapid stops are handled by a system level axis lock // mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically // circumvent the processes for executing motions in normal operation. // NOTE: Only the abort runtime command can interrupt this process. void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. // Initialize homing in search mode to quickly engage the specified cycle_mask limit switches. bool approach = true; float homing_rate = settings.homing_seek_rate; uint8_t invert_pin, idx; uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); ///***5 float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; float max_travel = 0.0; for (idx=0; idx<N_AXIS; idx++) { // Initialize limit and step pin masks limit_pin[idx] = get_limit_pin_mask(idx); ///////****get the Pin of limit min x, y ,z , Limit OK step_pin[idx] = get_step_pin_mask(idx); ///////****get the Pin of limit min x, y ,z now I let it 0, 1, 2 // Determine travel distance to the furthest homing switch based on user max travel settings. // NOTE: settings.max_travel[] is stored as a negative value. if (max_travel > settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } } max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. do { // Initialize invert_pin boolean based on approach and invert pin user setting. if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { invert_pin = approach; } else { invert_pin = !approach; } // Initialize and declare variables needed for homing routine. uint8_t n_active_axis = 0; uint8_t axislock = 0; for (idx=0; idx<N_AXIS; idx++) { // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; if (!approach) { target[idx] = -max_travel; } else { target[idx] = max_travel; } } else { target[idx] = 0.0; } // Set target direction based on cycle mask if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] = -target[idx]; } // Apply axislock to the step port pins active in this cycle. if (bit_istrue(cycle_mask,bit(idx))) { axislock |= step_pin[idx]; } } homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate. sys.homing_axis_lock = axislock; // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle. uint8_t limit_state; #ifdef USE_LINE_NUMBERS plan_buffer_line(target, homing_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion. #else plan_buffer_line(target, homing_rate, false); // Bypass mc_line(). Directly plan homing motion. #endif st_prep_buffer(); // Prep and fill segment buffer from newly planned block. st_wake_up(); // Initiate motion do { // Check limit state. Lock out cycle axes when they change. /////////////////########################################*********** #if MotherBoard==3 /////**MB==3 #ifdef limit_int_style limit_state = LIMIT_PIN; if (invert_pin) { limit_state ^= LIMIT_MASK; } #else //************Get Limit Pin State. PiBot get limit/endstop mask same with the step mask. #if LIMIT_MAX_OPEN if(isXMinEndstopHit()) { limit_state^= MASK(X_LIMIT_BIT);} ////***read X_endstop then write into limite_state if(isYMinEndstopHit()) { limit_state^= MASK(Y_LIMIT_BIT);} if(isZMinEndstopHit()) { limit_state^= MASK(Z_LIMIT_BIT);} ////*****add MAX limit if(isXMaxEndstopHit()) { limit_state^= MASK(X_LIMIT_MAX_BIT);} ////***read X_endstop then write into limite_state if(isYMaxEndstopHit()) { limit_state^= MASK(Y_LIMIT_MAX_BIT);} if(isZMaxEndstopHit()) { limit_state^= MASK(Z_LIMIT_MAX_BIT);} ////*****add MAX limit #else if(isXMinEndstopHit()) { limit_state^= MASK(X_MASK);} ////***read X_endstop then write into limite_state if(isYMinEndstopHit()) { limit_state^= MASK(Y_MASK);} if(isZMinEndstopHit()) { limit_state^= MASK(Z_MASK);} ////*****add MAX limit #endif #endif #else /////**MB!=3 ////////################################################# limit_state = LIMIT_PIN; if (invert_pin) { limit_state ^= LIMIT_MASK; } #endif /////**MB==3 /////////////////////////////##################################### for (idx=0; idx<N_AXIS; idx++) { if (axislock & step_pin[idx]) { if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); } } } sys.homing_axis_lock = axislock; st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // Check only for user reset. No time to run protocol_execute_runtime() in this loop. if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; } } while (STEP_MASK & axislock); st_reset(); // Immediately force kill steppers and reset step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared. delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. // Reverse direction and reset homing rate for locate cycle(s). homing_rate = settings.homing_feed_rate; approach = !approach; } while (n_cycle-- > 0); // The active cycle axes should now be homed and machine limits have been located. By // default, grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, // set up pull-off maneuver from axes limit switches that have been homed. This provides // some initial clearance off the switches and should also help prevent them from falsely // triggering when hard limits are enabled or when more than one axes shares a limit pin. for (idx=0; idx<N_AXIS; idx++) { // Set up pull off targets and machine positions for limit switches homed in the negative // direction, rather than the traditional positive. Leave non-homed positions as zero and // do not move them. // NOTE: settings.max_travel[] is stored as a negative value. if (cycle_mask & bit(idx)) { #ifdef HOMING_FORCE_SET_ORIGIN sys.position[idx] = 0; // Set axis homed location as axis origin target[idx] = settings.homing_pulloff; if ( bit_isfalse(settings.homing_dir_mask,bit(idx)) ) { target[idx] = -target[idx]; } #else if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) { target[idx] = settings.homing_pulloff+settings.max_travel[idx]; sys.position[idx] = lround(settings.max_travel[idx]*settings.steps_per_mm[idx]); } else { target[idx] = -settings.homing_pulloff; sys.position[idx] = 0; } #endif } else { // Non-active cycle axis. Set target to not move during pull-off. target[idx] = (float)sys.position[idx]/settings.steps_per_mm[idx]; } } plan_sync_position(); // Sync planner position to current machine position for pull-off move. #ifdef USE_LINE_NUMBERS plan_buffer_line(target, settings.homing_seek_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan motion. #else plan_buffer_line(target, settings.homing_seek_rate, false); // Bypass mc_line(). Directly plan motion. #endif // Initiate pull-off using main motion control routines. // TODO : Clean up state routines so that this motion still shows homing state. sys.state = STATE_QUEUED; bit_true_atomic(sys.execute, EXEC_CYCLE_START); protocol_execute_runtime(); protocol_buffer_synchronize(); // Complete pull-off motion. // Set system state to homing before returning. sys.state = STATE_HOMING; }
void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. if (sys.state == STATE_CHECK_MODE) { return; } // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. if (probe_get_state()) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } if (sys.abort) { return; } // Return if system reset has been issued. // Setup and queue probing motion. Auto cycle-start should not start the cycle. #ifdef USE_LINE_NUMBERS mc_line(target, feed_rate, invert_feed_rate, line_number); #else mc_line(target, feed_rate, invert_feed_rate); #endif // Activate the probing monitor in the stepper module. sys.probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); do { protocol_execute_runtime(); if (sys.abort) { return; } // Check for system abort } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. if (sys.probe_state == PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort // Reset the stepper and planner buffers to remove the remainder of the probe motion. st_reset(); // Reest step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. // Pull-off triggered probe to the trigger location since we had to decelerate a little beyond // it to stop the machine in a controlled manner. uint8_t idx; for(idx=0; idx<N_AXIS; idx++){ // NOTE: The target[] variable updated here will be sent back and synced with the g-code parser. target[idx] = (float)sys.probe_position[idx]/settings.steps_per_deg[idx]; } #ifdef USE_LINE_NUMBERS mc_line(target, feed_rate, invert_feed_rate, line_number); #else mc_line(target, feed_rate, invert_feed_rate); #endif // Execute pull-off motion and wait until it completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); protocol_buffer_synchronize(); if (sys.abort) { return; } // Return if system reset has been issued. sys.auto_start = auto_start_state; // Restore run state before returning #ifdef MESSAGE_PROBE_COORDINATES // All done! Output the probe position as message. report_probe_parameters(); #endif }
int main(void) { #ifdef PART_LM4F120H5QR // ARM code SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN ); //set system clock to 80 MHz FPUEnable(); //enable the Floating Point Unit // FPULazyStackingEnable(); // Enable stacking for interrupt handlers #endif // Initialize system serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load grbl settings from EEPROM st_init(); // Setup stepper pins and interrupt timers #ifdef PART_LM4F120H5QR // ARM code IntMasterEnable(); #else // AVR code sei(); // Enable interrupts #endif memset(&sys, 0, sizeof(sys)); // Clear all system variables sys.abort = true; // Set abort to complete initialization sys.state = STATE_INIT; // Set alarm state to indicate unknown initial position for(;;) { // Execute system reset upon a system abort, where the main program will return to this loop. // Once here, it is safe to re-initialize the system. At startup, the system will automatically // reset to finish the initialization process. if (sys.abort) { // Reset system. serial_reset_read_buffer(); // Clear serial read buffer plan_init(); // Clear block buffer and planner variables gc_init(); // Set g-code parser to default state protocol_init(); // Clear incoming line data and execute startup lines spindle_init(); coolant_init(); limits_init(); st_reset(); // Clear stepper subsystem variables. // Sync cleared gcode and planner positions to current system position, which is only // cleared upon startup, not a reset/abort. sys_sync_current_position(); // Reset system variables. sys.abort = false; sys.execute = 0; if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) { sys.auto_start = true; } // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (sys.state == STATE_INIT && bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Check for and report alarm state after a reset, error, or an initial power up. if (sys.state == STATE_ALARM) { report_feedback_message(MESSAGE_ALARM_LOCK); } else { // All systems go. Set system to ready and execute startup script. sys.state = STATE_IDLE; protocol_execute_startup(); } } protocol_execute_runtime(); protocol_process(); // ... process the serial protocol // When the serial protocol returns, there are no more characters in the serial read buffer to // be processed and executed. This indicates that individual commands are being issued or // streaming is finished. In either case, auto-cycle start, if enabled, any queued moves. if (sys.auto_start) { st_cycle_start(); } } // return 0; /* never reached */ }
bool umcwriter_init(const char* filename, const double heightZ, const char machine_type) { umcwriter_Z = 0; umcwriter_Z_height = heightZ; umcwriter_print_time = 0; umcwriter_machine_type = machine_type; umcwriter_bed_temp = 0; st_reset(); plan_reset(); umcwriter_file = fopen(filename,"wb+"); if( !umcwriter_file ) return false; umcwriter_set_report_data( 0, 0 ); UP3D_BLK blk; UP3D_PROG_BLK_Power(&blk,true); _umcwriter_write_file(&blk, 1); umcwriter_pause(4000); //wait for power on complete and temperature measurement to stabilize UP3D_PROG_BLK_SetParameter(&blk,0x41,0); //TEMP FOR NOZZLE1 TEMP REACHED _umcwriter_write_file(&blk, 1); UP3D_PROG_BLK_SetParameter(&blk,0x42,0); //TEMP FOR NOZZLE2 TEMP REACHED _umcwriter_write_file(&blk, 1); UP3D_PROG_BLK_SetParameter(&blk,0x43,0); //TEMP FOR BED TEMP REACHED _umcwriter_write_file(&blk, 1); // NEEDED? UP3D_PROG_BLK_SetParameter(&blk,0x46,13); //? _umcwriter_write_file(&blk, 1); if( 'm' == umcwriter_machine_type ) { UP3D_PROG_BLK_SetParameter(&blk,0x49,80); //? for up mini only! _umcwriter_write_file(&blk, 1); } //home all axis (needed for correct print status umcwriter_home(0); umcwriter_home(1); umcwriter_home(2); UP3D_PROG_BLK_SetParameter(&blk,PARA_PRINT_STATUS,1); //initialized _umcwriter_write_file(&blk, 1); UP3D_PROG_BLK_SetParameter(&blk,0x11,0); //no support _umcwriter_write_file(&blk, 1); // NEEDED ? UP3D_PROG_BLK_SetParameter(&blk,0x35,0); //needed for heat bed! _umcwriter_write_file(&blk, 1); // UP3D_PROG_BLK_SetParameter(&blk,0x36,103); //feedback length ? // _umcwriter_write_file(&blk, 1); // UP3D_PROG_BLK_SetParameter(&blk,0x2A,5000); //change nozzle time // _umcwriter_write_file(&blk, 1); // UP3D_PROG_BLK_SetParameter(&blk,0x2B,0); //jump time // _umcwriter_write_file(&blk, 1); UP3D_PROG_BLK_SetParameter(&blk,0x17,0); //nozzle #1 not open _umcwriter_write_file(&blk, 1); // PROBLEM... // UP3D_PROG_BLK_SetParameter(&blk,PARA_PRINT_STATUS,2); //running ==> PAUSED ??? // _umcwriter_write_file(&blk, 1); // // NEEDED? UP3D_PROG_BLK_SetParameter(&blk,0x82,255); //? _umcwriter_write_file(&blk, 1); UP3D_PROG_BLK_SetParameter(&blk,0x83,255); //? _umcwriter_write_file(&blk, 1); //DEL UP3D_PROG_BLK_SetParameter(&blk,0x1D,100000); //feed error length //DEL _umcwriter_write_file(&blk, 1); /* PROBLEM... UP3D_PROG_BLK_SetParameter(&blk,0x1C,1); //printing... _umcwriter_write_file(&blk, 1); */ return true; }
int main(void) { // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load Grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt #ifdef CPU_MAP_CUSTOM_1284p spi_init(); L6474_init(4); L6474_CmdEnableAll(); #endif memset(&sys, 0, sizeof(sys)); // Clear all system variables sys.abort = true; // Set abort to complete initialization sei(); // Enable interrupts // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Force Grbl into an ALARM state upon a power-cycle or hard reset. #ifdef FORCE_INITIALIZATION_ALARM sys.state = STATE_ALARM; #endif // Grbl initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. for(;;) { // TODO: Separate configure task that require interrupts to be disabled, especially upon // a system abort and ensuring any active interrupts are cleanly reset. // Reset Grbl primary systems. serial_reset_read_buffer(); // Clear serial read buffer gc_init(); // Set g-code parser to default state spindle_init(); coolant_init(); limits_init(); probe_init(); plan_reset(); // Clear block buffer and planner variables st_reset(); // Clear stepper subsystem variables. // Sync cleared gcode and planner positions to current system position. plan_sync_position(); gc_sync_position(); // Reset system variables. sys.abort = false; sys_rt_exec_state = 0; sys_rt_exec_alarm = 0; sys.suspend = false; // Start Grbl main loop. Processes program inputs and executes them. protocol_main_loop(); } return 0; /* Never reached */ }